@webex/plugin-meetings 3.12.0-next.11 → 3.12.0-next.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -178,7 +178,7 @@ var AIEnableRequest = _webexCore.WebexPlugin.extend({
178
178
  method: _constants.HTTP_VERBS.PUT
179
179
  });
180
180
  },
181
- version: "3.12.0-next.11"
181
+ version: "3.12.0-next.12"
182
182
  });
183
183
  var _default = exports.default = AIEnableRequest;
184
184
  //# sourceMappingURL=index.js.map
@@ -209,7 +209,7 @@ var Breakout = _webexCore.WebexPlugin.extend({
209
209
  sessionId: this.sessionId
210
210
  });
211
211
  },
212
- version: "3.12.0-next.11"
212
+ version: "3.12.0-next.12"
213
213
  });
214
214
  var _default = exports.default = Breakout;
215
215
  //# sourceMappingURL=breakout.js.map
@@ -1109,7 +1109,7 @@ var Breakouts = _webexCore.WebexPlugin.extend({
1109
1109
  this.trigger(_constants.BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
1110
1110
  }
1111
1111
  },
1112
- version: "3.12.0-next.11"
1112
+ version: "3.12.0-next.12"
1113
1113
  });
1114
1114
  var _default = exports.default = Breakouts;
1115
1115
  //# sourceMappingURL=index.js.map
@@ -1,11 +1,21 @@
1
1
  "use strict";
2
2
 
3
3
  var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
4
5
  _Object$defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
- exports.ENABLED = exports.CAN_UNSET = exports.CAN_SET = void 0;
8
+ exports.ENABLED = exports.CAN_UNSET = exports.CAN_SET = exports.AUDIO_CONTROL_BODY_KEYS = void 0;
9
+ var _set = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/set"));
10
+ var _lodash = require("lodash");
11
+ var _enums = require("./enums");
8
12
  var ENABLED = exports.ENABLED = 'enabled';
9
13
  var CAN_SET = exports.CAN_SET = 'canSet';
10
14
  var CAN_UNSET = exports.CAN_UNSET = 'canUnset';
15
+
16
+ /**
17
+ * Body keys that represent audio controls. These do not support cross-locus
18
+ * authorization and must be sent directly to the current locus URL.
19
+ */
20
+ var AUDIO_CONTROL_BODY_KEYS = exports.AUDIO_CONTROL_BODY_KEYS = new _set.default([_enums.Control.audio, (0, _lodash.camelCase)(_enums.Setting.muteOnEntry), (0, _lodash.camelCase)(_enums.Setting.disallowUnmute)]);
11
21
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ENABLED","exports","CAN_SET","CAN_UNSET"],"sources":["constants.ts"],"sourcesContent":["const ENABLED = 'enabled';\nconst CAN_SET = 'canSet';\nconst CAN_UNSET = 'canUnset';\n\nexport {ENABLED, CAN_SET, CAN_UNSET};\n"],"mappings":";;;;;;;AAAA,IAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,SAAS;AACzB,IAAME,OAAO,GAAAD,OAAA,CAAAC,OAAA,GAAG,QAAQ;AACxB,IAAMC,SAAS,GAAAF,OAAA,CAAAE,SAAA,GAAG,UAAU","ignoreList":[]}
1
+ {"version":3,"names":["_lodash","require","_enums","ENABLED","exports","CAN_SET","CAN_UNSET","AUDIO_CONTROL_BODY_KEYS","_set","default","Control","audio","camelCase","Setting","muteOnEntry","disallowUnmute"],"sources":["constants.ts"],"sourcesContent":["import {camelCase} from 'lodash';\nimport {Control, Setting} from './enums';\n\nconst ENABLED = 'enabled';\nconst CAN_SET = 'canSet';\nconst CAN_UNSET = 'canUnset';\n\n/**\n * Body keys that represent audio controls. These do not support cross-locus\n * authorization and must be sent directly to the current locus URL.\n */\nconst AUDIO_CONTROL_BODY_KEYS: ReadonlySet<string> = new Set([\n Control.audio,\n camelCase(Setting.muteOnEntry),\n camelCase(Setting.disallowUnmute),\n]);\n\nexport {ENABLED, CAN_SET, CAN_UNSET, AUDIO_CONTROL_BODY_KEYS};\n"],"mappings":";;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAEA,IAAME,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,SAAS;AACzB,IAAME,OAAO,GAAAD,OAAA,CAAAC,OAAA,GAAG,QAAQ;AACxB,IAAMC,SAAS,GAAAF,OAAA,CAAAE,SAAA,GAAG,UAAU;;AAE5B;AACA;AACA;AACA;AACA,IAAMC,uBAA4C,GAAAH,OAAA,CAAAG,uBAAA,GAAG,IAAAC,IAAA,CAAAC,OAAA,CAAQ,CAC3DC,cAAO,CAACC,KAAK,EACb,IAAAC,iBAAS,EAACC,cAAO,CAACC,WAAW,CAAC,EAC9B,IAAAF,iBAAS,EAACC,cAAO,CAACE,cAAc,CAAC,CAClC,CAAC","ignoreList":[]}
@@ -11,8 +11,8 @@ _Object$defineProperty(exports, "__esModule", {
11
11
  value: true
12
12
  });
13
13
  exports.default = void 0;
14
- var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
15
14
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
15
+ var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
16
16
  var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
17
17
  var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
18
18
  var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
@@ -21,12 +21,12 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/he
21
21
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
22
22
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
23
23
  var _lodash = require("lodash");
24
+ var _parameter = _interopRequireDefault(require("../common/errors/parameter"));
24
25
  var _permission = _interopRequireDefault(require("../common/errors/permission"));
25
- var _constants = require("../constants");
26
26
  var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
27
27
  var _enums = require("./enums");
28
28
  var _util = _interopRequireDefault(require("./util"));
29
- var _constants2 = require("./constants");
29
+ var _constants = require("./constants");
30
30
  function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
