Enable push services for a MUC domain

As soon as a chatroom from that domain is opened and if the MUC supports it.
This commit is contained in:
JC Brand 2018-08-09 10:41:31 +02:00
parent 989ce0f54d
commit 764686dd19
4 changed files with 217 additions and 148 deletions

152
dist/converse.js vendored
View File

@ -73489,100 +73489,128 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'push_app_servers': []
});
function disablePushAppServer(push_app_server) {
async function disablePushAppServer(domain, push_app_server) {
if (!push_app_server.jid) {
return;
}
Promise.all([_converse.api.disco.supports(Strophe.NS.PUSH, _converse.bare_jid)]).then(result => {
if (!result[0].length && !result[1].length) {
return _converse.log(`Not disabling push app server "${push_app_server.jid}", no disco support from your server.`, Strophe.LogLevel.WARN);
}
const result = await _converse.api.disco.supports(Strophe.NS.PUSH, domain || _converse.bare_jid);
const stanza = $iq({
'type': 'set'
}).c('disable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid
if (!result.length) {
return _converse.log(`Not disabling push app server "${push_app_server.jid}", no disco support from your server.`, Strophe.LogLevel.WARN);
}
const stanza = $iq({
'type': 'set'
});
if (domain !== _converse.bare_jid) {
stanza.attrs({
'to': domain
});
}
if (push_app_server.node) {
stanza.attrs({
'node': push_app_server.node
});
}
stanza.c('disable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid
});
_converse.api.sendIQ(stanza).then(() => _converse.session.set('push_enabled', true)).catch(e => {
_converse.log(`Could not enable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
if (push_app_server.node) {
stanza.attrs({
'node': push_app_server.node
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
_converse.api.sendIQ(stanza).catch(e => {
_converse.log(`Could not disable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}
function enablePushAppServer(push_app_server) {
async function enablePushAppServer(domain, push_app_server) {
if (!push_app_server.jid || !push_app_server.node) {
return;
}
_converse.api.disco.getIdentity('pubsub', 'push', push_app_server.jid).then(identity => {
if (!identity) {
return _converse.log(`Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`, Strophe.LogLevel.WARN);
}
const identity = await _converse.api.disco.getIdentity('pubsub', 'push', push_app_server.jid);
return Promise.all([_converse.api.disco.supports(Strophe.NS.PUSH, push_app_server.jid), _converse.api.disco.supports(Strophe.NS.PUSH, _converse.bare_jid)]).then(result => {
if (!result[0].length && !result[1].length) {
return _converse.log(`Not enabling push app server "${push_app_server.jid}", no disco support from your server.`, Strophe.LogLevel.WARN);
}
if (!identity) {
return _converse.log(`Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`, Strophe.LogLevel.WARN);
}
const stanza = $iq({
'type': 'set'
}).c('enable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid,
'node': push_app_server.node
});
const result = await Promise.all([_converse.api.disco.supports(Strophe.NS.PUSH, push_app_server.jid), _converse.api.disco.supports(Strophe.NS.PUSH, domain)]);
if (push_app_server.secret) {
stanza.c('x', {
'xmlns': Strophe.NS.XFORM,
'type': 'submit'
}).c('field', {
'var': 'FORM_TYPE'
}).c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up().c('field', {
'var': 'secret'
}).c('value').t(push_app_server.secret);
}
if (!result[0].length && !result[1].length) {
return _converse.log(`Not enabling push app server "${push_app_server.jid}", no disco support from your server.`, Strophe.LogLevel.WARN);
}
_converse.api.sendIQ(stanza).then(() => _converse.session.save('push_enabled', true)).catch(e => {
_converse.log(`Could not enable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
const stanza = $iq({
'type': 'set'
});
_converse.log(e, Strophe.LogLevel.ERROR);
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
if (domain !== _converse.bare_jid) {
stanza.attrs({
'to': domain
});
}
stanza.c('enable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid,
'node': push_app_server.node
});
if (push_app_server.secret) {
stanza.c('x', {
'xmlns': Strophe.NS.XFORM,
'type': 'submit'
}).c('field', {
'var': 'FORM_TYPE'
}).c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up().c('field', {
'var': 'secret'
}).c('value').t(push_app_server.secret);
}
return _converse.api.sendIQ(stanza);
}
function enablePush() {
if (_converse.session.get('push_enabled')) {
// XXX: this code is still a bit naive. We set push_enabled
// to true as soon as the first push app server has been set.
//
// When enabling or disabling multiple push app servers,
// we won't wait until we have confirmation that all have been set.
async function enablePush(domain) {
domain = domain || _converse.bare_jid;
const push_enabled = _converse.session.get('push_enabled') || [];
if (_.includes(push_enabled, domain)) {
return;
}
const enabled_services = _.reject(_converse.push_app_servers, 'disable');
_.each(enabled_services, enablePushAppServer);
try {
await Promise.all(_.map(enabled_services, _.partial(enablePushAppServer, domain)));
} catch (e) {
_converse.log('Could not enable push App Server', Strophe.LogLevel.ERROR);
if (e) _converse.log(e, Strophe.LogLevel.ERROR);
} finally {
push_enabled.push(domain);
}
const disabled_services = _.filter(_converse.push_app_servers, 'disable');
_.each(disabled_services, disablePushAppServer);
_.each(disabled_services, _.partial(disablePushAppServer, domain));
_converse.session.save('push_enabled', push_enabled);
}
_converse.api.listen.on('statusInitialized', enablePush);
function onChatBoxAdded(model) {
if (model.get('type') == _converse.CHATROOMS_TYPE) {
enablePush(Strophe.getDomainFromJid(model.get('jid')));
}
}
_converse.api.listen.on('statusInitialized', () => enablePush());
_converse.api.listen.on('chatBoxesInitialized', () => _converse.chatboxes.on('add', onChatBoxAdded));
}
});

View File

@ -5,6 +5,7 @@
var $iq = converse.env.$iq;
var Strophe = converse.env.Strophe;
var _ = converse.env._;
var f = converse.env.f;
describe("XEP-0357 Push Notifications", function () {
@ -53,9 +54,48 @@
'id': stanza.getAttribute('id')
})));
return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
}).then(done).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}));
it("can enabled for a MUC domain",
mock.initConverseWithPromises(null,
['rosterGroupsFetched'], {
'push_app_servers': [{
'jid': 'push-5@client.example',
'node': 'yxs32uqsflafdk3iuqo'
}]
}, function (done, _converse) {
const IQ_stanzas = _converse.connection.IQ_stanzas,
room_jid = 'coven@chat.shakespeare.lit';
expect(_converse.session.get('push_enabled')).toBeFalsy();
test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'oldhag')
.then(() => test_utils.waitUntilDiscoConfirmed(
_converse, _converse.push_app_servers[0].jid,
[{'category': 'pubsub', 'type':'push'}],
['urn:xmpp:push:0'], [], 'info'))
.then(() => {
return test_utils.waitUntilDiscoConfirmed(
_converse, 'chat.shakespeare.lit',
[{'category': 'account', 'type':'registered'}],
['urn:xmpp:push:0'], [], 'info')
}).then(() => {
done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
return test_utils.waitUntil(
() => _.filter(IQ_stanzas, (iq) => iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop())
}).then(stanza => {
expect(stanza.nodeTree.outerHTML).toEqual(
`<iq type="set" xmlns="jabber:client" to="chat.shakespeare.lit" id="${stanza.nodeTree.getAttribute('id')}">`+
'<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
'</iq>'
)
_converse.connection._dataRecv(test_utils.createRequest($iq({
'to': _converse.connection.jid,
'type': 'result',
'id': stanza.nodeTree.getAttribute('id')
})));
return test_utils.waitUntil(() => f.includes('chat.shakespeare.lit', _converse.session.get('push_enabled')));
}).then(done).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}));
it("can be disabled",
@ -100,9 +140,7 @@
'id': stanza.getAttribute('id')
})));
return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
}).then(() => {
done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).then(done).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}));
@ -156,9 +194,7 @@
'id': stanza.getAttribute('id')
})));
return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
}).then(() => {
done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).then(done).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}));
});
}));

View File

@ -30,98 +30,103 @@
'push_app_servers': [],
});
function disablePushAppServer (push_app_server) {
async function disablePushAppServer (domain, push_app_server) {
if (!push_app_server.jid) {
return;
}
Promise.all([
_converse.api.disco.supports(Strophe.NS.PUSH, _converse.bare_jid)
]).then(result => {
if (!result[0].length && !result[1].length) {
return _converse.log(
`Not disabling push app server "${push_app_server.jid}", no disco support from your server.`,
Strophe.LogLevel.WARN
);
}
const stanza = $iq({'type': 'set'})
.c('disable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid,
});
if (push_app_server.node) {
stanza.attrs({'node': push_app_server.node});
}
_converse.api.sendIQ(stanza)
.then(() => _converse.session.set('push_enabled', true))
.catch((e) => {
_converse.log(`Could not enable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
const result = await _converse.api.disco.supports(Strophe.NS.PUSH, domain || _converse.bare_jid)
if (!result.length) {
return _converse.log(
`Not disabling push app server "${push_app_server.jid}", no disco support from your server.`,
Strophe.LogLevel.WARN
);
}
const stanza = $iq({'type': 'set'});
if (domain !== _converse.bare_jid) {
stanza.attrs({'to': domain});
}
stanza.c('disable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid,
});
if (push_app_server.node) {
stanza.attrs({'node': push_app_server.node});
}
_converse.api.sendIQ(stanza)
.catch(e => {
_converse.log(`Could not disable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}
function enablePushAppServer (push_app_server) {
async function enablePushAppServer (domain, push_app_server) {
if (!push_app_server.jid || !push_app_server.node) {
return;
}
_converse.api.disco.getIdentity('pubsub', 'push', push_app_server.jid)
.then(identity => {
if (!identity) {
return _converse.log(
`Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`,
Strophe.LogLevel.WARN
);
}
return Promise.all([
_converse.api.disco.supports(Strophe.NS.PUSH, push_app_server.jid),
_converse.api.disco.supports(Strophe.NS.PUSH, _converse.bare_jid)
]).then((result) => {
if (!result[0].length && !result[1].length) {
return _converse.log(
`Not enabling push app server "${push_app_server.jid}", no disco support from your server.`,
Strophe.LogLevel.WARN
);
}
const stanza = $iq({'type': 'set'})
.c('enable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid,
'node': push_app_server.node
});
if (push_app_server.secret) {
stanza.c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var': 'FORM_TYPE'})
.c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up()
.c('field', {'var': 'secret'})
.c('value').t(push_app_server.secret);
}
_converse.api.sendIQ(stanza)
.then(() => _converse.session.save('push_enabled', true))
.catch((e) => {
_converse.log(`Could not enable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
const identity = await _converse.api.disco.getIdentity('pubsub', 'push', push_app_server.jid);
if (!identity) {
return _converse.log(
`Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`,
Strophe.LogLevel.WARN
);
}
const result = await Promise.all([
_converse.api.disco.supports(Strophe.NS.PUSH, push_app_server.jid),
_converse.api.disco.supports(Strophe.NS.PUSH, domain)
]);
if (!result[0].length && !result[1].length) {
return _converse.log(
`Not enabling push app server "${push_app_server.jid}", no disco support from your server.`,
Strophe.LogLevel.WARN
);
}
const stanza = $iq({'type': 'set'});
if (domain !== _converse.bare_jid) {
stanza.attrs({'to': domain});
}
stanza.c('enable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_app_server.jid,
'node': push_app_server.node
});
if (push_app_server.secret) {
stanza.c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var': 'FORM_TYPE'})
.c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up()
.c('field', {'var': 'secret'})
.c('value').t(push_app_server.secret);
}
return _converse.api.sendIQ(stanza);
}
function enablePush () {
if (_converse.session.get('push_enabled')) {
// XXX: this code is still a bit naive. We set push_enabled
// to true as soon as the first push app server has been set.
//
// When enabling or disabling multiple push app servers,
// we won't wait until we have confirmation that all have been set.
async function enablePush (domain) {
domain = domain || _converse.bare_jid;
const push_enabled = _converse.session.get('push_enabled') || [];
if (_.includes(push_enabled, domain)) {
return;
}
const enabled_services = _.reject(_converse.push_app_servers, 'disable');
_.each(enabled_services, enablePushAppServer);
try {
await Promise.all(_.map(enabled_services, _.partial(enablePushAppServer, domain)))
} catch (e) {
_converse.log('Could not enable push App Server', Strophe.LogLevel.ERROR);
if (e) _converse.log(e, Strophe.LogLevel.ERROR);
} finally {
push_enabled.push(domain);
}
const disabled_services = _.filter(_converse.push_app_servers, 'disable');
_.each(disabled_services, disablePushAppServer);
_.each(disabled_services, _.partial(disablePushAppServer, domain));
_converse.session.save('push_enabled', push_enabled);
}
_converse.api.listen.on('statusInitialized', enablePush);
function onChatBoxAdded (model) {
if (model.get('type') == _converse.CHATROOMS_TYPE) {
enablePush(Strophe.getDomainFromJid(model.get('jid')));
}
}
_converse.api.listen.on('statusInitialized', () => enablePush());
_converse.api.listen.on('chatBoxesInitialized', () => _converse.chatboxes.on('add', onChatBoxAdded));
}
});
}));

View File

@ -117,7 +117,7 @@
modal.el.querySelector('input[name="nickname"]').value = nick;
modal.el.querySelector('form input[type="submit"]').click();
resolve();
}).catch(_.partial(console.error, _));
});
}).catch(_.partial(console.error, _));
};