From e28b847fb06a0d423d625aa595e2f9acf0d1442e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BC=D1=8F=D0=BD=20=D0=9C=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Tue, 12 Dec 2017 13:16:55 -0600 Subject: [PATCH] Updates config feature and whitelists options that can be overridden. (#2282) * Removes unused config logic. * Whitelists config options that can be overridden using the URL. * Recorder login with credentials, not supported by externalconnect. Jibri uses xmpp credentials to login, which is not supported by externalconnect, so we want to skip it till that is supported. * Whitelist only config.js * Extracts whitelisting in separate function. --- config.js | 51 ++++++ .../do_external_connect.js | 7 +- package.json | 1 - react/features/base/config/functions.js | 167 +++++++++++------- react/features/conference/route.js | 3 +- 5 files changed, 157 insertions(+), 72 deletions(-) diff --git a/config.js b/config.js index 4fa3c85e8..e6f31aef7 100644 --- a/config.js +++ b/config.js @@ -317,6 +317,57 @@ var config = { // region: "europe", // userRegion: "asia" } + + // List of undocumented settings used in jitsi-meet + /** + alwaysVisibleToolbar + analyticsScriptUrls + autoEnableDesktopSharing + autoRecord + autoRecordToken + debug + debugAudioLevels + deploymentInfo + dialInConfCodeUrl + dialInNumbersUrl + dialOutAuthUrl + dialOutCodesUrl + disableRemoteControl + displayJids + enableLocalVideoFlip + etherpad_base + externalConnectUrl + firefox_fake_device + iAmRecorder + iAmSipGateway + peopleSearchQueryTypes + peopleSearchUrl + requireDisplayName + tokenAuthUrl + */ + + // List of undocumented settings used in lib-jitsi-meet + /** + _peerConnStatusOutOfLastNTimeout + _peerConnStatusRtcMuteTimeout + abTesting + avgRtpStatsN + callStatsConfIDNamespace + callStatsCustomScriptUrl + desktopSharingSources + disableAEC + disableAGC + disableAP + disableHPF + disableNS + enableLipSync + enableTalkWhileMuted + forceJVB121Ratio + hiddenDomain + ignoreStartMuted + nick + startBitrate + */ }; /* eslint-enable no-unused-vars, no-var */ diff --git a/connection_optimization/do_external_connect.js b/connection_optimization/do_external_connect.js index 2ce15f02d..2c46f93e6 100644 --- a/connection_optimization/do_external_connect.js +++ b/connection_optimization/do_external_connect.js @@ -16,14 +16,17 @@ import parseURLParams from '../react/features/base/config/parseURLParams'; */ if (typeof createConnectionExternally === 'function') { - // URL params have higher proirity than config params. + // URL params have higher priority than config params. let url = parseURLParams(window.location, true, 'hash')[ 'config.externalConnectUrl'] || config.externalConnectUrl; + const isRecorder + = parseURLParams(window.location, true, 'hash')['config.iAmRecorder']; + let roomName; - if (url && (roomName = getRoomName())) { + if (url && (roomName = getRoomName()) && !isRecorder) { url += `?room=${roomName}`; const token = parseURLParams(window.location, true, 'search').jwt; diff --git a/package.json b/package.json index 29fc2a600..8d06394fa 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "jquery-contextmenu": "2.4.5", "jquery-i18next": "1.2.0", "js-md5": "0.6.1", - "jssha": "2.2.0", "jwt-decode": "2.2.0", "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#81f57c024e137879d6c93bef62308971d0ec71b0", "lodash": "4.17.4", diff --git a/react/features/base/config/functions.js b/react/features/base/config/functions.js index 983f2083b..847adfce7 100644 --- a/react/features/base/config/functions.js +++ b/react/features/base/config/functions.js @@ -1,6 +1,5 @@ /* @flow */ -import JSSHA from 'jssha'; import _ from 'lodash'; import parseURLParams from './parseURLParams'; @@ -8,15 +7,87 @@ import parseURLParams from './parseURLParams'; declare var $: Object; /** - * The config keys to ignore because, for example, their values identify scripts - * and it is not desireable to inject these through URL params. + * The config keys to whitelist, the keys that can be overridden. + * Currently we can only whitelist the first part of the properties, like + * 'p2p.useStunTurn' and 'p2p.enabled' we whitelist all p2p options. + * The whitelist is used only for config.js. * * @private * @type Array */ -const _KEYS_TO_IGNORE = [ - 'analyticsScriptUrls', - 'callStatsCustomScriptUrl' +const WHITELISTED_KEYS = [ + '_peerConnStatusOutOfLastNTimeout', + '_peerConnStatusRtcMuteTimeout', + 'abTesting', + 'alwaysVisibleToolbar', + 'autoEnableDesktopSharing', + 'autoRecord', + 'autoRecordToken', + 'avgRtpStatsN', + 'callStatsConfIDNamespace', + 'callStatsID', + 'callStatsSecret', + 'channelLastN', + 'constraints', + 'debug', + 'debugAudioLevels', + 'defaultLanguage', + 'desktopSharingChromeDisabled', + 'desktopSharingChromeExtId', + 'desktopSharingChromeMinExtVersion', + 'desktopSharingChromeSources', + 'desktopSharingFirefoxDisabled', + 'desktopSharingSources', + 'disable1On1Mode', + 'disableAEC', + 'disableAGC', + 'disableAP', + 'disableAudioLevels', + 'disableDesktopSharing', + 'disableDesktopSharing', + 'disableH264', + 'disableHPF', + 'disableNS', + 'disableRemoteControl', + 'disableRtx', + 'disableSuspendVideo', + 'displayJids', + 'enableDisplayNameInStats', + 'enableLipSync', + 'enableLocalVideoFlip', + 'enableRecording', + 'enableStatsID', + 'enableTalkWhileMuted', + 'enableUserRolesBasedOnToken', + 'etherpad_base', + 'failICE', + 'firefox_fake_device', + 'forceJVB121Ratio', + 'hiddenDomain', + 'hosts', + 'iAmRecorder', + 'iAmSipGateway', + 'ignoreStartMuted', + 'nick', + 'openBridgeChannel', + 'p2p', + 'preferH264', + 'recordingType', + 'requireDisplayName', + 'resolution', + 'startAudioMuted', + 'startAudioOnly', + 'startBitrate', + 'startScreenSharing', + 'startVideoMuted', + 'startWithAudioMuted', + 'startWithVideoMuted', + 'testing', + 'useIPv6', + 'useNicks', + 'useStunTurn', + 'webrtcIceTcpDisable', + 'webrtcIceUdpDisable' ]; const logger = require('jitsi-meet-logger').getLogger(__filename); @@ -28,60 +99,6 @@ const logger = require('jitsi-meet-logger').getLogger(__filename); export { default as getRoomName } from './getRoomName'; export { parseURLParams }; -/* eslint-disable no-shadow */ - -/** - * Looks for a list of possible BOSH addresses in {@code config.boshList} and - * sets the value of {@code config.bosh} based on that list and - * {@code roomName}. - * - * @param {Object} config - The configuration object. - * @param {string} roomName - The name of the room/conference. - * @returns {void} - */ -export function chooseBOSHAddress(config: Object, roomName: string) { - if (!roomName) { - return; - } - - const { boshList } = config; - - if (!boshList || !Array.isArray(boshList) || !boshList.length) { - return; - } - - // This implements the actual choice of an entry in the list based on - // roomName. Please consider the implications for existing deployments - // before introducing changes. - const hash = (new JSSHA(roomName, 'TEXT')).getHash('SHA-1', 'HEX'); - const n = parseInt(hash.substr(-6), 16); - let idx = n % boshList.length; - - config.bosh = boshList[idx]; - logger.log(`Setting config.bosh to ${config.bosh} (idx=${idx})`); - - const { boshAttemptFirstList } = config; - - if (boshAttemptFirstList - && Array.isArray(boshAttemptFirstList) - && boshAttemptFirstList.length > 0) { - idx = n % boshAttemptFirstList.length; - - const attemptFirstAddress = boshAttemptFirstList[idx]; - - if (attemptFirstAddress === config.bosh) { - logger.log('Not setting config.boshAttemptFirst, address matches.'); - } else { - config.boshAttemptFirst = attemptFirstAddress; - logger.log( - `Setting config.boshAttemptFirst=${attemptFirstAddress} (idx=${ - idx})`); - } - } -} - -/* eslint-enable no-shadow */ - /** * Sends HTTP POST request to specified {@code endpoint}. In request the name * of the room is included in JSON format: @@ -135,6 +152,7 @@ export function obtainConfig( /** * Overrides JSON properties in {@code config} and * {@code interfaceConfig} Objects with the values from {@code newConfig}. + * Overrides only the whitelisted keys. * * @param {Object} config - The config Object in which we'll be overriding * properties. @@ -171,7 +189,8 @@ export function overrideConfigJSON( configObj = loggingConfig; } if (configObj) { - const configJSON = json[configName]; + const configJSON + = _getWhitelistedJSON(configName, json[configName]); if (!_.isEmpty(configJSON)) { logger.info( @@ -190,6 +209,26 @@ export function overrideConfigJSON( } } +/** + * Whitelist only config.js, skips this for others configs + * (interfaceConfig, loggingConfig). + * Only extracts overridden values for keys we allow to be overridden. + * + * @param {string} configName - The config name, one of config, + * interfaceConfig, loggingConfig. + * @param {Object} configJSON - The object with keys and values to override. + * @returns {Object} - The result object only with the keys + * that are whitelisted. + * @private + */ +function _getWhitelistedJSON(configName, configJSON) { + if (configName !== 'config') { + return configJSON; + } + + return _.pick(configJSON, WHITELISTED_KEYS); +} + /* eslint-enable max-params, no-shadow */ /** @@ -233,12 +272,6 @@ export function setConfigFromURLParams() { const names = param.split('.'); const last = names.pop(); - // Prevent passing some parameters which can inject scripts. - if (_KEYS_TO_IGNORE.indexOf(last) !== -1) { - // eslint-disable-next-line no-continue - continue; - } - for (const name of names) { base = base[name] = base[name] || {}; } diff --git a/react/features/conference/route.js b/react/features/conference/route.js index 3478b0f8f..bf4c5e188 100644 --- a/react/features/conference/route.js +++ b/react/features/conference/route.js @@ -2,7 +2,7 @@ import ConferenceUrl from '../../../modules/URL/ConferenceUrl'; -import { chooseBOSHAddress, obtainConfig } from '../base/config'; +import { obtainConfig } from '../base/config'; import { RouteRegistry } from '../base/react'; import { Conference } from './components'; @@ -86,7 +86,6 @@ function _obtainConfigAndInit() { }); }); } else { - chooseBOSHAddress(config, room); _initConference(); } }