31
31
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
32
32
  /**
@@ -181,6 +181,9 @@ var ControlsOptionsManager = exports.default = /*#__PURE__*/function () {
181
181
  key: "update",
182
182
  value: function update() {
183
183
  var _this = this;
184
+ if (!this.locusUrl) {
185
+ return _promise.default.reject(new _parameter.default('The associated locusUrl for update() controls must be defined.'));
186
+ }
184
187
  for (var _len = arguments.length, controls = new Array(_len), _key = 0; _key < _len; _key++) {
185
188
  controls[_key] = arguments[_key];
186
189
  }
@@ -194,17 +197,15 @@ var ControlsOptionsManager = exports.default = /*#__PURE__*/function () {
194
197
  return (0, _defineProperty2.default)({}, control.scope, control.properties);
195
198
  });
196
199
  return payloads.reduce(function (previous, payload) {
197
- var extraBody = _this.mainLocusUrl && _this.mainLocusUrl !== _this.locusUrl ? {
198
- authorizingLocusUrl: _this.locusUrl
199
- } : {};
200
+ var requestParams = _util.default.getControlsRequestParams({
201
+ body: payload,
202
+ locusUrl: _this.locusUrl,
203
+ mainLocusUrl: _this.mainLocusUrl
204
+ });
200
205
  return previous.then(function () {
201
206
  return (
202
207
  // @ts-ignore
203
- _this.request.request({
204
- uri: "".concat(_this.mainLocusUrl || _this.locusUrl, "/").concat(_constants.CONTROLS),
205
- body: _objectSpread(_objectSpread({}, payload), extraBody),
206
- method: _constants.HTTP_VERBS.PATCH
207
- })
208
+ _this.request.request(requestParams)
208
209
  );
209
210
  });
210
211
  }, _promise.default.resolve());
@@ -220,6 +221,9 @@ var ControlsOptionsManager = exports.default = /*#__PURE__*/function () {
220
221
  key: "setControls",
221
222
  value: function setControls(setting) {
222
223
  var _this2 = this;
224
+ if (!this.locusUrl) {
225
+ return _promise.default.reject(new _parameter.default('The associated locusUrl for setControls() must be defined.'));
226
+ }
223
227
  _loggerProxy.default.logger.log("ControlsOptionsManager:index#setControls --> ".concat((0, _stringify.default)(setting)));
224
228
  var body = {};
225
229
  var error;
@@ -228,7 +232,7 @@ var ControlsOptionsManager = exports.default = /*#__PURE__*/function () {
228
232
  var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
229
233
  key = _ref3[0],
230
234
  value = _ref3[1];
231
- if (!shouldSkipCheckToMergeBody && value !== undefined && !(_util.default !== null && _util.default !== void 0 && _util.default["".concat(value ? _constants2.CAN_SET : _constants2.CAN_UNSET).concat(key)](_this2.displayHints))) {
235
+ if (!shouldSkipCheckToMergeBody && value !== undefined && !(_util.default !== null && _util.default !== void 0 && _util.default["".concat(value ? _constants.CAN_SET : _constants.CAN_UNSET).concat(key)](_this2.displayHints))) {
232
236
  error = new _permission.default("".concat(key, " [").concat(value, "] not allowed, due to moderator property."));
233
237
  }
234
238
  if (error) {
@@ -245,7 +249,7 @@ var ControlsOptionsManager = exports.default = /*#__PURE__*/function () {
245
249
  body.audio = body.audio ? _objectSpread(_objectSpread({}, body.audio), {}, (0, _defineProperty2.default)({}, (0, _lodash.camelCase)(key), value)) : (0, _defineProperty2.default)({}, (0, _lodash.camelCase)(key), value);
246
250
  body.audio[(0, _lodash.camelCase)(key)] = value;
247
251
  } else {
248
- body[(0, _lodash.camelCase)(key)] = (0, _defineProperty2.default)({}, _constants2.ENABLED, value);
252
+ body[(0, _lodash.camelCase)(key)] = (0, _defineProperty2.default)({}, _constants.ENABLED, value);
249
253
  }
250
254
  break;
251
255
  case _enums.Setting.roles:
@@ -260,16 +264,14 @@ var ControlsOptionsManager = exports.default = /*#__PURE__*/function () {
260
264
  if (error) {
261
265
  return _promise.default.reject(error);
262
266
  }
263
- var extraBody = this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl ? {
264
- authorizingLocusUrl: this.locusUrl
265
- } : {};
267
+ var requestParams = _util.default.getControlsRequestParams({
268
+ body: body,
269
+ locusUrl: this.locusUrl,
270
+ mainLocusUrl: this.mainLocusUrl
271
+ });
266
272
 
267
273
  // @ts-ignore
268
- return this.request.request({
269
- uri: "".concat(this.mainLocusUrl || this.locusUrl, "/").concat(_constants.CONTROLS),
270
- body: _objectSpread(_objectSpread({}, body), extraBody),
271
- method: _constants.HTTP_VERBS.PATCH
272
- });
274
+ return this.request.request(requestParams);
273
275
  }
274
276
 
275
277
  /**
@@ -1 +1 @@
1
- {"version":3,"names":["_lodash","require","_permission","_interopRequireDefault","_constants","_loggerProxy","_enums","_util","_constants2","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","ControlsOptionsManager","exports","request","options","_classCallCheck2","initialize","set","_createClass2","key","value","extract","setLocusUrl","url","isMainLocus","locusUrl","mainLocusUrl","setDisplayHints","hints","displayHints","getLocusUrl","getDisplayHints","update","_this","_len","controls","Array","_key","payloads","map","control","_keys","Control","includes","scope","Error","concat","Util","canUpdate","PermissionError","properties","reduce","previous","payload","extraBody","authorizingLocusUrl","then","uri","CONTROLS","body","method","HTTP_VERBS","PATCH","_promise","resolve","setControls","setting","_this2","LoggerProxy","logger","log","_stringify","error","shouldSkipCheckToMergeBody","_entries","_ref2","_ref3","_slicedToArray2","undefined","CAN_SET","CAN_UNSET","Setting","muted","audio","camelCase","disallowUnmute","muteOnEntry","ENABLED","roles","_isArray","reject","setMuteOnEntry","enabled","setDisallowUnmute","setMuteAll","mutedEnabled","disallowUnmuteEnabled","muteOnEntryEnabled"],"sources":["index.ts"],"sourcesContent":["import {camelCase} from 'lodash';\nimport PermissionError from '../common/errors/permission';\nimport {CONTROLS, HTTP_VERBS} from '../constants';\nimport MeetingRequest from '../meeting/request';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {Control, Setting} from './enums';\nimport {ControlConfig} from './types';\nimport Util from './util';\nimport {CAN_SET, CAN_UNSET, ENABLED} from './constants';\n\n/**\n * docs\n * https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html\n * https://confluence-eng-gpk2.cisco.com/conf/display/LOCUS/Hard+Mute+and+Audio+Privacy#HardMuteandAudioPrivacy-SelfMuteonEntry\n * https://confluence-eng-gpk2.cisco.com/conf/pages/viewpage.action?spaceKey=UC&title=WEBEX-124454%3A+UCF%3A+Hard+mute+support+for+Teams+joining+Webex+meeting\n * https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-180867\n * https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-393351\n */\n\n/**\n * @description ControlsOptionsManager is responsible for handling the behavior of participant controls when somebody joins a meeting\n * @export\n * @private\n * @class Recording\n */\nexport default class ControlsOptionsManager {\n /**\n * @instance\n * @type {MeetingRequest}\n * @private\n * @memberof ControlsOptionsManager\n */\n private request: MeetingRequest;\n\n /**\n * @instance\n * @type {Array}\n * @private\n * @memberof ControlsOptionsManager\n */\n private displayHints: Array<string> = [];\n\n /**\n * @instance\n * @type {string}\n * @private\n * @memberof ControlsOptionsManager\n */\n private locusUrl: string;\n\n /**\n * @instance\n * @type {string}\n * @private\n * @memberof ControlsOptionsManager\n */\n private mainLocusUrl: string;\n\n /**\n * @param {MeetingRequest} request\n * @param {Object} options\n * @constructor\n * @memberof ControlsOptionsManager\n */\n constructor(\n request: MeetingRequest,\n options?: {\n locusUrl: string;\n displayHints?: Array<string>;\n }\n ) {\n this.initialize(request);\n this.set(options);\n }\n\n /**\n * @param {MeetingRequest} request\n * @returns {void}\n * @private\n * @memberof ControlsOptionsManager\n */\n private initialize(request: MeetingRequest) {\n this.request = request;\n }\n\n /**\n * @param {Object} options\n * @returns {void}\n * @public\n * @memberof ControlsOptionsManager\n */\n public set(options?: {locusUrl: string; displayHints?: Array<string>}) {\n this.extract(options);\n }\n\n /**\n * @param {string} url\n * @param {boolean} isMainLocus\n * @returns {void}\n * @public\n * @memberof ControlsOptionsManager\n */\n public setLocusUrl(url: string, isMainLocus?: boolean) {\n this.locusUrl = url;\n if (isMainLocus) {\n this.mainLocusUrl = url;\n }\n }\n\n /**\n * @param {Array} hints\n * @returns {void}\n * @public\n * @memberof ControlsOptionsManager\n */\n public setDisplayHints(hints: Array<string>) {\n this.displayHints = hints;\n }\n\n /**\n * @returns {string}\n * @public\n * @memberof ControlsOptionsManager\n */\n public getLocusUrl() {\n return this.locusUrl;\n }\n\n /**\n * @returns {Array}\n * @public\n * @memberof ControlsOptionsManager\n */\n public getDisplayHints() {\n return this.displayHints;\n }\n\n /**\n * @param {Object} options\n * @returns {void}\n * @private\n * @memberof ControlsOptionsManager\n */\n private extract(options?: {locusUrl: string; displayHints?: Array<string>}) {\n this.setDisplayHints(options?.displayHints);\n this.setLocusUrl(options?.locusUrl);\n }\n\n /**\n * Set controls for this meeting.\n *\n * @param {Array<ControlConfig>} controls - Spread Array of ControlConfigs\n * @returns {Promise<Array<any>>}- Promise resolving if the request was successful.\n */\n public update(...controls: Array<ControlConfig>) {\n const payloads = controls.map((control) => {\n if (!Object.keys(Control).includes(control.scope)) {\n throw new Error(\n `updating meeting control scope \"${control.scope}\" is not a supported scope`\n );\n }\n\n if (!Util.canUpdate(control, this.displayHints)) {\n throw new PermissionError(\n `updating meeting control scope \"${control.scope}\" not allowed, due to moderator property.`\n );\n }\n\n return {\n [control.scope]: control.properties,\n };\n });\n\n return payloads.reduce((previous, payload) => {\n const extraBody =\n this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl\n ? {authorizingLocusUrl: this.locusUrl}\n : {};\n\n return previous.then(() =>\n // @ts-ignore\n this.request.request({\n uri: `${this.mainLocusUrl || this.locusUrl}/${CONTROLS}`,\n body: {...payload, ...extraBody},\n method: HTTP_VERBS.PATCH,\n })\n );\n }, Promise.resolve());\n }\n\n /**\n * @param {Setting} setting\n * @private\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n private setControls(setting: {\n [Setting.muted]?: boolean;\n [Setting.disallowUnmute]?: boolean;\n [Setting.muteOnEntry]?: boolean;\n [Setting.roles]?: Array<string>;\n }): Promise<any> {\n LoggerProxy.logger.log(\n `ControlsOptionsManager:index#setControls --> ${JSON.stringify(setting)}`\n );\n\n const body: Record<string, any> = {};\n let error: PermissionError;\n\n let shouldSkipCheckToMergeBody = false;\n\n Object.entries(setting).forEach(([key, value]) => {\n if (\n !shouldSkipCheckToMergeBody &&\n value !== undefined &&\n !Util?.[`${value ? CAN_SET : CAN_UNSET}${key}`](this.displayHints)\n ) {\n error = new PermissionError(`${key} [${value}] not allowed, due to moderator property.`);\n }\n\n if (error) {\n return;\n }\n\n switch (key) {\n case Setting.muted:\n shouldSkipCheckToMergeBody = true;\n body.audio = body.audio\n ? {...body.audio, [camelCase(key)]: value}\n : {[camelCase(key)]: value};\n break;\n\n case Setting.disallowUnmute:\n case Setting.muteOnEntry:\n if (Object.keys(setting).includes(Setting.muted)) {\n body.audio = body.audio\n ? {...body.audio, [camelCase(key)]: value}\n : {[camelCase(key)]: value};\n body.audio[camelCase(key)] = value;\n } else {\n body[camelCase(key)] = {[ENABLED]: value};\n }\n break;\n\n case Setting.roles:\n if (Array.isArray(value)) {\n body.audio = body.audio\n ? {...body.audio, [camelCase(key)]: value}\n : {[camelCase(key)]: value};\n }\n break;\n\n default:\n error = new PermissionError(`${key} [${value}] not allowed, due to moderator property.`);\n }\n });\n\n if (error) {\n return Promise.reject(error);\n }\n const extraBody =\n this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl\n ? {authorizingLocusUrl: this.locusUrl}\n : {};\n\n // @ts-ignore\n return this.request.request({\n uri: `${this.mainLocusUrl || this.locusUrl}/${CONTROLS}`,\n body: {...body, ...extraBody},\n method: HTTP_VERBS.PATCH,\n });\n }\n\n /**\n * @public\n * @param {boolean} enabled\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n public setMuteOnEntry(enabled: boolean): Promise<any> {\n return this.setControls({[Setting.muteOnEntry]: enabled});\n }\n\n /**\n * @public\n * @param {boolean} enabled\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n public setDisallowUnmute(enabled: boolean): Promise<any> {\n return this.setControls({[Setting.disallowUnmute]: enabled});\n }\n\n /**\n * @public\n * @param {boolean} mutedEnabled\n * @param {boolean} disallowUnmuteEnabled\n * @param {boolean} muteOnEntryEnabled\n * @param {array} roles which should be muted\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n public setMuteAll(\n mutedEnabled: boolean,\n disallowUnmuteEnabled: boolean,\n muteOnEntryEnabled: boolean,\n roles: Array<string>\n ): Promise<any> {\n return this.setControls({\n [Setting.muted]: mutedEnabled,\n [Setting.disallowUnmute]: disallowUnmuteEnabled,\n [Setting.muteOnEntry]: muteOnEntryEnabled,\n [Setting.roles]: roles,\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_lodash","require","_parameter","_interopRequireDefault","_permission","_loggerProxy","_enums","_util","_constants","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","ControlsOptionsManager","exports","request","options","_classCallCheck2","initialize","set","_createClass2","key","value","extract","setLocusUrl","url","isMainLocus","locusUrl","mainLocusUrl","setDisplayHints","hints","displayHints","getLocusUrl","getDisplayHints","update","_this","_promise","reject","ParameterError","_len","controls","Array","_key","payloads","map","control","_keys","Control","includes","scope","Error","concat","Util","canUpdate","PermissionError","properties","reduce","previous","payload","requestParams","getControlsRequestParams","body","then","resolve","setControls","setting","_this2","LoggerProxy","logger","log","_stringify","error","shouldSkipCheckToMergeBody","_entries","_ref2","_ref3","_slicedToArray2","undefined","CAN_SET","CAN_UNSET","Setting","muted","audio","camelCase","disallowUnmute","muteOnEntry","ENABLED","roles","_isArray","setMuteOnEntry","enabled","setDisallowUnmute","setMuteAll","mutedEnabled","disallowUnmuteEnabled","muteOnEntryEnabled"],"sources":["index.ts"],"sourcesContent":["import {camelCase} from 'lodash';\nimport ParameterError from '../common/errors/parameter';\nimport PermissionError from '../common/errors/permission';\nimport MeetingRequest from '../meeting/request';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {Control, Setting} from './enums';\nimport {ControlConfig} from './types';\nimport Util from './util';\nimport {CAN_SET, CAN_UNSET, ENABLED} from './constants';\n\n/**\n * docs\n * https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html\n * https://confluence-eng-gpk2.cisco.com/conf/display/LOCUS/Hard+Mute+and+Audio+Privacy#HardMuteandAudioPrivacy-SelfMuteonEntry\n * https://confluence-eng-gpk2.cisco.com/conf/pages/viewpage.action?spaceKey=UC&title=WEBEX-124454%3A+UCF%3A+Hard+mute+support+for+Teams+joining+Webex+meeting\n * https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-180867\n * https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-393351\n */\n\n/**\n * @description ControlsOptionsManager is responsible for handling the behavior of participant controls when somebody joins a meeting\n * @export\n * @private\n * @class Recording\n */\nexport default class ControlsOptionsManager {\n /**\n * @instance\n * @type {MeetingRequest}\n * @private\n * @memberof ControlsOptionsManager\n */\n private request: MeetingRequest;\n\n /**\n * @instance\n * @type {Array}\n * @private\n * @memberof ControlsOptionsManager\n */\n private displayHints: Array<string> = [];\n\n /**\n * @instance\n * @type {string}\n * @private\n * @memberof ControlsOptionsManager\n */\n private locusUrl: string;\n\n /**\n * @instance\n * @type {string}\n * @private\n * @memberof ControlsOptionsManager\n */\n private mainLocusUrl: string;\n\n /**\n * @param {MeetingRequest} request\n * @param {Object} options\n * @constructor\n * @memberof ControlsOptionsManager\n */\n constructor(\n request: MeetingRequest,\n options?: {\n locusUrl: string;\n displayHints?: Array<string>;\n }\n ) {\n this.initialize(request);\n this.set(options);\n }\n\n /**\n * @param {MeetingRequest} request\n * @returns {void}\n * @private\n * @memberof ControlsOptionsManager\n */\n private initialize(request: MeetingRequest) {\n this.request = request;\n }\n\n /**\n * @param {Object} options\n * @returns {void}\n * @public\n * @memberof ControlsOptionsManager\n */\n public set(options?: {locusUrl: string; displayHints?: Array<string>}) {\n this.extract(options);\n }\n\n /**\n * @param {string} url\n * @param {boolean} isMainLocus\n * @returns {void}\n * @public\n * @memberof ControlsOptionsManager\n */\n public setLocusUrl(url: string, isMainLocus?: boolean) {\n this.locusUrl = url;\n if (isMainLocus) {\n this.mainLocusUrl = url;\n }\n }\n\n /**\n * @param {Array} hints\n * @returns {void}\n * @public\n * @memberof ControlsOptionsManager\n */\n public setDisplayHints(hints: Array<string>) {\n this.displayHints = hints;\n }\n\n /**\n * @returns {string}\n * @public\n * @memberof ControlsOptionsManager\n */\n public getLocusUrl() {\n return this.locusUrl;\n }\n\n /**\n * @returns {Array}\n * @public\n * @memberof ControlsOptionsManager\n */\n public getDisplayHints() {\n return this.displayHints;\n }\n\n /**\n * @param {Object} options\n * @returns {void}\n * @private\n * @memberof ControlsOptionsManager\n */\n private extract(options?: {locusUrl: string; displayHints?: Array<string>}) {\n this.setDisplayHints(options?.displayHints);\n this.setLocusUrl(options?.locusUrl);\n }\n\n /**\n * Set controls for this meeting.\n *\n * @param {Array<ControlConfig>} controls - Spread Array of ControlConfigs\n * @returns {Promise<Array<any>>}- Promise resolving if the request was successful.\n */\n public update(...controls: Array<ControlConfig>) {\n if (!this.locusUrl) {\n return Promise.reject(\n new ParameterError('The associated locusUrl for update() controls must be defined.')\n );\n }\n\n const payloads = controls.map((control) => {\n if (!Object.keys(Control).includes(control.scope)) {\n throw new Error(\n `updating meeting control scope \"${control.scope}\" is not a supported scope`\n );\n }\n\n if (!Util.canUpdate(control, this.displayHints)) {\n throw new PermissionError(\n `updating meeting control scope \"${control.scope}\" not allowed, due to moderator property.`\n );\n }\n\n return {\n [control.scope]: control.properties,\n };\n });\n\n return payloads.reduce((previous, payload) => {\n const requestParams = Util.getControlsRequestParams({\n body: payload,\n locusUrl: this.locusUrl,\n mainLocusUrl: this.mainLocusUrl,\n });\n\n return previous.then(() =>\n // @ts-ignore\n this.request.request(requestParams)\n );\n }, Promise.resolve());\n }\n\n /**\n * @param {Setting} setting\n * @private\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n private setControls(setting: {\n [Setting.muted]?: boolean;\n [Setting.disallowUnmute]?: boolean;\n [Setting.muteOnEntry]?: boolean;\n [Setting.roles]?: Array<string>;\n }): Promise<any> {\n if (!this.locusUrl) {\n return Promise.reject(\n new ParameterError('The associated locusUrl for setControls() must be defined.')\n );\n }\n\n LoggerProxy.logger.log(\n `ControlsOptionsManager:index#setControls --> ${JSON.stringify(setting)}`\n );\n\n const body: Record<string, any> = {};\n let error: PermissionError;\n\n let shouldSkipCheckToMergeBody = false;\n\n Object.entries(setting).forEach(([key, value]) => {\n if (\n !shouldSkipCheckToMergeBody &&\n value !== undefined &&\n !Util?.[`${value ? CAN_SET : CAN_UNSET}${key}`](this.displayHints)\n ) {\n error = new PermissionError(`${key} [${value}] not allowed, due to moderator property.`);\n }\n\n if (error) {\n return;\n }\n\n switch (key) {\n case Setting.muted:\n shouldSkipCheckToMergeBody = true;\n body.audio = body.audio\n ? {...body.audio, [camelCase(key)]: value}\n : {[camelCase(key)]: value};\n break;\n\n case Setting.disallowUnmute:\n case Setting.muteOnEntry:\n if (Object.keys(setting).includes(Setting.muted)) {\n body.audio = body.audio\n ? {...body.audio, [camelCase(key)]: value}\n : {[camelCase(key)]: value};\n body.audio[camelCase(key)] = value;\n } else {\n body[camelCase(key)] = {[ENABLED]: value};\n }\n break;\n\n case Setting.roles:\n if (Array.isArray(value)) {\n body.audio = body.audio\n ? {...body.audio, [camelCase(key)]: value}\n : {[camelCase(key)]: value};\n }\n break;\n\n default:\n error = new PermissionError(`${key} [${value}] not allowed, due to moderator property.`);\n }\n });\n\n if (error) {\n return Promise.reject(error);\n }\n\n const requestParams = Util.getControlsRequestParams({\n body,\n locusUrl: this.locusUrl,\n mainLocusUrl: this.mainLocusUrl,\n });\n\n // @ts-ignore\n return this.request.request(requestParams);\n }\n\n /**\n * @public\n * @param {boolean} enabled\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n public setMuteOnEntry(enabled: boolean): Promise<any> {\n return this.setControls({[Setting.muteOnEntry]: enabled});\n }\n\n /**\n * @public\n * @param {boolean} enabled\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n public setDisallowUnmute(enabled: boolean): Promise<any> {\n return this.setControls({[Setting.disallowUnmute]: enabled});\n }\n\n /**\n * @public\n * @param {boolean} mutedEnabled\n * @param {boolean} disallowUnmuteEnabled\n * @param {boolean} muteOnEntryEnabled\n * @param {array} roles which should be muted\n * @memberof ControlsOptionsManager\n * @returns {Promise}\n */\n public setMuteAll(\n mutedEnabled: boolean,\n disallowUnmuteEnabled: boolean,\n muteOnEntryEnabled: boolean,\n roles: Array<string>\n ): Promise<any> {\n return this.setControls({\n [Setting.muted]: mutedEnabled,\n [Setting.disallowUnmute]: disallowUnmuteEnabled,\n [Setting.muteOnEntry]: muteOnEntryEnabled,\n [Setting.roles]: roles,\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,15 +1,25 @@
1
1
  "use strict";
2
2
 
3
+ var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
4
+ var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
5
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
6
+ var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
7
+ var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
3
8
  var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
9
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
5
10
  _Object$defineProperty(exports, "__esModule", {
6
11
  value: true
7
12
  });
8
13
  exports.default = void 0;
14
+ var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
15
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
9
16
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
10
17
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
11
18
  var _constants = require("../constants");
12
19
  var _enums = require("./enums");
20
+ var _constants2 = require("./constants");
21
+ function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
22
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
13
23
  /**
14
24
  * The Controls Options Manager utilities
15
25
  *
@@ -401,6 +411,87 @@ var Utils = /*#__PURE__*/function () {
401
411
  }
402
412
  return determinant;
403
413
  }
414
+
415
+ /**
416
+ * Check if all body keys represent audio controls.
417
+ *
418
+ * @param {Record<string, any>} body - The request body to inspect.
419
+ * @returns {boolean} - True if every key in the body is an audio control key.
420
+ */
421
+ }, {
422
+ key: "isAudioControl",
423
+ value: function isAudioControl(body) {
424
+ return (0, _keys.default)(body).every(function (key) {
425
+ return _constants2.AUDIO_CONTROL_BODY_KEYS.has(key);
426
+ });
427
+ }
428
+
429
+ /**
430
+ * Check if the current locus URL differs from the main locus URL,
431
+ * indicating a breakout session.
432
+ *
433
+ * @param {string} locusUrl - The current locus URL.
434
+ * @param {string} [mainLocusUrl] - The main locus URL.
435
+ * @returns {boolean} - True if in a breakout session.
436
+ */
437
+ }, {
438
+ key: "isBreakoutLocusUrl",
439
+ value: function isBreakoutLocusUrl(locusUrl, mainLocusUrl) {
440
+ return Boolean(mainLocusUrl) && mainLocusUrl !== locusUrl;
441
+ }
442
+
443
+ /**
444
+ * Resolve the target URL and extra body fields for a controls request,
445
+ * handling breakout session routing. Note: This is a pure computation function.
446
+ * It does not validate that locusUrl is
447
+ * defined. Callers must guard against falsy locusUrl before
448
+ * invoking this function.
449
+ * Mixed audio and non-audio keys in a single body (e.g., {audio: {...},
450
+ * raiseHand: {...}}) are treated as non-audio and routed to mainLocusUrl with
451
+ * authorizingLocusUrl. This means the audio portion would go through unsupported
452
+ * cross-locus authorization. Callers must not produce mixed payloads — update()
453
+ * sends each control scope as a separate request, and setControls() only handles
454
+ * audio-related settings.
455
+ *
456
+ * The authorizingLocusUrl mechanism on PATCH /loci/{lid}/controls is not supported
457
+ * for audio control updates (mute/unmute, muteOnEntry, disallowUnmute).
458
+ * Audio controls are not wired into the cross-locus GraphQL authorization path that
459
+ * other control types (raiseHand, viewParticipantList, admit, reactions, etc.) use.
460
+ * Specifically, the GraphQL authorization layer does not recognize audio as a control
461
+ * type eligible for remote locus authorization.
462
+ * This means authorizingLocusUrl is effectively ignored for audio controls and the
463
+ * server evaluates the request against the target locus only, where the host may not
464
+ * be currently joined.
465
+ * Audio control updates must be sent directly to the locus the user is currently in.
466
+ * If the host is in a breakout and wants to mute participants in that breakout, the
467
+ * request should target the breakout locus URL directly, not the main session locus
468
+ * with authorizingLocusUrl.
469
+ * Meeting-wide audio control actions (e.g., muting panelists across all breakouts
470
+ * from a single request) are not currently supported through this mechanism.
471
+ *
472
+ * @param {object} options
473
+ * @param {Record<string, any>} options.body - The request body.
474
+ * @param {string} options.locusUrl - The current locus URL. Must be defined (callers must validate).
475
+ * @param {string} [options.mainLocusUrl] - The main locus URL.
476
+ * @returns {{ uri: string, body: Record<string, any>, method: string }}
477
+ */
478
+ }, {
479
+ key: "getControlsRequestParams",
480
+ value: function getControlsRequestParams(options) {
481
+ var body = options.body,
482
+ locusUrl = options.locusUrl,
483
+ mainLocusUrl = options.mainLocusUrl;
484
+ var isAudio = Utils.isAudioControl(body);
485
+ var inBreakout = Utils.isBreakoutLocusUrl(locusUrl, mainLocusUrl);
486
+ var targetUrl = inBreakout && !isAudio ? mainLocusUrl : locusUrl;
487
+ return {
488
+ uri: "".concat(targetUrl, "/").concat(_constants.CONTROLS),
489
+ body: inBreakout && !isAudio ? _objectSpread(_objectSpread({}, body), {}, {
490
+ authorizingLocusUrl: locusUrl
491
+ }) : body,
492
+ method: _constants.HTTP_VERBS.PATCH
493
+ };
494
+ }
404
495
  }]);
405
496
  }();
406
497
  var _default = exports.default = Utils;
@@ -1 +1 @@
1
- {"version":3,"names":["_constants","require","_enums","Utils","_classCallCheck2","default","_createClass2","key","value","canSetMuteOnEntry","displayHints","includes","DISPLAY_HINTS","ENABLE_MUTE_ON_ENTRY","canSetDisallowUnmute","ENABLE_HARD_MUTE","canUnsetMuteOnEntry","DISABLE_MUTE_ON_ENTRY","canUnsetDisallowUnmute","DISABLE_HARD_MUTE","canSetMuted","MUTE_ALL","canUnsetMuted","UNMUTE_ALL","hasHints","config","requiredHints","every","hint","hasPolicies","requiredPolicies","_config$policies","policies","canUpdateAudio","control","properties","muted","push","disallowUnmute","muteOnEntry","canUpdateRaiseHand","enabled","ENABLE_RAISE_HAND","DISABLE_RAISE_HAND","canUpdateReactions","showDisplayNameWithReactions","undefined","ENABLE_SHOW_DISPLAY_NAME","DISABLE_SHOW_DISPLAY_NAME","ENABLE_REACTIONS","DISABLE_REACTIONS","canUpdateShareControl","SHARE_CONTROL","canUpdateViewTheParticipantsList","ENABLE_VIEW_THE_PARTICIPANT_LIST","DISABLE_VIEW_THE_PARTICIPANT_LIST","panelistEnabled","ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST","DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST","attendeeCount","ENABLE_SHOW_ATTENDEE_COUNT","DISABLE_SHOW_ATTENDEE_COUNT","canUpdateVideo","ENABLE_VIDEO","DISABLE_VIDEO","canUpdateAnnotation","ENABLE_ANNOTATION_MEETING_OPTION","DISABLE_ANNOTATION_MEETING_OPTION","canUpdateRemoteDesktopControl","ENABLE_RDC_MEETING_OPTION","DISABLE_RDC_MEETING_OPTION","canUpdatePollingQA","ENABLE_ATTENDEE_START_POLLING_QA","DISABLE_ATTENDEE_START_POLLING_QA","canUpdate","determinant","scope","Control","audio","raiseHand","reactions","shareControl","video","viewTheParticipantList","annotation","rdc","pollingQA","_default","exports"],"sources":["util.ts"],"sourcesContent":["import {DISPLAY_HINTS} from '../constants';\nimport {Control} from './enums';\nimport {\n ControlConfig,\n AudioProperties,\n RaiseHandProperties,\n ReactionsProperties,\n ViewTheParticipantListProperties,\n VideoProperties,\n type RemoteDesktopControlProperties,\n type AnnotationProperties,\n type PollingQAProperties,\n} from './types';\n\n/**\n * The Controls Options Manager utilities\n *\n * @internal\n */\nclass Utils {\n /**\n * Validate if enabling mute on entry can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canSetMuteOnEntry(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);\n }\n\n /**\n * Validate if allowing unmuting can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canSetDisallowUnmute(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.ENABLE_HARD_MUTE);\n }\n\n /**\n * Validate if disabling mute on entry can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canUnsetMuteOnEntry(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);\n }\n\n /**\n * Validate if enabling muting can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canUnsetDisallowUnmute(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.DISABLE_HARD_MUTE);\n }\n\n /**\n * Validate if muting all can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canSetMuted(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.MUTE_ALL);\n }\n\n /**\n * Validate if unmuting all can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canUnsetMuted(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.UNMUTE_ALL);\n }\n\n /**\n * Validate an array of hints are allowed based on a full collection of hints.\n *\n * @param {Object} config - Configuration Object.\n * @param {Array<string>} config.requiredHints - Hints required for validation.\n * @param {Array<string>} config.displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static hasHints(config: {requiredHints: Array<string>; displayHints: Array<string>}) {\n const {requiredHints, displayHints} = config;\n\n return requiredHints.every((hint) => displayHints.includes(hint));\n }\n\n /**\n * Validate that the self policy object contains the required policies.\n *\n * @param {Object} config - Configuration Object.\n * @param {Array<string>} config.requiredPolicies - Policies required for validation.\n * @param {Array<string>} config.policies - All available policies.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static hasPolicies(config: {requiredPolicies: Array<string>; policies: Array<string>}) {\n const {requiredPolicies, policies = {}} = config;\n\n return requiredPolicies.every((hint) => policies[hint]);\n }\n\n /**\n * Validate if an audio-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<AudioProperties>} control - Audio control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateAudio(\n control: ControlConfig<AudioProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.muted === true) {\n requiredHints.push(DISPLAY_HINTS.MUTE_ALL);\n }\n if (control.properties.muted === false) {\n requiredHints.push(DISPLAY_HINTS.UNMUTE_ALL);\n }\n if (control.properties.disallowUnmute === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_HARD_MUTE);\n }\n if (control.properties.disallowUnmute === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_HARD_MUTE);\n }\n if (control.properties.muteOnEntry === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);\n }\n if (control.properties.muteOnEntry === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n public static canUpdateRaiseHand(\n control: ControlConfig<RaiseHandProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_RAISE_HAND);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_RAISE_HAND);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if an reactions-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<ReactionsProperties>} control - Reaction control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateReactions(\n control: ControlConfig<ReactionsProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n // This additional if statement avoids the display hint discrepency due to\n // the service blocking partial requests with this property only.\n if (control.properties.showDisplayNameWithReactions !== undefined) {\n if (control.properties.showDisplayNameWithReactions === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME);\n }\n if (control.properties.showDisplayNameWithReactions === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME);\n }\n } else {\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_REACTIONS);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_REACTIONS);\n }\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if an share-control-scoped control is allowed to be sent to the service.\n *\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateShareControl(displayHints: Array<string>) {\n return Utils.hasHints({requiredHints: [DISPLAY_HINTS.SHARE_CONTROL], displayHints});\n }\n\n /**\n * Validate if an view-the-participants-list-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<ViewTheParticipantListProperties>} control - View Participants List control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateViewTheParticipantsList(\n control: ControlConfig<ViewTheParticipantListProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST);\n }\n if (control.properties.panelistEnabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST);\n }\n if (control.properties.panelistEnabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST);\n }\n if (control.properties.attendeeCount === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_SHOW_ATTENDEE_COUNT);\n }\n if (control.properties.attendeeCount === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_SHOW_ATTENDEE_COUNT);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a video-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<VideoProperties>} control - Video control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateVideo(\n control: ControlConfig<VideoProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_VIDEO);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_VIDEO);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a annotation-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<AnnotationProperties>} control - Annotation control config to validate\n * @param {Array<string>} displayHints - All available hints\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateAnnotation(\n control: ControlConfig<AnnotationProperties>,\n displayHints: Array<string>\n ): boolean {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_ANNOTATION_MEETING_OPTION);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_ANNOTATION_MEETING_OPTION);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a rdc-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<RemoteDesktopControlProperties>} control - Remote Desktop Control config to validate\n * @param {Array<string>} displayHints - All available hints\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateRemoteDesktopControl(\n control: ControlConfig<RemoteDesktopControlProperties>,\n displayHints: Array<string>\n ): boolean {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_RDC_MEETING_OPTION);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a pollingQA-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<PollingQAProperties>} control - Polling QA config to validate\n * @param {Array<string>} displayHints - All available hints\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdatePollingQA(\n control: ControlConfig<PollingQAProperties>,\n displayHints: Array<string>\n ): boolean {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_ATTENDEE_START_POLLING_QA);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate that a control can be sent to the service based on the provided\n * display hints.\n *\n * @param {ControlConfig} control - Control to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdate(control: ControlConfig, displayHints: Array<string>) {\n let determinant: boolean;\n\n switch (control.scope) {\n case Control.audio:\n determinant = Utils.canUpdateAudio(control as ControlConfig<AudioProperties>, displayHints);\n break;\n\n case Control.raiseHand:\n determinant = Utils.canUpdateRaiseHand(\n control as ControlConfig<RaiseHandProperties>,\n displayHints\n );\n break;\n\n case Control.reactions:\n determinant = Utils.canUpdateReactions(\n control as ControlConfig<ReactionsProperties>,\n displayHints\n );\n break;\n\n case Control.shareControl:\n determinant = Utils.canUpdateShareControl(displayHints);\n break;\n\n case Control.video:\n determinant = Utils.canUpdateVideo(control as ControlConfig<VideoProperties>, displayHints);\n break;\n\n case Control.viewTheParticipantList:\n determinant = Utils.canUpdateViewTheParticipantsList(\n control as ControlConfig<ViewTheParticipantListProperties>,\n displayHints\n );\n break;\n\n case Control.annotation:\n determinant = Utils.canUpdateAnnotation(\n control as ControlConfig<AnnotationProperties>,\n displayHints\n );\n break;\n\n case Control.rdc:\n determinant = Utils.canUpdateRemoteDesktopControl(\n control as ControlConfig<RemoteDesktopControlProperties>,\n displayHints\n );\n break;\n\n case Control.pollingQA:\n determinant = Utils.canUpdatePollingQA(\n control as ControlConfig<PollingQAProperties>,\n displayHints\n );\n break;\n\n default:\n determinant = false;\n }\n\n return determinant;\n }\n}\n\nexport default Utils;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_constants","require","_enums","_constants2","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","Utils","_classCallCheck2","_createClass2","key","value","canSetMuteOnEntry","displayHints","includes","DISPLAY_HINTS","ENABLE_MUTE_ON_ENTRY","canSetDisallowUnmute","ENABLE_HARD_MUTE","canUnsetMuteOnEntry","DISABLE_MUTE_ON_ENTRY","canUnsetDisallowUnmute","DISABLE_HARD_MUTE","canSetMuted","MUTE_ALL","canUnsetMuted","UNMUTE_ALL","hasHints","config","requiredHints","every","hint","hasPolicies","requiredPolicies","_config$policies","policies","canUpdateAudio","control","properties","muted","disallowUnmute","muteOnEntry","canUpdateRaiseHand","enabled","ENABLE_RAISE_HAND","DISABLE_RAISE_HAND","canUpdateReactions","showDisplayNameWithReactions","undefined","ENABLE_SHOW_DISPLAY_NAME","DISABLE_SHOW_DISPLAY_NAME","ENABLE_REACTIONS","DISABLE_REACTIONS","canUpdateShareControl","SHARE_CONTROL","canUpdateViewTheParticipantsList","ENABLE_VIEW_THE_PARTICIPANT_LIST","DISABLE_VIEW_THE_PARTICIPANT_LIST","panelistEnabled","ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST","DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST","attendeeCount","ENABLE_SHOW_ATTENDEE_COUNT","DISABLE_SHOW_ATTENDEE_COUNT","canUpdateVideo","ENABLE_VIDEO","DISABLE_VIDEO","canUpdateAnnotation","ENABLE_ANNOTATION_MEETING_OPTION","DISABLE_ANNOTATION_MEETING_OPTION","canUpdateRemoteDesktopControl","ENABLE_RDC_MEETING_OPTION","DISABLE_RDC_MEETING_OPTION","canUpdatePollingQA","ENABLE_ATTENDEE_START_POLLING_QA","DISABLE_ATTENDEE_START_POLLING_QA","canUpdate","determinant","scope","Control","audio","raiseHand","reactions","shareControl","video","viewTheParticipantList","annotation","rdc","pollingQA","isAudioControl","body","_keys","AUDIO_CONTROL_BODY_KEYS","has","isBreakoutLocusUrl","locusUrl","mainLocusUrl","Boolean","getControlsRequestParams","options","isAudio","inBreakout","targetUrl","uri","concat","CONTROLS","authorizingLocusUrl","method","HTTP_VERBS","PATCH","_default","exports"],"sources":["util.ts"],"sourcesContent":["import {CONTROLS, DISPLAY_HINTS, HTTP_VERBS} from '../constants';\nimport {Control} from './enums';\nimport {AUDIO_CONTROL_BODY_KEYS} from './constants';\nimport {\n ControlConfig,\n AudioProperties,\n RaiseHandProperties,\n ReactionsProperties,\n ViewTheParticipantListProperties,\n VideoProperties,\n type RemoteDesktopControlProperties,\n type AnnotationProperties,\n type PollingQAProperties,\n} from './types';\n\n/**\n * The Controls Options Manager utilities\n *\n * @internal\n */\nclass Utils {\n /**\n * Validate if enabling mute on entry can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canSetMuteOnEntry(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);\n }\n\n /**\n * Validate if allowing unmuting can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canSetDisallowUnmute(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.ENABLE_HARD_MUTE);\n }\n\n /**\n * Validate if disabling mute on entry can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canUnsetMuteOnEntry(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);\n }\n\n /**\n * Validate if enabling muting can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canUnsetDisallowUnmute(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.DISABLE_HARD_MUTE);\n }\n\n /**\n * Validate if muting all can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canSetMuted(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.MUTE_ALL);\n }\n\n /**\n * Validate if unmuting all can be set.\n *\n * @param {Array<string>} displayHints - Display Hints to use when validating.\n * @returns {boolean} - True if the action is allowed.\n */\n public static canUnsetMuted(displayHints: Array<string>): boolean {\n return displayHints.includes(DISPLAY_HINTS.UNMUTE_ALL);\n }\n\n /**\n * Validate an array of hints are allowed based on a full collection of hints.\n *\n * @param {Object} config - Configuration Object.\n * @param {Array<string>} config.requiredHints - Hints required for validation.\n * @param {Array<string>} config.displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static hasHints(config: {requiredHints: Array<string>; displayHints: Array<string>}) {\n const {requiredHints, displayHints} = config;\n\n return requiredHints.every((hint) => displayHints.includes(hint));\n }\n\n /**\n * Validate that the self policy object contains the required policies.\n *\n * @param {Object} config - Configuration Object.\n * @param {Array<string>} config.requiredPolicies - Policies required for validation.\n * @param {Array<string>} config.policies - All available policies.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static hasPolicies(config: {requiredPolicies: Array<string>; policies: Array<string>}) {\n const {requiredPolicies, policies = {}} = config;\n\n return requiredPolicies.every((hint) => policies[hint]);\n }\n\n /**\n * Validate if an audio-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<AudioProperties>} control - Audio control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateAudio(\n control: ControlConfig<AudioProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.muted === true) {\n requiredHints.push(DISPLAY_HINTS.MUTE_ALL);\n }\n if (control.properties.muted === false) {\n requiredHints.push(DISPLAY_HINTS.UNMUTE_ALL);\n }\n if (control.properties.disallowUnmute === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_HARD_MUTE);\n }\n if (control.properties.disallowUnmute === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_HARD_MUTE);\n }\n if (control.properties.muteOnEntry === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);\n }\n if (control.properties.muteOnEntry === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n public static canUpdateRaiseHand(\n control: ControlConfig<RaiseHandProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_RAISE_HAND);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_RAISE_HAND);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if an reactions-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<ReactionsProperties>} control - Reaction control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateReactions(\n control: ControlConfig<ReactionsProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n // This additional if statement avoids the display hint discrepency due to\n // the service blocking partial requests with this property only.\n if (control.properties.showDisplayNameWithReactions !== undefined) {\n if (control.properties.showDisplayNameWithReactions === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME);\n }\n if (control.properties.showDisplayNameWithReactions === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME);\n }\n } else {\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_REACTIONS);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_REACTIONS);\n }\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if an share-control-scoped control is allowed to be sent to the service.\n *\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateShareControl(displayHints: Array<string>) {\n return Utils.hasHints({requiredHints: [DISPLAY_HINTS.SHARE_CONTROL], displayHints});\n }\n\n /**\n * Validate if an view-the-participants-list-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<ViewTheParticipantListProperties>} control - View Participants List control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateViewTheParticipantsList(\n control: ControlConfig<ViewTheParticipantListProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST);\n }\n if (control.properties.panelistEnabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST);\n }\n if (control.properties.panelistEnabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST);\n }\n if (control.properties.attendeeCount === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_SHOW_ATTENDEE_COUNT);\n }\n if (control.properties.attendeeCount === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_SHOW_ATTENDEE_COUNT);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a video-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<VideoProperties>} control - Video control config to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateVideo(\n control: ControlConfig<VideoProperties>,\n displayHints: Array<string>\n ) {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_VIDEO);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_VIDEO);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a annotation-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<AnnotationProperties>} control - Annotation control config to validate\n * @param {Array<string>} displayHints - All available hints\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateAnnotation(\n control: ControlConfig<AnnotationProperties>,\n displayHints: Array<string>\n ): boolean {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_ANNOTATION_MEETING_OPTION);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_ANNOTATION_MEETING_OPTION);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a rdc-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<RemoteDesktopControlProperties>} control - Remote Desktop Control config to validate\n * @param {Array<string>} displayHints - All available hints\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdateRemoteDesktopControl(\n control: ControlConfig<RemoteDesktopControlProperties>,\n displayHints: Array<string>\n ): boolean {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_RDC_MEETING_OPTION);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate if a pollingQA-scoped control is allowed to be sent to the service.\n *\n * @param {ControlConfig<PollingQAProperties>} control - Polling QA config to validate\n * @param {Array<string>} displayHints - All available hints\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdatePollingQA(\n control: ControlConfig<PollingQAProperties>,\n displayHints: Array<string>\n ): boolean {\n const requiredHints = [];\n\n if (control.properties.enabled === true) {\n requiredHints.push(DISPLAY_HINTS.ENABLE_ATTENDEE_START_POLLING_QA);\n }\n if (control.properties.enabled === false) {\n requiredHints.push(DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA);\n }\n\n return Utils.hasHints({requiredHints, displayHints});\n }\n\n /**\n * Validate that a control can be sent to the service based on the provided\n * display hints.\n *\n * @param {ControlConfig} control - Control to validate.\n * @param {Array<string>} displayHints - All available hints.\n * @returns {boolean} - True if all of the actions are allowed.\n */\n public static canUpdate(control: ControlConfig, displayHints: Array<string>) {\n let determinant: boolean;\n\n switch (control.scope) {\n case Control.audio:\n determinant = Utils.canUpdateAudio(control as ControlConfig<AudioProperties>, displayHints);\n break;\n\n case Control.raiseHand:\n determinant = Utils.canUpdateRaiseHand(\n control as ControlConfig<RaiseHandProperties>,\n displayHints\n );\n break;\n\n case Control.reactions:\n determinant = Utils.canUpdateReactions(\n control as ControlConfig<ReactionsProperties>,\n displayHints\n );\n break;\n\n case Control.shareControl:\n determinant = Utils.canUpdateShareControl(displayHints);\n break;\n\n case Control.video:\n determinant = Utils.canUpdateVideo(control as ControlConfig<VideoProperties>, displayHints);\n break;\n\n case Control.viewTheParticipantList:\n determinant = Utils.canUpdateViewTheParticipantsList(\n control as ControlConfig<ViewTheParticipantListProperties>,\n displayHints\n );\n break;\n\n case Control.annotation:\n determinant = Utils.canUpdateAnnotation(\n control as ControlConfig<AnnotationProperties>,\n displayHints\n );\n break;\n\n case Control.rdc:\n determinant = Utils.canUpdateRemoteDesktopControl(\n control as ControlConfig<RemoteDesktopControlProperties>,\n displayHints\n );\n break;\n\n case Control.pollingQA:\n determinant = Utils.canUpdatePollingQA(\n control as ControlConfig<PollingQAProperties>,\n displayHints\n );\n break;\n\n default:\n determinant = false;\n }\n\n return determinant;\n }\n\n /**\n * Check if all body keys represent audio controls.\n *\n * @param {Record<string, any>} body - The request body to inspect.\n * @returns {boolean} - True if every key in the body is an audio control key.\n */\n public static isAudioControl(body: Record<string, any>): boolean {\n return Object.keys(body).every((key) => AUDIO_CONTROL_BODY_KEYS.has(key));\n }\n\n /**\n * Check if the current locus URL differs from the main locus URL,\n * indicating a breakout session.\n *\n * @param {string} locusUrl - The current locus URL.\n * @param {string} [mainLocusUrl] - The main locus URL.\n * @returns {boolean} - True if in a breakout session.\n */\n public static isBreakoutLocusUrl(locusUrl: string, mainLocusUrl?: string): boolean {\n return Boolean(mainLocusUrl) && mainLocusUrl !== locusUrl;\n }\n\n /**\n * Resolve the target URL and extra body fields for a controls request,\n * handling breakout session routing. Note: This is a pure computation function.\n * It does not validate that locusUrl is\n * defined. Callers must guard against falsy locusUrl before\n * invoking this function.\n * Mixed audio and non-audio keys in a single body (e.g., {audio: {...},\n * raiseHand: {...}}) are treated as non-audio and routed to mainLocusUrl with\n * authorizingLocusUrl. This means the audio portion would go through unsupported\n * cross-locus authorization. Callers must not produce mixed payloads — update()\n * sends each control scope as a separate request, and setControls() only handles\n * audio-related settings.\n *\n * The authorizingLocusUrl mechanism on PATCH /loci/{lid}/controls is not supported\n * for audio control updates (mute/unmute, muteOnEntry, disallowUnmute).\n * Audio controls are not wired into the cross-locus GraphQL authorization path that\n * other control types (raiseHand, viewParticipantList, admit, reactions, etc.) use.\n * Specifically, the GraphQL authorization layer does not recognize audio as a control\n * type eligible for remote locus authorization.\n * This means authorizingLocusUrl is effectively ignored for audio controls and the\n * server evaluates the request against the target locus only, where the host may not\n * be currently joined.\n * Audio control updates must be sent directly to the locus the user is currently in.\n * If the host is in a breakout and wants to mute participants in that breakout, the\n * request should target the breakout locus URL directly, not the main session locus\n * with authorizingLocusUrl.\n * Meeting-wide audio control actions (e.g., muting panelists across all breakouts\n * from a single request) are not currently supported through this mechanism.\n *\n * @param {object} options\n * @param {Record<string, any>} options.body - The request body.\n * @param {string} options.locusUrl - The current locus URL. Must be defined (callers must validate).\n * @param {string} [options.mainLocusUrl] - The main locus URL.\n * @returns {{ uri: string, body: Record<string, any>, method: string }}\n */\n public static getControlsRequestParams(options: {\n body: Record<string, any>;\n locusUrl: string;\n mainLocusUrl?: string;\n }): {\n uri: string;\n body: Record<string, any>;\n method: string;\n } {\n const {body, locusUrl, mainLocusUrl} = options;\n\n const isAudio = Utils.isAudioControl(body);\n const inBreakout = Utils.isBreakoutLocusUrl(locusUrl, mainLocusUrl);\n const targetUrl = inBreakout && !isAudio ? mainLocusUrl : locusUrl;\n\n return {\n uri: `${targetUrl}/${CONTROLS}`,\n body: inBreakout && !isAudio ? {...body, authorizingLocusUrl: locusUrl} : body,\n method: HTTP_VERBS.PATCH,\n };\n }\n}\n\nexport default Utils;\n"],"mappings":"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","ignoreList":[]}
@@ -372,7 +372,7 @@ var SimultaneousInterpretation = _webexCore.WebexPlugin.extend({
372
372
  throw error;
373
373
  });
374
374
  },
375
- version: "3.12.0-next.11"
375
+ version: "3.12.0-next.12"
376
376
  });
377
377
  var _default = exports.default = SimultaneousInterpretation;
378
378
  //# sourceMappingURL=index.js.map
@@ -18,7 +18,7 @@ var SILanguage = _webexCore.WebexPlugin.extend({
18
18
  languageCode: 'number',
19
19
  languageName: 'string'
20
20
  },
21
- version: "3.12.0-next.11"
21
+ version: "3.12.0-next.12"
22
22
  });
23
23
  var _default = exports.default = SILanguage;
24
24
  //# sourceMappingURL=siLanguage.js.map
@@ -1,4 +1,9 @@
1
1
  declare const ENABLED = "enabled";
2
2
  declare const CAN_SET = "canSet";
3
3
  declare const CAN_UNSET = "canUnset";
4
- export { ENABLED, CAN_SET, CAN_UNSET };
4
+ /**
5
+ * Body keys that represent audio controls. These do not support cross-locus
6
+ * authorization and must be sent directly to the current locus URL.
7
+ */
8
+ declare const AUDIO_CONTROL_BODY_KEYS: ReadonlySet<string>;
9
+ export { ENABLED, CAN_SET, CAN_UNSET, AUDIO_CONTROL_BODY_KEYS };
@@ -723,7 +723,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
723
723
  }, _callee1);
