@webex/internal-plugin-user 3.12.0-mobius-socket.1 → 3.12.0-next.10

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.
@@ -125,7 +125,7 @@ var UserUUIDBatcher = _webexCore.WebexPlugin.extend({
125
125
  request: function request(payload) {
126
126
  return payload.create ? this.creator.request(payload.email) : this.faker.request(payload.email);
127
127
  },
128
- version: "3.12.0-mobius-socket.1"
128
+ version: "3.12.0-next.10"
129
129
  });
130
130
  var _default = exports.default = UserUUIDBatcher;
131
131
  //# sourceMappingURL=user-uuid-batcher.js.map
package/dist/user.js CHANGED
@@ -10,12 +10,17 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
10
10
  _Object$defineProperty(exports, "__esModule", {
11
11
  value: true
12
12
  });
13
+ exports.SCIM_SCHEMAS = void 0;
14
+ exports.buildMeetingSiteList = buildMeetingSiteList;
15
+ exports.buildPreferredSiteBody = buildPreferredSiteBody;
13
16
  exports.default = void 0;
17
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
18
+ var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/applyDecoratedDescriptor"));
19
+ var _set = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/set"));
14
20
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
15
21
  var _apply = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/apply"));
16
22
  var _getOwnPropertyDescriptor = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor"));
17
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
18
- var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/applyDecoratedDescriptor"));
23
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
19
24
  var _lodash = require("lodash");
20
25
  var _common = require("@webex/common");
21
26
  var _webexCore = require("@webex/webex-core");
@@ -27,6 +32,50 @@ var _dec, _dec2, _dec3, _dec4, _obj;
27
32
  */
28
33
  function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor2(e, r).enumerable; })), t.push.apply(t, o); } return t; }
29
34
  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$getOwnPropertyDescriptor2(t, r)); }); } return e; }
35
+ var SCIM_SCHEMAS = exports.SCIM_SCHEMAS = ['urn:scim:schemas:core:1.0', 'urn:scim:schemas:extension:cisco:commonidentity:1.0'];
36
+
37
+ /**
38
+ * Builds a SCIM PATCH body for updating the user's preferred Webex site.
39
+ * Matches the native client's SCIM format: delete old + add new in a single PATCH.
40
+ * @param {string} newSiteUrl - The new preferred site
41
+ * @param {string} [oldSiteUrl] - The previous preferred site to remove
42
+ * @returns {Object} SCIM-formatted request body
43
+ */
44
+ function buildPreferredSiteBody(newSiteUrl, oldSiteUrl) {
45
+ var userPreferences = [];
46
+ if (oldSiteUrl) {
47
+ userPreferences.push({
48
+ operation: 'delete',
49
+ value: "\"preferredWebExSite\":\"".concat(oldSiteUrl, "\"")
50
+ });
51
+ }
52
+ userPreferences.push({
53
+ value: "\"preferredWebExSite\":\"".concat(newSiteUrl, "\"")
54
+ });
55
+ return {
56
+ schemas: SCIM_SCHEMAS,
57
+ userPreferences: userPreferences
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Builds a deduplicated, sorted list of meeting sites from a user profile.
63
+ * Merges linkedTrainSiteNames and trainSiteNames, filters out attendee-only
64
+ * sites (those containing '#'), and sorts alphabetically.
65
+ * Matches the native client's site list filtering logic.
66
+ * @param {Object} user - User profile object
67
+ * @param {string[]} [user.linkedTrainSiteNames] - Linked training site names
68
+ * @param {string[]} [user.trainSiteNames] - Training site names
69
+ * @returns {string[]} Sorted array of site URLs
70
+ */
71
+ function buildMeetingSiteList(user) {
72
+ var linked = user && user.linkedTrainSiteNames || [];
73
+ var train = user && user.trainSiteNames || [];
74
+ return (0, _toConsumableArray2.default)(new _set.default(linked.concat(train))).filter(function (site) {
75
+ return site.indexOf('#') === -1;
76
+ }).sort();
77
+ }
78
+
30
79
  /**
31
80
  * @class
32
81
  */
@@ -312,6 +361,53 @@ var User = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)('@
312
361
  return res.body;
313
362
  });
314
363
  },
