converse-push.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Converse.js
  2. // https://conversejs.org
  3. //
  4. // Copyright (c) 2013-2018, the Converse.js developers
  5. // Licensed under the Mozilla Public License (MPLv2)
  6. /* This is a Converse.js plugin which add support for registering
  7. * an "App Server" as defined in XEP-0357
  8. */
  9. import converse from "@converse/headless/converse-core";
  10. const { Strophe, $iq, _ } = converse.env;
  11. Strophe.addNamespace('PUSH', 'urn:xmpp:push:0');
  12. converse.plugins.add('converse-push', {
  13. initialize () {
  14. /* The initialize function gets called as soon as the plugin is
  15. * loaded by converse.js's plugin machinery.
  16. */
  17. const { _converse } = this,
  18. { __ } = _converse;
  19. _converse.api.settings.update({
  20. 'push_app_servers': [],
  21. 'enable_muc_push': false
  22. });
  23. async function disablePushAppServer (domain, push_app_server) {
  24. if (!push_app_server.jid) {
  25. return;
  26. }
  27. const result = await _converse.api.disco.supports(Strophe.NS.PUSH, domain || _converse.bare_jid)
  28. if (!result.length) {
  29. return _converse.log(
  30. `Not disabling push app server "${push_app_server.jid}", no disco support from your server.`,
  31. Strophe.LogLevel.WARN
  32. );
  33. }
  34. const stanza = $iq({'type': 'set'});
  35. if (domain !== _converse.bare_jid) {
  36. stanza.attrs({'to': domain});
  37. }
  38. stanza.c('disable', {
  39. 'xmlns': Strophe.NS.PUSH,
  40. 'jid': push_app_server.jid,
  41. });
  42. if (push_app_server.node) {
  43. stanza.attrs({'node': push_app_server.node});
  44. }
  45. _converse.api.sendIQ(stanza)
  46. .catch(e => {
  47. _converse.log(`Could not disable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR);
  48. _converse.log(e, Strophe.LogLevel.ERROR);
  49. });
  50. }
  51. async function enablePushAppServer (domain, push_app_server) {
  52. if (!push_app_server.jid || !push_app_server.node) {
  53. return;
  54. }
  55. const identity = await _converse.api.disco.getIdentity('pubsub', 'push', push_app_server.jid);
  56. if (!identity) {
  57. return _converse.log(
  58. `Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`,
  59. Strophe.LogLevel.WARN
  60. );
  61. }
  62. const result = await Promise.all([
  63. _converse.api.disco.supports(Strophe.NS.PUSH, push_app_server.jid),
  64. _converse.api.disco.supports(Strophe.NS.PUSH, domain)
  65. ]);
  66. if (!result[0].length && !result[1].length) {
  67. return _converse.log(
  68. `Not enabling push app server "${push_app_server.jid}", no disco support from your server.`,
  69. Strophe.LogLevel.WARN
  70. );
  71. }
  72. const stanza = $iq({'type': 'set'});
  73. if (domain !== _converse.bare_jid) {
  74. stanza.attrs({'to': domain});
  75. }
  76. stanza.c('enable', {
  77. 'xmlns': Strophe.NS.PUSH,
  78. 'jid': push_app_server.jid,
  79. 'node': push_app_server.node
  80. });
  81. if (push_app_server.secret) {
  82. stanza.c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'})
  83. .c('field', {'var': 'FORM_TYPE'})
  84. .c('value').t(`${Strophe.NS.PUBSUB}#publish-options`).up().up()
  85. .c('field', {'var': 'secret'})
  86. .c('value').t(push_app_server.secret);
  87. }
  88. return _converse.api.sendIQ(stanza);
  89. }
  90. async function enablePush (domain) {
  91. domain = domain || _converse.bare_jid;
  92. const push_enabled = _converse.session.get('push_enabled') || [];
  93. if (_.includes(push_enabled, domain)) {
  94. return;
  95. }
  96. const enabled_services = _.reject(_converse.push_app_servers, 'disable');
  97. try {
  98. await Promise.all(_.map(enabled_services, _.partial(enablePushAppServer, domain)))
  99. } catch (e) {
  100. _converse.log('Could not enable push App Server', Strophe.LogLevel.ERROR);
  101. if (e) _converse.log(e, Strophe.LogLevel.ERROR);
  102. } finally {
  103. push_enabled.push(domain);
  104. }
  105. const disabled_services = _.filter(_converse.push_app_servers, 'disable');
  106. _.each(disabled_services, _.partial(disablePushAppServer, domain));
  107. _converse.session.save('push_enabled', push_enabled);
  108. }
  109. _converse.api.listen.on('statusInitialized', () => enablePush());
  110. function onChatBoxAdded (model) {
  111. if (model.get('type') == _converse.CHATROOMS_TYPE) {
  112. enablePush(Strophe.getDomainFromJid(model.get('jid')));
  113. }
  114. }
  115. if (_converse.enable_muc_push) {
  116. _converse.api.listen.on('chatBoxesInitialized', () => _converse.chatboxes.on('add', onChatBoxAdded));
  117. }
  118. }
  119. });