diff --git a/CHANGES.md b/CHANGES.md index 077894eca..6d611ea36 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # Changelog ## 5.0.0 (Unreleased) +- BOSH support has been moved to a plugin. - Support for XEP-0410 to check whether we're still present in a room - Initial support for the [CredentialsContainer](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer) web API - Allow for synchronous events. When a synchronous event is fired, Converse will @@ -46,6 +47,10 @@ - `_converse.api.disco.supports` now returns a Promise which resolves to a Boolean instead of an Array. - The `forward_messages` config option (which was set to `false` by default) has been removed. Use [message_carbons](https://conversejs.org/docs/html/configuration.html#message-carbons) instead. +- Remove the `keepalive` configuration setting. It is now always implicitly `true`. +- Remove the `expose_rid_and_sid` configuration setting. +- A `prebind_url` is now mandatory when setting `authentication` to `prebind`. + It's no longer possible to pass in `rid` and `sid` values to `converse.initialize. ### API changes diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index aee51f1b3..6c178b018 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -66,6 +66,8 @@ as soon as the page loads. The server's domain is passed in via the `jid`_ setting. +.. _`prebind`: + prebind ~~~~~~~ @@ -85,25 +87,15 @@ A JID (jabber ID), SID (session ID) and RID (Request ID). Converse needs these tokens in order to attach to that same session. -There are two complementary configuration settings to ``prebind``. -They are :ref:`keepalive` and `prebind_url`_. +In addition to setting ``authentication`` to ``prebind``, you'll also need to +set the `prebind_url`_ and `bosh-service-url`_. -``keepalive`` can be used keep the session alive without having to pass in -new RID and SID tokens to ``converse.initialize`` every time you reload the page. -This removes the need to set up a new BOSH session every time a page loads. -You do however still need to supply the user's JID so that Converse can be -sure that the session it's resuming is for the right user. - -`prebind_url`_ lets you specify a URL which Converse will call whenever a -new BOSH session needs to be set up. - -Here's an example of Converse being initialized with these three options: +Here's an example of Converse being initialized with these options: .. code-block:: javascript converse.initialize({ bosh_service_url: 'https://bind.example.com', - keepalive: true, jid: 'me@example.com', authentication: 'prebind', prebind_url: 'http://example.com/api/prebind', @@ -187,8 +179,8 @@ allow_non_roster_messaging Determines whether you'll receive messages from users that are not in your roster. The XMPP specification allows for this (similar to email). -Setting this to `true` increases your chances of receiving spam (when using a -federated server), while setting it to `false` means that people not on your +Setting this to ``true`` increases your chances of receiving spam (when using a +federated server), while setting it to ``false`` means that people not on your roster can't contact you unless one (or both) of you subscribe to one another's presence (i.e. adding as a roster contact). @@ -321,13 +313,13 @@ auto_reconnect Automatically reconnect to the XMPP server if the connection drops unexpectedly. -This option works best when you have `authentication` set to `prebind` and have -also specified a `prebind_url` URL, from where Converse can fetch the BOSH +This option works best when you have ``authentication`` set to ``prebind`` and have +also specified a ``prebind_url`` URL, from where Converse can fetch the BOSH tokens. In this case, Converse will automaticallly reconnect when the connection drops but also reestablish earlier lost connections (due to network outages, closing your laptop etc.). -When `authentication` is set to `login`, then this option will only work when +When ``authentication`` is set to `login`, then this option will only work when the page hasn't been reloaded yet, because then the user's password has been wiped from memory. This configuration can however still be useful when using Converse in desktop apps, for example those based on `CEF `_ @@ -407,6 +399,7 @@ plugins from registering themselves under those names. The core, and by default whitelisted, plugins are:: + converse-bosh converse-bookmarks converse-chatboxes converse-chatview @@ -427,8 +420,9 @@ The core, and by default whitelisted, plugins are:: converse-roomslist converse-rosterview converse-singleton + converse-smacks converse-spoilers - converse-vcard' + converse-vcard Example: @@ -519,7 +513,7 @@ credentials_url * Default: ``null`` * Type: URL -This setting should be used in conjunction with ``authentication`` set to ``login`` and :ref:`keepalive` set to ``true``. +This setting should be used in conjunction with ``authentication`` set to ``login``. It allows you to specify a URL which Converse will call when it needs to get the username and password (or authentication token) which Converse will use @@ -644,18 +638,6 @@ Determines whether `XEP-0198 Stream Management `_, specifically - with regards to "stream resumption". - .. _`locales`: locales @@ -818,7 +773,7 @@ injection attack could be attempted. The variable being interpolated via the curly braces is ``locale``, which is the value passed in to the `i18n`_ setting, or the browser's locale or the -default local or `en` (resolved in that order). +default local or ``en`` (resolved in that order). From version 3.3.0, Converse no longer bundles all translations into its final build file. Instead, only the relevant translations are fetched at @@ -899,7 +854,7 @@ message_archiving_timeout The amount of time (in milliseconds) to wait when requesting archived messages from the XMPP server. -Used in conjunction with `message_archiving` and in context of `XEP-0313: Message Archive Management `_. +Used in conjunction with ``message_archiving`` and in context of `XEP-0313: Message Archive Management `_. message_carbons --------------- @@ -1037,7 +992,7 @@ The nickname will be included in presence requests to other users and will also be used as the default nickname when entering MUC chatrooms. This value will have first preference ahead of other nickname sources, such as -the VCard `nickname` value. +the VCard ``nickname`` value. notify_all_room_messages @@ -1141,7 +1096,7 @@ prebind_url See also: :ref:`session-support` -This setting should be used in conjunction with ``authentication`` set to `prebind` and :ref:`keepalive` set to ``true``. +This setting should be used in conjunction with ``authentication`` set to `prebind`. It allows you to specify a URL which Converse will call when it needs to get the RID and SID (Request ID and Session ID) tokens of a BOSH connection, which @@ -1322,7 +1277,7 @@ If set to ``true``, notifications will be shown in the following cases: * the browser is not visible nor focused and a private message is received. * the browser is not visible nor focused and a groupchat message is received which mentions you. -* `auto_subscribe` is set to `false` and a new contact request is received. +* ``auto_subscribe`` is set to ``false`` and a new contact request is received. If set to ``all``, notifications will be shown even if the above conditions are not fulfilled. @@ -1457,7 +1412,7 @@ synchronize_availability Valid options: ``true``, ``false``, ``a resource name``. This option lets you synchronize your chat status (`online`, `busy`, `away`) with other chat clients. In other words, -if you change your status to `busy` in a different chat client, your status will change to `busy` in Converse as well. +if you change your status to ``busy`` in a different chat client, your status will change to ``busy`` in Converse as well. If set to ``true``, Converse will synchronize with all other clients you are logged in with. @@ -1519,8 +1474,8 @@ time_format Examples: ``HH:mm``, ``hh:mm``, ``hh:mm a``. This option makes the time format for the time shown, for each message, configurable. Converse uses `DayJS `_ -for showing time. This option allows the configuration of the format in which `DayJS` will display the time for the messages. For detailed -description of time-format options available for `DayJS` you can check the +for showing time. This option allows the configuration of the format in which ``DayJS`` will display the time for the messages. For detailed +description of time-format options available for ``DayJS`` you can check the `default formatting options `_ and the `advanced options `_. @@ -1577,13 +1532,6 @@ techniques for bidirectional HTTP (such as `BOSH { - const authentication = _converse.authentication; - const jid = _converse.jid; - delete _converse.jid; - _converse.keepalive = true; - _converse.authentication = "prebind"; - expect(_converse.api.user.login.bind(_converse)).toThrow( - new Error( - "restoreBOSHSession: tried to restore a \"keepalive\" session "+ - "but we don't have the JID for the user!")); - _converse.authentication= authentication; - _converse.jid = jid; - _converse.keepalive = false; - done(); - })); - - it("needs jid, rid and sid values when not using keepalive", mock.initConverse((done, _converse) => { - const jid = _converse.jid; - delete _converse.jid; - _converse.keepalive = false; - _converse.authentication = "prebind"; - expect(_converse.api.user.login.bind(_converse)).toThrow( - new Error("attemptPreboundSession: If you use prebind and not keepalive, then you MUST supply JID, RID and SID values or a prebind_url.")); - _converse.bosh_service_url = undefined; - _converse.jid = jid; - done(); - })); - }); }); describe("A chat state indication", function () { @@ -219,9 +188,6 @@ test_utils.createContacts(_converse, 'current'); const old_connection = _converse.connection; _converse.connection._proto.rid = '1234'; - _converse.expose_rid_and_sid = false; - expect(_converse.api.tokens.get('rid')).toBe(null); - _converse.expose_rid_and_sid = true; expect(_converse.api.tokens.get('rid')).toBe('1234'); _converse.connection = undefined; expect(_converse.api.tokens.get('rid')).toBe(null); @@ -234,9 +200,6 @@ test_utils.createContacts(_converse, 'current'); const old_connection = _converse.connection; _converse.connection._proto.sid = '1234'; - _converse.expose_rid_and_sid = false; - expect(_converse.api.tokens.get('sid')).toBe(null); - _converse.expose_rid_and_sid = true; expect(_converse.api.tokens.get('sid')).toBe('1234'); _converse.connection = undefined; expect(_converse.api.tokens.get('sid')).toBe(null); diff --git a/src/headless/converse-bosh.js b/src/headless/converse-bosh.js new file mode 100644 index 000000000..81f5b56b7 --- /dev/null +++ b/src/headless/converse-bosh.js @@ -0,0 +1,143 @@ +// Converse.js +// http://conversejs.org +// +// Copyright (c) The Converse.js developers +// Licensed under the Mozilla Public License (MPLv2) + +/* This is a Converse.js plugin which add support for XEP-0206: XMPP Over BOSH */ + +import BrowserStorage from "backbone.browserStorage"; +import converse from "./converse-core"; + +const { Backbone, Strophe, _ } = converse.env; +const u = converse.env.utils; + + +converse.plugins.add('converse-bosh', { + + initialize () { + const { _converse } = this; + + _converse.api.settings.update({ + bosh_service_url: undefined, + prebind_url: null + }); + + + async function initBOSHSession () { + const id = 'converse.bosh-session'; + if (!_converse.bosh_session) { + _converse.bosh_session = new Backbone.Model({id}); + _converse.bosh_session.browserStorage = new BrowserStorage.session(id); + await new Promise(resolve => _converse.bosh_session.fetch({'success': resolve, 'error': resolve})); + } + if (_converse.jid && _converse.bosh_session.get('jid') === _converse.jid) { + _converse.bosh_session.clear({'silent': true }); + _converse.bosh_session.save({'jid': _converse.jid, id}); + } + return _converse.bosh_session; + } + + + _converse.startNewBOSHSession = function () { + if (!_converse.prebind_url) { + throw new Error( + "attemptPreboundSession: If you use prebind then you MUST supply a prebind_url"); + } + const xhr = new XMLHttpRequest(); + xhr.open('GET', _converse.prebind_url, true); + xhr.setRequestHeader('Accept', 'application/json, text/javascript'); + xhr.onload = function () { + if (xhr.status >= 200 && xhr.status < 400) { + const data = JSON.parse(xhr.responseText); + _converse.connection.attach( + data.jid, + data.sid, + data.rid, + _converse.onConnectStatusChanged + ); + } else { + xhr.onerror(); + } + }; + xhr.onerror = function () { + delete _converse.connection; + /** + * Triggered when fetching prebind tokens failed + * @event _converse#noResumeableBOSHSession + * @type { _converse } + * @example _converse.api.listen.on('noResumeableBOSHSession', _converse => { ... }); + */ + _converse.api.trigger('noResumeableBOSHSession', _converse); + }; + xhr.send(); + } + + + _converse.restoreBOSHSession = async function () { + if (!_converse.api.connection.isType('bosh')) { + return false; + } + const jid = (await initBOSHSession()).get('jid'); + if (jid) { + try { + _converse.connection.restore(jid, _converse.onConnectStatusChanged); + return true; + } catch (e) { + _converse.log( + "Could not restore session for jid: "+ + jid+" Error message: "+e.message, Strophe.LogLevel.WARN); + _converse.clearSession(); // We want to clear presences (see #555) + return false; + } + } + return false; + } + + + /************************ BEGIN Event Handlers ************************/ + _converse.api.listen.on('clearSession', () => { + if (!_.isUndefined(_converse.bosh_session)) { + _converse.bosh_session.destroy(); + delete _converse.bosh_session; + } + }); + + _converse.api.listen.on('setUserJID', () => { + if (!_.isUndefined(_converse.bosh_session)) { + _converse.bosh_session.save({'jid': _converse.jid}); + } + }); + /************************ END Event Handlers ************************/ + + + /************************ BEGIN API ************************/ + Object.assign(_converse.api, { + /** + * This namespace lets you access the BOSH tokens + * + * @namespace _converse.api.tokens + * @memberOf _converse.api + */ + tokens: { + /** + * @method _converse.api.tokens.get + * @param {string} [id] The type of token to return ('rid' or 'sid'). + * @returns 'string' A token, either the RID or SID token depending on what's asked for. + * @example _converse.api.tokens.get('rid'); + */ + get (id) { + if (_.isUndefined(_converse.connection)) { + return null; + } + if (id.toLowerCase() === 'rid') { + return _converse.connection.rid || _converse.connection._proto.rid; + } else if (id.toLowerCase() === 'sid') { + return _converse.connection.sid || _converse.connection._proto.sid; + } + } + } + }); + /************************ end api ************************/ + } +}); diff --git a/src/headless/converse-core.js b/src/headless/converse-core.js index a1d077f23..bc6e585ad 100644 --- a/src/headless/converse-core.js +++ b/src/headless/converse-core.js @@ -75,6 +75,7 @@ const BOSH_WAIT = 59; // the other plugins are whitelisted in src/converse.js const CORE_PLUGINS = [ 'converse-bookmarks', + 'converse-bosh', 'converse-caps', 'converse-chatboxes', 'converse-disco', @@ -205,18 +206,15 @@ _converse.default_settings = { auto_reconnect: true, auto_xa: 0, // Seconds after which user status is set to 'xa' blacklisted_plugins: [], - bosh_service_url: undefined, connection_options: {}, credentials_url: null, // URL from where login credentials can be fetched csi_waiting_time: 0, // Support for XEP-0352. Seconds before client is considered idle and CSI is sent out. debug: false, default_state: 'online', - expose_rid_and_sid: false, geouri_regex: /https:\/\/www.openstreetmap.org\/.*#map=[0-9]+\/([\-0-9.]+)\/([\-0-9.]+)\S*/g, geouri_replacement: 'https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2', idle_presence_timeout: 300, // Seconds after which an idle presence is sent jid: undefined, - keepalive: true, locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json', locales: [ 'af', 'ar', 'bg', 'ca', 'cs', 'de', 'eo', 'es', 'eu', 'en', 'fr', 'gl', @@ -226,7 +224,6 @@ _converse.default_settings = { message_carbons: true, nickname: undefined, password: undefined, - prebind_url: null, priority: 0, rid: undefined, root: window.document, @@ -443,32 +440,14 @@ const debouncedReconnect = _.debounce(reconnect, 2000); function clearSession () { - if (!_.isUndefined(_converse.bosh_session)) { - _converse.bosh_session.destroy(); - delete _converse.bosh_session; - } if (!_.isUndefined(_converse.session)) { _converse.session.destroy(); delete _converse.session; } - // TODO: Refactor so that we don't clear if (!_converse.config.get('trusted') || isTestEnv()) { window.localStorage.clear(); window.sessionStorage.clear(); - } else { - if (!_.isUndefined(_converse.bosh_session)) { - _converse.bosh_session.destroy(); - delete _converse.bosh_session; - } - if (!_.isUndefined(_converse.session)) { - _converse.session.destroy(); - delete _converse.session; - } - _.get(_converse, 'bosh_session.browserStorage', { - _clear: _.noop - })._clear(); - _.get(_converse, 'session.browserStorage', { _clear: _.noop })._clear(); } /** * Triggered once the session information has been cleared, @@ -479,6 +458,7 @@ function clearSession () { _converse.api.trigger('clearSession'); } + _converse.initConnection = function () { /* Creates a new Strophe.Connection instance if we don't already have one. */ @@ -494,7 +474,11 @@ _converse.initConnection = function () { } else if (_converse.bosh_service_url) { _converse.connection = new Strophe.Connection( _converse.bosh_service_url, - Object.assign(_converse.default_connection_options, _converse.connection_options, {'keepalive': _converse.keepalive}) + Object.assign( + _converse.default_connection_options, + _converse.connection_options, + {'keepalive': true} + ) ); } else { throw new Error("initConnection: this browser does not support websockets and bosh_service_url wasn't specified."); @@ -510,29 +494,6 @@ _converse.initConnection = function () { _converse.api.trigger('connectionInitialized'); }; -async function initBOSHSession () { - const id = 'converse.bosh-session'; - _converse.bosh_session = new Backbone.Model({id}); - _converse.bosh_session.browserStorage = new BrowserStorage.session(id); - try { - await new Promise((success, error) => _converse.bosh_session.fetch({ success, error })); - if (_converse.jid && !u.isSameBareJID(_converse.bosh_session.get('jid'), _converse.jid)) { - _converse.bosh_session.clear({ silent: true }); - _converse.bosh_session.save({ jid: _converse.jid, id }); - } - } catch (e) { - if (_converse.jid) { - _converse.bosh_session.save({ jid: _converse.jid }); - } - } - /** - * Triggered once the session has been initialized. The session is a - * persistent object which stores session information in the browser storage. - * @event _converse#BOSHSessionInitialized - * @memberOf _converse - */ - _converse.api.trigger('BOSHSessionInitialized'); -} async function initUserSession (jid) { const bare_jid = Strophe.getBareJidFromJid(jid); @@ -567,6 +528,11 @@ function setUserJID (jid) { 'resource': _converse.resource, 'domain': _converse.domain }); + /** + * Triggered whenever the user's JID has been updated + * @event _converse#setUserJID + */ + _converse.api.trigger('setUserJID'); } @@ -604,11 +570,10 @@ function setUpXMLLogging () { } -async function finishInitialization () { +function finishInitialization () { initClientConfig(); initPlugins(); _converse.initConnection(); - await initBOSHSession(); _converse.api.user.login(); _converse.registerGlobalEventHandlers(); if (!Backbone.history.started) { @@ -735,9 +700,8 @@ _converse.initialize = async function (settings, callback) { /* When reloading the page: * For new sessions, we need to send out a presence stanza to notify * the server/network that we're online. - * When re-attaching to an existing session (e.g. via the keepalive - * option), we don't need to again send out a presence stanza, because - * it's as if "we never left" (see onConnectStatusChanged). + * When re-attaching to an existing session we don't need to again send out a presence stanza, + * because it's as if "we never left" (see onConnectStatusChanged). * https://github.com/jcbrand/converse.js/issues/521 */ this.send_initial_presence = true; @@ -1243,106 +1207,8 @@ _converse.initialize = async function (settings, callback) { }); - this.startNewBOSHSession = function () { - const xhr = new XMLHttpRequest(); - xhr.open('GET', _converse.prebind_url, true); - xhr.setRequestHeader('Accept', 'application/json, text/javascript'); - xhr.onload = function () { - if (xhr.status >= 200 && xhr.status < 400) { - const data = JSON.parse(xhr.responseText); - _converse.connection.attach( - data.jid, - data.sid, - data.rid, - _converse.onConnectStatusChanged - ); - } else { - xhr.onerror(); - } - }; - xhr.onerror = function () { - delete _converse.connection; - /** - * Triggered when keepalive=true but there aren't any stored prebind tokens. - * @event _converse#noResumeableSession - * @type { _converse } - * @example _converse.api.listen.on('noResumeableSession', _converse => { ... }); - */ - _converse.api.trigger('noResumeableSession', this); - }; - xhr.send(); - }; - - this.restoreBOSHSession = function (jid_is_required) { - if (!_converse.api.connection.isType('bosh')) { - return false; - } - /* Tries to restore a cached BOSH session. */ - const jid = _converse.bosh_session.get('jid'); - if (!jid) { - const msg = "restoreBOSHSession: tried to restore a \"keepalive\" session "+ - "but we don't have the JID for the user!"; - if (jid_is_required) { - throw new Error(msg); - } else { - _converse.log(msg); - return false; - } - } else { - try { - this.connection.restore(jid, this.onConnectStatusChanged); - return true; - } catch (e) { - _converse.log( - "Could not restore session for jid: "+ - jid+" Error message: "+e.message, Strophe.LogLevel.WARN); - clearSession(); // We want to clear presences (see #555) - return false; - } - } - }; - - this.attemptPreboundSession = function (reconnecting) { - /* Handle session resumption or initialization when prebind is - * being used. - */ - if (!reconnecting) { - if (this.keepalive && this.restoreBOSHSession(true)) { - return; - } - // No keepalive, or session resumption has failed. - if (this.jid && this.sid && this.rid) { - return this.connection.attach( - this.jid, - this.sid, - this.rid, - this.onConnectStatusChanged - ); - } - } - if (this.prebind_url) { - return this.startNewBOSHSession(); - } else { - throw new Error( - "attemptPreboundSession: If you use prebind and not keepalive, "+ - "then you MUST supply JID, RID and SID values or a prebind_url."); - } - }; - this.attemptNonPreboundSession = async function (credentials, reconnecting) { - /* Handle session resumption or initialization when prebind is not being used. - * - * Two potential options exist and are handled in this method: - * 1. keepalive - * 2. auto_login - */ - if (!reconnecting && this.keepalive && this.restoreBOSHSession()) { - return; - } - if (credentials) { - // When credentials are passed in, they override prebinding - // or credentials fetching via HTTP this.autoLogin(credentials); } else if (this.auto_login) { if (this.credentials_url) { @@ -1577,28 +1443,25 @@ _converse.api = { * @param {string} [jid] * @param {string} [password] * @param {boolean} [reconnecting] - * @example - * converse.plugins.add('myplugin', { - * initialize: function () { - * this._converse.api.user.login('romeo@montague.lit', 'secret'); - * } - * }); */ - login (jid, password, reconnecting) { - if (_converse.authentication === _converse.PREBIND) { - _converse.attemptPreboundSession(reconnecting); - } else { - let credentials; - if (jid && password) { - credentials = { jid: jid, password: password }; - } else if (u.isValidJID(_converse.jid) && _converse.password) { - credentials = { jid: _converse.jid, password: _converse.password }; + async login (jid, password, reconnecting) { + if (_converse.api.connection.isType('bosh')) { + if (reconnecting && _converse.prebind_url) { + return _converse.startNewBOSHSession(); + } else if (await _converse.restoreBOSHSession()) { + return; } - if (credentials && credentials.jid) { - setUserJID(credentials.jid); - } - _converse.attemptNonPreboundSession(credentials, reconnecting); } + let credentials; + if (jid && password) { + credentials = { jid: jid, password: password }; + } else if (u.isValidJID(_converse.jid) && _converse.password) { + credentials = { jid: _converse.jid, password: _converse.password }; + } + if (credentials && credentials.jid) { + setUserJID(credentials.jid); + } + _converse.attemptNonPreboundSession(credentials, reconnecting); }, /** @@ -1810,31 +1673,6 @@ _converse.api = { } }, - /** - * This namespace lets you access the BOSH tokens - * - * @namespace _converse.api.tokens - * @memberOf _converse.api - */ - tokens: { - /** - * @method _converse.api.tokens.get - * @param {string} [id] The type of token to return ('rid' or 'sid'). - * @returns 'string' A token, either the RID or SID token depending on what's asked for. - * @example _converse.api.tokens.get('rid'); - */ - get (id) { - if (!_converse.expose_rid_and_sid || _.isUndefined(_converse.connection)) { - return null; - } - if (id.toLowerCase() === 'rid') { - return _converse.connection.rid || _converse.connection._proto.rid; - } else if (id.toLowerCase() === 'sid') { - return _converse.connection.sid || _converse.connection._proto.sid; - } - } - }, - /** * Converse emits events to which you can subscribe to. * @@ -1986,9 +1824,7 @@ const converse = { * bosh_service_url: 'https://bind.example.com', * hide_muc_server: false, * i18n: locales['en'], - * keepalive: true, * play_sounds: true, - * prebind: false, * show_controlbox_by_default: true, * debug: false, * roster_groups: true diff --git a/src/headless/converse-smacks.js b/src/headless/converse-smacks.js index 94c0392d4..5478baa9a 100644 --- a/src/headless/converse-smacks.js +++ b/src/headless/converse-smacks.js @@ -192,7 +192,7 @@ converse.plugins.add('converse-smacks', { _converse.connection.addHandler(sendAck, Strophe.NS.SM, 'r'); _converse.connection.addHandler(handleAck, Strophe.NS.SM, 'a'); - if (_converse.connection._proto instanceof Strophe.Bosh && + if (_converse.api.connection.isType('bosh') && _converse.connfeedback.get('connection_status') === Strophe.Status.ATTACHED) { // No need to continue further when we have an existing BOSH session, // since our existing session still exists server-side. diff --git a/src/headless/headless.js b/src/headless/headless.js index aeba5705b..4417735ee 100644 --- a/src/headless/headless.js +++ b/src/headless/headless.js @@ -3,6 +3,7 @@ * Any of the following components may be removed if they're not needed. */ import "./converse-bookmarks"; // XEP-0199 XMPP Ping +import "./converse-bosh"; // XEP-0115 Entity Capabilities import "./converse-caps"; // XEP-0115 Entity Capabilities import "./converse-chatboxes"; // Backbone Collection and Models for chat boxes import "./converse-disco"; // XEP-0030 Service discovery diff --git a/src/headless/utils/core.js b/src/headless/utils/core.js index 0ded3eabd..bb404abca 100644 --- a/src/headless/utils/core.js +++ b/src/headless/utils/core.js @@ -87,6 +87,9 @@ u.isValidMUCJID = function (jid) { }; u.isSameBareJID = function (jid1, jid2) { + if (!_.isString(jid1) || !_.isString(jid2)) { + return false; + } return Strophe.getBareJidFromJid(jid1).toLowerCase() === Strophe.getBareJidFromJid(jid2).toLowerCase(); };