364
+ /**
365
+ * Updates the user's preferred Webex meeting site via org-scoped SCIM PATCH.
366
+ * @instance
367
+ * @memberof User
368
+ * @param {Object} options
369
+ * @param {string} options.newSiteUrl - The new preferred site (e.g., 'example.webex.com')
370
+ * @param {string} [options.oldSiteUrl] - The previous preferred site to remove
371
+ * @param {string} [options.orgId] - Organization ID. If not provided, extracted from credentials.
372
+ * @returns {Promise<Object>} Resolves with the SCIM response body
373
+ */
374
+ updatePreferredWebexSite: function updatePreferredWebexSite() {
375
+ var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
376
+ newSiteUrl = _ref2.newSiteUrl,
377
+ oldSiteUrl = _ref2.oldSiteUrl,
378
+ orgId = _ref2.orgId;
379
+ if (!newSiteUrl) {
380
+ return _promise.default.reject(new Error('`options.newSiteUrl` is required'));
381
+ }
382
+ try {
383
+ var resolvedOrgId = orgId || this.webex.credentials.getOrgId();
384
+ var userId = this.webex.internal.device.userId;
385
+ if (!userId) {
386
+ return _promise.default.reject(new Error('device.userId is not available — ensure device.register() has completed'));
387
+ }
388
+ var identityUrl = this.webex.config.credentials.identity.url;
389
+ return this.request({
390
+ uri: "".concat(identityUrl, "/identity/scim/").concat(resolvedOrgId, "/v1/Users/").concat(userId),
391
+ method: 'PATCH',
392
+ body: buildPreferredSiteBody(newSiteUrl, oldSiteUrl)
393
+ }).then(function (res) {
394
+ return res.body;
395
+ });
396
+ } catch (error) {
397
+ return _promise.default.reject(error);
398
+ }
399
+ },
400
+ /**
401
+ * Returns a sorted, filtered list of meeting sites from a user profile.
402
+ * Delegates to the pure buildMeetingSiteList function.
403
+ * @instance
404
+ * @memberof User
405
+ * @param {Object} user - User profile object from webex.internal.user.get()
406
+ * @returns {string[]} Sorted array of site URLs
407
+ */
408
+ getMeetingSiteList: function getMeetingSiteList(user) {
409
+ return buildMeetingSiteList(user);
410
+ },
315
411
  /**
316
412
  * Updates the current user's display name
317
413
  * @param {Object} options
@@ -451,7 +547,7 @@ var User = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)('@
451
547
  _extractEmailAddress: function _extractEmailAddress(user) {
452
548
  return user.email || user.emailAddress || user.entryEmail || user;
453
549
  },
454
- version: "3.12.0-mobius-socket.1"
550
+ version: "3.12.0-next.10"
455
551
  }, (0, _applyDecoratedDescriptor2.default)(_obj, "activate", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "activate"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "getUUID", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "getUUID"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initialize", [_dec3], (0, _getOwnPropertyDescriptor.default)(_obj, "initialize"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "register", [_dec4], (0, _getOwnPropertyDescriptor.default)(_obj, "register"), _obj), _obj));
456
552
  var _default2 = exports.default = User;
457
553
  //# sourceMappingURL=user.js.map
package/dist/user.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["_lodash","require","_common","_webexCore","_userUuidBatcher","_interopRequireDefault","_userUuidStore","_dec","_dec2","_dec3","_dec4","_obj","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor2","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","User","WebexPlugin","extend","waitForValue","oneFlight","keyFactory","email","options","String","create","persist","deprecated","namespace","children","batcher","UserUUIDBatcher","props","hasPassword","type","session","store","UserUUIDStore","activate","_this","undefined","verificationToken","confirmationCode","id","_promise","reject","Error","scope","webex","config","credentials","activateOptions","request","uri","activationUrl","method","body","auth","user","client_id","pass","client_secret","sendImmediately","then","res","set","supertoken","tokenData","asUUID","_this2","isArray","all","map","u","_extractUUID","force","patterns","uuid","test","resolve","_extractEmailAddress","getUUID","fetchUUID","_this3","recordUUID","emailAddress","generateOTP","generateOtpUrl","get","_this4","service","resource","tap","_this5","getByEmail","userExists","catch","initialize","_len","args","Array","_key","_apply","prototype","add","register","verify","_setUser","_this6","getUserToken","token","concat","setPasswordUrl","internal","device","userId","headers","authorization","toString","setPassword","_this7","password","schemas","updateName","_ref","givenName","familyName","displayName","name","update","validateOTP","_this8","oneTimePassword","validateOtpUrl","_this9","verifyDefaults","_options","services","collectPreauthCatalog","getClientToken","preloginId","shouldRefreshAccessToken","sso","getUserCI","lookupCI","verifyOptions","suppressEmail","userEntities","idBrokerUrl","idbroker","url","identityUrl","identity","entryUUID","entryEmail","version","_applyDecoratedDescriptor2","_getOwnPropertyDescriptor","_default2","exports"],"sources":["user.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {isArray} from 'lodash';\nimport {deprecated, oneFlight, patterns, tap} from '@webex/common';\nimport {persist, WebexPlugin, waitForValue} from '@webex/webex-core';\n\nimport UserUUIDBatcher from './user-uuid-batcher';\nimport UserUUIDStore from './user-uuid-store';\n\n/**\n * @class\n */\nconst User = WebexPlugin.extend({\n namespace: 'User',\n\n children: {\n batcher: UserUUIDBatcher,\n },\n\n props: {\n /**\n * Indicates if the current user is known to have a password.\n * @instance\n * @memberof User\n * @type {boolean}\n */\n hasPassword: {\n default: false,\n type: 'boolean',\n },\n },\n\n session: {\n store: {\n default() {\n return new UserUUIDStore();\n },\n type: 'any',\n },\n },\n\n @waitForValue('@')\n /**\n * Activates a Webex user account and exchanges for user token.\n * @instance\n * @memberof User\n * @param {Object} options\n * @param {Object} options.confirmationCode (required -- optional if verification token is provided)\n * @param {Object} options.id (required -- optional if verification token is provided)\n * @param {Object} options.verificationToken (required -- optional if uuid and verification token provided)\n * @param {Object} options.email (required with verificationToken for Federation/global user)\n * @returns {Promise} Resolves with a userSession\n */\n activate(options = {}) {\n if (!(options.verificationToken || (options.confirmationCode && options.id))) {\n return Promise.reject(\n new Error(\n 'either options.verificationToken is required or both options.confirmationCode and options.id are required'\n )\n );\n }\n\n options.scope = this.webex.config.credentials.scope;\n\n // if we have options.email and options.verificationToken\n // and Federation flag is enabled, flag that we need to\n // lookup user's CI.\n const activateOptions = {...options};\n\n delete activateOptions.email;\n\n return this.request({\n uri: this.webex.config.credentials.activationUrl,\n method: 'POST',\n body: activateOptions,\n auth: {\n user: this.webex.config.credentials.client_id,\n pass: this.webex.config.credentials.client_secret,\n sendImmediately: true,\n },\n }).then((res) => {\n this.webex.credentials.set({supertoken: res.body.tokenData});\n\n return res.body;\n });\n },\n\n /**\n * Converts a user-identifying object to a uuid, perhaps by doing a network\n * lookup\n * @param {string|Object} user\n * @param {Object} options\n * @param {boolean} options.create if true, ensures the return UUID refers to\n * an existing user (rather than creating one deterministically based on email\n * address), even if that user must be created\n * @returns {Promise<string>}\n */\n asUUID(user, options) {\n if (!user) {\n return Promise.reject(new Error('`user` is required'));\n }\n\n if (isArray(user)) {\n return Promise.all(user.map((u) => this.asUUID(u, options)));\n }\n\n const id = this._extractUUID(user);\n\n if (!(options && options.force) && patterns.uuid.test(id)) {\n return Promise.resolve(id);\n }\n\n const email = this._extractEmailAddress(user);\n\n if (!patterns.email.test(email)) {\n return Promise.reject(new Error('Provided user object does not appear to identify a user'));\n }\n\n return this.getUUID(email, options);\n },\n\n /**\n * Requests a uuid from the api\n * @param {string} email\n * @param {Object} options\n * @param {boolean} options.create\n * @returns {Promise<string>}\n */\n fetchUUID(email, options) {\n return this.batcher\n .request({\n email,\n create: options && options.create,\n })\n .then((user) => this.recordUUID({emailAddress: email, ...user}).then(() => user.id));\n },\n /**\n * Generates One Time Password.\n * @instance\n * @param {Object} options\n * @param {string} options.email\n * @param {string} options.id\n * @returns {Promise}\n */\n generateOTP(options = {}) {\n if (!(options.email || options.id)) {\n return Promise.reject(new Error('One of `options.email` or `options.id` is required'));\n }\n\n return this.request({\n uri: this.webex.config.credentials.generateOtpUrl,\n method: 'POST',\n body: options,\n auth: {\n user: this.webex.config.credentials.client_id,\n pass: this.webex.config.credentials.client_secret,\n },\n }).then((res) => res.body);\n },\n\n /**\n * Fetches details about the current user\n * @returns {Promise<Object>}\n */\n get() {\n return this.request({\n service: 'conversation',\n resource: 'users',\n })\n .then((res) => res.body)\n .then(\n tap((user) =>\n this.recordUUID({\n id: user.id,\n // CI endpoints don't use the same user format as actors, so, email may\n // be in one of a few fields\n emailAddress: user.email || user.emailAddress,\n })\n )\n );\n },\n\n /**\n * Converts an email address to a uuid, perhaps by doing a network lookup\n * @param {string} email\n * @param {Object} options\n * @param {boolean} options.create\n * @returns {Promise<string>}\n */\n @oneFlight({keyFactory: (email, options) => email + String(options && options.create)})\n getUUID(email, options) {\n return this.store\n .getByEmail(email)\n .then((user) => {\n if (options && options.create && !user.userExists) {\n return Promise.reject(new Error('User for specified email cannot be confirmed to exist'));\n }\n\n if (!user.id) {\n return Promise.reject(new Error('No id recorded for specified user'));\n }\n\n return user.id;\n })\n .catch(() => this.fetchUUID(email, options));\n },\n\n @persist('@')\n initialize(...args) {\n return Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n },\n\n /**\n * Caches the uuid for the specified email address\n * @param {Object} user\n * @param {string} user.id\n * @param {string} user.emailAddress\n * @returns {Promise}\n */\n recordUUID(user) {\n if (!user) {\n return Promise.reject(new Error('`user` is required'));\n }\n\n if (!user.id) {\n return Promise.reject(new Error('`user.id` is required'));\n }\n\n if (!patterns.uuid.test(user.id)) {\n return Promise.reject(new Error('`user.id` must be a uuid'));\n }\n\n if (!user.emailAddress) {\n return Promise.reject(new Error('`user.emailAddress` is required'));\n }\n\n if (!patterns.email.test(user.emailAddress)) {\n return Promise.reject(new Error('`user.emailAddress` must be an email address'));\n }\n\n return this.store.add(user);\n },\n\n @deprecated('Use User#verify()')\n register(...args) {\n return this.verify(...args);\n },\n\n /**\n * Updates a user with webex.\n * @param {Object} body\n * @private\n * @returns {Promise} Resolves with a response from PATCH request\n */\n _setUser(body) {\n return this.webex.credentials.getUserToken().then((token) =>\n this.request({\n uri: `${this.webex.config.credentials.setPasswordUrl}/${this.webex.internal.device.userId}`,\n method: 'PATCH',\n headers: {\n authorization: token.toString(),\n },\n body,\n })\n );\n },\n\n /**\n * Updates a user's password with webex.\n * @instance\n * @memberof User\n * @param {Object} options\n * @param {string} options.password (required)\n * @param {string} options.email (required when federation enabled)\n * @returns {Promise} Resolves with complete user object containing new password\n */\n setPassword(options) {\n options = options || {};\n if (!options.password) {\n return Promise.reject(new Error('`options.password` is required'));\n }\n\n return this._setUser({\n schemas: ['urn:scim:schemas:core:1.0', 'urn:scim:schemas:extension:cisco:commonidentity:1.0'],\n password: options.password,\n }).then((res) => {\n this.hasPassword = true;\n\n return res.body;\n });\n },\n\n /**\n * Updates a user's name with webex.\n * @instance\n * @memberof User\n * @param {string} givenName\n * @param {string} familyName\n * @param {string} displayName\n * @returns {Promise<Object>}\n */\n updateName({givenName, familyName, displayName} = {}) {\n if (!(givenName || familyName || displayName)) {\n return Promise.reject(\n new Error('One of `givenName` and `familyName` or `displayName` is required')\n );\n }\n\n return this._setUser({\n schemas: ['urn:scim:schemas:core:1.0', 'urn:scim:schemas:extension:cisco:commonidentity:1.0'],\n name: {givenName, familyName},\n displayName,\n }).then((res) => res.body);\n },\n\n /**\n * Updates the current user's display name\n * @param {Object} options\n * @param {string} options.displayName\n * @returns {Promise<Object>}\n */\n update(options) {\n options = options || {};\n if (!options.displayName) {\n return Promise.reject(new Error('`options.displayName` is required'));\n }\n\n return this.request({\n method: 'PATCH',\n service: 'conversation',\n resource: 'users/user',\n body: options,\n }).then((res) => res.body);\n },\n\n /**\n * Validated One Time Password.\n * @instance\n * @param {Object} options\n * @param {string} options.email\n * @param {string} options.id\n * @param {string} options.oneTimePassword\n * @returns {Promise}\n */\n validateOTP(options = {}) {\n if (!(options.email || options.id) || !options.oneTimePassword) {\n return Promise.reject(\n new Error(\n 'One of `options.email` or `options.id` and `options.oneTimePassword` are required'\n )\n );\n }\n\n options.scope = this.webex.config.credentials.scope;\n\n return this.request({\n uri: this.webex.config.credentials.validateOtpUrl,\n method: 'POST',\n body: options,\n auth: {\n user: this.webex.config.credentials.client_id,\n pass: this.webex.config.credentials.client_secret,\n },\n }).then((res) => {\n this.webex.credentials.set({supertoken: res.body.tokenData});\n\n return res.body;\n });\n },\n\n /**\n * Determines if the specified user needs to signup or can signin.\n * Triggers activation email if client credentials are used\n * @param {Object} options\n * @param {string} options.email (required)\n * @param {string} options.reqId required if need to check email status\n * @param {string} options.preloginId\n * @returns {Promise<Object>}\n */\n verify(options) {\n options = {...this.config.verifyDefaults, ...options};\n const {email} = options;\n\n if (!email) {\n return Promise.reject(new Error('`options.email` is required'));\n }\n\n return this.webex.internal.services\n .collectPreauthCatalog({email})\n .then(() => this.webex.credentials.getUserToken())\n .catch(() => this.webex.credentials.getClientToken())\n .then((token) =>\n this.request({\n service: 'atlas',\n resource: 'users/activations',\n method: 'POST',\n headers: {\n authorization: token.toString(),\n 'x-prelogin-userid': options.preloginId,\n },\n body: options,\n shouldRefreshAccessToken: false,\n })\n )\n .then((res) => {\n if (res.body.hasPassword || res.body.sso) {\n this.hasPassword = true;\n }\n\n return res.body;\n });\n },\n\n /**\n * If the passed-in lookupCI is true, retrieve the user's\n * CI from Atlas and return the URL's via a Promise.\n * Otherwise, return current CI in config via a Promise.\n * Useful in a Promise chain to retrieve the CI based on\n * conditions like Federation enabled, and suppresses sending\n * an additional email to the user, since this is just a\n * look-up.\n * @param {string} email (required)\n * @param {boolean} lookupCI (required)\n * @returns {Promise<Object>}\n */\n getUserCI(email, lookupCI) {\n if (lookupCI) {\n // call verify first to get the user's CI, but suppress sending another email\n const verifyOptions = {\n email,\n suppressEmail: true,\n };\n\n return this.verify(verifyOptions).then((res) => Promise.resolve(res.userEntities));\n }\n\n return Promise.resolve({\n idBrokerUrl: this.webex.config.credentials.idbroker.url,\n identityUrl: this.webex.config.credentials.identity.url,\n });\n },\n\n /**\n * Extracts the uuid from a user identifying object\n * @param {string|Object} user\n * @private\n * @returns {string}\n */\n _extractUUID(user) {\n return user.entryUUID || user.id || user;\n },\n\n /**\n * Extracts the email address from a user identifying object\n * @param {string|Object} user\n * @private\n * @returns {string}\n */\n _extractEmailAddress(user) {\n return user.email || user.emailAddress || user.entryEmail || user;\n },\n});\n\nexport default User;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_lodash","require","_common","_webexCore","_userUuidBatcher","_interopRequireDefault","_userUuidStore","_dec","_dec2","_dec3","_dec4","_obj","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor2","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","SCIM_SCHEMAS","exports","buildPreferredSiteBody","newSiteUrl","oldSiteUrl","userPreferences","operation","value","concat","schemas","buildMeetingSiteList","user","linked","linkedTrainSiteNames","train","trainSiteNames","_toConsumableArray2","_set","site","indexOf","sort","User","WebexPlugin","extend","waitForValue","oneFlight","keyFactory","email","options","String","create","persist","deprecated","namespace","children","batcher","UserUUIDBatcher","props","hasPassword","type","session","store","UserUUIDStore","activate","_this","undefined","verificationToken","confirmationCode","id","_promise","reject","Error","scope","webex","config","credentials","activateOptions","request","uri","activationUrl","method","body","auth","client_id","pass","client_secret","sendImmediately","then","res","set","supertoken","tokenData","asUUID","_this2","isArray","all","map","u","_extractUUID","force","patterns","uuid","test","resolve","_extractEmailAddress","getUUID","fetchUUID","_this3","recordUUID","emailAddress","generateOTP","generateOtpUrl","get","_this4","service","resource","tap","_this5","getByEmail","userExists","catch","initialize","_len","args","Array","_key","_apply","prototype","add","register","verify","_setUser","_this6","getUserToken","token","setPasswordUrl","internal","device","userId","headers","authorization","toString","setPassword","_this7","password","updateName","_ref","givenName","familyName","displayName","name","updatePreferredWebexSite","_ref2","orgId","resolvedOrgId","getOrgId","identityUrl","identity","url","error","getMeetingSiteList","update","validateOTP","_this8","oneTimePassword","validateOtpUrl","_this9","verifyDefaults","_options","services","collectPreauthCatalog","getClientToken","preloginId","shouldRefreshAccessToken","sso","getUserCI","lookupCI","verifyOptions","suppressEmail","userEntities","idBrokerUrl","idbroker","entryUUID","entryEmail","version","_applyDecoratedDescriptor2","_getOwnPropertyDescriptor","_default2"],"sources":["user.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {isArray} from 'lodash';\nimport {deprecated, oneFlight, patterns, tap} from '@webex/common';\nimport {persist, WebexPlugin, waitForValue} from '@webex/webex-core';\n\nimport UserUUIDBatcher from './user-uuid-batcher';\nimport UserUUIDStore from './user-uuid-store';\n\nconst SCIM_SCHEMAS = [\n 'urn:scim:schemas:core:1.0',\n 'urn:scim:schemas:extension:cisco:commonidentity:1.0',\n];\n\n/**\n * Builds a SCIM PATCH body for updating the user's preferred Webex site.\n * Matches the native client's SCIM format: delete old + add new in a single PATCH.\n * @param {string} newSiteUrl - The new preferred site\n * @param {string} [oldSiteUrl] - The previous preferred site to remove\n * @returns {Object} SCIM-formatted request body\n */\nfunction buildPreferredSiteBody(newSiteUrl, oldSiteUrl) {\n const userPreferences = [];\n\n if (oldSiteUrl) {\n userPreferences.push({\n operation: 'delete',\n value: `\"preferredWebExSite\":\"${oldSiteUrl}\"`,\n });\n }\n\n userPreferences.push({\n value: `\"preferredWebExSite\":\"${newSiteUrl}\"`,\n });\n\n return {schemas: SCIM_SCHEMAS, userPreferences};\n}\n\n/**\n * Builds a deduplicated, sorted list of meeting sites from a user profile.\n * Merges linkedTrainSiteNames and trainSiteNames, filters out attendee-only\n * sites (those containing '#'), and sorts alphabetically.\n * Matches the native client's site list filtering logic.\n * @param {Object} user - User profile object\n * @param {string[]} [user.linkedTrainSiteNames] - Linked training site names\n * @param {string[]} [user.trainSiteNames] - Training site names\n * @returns {string[]} Sorted array of site URLs\n */\nfunction buildMeetingSiteList(user) {\n const linked = (user && user.linkedTrainSiteNames) || [];\n const train = (user && user.trainSiteNames) || [];\n\n return [...new Set(linked.concat(train))].filter((site) => site.indexOf('#') === -1).sort();\n}\n\n/**\n * @class\n */\nconst User = WebexPlugin.extend({\n namespace: 'User',\n\n children: {\n batcher: UserUUIDBatcher,\n },\n\n props: {\n /**\n * Indicates if the current user is known to have a password.\n * @instance\n * @memberof User\n * @type {boolean}\n */\n hasPassword: {\n default: false,\n type: 'boolean',\n },\n },\n\n session: {\n store: {\n default() {\n return new UserUUIDStore();\n },\n type: 'any',\n },\n },\n\n @waitForValue('@')\n /**\n * Activates a Webex user account and exchanges for user token.\n * @instance\n * @memberof User\n * @param {Object} options\n * @param {Object} options.confirmationCode (required -- optional if verification token is provided)\n * @param {Object} options.id (required -- optional if verification token is provided)\n * @param {Object} options.verificationToken (required -- optional if uuid and verification token provided)\n * @param {Object} options.email (required with verificationToken for Federation/global user)\n * @returns {Promise} Resolves with a userSession\n */\n activate(options = {}) {\n if (!(options.verificationToken || (options.confirmationCode && options.id))) {\n return Promise.reject(\n new Error(\n 'either options.verificationToken is required or both options.confirmationCode and options.id are required'\n )\n );\n }\n\n options.scope = this.webex.config.credentials.scope;\n\n // if we have options.email and options.verificationToken\n // and Federation flag is enabled, flag that we need to\n // lookup user's CI.\n const activateOptions = {...options};\n\n delete activateOptions.email;\n\n return this.request({\n uri: this.webex.config.credentials.activationUrl,\n method: 'POST',\n body: activateOptions,\n auth: {\n user: this.webex.config.credentials.client_id,\n pass: this.webex.config.credentials.client_secret,\n sendImmediately: true,\n },\n }).then((res) => {\n this.webex.credentials.set({supertoken: res.body.tokenData});\n\n return res.body;\n });\n },\n\n /**\n * Converts a user-identifying object to a uuid, perhaps by doing a network\n * lookup\n * @param {string|Object} user\n * @param {Object} options\n * @param {boolean} options.create if true, ensures the return UUID refers to\n * an existing user (rather than creating one deterministically based on email\n * address), even if that user must be created\n * @returns {Promise<string>}\n */\n asUUID(user, options) {\n if (!user) {\n return Promise.reject(new Error('`user` is required'));\n }\n\n if (isArray(user)) {\n return Promise.all(user.map((u) => this.asUUID(u, options)));\n }\n\n const id = this._extractUUID(user);\n\n if (!(options && options.force) && patterns.uuid.test(id)) {\n return Promise.resolve(id);\n }\n\n const email = this._extractEmailAddress(user);\n\n if (!patterns.email.test(email)) {\n return Promise.reject(new Error('Provided user object does not appear to identify a user'));\n }\n\n return this.getUUID(email, options);\n },\n\n /**\n * Requests a uuid from the api\n * @param {string} email\n * @param {Object} options\n * @param {boolean} options.create\n * @returns {Promise<string>}\n */\n fetchUUID(email, options) {\n return this.batcher\n .request({\n email,\n create: options && options.create,\n })\n .then((user) => this.recordUUID({emailAddress: email, ...user}).then(() => user.id));\n },\n /**\n * Generates One Time Password.\n * @instance\n * @param {Object} options\n * @param {string} options.email\n * @param {string} options.id\n * @returns {Promise}\n */\n generateOTP(options = {}) {\n if (!(options.email || options.id)) {\n return Promise.reject(new Error('One of `options.email` or `options.id` is required'));\n }\n\n return this.request({\n uri: this.webex.config.credentials.generateOtpUrl,\n method: 'POST',\n body: options,\n auth: {\n user: this.webex.config.credentials.client_id,\n pass: this.webex.config.credentials.client_secret,\n },\n }).then((res) => res.body);\n },\n\n /**\n * Fetches details about the current user\n * @returns {Promise<Object>}\n */\n get() {\n return this.request({\n service: 'conversation',\n resource: 'users',\n })\n .then((res) => res.body)\n .then(\n tap((user) =>\n this.recordUUID({\n id: user.id,\n // CI endpoints don't use the same user format as actors, so, email may\n // be in one of a few fields\n emailAddress: user.email || user.emailAddress,\n })\n )\n );\n },\n\n /**\n * Converts an email address to a uuid, perhaps by doing a network lookup\n * @param {string} email\n * @param {Object} options\n * @param {boolean} options.create\n * @returns {Promise<string>}\n */\n @oneFlight({keyFactory: (email, options) => email + String(options && options.create)})\n getUUID(email, options) {\n return this.store\n .getByEmail(email)\n .then((user) => {\n if (options && options.create && !user.userExists) {\n return Promise.reject(new Error('User for specified email cannot be confirmed to exist'));\n }\n\n if (!user.id) {\n return Promise.reject(new Error('No id recorded for specified user'));\n }\n\n return user.id;\n })\n .catch(() => this.fetchUUID(email, options));\n },\n\n @persist('@')\n initialize(...args) {\n return Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n },\n\n /**\n * Caches the uuid for the specified email address\n * @param {Object} user\n * @param {string} user.id\n * @param {string} user.emailAddress\n * @returns {Promise}\n */\n recordUUID(user) {\n if (!user) {\n return Promise.reject(new Error('`user` is required'));\n }\n\n if (!user.id) {\n return Promise.reject(new Error('`user.id` is required'));\n }\n\n if (!patterns.uuid.test(user.id)) {\n return Promise.reject(new Error('`user.id` must be a uuid'));\n }\n\n if (!user.emailAddress) {\n return Promise.reject(new Error('`user.emailAddress` is required'));\n }\n\n if (!patterns.email.test(user.emailAddress)) {\n return Promise.reject(new Error('`user.emailAddress` must be an email address'));\n }\n\n return this.store.add(user);\n },\n\n @deprecated('Use User#verify()')\n register(...args) {\n return this.verify(...args);\n },\n\n /**\n * Updates a user with webex.\n * @param {Object} body\n * @private\n * @returns {Promise} Resolves with a response from PATCH request\n */\n _setUser(body) {\n return this.webex.credentials.getUserToken().then((token) =>\n this.request({\n uri: `${this.webex.config.credentials.setPasswordUrl}/${this.webex.internal.device.userId}`,\n method: 'PATCH',\n headers: {\n authorization: token.toString(),\n },\n body,\n })\n );\n },\n\n /**\n * Updates a user's password with webex.\n * @instance\n * @memberof User\n * @param {Object} options\n * @param {string} options.password (required)\n * @param {string} options.email (required when federation enabled)\n * @returns {Promise} Resolves with complete user object containing new password\n */\n setPassword(options) {\n options = options || {};\n if (!options.password) {\n return Promise.reject(new Error('`options.password` is required'));\n }\n\n return this._setUser({\n schemas: ['urn:scim:schemas:core:1.0', 'urn:scim:schemas:extension:cisco:commonidentity:1.0'],\n password: options.password,\n }).then((res) => {\n this.hasPassword = true;\n\n return res.body;\n });\n },\n\n /**\n * Updates a user's name with webex.\n * @instance\n * @memberof User\n * @param {string} givenName\n * @param {string} familyName\n * @param {string} displayName\n * @returns {Promise<Object>}\n */\n updateName({givenName, familyName, displayName} = {}) {\n if (!(givenName || familyName || displayName)) {\n return Promise.reject(\n new Error('One of `givenName` and `familyName` or `displayName` is required')\n );\n }\n\n return this._setUser({\n schemas: ['urn:scim:schemas:core:1.0', 'urn:scim:schemas:extension:cisco:commonidentity:1.0'],\n name: {givenName, familyName},\n displayName,\n }).then((res) => res.body);\n },\n\n /**\n * Updates the user's preferred Webex meeting site via org-scoped SCIM PATCH.\n * @instance\n * @memberof User\n * @param {Object} options\n * @param {string} options.newSiteUrl - The new preferred site (e.g., 'example.webex.com')\n * @param {string} [options.oldSiteUrl] - The previous preferred site to remove\n * @param {string} [options.orgId] - Organization ID. If not provided, extracted from credentials.\n * @returns {Promise<Object>} Resolves with the SCIM response body\n */\n updatePreferredWebexSite({newSiteUrl, oldSiteUrl, orgId} = {}) {\n if (!newSiteUrl) {\n return Promise.reject(new Error('`options.newSiteUrl` is required'));\n }\n\n try {\n const resolvedOrgId = orgId || this.webex.credentials.getOrgId();\n const {userId} = this.webex.internal.device;\n\n if (!userId) {\n return Promise.reject(\n new Error('device.userId is not available — ensure device.register() has completed')\n );\n }\n\n const {url: identityUrl} = this.webex.config.credentials.identity;\n\n return this.request({\n uri: `${identityUrl}/identity/scim/${resolvedOrgId}/v1/Users/${userId}`,\n method: 'PATCH',\n body: buildPreferredSiteBody(newSiteUrl, oldSiteUrl),\n }).then((res) => res.body);\n } catch (error) {\n return Promise.reject(error);\n }\n },\n\n /**\n * Returns a sorted, filtered list of meeting sites from a user profile.\n * Delegates to the pure buildMeetingSiteList function.\n * @instance\n * @memberof User\n * @param {Object} user - User profile object from webex.internal.user.get()\n * @returns {string[]} Sorted array of site URLs\n */\n getMeetingSiteList(user) {\n return buildMeetingSiteList(user);\n },\n\n /**\n * Updates the current user's display name\n * @param {Object} options\n * @param {string} options.displayName\n * @returns {Promise<Object>}\n */\n update(options) {\n options = options || {};\n if (!options.displayName) {\n return Promise.reject(new Error('`options.displayName` is required'));\n }\n\n return this.request({\n method: 'PATCH',\n service: 'conversation',\n resource: 'users/user',\n body: options,\n }).then((res) => res.body);\n },\n\n /**\n * Validated One Time Password.\n * @instance\n * @param {Object} options\n * @param {string} options.email\n * @param {string} options.id\n * @param {string} options.oneTimePassword\n * @returns {Promise}\n */\n validateOTP(options = {}) {\n if (!(options.email || options.id) || !options.oneTimePassword) {\n return Promise.reject(\n new Error(\n 'One of `options.email` or `options.id` and `options.oneTimePassword` are required'\n )\n );\n }\n\n options.scope = this.webex.config.credentials.scope;\n\n return this.request({\n uri: this.webex.config.credentials.validateOtpUrl,\n method: 'POST',\n body: options,\n auth: {\n user: this.webex.config.credentials.client_id,\n pass: this.webex.config.credentials.client_secret,\n },\n }).then((res) => {\n this.webex.credentials.set({supertoken: res.body.tokenData});\n\n return res.body;\n });\n },\n\n /**\n * Determines if the specified user needs to signup or can signin.\n * Triggers activation email if client credentials are used\n * @param {Object} options\n * @param {string} options.email (required)\n * @param {string} options.reqId required if need to check email status\n * @param {string} options.preloginId\n * @returns {Promise<Object>}\n */\n verify(options) {\n options = {...this.config.verifyDefaults, ...options};\n const {email} = options;\n\n if (!email) {\n return Promise.reject(new Error('`options.email` is required'));\n }\n\n return this.webex.internal.services\n .collectPreauthCatalog({email})\n .then(() => this.webex.credentials.getUserToken())\n .catch(() => this.webex.credentials.getClientToken())\n .then((token) =>\n this.request({\n service: 'atlas',\n resource: 'users/activations',\n method: 'POST',\n headers: {\n authorization: token.toString(),\n 'x-prelogin-userid': options.preloginId,\n },\n body: options,\n shouldRefreshAccessToken: false,\n })\n )\n .then((res) => {\n if (res.body.hasPassword || res.body.sso) {\n this.hasPassword = true;\n }\n\n return res.body;\n });\n },\n\n /**\n * If the passed-in lookupCI is true, retrieve the user's\n * CI from Atlas and return the URL's via a Promise.\n * Otherwise, return current CI in config via a Promise.\n * Useful in a Promise chain to retrieve the CI based on\n * conditions like Federation enabled, and suppresses sending\n * an additional email to the user, since this is just a\n * look-up.\n * @param {string} email (required)\n * @param {boolean} lookupCI (required)\n * @returns {Promise<Object>}\n */\n getUserCI(email, lookupCI) {\n if (lookupCI) {\n // call verify first to get the user's CI, but suppress sending another email\n const verifyOptions = {\n email,\n suppressEmail: true,\n };\n\n return this.verify(verifyOptions).then((res) => Promise.resolve(res.userEntities));\n }\n\n return Promise.resolve({\n idBrokerUrl: this.webex.config.credentials.idbroker.url,\n identityUrl: this.webex.config.credentials.identity.url,\n });\n },\n\n /**\n * Extracts the uuid from a user identifying object\n * @param {string|Object} user\n * @private\n * @returns {string}\n */\n _extractUUID(user) {\n return user.entryUUID || user.id || user;\n },\n\n /**\n * Extracts the email address from a user identifying object\n * @param {string|Object} user\n * @private\n * @returns {string}\n */\n _extractEmailAddress(user) {\n return user.email || user.emailAddress || user.entryEmail || user;\n },\n});\n\nexport default User;\nexport {buildPreferredSiteBody, buildMeetingSiteList, SCIM_SCHEMAS};\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -24,21 +24,21 @@
24
24
  "@webex/eslint-config-legacy": "0.0.0",
25
25
  "@webex/jest-config-legacy": "0.0.0",
26
26
  "@webex/legacy-tools": "0.0.0",
27
- "@webex/test-helper-chai": "3.12.0-mobius-socket.0",
28
- "@webex/test-helper-mocha": "3.12.0-mobius-socket.0",
29
- "@webex/test-helper-mock-webex": "3.12.0-mobius-socket.0",
30
- "@webex/test-helper-test-users": "3.12.0-mobius-socket.0",
27
+ "@webex/test-helper-chai": "3.11.0-next.1",
28
+ "@webex/test-helper-mocha": "3.11.0-next.1",
29
+ "@webex/test-helper-mock-webex": "3.11.0-next.1",
30
+ "@webex/test-helper-test-users": "3.11.0-next.1",
31
31
  "eslint": "^8.24.0",
32
32
  "prettier": "^2.7.1",
33
33
  "sinon": "^9.2.4"
34
34
  },
35
35
  "dependencies": {
36
- "@webex/common": "3.12.0-mobius-socket.0",
37
- "@webex/internal-plugin-device": "3.12.0-mobius-socket.1",
38
- "@webex/test-helper-chai": "3.12.0-mobius-socket.0",
39
- "@webex/test-helper-mock-webex": "3.12.0-mobius-socket.0",
40
- "@webex/test-helper-test-users": "3.12.0-mobius-socket.0",
41
- "@webex/webex-core": "3.12.0-mobius-socket.1",
36
+ "@webex/common": "3.11.0-next.1",
37
+ "@webex/internal-plugin-device": "3.12.0-next.9",
38
+ "@webex/test-helper-chai": "3.11.0-next.1",
39
+ "@webex/test-helper-mock-webex": "3.11.0-next.1",
40
+ "@webex/test-helper-test-users": "3.11.0-next.1",
41
+ "@webex/webex-core": "3.12.0-next.9",
42
42
  "lodash": "^4.17.21",
43
43
  "uuid": "^3.3.2"
44
44
  },
@@ -51,5 +51,5 @@
51
51
  "test:style": "eslint ./src/**/*.*",
52
52
  "test:unit": "webex-legacy-tools test --unit --runner jest"
53
53
  },
54
- "version": "3.12.0-mobius-socket.1"
54
+ "version": "3.12.0-next.10"
55
55
  }
package/src/user.js CHANGED
@@ -9,6 +9,52 @@ import {persist, WebexPlugin, waitForValue} from '@webex/webex-core';
9
9
  import UserUUIDBatcher from './user-uuid-batcher';
10
10
  import UserUUIDStore from './user-uuid-store';
11
11
 
12
+ const SCIM_SCHEMAS = [
13
+ 'urn:scim:schemas:core:1.0',
14
+ 'urn:scim:schemas:extension:cisco:commonidentity:1.0',
15
+ ];
16
+
17
+ /**
18
+ * Builds a SCIM PATCH body for updating the user's preferred Webex site.
19
+ * Matches the native client's SCIM format: delete old + add new in a single PATCH.
20
+ * @param {string} newSiteUrl - The new preferred site
21
+ * @param {string} [oldSiteUrl] - The previous preferred site to remove
22
+ * @returns {Object} SCIM-formatted request body
23
+ */
24
+ function buildPreferredSiteBody(newSiteUrl, oldSiteUrl) {
25
+ const userPreferences = [];
26
+
27
+ if (oldSiteUrl) {
28
+ userPreferences.push({
29
+ operation: 'delete',
30
+ value: `"preferredWebExSite":"${oldSiteUrl}"`,
31
+ });
32
+ }
33
+
34
+ userPreferences.push({
35
+ value: `"preferredWebExSite":"${newSiteUrl}"`,
36
+ });
37
+
38
+ return {schemas: SCIM_SCHEMAS, userPreferences};
39
+ }
40
+
41
+ /**
42
+ * Builds a deduplicated, sorted list of meeting sites from a user profile.
43
+ * Merges linkedTrainSiteNames and trainSiteNames, filters out attendee-only
44
+ * sites (those containing '#'), and sorts alphabetically.
45
+ * Matches the native client's site list filtering logic.
46
+ * @param {Object} user - User profile object
47
+ * @param {string[]} [user.linkedTrainSiteNames] - Linked training site names
48
+ * @param {string[]} [user.trainSiteNames] - Training site names
49
+ * @returns {string[]} Sorted array of site URLs
50
+ */
51
+ function buildMeetingSiteList(user) {
52
+ const linked = (user && user.linkedTrainSiteNames) || [];
53
+ const train = (user && user.trainSiteNames) || [];
54
+
55
+ return [...new Set(linked.concat(train))].filter((site) => site.indexOf('#') === -1).sort();
56
+ }
57
+
12
58
  /**
13
59
  * @class
14
60
  */
