@webex/webex-core 3.10.0 → 3.11.0

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.
Files changed (118) hide show
  1. package/dist/config.js +14 -0
  2. package/dist/config.js.map +1 -1
  3. package/dist/credentials-config.js.map +1 -1
  4. package/dist/index.js +1 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/interceptors/auth.js +6 -8
  7. package/dist/interceptors/auth.js.map +1 -1
  8. package/dist/interceptors/default-options.js +6 -8
  9. package/dist/interceptors/default-options.js.map +1 -1
  10. package/dist/interceptors/embargo.js +6 -8
  11. package/dist/interceptors/embargo.js.map +1 -1
  12. package/dist/interceptors/network-timing.js +6 -8
  13. package/dist/interceptors/network-timing.js.map +1 -1
  14. package/dist/interceptors/payload-transformer.js +6 -8
  15. package/dist/interceptors/payload-transformer.js.map +1 -1
  16. package/dist/interceptors/proxy.js +7 -10
  17. package/dist/interceptors/proxy.js.map +1 -1
  18. package/dist/interceptors/rate-limit.js +7 -10
  19. package/dist/interceptors/rate-limit.js.map +1 -1
  20. package/dist/interceptors/redirect.js +9 -8
  21. package/dist/interceptors/redirect.js.map +1 -1
  22. package/dist/interceptors/request-event.js +6 -8
  23. package/dist/interceptors/request-event.js.map +1 -1
  24. package/dist/interceptors/request-logger.js +6 -8
  25. package/dist/interceptors/request-logger.js.map +1 -1
  26. package/dist/interceptors/request-timing.js +6 -8
  27. package/dist/interceptors/request-timing.js.map +1 -1
  28. package/dist/interceptors/response-logger.js +6 -8
  29. package/dist/interceptors/response-logger.js.map +1 -1
  30. package/dist/interceptors/user-agent.js +8 -11
  31. package/dist/interceptors/user-agent.js.map +1 -1
  32. package/dist/interceptors/webex-tracking-id.js +6 -8
  33. package/dist/interceptors/webex-tracking-id.js.map +1 -1
  34. package/dist/interceptors/webex-user-agent.js +7 -10
  35. package/dist/interceptors/webex-user-agent.js.map +1 -1
  36. package/dist/lib/batcher.js +1 -1
  37. package/dist/lib/batcher.js.map +1 -1
  38. package/dist/lib/constants.js.map +1 -1
  39. package/dist/lib/credentials/credentials.js +4 -6
  40. package/dist/lib/credentials/credentials.js.map +1 -1
  41. package/dist/lib/credentials/grant-errors.js +18 -26
  42. package/dist/lib/credentials/grant-errors.js.map +1 -1
  43. package/dist/lib/credentials/index.js.map +1 -1
  44. package/dist/lib/credentials/scope.js.map +1 -1
  45. package/dist/lib/credentials/token-collection.js.map +1 -1
  46. package/dist/lib/credentials/token.js +5 -5
  47. package/dist/lib/credentials/token.js.map +1 -1
  48. package/dist/lib/interceptors/hostmap.js +6 -8
  49. package/dist/lib/interceptors/hostmap.js.map +1 -1
  50. package/dist/lib/interceptors/server-error.js +6 -8
  51. package/dist/lib/interceptors/server-error.js.map +1 -1
  52. package/dist/lib/interceptors/service.js +6 -8
  53. package/dist/lib/interceptors/service.js.map +1 -1
  54. package/dist/lib/metrics.js.map +1 -1
  55. package/dist/lib/page.js +5 -6
  56. package/dist/lib/page.js.map +1 -1
  57. package/dist/lib/services/index.js.map +1 -1
  58. package/dist/lib/services/service-catalog.js +3 -3
  59. package/dist/lib/services/service-catalog.js.map +1 -1
  60. package/dist/lib/services/service-fed-ramp.js.map +1 -1
  61. package/dist/lib/services/service-host.js +1 -2
  62. package/dist/lib/services/service-host.js.map +1 -1
  63. package/dist/lib/services/service-registry.js +1 -2
  64. package/dist/lib/services/service-registry.js.map +1 -1
  65. package/dist/lib/services/service-state.js +1 -2
  66. package/dist/lib/services/service-state.js.map +1 -1
  67. package/dist/lib/services/service-url.js +11 -1
  68. package/dist/lib/services/service-url.js.map +1 -1
  69. package/dist/lib/services/services.js +485 -127
  70. package/dist/lib/services/services.js.map +1 -1
  71. package/dist/lib/services-v2/index.js.map +1 -1
  72. package/dist/lib/services-v2/metrics.js.map +1 -1
  73. package/dist/lib/services-v2/service-catalog.js +7 -7
  74. package/dist/lib/services-v2/service-catalog.js.map +1 -1
  75. package/dist/lib/services-v2/service-detail.js.map +1 -1
  76. package/dist/lib/services-v2/service-fed-ramp.js.map +1 -1
  77. package/dist/lib/services-v2/services-v2.js +379 -51
  78. package/dist/lib/services-v2/services-v2.js.map +1 -1
  79. package/dist/lib/services-v2/types.js.map +1 -1
  80. package/dist/lib/stateless-webex-plugin.js +3 -4
  81. package/dist/lib/stateless-webex-plugin.js.map +1 -1
  82. package/dist/lib/storage/decorators.js.map +1 -1
  83. package/dist/lib/storage/errors.js +7 -9
  84. package/dist/lib/storage/errors.js.map +1 -1
  85. package/dist/lib/storage/index.js.map +1 -1
  86. package/dist/lib/storage/make-webex-plugin-store.js +14 -5
  87. package/dist/lib/storage/make-webex-plugin-store.js.map +1 -1
  88. package/dist/lib/storage/make-webex-store.js +13 -5
  89. package/dist/lib/storage/make-webex-store.js.map +1 -1
  90. package/dist/lib/storage/memory-store-adapter.js.map +1 -1
  91. package/dist/lib/webex-core-plugin-mixin.js.map +1 -1
  92. package/dist/lib/webex-http-error.js +8 -11
  93. package/dist/lib/webex-http-error.js.map +1 -1
  94. package/dist/lib/webex-internal-core-plugin-mixin.js.map +1 -1
  95. package/dist/lib/webex-plugin.js.map +1 -1
  96. package/dist/plugins/logger.js +1 -1
  97. package/dist/plugins/logger.js.map +1 -1
  98. package/dist/webex-core.js +11 -11
  99. package/dist/webex-core.js.map +1 -1
  100. package/dist/webex-internal-core.js.map +1 -1
  101. package/package.json +13 -13
  102. package/src/config.js +15 -0
  103. package/src/interceptors/redirect.js +4 -0
  104. package/src/lib/services/service-url.js +9 -1
  105. package/src/lib/services/services.js +315 -7
  106. package/src/lib/services-v2/index.ts +0 -1
  107. package/src/lib/services-v2/service-catalog.ts +4 -4
  108. package/src/lib/services-v2/services-v2.ts +307 -7
  109. package/src/lib/services-v2/types.ts +13 -0
  110. package/test/fixtures/host-catalog-v2.ts +1 -1
  111. package/test/integration/spec/services/service-catalog.js +10 -4
  112. package/test/integration/spec/services/services.js +65 -9
  113. package/test/integration/spec/services-v2/service-catalog.js +2 -2
  114. package/test/integration/spec/services-v2/services-v2.js +56 -6
  115. package/test/unit/spec/interceptors/redirect.js +98 -0
  116. package/test/unit/spec/services/service-url.js +110 -0
  117. package/test/unit/spec/services/services.js +411 -2
  118. package/test/unit/spec/services-v2/services-v2.ts +316 -0
