@webex/webex-core 3.12.0-task-refactor.1 → 3.12.0-webex-services-ready.1
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.
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/credentials-config.js +12 -0
- package/dist/credentials-config.js.map +1 -1
- package/dist/interceptors/redirect.js +1 -1
- package/dist/interceptors/redirect.js.map +1 -1
- package/dist/lib/batcher.js +23 -7
- package/dist/lib/batcher.js.map +1 -1
- package/dist/lib/credentials/credentials.js +48 -4
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/token.js +1 -1
- package/dist/lib/services/service-url.js +11 -1
- package/dist/lib/services/service-url.js.map +1 -1
- package/dist/lib/services/services.js +501 -96
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/services-v2/services-v2.js +426 -42
- package/dist/lib/services-v2/services-v2.js.map +1 -1
- package/dist/lib/services-v2/types.js.map +1 -1
- package/dist/plugins/logger.js +1 -1
- package/dist/webex-core.js +2 -2
- package/dist/webex-core.js.map +1 -1
- package/package.json +13 -13
- package/src/config.js +7 -0
- package/src/credentials-config.js +13 -0
- package/src/interceptors/redirect.js +4 -1
- package/src/lib/batcher.js +25 -10
- package/src/lib/credentials/credentials.js +50 -3
- package/src/lib/services/service-url.js +9 -1
- package/src/lib/services/services.js +368 -14
- package/src/lib/services-v2/services-v2.ts +353 -10
- package/src/lib/services-v2/types.ts +5 -0
- package/test/integration/spec/services/service-catalog.js +16 -11
- package/test/integration/spec/services/services.js +38 -11
- package/test/integration/spec/services-v2/services-v2.js +29 -8
- package/test/unit/spec/credentials/credentials.js +133 -2
- package/test/unit/spec/lib/batcher.js +56 -0
- package/test/unit/spec/services/service-url.js +110 -0
- package/test/unit/spec/services/services.js +680 -80
- package/test/unit/spec/services-v2/services-v2.ts +484 -62
- package/test/unit/spec/webex-core.js +2 -0
- package/test/unit/spec/webex-internal-core.js +2 -0
|
@@ -11,6 +11,8 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
11
11
|
value: true
|
|
12
12
|
});
|
|
13
13
|
exports.default = exports.DEFAULT_CLUSTER_SERVICE = exports.DEFAULT_CLUSTER = void 0;
|
|
14
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
15
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
14
16
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
15
17
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
16
18
|
var _weakMap = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/weak-map"));
|
|
@@ -18,6 +20,8 @@ var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/ar
|
|
|
18
20
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
19
21
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
20
22
|
var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
|
|
23
|
+
var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
|
|
24
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
21
25
|
var _sha = _interopRequireDefault(require("crypto-js/sha256"));
|
|
22
26
|
var _lodash = require("lodash");
|
|
23
27
|
var _webexPlugin = _interopRequireDefault(require("../webex-plugin"));
|
|
@@ -35,6 +39,14 @@ var DEFAULT_CLUSTER = exports.DEFAULT_CLUSTER = 'urn:TEAM:us-east-2_a';
|
|
|
35
39
|
var DEFAULT_CLUSTER_SERVICE = exports.DEFAULT_CLUSTER_SERVICE = 'identityLookup';
|
|
36
40
|
var CLUSTER_SERVICE = process.env.WEBEX_CONVERSATION_CLUSTER_SERVICE || DEFAULT_CLUSTER_SERVICE;
|
|
37
41
|
var DEFAULT_CLUSTER_IDENTIFIER = process.env.WEBEX_CONVERSATION_DEFAULT_CLUSTER || "".concat(DEFAULT_CLUSTER, ":").concat(CLUSTER_SERVICE);
|
|
42
|
+
var CATALOG_CACHE_KEY_V2 = 'services.v2.u2cHostMap';
|
|
43
|
+
var CATALOG_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
44
|
+
|
|
45
|
+
// Maximum time we will wait for the initial catalog collection before letting
|
|
46
|
+
// `services.ready` (and therefore `webex.ready`) fire anyway. A hung request
|
|
47
|
+
// must never leave the app on a permanent spinner - past this point downstream
|
|
48
|
+
// consumers must fall through to their normal error/login paths.
|
|
49
|
+
var SERVICES_INIT_TIMEOUT_MS = 15000;
|
|
38
50
|
|
|
39
51
|
/* eslint-disable no-underscore-dangle */
|
|
40
52
|
/**
|
|
@@ -46,6 +58,19 @@ var Services = _webexPlugin.default.extend({
|
|
|
46
58
|
validateDomains: ['boolean', false, true],
|
|
47
59
|
initFailed: ['boolean', false, false]
|
|
48
60
|
},
|
|
61
|
+
session: {
|
|
62
|
+
/**
|
|
63
|
+
* Becomes `true` once services initialization has completed.
|
|
64
|
+
* This blocks `webex.ready` until services are initialized.
|
|
65
|
+
* @instance
|
|
66
|
+
* @memberof Services
|
|
67
|
+
* @type {boolean}
|
|
68
|
+
*/
|
|
69
|
+
ready: {
|
|
70
|
+
default: false,
|
|
71
|
+
type: 'boolean'
|
|
72
|
+
}
|
|
73
|
+
},
|
|
49
74
|
_catalogs: new _weakMap.default(),
|
|
50
75
|
_activeServices: {},
|
|
51
76
|
_services: [],
|
|
@@ -58,6 +83,45 @@ var Services = _webexPlugin.default.extend({
|
|
|
58
83
|
_getCatalog: function _getCatalog() {
|
|
59
84
|
return this._catalogs.get(this.webex);
|
|
60
85
|
},
|
|
86
|
+
/**
|
|
87
|
+
* Safely access localStorage if available; returns the Storage or null.
|
|
88
|
+
* @returns {Storage | null}
|
|
89
|
+
*/
|
|
90
|
+
_getLocalStorageSafe: function _getLocalStorageSafe() {
|
|
91
|
+
if (typeof window !== 'undefined' && window.localStorage) {
|
|
92
|
+
return window.localStorage;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* Determine the intended preauth selection based on the current context.
|
|
98
|
+
* @param {string} [currentOrgId]
|
|
99
|
+
* @returns {{selectionType: string, selectionValue: string}}
|
|
100
|
+
*/
|
|
101
|
+
getIntendedPreauthSelection: function getIntendedPreauthSelection(currentOrgId) {
|
|
102
|
+
var _this$webex$credentia;
|
|
103
|
+
if ((_this$webex$credentia = this.webex.credentials) !== null && _this$webex$credentia !== void 0 && _this$webex$credentia.canAuthorize) {
|
|
104
|
+
if (currentOrgId) {
|
|
105
|
+
return {
|
|
106
|
+
selectionType: 'orgId',
|
|
107
|
+
selectionValue: currentOrgId
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
var emailConfig = this.webex.config && this.webex.config.email;
|
|
112
|
+
if (typeof emailConfig === 'string' && emailConfig.trim()) {
|
|
113
|
+
return {
|
|
114
|
+
selectionType: 'emailhash',
|
|
115
|
+
selectionValue: (0, _sha.default)(emailConfig.toLowerCase()).toString()
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// fall back to proximity mode when no orgId or email available
|
|
120
|
+
return {
|
|
121
|
+
selectionType: 'mode',
|
|
122
|
+
selectionValue: 'DEFAULT_BY_PROXIMITY'
|
|
123
|
+
};
|
|
124
|
+
},
|
|
61
125
|
/**
|
|
62
126
|
* Get a service url from the current services list by name
|
|
63
127
|
* from the associated instance catalog.
|
|
@@ -104,6 +168,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
104
168
|
* @returns {Array<ServiceHost>} - An array of `ServiceHost` objects.
|
|
105
169
|
*/
|
|
106
170
|
getMobiusClusters: function getMobiusClusters() {
|
|
171
|
+
this.logger.info('services: fetching mobius clusters');
|
|
107
172
|
var clusters = [];
|
|
108
173
|
var services = this._services || [];
|
|
109
174
|
services.filter(function (service) {
|
|
@@ -140,6 +205,24 @@ var Services = _webexPlugin.default.extend({
|
|
|
140
205
|
});
|
|
141
206
|
});
|
|
142
207
|
},
|
|
208
|
+
/**
|
|
209
|
+
* Checks if the current environment is an integration (INT) environment
|
|
210
|
+
* by examining the u2c discovery URL from webex config.
|
|
211
|
+
* INT environments use discovery URLs containing 'intb' (e.g., u2c-intb.ciscospark.com).
|
|
212
|
+
* @returns {boolean} True if INT environment, false otherwise
|
|
213
|
+
*/
|
|
214
|
+
isIntegrationEnvironment: function isIntegrationEnvironment() {
|
|
215
|
+
try {
|
|
216
|
+
var _this$webex, _this$webex$config, _this$webex$config$se, _this$webex$config$se2;
|
|
217
|
+
var u2cUrl = ((_this$webex = this.webex) === null || _this$webex === void 0 ? void 0 : (_this$webex$config = _this$webex.config) === null || _this$webex$config === void 0 ? void 0 : (_this$webex$config$se = _this$webex$config.services) === null || _this$webex$config$se === void 0 ? void 0 : (_this$webex$config$se2 = _this$webex$config$se.discovery) === null || _this$webex$config$se2 === void 0 ? void 0 : _this$webex$config$se2.u2c) || '';
|
|
218
|
+
var isInt = u2cUrl.includes('intb');
|
|
219
|
+
this.logger.info("services: isIntegrationEnvironment: ".concat(isInt));
|
|
220
|
+
return isInt;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
this.logger.error('services: failed to determine integration environment', error);
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
},
|
|
143
226
|
/**
|
|
144
227
|
* saves all the services from the pre and post catalog service
|
|
145
228
|
* @param {ActiveServices} activeServices
|
|
@@ -222,6 +305,18 @@ var Services = _webexPlugin.default.extend({
|
|
|
222
305
|
forceRefresh: forceRefresh
|
|
223
306
|
}).then(function (serviceHostMap) {
|
|
224
307
|
catalog.updateServiceGroups(serviceGroup, serviceHostMap === null || serviceHostMap === void 0 ? void 0 : serviceHostMap.services, serviceHostMap === null || serviceHostMap === void 0 ? void 0 : serviceHostMap.timestamp);
|
|
308
|
+
// Build selection metadata for caching discrimination (preauth/signin)
|
|
309
|
+
var selectionMeta;
|
|
310
|
+
if (serviceGroup === 'preauth' || serviceGroup === 'signin') {
|
|
311
|
+
var key = formattedQuery && (0, _keys.default)(formattedQuery || {})[0];
|
|
312
|
+
if (key) {
|
|
313
|
+
selectionMeta = {
|
|
314
|
+
selectionType: key,
|
|
315
|
+
selectionValue: formattedQuery[key]
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
_this._cacheCatalog(serviceGroup, serviceHostMap, selectionMeta);
|
|
225
320
|
_this.updateCredentialsConfig();
|
|
226
321
|
catalog.status[serviceGroup].collecting = false;
|
|
227
322
|
}).catch(function (error) {
|
|
@@ -298,9 +393,9 @@ var Services = _webexPlugin.default.extend({
|
|
|
298
393
|
|
|
299
394
|
// Destructure the client authorization details.
|
|
300
395
|
/* eslint-disable camelcase */
|
|
301
|
-
var _this$webex$
|
|
302
|
-
client_id = _this$webex$
|
|
303
|
-
client_secret = _this$webex$
|
|
396
|
+
var _this$webex$credentia2 = this.webex.credentials.config,
|
|
397
|
+
client_id = _this$webex$credentia2.client_id,
|
|
398
|
+
client_secret = _this$webex$credentia2.client_secret;
|
|
304
399
|
|
|
305
400
|
// Validate that client authentication details exist.
|
|
306
401
|
if (!client_id || !client_secret) {
|
|
@@ -876,6 +971,213 @@ var Services = _webexPlugin.default.extend({
|
|
|
876
971
|
}
|
|
877
972
|
return url.replace(data.defaultUrl, data.priorityUrl);
|
|
878
973
|
},
|
|
974
|
+
/**
|
|
975
|
+
* @private
|
|
976
|
+
* Cache the catalog in the bounded storage.
|
|
977
|
+
* @param {ServiceGroup} serviceGroup - preauth, signin, postauth
|
|
978
|
+
* @param {ServiceHostmap} hostMap - The hostmap to cache
|
|
979
|
+
* @param {object} [meta] - Optional selection metadata for cache discrimination
|
|
980
|
+
* @returns {Promise<void>}
|
|
981
|
+
*/
|
|
982
|
+
_cacheCatalog: function _cacheCatalog(serviceGroup, hostMap, meta) {
|
|
983
|
+
var _this9 = this;
|
|
984
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
985
|
+
var current, orgId, _this9$webex$config, _this9$webex$config$c, _this9$webex, _this9$webex$config2, _this9$webex2, _this9$webex2$config, _this9$webex2$config$, _this9$webex2$config$2, _ls, cachedJson, credentials, _current, env, fedramp, u2cDiscoveryUrl, updated, ls, _t;
|
|
986
|
+
return _regenerator.default.wrap(function (_context) {
|
|
987
|
+
while (1) switch (_context.prev = _context.next) {
|
|
988
|
+
case 0:
|
|
989
|
+
current = {};
|
|
990
|
+
_context.prev = 1;
|
|
991
|
+
if ((_this9$webex$config = _this9.webex.config) !== null && _this9$webex$config !== void 0 && (_this9$webex$config$c = _this9$webex$config.calling) !== null && _this9$webex$config$c !== void 0 && _this9$webex$config$c.cacheU2C) {
|
|
992
|
+
_context.next = 2;
|
|
993
|
+
break;
|
|
994
|
+
}
|
|
995
|
+
_this9.logger.info("services: skipping cache write for ".concat(serviceGroup, " as per the config"));
|
|
996
|
+
return _context.abrupt("return");
|
|
997
|
+
case 2:
|
|
998
|
+
try {
|
|
999
|
+
_ls = _this9._getLocalStorageSafe();
|
|
1000
|
+
cachedJson = _ls ? _ls.getItem(CATALOG_CACHE_KEY_V2) : null;
|
|
1001
|
+
current = cachedJson ? JSON.parse(cachedJson) : {};
|
|
1002
|
+
} catch (_unused2) {
|
|
1003
|
+
current = {};
|
|
1004
|
+
}
|
|
1005
|
+
try {
|
|
1006
|
+
credentials = _this9.webex.credentials;
|
|
1007
|
+
orgId = credentials.getOrgId();
|
|
1008
|
+
} catch (_unused3) {
|
|
1009
|
+
orgId = current.orgId;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// Capture environment fingerprint to invalidate cache across env changes
|
|
1013
|
+
_current = current, env = _current.env;
|
|
1014
|
+
fedramp = !!((_this9$webex = _this9.webex) !== null && _this9$webex !== void 0 && (_this9$webex$config2 = _this9$webex.config) !== null && _this9$webex$config2 !== void 0 && _this9$webex$config2.fedramp);
|
|
1015
|
+
u2cDiscoveryUrl = (_this9$webex2 = _this9.webex) === null || _this9$webex2 === void 0 ? void 0 : (_this9$webex2$config = _this9$webex2.config) === null || _this9$webex2$config === void 0 ? void 0 : (_this9$webex2$config$ = _this9$webex2$config.services) === null || _this9$webex2$config$ === void 0 ? void 0 : (_this9$webex2$config$2 = _this9$webex2$config$.discovery) === null || _this9$webex2$config$2 === void 0 ? void 0 : _this9$webex2$config$2.u2c;
|
|
1016
|
+
env = {
|
|
1017
|
+
fedramp: fedramp,
|
|
1018
|
+
u2cDiscoveryUrl: u2cDiscoveryUrl
|
|
1019
|
+
};
|
|
1020
|
+
updated = _objectSpread(_objectSpread({}, current), {}, (0, _defineProperty2.default)((0, _defineProperty2.default)({
|
|
1021
|
+
orgId: orgId || current.orgId,
|
|
1022
|
+
env: env || current.env
|
|
1023
|
+
}, serviceGroup, meta ? {
|
|
1024
|
+
hostMap: hostMap,
|
|
1025
|
+
meta: meta
|
|
1026
|
+
} : hostMap), "cachedAt", (0, _now.default)()));
|
|
1027
|
+
ls = _this9._getLocalStorageSafe();
|
|
1028
|
+
if (ls) {
|
|
1029
|
+
ls.setItem(CATALOG_CACHE_KEY_V2, (0, _stringify.default)(updated));
|
|
1030
|
+
}
|
|
1031
|
+
_context.next = 4;
|
|
1032
|
+
break;
|
|
1033
|
+
case 3:
|
|
1034
|
+
_context.prev = 3;
|
|
1035
|
+
_t = _context["catch"](1);
|
|
1036
|
+
_this9.logger.warn('services: error caching catalog', _t);
|
|
1037
|
+
case 4:
|
|
1038
|
+
case "end":
|
|
1039
|
+
return _context.stop();
|
|
1040
|
+
}
|
|
1041
|
+
}, _callee, null, [[1, 3]]);
|
|
1042
|
+
}))();
|
|
1043
|
+
},
|
|
1044
|
+
/**
|
|
1045
|
+
* @private
|
|
1046
|
+
* Load the catalog from cache and hydrate the in-memory ServiceCatalog.
|
|
1047
|
+
* @returns {Promise<boolean>} true if cache was loaded, false otherwise
|
|
1048
|
+
*/
|
|
1049
|
+
_loadCatalogFromCache: function _loadCatalogFromCache() {
|
|
1050
|
+
var _this0 = this;
|
|
1051
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
1052
|
+
var currentOrgId, _this0$webex$config, _this0$webex$config$c, _this0$webex$config2, _this0$webex$config3, _this0$webex$config3$, _this0$webex$config3$2, ls, cachedJson, cached, cachedAt, _this0$webex$credenti, credentials, fedramp, u2cDiscoveryUrl, currentEnv, sameEnv, catalog, groups, _t2, _t3;
|
|
1053
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
1054
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
1055
|
+
case 0:
|
|
1056
|
+
_context2.prev = 0;
|
|
1057
|
+
if ((_this0$webex$config = _this0.webex.config) !== null && _this0$webex$config !== void 0 && (_this0$webex$config$c = _this0$webex$config.calling) !== null && _this0$webex$config$c !== void 0 && _this0$webex$config$c.cacheU2C) {
|
|
1058
|
+
_context2.next = 1;
|
|
1059
|
+
break;
|
|
1060
|
+
}
|
|
1061
|
+
_this0.logger.info('services: skipping cache warm-up as per the cache config');
|
|
1062
|
+
return _context2.abrupt("return", false);
|
|
1063
|
+
case 1:
|
|
1064
|
+
ls = _this0._getLocalStorageSafe();
|
|
1065
|
+
if (ls) {
|
|
1066
|
+
_context2.next = 2;
|
|
1067
|
+
break;
|
|
1068
|
+
}
|
|
1069
|
+
_this0.logger.info('services: skipping cache warm-up as no localStorage is available');
|
|
1070
|
+
return _context2.abrupt("return", false);
|
|
1071
|
+
case 2:
|
|
1072
|
+
cachedJson = ls.getItem(CATALOG_CACHE_KEY_V2);
|
|
1073
|
+
cached = cachedJson ? JSON.parse(cachedJson) : undefined;
|
|
1074
|
+
if (cached) {
|
|
1075
|
+
_context2.next = 3;
|
|
1076
|
+
break;
|
|
1077
|
+
}
|
|
1078
|
+
return _context2.abrupt("return", false);
|
|
1079
|
+
case 3:
|
|
1080
|
+
// TTL enforcement
|
|
1081
|
+
cachedAt = Number(cached.cachedAt) || 0;
|
|
1082
|
+
if (!(!cachedAt || (0, _now.default)() - cachedAt > CATALOG_TTL_MS)) {
|
|
1083
|
+
_context2.next = 4;
|
|
1084
|
+
break;
|
|
1085
|
+
}
|
|
1086
|
+
_this0.clearCatalogCache();
|
|
1087
|
+
return _context2.abrupt("return", false);
|
|
1088
|
+
case 4:
|
|
1089
|
+
_context2.prev = 4;
|
|
1090
|
+
if (!((_this0$webex$credenti = _this0.webex.credentials) !== null && _this0$webex$credenti !== void 0 && _this0$webex$credenti.canAuthorize)) {
|
|
1091
|
+
_context2.next = 5;
|
|
1092
|
+
break;
|
|
1093
|
+
}
|
|
1094
|
+
credentials = _this0.webex.credentials;
|
|
1095
|
+
currentOrgId = credentials.getOrgId();
|
|
1096
|
+
if (!(cached.orgId && cached.orgId !== currentOrgId)) {
|
|
1097
|
+
_context2.next = 5;
|
|
1098
|
+
break;
|
|
1099
|
+
}
|
|
1100
|
+
return _context2.abrupt("return", false);
|
|
1101
|
+
case 5:
|
|
1102
|
+
_context2.next = 7;
|
|
1103
|
+
break;
|
|
1104
|
+
case 6:
|
|
1105
|
+
_context2.prev = 6;
|
|
1106
|
+
_t2 = _context2["catch"](4);
|
|
1107
|
+
_this0.logger.warn('services: error checking orgId', _t2);
|
|
1108
|
+
case 7:
|
|
1109
|
+
// Ensure cached environment matches current environment
|
|
1110
|
+
fedramp = !!((_this0$webex$config2 = _this0.webex.config) !== null && _this0$webex$config2 !== void 0 && _this0$webex$config2.fedramp);
|
|
1111
|
+
u2cDiscoveryUrl = (_this0$webex$config3 = _this0.webex.config) === null || _this0$webex$config3 === void 0 ? void 0 : (_this0$webex$config3$ = _this0$webex$config3.services) === null || _this0$webex$config3$ === void 0 ? void 0 : (_this0$webex$config3$2 = _this0$webex$config3$.discovery) === null || _this0$webex$config3$2 === void 0 ? void 0 : _this0$webex$config3$2.u2c;
|
|
1112
|
+
currentEnv = {
|
|
1113
|
+
fedramp: fedramp,
|
|
1114
|
+
u2cDiscoveryUrl: u2cDiscoveryUrl
|
|
1115
|
+
};
|
|
1116
|
+
if (!cached.env) {
|
|
1117
|
+
_context2.next = 8;
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
sameEnv = cached.env.fedramp === currentEnv.fedramp && cached.env.u2cDiscoveryUrl === currentEnv.u2cDiscoveryUrl;
|
|
1121
|
+
if (sameEnv) {
|
|
1122
|
+
_context2.next = 8;
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
return _context2.abrupt("return", false);
|
|
1126
|
+
case 8:
|
|
1127
|
+
catalog = _this0._getCatalog();
|
|
1128
|
+
groups = ['preauth', 'signin', 'postauth'];
|
|
1129
|
+
groups.forEach(function (serviceGroup) {
|
|
1130
|
+
var cachedGroup = cached[serviceGroup];
|
|
1131
|
+
if (!cachedGroup) {
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// Support legacy (hostMap) and new ({hostMap, meta}) shapes
|
|
1136
|
+
var hostMap = cachedGroup && cachedGroup.hostMap ? cachedGroup.hostMap : cachedGroup;
|
|
1137
|
+
var meta = cachedGroup === null || cachedGroup === void 0 ? void 0 : cachedGroup.meta;
|
|
1138
|
+
if (serviceGroup === 'preauth' && meta) {
|
|
1139
|
+
// For proximity-based selection, always fetch fresh to respect IP/region changes
|
|
1140
|
+
if (meta.selectionType === 'mode') {
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
var intended = _this0.getIntendedPreauthSelection(currentOrgId);
|
|
1144
|
+
var matches = intended && intended.selectionType === meta.selectionType && intended.selectionValue === meta.selectionValue;
|
|
1145
|
+
if (!matches) {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
if (hostMap) {
|
|
1150
|
+
catalog.updateServiceGroups(serviceGroup, hostMap === null || hostMap === void 0 ? void 0 : hostMap.services, hostMap === null || hostMap === void 0 ? void 0 : hostMap.timestamp);
|
|
1151
|
+
}
|
|
1152
|
+
});
|
|
1153
|
+
_this0.updateCredentialsConfig();
|
|
1154
|
+
return _context2.abrupt("return", true);
|
|
1155
|
+
case 9:
|
|
1156
|
+
_context2.prev = 9;
|
|
1157
|
+
_t3 = _context2["catch"](0);
|
|
1158
|
+
return _context2.abrupt("return", false);
|
|
1159
|
+
case 10:
|
|
1160
|
+
case "end":
|
|
1161
|
+
return _context2.stop();
|
|
1162
|
+
}
|
|
1163
|
+
}, _callee2, null, [[0, 9], [4, 6]]);
|
|
1164
|
+
}))();
|
|
1165
|
+
},
|
|
1166
|
+
/**
|
|
1167
|
+
* Clear the catalog cache from the bounded storage (v2).
|
|
1168
|
+
* @returns {Promise<void>}
|
|
1169
|
+
*/
|
|
1170
|
+
clearCatalogCache: function clearCatalogCache() {
|
|
1171
|
+
try {
|
|
1172
|
+
var ls = this._getLocalStorageSafe();
|
|
1173
|
+
if (ls) {
|
|
1174
|
+
ls.removeItem(CATALOG_CACHE_KEY_V2);
|
|
1175
|
+
}
|
|
1176
|
+
} catch (e) {
|
|
1177
|
+
this.logger.warn('services: error clearing catalog cache', e);
|
|
1178
|
+
}
|
|
1179
|
+
return _promise.default.resolve();
|
|
1180
|
+
},
|
|
879
1181
|
/**
|
|
880
1182
|
* @private
|
|
881
1183
|
* Simplified method wrapper for sending a request to get
|
|
@@ -890,7 +1192,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
890
1192
|
* @returns {Promise<object>}
|
|
891
1193
|
*/
|
|
892
1194
|
_fetchNewServiceHostmap: function _fetchNewServiceHostmap() {
|
|
893
|
-
var
|
|
1195
|
+
var _this1 = this;
|
|
894
1196
|
var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
895
1197
|
from = _ref11.from,
|
|
896
1198
|
query = _ref11.query,
|
|
@@ -917,10 +1219,10 @@ var Services = _webexPlugin.default.extend({
|
|
|
917
1219
|
};
|
|
918
1220
|
}
|
|
919
1221
|
return this.webex.internal.newMetrics.callDiagnosticLatencies.measureLatency(function () {
|
|
920
|
-
return
|
|
1222
|
+
return _this1.request(requestObject);
|
|
921
1223
|
}, 'internal.get.u2c.time').then(function (_ref12) {
|
|
922
1224
|
var body = _ref12.body;
|
|
923
|
-
return
|
|
1225
|
+
return _this1._formatReceivedHostmap(body || {});
|
|
924
1226
|
});
|
|
925
1227
|
},
|
|
926
1228
|
/**
|
|
@@ -929,12 +1231,12 @@ var Services = _webexPlugin.default.extend({
|
|
|
929
1231
|
* @returns {void}
|
|
930
1232
|
*/
|
|
931
1233
|
initConfig: function initConfig() {
|
|
932
|
-
var
|
|
1234
|
+
var _this10 = this;
|
|
933
1235
|
// Get the catalog and destructure the services config.
|
|
934
1236
|
var catalog = this._getCatalog();
|
|
935
|
-
var _this$webex$
|
|
936
|
-
services = _this$webex$
|
|
937
|
-
fedramp = _this$webex$
|
|
1237
|
+
var _this$webex$config2 = this.webex.config,
|
|
1238
|
+
services = _this$webex$config2.services,
|
|
1239
|
+
fedramp = _this$webex$config2.fedramp;
|
|
938
1240
|
|
|
939
1241
|
// Validate that the services configuration exists.
|
|
940
1242
|
if (services) {
|
|
@@ -945,7 +1247,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
945
1247
|
if (services.discovery) {
|
|
946
1248
|
// Format the discovery configuration into an injectable array.
|
|
947
1249
|
var formattedDiscoveryServices = (0, _keys.default)(services.discovery).map(function (key) {
|
|
948
|
-
return
|
|
1250
|
+
return _this10._formatHostMapEntry({
|
|
949
1251
|
id: key,
|
|
950
1252
|
serviceName: key,
|
|
951
1253
|
serviceUrls: [{
|
|
@@ -961,7 +1263,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
961
1263
|
if (services.override) {
|
|
962
1264
|
// Format the override configuration into an injectable array.
|
|
963
1265
|
var formattedOverrideServices = (0, _keys.default)(services.override).map(function (key) {
|
|
964
|
-
return
|
|
1266
|
+
return _this10._formatHostMapEntry({
|
|
965
1267
|
id: key,
|
|
966
1268
|
serviceName: key,
|
|
967
1269
|
serviceUrls: [{
|
|
@@ -996,7 +1298,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
996
1298
|
* @returns {Promise<void, Error>} - Errors if the token is unavailable.
|
|
997
1299
|
*/
|
|
998
1300
|
initServiceCatalogs: function initServiceCatalogs() {
|
|
999
|
-
var
|
|
1301
|
+
var _this11 = this;
|
|
1000
1302
|
var refresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
1001
1303
|
this.logger.info('services: initializing initial service catalogs');
|
|
1002
1304
|
|
|
@@ -1012,18 +1314,18 @@ var Services = _webexPlugin.default.extend({
|
|
|
1012
1314
|
})
|
|
1013
1315
|
// Begin collecting the preauth/limited catalog.
|
|
1014
1316
|
.then(function (orgId) {
|
|
1015
|
-
return
|
|
1317
|
+
return _this11.collectPreauthCatalog({
|
|
1016
1318
|
orgId: orgId
|
|
1017
1319
|
}, refresh);
|
|
1018
1320
|
}).then(function () {
|
|
1019
1321
|
// Validate if the token is authorized.
|
|
1020
1322
|
if (credentials.canAuthorize) {
|
|
1021
1323
|
// Attempt to collect the postauth catalog.
|
|
1022
|
-
return
|
|
1324
|
+
return _this11.updateServices({
|
|
1023
1325
|
forceRefresh: refresh
|
|
1024
1326
|
}).catch(function () {
|
|
1025
|
-
|
|
1026
|
-
|
|
1327
|
+
_this11.initFailed = true;
|
|
1328
|
+
_this11.logger.warn('services: cannot retrieve postauth catalog');
|
|
1027
1329
|
});
|
|
1028
1330
|
}
|
|
1029
1331
|
|
|
@@ -1031,6 +1333,43 @@ var Services = _webexPlugin.default.extend({
|
|
|
1031
1333
|
return _promise.default.resolve();
|
|
1032
1334
|
});
|
|
1033
1335
|
},
|
|
1336
|
+
/**
|
|
1337
|
+
* Await any in-flight credentials refresh, then flip `services.ready` so
|
|
1338
|
+
* `webex.ready` can fire. Closes the parallel-refresh window: if a credential
|
|
1339
|
+
* refresh is in flight when initial catalog collection settles, we must not
|
|
1340
|
+
* signal ready until the refresh has resolved - otherwise downstream
|
|
1341
|
+
* consumers may observe `canAuthorize`/token state that is about to change
|
|
1342
|
+
* under them.
|
|
1343
|
+
*
|
|
1344
|
+
* @private
|
|
1345
|
+
* @returns {Promise<void>}
|
|
1346
|
+
*/
|
|
1347
|
+
_finalizeReady: function _finalizeReady() {
|
|
1348
|
+
var _this12 = this;
|
|
1349
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
1350
|
+
var credentials;
|
|
1351
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
1352
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
1353
|
+
case 0:
|
|
1354
|
+
credentials = _this12.webex.credentials;
|
|
1355
|
+
if (!(credentials && credentials.isRefreshing)) {
|
|
1356
|
+
_context3.next = 1;
|
|
1357
|
+
break;
|
|
1358
|
+
}
|
|
1359
|
+
_context3.next = 1;
|
|
1360
|
+
return new _promise.default(function (resolve) {
|
|
1361
|
+
credentials.once('change:isRefreshing', resolve);
|
|
1362
|
+
});
|
|
1363
|
+
case 1:
|
|
1364
|
+
_this12.ready = true;
|
|
1365
|
+
_this12.trigger('services:initialized');
|
|
1366
|
+
case 2:
|
|
1367
|
+
case "end":
|
|
1368
|
+
return _context3.stop();
|
|
1369
|
+
}
|
|
1370
|
+
}, _callee3);
|
|
1371
|
+
}))();
|
|
1372
|
+
},
|
|
1034
1373
|
/**
|
|
1035
1374
|
* Initializer
|
|
1036
1375
|
*
|
|
@@ -1039,39 +1378,84 @@ var Services = _webexPlugin.default.extend({
|
|
|
1039
1378
|
* @returns {Services}
|
|
1040
1379
|
*/
|
|
1041
1380
|
initialize: function initialize() {
|
|
1042
|
-
var
|
|
1381
|
+
var _this13 = this;
|
|
1043
1382
|
var catalog = new _serviceCatalog.default();
|
|
1044
1383
|
this._catalogs.set(this.webex, catalog);
|
|
1045
1384
|
|
|
1046
1385
|
// Listen for configuration changes once.
|
|
1047
1386
|
this.listenToOnce(this.webex, 'change:config', function () {
|
|
1048
|
-
|
|
1387
|
+
_this13.initConfig();
|
|
1049
1388
|
});
|
|
1050
1389
|
|
|
1051
|
-
//
|
|
1052
|
-
//
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1390
|
+
// Wait for storage to be loaded before attempting to update the service catalogs.
|
|
1391
|
+
// We listen for 'loaded' instead of 'ready' because services.ready is a dependency
|
|
1392
|
+
// of webex.ready - listening to 'ready' would cause a deadlock.
|
|
1393
|
+
this.listenToOnce(this.webex, 'loaded', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
1394
|
+
var warmed, supertoken, timeout, email;
|
|
1395
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
1396
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
1397
|
+
case 0:
|
|
1398
|
+
_context4.next = 1;
|
|
1399
|
+
return _this13._loadCatalogFromCache();
|
|
1400
|
+
case 1:
|
|
1401
|
+
warmed = _context4.sent;
|
|
1402
|
+
if (!warmed) {
|
|
1403
|
+
_context4.next = 3;
|
|
1404
|
+
break;
|
|
1405
|
+
}
|
|
1406
|
+
catalog.isReady = true;
|
|
1407
|
+
_context4.next = 2;
|
|
1408
|
+
return _this13._finalizeReady();
|
|
1409
|
+
case 2:
|
|
1410
|
+
return _context4.abrupt("return");
|
|
1411
|
+
case 3:
|
|
1412
|
+
supertoken = _this13.webex.credentials.supertoken; // Race init against a hard timeout so a hung request never leaves
|
|
1413
|
+
// `services.ready` false forever - that would stall `webex.ready` and
|
|
1414
|
+
// leave the app on a permanent spinner.
|
|
1415
|
+
timeout = new _promise.default(function (_, reject) {
|
|
1416
|
+
setTimeout(function () {
|
|
1417
|
+
return reject(new Error("services: init timed out after ".concat(SERVICES_INIT_TIMEOUT_MS, "ms")));
|
|
1418
|
+
}, SERVICES_INIT_TIMEOUT_MS);
|
|
1419
|
+
}); // Validate if the supertoken exists.
|
|
1420
|
+
if (supertoken && supertoken.access_token) {
|
|
1421
|
+
_promise.default.race([_this13.initServiceCatalogs(), timeout]).then(function () {
|
|
1422
|
+
catalog.isReady = true;
|
|
1423
|
+
}).catch(function (error) {
|
|
1424
|
+
_this13.initFailed = true;
|
|
1425
|
+
_this13.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1426
|
+
}).finally(function () {
|
|
1427
|
+
return _this13._finalizeReady();
|
|
1428
|
+
});
|
|
1429
|
+
} else {
|
|
1430
|
+
email = _this13.webex.config.email;
|
|
1431
|
+
_promise.default.race([_this13.collectPreauthCatalog(email ? {
|
|
1432
|
+
email: email
|
|
1433
|
+
} : undefined), timeout]).catch(function (error) {
|
|
1434
|
+
_this13.initFailed = true;
|
|
1435
|
+
_this13.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1436
|
+
}).finally(function () {
|
|
1437
|
+
return _this13._finalizeReady();
|
|
1438
|
+
});
|
|
1439
|
+
// Listen for when credentials become available to fetch the full catalog.
|
|
1440
|
+
// This handles fresh login where 'loaded' fires before OAuth completes.
|
|
1441
|
+
_this13.listenToOnce(_this13.webex, 'change:canAuthorize', function () {
|
|
1442
|
+
if (_this13.webex.canAuthorize && !catalog.status.postauth.ready) {
|
|
1443
|
+
_this13.initServiceCatalogs().then(function () {
|
|
1444
|
+
catalog.isReady = true;
|
|
1445
|
+
}).catch(function (error) {
|
|
1446
|
+
_this13.logger.error("services: failed to init service catalogs after auth, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
case 4:
|
|
1452
|
+
case "end":
|
|
1453
|
+
return _context4.stop();
|
|
1454
|
+
}
|
|
1455
|
+
}, _callee4);
|
|
1456
|
+
})));
|
|
1073
1457
|
},
|
|
1074
|
-
version: "3.12.0-
|
|
1458
|
+
version: "3.12.0-webex-services-ready.1"
|
|
1075
1459
|
});
|
|
1076
1460
|
/* eslint-enable no-underscore-dangle */
|
|
1077
1461
|
var _default = exports.default = Services;
|