@@ -315,6 +361,55 @@ const User = WebexPlugin.extend({
315
361
  }).then((res) => res.body);
316
362
  },
317
363
 
364
+ /**
365
+ * Updates the user's preferred Webex meeting site via org-scoped SCIM PATCH.
366
+ * @instance
367
+ * @memberof User
368
+ * @param {Object} options
369
+ * @param {string} options.newSiteUrl - The new preferred site (e.g., 'example.webex.com')
370
+ * @param {string} [options.oldSiteUrl] - The previous preferred site to remove
371
+ * @param {string} [options.orgId] - Organization ID. If not provided, extracted from credentials.
372
+ * @returns {Promise<Object>} Resolves with the SCIM response body
373
+ */
374
+ updatePreferredWebexSite({newSiteUrl, oldSiteUrl, orgId} = {}) {
375
+ if (!newSiteUrl) {
376
+ return Promise.reject(new Error('`options.newSiteUrl` is required'));
377
+ }
378
+
379
+ try {
380
+ const resolvedOrgId = orgId || this.webex.credentials.getOrgId();
381
+ const {userId} = this.webex.internal.device;
382
+
383
+ if (!userId) {
384
+ return Promise.reject(
385
+ new Error('device.userId is not available — ensure device.register() has completed')
386
+ );
387
+ }
388
+
389
+ const {url: identityUrl} = this.webex.config.credentials.identity;
390
+
391
+ return this.request({
392
+ uri: `${identityUrl}/identity/scim/${resolvedOrgId}/v1/Users/${userId}`,
393
+ method: 'PATCH',
394
+ body: buildPreferredSiteBody(newSiteUrl, oldSiteUrl),
395
+ }).then((res) => res.body);
396
+ } catch (error) {
397
+ return Promise.reject(error);
398
+ }
399
+ },
400
+
401
+ /**
402
+ * Returns a sorted, filtered list of meeting sites from a user profile.
403
+ * Delegates to the pure buildMeetingSiteList function.
404
+ * @instance
405
+ * @memberof User
406
+ * @param {Object} user - User profile object from webex.internal.user.get()
407
+ * @returns {string[]} Sorted array of site URLs
408
+ */
409
+ getMeetingSiteList(user) {
410
+ return buildMeetingSiteList(user);
411
+ },
412
+
318
413
  /**
319
414
  * Updates the current user's display name
320
415
  * @param {Object} options
@@ -464,3 +559,4 @@ const User = WebexPlugin.extend({
464
559
  });
465
560
 
466
561
  export default User;
562
+ export {buildPreferredSiteBody, buildMeetingSiteList, SCIM_SCHEMAS};
@@ -3,12 +3,90 @@
3
3
  */