@@ -1 +1 @@
1
- {"version":3,"names":["hydra","u2c","sqdiscovery"],"sources":["service-fed-ramp.ts"],"sourcesContent":["export default {\n hydra: 'https://api-usgov.webex.com/v1',\n u2c: 'https://u2c.gov.ciscospark.com/u2c/api/v1',\n sqdiscovery: 'https://ds.ciscospark.com/v1/region', // TODO: fedramp load balanced URL? this has been here for years as of now but now explicitly done\n};\n"],"mappings":";;;;;;;iCAAe;EACbA,KAAK,EAAE,gCAAgC;EACvCC,GAAG,EAAE,2CAA2C;EAChDC,WAAW,EAAE,qCAAqC,CAAE;AACtD,CAAC"}
1
+ {"version":3,"names":["hydra","u2c","sqdiscovery"],"sources":["service-fed-ramp.ts"],"sourcesContent":["export default {\n hydra: 'https://api-usgov.webex.com/v1',\n u2c: 'https://u2c.gov.ciscospark.com/u2c/api/v1',\n sqdiscovery: 'https://ds.ciscospark.com/v1/region', // TODO: fedramp load balanced URL? this has been here for years as of now but now explicitly done\n};\n"],"mappings":";;;;;;;iCAAe;EACbA,KAAK,EAAE,gCAAgC;EACvCC,GAAG,EAAE,2CAA2C;EAChDC,WAAW,EAAE,qCAAqC,CAAE;AACtD,CAAC","ignoreList":[]}
@@ -11,12 +11,17 @@ _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"));
19
+ var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
17
20
  var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
