Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
a09333f8
Commit
a09333f8
authored
Jun 07, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow multiple push services to be enabled and also allow disabling
parent
5954cd8f
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
251 additions
and
117 deletions
+251
-117
dist/converse.js
dist/converse.js
+82
-36
docs/source/configuration.rst
docs/source/configuration.rst
+24
-24
spec/push.js
spec/push.js
+61
-16
src/converse-push.js
src/converse-push.js
+84
-41
No files found.
dist/converse.js
View file @
a09333f8
...
...
@@ -73353,36 +73353,64 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
__ = _converse.__;
_converse.api.settings.update({
'push_service': undefined,
'push_service_node': undefined,
'push_service_secret': undefined
'push_services': []
});
function
enablePush(
) {
if (
_converse.session.get('push_enabled')
) {
function
disablePushService(push_service
) {
if (
!push_service.jid
) {
return;
}
if (_converse.push_service && _converse.push_service_node) {
_converse.api.disco.getIdentity('pubsub', 'push', _converse.push_service).then(identity => {
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 service "${push_service.jid}", no disco support from your server.`, Strophe.LogLevel.WARN);
}
const stanza = $iq({
'type': 'set'
}).c('disable', {
'xmlns': Strophe.NS.PUSH,
'jid': push_service.jid
});
if (push_service.node) {
stanza.attrs({
'node': push_service.node
});
}
_converse.api.sendIQ(stanza).then(() => _converse.session.set('push_enabled', true)).catch(e => {
_converse.log(`Could not enable push service for ${push_service.jid}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
function enablePushService(push_service) {
if (!push_service.jid || !push_service.node) {
return;
}
_converse.api.disco.getIdentity('pubsub', 'push', push_service.jid).then(identity => {
if (!identity) {
return _converse.log(`Not enabling push the service "${_converse.push_service
}", it doesn't have the right disco identtiy.`, Strophe.LogLevel.WARN);
return _converse.log(`Not enabling push the service "${push_service.jid
}", it doesn't have the right disco identtiy.`, Strophe.LogLevel.WARN);
}
return Promise.all([_converse.api.disco.supports(Strophe.NS.PUSH, _converse.push_service
), _converse.api.disco.supports(Strophe.NS.PUSH, _converse.bare_jid)]).then(result => {
return Promise.all([_converse.api.disco.supports(Strophe.NS.PUSH, push_service.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 service "${_converse.push_service}", no disco support
`, Strophe.LogLevel.WARN);
return _converse.log(`Not enabling push service "${push_service.jid}", no disco support from your server.
`, Strophe.LogLevel.WARN);
}
const stanza = $iq({
'type': 'set'
}).c('enable', {
'xmlns': Strophe.NS.PUSH,
'jid': _converse.push_service
,
'node': _converse.push_service_
node
'jid': push_service.jid
,
'node': push_service.
node
});
if (_converse.push_service_
secret) {
if (push_service.
secret) {
stanza.c('x', {
'xmlns': Strophe.NS.XFORM,
'type': 'submit'
...
...
@@ -73390,17 +73418,35 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'var': 'FORM_TYPE'
}).c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up().c('field', {
'var': 'secret'
}).c('value').t(_converse.push_service_
secret);
}).c('value').t(push_service.
secret);
}
_converse.api.sendIQ(stanza).then(() => _converse.session.set('push_enabled', true)).catch(e => {
_converse.log(`Could not enable push service for ${_converse.push_service
}`, Strophe.LogLevel.ERROR);
_converse.log(`Could not enable push service for ${push_service.jid
}`, Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
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 service has been set.
//
// When enabling or disabling multiple push services,
// we won't wait until we have confirmation that all have been set.
return;
}
const enabled_services = _.reject(_converse.push_services, 'disable');
_.each(enabled_services, enablePushService);
const disabled_services = _.filter(_converse.push_services, 'disable');
_.each(disabled_services, disablePushService);
}
_converse.api.listen.on('statusInitialized', enablePush);
docs/source/configuration.rst
View file @
a09333f8
...
...
@@ -1068,38 +1068,38 @@ providers_link
The hyperlink on the registration form which points to a directory of public
XMPP servers.
push_service
------------
* Default: ``undefined``
This option allows you to specify a URI for the push notifications service
(called an "App Server" by `XEP-0357 <https://xmpp.org/extensions/xep-0357.html>`_).
push_services
-------------
If provided, together with a `push_service_node`_, then Converse will instruct
the user's XMPP server to send push notificatiosn to that URI.
* Default: ``[]``
push_service_node
-----------------
This option lets you enable or disable so-called push notification "App Servers"
(as per `XEP-0357 <https://xmpp.org/extensions/xep-0357.html>`_).
* Default: ``undefined``
For each "App Server" an object needs to be passed in. When enabling, you need
to specify ``jid`` and ``node`` values. You can also provide a
``secret``, if required by your App Server.
This is the PubSub node of the push notifications service (aka "App Server") specified with the
`push_service`_ setting.
When disabling, you need to specify at least a ``jid`` and set ``disabled`` to
``true``. This will disable notifications to all pubsub nodes on that "App
Server". If you want to disable only a particular node, then specify a ``node``
value as well.
Push notifications will be sent to this node. If this value is not set, then
push notifications won't be sent out.
push_service_secret
-------------------
For example:
* Default: ``undefined``
Some push notification services (aka "App Servers") require a secret token to
be used when sending out notifications.
.. code-block:: javascript
This setting enables you to provide such a secret to Converse which will
forward it to your XMPP server to be included in push notifications.
converse.initialize({
'push_services': [{
'jid': 'push-4@client.example',
'node': 'yxs32uqsflafdk3iuqo',
'disable': true
}, {
'jid': 'push-5@client.example',
'node': 'yxs32uqsflafdk3iuqo',
}]
});
root
----
...
...
spec/push.js
View file @
a09333f8
...
...
@@ -8,22 +8,22 @@
describe
(
"
XEP-0357 Push Notifications
"
,
function
()
{
it
(
"
can be enabled
by specifying a push_service and push_service_node
"
,
it
(
"
can be enabled
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{
'
push_service
'
:
'
push-5@client.example
'
,
'
push_service_node
'
:
'
yxs32uqsflafdk3iuqo
'
'
push_services
'
:
[{
'
jid
'
:
'
push-5@client.example
'
,
'
node
'
:
'
yxs32uqsflafdk3iuqo
'
}]
},
function
(
done
,
_converse
)
{
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
let
stanza
;
expect
(
_converse
.
push_service
).
toBe
(
'
push-5@client.example
'
);
expect
(
_converse
.
push_service_node
).
toBe
(
'
yxs32uqsflafdk3iuqo
'
);
expect
(
_converse
.
session
.
get
(
'
push_enabled
'
)).
toBeFalsy
();
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
push_service
,
_converse
,
_converse
.
push_service
s
[
0
].
jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
push
'
}],
[
'
urn:xmpp:push:0
'
],
[],
'
info
'
)
.
then
(()
=>
test_utils
.
waitUntilDiscoConfirmed
(
...
...
@@ -58,25 +58,70 @@
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
}));
it
(
"
can be disabled
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{
'
push_services
'
:
[{
'
jid
'
:
'
push-5@client.example
'
,
'
node
'
:
'
yxs32uqsflafdk3iuqo
'
,
'
disable
'
:
true
}]
},
function
(
done
,
_converse
)
{
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
let
stanza
;
expect
(
_converse
.
session
.
get
(
'
push_enabled
'
)).
toBeFalsy
();
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
account
'
,
'
type
'
:
'
registered
'
}],
[
'
urn:xmpp:push:0
'
],
[],
'
info
'
)
.
then
(()
=>
{
return
test_utils
.
waitUntil
(()
=>
{
const
node
=
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[type="set"] disable[xmlns="urn:xmpp:push:0"]
'
);
}).
pop
();
if
(
node
)
{
stanza
=
node
.
nodeTree
;
return
true
;
}
})
}).
then
(()
=>
{
expect
(
stanza
.
outerHTML
).
toEqual
(
`<iq type="set" xmlns="jabber:client" id="
${
stanza
.
getAttribute
(
'
id
'
)}
">`
+
'
<disable 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
.
getAttribute
(
'
id
'
)
})));
return
test_utils
.
waitUntil
(()
=>
_converse
.
session
.
get
(
'
push_enabled
'
))
}).
then
(()
=>
{
done
();
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
}));
it
(
"
can require a secret token to be included
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{
'
push_service
'
:
'
push-5@client.example
'
,
'
push_service_node
'
:
'
yxs32uqsflafdk3iuqo
'
,
'
push_service_secret
'
:
'
eruio234vzxc2kla-91
'
'
push_services
'
:
[{
'
jid
'
:
'
push-5@client.example
'
,
'
node
'
:
'
yxs32uqsflafdk3iuqo
'
,
'
secret
'
:
'
eruio234vzxc2kla-91
'
}]
},
function
(
done
,
_converse
)
{
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
let
stanza
;
expect
(
_converse
.
push_service
).
toBe
(
'
push-5@client.example
'
);
expect
(
_converse
.
push_service_node
).
toBe
(
'
yxs32uqsflafdk3iuqo
'
);
expect
(
_converse
.
push_service_secret
).
toBe
(
'
eruio234vzxc2kla-91
'
);
expect
(
_converse
.
session
.
get
(
'
push_enabled
'
)).
toBeFalsy
();
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
push_service
,
_converse
,
_converse
.
push_service
s
[
0
].
jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
push
'
}],
[
'
urn:xmpp:push:0
'
],
[],
'
info
'
)
.
then
(()
=>
test_utils
.
waitUntilDiscoConfirmed
(
...
...
src/converse-push.js
View file @
a09333f8
...
...
@@ -27,56 +27,99 @@
{
__
}
=
_converse
;
_converse
.
api
.
settings
.
update
({
'
push_service
'
:
undefined
,
'
push_service_node
'
:
undefined
,
'
push_service_secret
'
:
undefined
'
push_services
'
:
[],
});
function
enablePush
()
{
if
(
_converse
.
session
.
get
(
'
push_enabled
'
))
{
function
disablePushService
(
push_service
)
{
if
(
!
push_service
.
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 service "
${
push_service
.
jid
}
", no disco support from your server.`
,
Strophe
.
LogLevel
.
WARN
);
}
const
stanza
=
$iq
({
'
type
'
:
'
set
'
})
.
c
(
'
disable
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUSH
,
'
jid
'
:
push_service
.
jid
,
});
if
(
push_service
.
node
)
{
stanza
.
attrs
({
'
node
'
:
push_service
.
node
});
}
_converse
.
api
.
sendIQ
(
stanza
)
.
then
(()
=>
_converse
.
session
.
set
(
'
push_enabled
'
,
true
))
.
catch
((
e
)
=>
{
_converse
.
log
(
`Could not enable push service for
${
push_service
.
jid
}
`
,
Strophe
.
LogLevel
.
ERROR
);
_converse
.
log
(
e
,
Strophe
.
LogLevel
.
ERROR
);
});
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
}
function
enablePushService
(
push_service
)
{
if
(
!
push_service
.
jid
||
!
push_service
.
node
)
{
return
;
}
if
(
_converse
.
push_service
&&
_converse
.
push_service_node
)
{
_converse
.
api
.
disco
.
getIdentity
(
'
pubsub
'
,
'
push
'
,
_converse
.
push_service
)
_converse
.
api
.
disco
.
getIdentity
(
'
pubsub
'
,
'
push
'
,
push_service
.
jid
)
.
then
((
identity
)
=>
{
if
(
!
identity
)
{
return
_converse
.
log
(
`Not enabling push the service "
${
_converse
.
push_service
}
", it doesn't have the right disco identtiy.`
,
`Not enabling push the service "
${
push_service
.
jid
}
", it doesn't have the right disco identtiy.`
,
Strophe
.
LogLevel
.
WARN
);
}
return
Promise
.
all
([
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
PUSH
,
_converse
.
push_service
),
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
PUSH
,
push_service
.
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 service "
${
_converse
.
push_service
}
", no disco support
`
,
`Not enabling push service "
${
push_service
.
jid
}
", no disco support from your server.
`
,
Strophe
.
LogLevel
.
WARN
);
}
const
stanza
=
$iq
({
'
type
'
:
'
set
'
})
.
c
(
'
enable
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUSH
,
'
jid
'
:
_converse
.
push_service
,
'
node
'
:
_converse
.
push_service_
node
'
jid
'
:
push_service
.
jid
,
'
node
'
:
push_service
.
node
});
if
(
_converse
.
push_service_
secret
)
{
if
(
push_service
.
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
(
_converse
.
push_service_
secret
);
.
c
(
'
value
'
).
t
(
push_service
.
secret
);
}
_converse
.
api
.
sendIQ
(
stanza
)
.
then
(()
=>
_converse
.
session
.
set
(
'
push_enabled
'
,
true
))
.
catch
((
e
)
=>
{
_converse
.
log
(
`Could not enable push service for
${
_converse
.
push_service
}
`
,
Strophe
.
LogLevel
.
ERROR
);
_converse
.
log
(
`Could not enable push service for
${
push_service
.
jid
}
`
,
Strophe
.
LogLevel
.
ERROR
);
_converse
.
log
(
e
,
Strophe
.
LogLevel
.
ERROR
);
});
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
}
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 service has been set.
//
// When enabling or disabling multiple push services,
// we won't wait until we have confirmation that all have been set.
return
;
}
const
enabled_services
=
_
.
reject
(
_converse
.
push_services
,
'
disable
'
);
_
.
each
(
enabled_services
,
enablePushService
);
const
disabled_services
=
_
.
filter
(
_converse
.
push_services
,
'
disable
'
);
_
.
each
(
disabled_services
,
disablePushService
);
}
_converse
.
api
.
listen
.
on
(
'
statusInitialized
'
,
enablePush
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment