Move BOSH code into a plugin
- 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.
This commit is contained in:
parent
01fce55733
commit
38a232fd45
@ -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
|
||||
|
||||
|
@ -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 <https://bitbucket.org/chromiumembedded/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 <https://xmpp.org/extensions/xep-
|
||||
support is turned on or not.
|
||||
|
||||
|
||||
expose_rid_and_sid
|
||||
------------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
|
||||
globally via the API. This allows other scripts served on the same page to use
|
||||
these values.
|
||||
|
||||
*Beware*: a malicious script could use these tokens to assume your identity
|
||||
and inject fake chat messages.
|
||||
|
||||
filter_by_resource
|
||||
------------------
|
||||
|
||||
@ -744,37 +726,10 @@ The Jabber ID or "JID" of the current user. The JID uniquely identifies a user
|
||||
on the XMPP network. It looks like an email address, but it's used for instant
|
||||
messaging instead.
|
||||
|
||||
This value needs to be provided when using the :ref:`keepalive` option together
|
||||
with `prebind`_.
|
||||
This value may be provided together with a ``password`` instead of supplying a
|
||||
`credentials_url`_ when setting ``auto_login`` to ``true``.
|
||||
|
||||
|
||||
.. _`keepalive`:
|
||||
|
||||
keepalive
|
||||
---------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
Determines whether Converse will maintain the chat session across page
|
||||
loads.
|
||||
|
||||
This setting should also be used in conjunction with ``authentication`` set to `prebind`_.
|
||||
|
||||
When using ``keepalive`` and ``prebind``, you will have to provide the `jid`_
|
||||
of the current user to ensure that a cached session is only resumed if it
|
||||
belongs to the current user.
|
||||
|
||||
See also:
|
||||
|
||||
* :ref:`session-support`
|
||||
|
||||
.. note::
|
||||
Currently the "keepalive" setting only works with BOSH and not with
|
||||
websockets. This is because XMPP over websocket does not use the same
|
||||
session token as with BOSH. A possible solution for this is to implement
|
||||
`XEP-0198 <https://xmpp.org/extensions/xep-0198.html>`_, 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 <https://xmpp.org/extensions/xep-0313.html>`_.
|
||||
Used in conjunction with ``message_archiving`` and in context of `XEP-0313: Message Archive Management <https://xmpp.org/extensions/xep-0313.html>`_.
|
||||
|
||||
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 <https://github.com/iamkun/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 <https://github.com/iamkun/dayjs/blob/dev/docs/en/API-reference.md#displaying>`_ and the
|
||||
`advanced options <https://github.com/iamkun/dayjs/blob/master/docs/en/Plugin.md#advancedformat>`_.
|
||||
|
||||
@ -1577,13 +1532,6 @@ techniques for bidirectional HTTP (such as `BOSH <https://en.wikipedia.org/wiki/
|
||||
Please refer to your XMPP server's documentation on how to enable websocket
|
||||
support.
|
||||
|
||||
.. note::
|
||||
Please note that not older browsers do not support websockets. For older
|
||||
browsers you'll want to specify a BOSH URL. See the :ref:`bosh-service-url`
|
||||
configuration setting).
|
||||
|
||||
.. note::
|
||||
Converse does not yet support "keepalive" with websockets.
|
||||
|
||||
.. _`view_mode`:
|
||||
|
||||
|
@ -116,7 +116,6 @@ your components, for example:
|
||||
'auto_reconnect': true,
|
||||
'bosh_service_url': bosh_url,
|
||||
'jid': bare_jid,
|
||||
'keepalive': true,
|
||||
'credentials_url': credentials_url,
|
||||
'whitelisted_plugins': ['conversejs-angular-service']
|
||||
});
|
||||
|
@ -29,8 +29,7 @@ The diagram below shows a fairly common setup for a website or intranet:
|
||||
|
||||
* It communicates with the XMPP server via BOSH or websocket which is usually
|
||||
reverse-proxied by a web-server in order to overcome cross-site scripting
|
||||
restrictions in the browser. For more info on that, read the section:
|
||||
`Overcoming cross-domain request restrictions`_
|
||||
restrictions in the browser.
|
||||
|
||||
* Optionally the XMPP server is configured to use a SQL database for storing
|
||||
archived chat messages.
|
||||
@ -293,8 +292,7 @@ Single Session Support
|
||||
It's possible to enable shared sessions whereby users already
|
||||
logged in to your website will also automatically be logged in on the XMPP server,
|
||||
|
||||
Once a user is logged in, the session will be kept alive across page loads by
|
||||
way of the :ref:`keepalive` setting.
|
||||
Once a user is logged in, the session will be kept alive across page loads.
|
||||
|
||||
There are a few ways to let your users be automatically authenticated to an
|
||||
XMPP server once they've logged in to your site.
|
||||
@ -364,8 +362,7 @@ page load). Each page load is a new request which requires a new unique RID.
|
||||
The best way to achieve this is to simply increment the RID with each page
|
||||
load.
|
||||
|
||||
You'll need to configure Converse with the ``prebind``, :ref:`keepalive` and
|
||||
:ref:`prebind_url` settings.
|
||||
You'll need to configure Converse with the :ref:`prebind` :ref:`prebind_url` settings.
|
||||
|
||||
Please read the documentation on those settings for a fuller picture of what
|
||||
needs to be done.
|
||||
|
@ -23,37 +23,6 @@
|
||||
_converse.connection = connection;
|
||||
done();
|
||||
}));
|
||||
|
||||
describe("with prebind", function () {
|
||||
|
||||
it("needs a jid when also using keepalive", mock.initConverse([], null, {'auto_login': false}, (done, _converse) => {
|
||||
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);
|
||||
|
143
src/headless/converse-bosh.js
Normal file
143
src/headless/converse-bosh.js
Normal file
@ -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 ************************/
|
||||
}
|
||||
});
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user