18
21
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
19
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"));
20
25
  var _sha = _interopRequireDefault(require("crypto-js/sha256"));
21
26
  var _lodash = require("lodash");
22
27
  var _webexPlugin = _interopRequireDefault(require("../webex-plugin"));
@@ -34,6 +39,8 @@ var DEFAULT_CLUSTER = exports.DEFAULT_CLUSTER = 'urn:TEAM:us-east-2_a';
34
39
  var DEFAULT_CLUSTER_SERVICE = exports.DEFAULT_CLUSTER_SERVICE = 'identityLookup';
35
40
  var CLUSTER_SERVICE = process.env.WEBEX_CONVERSATION_CLUSTER_SERVICE || DEFAULT_CLUSTER_SERVICE;
36
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
37
44
 
38
45
  /* eslint-disable no-underscore-dangle */
39
46
  /**
@@ -57,6 +64,45 @@ var Services = _webexPlugin.default.extend({
57
64
  _getCatalog: function _getCatalog() {
58
65
  return this._catalogs.get(this.webex);
59
66
  },
67
+ /**
68
+ * Safely access localStorage if available; returns the Storage or null.
69
+ * @returns {Storage | null}
70
+ */
71
+ _getLocalStorageSafe: function _getLocalStorageSafe() {
72
+ if (typeof window !== 'undefined' && window.localStorage) {
73
+ return window.localStorage;
74
+ }
75
+ return null;
76
+ },
77
+ /**
78
+ * Determine the intended preauth selection based on the current context.
79
+ * @param {string} [currentOrgId]
80
+ * @returns {{selectionType: string, selectionValue: string}}
81
+ */
82
+ getIntendedPreauthSelection: function getIntendedPreauthSelection(currentOrgId) {
83
+ var _this$webex$credentia;
84
+ if ((_this$webex$credentia = this.webex.credentials) !== null && _this$webex$credentia !== void 0 && _this$webex$credentia.canAuthorize) {
85
+ if (currentOrgId) {
86
+ return {
87
+ selectionType: 'orgId',
88
+ selectionValue: currentOrgId
89
+ };
90
+ }
91
+ }
92
+ var emailConfig = this.webex.config && this.webex.config.email;
93
+ if (typeof emailConfig === 'string' && emailConfig.trim()) {
94
+ return {
95
+ selectionType: 'emailhash',
96
+ selectionValue: (0, _sha.default)(emailConfig.toLowerCase()).toString()
97
+ };
98
+ }
99
+
100
+ // fall back to proximity mode when no orgId or email available
101
+ return {
102
+ selectionType: 'mode',
103
+ selectionValue: 'DEFAULT_BY_PROXIMITY'
104
+ };
105
+ },
60
106
  /**
61
107
  * Get a service url from the current services list by name
62
108
  * from the associated instance catalog.
@@ -98,6 +144,48 @@ var Services = _webexPlugin.default.extend({
98
144
  var catalog = this._getCatalog();
99
145
  return catalog.markFailedServiceUrl(url);
100
146
  },
147
+ /**
148
+ * Get all Mobius cluster host entries from the v2 services list.
149
+ * @returns {Array<ServiceHost>} - An array of `ServiceHost` objects.
150
+ */
151
+ getMobiusClusters: function getMobiusClusters() {
152
+ this.logger.info('services: fetching mobius clusters');
153
+ var clusters = [];
154
+ var services = this._services || [];
155
+ services.filter(function (service) {
156
+ return (service === null || service === void 0 ? void 0 : service.serviceName) === 'mobius' && (0, _isArray.default)(service.serviceUrls) && service.serviceUrls.length > 0;
157
+ }).forEach(function (service) {
158
+ service.serviceUrls.forEach(function (serviceUrl) {
159
+ var modifiedHost = serviceUrl.baseUrl.replace('https://', '').replace('/api/v1', '');
160
+ if (!clusters.find(function (c) {
161
+ return c && c.host === modifiedHost;
162
+ })) {
163
+ clusters.push({
164
+ host: modifiedHost,
165
+ priority: serviceUrl.priority,
166
+ id: service.id,
167
+ ttl: 0
168
+ });
169
+ }
170
+ });
171
+ });
172
+ return clusters;
173
+ },
174
+ /**
175
+ * Check is valid host from services list.
176
+ * @param {string} host
177
+ * @returns {Boolean}
178
+ */
179
+ isValidHost: function isValidHost(host) {
180
+ var services = this._services || [];
181
+ return services.some(function (service) {
182
+ return service.serviceUrls.some(function (serviceUrl) {
183
+ var _URL;
184
+ var serviceHost = (serviceUrl === null || serviceUrl === void 0 ? void 0 : serviceUrl.baseUrl) && ((_URL = new URL(serviceUrl.baseUrl)) === null || _URL === void 0 ? void 0 : _URL.host);
185
+ return serviceHost === host;
186
+ });
187
+ });
188
+ },
101
189
  /**
102
190
  * saves all the services from the pre and post catalog service
103
191
  * @param {ActiveServices} activeServices
@@ -180,6 +268,18 @@ var Services = _webexPlugin.default.extend({
180
268
  forceRefresh: forceRefresh
181
269
  }).then(function (serviceHostMap) {
182
270
  catalog.updateServiceGroups(serviceGroup, serviceHostMap === null || serviceHostMap === void 0 ? void 0 : serviceHostMap.services, serviceHostMap === null || serviceHostMap === void 0 ? void 0 : serviceHostMap.timestamp);
271
+ // Build selection metadata for caching discrimination (preauth/signin)
272
+ var selectionMeta;
273
+ if (serviceGroup === 'preauth' || serviceGroup === 'signin') {
274
+ var key = formattedQuery && (0, _keys.default)(formattedQuery || {})[0];
275
+ if (key) {
276
+ selectionMeta = {
277
+ selectionType: key,
278
+ selectionValue: formattedQuery[key]
279
+ };
280
+ }
281
+ }
282
+ _this._cacheCatalog(serviceGroup, serviceHostMap, selectionMeta);
183
283
  _this.updateCredentialsConfig();
184
284
  catalog.status[serviceGroup].collecting = false;
185
285
  }).catch(function (error) {
@@ -256,9 +356,9 @@ var Services = _webexPlugin.default.extend({
256
356
 
257
357
  // Destructure the client authorization details.
258
358
  /* eslint-disable camelcase */