724
724
  }))();
725
725
  },
726
- version: "3.12.0-next.11"
726
+ version: "3.12.0-next.12"
727
727
  });
728
728
  var _default = exports.default = Webinar;
729
729
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -94,5 +94,5 @@
94
94
  "//": [
95
95
  "TODO: upgrade jwt-decode when moving to node 18"
96
96
  ],
97
- "version": "3.12.0-next.11"
97
+ "version": "3.12.0-next.12"
98
98
  }
@@ -1,5 +1,18 @@
1
+ import {camelCase} from 'lodash';
2
+ import {Control, Setting} from './enums';
3
+
1
4
  const ENABLED = 'enabled';
2
5
  const CAN_SET = 'canSet';
3
6
  const CAN_UNSET = 'canUnset';
4
7
 
5
- export {ENABLED, CAN_SET, CAN_UNSET};
8
+ /**
9
+ * Body keys that represent audio controls. These do not support cross-locus
10
+ * authorization and must be sent directly to the current locus URL.
11
+ */
12
+ const AUDIO_CONTROL_BODY_KEYS: ReadonlySet<string> = new Set([
13
+ Control.audio,
14
+ camelCase(Setting.muteOnEntry),
15
+ camelCase(Setting.disallowUnmute),
16
+ ]);
17
+
18
+ export {ENABLED, CAN_SET, CAN_UNSET, AUDIO_CONTROL_BODY_KEYS};
@@ -1,6 +1,6 @@
1
1
  import {camelCase} from 'lodash';