4
4
 
5
5
  import UserService from '@webex/internal-plugin-user';
6
+ import {buildPreferredSiteBody, buildMeetingSiteList, SCIM_SCHEMAS} from '@webex/internal-plugin-user/src/user';
6
7
  import {assert} from '@webex/test-helper-chai';
7
8
  import MockWebex from '@webex/test-helper-mock-webex';
8
9
  import sinon from 'sinon';
9
10
  import uuid from 'uuid';
10
11
 
11
12
  describe('plugin-user', () => {
13
+ describe('buildPreferredSiteBody()', () => {
14
+ it('returns SCIM schemas in the body', () => {
15
+ const body = buildPreferredSiteBody('new.webex.com');
16
+
17
+ assert.deepEqual(body.schemas, SCIM_SCHEMAS);
18
+ });
19
+
20
+ it('builds add-only body when no oldSiteUrl', () => {
21
+ const body = buildPreferredSiteBody('new.webex.com');
22
+
23
+ assert.deepEqual(body.userPreferences, [
24
+ {value: '"preferredWebExSite":"new.webex.com"'},
25
+ ]);
26
+ });
27
+
28
+ it('builds delete+add body when oldSiteUrl provided', () => {
29
+ const body = buildPreferredSiteBody('new.webex.com', 'old.webex.com');
30
+
31
+ assert.deepEqual(body.userPreferences, [
32
+ {operation: 'delete', value: '"preferredWebExSite":"old.webex.com"'},
33
+ {value: '"preferredWebExSite":"new.webex.com"'},
34
+ ]);
35
+ });
36
+
37
+ it('embeds site URLs in the SCIM string format', () => {
38
+ const body = buildPreferredSiteBody('my-site.webex.com');
39
+
40
+ assert.equal(body.userPreferences[0].value, '"preferredWebExSite":"my-site.webex.com"');
41
+ });
42
+ });
43
+
44
+ describe('buildMeetingSiteList()', () => {
45
+ it('returns empty array for null/undefined/empty user', () => {
46
+ assert.deepEqual(buildMeetingSiteList(null), []);
47
+ assert.deepEqual(buildMeetingSiteList(undefined), []);
48
+ assert.deepEqual(buildMeetingSiteList({}), []);
49
+ });
50
+
51
+ it('merges linked + train sites and sorts alphabetically', () => {
52
+ const result = buildMeetingSiteList({
53
+ linkedTrainSiteNames: ['charlie.webex.com', 'alpha.webex.com'],
54
+ trainSiteNames: ['bravo.webex.com'],
55
+ });
56
+
57
+ assert.deepEqual(result, ['alpha.webex.com', 'bravo.webex.com', 'charlie.webex.com']);
58
+ });
59
+
60
+ it('filters out attendee-only sites containing #', () => {
61
+ const result = buildMeetingSiteList({
62
+ trainSiteNames: ['good.webex.com', 'attendee#only.webex.com', 'also-good.webex.com'],
63
+ });
64
+
65
+ assert.deepEqual(result, ['also-good.webex.com', 'good.webex.com']);
66
+ });
67
+
68
+ it('handles missing linkedTrainSiteNames gracefully', () => {
69
+ const result = buildMeetingSiteList({trainSiteNames: ['only.webex.com']});
70
+
71
+ assert.deepEqual(result, ['only.webex.com']);
72
+ });
73
+
74
+ it('handles missing trainSiteNames gracefully', () => {
75
+ const result = buildMeetingSiteList({linkedTrainSiteNames: ['only.webex.com']});
76
+
77
+ assert.deepEqual(result, ['only.webex.com']);
78
+ });
79
+
80
+ it('deduplicates sites appearing in both arrays', () => {
81
+ const result = buildMeetingSiteList({
82
+ linkedTrainSiteNames: ['shared.webex.com', 'alpha.webex.com'],
83
+ trainSiteNames: ['shared.webex.com', 'bravo.webex.com'],
84
+ });
85
+
86
+ assert.deepEqual(result, ['alpha.webex.com', 'bravo.webex.com', 'shared.webex.com']);
87
+ });
88
+ });
89
+
12
90
  describe('User', () => {
13
91
  let webex, userService;
14
92
 
@@ -147,6 +225,121 @@ describe('plugin-user', () => {
147
225
  ));
148
226
  });
149
227
 
228
+ describe('#updatePreferredWebexSite()', () => {
229
+ const testUserId = 'test-user-id-1234';
230
+ const testOrgId = 'test-org-id-5678';
231
+
232
+ beforeEach(() => {
233
+ webex.internal.device.userId = testUserId;
234
+ webex.credentials.getOrgId = sinon.stub().returns(testOrgId);
235
+ webex.config.credentials.identity = {url: 'https://identity.webex.com'};
236
+ });
237
+
238
+ it('rejects when `newSiteUrl` is not provided', () =>
239
+ assert.isRejected(
240
+ userService.updatePreferredWebexSite({}),
241
+ /`options.newSiteUrl` is required/
242
+ ));
243
+
244
+ it('rejects when getOrgId throws and none provided', () => {
245
+ webex.credentials.getOrgId = sinon.stub().throws(new Error('no org'));
246
+
247
+ return assert.isRejected(
248
+ userService.updatePreferredWebexSite({newSiteUrl: 'new.webex.com'}),
249
+ /no org/
250
+ );
251
+ });
252
+
253
+ it('rejects when device.userId is not available', () => {
254
+ webex.internal.device.userId = undefined;
255
+
256
+ return assert.isRejected(
257
+ userService.updatePreferredWebexSite({newSiteUrl: 'new.webex.com'}),
258
+ /device\.userId is not available/
259
+ );
260
+ });
261
+
262
+ it('uses provided orgId instead of extracting from credentials', () =>
263
+ userService
264
+ .updatePreferredWebexSite({newSiteUrl: 'new.webex.com', orgId: 'custom-org-9999'})
265
+ .then(() => {
266
+ assert.notCalled(webex.credentials.getOrgId);
267
+ const {uri} = webex.request.getCall(0).args[0];
268
+
269
+ assert.include(uri, '/identity/scim/custom-org-9999/v1/Users/');
270
+ }));
271
+
272
+ it('constructs org-scoped PATCH request with correct URL', () =>
273
+ userService
274
+ .updatePreferredWebexSite({newSiteUrl: 'new.webex.com'})
275
+ .then(() => {
276
+ const requestArgs = webex.request.getCall(0).args[0];
277
+
278
+ assert.equal(
279
+ requestArgs.uri,
280
+ `https://identity.webex.com/identity/scim/${testOrgId}/v1/Users/${testUserId}`
281
+ );
282
+ assert.equal(requestArgs.method, 'PATCH');
283
+ }));
284
+
285
+ it('does not manually set the authorization header (relies on auth interceptor)', () =>
286
+ userService
287
+ .updatePreferredWebexSite({newSiteUrl: 'new.webex.com'})
288
+ .then(() => {
289
+ const requestArgs = webex.request.getCall(0).args[0];
290
+
291
+ assert.notProperty(requestArgs, 'headers');
292
+ }));
293
+
294
+ it('passes buildPreferredSiteBody output as request body', () =>
295
+ userService
296
+ .updatePreferredWebexSite({newSiteUrl: 'new.webex.com', oldSiteUrl: 'old.webex.com'})
297
+ .then(() => {
298
+ const {body} = webex.request.getCall(0).args[0];
299
+
300
+ assert.deepEqual(body.schemas, SCIM_SCHEMAS);
301
+ assert.lengthOf(body.userPreferences, 2);
302
+ }));
303
+
304
+ it('returns the response body', () => {
305
+ const responseBody = {id: testUserId, preferredWebExSite: 'new.webex.com'};
306
+
307
+ userService.request = sinon.stub().returns(Promise.resolve({body: responseBody}));
308
+
309
+ return userService
310
+ .updatePreferredWebexSite({newSiteUrl: 'new.webex.com'})
311
+ .then((result) => {
312
+ assert.deepEqual(result, responseBody);
313
+ });
314
+ });
315
+
316
+ it('propagates request errors', () => {
317
+ const error = new Error('Forbidden');
318
+
319
+ error.statusCode = 403;
320
+ userService.request = sinon.stub().callsFake(() => Promise.reject(error));
321
+
322
+ return assert.isRejected(
323
+ userService.updatePreferredWebexSite({newSiteUrl: 'new.webex.com'}),
324
+ /Forbidden/
325
+ );
326
+ });
327
+ });
328
+
329
+ describe('#getMeetingSiteList()', () => {
330
+ it('delegates to buildMeetingSiteList', () => {
331
+ const user = {
332
+ linkedTrainSiteNames: ['charlie.webex.com'],
333
+ trainSiteNames: ['alpha.webex.com'],
334
+ };
335
+
336
+ assert.deepEqual(
337
+ userService.getMeetingSiteList(user),
338
+ ['alpha.webex.com', 'charlie.webex.com']
339
+ );
340
+ });
341
+ });
342
+
150
343
  describe('#verify()', () => {
151
344
  it('requires an `email` param', () =>
152
345
  assert.isRejected(userService.verify(), /`options.email` is required/));