259
- var _this$webex$credentia = this.webex.credentials.config,
260
- client_id = _this$webex$credentia.client_id,
261
- client_secret = _this$webex$credentia.client_secret;
359
+ var _this$webex$credentia2 = this.webex.credentials.config,
360
+ client_id = _this$webex$credentia2.client_id,
361
+ client_secret = _this$webex$credentia2.client_secret;
262
362
 
263
363
  // Validate that client authentication details exist.
264
364
  if (!client_id || !client_secret) {
@@ -449,15 +549,18 @@ var Services = _webexPlugin.default.extend({
449
549
 
450
550
  // try to fetch client region info first
451
551
  return this.fetchClientRegionInfo().then(function (clientRegionInfo) {
552
+ var _this6$webex$config$s;
452
553
  if (clientRegionInfo) {
453
554
  countryCode = clientRegionInfo.countryCode;
454
555
  timezone = clientRegionInfo.timezone;
455
556
  }
456
557
 
457
- // Send the user activation request to the **License** service.
558
+ // Send the user activation request.
559
+ // Use user-onboarding service if configured, otherwise use license service.
560
+ var useUserOnboarding = (_this6$webex$config$s = _this6.webex.config.services) === null || _this6$webex$config$s === void 0 ? void 0 : _this6$webex$config$s.useUserOnboardingServiceForActivations;
458
561
  return _this6.request({
459
- service: 'license',
460
- resource: 'users/activations',
562
+ service: useUserOnboarding ? 'user-onboarding' : 'license',
563
+ resource: useUserOnboarding ? 'api/v1/users/activations' : 'users/activations',
461
564
  method: 'POST',
462
565
  headers: {
463
566
  accept: 'application/json',
@@ -491,7 +594,7 @@ var Services = _webexPlugin.default.extend({
491
594
  */
492
595
  updateCatalog: function updateCatalog(serviceGroup, hostMap) {
493
596
  var catalog = this._getCatalog();
494
- var serviceHostMap = this._formatReceivedHostmap(hostMap);
597
+ var serviceHostMap = this._formatReceivedHostmap(hostMap || {});
495
598
  return catalog.updateServiceGroups(serviceGroup, serviceHostMap === null || serviceHostMap === void 0 ? void 0 : serviceHostMap.services, serviceHostMap === null || serviceHostMap === void 0 ? void 0 : serviceHostMap.timestamp);
496
599
  },
497
600
  /**
@@ -568,7 +671,6 @@ var Services = _webexPlugin.default.extend({
568
671
  idbroker: {
569
672
  url: idbrokerUrl.replace(trailingSlashes, '') // remove trailing slash
570
673
  },
571
-
572
674
  identity: {
573
675
  url: identityUrl.replace(trailingSlashes, '') // remove trailing slash
574
676
  }
@@ -711,16 +813,16 @@ var Services = _webexPlugin.default.extend({
711
813
  * catalog endpoint.
712
814
  * @returns {Array<Service>}
713
815
  */
714
- _formatReceivedHostmap: function _formatReceivedHostmap(_ref10) {
816
+ _formatReceivedHostmap: function _formatReceivedHostmap(_ref0) {
715
817
  var _this8 = this;
716
- var services = _ref10.services,
717
- activeServices = _ref10.activeServices,
718
- timestamp = _ref10.timestamp,
719
- orgId = _ref10.orgId,
720
- format = _ref10.format;
818
+ var services = _ref0.services,
819
+ activeServices = _ref0.activeServices,
820
+ timestamp = _ref0.timestamp,
821
+ orgId = _ref0.orgId,
822
+ format = _ref0.format;
721
823
  var formattedHostmap = {
722
824
  activeServices: activeServices,
723
- services: services.map(function (service) {
825
+ services: services === null || services === void 0 ? void 0 : services.map(function (service) {
724
826
  return _this8._formatHostMapEntry(service);
725
827
  }),
726
828
  timestamp: timestamp,
@@ -761,9 +863,9 @@ var Services = _webexPlugin.default.extend({
761
863
  * @returns {String} url of the service
762
864
  */
763
865
  getServiceUrlFromClusterId: function getServiceUrlFromClusterId() {
764
- var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
765
- _ref11$cluster = _ref11.cluster,
766
- cluster = _ref11$cluster === void 0 ? 'us' : _ref11$cluster;
866
+ var _ref1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
867
+ _ref1$cluster = _ref1.cluster,
868
+ cluster = _ref1$cluster === void 0 ? 'us' : _ref1$cluster;
767
869
  var clusterId = cluster === 'us' ? DEFAULT_CLUSTER_IDENTIFIER : cluster;
768
870
 
769
871
  // Determine if cluster has service name (non-US clusters from hydra do not)
@@ -771,10 +873,10 @@ var Services = _webexPlugin.default.extend({
771
873
  // Add Service to cluster identifier
772
874
  clusterId = "".concat(cluster, ":").concat(CLUSTER_SERVICE);
773
875
  }
774
- var _ref12 = this.getServiceFromClusterId({
876
+ var _ref10 = this.getServiceFromClusterId({
775
877
  clusterId: clusterId
776
878
  }) || {},
777
- url = _ref12.url;
879
+ url = _ref10.url;
778
880
  if (!url) {
779
881
  throw Error("Could not find service for cluster [".concat(cluster, "]"));
780
882
  }
@@ -832,6 +934,213 @@ var Services = _webexPlugin.default.extend({
832
934
  }
833
935
  return url.replace(data.defaultUrl, data.priorityUrl);
834
936
  },
937
+ /**
938
+ * @private
939
+ * Cache the catalog in the bounded storage.
940
+ * @param {ServiceGroup} serviceGroup - preauth, signin, postauth
941
+ * @param {ServiceHostmap} hostMap - The hostmap to cache
942
+ * @param {object} [meta] - Optional selection metadata for cache discrimination
943
+ * @returns {Promise<void>}
944
+ */
945
+ _cacheCatalog: function _cacheCatalog(serviceGroup, hostMap, meta) {
946
+ var _this9 = this;
947
+ return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
948
+ 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;
949
+ return _regenerator.default.wrap(function (_context) {
950
+ while (1) switch (_context.prev = _context.next) {
951
+ case 0:
952
+ current = {};
953
+ _context.prev = 1;
954
+ 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) {
955
+ _context.next = 2;
956
+ break;
957
+ }
958
+ _this9.logger.info("services: skipping cache write for ".concat(serviceGroup, " as per the config"));
959
+ return _context.abrupt("return");
960
+ case 2:
961
+ try {
962
+ _ls = _this9._getLocalStorageSafe();
963
+ cachedJson = _ls ? _ls.getItem(CATALOG_CACHE_KEY_V2) : null;
964
+ current = cachedJson ? JSON.parse(cachedJson) : {};
965
+ } catch (_unused2) {
966
+ current = {};
967
+ }
968
+ try {
969
+ credentials = _this9.webex.credentials;
970
+ orgId = credentials.getOrgId();
971
+ } catch (_unused3) {
972
+ orgId = current.orgId;
973
+ }
974
+
975
+ // Capture environment fingerprint to invalidate cache across env changes
976
+ _current = current, env = _current.env;
977
+ 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);
978
+ 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;
979
+ env = {
980
+ fedramp: fedramp,
981
+ u2cDiscoveryUrl: u2cDiscoveryUrl
982
+ };
983
+ updated = _objectSpread(_objectSpread({}, current), {}, (0, _defineProperty2.default)((0, _defineProperty2.default)({
984
+ orgId: orgId || current.orgId,
985
+ env: env || current.env
986
+ }, serviceGroup, meta ? {
987
+ hostMap: hostMap,
988
+ meta: meta
989
+ } : hostMap), "cachedAt", (0, _now.default)()));
990
+ ls = _this9._getLocalStorageSafe();
991
+ if (ls) {
992
+ ls.setItem(CATALOG_CACHE_KEY_V2, (0, _stringify.default)(updated));
993
+ }
994
+ _context.next = 4;
995
+ break;
996
+ case 3:
997
+ _context.prev = 3;
998
+ _t = _context["catch"](1);
999
+ _this9.logger.warn('services: error caching catalog', _t);
1000
+ case 4:
1001
+ case "end":
1002
+ return _context.stop();
1003
+ }
1004
+ }, _callee, null, [[1, 3]]);
1005
+ }))();
1006
+ },
1007
+ /**
1008
+ * @private
1009
+ * Load the catalog from cache and hydrate the in-memory ServiceCatalog.
1010
+ * @returns {Promise<boolean>} true if cache was loaded, false otherwise
1011
+ */
1012
+ _loadCatalogFromCache: function _loadCatalogFromCache() {
1013
+ var _this0 = this;
1014
+ return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
1015
+ 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;
1016
+ return _regenerator.default.wrap(function (_context2) {
1017
+ while (1) switch (_context2.prev = _context2.next) {
1018
+ case 0:
1019
+ _context2.prev = 0;
1020
+ 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) {
1021
+ _context2.next = 1;
1022
+ break;
1023
+ }
1024
+ _this0.logger.info('services: skipping cache warm-up as per the cache config');
1025
+ return _context2.abrupt("return", false);
1026
+ case 1:
1027
+ ls = _this0._getLocalStorageSafe();
1028
+ if (ls) {
1029
+ _context2.next = 2;
1030
+ break;
1031
+ }
1032
+ _this0.logger.info('services: skipping cache warm-up as no localStorage is available');
1033
+ return _context2.abrupt("return", false);
1034
+ case 2:
1035
+ cachedJson = ls.getItem(CATALOG_CACHE_KEY_V2);
1036
+ cached = cachedJson ? JSON.parse(cachedJson) : undefined;
1037
+ if (cached) {
1038
+ _context2.next = 3;
1039
+ break;
1040
+ }
1041
+ return _context2.abrupt("return", false);
1042
+ case 3:
1043
+ // TTL enforcement
1044
+ cachedAt = Number(cached.cachedAt) || 0;
1045
+ if (!(!cachedAt || (0, _now.default)() - cachedAt > CATALOG_TTL_MS)) {
1046
+ _context2.next = 4;
1047
+ break;
1048
+ }
1049
+ _this0.clearCatalogCache();
1050
+ return _context2.abrupt("return", false);
1051
+ case 4:
1052
+ _context2.prev = 4;
1053
+ if (!((_this0$webex$credenti = _this0.webex.credentials) !== null && _this0$webex$credenti !== void 0 && _this0$webex$credenti.canAuthorize)) {
1054
+ _context2.next = 5;
1055
+ break;
1056
+ }
1057
+ credentials = _this0.webex.credentials;
1058
+ currentOrgId = credentials.getOrgId();
1059
+ if (!(cached.orgId && cached.orgId !== currentOrgId)) {
1060
+ _context2.next = 5;
1061
+ break;
1062
+ }
1063
+ return _context2.abrupt("return", false);
1064
+ case 5:
1065
+ _context2.next = 7;
1066
+ break;
1067
+ case 6:
1068
+ _context2.prev = 6;
1069
+ _t2 = _context2["catch"](4);
1070
+ _this0.logger.warn('services: error checking orgId', _t2);
1071
+ case 7:
1072
+ // Ensure cached environment matches current environment
1073
+ fedramp = !!((_this0$webex$config2 = _this0.webex.config) !== null && _this0$webex$config2 !== void 0 && _this0$webex$config2.fedramp);
1074
+ 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;
1075
+ currentEnv = {
1076
+ fedramp: fedramp,
1077
+ u2cDiscoveryUrl: u2cDiscoveryUrl
1078
+ };
1079
+ if (!cached.env) {
1080
+ _context2.next = 8;
1081
+ break;
1082
+ }
1083
+ sameEnv = cached.env.fedramp === currentEnv.fedramp && cached.env.u2cDiscoveryUrl === currentEnv.u2cDiscoveryUrl;
1084
+ if (sameEnv) {
1085
+ _context2.next = 8;
1086
+ break;
1087
+ }
1088
+ return _context2.abrupt("return", false);
1089
+ case 8:
1090
+ catalog = _this0._getCatalog();
1091
+ groups = ['preauth', 'signin', 'postauth'];
1092
+ groups.forEach(function (serviceGroup) {
1093
+ var cachedGroup = cached[serviceGroup];
1094
+ if (!cachedGroup) {
1095
+ return;
1096
+ }
1097
+
1098
+ // Support legacy (hostMap) and new ({hostMap, meta}) shapes
1099
+ var hostMap = cachedGroup && cachedGroup.hostMap ? cachedGroup.hostMap : cachedGroup;
1100
+ var meta = cachedGroup === null || cachedGroup === void 0 ? void 0 : cachedGroup.meta;
1101
+ if (serviceGroup === 'preauth' && meta) {
1102
+ // For proximity-based selection, always fetch fresh to respect IP/region changes
1103
+ if (meta.selectionType === 'mode') {
1104
+ return;
1105
+ }
1106
+ var intended = _this0.getIntendedPreauthSelection(currentOrgId);
1107
+ var matches = intended && intended.selectionType === meta.selectionType && intended.selectionValue === meta.selectionValue;
1108
+ if (!matches) {
1109
+ return;
1110
+ }
1111
+ }
1112
+ if (hostMap) {
1113
+ catalog.updateServiceGroups(serviceGroup, hostMap === null || hostMap === void 0 ? void 0 : hostMap.services, hostMap === null || hostMap === void 0 ? void 0 : hostMap.timestamp);
1114
+ }
1115
+ });
1116
+ _this0.updateCredentialsConfig();
1117
+ return _context2.abrupt("return", true);
1118
+ case 9:
1119
+ _context2.prev = 9;
1120
+ _t3 = _context2["catch"](0);
1121
+ return _context2.abrupt("return", false);
1122
+ case 10:
1123
+ case "end":
1124
+ return _context2.stop();
1125
+ }
1126
+ }, _callee2, null, [[0, 9], [4, 6]]);
1127
+ }))();
1128
+ },
1129
+ /**
1130
+ * Clear the catalog cache from the bounded storage (v2).
1131
+ * @returns {Promise<void>}
1132
+ */
1133
+ clearCatalogCache: function clearCatalogCache() {
1134
+ try {
1135
+ var ls = this._getLocalStorageSafe();
1136
+ if (ls) {
1137
+ ls.removeItem(CATALOG_CACHE_KEY_V2);
1138
+ }
1139
+ } catch (e) {
1140
+ this.logger.warn('services: error clearing catalog cache', e);
1141
+ }
1142
+ return _promise.default.resolve();
1143
+ },
835
1144
  /**
836
1145
  * @private
837
1146
  * Simplified method wrapper for sending a request to get
@@ -846,12 +1155,12 @@ var Services = _webexPlugin.default.extend({
846
1155
  * @returns {Promise<object>}
847
1156
  */
848
1157
  _fetchNewServiceHostmap: function _fetchNewServiceHostmap() {
849
- var _this9 = this;
850
- var _ref13 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
851
- from = _ref13.from,
852
- query = _ref13.query,
853
- token = _ref13.token,
854
- forceRefresh = _ref13.forceRefresh;
1158
+ var _this1 = this;
1159
+ var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1160
+ from = _ref11.from,
1161
+ query = _ref11.query,
1162
+ token = _ref11.token,
1163
+ forceRefresh = _ref11.forceRefresh;
855
1164
  var service = 'u2c';
856
1165
  var resource = from ? "/".concat(from, "/catalog") : '/catalog';
857
1166
  var qs = _objectSpread(_objectSpread({}, query || {}), {}, {
@@ -873,10 +1182,10 @@ var Services = _webexPlugin.default.extend({
873
1182
  };
874
1183
  }
875
1184
  return this.webex.internal.newMetrics.callDiagnosticLatencies.measureLatency(function () {
876
- return _this9.request(requestObject);
877
- }, 'internal.get.u2c.time').then(function (_ref14) {
878
- var body = _ref14.body;
879
- return _this9._formatReceivedHostmap(body);
1185
+ return _this1.request(requestObject);
1186
+ }, 'internal.get.u2c.time').then(function (_ref12) {
1187
+ var body = _ref12.body;
1188
+ return _this1._formatReceivedHostmap(body || {});
880
1189
  });
881
1190
  },
882
1191
  /**
@@ -1006,28 +1315,47 @@ var Services = _webexPlugin.default.extend({
1006
1315
 
1007
1316
  // wait for webex instance to be ready before attempting
1008
1317
  // to update the service catalogs
1009
- this.listenToOnce(this.webex, 'ready', function () {
1010
- var supertoken = _this12.webex.credentials.supertoken;
1011
- // Validate if the supertoken exists.
1012
- if (supertoken && supertoken.access_token) {
1013
- _this12.initServiceCatalogs().then(function () {
1014
- catalog.isReady = true;
1015
- }).catch(function (error) {
1016
- _this12.initFailed = true;
1017
- _this12.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
1018
- });
1019
- } else {
1020
- var email = _this12.webex.config.email;
1021
- _this12.collectPreauthCatalog(email ? {
1022
- email: email
1023
- } : undefined).catch(function (error) {
1024
- _this12.initFailed = true;
1025
- _this12.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
1026
- });
1027
- }
1028
- });
1318
+ this.listenToOnce(this.webex, 'ready', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
1319
+ var warmed, supertoken, email;
1320
+ return _regenerator.default.wrap(function (_context3) {
1321
+ while (1) switch (_context3.prev = _context3.next) {
1322
+ case 0:
1323
+ _context3.next = 1;
1324
+ return _this12._loadCatalogFromCache();
1325
+ case 1:
1326
+ warmed = _context3.sent;
1327
+ if (!warmed) {
1328
+ _context3.next = 2;
1329
+ break;
1330
+ }
1331
+ catalog.isReady = true;
1332
+ return _context3.abrupt("return");
1333
+ case 2:
1334
+ supertoken = _this12.webex.credentials.supertoken; // Validate if the supertoken exists.
1335
+ if (supertoken && supertoken.access_token) {
1336
+ _this12.initServiceCatalogs().then(function () {
1337
+ catalog.isReady = true;
1338
+ }).catch(function (error) {
1339
+ _this12.initFailed = true;
1340
+ _this12.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
1341
+ });
1342
+ } else {
1343
+ email = _this12.webex.config.email;
1344
+ _this12.collectPreauthCatalog(email ? {
1345
+ email: email
1346
+ } : undefined).catch(function (error) {
1347
+ _this12.initFailed = true;
1348
+ _this12.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
1349
+ });
1350
+ }
1351
+ case 3:
1352
+ case "end":
1353
+ return _context3.stop();
1354
+ }
1355
+ }, _callee3);
1356
+ })));
1029
1357
  },
1030
- version: "3.10.0"
1358
+ version: "0.0.0"
1031
1359
  });
1032
1360
  /* eslint-enable no-underscore-dangle */
1033
1361
  var _default = exports.default = Services;