2
+ import ParameterError from '../common/errors/parameter';
2
3
  import PermissionError from '../common/errors/permission';
3
- import {CONTROLS, HTTP_VERBS} from '../constants';
4
4
  import MeetingRequest from '../meeting/request';
5
5
  import LoggerProxy from '../common/logs/logger-proxy';
6
6
  import {Control, Setting} from './enums';
@@ -153,6 +153,12 @@ export default class ControlsOptionsManager {
153
153
  * @returns {Promise<Array<any>>}- Promise resolving if the request was successful.
154
154
  */
155
155
  public update(...controls: Array<ControlConfig>) {
156
+ if (!this.locusUrl) {
157
+ return Promise.reject(
158
+ new ParameterError('The associated locusUrl for update() controls must be defined.')
159
+ );
160
+ }
161
+
156
162
  const payloads = controls.map((control) => {
157
163
  if (!Object.keys(Control).includes(control.scope)) {
158
164
  throw new Error(
@@ -172,18 +178,15 @@ export default class ControlsOptionsManager {
172
178
  });
173
179
 
174
180
  return payloads.reduce((previous, payload) => {
175
- const extraBody =
176
- this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl
177
- ? {authorizingLocusUrl: this.locusUrl}
178
- : {};
181
+ const requestParams = Util.getControlsRequestParams({
182
+ body: payload,
183
+ locusUrl: this.locusUrl,
184
+ mainLocusUrl: this.mainLocusUrl,
185
+ });
179
186
 
180
187
  return previous.then(() =>
181
188
  // @ts-ignore
182
- this.request.request({
183
- uri: `${this.mainLocusUrl || this.locusUrl}/${CONTROLS}`,
184
- body: {...payload, ...extraBody},
185
- method: HTTP_VERBS.PATCH,
186
- })
189
+ this.request.request(requestParams)
187
190
  );
188
191
  }, Promise.resolve());
189
192
  }
@@ -200,6 +203,12 @@ export default class ControlsOptionsManager {
200
203
  [Setting.muteOnEntry]?: boolean;
201
204
  [Setting.roles]?: Array<string>;
202
205
  }): Promise<any> {
206
+ if (!this.locusUrl) {
207
+ return Promise.reject(
208
+ new ParameterError('The associated locusUrl for setControls() must be defined.')
209
+ );
210
+ }
211
+
203
212
  LoggerProxy.logger.log(
204
213
  `ControlsOptionsManager:index#setControls --> ${JSON.stringify(setting)}`
205
214
  );
@@ -258,17 +267,15 @@ export default class ControlsOptionsManager {
258
267
  if (error) {
259
268
  return Promise.reject(error);
260
269
  }
261
- const extraBody =
262
- this.mainLocusUrl && this.mainLocusUrl !== this.locusUrl
263
- ? {authorizingLocusUrl: this.locusUrl}
264
- : {};
265
270
 
266
- // @ts-ignore
267
- return this.request.request({
268
- uri: `${this.mainLocusUrl || this.locusUrl}/${CONTROLS}`,
269
- body: {...body, ...extraBody},
270
- method: HTTP_VERBS.PATCH,
271
+ const requestParams = Util.getControlsRequestParams({
272
+ body,
273
+ locusUrl: this.locusUrl,
274
+ mainLocusUrl: this.mainLocusUrl,
271
275
  });
276
+
277
+ // @ts-ignore
278
+ return this.request.request(requestParams);
272
279
  }
273
280
 
274
281
  /**
@@ -1,5 +1,6 @@
1
- import {DISPLAY_HINTS} from '../constants';
1
+ import {CONTROLS, DISPLAY_HINTS, HTTP_VERBS} from '../constants';
2
2
  import {Control} from './enums';
3
+ import {AUDIO_CONTROL_BODY_KEYS} from './constants';
3
4
  import {
4
5
  ControlConfig,
5
6
  AudioProperties,
@@ -400,6 +401,85 @@ class Utils {
400
401
 
401
402
  return determinant;
402
403
  }
404
+
405
+ /**
406
+ * Check if all body keys represent audio controls.
407
+ *
408
+ * @param {Record<string, any>} body - The request body to inspect.
409
+ * @returns {boolean} - True if every key in the body is an audio control key.
410
+ */
411
+ public static isAudioControl(body: Record<string, any>): boolean {
412
+ return Object.keys(body).every((key) => AUDIO_CONTROL_BODY_KEYS.has(key));
413
+ }
414
+
415
+ /**
416
+ * Check if the current locus URL differs from the main locus URL,
417
+ * indicating a breakout session.
418
+ *
419
+ * @param {string} locusUrl - The current locus URL.
420
+ * @param {string} [mainLocusUrl] - The main locus URL.
421
+ * @returns {boolean} - True if in a breakout session.
422
+ */
423
+ public static isBreakoutLocusUrl(locusUrl: string, mainLocusUrl?: string): boolean {
424
+ return Boolean(mainLocusUrl) && mainLocusUrl !== locusUrl;
425
+ }
426
+
427
+ /**
428
+ * Resolve the target URL and extra body fields for a controls request,
429
+ * handling breakout session routing. Note: This is a pure computation function.
430
+ * It does not validate that locusUrl is
431
+ * defined. Callers must guard against falsy locusUrl before
432
+ * invoking this function.
433
+ * Mixed audio and non-audio keys in a single body (e.g., {audio: {...},
434
+ * raiseHand: {...}}) are treated as non-audio and routed to mainLocusUrl with
435
+ * authorizingLocusUrl. This means the audio portion would go through unsupported
436
+ * cross-locus authorization. Callers must not produce mixed payloads — update()
437
+ * sends each control scope as a separate request, and setControls() only handles
438
+ * audio-related settings.
439
+ *
440
+ * The authorizingLocusUrl mechanism on PATCH /loci/{lid}/controls is not supported
441
+ * for audio control updates (mute/unmute, muteOnEntry, disallowUnmute).
442
+ * Audio controls are not wired into the cross-locus GraphQL authorization path that
443
+ * other control types (raiseHand, viewParticipantList, admit, reactions, etc.) use.
444
+ * Specifically, the GraphQL authorization layer does not recognize audio as a control
445
+ * type eligible for remote locus authorization.
446
+ * This means authorizingLocusUrl is effectively ignored for audio controls and the
447
+ * server evaluates the request against the target locus only, where the host may not
448
+ * be currently joined.
449
+ * Audio control updates must be sent directly to the locus the user is currently in.
450
+ * If the host is in a breakout and wants to mute participants in that breakout, the
451
+ * request should target the breakout locus URL directly, not the main session locus
452
+ * with authorizingLocusUrl.
453
+ * Meeting-wide audio control actions (e.g., muting panelists across all breakouts
454
+ * from a single request) are not currently supported through this mechanism.
455
+ *
456
+ * @param {object} options
457
+ * @param {Record<string, any>} options.body - The request body.
458
+ * @param {string} options.locusUrl - The current locus URL. Must be defined (callers must validate).
459
+ * @param {string} [options.mainLocusUrl] - The main locus URL.
460
+ * @returns {{ uri: string, body: Record<string, any>, method: string }}
461
+ */
462
+ public static getControlsRequestParams(options: {
463
+ body: Record<string, any>;
464
+ locusUrl: string;
465
+ mainLocusUrl?: string;
466
+ }): {
467
+ uri: string;
468
+ body: Record<string, any>;
469
+ method: string;
470
+ } {
471
+ const {body, locusUrl, mainLocusUrl} = options;
472
+
473
+ const isAudio = Utils.isAudioControl(body);
474
+ const inBreakout = Utils.isBreakoutLocusUrl(locusUrl, mainLocusUrl);
475
+ const targetUrl = inBreakout && !isAudio ? mainLocusUrl : locusUrl;
476
+
477
+ return {
478
+ uri: `${targetUrl}/${CONTROLS}`,
479
+ body: inBreakout && !isAudio ? {...body, authorizingLocusUrl: locusUrl} : body,
480
+ method: HTTP_VERBS.PATCH,
481
+ };
482
+ }
403
483
  }
404
484
 
405
485
  export default Utils;
@@ -1,5 +1,6 @@
1
1
  import ControlsOptionsManager from '@webex/plugin-meetings/src/controls-options-manager';
2
2
  import Util from '@webex/plugin-meetings/src/controls-options-manager/util';
3
+ import ParameterError from '@webex/plugin-meetings/src/common/errors/parameter';
3
4
  import sinon from 'sinon';
4
5
  import {assert} from '@webex/test-helper-chai';
5
6
  import { HTTP_VERBS } from '@webex/plugin-meetings/src/constants';
@@ -76,6 +77,19 @@ describe('plugin-meetings', () => {
76
77
 
77
78
  assert.deepEqual(result, request.request.firstCall.returnValue);
78
79
  });
80
+
81
+ it('should send setMuteOnEntry to locusUrl without authorizingLocusUrl when in breakout', () => {
82
+ manager.setDisplayHints(['ENABLE_MUTE_ON_ENTRY']);
83
+ manager.mainLocusUrl = 'test/main';
84
+
85
+ const result = manager.setMuteOnEntry(true);
86
+
87
+ assert.calledWith(request.request, { uri: 'test/id/controls',
88
+ body: { muteOnEntry: { enabled: true } },
89
+ method: HTTP_VERBS.PATCH});
90
+
91
+ assert.deepEqual(result, request.request.firstCall.returnValue);
92
+ });
79
93
  });
80
94
 
81
95
  describe('setDisallowUnmute', () => {
@@ -118,6 +132,19 @@ describe('plugin-meetings', () => {
118
132
 
119
133
  assert.deepEqual(result, request.request.firstCall.returnValue);
120
134
  });
135
+
136
+ it('should send setDisallowUnmute to locusUrl without authorizingLocusUrl when in breakout', () => {
137
+ manager.setDisplayHints(['ENABLE_HARD_MUTE']);
138
+ manager.mainLocusUrl = 'test/main';
139
+
140
+ const result = manager.setDisallowUnmute(true);
141
+
142
+ assert.calledWith(request.request, { uri: 'test/id/controls',
143
+ body: { disallowUnmute: { enabled: true } },
144
+ method: HTTP_VERBS.PATCH});
145
+
146
+ assert.deepEqual(result, request.request.firstCall.returnValue);
147
+ });
121
148
  });
122
149
  });
123
150
 
@@ -138,6 +165,18 @@ describe('plugin-meetings', () => {
138
165
  });
139
166
  });
