diff --git a/connection_optimization/do_external_connect.js b/connection_optimization/do_external_connect.js
index 46ae83261..52af8ecb5 100644
--- a/connection_optimization/do_external_connect.js
+++ b/connection_optimization/do_external_connect.js
@@ -1,7 +1,9 @@
-/* global config,
- createConnectionExternally,
- getConfigParamsFromUrl,
- getRoomName */
+/* global config, createConnectionExternally */
+
+import {
+ getRoomName,
+ parseURLParams
+} from '../react/features/base/config/functions';
/**
* Implements external connect using createConnectionExternally function defined
@@ -15,14 +17,10 @@
* external_connect.js.
*/
-const hashParams = getConfigParamsFromUrl('hash', true);
-const searchParams = getConfigParamsFromUrl('search', true);
+const hashParams = parseURLParams(window.location, true);
// URL params have higher proirity than config params.
-let url
- = hashParams.hasOwnProperty('config.externalConnectUrl')
- ? hashParams['config.externalConnectUrl']
- : config.externalConnectUrl;
+let url = hashParams['config.externalConnectUrl'] || config.externalConnectUrl;
if (url && window.createConnectionExternally) {
const roomName = getRoomName();
@@ -30,9 +28,14 @@ if (url && window.createConnectionExternally) {
if (roomName) {
url += `?room=${roomName}`;
- const token
- = hashParams['config.token'] || config.token || searchParams.jwt;
+ let token = hashParams['config.token'] || config.token;
+ if (!token) {
+ const searchParams
+ = parseURLParams(window.location, true, 'search');
+
+ token = searchParams.jwt;
+ }
if (token) {
url += `&token=${token}`;
}
diff --git a/index.html b/index.html
index 5a7fb30b1..3884188b3 100644
--- a/index.html
+++ b/index.html
@@ -127,7 +127,6 @@
'error', loadErrHandler, true /* capture phase type of listener */);
-
diff --git a/modules/config/URLProcessor.js b/modules/config/URLProcessor.js
index d7fed1886..a9b9af912 100644
--- a/modules/config/URLProcessor.js
+++ b/modules/config/URLProcessor.js
@@ -1,13 +1,13 @@
-/* global config, getConfigParamsFromUrl, interfaceConfig, loggingConfig */
+/* global config, interfaceConfig, loggingConfig */
const logger = require("jitsi-meet-logger").getLogger(__filename);
-var configUtils = require('./Util');
-var params = {};
+import { getConfigParamsFromUrl } from '../../react/features/base/config';
-if (typeof getConfigParamsFromUrl === 'function') {
- params = getConfigParamsFromUrl();
-}
+import configUtils from './Util';
+
+// Parsing config params from URL hash.
+const URL_PARAMS = getConfigParamsFromUrl(window.location);
var URLProcessor = {
setConfigParametersFromUrl: function () {
@@ -33,7 +33,7 @@ var URLProcessor = {
interfaceConfig: {},
loggingConfig: {}
};
- for (var key in params) {
+ for (var key in URL_PARAMS) {
if (typeof key !== "string") {
logger.warn("Invalid config key: ", key);
continue;
@@ -59,7 +59,7 @@ var URLProcessor = {
if (!confObj)
continue;
- confObj[confKey] = params[key];
+ confObj[confKey] = URL_PARAMS[key];
}
configUtils.overrideConfigJSON(
config, interfaceConfig, loggingConfig, configJSON);
diff --git a/modules/tokendata/TokenData.js b/modules/tokendata/TokenData.js
index 86438937b..7b879333d 100644
--- a/modules/tokendata/TokenData.js
+++ b/modules/tokendata/TokenData.js
@@ -1,4 +1,4 @@
-/* global getConfigParamsFromUrl, config */
+/* global config */
/**
* Parses and handles JWT tokens. Sets config.token.
@@ -6,10 +6,12 @@
import * as jws from "jws";
+import { getConfigParamsFromUrl } from '../../react/features/base/config';
+
/**
* Get the JWT token from the URL.
*/
-let params = getConfigParamsFromUrl("search", true);
+let params = getConfigParamsFromUrl(window.location, true, 'search');
let jwt = params.jwt;
/**
diff --git a/react/features/base/config/functions.js b/react/features/base/config/functions.js
new file mode 100644
index 000000000..39d84b85e
--- /dev/null
+++ b/react/features/base/config/functions.js
@@ -0,0 +1,72 @@
+/* @flow */
+
+declare var config: Object;
+
+/**
+ * Builds and returns the room name.
+ *
+ * @returns {string}
+ */
+export function getRoomName(): ?string {
+ const { getroomnode } = config;
+ const path = window.location.pathname;
+ let roomName;
+
+ // Determine the room node from the URL.
+ if (getroomnode && typeof getroomnode === 'function') {
+ roomName = getroomnode.call(config, path);
+ } else {
+ // Fall back to the default strategy of making assumptions about how the
+ // URL maps to the room (name). It currently assumes a deployment in
+ // which the last non-directory component of the path (name) is the
+ // room.
+ roomName
+ = path.substring(path.lastIndexOf('/') + 1).toLowerCase()
+ || undefined;
+ }
+
+ return roomName;
+}
+
+/**
+ * Parses the parameters from the URL and returns them as a JS object.
+ *
+ * @param {string} url - URL to parse.
+ * @param {boolean} dontParse - If false or undefined some transformations
+ * (for parsing the value as JSON) are going to be executed.
+ * @param {string} source - Values - "hash"/"search" if "search" the parameters
+ * will parsed from location.search otherwise from location.hash.
+ * @returns {Object}
+ */
+export function parseURLParams(
+ url: URL,
+ dontParse: boolean = false,
+ source: string = 'hash'): Object {
+ const paramStr = source === 'search' ? url.search : url.hash;
+ const params = {};
+
+ // eslint-disable-next-line newline-per-chained-call
+ paramStr && paramStr.substr(1).split('&').forEach(part => {
+ const param = part.split('=');
+ let value;
+
+ try {
+ value = param[1];
+ if (!dontParse) {
+ value
+ = JSON.parse(
+ decodeURIComponent(param[1]).replace(/\\&/, '&'));
+ }
+ } catch (e) {
+ const msg = `Failed to parse URL parameter value: ${String(value)}`;
+
+ console.warn(msg, e);
+ window.onerror && window.onerror(msg, null, null, null, e);
+
+ return;
+ }
+ params[param[0]] = value;
+ });
+
+ return params;
+}
diff --git a/react/features/base/config/index.js b/react/features/base/config/index.js
index 81e1e72ee..03776f5f0 100644
--- a/react/features/base/config/index.js
+++ b/react/features/base/config/index.js
@@ -1,4 +1,5 @@
export * from './actions';
export * from './actionTypes';
+export * from './functions';
import './reducer';
diff --git a/static/utils.js b/static/utils.js
deleted file mode 100644
index 860f03257..000000000
--- a/static/utils.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* global config */
-
-/**
- * Defines some utility methods that are used before the other JS files are
- * loaded.
- */
-
-
-/**
- * Builds and returns the room name.
- */
-function getRoomName () { // eslint-disable-line no-unused-vars
- var getroomnode = config.getroomnode;
- var path = window.location.pathname;
- var roomName;
-
- // Determine the room node from the URL.
- if (getroomnode && typeof getroomnode === 'function') {
- // custom function might be responsible for doing the pushstate
- roomName = getroomnode.call(config, path);
- } else {
- // Fall back to the default strategy of making assumptions about how the
- // URL maps to the room (name). It currently assumes a deployment in
- // which the last non-directory component of the path (name) is the
- // room.
- roomName
- = path.substring(path.lastIndexOf('/') + 1).toLowerCase()
- || undefined;
- }
-
- return roomName;
-}
-
-/**
- * Parses the parameters from the URL and returns them as a JS object.
- * @param source {string} values - "hash"/"search" if "search" the parameters
- * will parsed from location.search otherwise from location.hash
- * @param dontParse if false or undefined some transformations
- * (for parsing the value as JSON) are going to be executed
- */
-// eslint-disable-next-line no-unused-vars
-function getConfigParamsFromUrl(source, dontParse) {
- var paramStr = (source === "search")? location.search : location.hash;
- if (!paramStr)
- return {};
- paramStr = paramStr.substr(1);
- var result = {};
- paramStr.split("&").forEach(function (part) {
- var item = part.split("=");
- var value;
- try {
- value = (dontParse)? item[1] : JSON.parse(
- decodeURIComponent(item[1]).replace(/\\&/, "&"));
- } catch (e) {
- console.warn("Failed to parse URL argument", e);
- if(window.onerror)
- window.onerror("Failed to parse URL argument", null, null,
- null, e);
- return;
- }
- result[item[0]] = value;
- });
- return result;
-}