Browse Source

Move BOSH plugin into its own folder

JC Brand 1 year ago
parent
commit
a037fdd434

+ 1 - 1
src/headless/index.js

@@ -17,7 +17,7 @@ dayjs.extend(advancedFormat);
  */
 
 import "./plugins/bookmarks/index.js";  // XEP-0199 XMPP Ping
-import "./plugins/bosh.js";             // XEP-0206 BOSH
+import "./plugins/bosh/index.js";             // XEP-0206 BOSH
 import "./plugins/caps/index.js";       // XEP-0115 Entity Capabilities
 import "./plugins/chat/index.js";       // RFC-6121 Instant messaging
 import "./plugins/chatboxes/index.js";

+ 0 - 189
src/headless/plugins/bosh.js

@@ -1,189 +0,0 @@
-/**
- * @copyright The Converse.js contributors
- * @license Mozilla Public License (MPLv2)
- * @description Converse.js plugin which add support for XEP-0206: XMPP Over BOSH
- *
- * @typedef {module:shared.api.user} LoginHookPayload
- */
-import 'strophe.js/src/bosh';
-import _converse from '../shared/_converse.js';
-import api, { converse } from '../shared/api/index.js';
-import log from "../log.js";
-import { BOSH_WAIT, PREBIND } from '../shared/constants.js';
-import { Model } from '@converse/skeletor';
-import { setUserJID, } from '../utils/init.js';
-import { isTestEnv } from '../utils/session.js';
-import { createStore } from '../utils/storage.js';
-
-const { Strophe } = converse.env;
-
-const BOSH_SESSION_ID = 'converse.bosh-session';
-
-let bosh_session;
-
-
-converse.plugins.add('converse-bosh', {
-
-    enabled () {
-        return !_converse.api.settings.get("blacklisted_plugins").includes('converse-bosh');
-    },
-
-    initialize () {
-        api.settings.extend({
-            bosh_service_url: undefined,
-            prebind_url: null
-        });
-
-
-        async function initBOSHSession () {
-            const id = BOSH_SESSION_ID;
-            if (!bosh_session) {
-                bosh_session = new Model({id});
-                bosh_session.browserStorage = createStore(id, "session");
-                await new Promise(resolve => bosh_session.fetch({'success': resolve, 'error': resolve}));
-            }
-
-            let jid = _converse.session.get('jid');
-            if (jid) {
-                if (bosh_session.get('jid') !== jid) {
-                    jid = await setUserJID(jid);
-                    bosh_session.clear({'silent': true });
-                    bosh_session.save({jid});
-                }
-            } else { // Keepalive
-                const jid = bosh_session.get('jid');
-                jid && await setUserJID(jid);
-            }
-            return bosh_session;
-        }
-
-
-        function startNewPreboundBOSHSession () {
-            if (!api.settings.get('prebind_url')) {
-                throw new Error("startNewPreboundBOSHSession: If you use prebind then you MUST supply a prebind_url");
-            }
-            const connection = api.connection.get();
-            const xhr = new XMLHttpRequest();
-            xhr.open('GET', api.settings.get('prebind_url'), true);
-            xhr.setRequestHeader('Accept', 'application/json, text/javascript');
-            xhr.onload = async function (event) {
-                if (xhr.status >= 200 && xhr.status < 400) {
-                    const data = JSON.parse(xhr.responseText);
-                    const jid = await setUserJID(data.jid);
-                    connection.attach(
-                        jid,
-                        data.sid,
-                        data.rid,
-                        connection.onConnectStatusChanged,
-                        BOSH_WAIT
-                    );
-                } else {
-                    xhr.onerror(event);
-                }
-            };
-            xhr.onerror = function () {
-                api.connection.destroy();
-                /**
-                 * Triggered when fetching prebind tokens failed
-                 * @event _converse#noResumeableBOSHSession
-                 * @type { _converse }
-                 * @example _converse.api.listen.on('noResumeableBOSHSession', _converse => { ... });
-                 */
-                api.trigger('noResumeableBOSHSession', _converse);
-            };
-            xhr.send();
-        }
-
-
-        async function restoreBOSHSession () {
-            const jid = (await initBOSHSession()).get('jid');
-            const connection = api.connection.get();
-            if (jid && (connection._proto instanceof Strophe.Bosh)) {
-                try {
-                    connection.restore(jid, connection.onConnectStatusChanged);
-                    return true;
-                } catch (e) {
-                    !isTestEnv() && log.warn("Could not restore session for jid: "+jid+" Error message: "+e.message);
-                    return false;
-                }
-            }
-            return false;
-        }
-
-
-        /************************ BEGIN Event Handlers ************************/
-        api.listen.on('clearSession', () => {
-            if (bosh_session === undefined) {
-                // Remove manually, even if we don't have the corresponding
-                // model, to avoid trying to reconnect to a stale BOSH session
-                const id = BOSH_SESSION_ID;
-                sessionStorage.removeItem(id);
-                sessionStorage.removeItem(`${id}-${id}`);
-            } else {
-                bosh_session.destroy();
-                bosh_session = undefined;
-            }
-        });
-
-        api.listen.on('setUserJID', () => {
-            if (bosh_session !== undefined) {
-                bosh_session.save({'jid': _converse.session.get('jid')});
-            }
-        });
-
-        api.listen.on('login',
-            /**
-             * @param {unknown} _
-             * @param {LoginHookPayload} payload
-             */
-            async (_, payload) => {
-                if (payload.success) return payload;
-
-                const { automatic } = payload;
-                // See whether there is a BOSH session to re-attach to
-                if (await restoreBOSHSession()) {
-                    return { ...payload, success: true };
-                } else if (api.settings.get("authentication") === PREBIND && (!automatic || api.settings.get("auto_login"))) {
-                    startNewPreboundBOSHSession();
-                    return { ...payload, success: true };
-                }
-                return payload;
-            }
-        );
-
-        api.listen.on('addClientFeatures', () => api.disco.own.features.add(Strophe.NS.BOSH));
-
-        /************************ END Event Handlers ************************/
-
-
-        /************************ BEGIN API ************************/
-        Object.assign(api, {
-            /**
-             * This namespace lets you access the BOSH tokens
-             *
-             * @namespace api.tokens
-             * @memberOf api
-             */
-            tokens: {
-                /**
-                 * @method 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) {
-                    const connection = api.connection.get();
-                    if (!connection) {
-                        return null;
-                    }
-                    if (id.toLowerCase() === 'rid') {
-                        return connection.rid || connection._proto.rid;
-                    } else if (id.toLowerCase() === 'sid') {
-                        return connection.sid || connection._proto.sid;
-                    }
-                }
-            }
-        });
-        /************************ end api ************************/
-    }
-});

+ 28 - 0
src/headless/plugins/bosh/api.js

@@ -0,0 +1,28 @@
+import api from '../../shared/api/index.js';
+
+export default {
+    /**
+     * This API namespace lets you access the BOSH tokens
+     * @namespace api.tokens
+     * @memberOf api
+     */
+    tokens: {
+        /**
+         * @method 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) {
+            const connection = api.connection.get();
+            if (!connection) return null;
+
+            if (id.toLowerCase() === 'rid') {
+                return connection.rid || connection._proto.rid;
+            } else if (id.toLowerCase() === 'sid') {
+                return connection.sid || connection._proto.sid;
+            }
+        }
+    }
+
+};

+ 35 - 0
src/headless/plugins/bosh/index.js

@@ -0,0 +1,35 @@
+/**
+ * @copyright The Converse.js contributors
+ * @license Mozilla Public License (MPLv2)
+ * @description Converse.js plugin which add support for XEP-0206: XMPP Over BOSH
+ */
+import 'strophe.js/src/bosh';
+import { Strophe } from "strophe.js";
+import _converse from '../../shared/_converse.js';
+import api, { converse } from '../../shared/api/index.js';
+import bosh_api from './api.js';
+import { attemptPrebind, clearSession, saveJIDToSession} from './utils.js';
+
+
+converse.plugins.add('converse-bosh', {
+
+    enabled () {
+        return !_converse.api.settings.get("blacklisted_plugins").includes('converse-bosh');
+    },
+
+    initialize () {
+        api.settings.extend({
+            bosh_service_url: undefined,
+            prebind_url: null
+        });
+
+        Object.assign(api, bosh_api);
+
+        api.listen.on('clearSession', clearSession);
+        api.listen.on('setUserJID', saveJIDToSession);
+        api.listen.on('login', attemptPrebind);
+        api.listen.on('addClientFeatures',
+            () => api.disco.own.features.add(Strophe.NS.BOSH)
+        );
+    }
+});

+ 128 - 0
src/headless/plugins/bosh/utils.js

@@ -0,0 +1,128 @@
+/**
+ * @typedef {module:shared.api.user} LoginHookPayload
+ */
+import log from "../../log.js";
+import api from '../../shared/api/index.js';
+import _converse from "../../shared/_converse.js";
+import { Strophe } from "strophe.js";
+import { Model } from '@converse/skeletor';
+import { createStore } from '../../utils/storage.js';
+import { isTestEnv } from '../../utils/session.js';
+import { setUserJID, } from '../../utils/init.js';
+import { BOSH_WAIT, PREBIND } from '../../shared/constants.js';
+
+const BOSH_SESSION_ID = 'converse.bosh-session';
+
+let bosh_session;
+
+async function initBOSHSession () {
+    const id = BOSH_SESSION_ID;
+    if (!bosh_session) {
+        bosh_session = new Model({id});
+        bosh_session.browserStorage = createStore(id, "session");
+        await new Promise(resolve => bosh_session.fetch({'success': resolve, 'error': resolve}));
+    }
+
+    let jid = _converse.session.get('jid');
+    if (jid) {
+        if (bosh_session.get('jid') !== jid) {
+            jid = await setUserJID(jid);
+            bosh_session.clear({'silent': true });
+            bosh_session.save({jid});
+        }
+    } else { // Keepalive
+        const jid = bosh_session.get('jid');
+        jid && await setUserJID(jid);
+    }
+    return bosh_session;
+}
+
+
+export function startNewPreboundBOSHSession () {
+    if (!api.settings.get('prebind_url')) {
+        throw new Error("startNewPreboundBOSHSession: If you use prebind then you MUST supply a prebind_url");
+    }
+    const connection = api.connection.get();
+    const xhr = new XMLHttpRequest();
+    xhr.open('GET', api.settings.get('prebind_url'), true);
+    xhr.setRequestHeader('Accept', 'application/json, text/javascript');
+    xhr.onload = async function (event) {
+        if (xhr.status >= 200 && xhr.status < 400) {
+            const data = JSON.parse(xhr.responseText);
+            const jid = await setUserJID(data.jid);
+            connection.attach(
+                jid,
+                data.sid,
+                data.rid,
+                connection.onConnectStatusChanged,
+                BOSH_WAIT
+            );
+        } else {
+            xhr.onerror(event);
+        }
+    };
+    xhr.onerror = function () {
+        api.connection.destroy();
+        /**
+         * Triggered when fetching prebind tokens failed
+         * @event _converse#noResumeableBOSHSession
+         * @type { _converse }
+         * @example _converse.api.listen.on('noResumeableBOSHSession', _converse => { ... });
+         */
+        api.trigger('noResumeableBOSHSession', _converse);
+    };
+    xhr.send();
+}
+
+/**
+ * @param {unknown} _
+ * @param {LoginHookPayload} payload
+ */
+export async function attemptPrebind (_, payload) {
+    if (payload.success) return payload;
+
+    const { automatic } = payload;
+    // See whether there is a BOSH session to re-attach to
+    if (await restoreBOSHSession()) {
+        return { ...payload, success: true };
+    } else if (api.settings.get("authentication") === PREBIND && (!automatic || api.settings.get("auto_login"))) {
+        startNewPreboundBOSHSession();
+        return { ...payload, success: true };
+    }
+    return payload;
+}
+
+export function saveJIDToSession() {
+    if (bosh_session !== undefined) {
+        bosh_session.save({'jid': _converse.session.get('jid')});
+    }
+}
+
+export function clearSession () {
+    if (bosh_session === undefined) {
+        // Remove manually, even if we don't have the corresponding
+        // model, to avoid trying to reconnect to a stale BOSH session
+        const id = BOSH_SESSION_ID;
+        sessionStorage.removeItem(id);
+        sessionStorage.removeItem(`${id}-${id}`);
+    } else {
+        bosh_session.destroy();
+        bosh_session = undefined;
+    }
+}
+
+
+export async function restoreBOSHSession () {
+    const jid = (await initBOSHSession()).get('jid');
+    const connection = api.connection.get();
+    if (jid && (connection._proto instanceof Strophe.Bosh)) {
+        try {
+            connection.restore(jid, connection.onConnectStatusChanged);
+            return true;
+        } catch (e) {
+            !isTestEnv() && log.warn("Could not restore session for jid: "+jid+" Error message: "+e.message);
+            return false;
+        }
+    }
+    return false;
+}