@webex/webex-core 3.12.0-task-refactor.1 → 3.12.0-webex-services-ready.2
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 +583 -94
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/services-v2/services-v2.js +507 -41
- 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 +433 -6
- package/src/lib/services-v2/services-v2.ts +417 -2
- 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 +58 -9
- package/test/integration/spec/services-v2/services-v2.js +49 -6
- 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 +692 -12
- package/test/unit/spec/services-v2/services-v2.ts +539 -0
- package/test/unit/spec/webex-core.js +2 -0
- package/test/unit/spec/webex-internal-core.js +2 -0
|
@@ -11,12 +11,16 @@ _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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
15
17
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
16
18
|
var _weakMap = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/weak-map"));
|
|
17
19
|
var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
|
|
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"));
|
|
22
|
+
var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
|
|
23
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
20
24
|
var _sha = _interopRequireDefault(require("crypto-js/sha256"));
|
|
21
25
|
var _lodash = require("lodash");
|
|
22
26
|
var _webexPlugin = _interopRequireDefault(require("../webex-plugin"));
|
|
@@ -36,6 +40,14 @@ var DEFAULT_CLUSTER = exports.DEFAULT_CLUSTER = 'urn:TEAM:us-east-2_a';
|
|
|
36
40
|
var DEFAULT_CLUSTER_SERVICE = exports.DEFAULT_CLUSTER_SERVICE = 'identityLookup';
|
|
37
41
|
var CLUSTER_SERVICE = process.env.WEBEX_CONVERSATION_CLUSTER_SERVICE || DEFAULT_CLUSTER_SERVICE;
|
|
38
42
|
var DEFAULT_CLUSTER_IDENTIFIER = process.env.WEBEX_CONVERSATION_DEFAULT_CLUSTER || "".concat(DEFAULT_CLUSTER, ":").concat(CLUSTER_SERVICE);
|
|
43
|
+
var CATALOG_CACHE_KEY_V1 = 'services.v1.u2cHostMap';
|
|
44
|
+
var CATALOG_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
45
|
+
|
|
46
|
+
// Maximum time we will wait for the initial catalog collection before letting
|
|
47
|
+
// `services.ready` (and therefore `webex.ready`) fire anyway. A hung request
|
|
48
|
+
// must never leave the app on a permanent spinner - past this point downstream
|
|
49
|
+
// consumers must fall through to their normal error/login paths.
|
|
50
|
+
var SERVICES_INIT_TIMEOUT_MS = 15000;
|
|
39
51
|
|
|
40
52
|
/* eslint-disable no-underscore-dangle */
|
|
41
53
|
/**
|
|
@@ -67,6 +79,21 @@ var Services = _webexPlugin.default.extend({
|
|
|
67
79
|
validateDomains: ['boolean', false, true],
|
|
68
80
|
initFailed: ['boolean', false, false]
|
|
69
81
|
},
|
|
82
|
+
session: {
|
|
83
|
+
/**
|
|
84
|
+
* Becomes `true` once the initial catalog collection has completed
|
|
85
|
+
* (successfully or otherwise) and any in-flight credentials refresh has
|
|
86
|
+
* settled. Blocks `webex.ready` so consumers can rely on `webex.ready`
|
|
87
|
+
* implying "catalogs populated AND credential state stable".
|
|
88
|
+
* @instance
|
|
89
|
+
* @memberof Services
|
|
90
|
+
* @type {boolean}
|
|
91
|
+
*/
|
|
92
|
+
ready: {
|
|
93
|
+
default: false,
|
|
94
|
+
type: 'boolean'
|
|
95
|
+
}
|
|
96
|
+
},
|
|
70
97
|
_catalogs: new _weakMap.default(),
|
|
71
98
|
_serviceUrls: null,
|
|
72
99
|
_hostCatalog: null,
|
|
@@ -101,6 +128,45 @@ var Services = _webexPlugin.default.extend({
|
|
|
101
128
|
_getCatalog: function _getCatalog() {
|
|
102
129
|
return this._catalogs.get(this.webex);
|
|
103
130
|
},
|
|
131
|
+
/**
|
|
132
|
+
* Safely access localStorage if available; returns the Storage or null.
|
|
133
|
+
* @returns {Storage|null}
|
|
134
|
+
*/
|
|
135
|
+
_getLocalStorageSafe: function _getLocalStorageSafe() {
|
|
136
|
+
if (typeof window !== 'undefined' && window.localStorage) {
|
|
137
|
+
return window.localStorage;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
},
|
|
141
|
+
/**
|
|
142
|
+
* Determine the intended preauth selection based on the current context.
|
|
143
|
+
* @param {string|undefined} currentOrgId
|
|
144
|
+
* @returns {{selectionType: string, selectionValue: string}}
|
|
145
|
+
*/
|
|
146
|
+
getIntendedPreauthSelection: function getIntendedPreauthSelection(currentOrgId) {
|
|
147
|
+
var _this$webex$credentia;
|
|
148
|
+
if ((_this$webex$credentia = this.webex.credentials) !== null && _this$webex$credentia !== void 0 && _this$webex$credentia.canAuthorize) {
|
|
149
|
+
if (currentOrgId) {
|
|
150
|
+
return {
|
|
151
|
+
selectionType: 'orgId',
|
|
152
|
+
selectionValue: currentOrgId
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
var emailConfig = this.webex.config && this.webex.config.email;
|
|
157
|
+
if (typeof emailConfig === 'string' && emailConfig.trim()) {
|
|
158
|
+
return {
|
|
159
|
+
selectionType: 'emailhash',
|
|
160
|
+
selectionValue: (0, _sha.default)(emailConfig.toLowerCase()).toString()
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// fall back to proximity mode when no orgId or email available
|
|
165
|
+
return {
|
|
166
|
+
selectionType: 'mode',
|
|
167
|
+
selectionValue: 'DEFAULT_BY_PROXIMITY'
|
|
168
|
+
};
|
|
169
|
+
},
|
|
104
170
|
/**
|
|
105
171
|
* Get a service url from the current services list by name
|
|
106
172
|
* from the associated instance catalog.
|
|
@@ -161,9 +227,10 @@ var Services = _webexPlugin.default.extend({
|
|
|
161
227
|
},
|
|
162
228
|
/**
|
|
163
229
|
* Get all Mobius cluster host entries from the legacy host catalog.
|
|
164
|
-
* @returns {Array<
|
|
230
|
+
* @returns {Array<{host: string, id: string, ttl: number, priority: number}>}
|
|
165
231
|
*/
|
|
166
232
|
getMobiusClusters: function getMobiusClusters() {
|
|
233
|
+
this.logger.info('services: fetching mobius clusters');
|
|
167
234
|
var clusters = [];
|
|
168
235
|
var hostCatalog = this._hostCatalog || {};
|
|
169
236
|
(0, _entries.default)(hostCatalog).forEach(function (_ref) {
|
|
@@ -197,6 +264,24 @@ var Services = _webexPlugin.default.extend({
|
|
|
197
264
|
var hostCatalog = this._hostCatalog || {};
|
|
198
265
|
return !!((_hostCatalog$host = hostCatalog[host]) !== null && _hostCatalog$host !== void 0 && _hostCatalog$host.length);
|
|
199
266
|
},
|
|
267
|
+
/**
|
|
268
|
+
* Checks if the current environment is an integration (INT) environment
|
|
269
|
+
* by examining the u2c discovery URL from webex config.
|
|
270
|
+
* INT environments use discovery URLs containing 'intb' (e.g., u2c-intb.ciscospark.com).
|
|
271
|
+
* @returns {boolean} True if INT environment, false otherwise
|
|
272
|
+
*/
|
|
273
|
+
isIntegrationEnvironment: function isIntegrationEnvironment() {
|
|
274
|
+
try {
|
|
275
|
+
var _this$webex, _this$webex$config, _this$webex$config$se, _this$webex$config$se2;
|
|
276
|
+
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) || '';
|
|
277
|
+
var isInt = u2cUrl.includes('intb');
|
|
278
|
+
this.logger.info("services: isIntegrationEnvironment: ".concat(isInt));
|
|
279
|
+
return isInt;
|
|
280
|
+
} catch (error) {
|
|
281
|
+
this.logger.error('services: failed to determine integration environment', error);
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
},
|
|
200
285
|
/**
|
|
201
286
|
* Merge provided active cluster mappings into current state.
|
|
202
287
|
* @param {Record<string,string>} activeServices
|
|
@@ -235,63 +320,88 @@ var Services = _webexPlugin.default.extend({
|
|
|
235
320
|
* @returns {Promise<object>}
|
|
236
321
|
*/
|
|
237
322
|
updateServices: function updateServices() {
|
|
238
|
-
var
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
323
|
+
var _arguments = arguments,
|
|
324
|
+
_this = this;
|
|
325
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
326
|
+
var _ref3, from, query, token, forceRefresh, catalog, formattedQuery, serviceGroup, queryKey, _queryKey, _t;
|
|
327
|
+
return _regenerator.default.wrap(function (_context) {
|
|
328
|
+
while (1) switch (_context.prev = _context.next) {
|
|
329
|
+
case 0:
|
|
330
|
+
_ref3 = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : {}, from = _ref3.from, query = _ref3.query, token = _ref3.token, forceRefresh = _ref3.forceRefresh;
|
|
331
|
+
catalog = _this._getCatalog();
|
|
332
|
+
_t = from;
|
|
333
|
+
_context.next = _t === 'limited' ? 1 : _t === 'signin' ? 2 : 3;
|
|
334
|
+
break;
|
|
335
|
+
case 1:
|
|
336
|
+
serviceGroup = 'preauth';
|
|
337
|
+
return _context.abrupt("continue", 4);
|
|
338
|
+
case 2:
|
|
339
|
+
serviceGroup = 'signin';
|
|
340
|
+
return _context.abrupt("continue", 4);
|
|
341
|
+
case 3:
|
|
342
|
+
serviceGroup = 'postauth';
|
|
343
|
+
return _context.abrupt("continue", 4);
|
|
344
|
+
case 4:
|
|
345
|
+
if (!catalog.status[serviceGroup].collecting) {
|
|
346
|
+
_context.next = 5;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
return _context.abrupt("return", _this.waitForCatalog(serviceGroup));
|
|
350
|
+
case 5:
|
|
351
|
+
catalog.status[serviceGroup].collecting = true;
|
|
352
|
+
if (!(serviceGroup === 'preauth')) {
|
|
353
|
+
_context.next = 6;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
queryKey = query && (0, _keys.default)(query)[0];
|
|
357
|
+
if (['email', 'emailhash', 'userId', 'orgId', 'mode'].includes(queryKey)) {
|
|
358
|
+
_context.next = 6;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
return _context.abrupt("return", _promise.default.reject(new Error('a query param of email, emailhash, userId, orgId, or mode is required')));
|
|
362
|
+
case 6:
|
|
363
|
+
// encode email when query key is email
|
|
364
|
+
if (serviceGroup === 'preauth' || serviceGroup === 'signin') {
|
|
365
|
+
_queryKey = (0, _keys.default)(query)[0];
|
|
366
|
+
formattedQuery = {};
|
|
367
|
+
if (_queryKey === 'email' && query.email) {
|
|
368
|
+
formattedQuery.emailhash = (0, _sha.default)(query.email.toLowerCase()).toString();
|
|
369
|
+
} else {
|
|
370
|
+
formattedQuery[_queryKey] = query[_queryKey];
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return _context.abrupt("return", _this._fetchNewServiceHostmap({
|
|
374
|
+
from: from,
|
|
375
|
+
token: token,
|
|
376
|
+
query: formattedQuery,
|
|
377
|
+
forceRefresh: forceRefresh
|
|
378
|
+
}).then(function (serviceHostMap) {
|
|
379
|
+
var formattedServiceHostMap = _this._formatReceivedHostmap(serviceHostMap);
|
|
380
|
+
// Build selection metadata for caching discrimination
|
|
381
|
+
var selectionMeta;
|
|
382
|
+
if (serviceGroup === 'preauth' || serviceGroup === 'signin') {
|
|
383
|
+
var key = formattedQuery && (0, _keys.default)(formattedQuery || {})[0];
|
|
384
|
+
if (key) {
|
|
385
|
+
selectionMeta = {
|
|
386
|
+
selectionType: key,
|
|
387
|
+
selectionValue: formattedQuery[key]
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
_this._cacheCatalog(serviceGroup, serviceHostMap, selectionMeta);
|
|
392
|
+
catalog.updateServiceUrls(serviceGroup, formattedServiceHostMap);
|
|
393
|
+
_this.updateCredentialsConfig();
|
|
394
|
+
catalog.status[serviceGroup].collecting = false;
|
|
395
|
+
}).catch(function (error) {
|
|
396
|
+
catalog.status[serviceGroup].collecting = false;
|
|
397
|
+
return _promise.default.reject(error);
|
|
398
|
+
}));
|
|
399
|
+
case 7:
|
|
400
|
+
case "end":
|
|
401
|
+
return _context.stop();
|
|
402
|
+
}
|
|
403
|
+
}, _callee);
|
|
404
|
+
}))();
|
|
295
405
|
},
|
|
296
406
|
/**
|
|
297
407
|
* User validation parameter transfer object for {@link validateUser}.
|
|
@@ -362,9 +472,9 @@ var Services = _webexPlugin.default.extend({
|
|
|
362
472
|
|
|
363
473
|
// Destructure the client authorization details.
|
|
364
474
|
/* eslint-disable camelcase */
|
|
365
|
-
var _this$webex$
|
|
366
|
-
client_id = _this$webex$
|
|
367
|
-
client_secret = _this$webex$
|
|
475
|
+
var _this$webex$credentia2 = this.webex.credentials.config,
|
|
476
|
+
client_id = _this$webex$credentia2.client_id,
|
|
477
|
+
client_secret = _this$webex$credentia2.client_secret;
|
|
368
478
|
|
|
369
479
|
// Validate that client authentication details exist.
|
|
370
480
|
if (!client_id || !client_secret) {
|
|
@@ -975,9 +1085,223 @@ var Services = _webexPlugin.default.extend({
|
|
|
975
1085
|
return _this7.request(requestObject);
|
|
976
1086
|
}, 'internal.get.u2c.time').then(function (_ref12) {
|
|
977
1087
|
var body = _ref12.body;
|
|
978
|
-
return
|
|
1088
|
+
return body;
|
|
979
1089
|
});
|
|
980
1090
|
},
|
|
1091
|
+
/**
|
|
1092
|
+
* Cache the catalog in the bounded storage.
|
|
1093
|
+
* @param {string} serviceGroup - preauth, signin, postauth
|
|
1094
|
+
* @param {object} hostMap - The hostmap to cache
|
|
1095
|
+
* @param {object} [meta] - Optional selection metadata used to validate cache reuse
|
|
1096
|
+
* @returns {Promise<void>}
|
|
1097
|
+
*
|
|
1098
|
+
*/
|
|
1099
|
+
_cacheCatalog: function _cacheCatalog(serviceGroup, hostMap, meta) {
|
|
1100
|
+
var _this8 = this;
|
|
1101
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
1102
|
+
var current, orgId, _this8$webex$config, _this8$webex$config$c, _this8$webex, _this8$webex$config2, _this8$webex2, _this8$webex2$config, _this8$webex2$config$, _this8$webex2$config$2, _ls, cachedJson, credentials, _current, env, fedramp, u2cDiscoveryUrl, updated, ls, _t2;
|
|
1103
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
1104
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
1105
|
+
case 0:
|
|
1106
|
+
current = {};
|
|
1107
|
+
_context2.prev = 1;
|
|
1108
|
+
if ((_this8$webex$config = _this8.webex.config) !== null && _this8$webex$config !== void 0 && (_this8$webex$config$c = _this8$webex$config.calling) !== null && _this8$webex$config$c !== void 0 && _this8$webex$config$c.cacheU2C) {
|
|
1109
|
+
_context2.next = 2;
|
|
1110
|
+
break;
|
|
1111
|
+
}
|
|
1112
|
+
_this8.logger.info("services: skipping cache write for ".concat(serviceGroup, " as per the config"));
|
|
1113
|
+
return _context2.abrupt("return");
|
|
1114
|
+
case 2:
|
|
1115
|
+
// Persist to localStorage to survive browser refresh
|
|
1116
|
+
try {
|
|
1117
|
+
_ls = _this8._getLocalStorageSafe();
|
|
1118
|
+
cachedJson = _ls ? _ls.getItem(CATALOG_CACHE_KEY_V1) : null;
|
|
1119
|
+
current = cachedJson ? JSON.parse(cachedJson) : {};
|
|
1120
|
+
} catch (e) {
|
|
1121
|
+
current = {};
|
|
1122
|
+
}
|
|
1123
|
+
try {
|
|
1124
|
+
credentials = _this8.webex.credentials;
|
|
1125
|
+
orgId = credentials.getOrgId();
|
|
1126
|
+
} catch (e) {
|
|
1127
|
+
orgId = current.orgId;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
// Capture environment fingerprint to invalidate cache across env changes
|
|
1131
|
+
_current = current, env = _current.env;
|
|
1132
|
+
fedramp = !!((_this8$webex = _this8.webex) !== null && _this8$webex !== void 0 && (_this8$webex$config2 = _this8$webex.config) !== null && _this8$webex$config2 !== void 0 && _this8$webex$config2.fedramp);
|
|
1133
|
+
u2cDiscoveryUrl = (_this8$webex2 = _this8.webex) === null || _this8$webex2 === void 0 ? void 0 : (_this8$webex2$config = _this8$webex2.config) === null || _this8$webex2$config === void 0 ? void 0 : (_this8$webex2$config$ = _this8$webex2$config.services) === null || _this8$webex2$config$ === void 0 ? void 0 : (_this8$webex2$config$2 = _this8$webex2$config$.discovery) === null || _this8$webex2$config$2 === void 0 ? void 0 : _this8$webex2$config$2.u2c;
|
|
1134
|
+
env = {
|
|
1135
|
+
fedramp: fedramp,
|
|
1136
|
+
u2cDiscoveryUrl: u2cDiscoveryUrl
|
|
1137
|
+
};
|
|
1138
|
+
updated = _objectSpread(_objectSpread({}, current), {}, (0, _defineProperty2.default)((0, _defineProperty2.default)({
|
|
1139
|
+
orgId: orgId || current.orgId,
|
|
1140
|
+
env: env || current.env
|
|
1141
|
+
}, serviceGroup, meta ? {
|
|
1142
|
+
hostMap: hostMap,
|
|
1143
|
+
meta: meta
|
|
1144
|
+
} : hostMap), "cachedAt", (0, _now.default)()));
|
|
1145
|
+
ls = _this8._getLocalStorageSafe();
|
|
1146
|
+
if (ls) {
|
|
1147
|
+
ls.setItem(CATALOG_CACHE_KEY_V1, (0, _stringify.default)(updated));
|
|
1148
|
+
}
|
|
1149
|
+
_context2.next = 4;
|
|
1150
|
+
break;
|
|
1151
|
+
case 3:
|
|
1152
|
+
_context2.prev = 3;
|
|
1153
|
+
_t2 = _context2["catch"](1);
|
|
1154
|
+
_this8.logger.warn('services: error caching catalog', _t2);
|
|
1155
|
+
case 4:
|
|
1156
|
+
case "end":
|
|
1157
|
+
return _context2.stop();
|
|
1158
|
+
}
|
|
1159
|
+
}, _callee2, null, [[1, 3]]);
|
|
1160
|
+
}))();
|
|
1161
|
+
},
|
|
1162
|
+
/**
|
|
1163
|
+
* Load the catalog from cache and hydrate the in-memory ServiceCatalog.
|
|
1164
|
+
* @returns {Promise<boolean>} true if cache was loaded, false otherwise
|
|
1165
|
+
*/
|
|
1166
|
+
_loadCatalogFromCache: function _loadCatalogFromCache() {
|
|
1167
|
+
var _this9 = this;
|
|
1168
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
1169
|
+
var currentOrgId, _this9$webex$config, _this9$webex$config$c, _this9$webex$config2, _this9$webex$config3, _this9$webex$config3$, _this9$webex$config3$2, ls, cachedJson, cached, cachedAt, _this9$webex$credenti, credentials, fedramp, u2cDiscoveryUrl, currentEnv, sameEnv, catalog, groups, _t3, _t4;
|
|
1170
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
1171
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
1172
|
+
case 0:
|
|
1173
|
+
_context3.prev = 0;
|
|
1174
|
+
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) {
|
|
1175
|
+
_context3.next = 1;
|
|
1176
|
+
break;
|
|
1177
|
+
}
|
|
1178
|
+
_this9.logger.info('services: skipping cache warm-up as per the cache config');
|
|
1179
|
+
return _context3.abrupt("return", false);
|
|
1180
|
+
case 1:
|
|
1181
|
+
ls = _this9._getLocalStorageSafe();
|
|
1182
|
+
if (ls) {
|
|
1183
|
+
_context3.next = 2;
|
|
1184
|
+
break;
|
|
1185
|
+
}
|
|
1186
|
+
_this9.logger.info('services: skipping cache warm-up as no localStorage is available');
|
|
1187
|
+
return _context3.abrupt("return", false);
|
|
1188
|
+
case 2:
|
|
1189
|
+
cachedJson = ls.getItem(CATALOG_CACHE_KEY_V1);
|
|
1190
|
+
cached = cachedJson ? JSON.parse(cachedJson) : undefined;
|
|
1191
|
+
if (cached) {
|
|
1192
|
+
_context3.next = 3;
|
|
1193
|
+
break;
|
|
1194
|
+
}
|
|
1195
|
+
return _context3.abrupt("return", false);
|
|
1196
|
+
case 3:
|
|
1197
|
+
// TTL enforcement: clear if older than 24 hours
|
|
1198
|
+
cachedAt = Number(cached.cachedAt) || 0;
|
|
1199
|
+
if (!(!cachedAt || (0, _now.default)() - cachedAt > CATALOG_TTL_MS)) {
|
|
1200
|
+
_context3.next = 4;
|
|
1201
|
+
break;
|
|
1202
|
+
}
|
|
1203
|
+
_this9.clearCatalogCache();
|
|
1204
|
+
return _context3.abrupt("return", false);
|
|
1205
|
+
case 4:
|
|
1206
|
+
_context3.prev = 4;
|
|
1207
|
+
if (!((_this9$webex$credenti = _this9.webex.credentials) !== null && _this9$webex$credenti !== void 0 && _this9$webex$credenti.canAuthorize)) {
|
|
1208
|
+
_context3.next = 5;
|
|
1209
|
+
break;
|
|
1210
|
+
}
|
|
1211
|
+
credentials = _this9.webex.credentials;
|
|
1212
|
+
currentOrgId = credentials.getOrgId();
|
|
1213
|
+
if (!(cached.orgId && cached.orgId !== currentOrgId)) {
|
|
1214
|
+
_context3.next = 5;
|
|
1215
|
+
break;
|
|
1216
|
+
}
|
|
1217
|
+
return _context3.abrupt("return", false);
|
|
1218
|
+
case 5:
|
|
1219
|
+
_context3.next = 7;
|
|
1220
|
+
break;
|
|
1221
|
+
case 6:
|
|
1222
|
+
_context3.prev = 6;
|
|
1223
|
+
_t3 = _context3["catch"](4);
|
|
1224
|
+
_this9.logger.warn('services: error checking orgId', _t3);
|
|
1225
|
+
case 7:
|
|
1226
|
+
// Ensure cached environment matches current environment
|
|
1227
|
+
fedramp = !!((_this9$webex$config2 = _this9.webex.config) !== null && _this9$webex$config2 !== void 0 && _this9$webex$config2.fedramp);
|
|
1228
|
+
u2cDiscoveryUrl = (_this9$webex$config3 = _this9.webex.config) === null || _this9$webex$config3 === void 0 ? void 0 : (_this9$webex$config3$ = _this9$webex$config3.services) === null || _this9$webex$config3$ === void 0 ? void 0 : (_this9$webex$config3$2 = _this9$webex$config3$.discovery) === null || _this9$webex$config3$2 === void 0 ? void 0 : _this9$webex$config3$2.u2c;
|
|
1229
|
+
currentEnv = {
|
|
1230
|
+
fedramp: fedramp,
|
|
1231
|
+
u2cDiscoveryUrl: u2cDiscoveryUrl
|
|
1232
|
+
};
|
|
1233
|
+
if (!cached.env) {
|
|
1234
|
+
_context3.next = 8;
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
sameEnv = cached.env.fedramp === currentEnv.fedramp && cached.env.u2cDiscoveryUrl === currentEnv.u2cDiscoveryUrl;
|
|
1238
|
+
if (sameEnv) {
|
|
1239
|
+
_context3.next = 8;
|
|
1240
|
+
break;
|
|
1241
|
+
}
|
|
1242
|
+
_this9.logger.info('services: skipping cache warm due to environment mismatch');
|
|
1243
|
+
return _context3.abrupt("return", false);
|
|
1244
|
+
case 8:
|
|
1245
|
+
catalog = _this9._getCatalog(); // Apply any cached groups (with preauth selection validation if available)
|
|
1246
|
+
groups = ['preauth', 'signin', 'postauth'];
|
|
1247
|
+
groups.forEach(function (serviceGroup) {
|
|
1248
|
+
var cachedGroup = cached[serviceGroup];
|
|
1249
|
+
if (!cachedGroup) {
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// Support legacy (hostMap) and new ({hostMap, meta}) shapes
|
|
1254
|
+
var hostMap = cachedGroup && cachedGroup.hostMap ? cachedGroup.hostMap : cachedGroup;
|
|
1255
|
+
var meta = cachedGroup === null || cachedGroup === void 0 ? void 0 : cachedGroup.meta;
|
|
1256
|
+
if (serviceGroup === 'preauth' && meta) {
|
|
1257
|
+
// For proximity-based selection, always fetch fresh to respect IP/region changes
|
|
1258
|
+
if (meta.selectionType === 'mode') {
|
|
1259
|
+
_this9.logger.info('services: skipping preauth cache warm for proximity mode');
|
|
1260
|
+
return;
|
|
1261
|
+
}
|
|
1262
|
+
var intended = _this9.getIntendedPreauthSelection(currentOrgId);
|
|
1263
|
+
var matches = intended && intended.selectionType === meta.selectionType && intended.selectionValue === meta.selectionValue;
|
|
1264
|
+
if (!matches) {
|
|
1265
|
+
_this9.logger.info('services: skipping preauth cache warm due to selection mismatch');
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
if (hostMap) {
|
|
1270
|
+
var formatted = _this9._formatReceivedHostmap(hostMap);
|
|
1271
|
+
catalog.updateServiceUrls(serviceGroup, formatted);
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
// Align credentials against warmed catalog
|
|
1276
|
+
_this9.updateCredentialsConfig();
|
|
1277
|
+
return _context3.abrupt("return", true);
|
|
1278
|
+
case 9:
|
|
1279
|
+
_context3.prev = 9;
|
|
1280
|
+
_t4 = _context3["catch"](0);
|
|
1281
|
+
_this9.logger.warn('services: error loading catalog from cache', _t4);
|
|
1282
|
+
return _context3.abrupt("return", false);
|
|
1283
|
+
case 10:
|
|
1284
|
+
case "end":
|
|
1285
|
+
return _context3.stop();
|
|
1286
|
+
}
|
|
1287
|
+
}, _callee3, null, [[0, 9], [4, 6]]);
|
|
1288
|
+
}))();
|
|
1289
|
+
},
|
|
1290
|
+
/**
|
|
1291
|
+
* Clear the catalog cache from the bounded storage.
|
|
1292
|
+
* @returns {Promise<void>}
|
|
1293
|
+
*/
|
|
1294
|
+
clearCatalogCache: function clearCatalogCache() {
|
|
1295
|
+
try {
|
|
1296
|
+
var ls = this._getLocalStorageSafe();
|
|
1297
|
+
if (ls) {
|
|
1298
|
+
ls.removeItem(CATALOG_CACHE_KEY_V1);
|
|
1299
|
+
}
|
|
1300
|
+
} catch (e) {
|
|
1301
|
+
this.logger.warn('services: error clearing catalog cache', e);
|
|
1302
|
+
}
|
|
1303
|
+
return _promise.default.resolve();
|
|
1304
|
+
},
|
|
981
1305
|
/**
|
|
982
1306
|
* Initialize the discovery services and the whitelisted services.
|
|
983
1307
|
*
|
|
@@ -986,9 +1310,9 @@ var Services = _webexPlugin.default.extend({
|
|
|
986
1310
|
initConfig: function initConfig() {
|
|
987
1311
|
// Get the catalog and destructure the services config.
|
|
988
1312
|
var catalog = this._getCatalog();
|
|
989
|
-
var _this$webex$
|
|
990
|
-
services = _this$webex$
|
|
991
|
-
fedramp = _this$webex$
|
|
1313
|
+
var _this$webex$config2 = this.webex.config,
|
|
1314
|
+
services = _this$webex$config2.services,
|
|
1315
|
+
fedramp = _this$webex$config2.fedramp;
|
|
992
1316
|
|
|
993
1317
|
// Validate that the services configuration exists.
|
|
994
1318
|
if (services) {
|
|
@@ -1042,7 +1366,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
1042
1366
|
* @returns {Promise<void, Error>} - Errors if the token is unavailable.
|
|
1043
1367
|
*/
|
|
1044
1368
|
initServiceCatalogs: function initServiceCatalogs() {
|
|
1045
|
-
var
|
|
1369
|
+
var _this0 = this;
|
|
1046
1370
|
this.logger.info('services: initializing initial service catalogs');
|
|
1047
1371
|
|
|
1048
1372
|
// Destructure the credentials plugin.
|
|
@@ -1057,16 +1381,17 @@ var Services = _webexPlugin.default.extend({
|
|
|
1057
1381
|
})
|
|
1058
1382
|
// Begin collecting the preauth/limited catalog.
|
|
1059
1383
|
.then(function (orgId) {
|
|
1060
|
-
return
|
|
1384
|
+
return _this0.collectPreauthCatalog({
|
|
1061
1385
|
orgId: orgId
|
|
1062
1386
|
});
|
|
1063
1387
|
}).then(function () {
|
|
1064
1388
|
// Validate if the token is authorized.
|
|
1065
1389
|
if (credentials.canAuthorize) {
|
|
1066
1390
|
// Attempt to collect the postauth catalog.
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1391
|
+
|
|
1392
|
+
return _this0.updateServices().catch(function () {
|
|
1393
|
+
_this0.initFailed = true;
|
|
1394
|
+
_this0.logger.warn('services: cannot retrieve postauth catalog');
|
|
1070
1395
|
});
|
|
1071
1396
|
}
|
|
1072
1397
|
|
|
@@ -1074,6 +1399,42 @@ var Services = _webexPlugin.default.extend({
|
|
|
1074
1399
|
return _promise.default.resolve();
|
|
1075
1400
|
});
|
|
1076
1401
|
},
|
|
1402
|
+
/**
|
|
1403
|
+
* Await any in-flight credentials refresh, then flip `services.ready` so
|
|
1404
|
+
* `webex.ready` can fire. Closes the parallel-refresh window: if a credential
|
|
1405
|
+
* refresh is in flight when initial catalog collection settles, we must not
|
|
1406
|
+
* signal ready until the refresh has resolved - otherwise downstream
|
|
1407
|
+
* consumers may observe `canAuthorize`/token state that is about to change
|
|
1408
|
+
* under them.
|
|
1409
|
+
*
|
|
1410
|
+
* @private
|
|
1411
|
+
* @returns {Promise<void>}
|
|
1412
|
+
*/
|
|
1413
|
+
_finalizeReady: function _finalizeReady() {
|
|
1414
|
+
var _this1 = this;
|
|
1415
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
1416
|
+
var credentials;
|
|
1417
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
1418
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
1419
|
+
case 0:
|
|
1420
|
+
credentials = _this1.webex.credentials;
|
|
1421
|
+
if (!(credentials && credentials.isRefreshing)) {
|
|
1422
|
+
_context4.next = 1;
|
|
1423
|
+
break;
|
|
1424
|
+
}
|
|
1425
|
+
_context4.next = 1;
|
|
1426
|
+
return new _promise.default(function (resolve) {
|
|
1427
|
+
credentials.once('change:isRefreshing', resolve);
|
|
1428
|
+
});
|
|
1429
|
+
case 1:
|
|
1430
|
+
_this1.ready = true;
|
|
1431
|
+
case 2:
|
|
1432
|
+
case "end":
|
|
1433
|
+
return _context4.stop();
|
|
1434
|
+
}
|
|
1435
|
+
}, _callee4);
|
|
1436
|
+
}))();
|
|
1437
|
+
},
|
|
1077
1438
|
/**
|
|
1078
1439
|
* Initializer
|
|
1079
1440
|
*
|
|
@@ -1082,7 +1443,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
1082
1443
|
* @returns {Services}
|
|
1083
1444
|
*/
|
|
1084
1445
|
initialize: function initialize() {
|
|
1085
|
-
var
|
|
1446
|
+
var _this10 = this;
|
|
1086
1447
|
var catalog = new _serviceCatalog.default();
|
|
1087
1448
|
var registry = new _serviceRegistry.default();
|
|
1088
1449
|
var state = new _serviceState.default();
|
|
@@ -1090,35 +1451,163 @@ var Services = _webexPlugin.default.extend({
|
|
|
1090
1451
|
this.registries.set(this.webex, registry);
|
|
1091
1452
|
this.states.set(this.webex, state);
|
|
1092
1453
|
|
|
1093
|
-
// Listen for configuration changes once.
|
|
1454
|
+
// Listen for configuration changes once. The config is not populated on the
|
|
1455
|
+
// webex instance until the `change:config` event fires, so any decision that
|
|
1456
|
+
// depends on config values (such as the gated-vs-ungated init below) must be
|
|
1457
|
+
// made from within this handler rather than synchronously in `initialize()`.
|
|
1094
1458
|
this.listenToOnce(this.webex, 'change:config', function () {
|
|
1095
|
-
|
|
1096
|
-
|
|
1459
|
+
var _this10$webex$config, _this10$webex$config$;
|
|
1460
|
+
_this10.initConfig();
|
|
1097
1461
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
//
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
}).catch(function (error) {
|
|
1107
|
-
_this9.initFailed = true;
|
|
1108
|
-
_this9.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1109
|
-
});
|
|
1462
|
+
// Feature flag: when enabled, `webex.ready` is blocked until the initial
|
|
1463
|
+
// catalog collection has settled AND any in-flight credentials refresh has
|
|
1464
|
+
// completed. When disabled (the default), preserves the pre-existing
|
|
1465
|
+
// behavior where `webex.ready` fires as soon as `webex.loaded` does and
|
|
1466
|
+
// the catalog is collected out-of-band.
|
|
1467
|
+
var waitForCatalogInit = ((_this10$webex$config = _this10.webex.config) === null || _this10$webex$config === void 0 ? void 0 : (_this10$webex$config$ = _this10$webex$config.services) === null || _this10$webex$config$ === void 0 ? void 0 : _this10$webex$config$.waitForCatalogInit) === true;
|
|
1468
|
+
if (waitForCatalogInit) {
|
|
1469
|
+
_this10._initializeCatalogsGated(catalog);
|
|
1110
1470
|
} else {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
} : undefined).catch(function (error) {
|
|
1115
|
-
_this9.initFailed = true;
|
|
1116
|
-
_this9.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1117
|
-
});
|
|
1471
|
+
// Not gating - immediately mark ready so we do not block webex.ready.
|
|
1472
|
+
_this10.ready = true;
|
|
1473
|
+
_this10._initializeCatalogsUngated(catalog);
|
|
1118
1474
|
}
|
|
1119
1475
|
});
|
|
1120
1476
|
},
|
|
1121
|
-
|
|
1477
|
+
/**
|
|
1478
|
+
* Original (pre-verified-ready) initialization path. Runs on `webex.ready`
|
|
1479
|
+
* and collects catalogs opportunistically without blocking anything.
|
|
1480
|
+
*
|
|
1481
|
+
* @private
|
|
1482
|
+
* @param {ServiceCatalog} catalog
|
|
1483
|
+
* @returns {void}
|
|
1484
|
+
*/
|
|
1485
|
+
_initializeCatalogsUngated: function _initializeCatalogsUngated(catalog) {
|
|
1486
|
+
var _this11 = this;
|
|
1487
|
+
// wait for webex instance to be ready before attempting
|
|
1488
|
+
// to update the service catalogs
|
|
1489
|
+
// this can cause a race condition because credentials may
|
|
1490
|
+
// not be valid when services is initialized
|
|
1491
|
+
this.listenToOnce(this.webex, 'ready', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
1492
|
+
var cachedCatalog, supertoken, email;
|
|
1493
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
1494
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
1495
|
+
case 0:
|
|
1496
|
+
_context5.next = 1;
|
|
1497
|
+
return _this11._loadCatalogFromCache();
|
|
1498
|
+
case 1:
|
|
1499
|
+
cachedCatalog = _context5.sent;
|
|
1500
|
+
if (!cachedCatalog) {
|
|
1501
|
+
_context5.next = 2;
|
|
1502
|
+
break;
|
|
1503
|
+
}
|
|
1504
|
+
catalog.isReady = true;
|
|
1505
|
+
return _context5.abrupt("return");
|
|
1506
|
+
case 2:
|
|
1507
|
+
supertoken = _this11.webex.credentials.supertoken; // Validate if the supertoken exists.
|
|
1508
|
+
if (supertoken && supertoken.access_token) {
|
|
1509
|
+
_this11.initServiceCatalogs().then(function () {
|
|
1510
|
+
catalog.isReady = true;
|
|
1511
|
+
}).catch(function (error) {
|
|
1512
|
+
_this11.initFailed = true;
|
|
1513
|
+
_this11.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1514
|
+
});
|
|
1515
|
+
} else {
|
|
1516
|
+
email = _this11.webex.config.email;
|
|
1517
|
+
_this11.collectPreauthCatalog(email ? {
|
|
1518
|
+
email: email
|
|
1519
|
+
} : undefined).catch(function (error) {
|
|
1520
|
+
_this11.initFailed = true;
|
|
1521
|
+
_this11.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
case 3:
|
|
1525
|
+
case "end":
|
|
1526
|
+
return _context5.stop();
|
|
1527
|
+
}
|
|
1528
|
+
}, _callee5);
|
|
1529
|
+
})));
|
|
1530
|
+
},
|
|
1531
|
+
/**
|
|
1532
|
+
* Verified-ready initialization path. Blocks `webex.ready` until the initial
|
|
1533
|
+
* catalog fetch has settled (or timed out) AND any in-flight credentials
|
|
1534
|
+
* refresh has completed. Also handles the fresh-login case where OAuth
|
|
1535
|
+
* completes after `loaded` fires.
|
|
1536
|
+
*
|
|
1537
|
+
* @private
|
|
1538
|
+
* @param {ServiceCatalog} catalog
|
|
1539
|
+
* @returns {void}
|
|
1540
|
+
*/
|
|
1541
|
+
_initializeCatalogsGated: function _initializeCatalogsGated(catalog) {
|
|
1542
|
+
var _this12 = this;
|
|
1543
|
+
// Wait for storage to be loaded before attempting to update the service
|
|
1544
|
+
// catalogs. We listen for 'loaded' instead of 'ready' because `services.ready`
|
|
1545
|
+
// now blocks `webex.ready` - listening to 'ready' would deadlock.
|
|
1546
|
+
this.listenToOnce(this.webex, 'loaded', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
|
|
1547
|
+
var cachedCatalog, supertoken, timeout, email;
|
|
1548
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
1549
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
1550
|
+
case 0:
|
|
1551
|
+
_context6.next = 1;
|
|
1552
|
+
return _this12._loadCatalogFromCache();
|
|
1553
|
+
case 1:
|
|
1554
|
+
cachedCatalog = _context6.sent;
|
|
1555
|
+
if (!cachedCatalog) {
|
|
1556
|
+
_context6.next = 3;
|
|
1557
|
+
break;
|
|
1558
|
+
}
|
|
1559
|
+
catalog.isReady = true;
|
|
1560
|
+
_context6.next = 2;
|
|
1561
|
+
return _this12._finalizeReady();
|
|
1562
|
+
case 2:
|
|
1563
|
+
return _context6.abrupt("return");
|
|
1564
|
+
case 3:
|
|
1565
|
+
supertoken = _this12.webex.credentials.supertoken; // Race init against a hard timeout so a hung request never leaves
|
|
1566
|
+
// `services.ready` false forever - that would stall `webex.ready` and
|
|
1567
|
+
// leave the app on a permanent spinner.
|
|
1568
|
+
timeout = new _promise.default(function (_, reject) {
|
|
1569
|
+
setTimeout(function () {
|
|
1570
|
+
return reject(new Error("services: init timed out after ".concat(SERVICES_INIT_TIMEOUT_MS, "ms")));
|
|
1571
|
+
}, SERVICES_INIT_TIMEOUT_MS);
|
|
1572
|
+
}); // Validate if the supertoken exists.
|
|
1573
|
+
if (supertoken && supertoken.access_token) {
|
|
1574
|
+
_promise.default.race([_this12.initServiceCatalogs(), timeout]).then(function () {
|
|
1575
|
+
catalog.isReady = true;
|
|
1576
|
+
}).catch(function (error) {
|
|
1577
|
+
_this12.initFailed = true;
|
|
1578
|
+
_this12.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1579
|
+
}).finally(function () {
|
|
1580
|
+
return _this12._finalizeReady();
|
|
1581
|
+
});
|
|
1582
|
+
} else {
|
|
1583
|
+
email = _this12.webex.config.email;
|
|
1584
|
+
_promise.default.race([_this12.collectPreauthCatalog(email ? {
|
|
1585
|
+
email: email
|
|
1586
|
+
} : undefined), timeout]).catch(function (error) {
|
|
1587
|
+
_this12.initFailed = true;
|
|
1588
|
+
_this12.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1589
|
+
}).finally(function () {
|
|
1590
|
+
return _this12._finalizeReady();
|
|
1591
|
+
});
|
|
1592
|
+
|
|
1593
|
+
// Handle fresh login: 'loaded' fires before OAuth completes, so listen
|
|
1594
|
+
// for `canAuthorize` flipping true and then collect the postauth catalog.
|
|
1595
|
+
_this12.listenToOnce(_this12.webex, 'change:canAuthorize', function () {
|
|
1596
|
+
if (_this12.webex.canAuthorize && !catalog.status.postauth.ready) {
|
|
1597
|
+
_this12.initServiceCatalogs().catch(function (error) {
|
|
1598
|
+
_this12.logger.error("services: failed to init service catalogs after auth, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
case 4:
|
|
1604
|
+
case "end":
|
|
1605
|
+
return _context6.stop();
|
|
1606
|
+
}
|
|
1607
|
+
}, _callee6);
|
|
1608
|
+
})));
|
|
1609
|
+
},
|
|
1610
|
+
version: "3.12.0-webex-services-ready.2"
|
|
1122
1611
|
});
|
|
1123
1612
|
/* eslint-enable no-underscore-dangle */
|
|
1124
1613
|
var _default = exports.default = Services;
|