140
167
 
168
+ it('should reject with ParameterError when locusUrl is not set', () => {
169
+ const noLocusManager = new ControlsOptionsManager(request);
170
+
171
+ const result = noLocusManager.update({scope: 'audio', properties: {muted: true}});
172
+
173
+ assert.notCalled(request.request);
174
+ return assert.isRejected(result).then((err) => {
175
+ assert.instanceOf(err, ParameterError);
176
+ assert.match(err.message, /locusUrl.*must be defined/);
177
+ });
178
+ });
179
+
141
180
  it('should throw an error if the scope is not supported', () => {
142
181
  const scope = 'invalid';
143
182
 
@@ -203,7 +242,7 @@ describe('plugin-meetings', () => {
203
242
  });
204
243
  });
205
244
 
206
- it('should call request with mainLocusUrl and locusUrl as authorizingLocusUrl if mainLocusUrl is exist and not same with locusUrl', () => {
245
+ it('should send audio controls to locusUrl without authorizingLocusUrl and non-audio to mainLocusUrl with authorizingLocusUrl when in breakout', () => {
207
246
  const restorable = Util.canUpdate;
208
247
  Util.canUpdate = sinon.stub().returns(true);
209
248
  manager.mainLocusUrl = 'test/main';
@@ -213,15 +252,16 @@ describe('plugin-meetings', () => {
213
252
 
214
253
  return manager.update(audio, reactions)
215
254
  .then(() => {
255
+ // Audio controls go directly to current locusUrl (no cross-locus authorization)
216
256
  assert.calledWith(request.request, {
217
- uri: 'test/main/controls',
257
+ uri: 'test/id/controls',
218
258
  body: {
219
259
  audio: audio.properties,
220
- authorizingLocusUrl: 'test/id'
221
260
  },
222
261
  method: HTTP_VERBS.PATCH,
223
262
  });
224
263
 
264
+ // Non-audio controls go to mainLocusUrl with authorizingLocusUrl
225
265
  assert.calledWith(request.request, {
226
266
  uri: 'test/main/controls',
227
267
  body: {
@@ -234,6 +274,49 @@ describe('plugin-meetings', () => {
234
274
  Util.canUpdate = restorable;
235
275
  });
236
276
  });
277
+
278
+ it('should send audio controls to locusUrl without authorizingLocusUrl when in breakout', () => {
279
+ const restorable = Util.canUpdate;
280
+ Util.canUpdate = sinon.stub().returns(true);
281
+ manager.mainLocusUrl = 'test/main';
282
+
283
+ const audio = {scope: 'audio', properties: {muted: true, disallowUnmute: false}};
284
+
285
+ return manager.update(audio)
286
+ .then(() => {
287
+ assert.calledWith(request.request, {
288
+ uri: 'test/id/controls',
289
+ body: {
290
+ audio: audio.properties,
291
+ },
292
+ method: HTTP_VERBS.PATCH,
293
+ });
294
+
295
+ Util.canUpdate = restorable;
296
+ });
297
+ });
298
+
299
+ it('should send non-audio controls to mainLocusUrl with authorizingLocusUrl when in breakout', () => {
300
+ const restorable = Util.canUpdate;
301
+ Util.canUpdate = sinon.stub().returns(true);
302
+ manager.mainLocusUrl = 'test/main';
303
+
304
+ const reactions = {scope: 'reactions', properties: {enabled: true}};
305
+
306
+ return manager.update(reactions)
307
+ .then(() => {
308
+ assert.calledWith(request.request, {
309
+ uri: 'test/main/controls',
310
+ body: {
311
+ reactions: reactions.properties,
312
+ authorizingLocusUrl: 'test/id',
313
+ },
314
+ method: HTTP_VERBS.PATCH,
315
+ });
316
+
317
+ Util.canUpdate = restorable;
318
+ });
319
+ });
237
320
  });
238
321
 
239
322
  describe('Mute/Unmute All', () => {
@@ -252,6 +335,18 @@ describe('plugin-meetings', () => {
252
335
  })
253
336
  });
254
337
 
338
+ it('should reject with ParameterError when locusUrl is not set', () => {
339
+ const noLocusManager = new ControlsOptionsManager(request);
340
+
341
+ const result = noLocusManager.setMuteAll(true, true, true);
342
+
343
+ assert.notCalled(request.request);
344
+ return assert.isRejected(result).then((err) => {
345
+ assert.instanceOf(err, ParameterError);
346
+ assert.match(err.message, /locusUrl.*must be defined/);
347
+ });
348
+ });
349
+
255
350
  it('rejects when correct display hint is not present mutedEnabled=false', () => {
256
351
  const result = manager.setMuteAll(false, false, false);
257
352
 
@@ -340,14 +435,27 @@ describe('plugin-meetings', () => {
340
435
  assert.deepEqual(result, request.request.firstCall.returnValue);
341
436
  });
342
437
 
343
- it('request with mainLocusUrl and make locusUrl as authorizingLocusUrl if mainLocusUrl is exist and not same with locusUrl', () => {
438
+ it('should send setMuteAll to locusUrl without authorizingLocusUrl when in breakout', () => {
344
439
  manager.setDisplayHints(['MUTE_ALL', 'DISABLE_HARD_MUTE', 'DISABLE_MUTE_ON_ENTRY']);
345
440
  manager.mainLocusUrl = `test/main`;
346
441
 
347
442
  const result = manager.setMuteAll(true, true, true, ['attendee']);
348
443
 
349
- assert.calledWith(request.request, { uri: 'test/main/controls',
350
- body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] }, authorizingLocusUrl: 'test/id' },
444
+ assert.calledWith(request.request, { uri: 'test/id/controls',
445
+ body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] } },
446
+ method: HTTP_VERBS.PATCH});
447
+
448
+ assert.deepEqual(result, request.request.firstCall.returnValue);
449
+ });
450
+
451
+ it('should send setMuteAll with PANELIST role to locusUrl without authorizingLocusUrl when in breakout', () => {
452
+ manager.setDisplayHints(['MUTE_ALL', 'ENABLE_HARD_MUTE', 'ENABLE_MUTE_ON_ENTRY']);
453
+ manager.mainLocusUrl = `test/main`;
454
+
455
+ const result = manager.setMuteAll(true, true, true, ['PANELIST']);
456
+
457
+ assert.calledWith(request.request, { uri: 'test/id/controls',
458
+ body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['PANELIST'] } },
351
459
  method: HTTP_VERBS.PATCH});
352
460
 
353
461
  assert.deepEqual(result, request.request.firstCall.returnValue);
@@ -799,6 +799,171 @@ describe('plugin-meetings', () => {
799
799
  );
800
800
  });
801
801
  });
802
+
803
+ describe('isAudioControl()', () => {
804
+ it('should return true when all body keys are audio control keys', () => {
805
+ assert.isTrue(ControlsOptionsUtil.isAudioControl({audio: {muted: true}}));
806
+ });
807
+
808
+ it('should return true when body has muteOnEntry key', () => {
809
+ assert.isTrue(ControlsOptionsUtil.isAudioControl({muteOnEntry: {enabled: true}}));
810
+ });
811
+
812
+ it('should return true when body has disallowUnmute key', () => {
813
+ assert.isTrue(ControlsOptionsUtil.isAudioControl({disallowUnmute: {enabled: true}}));
814
+ });
815
+
816
+ it('should return true when body has multiple audio control keys', () => {
817
+ assert.isTrue(ControlsOptionsUtil.isAudioControl({audio: {muted: true}, muteOnEntry: {enabled: true}, disallowUnmute: {enabled: true}}));
818
+ });
819
+
820
+ it('should return false when body has a non-audio control key', () => {
821
+ assert.isFalse(ControlsOptionsUtil.isAudioControl({raiseHand: {enabled: true}}));
822
+ });
823
+
824
+ it('should return false when body has a mix of audio and non-audio keys', () => {
825
+ assert.isFalse(ControlsOptionsUtil.isAudioControl({audio: {muted: true}, raiseHand: {enabled: true}}));
826
+ });
827
+
828
+ it('should return true for an empty body', () => {
829
+ assert.isTrue(ControlsOptionsUtil.isAudioControl({}));
830
+ });
831
+ });
832
+
833
+ describe('isBreakoutLocusUrl()', () => {
834
+ it('should return true when mainLocusUrl differs from locusUrl', () => {
835
+ assert.isTrue(ControlsOptionsUtil.isBreakoutLocusUrl('locus/breakout', 'locus/main'));
836
+ });
837
+
838
+ it('should return false when mainLocusUrl equals locusUrl', () => {
839
+ assert.isFalse(ControlsOptionsUtil.isBreakoutLocusUrl('locus/main', 'locus/main'));
840
+ });
841
+
842
+ it('should return false when mainLocusUrl is undefined', () => {
843
+ assert.isFalse(ControlsOptionsUtil.isBreakoutLocusUrl('locus/breakout', undefined));
844
+ });
845
+
846
+ it('should return false when mainLocusUrl is null', () => {
847
+ assert.isFalse(ControlsOptionsUtil.isBreakoutLocusUrl('locus/breakout', null));
848
+ });
849
+
850
+ it('should return false when mainLocusUrl is empty string', () => {
851
+ assert.isFalse(ControlsOptionsUtil.isBreakoutLocusUrl('locus/breakout', ''));
852
+ });
853
+ });
854
+
855
+ describe('getControlsRequestParams()', () => {
856
+ const locusUrl = 'locus/breakout';
857
+ const mainLocusUrl = 'locus/main';
858
+
859
+ it('should return full request params targeting locusUrl when not in a breakout', () => {
860
+ const result = ControlsOptionsUtil.getControlsRequestParams({
861
+ body: {raiseHand: {enabled: true}},
862
+ locusUrl: 'locus/main',
863
+ mainLocusUrl: 'locus/main',
864
+ });
865
+
866
+ assert.equal(result.uri, 'locus/main/controls');
867
+ assert.deepEqual(result.body, {raiseHand: {enabled: true}});
868
+ assert.equal(result.method, 'PATCH');
869
+ });
870
+
871
+ it('should return mainLocusUrl with authorizingLocusUrl in body for non-audio controls in a breakout', () => {
872
+ const result = ControlsOptionsUtil.getControlsRequestParams({
873
+ body: {raiseHand: {enabled: true}},
874
+ locusUrl,
875
+ mainLocusUrl,
876
+ });
877
+
878
+ assert.equal(result.uri, 'locus/main/controls');
879
+ assert.deepEqual(result.body, {raiseHand: {enabled: true}, authorizingLocusUrl: locusUrl});
880
+ assert.equal(result.method, 'PATCH');
881
+ });
882
+
883
+ it('should return locusUrl without authorizingLocusUrl for audio controls in a breakout', () => {
884
+ const result = ControlsOptionsUtil.getControlsRequestParams({
885
+ body: {audio: {muted: true}},
886
+ locusUrl,
887
+ mainLocusUrl,
888
+ });
889
+
890
+ assert.equal(result.uri, 'locus/breakout/controls');
891
+ assert.deepEqual(result.body, {audio: {muted: true}});
892
+ assert.equal(result.method, 'PATCH');
893
+ });
894
+
895
+ it('should return locusUrl without authorizingLocusUrl for muteOnEntry in a breakout', () => {
896
+ const result = ControlsOptionsUtil.getControlsRequestParams({
897
+ body: {muteOnEntry: {enabled: true}},
898
+ locusUrl,
899
+ mainLocusUrl,
900
+ });
901
+
902
+ assert.equal(result.uri, 'locus/breakout/controls');
903
+ assert.deepEqual(result.body, {muteOnEntry: {enabled: true}});
904
+ assert.equal(result.method, 'PATCH');
905
+ });
906
+
907
+ it('should return locusUrl without authorizingLocusUrl for disallowUnmute in a breakout', () => {
908
+ const result = ControlsOptionsUtil.getControlsRequestParams({
909
+ body: {disallowUnmute: {enabled: true}},
910
+ locusUrl,
911
+ mainLocusUrl,
912
+ });
913
+
914
+ assert.equal(result.uri, 'locus/breakout/controls');
915
+ assert.deepEqual(result.body, {disallowUnmute: {enabled: true}});
916
+ assert.equal(result.method, 'PATCH');
917
+ });
918
+
919
+ it('should return locusUrl when mainLocusUrl is undefined', () => {
920
+ const result = ControlsOptionsUtil.getControlsRequestParams({
921
+ body: {raiseHand: {enabled: true}},
922
+ locusUrl,
923
+ mainLocusUrl: undefined,
924
+ });
925
+
926
+ assert.equal(result.uri, 'locus/breakout/controls');
927
+ assert.deepEqual(result.body, {raiseHand: {enabled: true}});
928
+ assert.equal(result.method, 'PATCH');
929
+ });
930
+
931
+ it('should return locusUrl when mainLocusUrl is null', () => {
932
+ const result = ControlsOptionsUtil.getControlsRequestParams({
933
+ body: {raiseHand: {enabled: true}},
934
+ locusUrl,
935
+ mainLocusUrl: null,
936
+ });
937
+
938
+ assert.equal(result.uri, 'locus/breakout/controls');
939
+ assert.deepEqual(result.body, {raiseHand: {enabled: true}});
940
+ assert.equal(result.method, 'PATCH');
941
+ });
942
+
943
+ it('should return locusUrl when mainLocusUrl is empty string', () => {
944
+ const result = ControlsOptionsUtil.getControlsRequestParams({
945
+ body: {raiseHand: {enabled: true}},
946
+ locusUrl,
947
+ mainLocusUrl: '',
948
+ });
949
+
950
+ assert.equal(result.uri, 'locus/breakout/controls');
951
+ assert.deepEqual(result.body, {raiseHand: {enabled: true}});
952
+ assert.equal(result.method, 'PATCH');
953
+ });
954
+
955
+ it('should return locusUrl for audio controls when not in a breakout', () => {
956
+ const result = ControlsOptionsUtil.getControlsRequestParams({
957
+ body: {audio: {muted: true}},
958
+ locusUrl: 'locus/main',
959
+ mainLocusUrl: 'locus/main',
960
+ });
961
+
962
+ assert.equal(result.uri, 'locus/main/controls');
963
+ assert.deepEqual(result.body, {audio: {muted: true}});
964
+ assert.equal(result.method, 'PATCH');
965
+ });
966
+ });
802
967
  });
803
968
  });
804
969
  });