@webex/internal-plugin-device 3.6.0 → 3.7.0-next.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/device.js +113 -52
- package/dist/device.js.map +1 -1
- package/dist/ipNetworkDetector.js +48 -16
- package/dist/ipNetworkDetector.js.map +1 -1
- package/package.json +10 -10
- package/src/device.js +71 -6
- package/src/ipNetworkDetector.ts +31 -3
- package/test/unit/spec/device.js +96 -0
- package/test/unit/spec/ipNetworkDetector.js +84 -1
package/dist/device.js
CHANGED
|
@@ -20,12 +20,13 @@ var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime-
|
|
|
20
20
|
var _common = require("@webex/common");
|
|
21
21
|
var _webexCore = require("@webex/webex-core");
|
|
22
22
|
var _commonTimers = require("@webex/common-timers");
|
|
23
|
+
var _lodash = require("lodash");
|
|
23
24
|
var _metrics = _interopRequireDefault(require("./metrics"));
|
|
24
25
|
var _constants = require("./constants");
|
|
25
26
|
var _featuresModel = _interopRequireDefault(require("./features/features-model"));
|
|
26
27
|
var _ipNetworkDetector = _interopRequireDefault(require("./ipNetworkDetector"));
|
|
27
28
|
var _types = require("./types");
|
|
28
|
-
var _dec, _dec2, _dec3, _dec4, _dec5, _obj; // Internal Dependencies
|
|
29
|
+
var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _obj; // Internal Dependencies
|
|
29
30
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor2(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
30
31
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor2(t, r)); }); } return e; }
|
|
31
32
|
/**
|
|
@@ -36,7 +37,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
36
37
|
function decider() {
|
|
37
38
|
return !this.config.ephemeral;
|
|
38
39
|
}
|
|
39
|
-
var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)('@'), _dec2 = (0, _webexCore.waitForValue)('@'), _dec3 = (0, _webexCore.waitForValue)('@'), _dec4 = (0, _common.deprecated)('device#markUrlFailedAndGetNew(): Use services#markFailedUrl()'),
|
|
40
|
+
var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)('@'), _dec2 = (0, _webexCore.waitForValue)('@'), _dec3 = (0, _webexCore.waitForValue)('@'), _dec4 = (0, _webexCore.waitForValue)('@'), _dec5 = (0, _common.deprecated)('device#markUrlFailedAndGetNew(): Use services#markFailedUrl()'), _dec6 = (0, _webexCore.persist)('@', decider), (_obj = {
|
|
40
41
|
// Ampersand property members.
|
|
41
42
|
|
|
42
43
|
namespace: 'Device',
|
|
@@ -396,8 +397,68 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
396
397
|
});
|
|
397
398
|
});
|
|
398
399
|
},
|
|
399
|
-
|
|
400
|
+
/**
|
|
401
|
+
* Fetches the web devices and deletes the third of them which are not recent devices in use
|
|
402
|
+
* @returns {Promise<void, Error>}
|
|
403
|
+
*/
|
|
404
|
+
deleteDevices: function deleteDevices() {
|
|
400
405
|
var _this2 = this;
|
|
406
|
+
// Fetch devices with a GET request
|
|
407
|
+
return this.request({
|
|
408
|
+
method: 'GET',
|
|
409
|
+
service: 'wdm',
|
|
410
|
+
resource: 'devices'
|
|
411
|
+
}).then(function (response) {
|
|
412
|
+
var devices = response.body.devices;
|
|
413
|
+
var _this2$_getBody = _this2._getBody(),
|
|
414
|
+
deviceType = _this2$_getBody.deviceType;
|
|
415
|
+
|
|
416
|
+
// Filter devices of type deviceType
|
|
417
|
+
var webDevices = devices.filter(function (item) {
|
|
418
|
+
return item.deviceType === deviceType;
|
|
419
|
+
});
|
|
420
|
+
var sortedDevices = (0, _lodash.orderBy)(webDevices, [function (item) {
|
|
421
|
+
return new Date(item.modificationTime);
|
|
422
|
+
}]);
|
|
423
|
+
|
|
424
|
+
// If there are more than two devices, delete the last third
|
|
425
|
+
if (sortedDevices.length > 2) {
|
|
426
|
+
var totalItems = sortedDevices.length;
|
|
427
|
+
var countToDelete = Math.ceil(totalItems / 3);
|
|
428
|
+
var urlsToDelete = sortedDevices.slice(0, countToDelete).map(function (item) {
|
|
429
|
+
return item.url;
|
|
430
|
+
});
|
|
431
|
+
return _promise.default.race(urlsToDelete.map(function (url) {
|
|
432
|
+
return _this2.request({
|
|
433
|
+
uri: url,
|
|
434
|
+
method: 'DELETE'
|
|
435
|
+
});
|
|
436
|
+
}));
|
|
437
|
+
}
|
|
438
|
+
return _promise.default.resolve();
|
|
439
|
+
}).catch(function (error) {
|
|
440
|
+
_this2.logger.error('Failed to retrieve devices:', error);
|
|
441
|
+
return _promise.default.reject(error);
|
|
442
|
+
});
|
|
443
|
+
},
|
|
444
|
+
register: function register() {
|
|
445
|
+
var _this3 = this;
|
|
446
|
+
var deviceRegistrationOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
447
|
+
return this._registerInternal(deviceRegistrationOptions).catch(function (error) {
|
|
448
|
+
var _error$body;
|
|
449
|
+
if ((error === null || error === void 0 ? void 0 : (_error$body = error.body) === null || _error$body === void 0 ? void 0 : _error$body.message) === 'User has excessive device registrations') {
|
|
450
|
+
return _this3.deleteDevices().then(function () {
|
|
451
|
+
return _this3._registerInternal(deviceRegistrationOptions);
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
throw error;
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
_getBody: function _getBody() {
|
|
458
|
+
return _objectSpread(_objectSpread({}, this.config.defaults.body ? this.config.defaults.body : {}), this.config.body ? this.config.body : {});
|
|
459
|
+
},
|
|
460
|
+
_registerInternal: function _registerInternal() {
|
|
461
|
+
var _this4 = this;
|
|
401
462
|
var deviceRegistrationOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
402
463
|
this.logger.info('device: registering');
|
|
403
464
|
this.webex.internal.newMetrics.callDiagnosticMetrics.setDeviceInfo(this);
|
|
@@ -405,51 +466,51 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
405
466
|
// Validate that the device can be registered.
|
|
406
467
|
return this.canRegister().then(function () {
|
|
407
468
|
// Validate if the device is already registered and refresh instead.
|
|
408
|
-
if (
|
|
409
|
-
|
|
410
|
-
return
|
|
469
|
+
if (_this4.registered) {
|
|
470
|
+
_this4.logger.info('device: device already registered, refreshing');
|
|
471
|
+
return _this4.refresh(deviceRegistrationOptions);
|
|
411
472
|
}
|
|
412
473
|
|
|
413
474
|
// Merge body configurations, overriding defaults.
|
|
414
|
-
var body =
|
|
475
|
+
var body = _this4._getBody();
|
|
415
476
|
|
|
416
477
|
// Merge header configurations, overriding defaults.
|
|
417
|
-
var headers = _objectSpread(_objectSpread({},
|
|
478
|
+
var headers = _objectSpread(_objectSpread({}, _this4.config.defaults.headers ? _this4.config.defaults.headers : {}), _this4.config.headers ? _this4.config.headers : {});
|
|
418
479
|
|
|
419
480
|
// Append a ttl value if the device is marked as ephemeral
|
|
420
|
-
if (
|
|
421
|
-
body.ttl =
|
|
481
|
+
if (_this4.config.ephemeral) {
|
|
482
|
+
body.ttl = _this4.config.ephemeralDeviceTTL;
|
|
422
483
|
}
|
|
423
|
-
|
|
484
|
+
_this4.webex.internal.newMetrics.submitInternalEvent({
|
|
424
485
|
name: 'internal.register.device.request'
|
|
425
486
|
});
|
|
426
487
|
var _deviceRegistrationOp2 = deviceRegistrationOptions.includeDetails,
|
|
427
488
|
includeDetails = _deviceRegistrationOp2 === void 0 ? _types.CatalogDetails.all : _deviceRegistrationOp2;
|
|
428
489
|
|
|
429
490
|
// This will be replaced by a `create()` method.
|
|
430
|
-
return
|
|
491
|
+
return _this4.request({
|
|
431
492
|
method: 'POST',
|
|
432
493
|
service: 'wdm',
|
|
433
494
|
resource: 'devices',
|
|
434
495
|
body: body,
|
|
435
496
|
headers: headers,
|
|
436
497
|
qs: {
|
|
437
|
-
includeUpstreamServices: "".concat(includeDetails).concat(
|
|
498
|
+
includeUpstreamServices: "".concat(includeDetails).concat(_this4.config.energyForecast && _this4.energyForecastConfig ? ',energyforecast' : '')
|
|
438
499
|
}
|
|
439
500
|
}).catch(function (error) {
|
|
440
|
-
|
|
501
|
+
_this4.webex.internal.newMetrics.submitInternalEvent({
|
|
441
502
|
name: 'internal.register.device.response'
|
|
442
503
|
});
|
|
443
504
|
throw error;
|
|
444
505
|
}).then(function (response) {
|
|
445
506
|
// Do not add any processing of response above this as that will affect timestamp
|
|
446
|
-
|
|
507
|
+
_this4.webex.internal.newMetrics.submitInternalEvent({
|
|
447
508
|
name: 'internal.register.device.response'
|
|
448
509
|
});
|
|
449
|
-
|
|
450
|
-
return
|
|
510
|
+
_this4.webex.internal.metrics.submitClientMetrics(_metrics.default.JS_SDK_WDM_REGISTRATION_SUCCESSFUL);
|
|
511
|
+
return _this4.processRegistrationSuccess(response);
|
|
451
512
|
}).catch(function (error) {
|
|
452
|
-
|
|
513
|
+
_this4.webex.internal.metrics.submitClientMetrics(_metrics.default.JS_SDK_WDM_REGISTRATION_FAILED, {
|
|
453
514
|
fields: {
|
|
454
515
|
error: error
|
|
455
516
|
}
|
|
@@ -459,7 +520,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
459
520
|
});
|
|
460
521
|
},
|
|
461
522
|
unregister: function unregister() {
|
|
462
|
-
var
|
|
523
|
+
var _this5 = this;
|
|
463
524
|
this.logger.info('device: unregistering');
|
|
464
525
|
if (!this.registered) {
|
|
465
526
|
this.logger.warn('device: not registered');
|
|
@@ -469,7 +530,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
469
530
|
uri: this.url,
|
|
470
531
|
method: 'DELETE'
|
|
471
532
|
}).then(function () {
|
|
472
|
-
return
|
|
533
|
+
return _this5.clear();
|
|
473
534
|
});
|
|
474
535
|
},
|
|
475
536
|
/* eslint-enable require-jsdoc */
|
|
@@ -501,7 +562,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
501
562
|
* @returns {Promise<void, Error>}
|
|
502
563
|
*/
|
|
503
564
|
checkNetworkReachability: function checkNetworkReachability() {
|
|
504
|
-
var
|
|
565
|
+
var _this6 = this;
|
|
505
566
|
this.logger.info('device: checking network reachability');
|
|
506
567
|
|
|
507
568
|
// Validate if the device has been checked and reset the logout timer.
|
|
@@ -529,13 +590,13 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
529
590
|
method: 'GET',
|
|
530
591
|
uri: this.intranetInactivityCheckUrl
|
|
531
592
|
}).then(function () {
|
|
532
|
-
|
|
533
|
-
return _promise.default.resolve(
|
|
593
|
+
_this6.isInNetwork = true;
|
|
594
|
+
return _promise.default.resolve(_this6.resetLogoutTimer());
|
|
534
595
|
}).catch(function () {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
return _promise.default.resolve(
|
|
596
|
+
_this6.logger.info('device: did not reach ping endpoint');
|
|
597
|
+
_this6.logger.info('device: triggering off-network timer');
|
|
598
|
+
_this6.isInNetwork = false;
|
|
599
|
+
return _promise.default.resolve(_this6.resetLogoutTimer());
|
|
539
600
|
});
|
|
540
601
|
},
|
|
541
602
|
/**
|
|
@@ -560,7 +621,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
560
621
|
* @returns {Promise<string, Error>} - The priority-mapped web socket url.
|
|
561
622
|
*/
|
|
562
623
|
getWebSocketUrl: function getWebSocketUrl() {
|
|
563
|
-
var
|
|
624
|
+
var _this7 = this;
|
|
564
625
|
var wait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
565
626
|
this.logger.info('device: getting the current websocket url');
|
|
566
627
|
|
|
@@ -570,9 +631,9 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
570
631
|
// Validate if the method should wait for registration.
|
|
571
632
|
if (wait) {
|
|
572
633
|
return this.waitForRegistration().then(function () {
|
|
573
|
-
return services.convertUrlToPriorityHostUrl(
|
|
634
|
+
return services.convertUrlToPriorityHostUrl(_this7.webSocketUrl);
|
|
574
635
|
}).catch(function (error) {
|
|
575
|
-
|
|
636
|
+
_this7.logger.warn(error.message);
|
|
576
637
|
return _promise.default.reject(new Error('device: failed to get the current websocket url'));
|
|
577
638
|
});
|
|
578
639
|
}
|
|
@@ -598,7 +659,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
598
659
|
* @returns {void}
|
|
599
660
|
*/
|
|
600
661
|
processRegistrationSuccess: function processRegistrationSuccess(response) {
|
|
601
|
-
var
|
|
662
|
+
var _this8 = this;
|
|
602
663
|
this.logger.info('device: received registration payload');
|
|
603
664
|
|
|
604
665
|
// Clone the response body for service cleaning.
|
|
@@ -633,7 +694,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
633
694
|
this.logger.info('device: enqueuing device refresh');
|
|
634
695
|
var delay = (this.config.ephemeralDeviceTTL / 2 + 60) * 1000;
|
|
635
696
|
this.refreshTimer = (0, _commonTimers.safeSetTimeout)(function () {
|
|
636
|
-
return
|
|
697
|
+
return _this8.refresh();
|
|
637
698
|
}, delay);
|
|
638
699
|
}
|
|
639
700
|
|
|
@@ -675,7 +736,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
675
736
|
* @returns {void}
|
|
676
737
|
*/
|
|
677
738
|
setLogoutTimer: function setLogoutTimer(duration) {
|
|
678
|
-
var
|
|
739
|
+
var _this9 = this;
|
|
679
740
|
this.logger.info('device: setting logout timer');
|
|
680
741
|
if (!duration || duration <= 0) {
|
|
681
742
|
return;
|
|
@@ -683,12 +744,12 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
683
744
|
|
|
684
745
|
// Setup user activity date event listener.
|
|
685
746
|
this.on('change:lastUserActivityDate', function () {
|
|
686
|
-
|
|
747
|
+
_this9.resetLogoutTimer();
|
|
687
748
|
});
|
|
688
749
|
|
|
689
750
|
// Initialize a new timer.
|
|
690
751
|
this.logoutTimer = (0, _commonTimers.safeSetTimeout)(function () {
|
|
691
|
-
|
|
752
|
+
_this9.webex.logout();
|
|
692
753
|
}, duration * 1000);
|
|
693
754
|
},
|
|
694
755
|
/**
|
|
@@ -698,17 +759,17 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
698
759
|
* @returns {Promise<void, Error>}
|
|
699
760
|
*/
|
|
700
761
|
waitForRegistration: function waitForRegistration() {
|
|
701
|
-
var
|
|
762
|
+
var _this10 = this;
|
|
702
763
|
var timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
703
764
|
this.logger.info('device: waiting for registration');
|
|
704
765
|
return new _promise.default(function (resolve, reject) {
|
|
705
|
-
if (
|
|
766
|
+
if (_this10.registered) {
|
|
706
767
|
resolve();
|
|
707
768
|
}
|
|
708
769
|
var timeoutTimer = (0, _commonTimers.safeSetTimeout)(function () {
|
|
709
770
|
return reject(new Error('device: timeout occured while waiting for registration'));
|
|
710
771
|
}, timeout * 1000);
|
|
711
|
-
|
|
772
|
+
_this10.once(_constants.DEVICE_EVENT_REGISTRATION_SUCCESS, function () {
|
|
712
773
|
clearTimeout(timeoutTimer);
|
|
713
774
|
resolve();
|
|
714
775
|
});
|
|
@@ -718,7 +779,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
718
779
|
return _promise.default.resolve(this.webex.internal.services.markFailedUrl(url));
|
|
719
780
|
},
|
|
720
781
|
initialize: function initialize() {
|
|
721
|
-
var
|
|
782
|
+
var _this11 = this;
|
|
722
783
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
723
784
|
args[_key2] = arguments[_key2];
|
|
724
785
|
}
|
|
@@ -727,45 +788,45 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
727
788
|
|
|
728
789
|
// Initialize feature events and listeners.
|
|
729
790
|
_constants.FEATURE_COLLECTION_NAMES.forEach(function (collectionName) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
791
|
+
_this11.features.on("change:".concat(collectionName), function (model, value, options) {
|
|
792
|
+
_this11.trigger('change', _this11, options);
|
|
793
|
+
_this11.trigger('change:features', _this11, _this11.features, options);
|
|
733
794
|
});
|
|
734
795
|
});
|
|
735
796
|
|
|
736
797
|
// Initialize network reachability checking event for url change.
|
|
737
798
|
this.on('change:intranetInactivityCheckUrl', function () {
|
|
738
|
-
|
|
799
|
+
_this11.checkNetworkReachability();
|
|
739
800
|
});
|
|
740
801
|
|
|
741
802
|
// Initialize network reachability checking event for duration change.
|
|
742
803
|
this.on('change:intranetInactivityDuration', function () {
|
|
743
|
-
|
|
804
|
+
_this11.checkNetworkReachability();
|
|
744
805
|
});
|
|
745
806
|
|
|
746
807
|
// Initialize network reachability checking event for duration change.
|
|
747
808
|
this.on('change:inNetworkInactivityDuration', function () {
|
|
748
|
-
|
|
809
|
+
_this11.checkNetworkReachability();
|
|
749
810
|
});
|
|
750
811
|
|
|
751
812
|
// Initialize listener for activity checking.
|
|
752
813
|
this.listenTo(this.webex, 'user-activity', function () {
|
|
753
|
-
|
|
814
|
+
_this11.lastUserActivityDate = (0, _now.default)();
|
|
754
815
|
});
|
|
755
816
|
|
|
756
817
|
// Initialize listener for meeting started event.
|
|
757
818
|
this.listenTo(this.webex, 'meeting started', function () {
|
|
758
|
-
|
|
759
|
-
|
|
819
|
+
_this11.isInMeeting = true;
|
|
820
|
+
_this11.resetLogoutTimer();
|
|
760
821
|
});
|
|
761
822
|
|
|
762
823
|
// Initialize listener for meeting ended event.
|
|
763
824
|
this.listenTo(this.webex, 'meeting ended', function () {
|
|
764
|
-
|
|
765
|
-
|
|
825
|
+
_this11.isInMeeting = false;
|
|
826
|
+
_this11.resetLogoutTimer();
|
|
766
827
|
});
|
|
767
828
|
} /* eslint-enable require-jsdoc */,
|
|
768
|
-
version: "3.
|
|
769
|
-
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "refresh", [_common.oneFlight, _dec], (0, _getOwnPropertyDescriptor.default)(_obj, "refresh"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "register", [_common.oneFlight, _dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "register"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "
|
|
829
|
+
version: "3.7.0-next.2"
|
|
830
|
+
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "refresh", [_common.oneFlight, _dec], (0, _getOwnPropertyDescriptor.default)(_obj, "refresh"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "register", [_common.oneFlight, _dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "register"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "_registerInternal", [_common.oneFlight, _dec3], (0, _getOwnPropertyDescriptor.default)(_obj, "_registerInternal"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "unregister", [_common.oneFlight, _dec4], (0, _getOwnPropertyDescriptor.default)(_obj, "unregister"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "markUrlFailedAndGetNew", [_dec5], (0, _getOwnPropertyDescriptor.default)(_obj, "markUrlFailedAndGetNew"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initialize", [_dec6], (0, _getOwnPropertyDescriptor.default)(_obj, "initialize"), _obj)), _obj)));
|
|
770
831
|
var _default = exports.default = Device;
|
|
771
832
|
//# sourceMappingURL=device.js.map
|
package/dist/device.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_common","require","_webexCore","_commonTimers","_metrics","_interopRequireDefault","_constants","_featuresModel","_ipNetworkDetector","_types","_dec","_dec2","_dec3","_dec4","_dec5","_obj","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor2","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","decider","config","ephemeral","Device","WebexPlugin","extend","waitForValue","deprecated","persist","namespace","extraProperties","idAttribute","children","features","FeaturesModel","ipNetworkDetector","IpNetworkDetector","props","clientMessagingGiphy","customerCompanyName","customerLogoUrl","deviceType","helpUrl","intranetInactivityDuration","intranetInactivityCheckUrl","inNetworkInactivityDuration","ecmEnabledForAllUsers","ecmSupportedStorageProviders","modificationTime","navigationBarColor","partnerCompanyName","partnerLogoUrl","peopleInsightsEnabled","reportingSiteDesc","reportingSiteUrl","searchEncryptionKeyUrl","showSupportText","supportProviderCompanyName","supportProviderLogoUrl","url","userId","webFileShareControl","webSocketUrl","whiteboardFileShareControl","derived","registered","deps","fn","session","logoutTimer","lastUserActivityDate","isReachabilityChecked","energyForecastConfig","isInMeeting","isInNetwork","meetingStarted","webex","trigger","meetingEnded","setEnergyForecastConfig","undefined","refresh","_this","deviceRegistrationOptions","logger","info","canRegister","then","register","body","serialize","mediaCluster","etag","ttl","ephemeralDeviceTTL","headers","defaults","_deviceRegistrationOp","includeDetails","CatalogDetails","all","request","method","uri","qs","includeUpstreamServices","concat","energyForecast","response","processRegistrationSuccess","catch","reason","statusCode","clear","_promise","reject","_this2","internal","newMetrics","callDiagnosticMetrics","setDeviceInfo","submitInternalEvent","name","_deviceRegistrationOp2","service","resource","error","metrics","submitClientMetrics","METRICS","JS_SDK_WDM_REGISTRATION_SUCCESSFUL","JS_SDK_WDM_REGISTRATION_FAILED","fields","unregister","_this3","warn","resolve","services","waitForCatalog","canRegisterWaitDuration","get","Error","join","checkNetworkReachability","_this4","resetLogoutTimer","trackingid","_len","args","Array","_key","_apply","prototype","getWebSocketUrl","_this5","wait","waitForRegistration","convertUrlToPriorityHostUrl","message","wsUrl","_this6","serviceHostMap","_ref","user","reset","entitlement","set","delay","refreshTimer","safeSetTimeout","DEVICE_EVENT_REGISTRATION_SUCCESS","clearTimeout","off","unset","enableInactivityEnforcement","setLogoutTimer","duration","_this7","on","logout","_this8","timeout","timeoutTimer","once","markUrlFailedAndGetNew","markFailedUrl","initialize","_this9","_len2","_key2","FEATURE_COLLECTION_NAMES","collectionName","model","value","options","listenTo","_now","version","_applyDecoratedDescriptor2","oneFlight","_getOwnPropertyDescriptor","_default","exports"],"sources":["device.js"],"sourcesContent":["// Internal Dependencies\nimport {deprecated, oneFlight} from '@webex/common';\nimport {persist, waitForValue, WebexPlugin} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\n\nimport METRICS from './metrics';\nimport {FEATURE_COLLECTION_NAMES, DEVICE_EVENT_REGISTRATION_SUCCESS} from './constants';\nimport FeaturesModel from './features/features-model';\nimport IpNetworkDetector from './ipNetworkDetector';\nimport {CatalogDetails} from './types';\n\n/**\n * Determine if the plugin should be initialized based on cached storage.\n *\n * @returns {boolean} - If the device is ephemeral.\n */\nfunction decider() {\n return !this.config.ephemeral;\n}\n\nconst Device = WebexPlugin.extend({\n // Ampersand property members.\n\n namespace: 'Device',\n\n // Allow for extra properties to prevent the plugin from failing due to\n // **WDM** service DTO changes.\n extraProperties: 'allow',\n\n idAttribute: 'url',\n\n children: {\n /**\n * The class object that contains all of the feature collections.\n *\n * @type {FeaturesModel}\n */\n features: FeaturesModel,\n /**\n * Helper class for detecting what IP network version (ipv4, ipv6) we're on.\n *\n * @type {IpNetworkDetector}\n */\n ipNetworkDetector: IpNetworkDetector,\n },\n\n /**\n * A collection of device properties mostly assigned by the retrieved DTO from\n * the **WDM** service that are mapped against the ampersand properties.\n *\n * @type {Object}\n */\n props: {\n /**\n * This property determines whether or not giphy support is enabled.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n clientMessagingGiphy: 'string',\n\n /**\n * This property should store the company name.\n *\n * @type {string}\n */\n customerCompanyName: 'string',\n\n /**\n * This property should store the logo url.\n *\n * @type {string}\n */\n customerLogoUrl: 'string',\n\n /**\n * This property doesn't have any real values, but is sent during device\n * refresh to prevent the **wdm** service from falling back to an iOS device\n * type.\n *\n * @type {string}\n */\n deviceType: 'string',\n\n /**\n * This property should store the help url.\n *\n * @type {string}\n */\n helpUrl: 'string',\n\n /**\n * This property should store the intranet inactivity timer duration.\n *\n * @type {number}\n */\n intranetInactivityDuration: 'number',\n\n /**\n * This property stores the url required to validate if the device is able\n * to actively reach the intranet network.\n *\n * @type {string}\n */\n intranetInactivityCheckUrl: 'string',\n\n /**\n * This property stores the inactivity timer duration, and could possibly\n * deprecate the `intranetInactivityDuration` property.\n *\n * @type {number}\n */\n inNetworkInactivityDuration: 'number',\n\n /**\n * This property stores the ECM (external content management) enabled value\n * for the whole organization.\n *\n * @type {boolean}\n */\n ecmEnabledForAllUsers: ['boolean', false, false],\n\n /**\n * This property stores an array of ECM (external content management)\n * providers that are currently available.\n *\n * @returns {Array<string>}\n */\n ecmSupportedStorageProviders: ['array', false, () => []],\n\n /**\n * This property stores the modification time value retrieved from the\n * **WDM** endpoint formatted as ISO 8601.\n *\n * @type {string}\n */\n modificationTime: 'string',\n\n /**\n * This property stores the navigation bar color.\n *\n * @type {string}\n */\n navigationBarColor: 'string',\n\n /**\n * This property stores the partner company's name when available.\n *\n * @type {string}\n */\n partnerCompanyName: 'string',\n\n /**\n * This property stores the partner company's logo when available.\n *\n * @type {string}\n */\n partnerLogoUrl: 'string',\n\n /**\n * This property stores the availability of people data from the **WDM**\n * service.\n *\n * @type {boolean}\n */\n peopleInsightsEnabled: 'boolean',\n\n /**\n * This property stores the reporting site's description when available.\n *\n * @type {string}\n */\n reportingSiteDesc: 'string',\n\n /**\n * This property stores the reporting site's access url when available.\n *\n * @type {string}\n */\n reportingSiteUrl: 'string',\n\n /**\n * This property stores the encryption key url when available.\n *\n * @type {string}\n */\n searchEncryptionKeyUrl: 'string',\n\n /**\n * This property stores the availability of support-provided text from the\n * **WDM** service.\n *\n * @type {boolean}\n */\n showSupportText: 'boolean',\n\n /**\n * This property stores the support provider's company name when available.\n *\n * @type {string}\n */\n supportProviderCompanyName: 'string',\n\n /**\n * This property stores the support provider's logo url when available.\n *\n * @type {string}\n */\n supportProviderLogoUrl: 'string',\n\n /**\n * This property stores the device's url retrieved from a registration\n * request. This property gets set via the initial registration process by a\n * `this.set()` method.\n *\n * @type {string}\n */\n url: 'string',\n\n /**\n * This property stores the device's userId uuid value, which can also be\n * derived from the device's registerd user's userId retrieved from\n * the **Hydra** service.\n *\n * @type {string}\n */\n userId: 'string',\n\n /**\n * This property stores whether or not file sharing is enabled\n *\n * @type {'BLOCK_BOTH' | 'BLOCK_UPLOAD'}\n */\n webFileShareControl: 'string',\n\n /**\n * This property stores the current web socket url used by the registered\n * device.\n *\n * @type {string}\n */\n webSocketUrl: 'string',\n\n /**\n * This property stores the value indicating whether or not white board file\n * sharing is enabled for the current device.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n whiteboardFileShareControl: 'string',\n },\n\n /**\n * A list of derived properties that populate based when their parent data\n * available via the device's properties.\n *\n * @type {Object}\n */\n derived: {\n /**\n * This property determines if the current device is registered.\n *\n * @type {boolean}\n */\n registered: {\n deps: ['url'],\n\n /**\n * Checks if the device is registered by validating that the url exists.\n * Amperstand does not allow this to method to be written as an arrow\n * function.\n *\n * @returns {boolean}\n */\n fn() {\n return !!this.url;\n },\n },\n },\n\n /**\n * Stores timer data as well as other state details.\n *\n * @type {Object}\n */\n session: {\n /**\n * This property stores the logout timer object\n *\n * @type {any}\n */\n logoutTimer: 'any',\n\n /**\n * This property stores the date for the last activity the user made\n * with the current device.\n *\n * @type {number}\n */\n lastUserActivityDate: 'number',\n\n /**\n * This property stores whether or not the reachability check has been\n * performed to prevent the reachability check from performing its\n * operation more than once after a successful check.\n *\n * @returns {boolean}\n */\n isReachabilityChecked: ['boolean', false, false],\n\n /**\n * This property stores whether or not the next refresh or register request should request energy forecast data\n * in order to prevent over fetching energy forecasts\n *\n * @type {boolean}\n */\n energyForecastConfig: 'boolean',\n\n /**\n * This property stores whether or not the current device is in a meeting\n * to prevent an unneeded timeout of a meeting due to inactivity.\n *\n * @type {boolean}\n */\n isInMeeting: 'boolean',\n\n /**\n * This property identifies if the device is currently in network to prevent\n * the `resetLogoutTimer()` method from being called repeatedly once its\n * known client is connected to the organization's internal network.\n *\n * @type {boolean}\n */\n isInNetwork: 'boolean',\n },\n\n // Event method members.\n\n /**\n * Trigger meeting started event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingStarted() {\n this.webex.trigger('meeting started');\n },\n\n /**\n * Trigger meeting ended event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingEnded() {\n this.webex.trigger('meeting ended');\n },\n\n /**\n * Set the value of energy forecast config for the current registered device.\n * @param {boolean} [energyForecastConfig=false] - fetch an energy forecast on the next refresh/register\n * @returns {void}\n */\n setEnergyForecastConfig(energyForecastConfig = false) {\n this.energyForecastConfig = energyForecastConfig;\n },\n\n // Registration method members\n\n /**\n * Refresh the current registered device if able.\n *\n * @param {DeviceRegistrationOptions} options - The options for refresh.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n refresh(deviceRegistrationOptions = {}) {\n this.logger.info('device: refreshing');\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is not registered and register instead.\n if (!this.registered) {\n this.logger.info('device: device not registered, registering');\n\n return this.register(deviceRegistrationOptions);\n }\n\n // Merge body configurations, overriding defaults.\n const body = {\n ...this.serialize(),\n ...(this.config.body ? this.config.body : {}),\n };\n\n // Remove unneeded properties from the body object.\n delete body.features;\n delete body.mediaCluster;\n delete body.etag;\n\n // Append a ttl value if the device is marked as ephemeral.\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n // If etag is sent, WDM will not send developer feature toggles unless they have changed\n ...(this.etag ? {'If-None-Match': this.etag} : {}),\n };\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n return this.request({\n method: 'PUT',\n uri: this.url,\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .then((response) => this.processRegistrationSuccess(response))\n .catch((reason) => {\n // Handle a 404 error, which indicates that the device is no longer\n // valid and needs to be registered as a new device.\n if (reason.statusCode === 404) {\n this.logger.info('device: refresh failed, device is not valid');\n this.logger.info('device: attempting to register a new device');\n\n this.clear();\n\n return this.register(deviceRegistrationOptions);\n }\n\n return Promise.reject(reason);\n });\n });\n },\n\n /**\n * Register or refresh a device depending on the current device state. Device\n * registration utilizes the services plugin to send the request to the\n * **WDM** service.\n *\n * @param {Object} options - The options for registration.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n register(deviceRegistrationOptions = {}) {\n this.logger.info('device: registering');\n\n this.webex.internal.newMetrics.callDiagnosticMetrics.setDeviceInfo(this);\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is already registered and refresh instead.\n if (this.registered) {\n this.logger.info('device: device already registered, refreshing');\n\n return this.refresh(deviceRegistrationOptions);\n }\n\n // Merge body configurations, overriding defaults.\n const body = {\n ...(this.config.defaults.body ? this.config.defaults.body : {}),\n ...(this.config.body ? this.config.body : {}),\n };\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n };\n\n // Append a ttl value if the device is marked as ephemeral\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.request',\n });\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n // This will be replaced by a `create()` method.\n return this.request({\n method: 'POST',\n service: 'wdm',\n resource: 'devices',\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .catch((error) => {\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n throw error;\n })\n .then((response) => {\n // Do not add any processing of response above this as that will affect timestamp\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n this.webex.internal.metrics.submitClientMetrics(\n METRICS.JS_SDK_WDM_REGISTRATION_SUCCESSFUL\n );\n\n return this.processRegistrationSuccess(response);\n })\n .catch((error) => {\n this.webex.internal.metrics.submitClientMetrics(METRICS.JS_SDK_WDM_REGISTRATION_FAILED, {\n fields: {error},\n });\n throw error;\n });\n });\n },\n\n /**\n * Unregister the current registered device if available. Unregistering a\n * device utilizes the services plugin to send the request to the **WDM**\n * service.\n *\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n unregister() {\n this.logger.info('device: unregistering');\n\n if (!this.registered) {\n this.logger.warn('device: not registered');\n\n return Promise.resolve();\n }\n\n return this.request({\n uri: this.url,\n method: 'DELETE',\n }).then(() => this.clear());\n },\n /* eslint-enable require-jsdoc */\n\n // Helper method members\n\n /**\n * Determine if registration methods can be performed. This method utilizes\n * the `services` plugin to confirm if the appropriate service urls are\n * available for device registration.\n *\n * @returns {Promise<void, Error>}\n */\n canRegister() {\n this.logger.info('device: validating if registration can occur');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Wait for the postauth catalog to populate.\n return services.waitForCatalog('postauth', this.config.canRegisterWaitDuration).then(() =>\n // Validate that the service exists after waiting for the catalog.\n services.get('wdm')\n ? Promise.resolve()\n : Promise.reject(\n new Error(\n [\n 'device: cannot register,',\n \"'wdm' service is not available from the postauth catalog\",\n ].join(' ')\n )\n )\n );\n },\n\n /**\n * Check if the device can currently reach the inactivity check url.\n *\n * @returns {Promise<void, Error>}\n */\n checkNetworkReachability() {\n this.logger.info('device: checking network reachability');\n\n // Validate if the device has been checked and reset the logout timer.\n if (this.isReachabilityChecked) {\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n this.isReachabilityChecked = true;\n\n // Validate if the device has a intranet checking url.\n if (!this.intranetInactivityCheckUrl) {\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n // Clear unnecessary headers for reachability request.\n const headers = {\n 'cisco-no-http-redirect': null,\n 'spark-user-agent': null,\n trackingid: null,\n };\n\n // Send the network reachability request.\n return this.request({\n headers,\n method: 'GET',\n uri: this.intranetInactivityCheckUrl,\n })\n .then(() => {\n this.isInNetwork = true;\n\n return Promise.resolve(this.resetLogoutTimer());\n })\n .catch(() => {\n this.logger.info('device: did not reach ping endpoint');\n this.logger.info('device: triggering off-network timer');\n\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n });\n },\n\n /**\n * Clears the registration ttl value if available.\n *\n * @param {Object} options - Values to be cleared.\n * @returns {void}\n */\n clear(...args) {\n this.logger.info('device: clearing registered device');\n\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.clear, this, args);\n },\n\n /**\n * Get the current websocket url with the appropriate priority host.\n *\n * @param {boolean} [wait=false] - Willing to wait on a valid url.\n * @returns {Promise<string, Error>} - The priority-mapped web socket url.\n */\n getWebSocketUrl(wait = false) {\n this.logger.info('device: getting the current websocket url');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Validate if the method should wait for registration.\n if (wait) {\n return this.waitForRegistration()\n .then(() => services.convertUrlToPriorityHostUrl(this.webSocketUrl))\n .catch((error) => {\n this.logger.warn(error.message);\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n });\n }\n\n // Validate if the device is registered.\n if (!this.registered) {\n return Promise.reject(\n new Error('device: cannot get websocket url, device is not registered')\n );\n }\n\n // Attempt to collect the priority-host-mapped web socket URL.\n const wsUrl = services.convertUrlToPriorityHostUrl(this.webSocketUrl);\n\n // Validate that the url was collected.\n if (wsUrl) {\n return Promise.resolve(wsUrl);\n }\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n },\n\n /**\n * Process a successful device registration.\n *\n * @param {Object} response - response object from registration success.\n * @returns {void}\n */\n processRegistrationSuccess(response) {\n this.logger.info('device: received registration payload');\n\n // Clone the response body for service cleaning.\n const body = {...response.body};\n\n // Clean service data.\n delete body.services;\n delete body.serviceHostMap;\n\n const {etag} = response.headers || {};\n\n if (this.etag && etag && this.etag === etag) {\n // If current etag matches the previous one and we have sent\n // If-None-Match header the developer and entitlement feature\n // toggles will not be returned\n const {features} = body;\n\n delete body.features;\n // When using the etag feature cache, user and entitlement features are still returned\n this.features.user.reset(features.user);\n this.features.entitlement.reset(features.entitlement);\n }\n\n // Assign the recieved DTO from **WDM** to this device.\n this.set(body);\n\n // Assign the new etag to this device.\n this.set({etag});\n\n // Validate if device is ephemeral and setup refresh timer.\n if (this.config.ephemeral) {\n this.logger.info('device: enqueuing device refresh');\n\n const delay = (this.config.ephemeralDeviceTTL / 2 + 60) * 1000;\n\n this.refreshTimer = safeSetTimeout(() => this.refresh(), delay);\n }\n\n // Emit the registration:success event.\n this.trigger(DEVICE_EVENT_REGISTRATION_SUCCESS, this);\n },\n\n /**\n * Reset the current local logout timer for the registered device if\n * registered.\n *\n * @returns {void}\n */\n resetLogoutTimer() {\n this.logger.info('device: resetting logout timer');\n\n // Clear current logout timer.\n clearTimeout(this.logoutTimer);\n\n // Remove last activity date event listener.\n this.off('change:lastUserActivityDate');\n\n // Remove the logout timer.\n this.unset('logoutTimer');\n\n // Validate if the device is currently in a meeting and is configured to\n // required inactivity enforcement.\n if (\n !this.isInMeeting &&\n this.config.enableInactivityEnforcement &&\n this.isReachabilityChecked\n ) {\n if (this.isInNetwork) {\n this.setLogoutTimer(this.inNetworkInactivityDuration);\n } else {\n this.setLogoutTimer(this.intranetInactivityDuration);\n }\n }\n },\n\n /**\n * Set the value of the logout timer for the current registered device.\n *\n * @param {number} duration - Value in seconds of the new logout timer.\n * @returns {void}\n */\n setLogoutTimer(duration) {\n this.logger.info('device: setting logout timer');\n\n if (!duration || duration <= 0) {\n return;\n }\n\n // Setup user activity date event listener.\n this.on('change:lastUserActivityDate', () => {\n this.resetLogoutTimer();\n });\n\n // Initialize a new timer.\n this.logoutTimer = safeSetTimeout(() => {\n this.webex.logout();\n }, duration * 1000);\n },\n\n /**\n * Wait for the device to be registered.\n *\n * @param {number} [timeout=10] - The maximum duration to wait, in seconds.\n * @returns {Promise<void, Error>}\n */\n waitForRegistration(timeout = 10) {\n this.logger.info('device: waiting for registration');\n\n return new Promise((resolve, reject) => {\n if (this.registered) {\n resolve();\n }\n\n const timeoutTimer = safeSetTimeout(\n () => reject(new Error('device: timeout occured while waiting for registration')),\n timeout * 1000\n );\n\n this.once(DEVICE_EVENT_REGISTRATION_SUCCESS, () => {\n clearTimeout(timeoutTimer);\n resolve();\n });\n });\n },\n\n // Deprecated methods.\n\n /**\n * Mark a url as failed and get the next priority host url.\n *\n * @param {string} url - The url to mark as failed.\n * @returns {Promise<string>} - The next priority url.\n */\n @deprecated('device#markUrlFailedAndGetNew(): Use services#markFailedUrl()')\n markUrlFailedAndGetNew(url) {\n return Promise.resolve(this.webex.internal.services.markFailedUrl(url));\n },\n\n // Ampersand method members\n\n /* eslint-disable require-jsdoc */\n /**\n * Initializer method for the device plugin.\n *\n * @override\n * @param {Array<any>} args - An array of items to be mapped as properties.\n * @returns {void}\n */\n @persist('@', decider)\n initialize(...args) {\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n\n // Initialize feature events and listeners.\n FEATURE_COLLECTION_NAMES.forEach((collectionName) => {\n this.features.on(`change:${collectionName}`, (model, value, options) => {\n this.trigger('change', this, options);\n this.trigger('change:features', this, this.features, options);\n });\n });\n\n // Initialize network reachability checking event for url change.\n this.on('change:intranetInactivityCheckUrl', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:intranetInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:inNetworkInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize listener for activity checking.\n this.listenTo(this.webex, 'user-activity', () => {\n this.lastUserActivityDate = Date.now();\n });\n\n // Initialize listener for meeting started event.\n this.listenTo(this.webex, 'meeting started', () => {\n this.isInMeeting = true;\n this.resetLogoutTimer();\n });\n\n // Initialize listener for meeting ended event.\n this.listenTo(this.webex, 'meeting ended', () => {\n this.isInMeeting = false;\n this.resetLogoutTimer();\n });\n },\n /* eslint-enable require-jsdoc */\n});\n\nexport default Device;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_common","require","_webexCore","_commonTimers","_lodash","_metrics","_interopRequireDefault","_constants","_featuresModel","_ipNetworkDetector","_types","_dec","_dec2","_dec3","_dec4","_dec5","_dec6","_obj","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor2","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","decider","config","ephemeral","Device","WebexPlugin","extend","waitForValue","deprecated","persist","namespace","extraProperties","idAttribute","children","features","FeaturesModel","ipNetworkDetector","IpNetworkDetector","props","clientMessagingGiphy","customerCompanyName","customerLogoUrl","deviceType","helpUrl","intranetInactivityDuration","intranetInactivityCheckUrl","inNetworkInactivityDuration","ecmEnabledForAllUsers","ecmSupportedStorageProviders","modificationTime","navigationBarColor","partnerCompanyName","partnerLogoUrl","peopleInsightsEnabled","reportingSiteDesc","reportingSiteUrl","searchEncryptionKeyUrl","showSupportText","supportProviderCompanyName","supportProviderLogoUrl","url","userId","webFileShareControl","webSocketUrl","whiteboardFileShareControl","derived","registered","deps","fn","session","logoutTimer","lastUserActivityDate","isReachabilityChecked","energyForecastConfig","isInMeeting","isInNetwork","meetingStarted","webex","trigger","meetingEnded","setEnergyForecastConfig","undefined","refresh","_this","deviceRegistrationOptions","logger","info","canRegister","then","register","body","serialize","mediaCluster","etag","ttl","ephemeralDeviceTTL","headers","defaults","_deviceRegistrationOp","includeDetails","CatalogDetails","all","request","method","uri","qs","includeUpstreamServices","concat","energyForecast","response","processRegistrationSuccess","catch","reason","statusCode","clear","_promise","reject","deleteDevices","_this2","service","resource","devices","_this2$_getBody","_getBody","webDevices","item","sortedDevices","orderBy","Date","totalItems","countToDelete","Math","ceil","urlsToDelete","slice","map","race","resolve","error","_this3","_registerInternal","_error$body","message","_this4","internal","newMetrics","callDiagnosticMetrics","setDeviceInfo","submitInternalEvent","name","_deviceRegistrationOp2","metrics","submitClientMetrics","METRICS","JS_SDK_WDM_REGISTRATION_SUCCESSFUL","JS_SDK_WDM_REGISTRATION_FAILED","fields","unregister","_this5","warn","services","waitForCatalog","canRegisterWaitDuration","get","Error","join","checkNetworkReachability","_this6","resetLogoutTimer","trackingid","_len","args","Array","_key","_apply","prototype","getWebSocketUrl","_this7","wait","waitForRegistration","convertUrlToPriorityHostUrl","wsUrl","_this8","serviceHostMap","_ref","user","reset","entitlement","set","delay","refreshTimer","safeSetTimeout","DEVICE_EVENT_REGISTRATION_SUCCESS","clearTimeout","off","unset","enableInactivityEnforcement","setLogoutTimer","duration","_this9","on","logout","_this10","timeout","timeoutTimer","once","markUrlFailedAndGetNew","markFailedUrl","initialize","_this11","_len2","_key2","FEATURE_COLLECTION_NAMES","collectionName","model","value","options","listenTo","_now","version","_applyDecoratedDescriptor2","oneFlight","_getOwnPropertyDescriptor","_default","exports"],"sources":["device.js"],"sourcesContent":["// Internal Dependencies\nimport {deprecated, oneFlight} from '@webex/common';\nimport {persist, waitForValue, WebexPlugin} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\nimport {orderBy} from 'lodash';\n\nimport METRICS from './metrics';\nimport {FEATURE_COLLECTION_NAMES, DEVICE_EVENT_REGISTRATION_SUCCESS} from './constants';\nimport FeaturesModel from './features/features-model';\nimport IpNetworkDetector from './ipNetworkDetector';\nimport {CatalogDetails} from './types';\n\n/**\n * Determine if the plugin should be initialized based on cached storage.\n *\n * @returns {boolean} - If the device is ephemeral.\n */\nfunction decider() {\n return !this.config.ephemeral;\n}\n\nconst Device = WebexPlugin.extend({\n // Ampersand property members.\n\n namespace: 'Device',\n\n // Allow for extra properties to prevent the plugin from failing due to\n // **WDM** service DTO changes.\n extraProperties: 'allow',\n\n idAttribute: 'url',\n\n children: {\n /**\n * The class object that contains all of the feature collections.\n *\n * @type {FeaturesModel}\n */\n features: FeaturesModel,\n /**\n * Helper class for detecting what IP network version (ipv4, ipv6) we're on.\n *\n * @type {IpNetworkDetector}\n */\n ipNetworkDetector: IpNetworkDetector,\n },\n\n /**\n * A collection of device properties mostly assigned by the retrieved DTO from\n * the **WDM** service that are mapped against the ampersand properties.\n *\n * @type {Object}\n */\n props: {\n /**\n * This property determines whether or not giphy support is enabled.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n clientMessagingGiphy: 'string',\n\n /**\n * This property should store the company name.\n *\n * @type {string}\n */\n customerCompanyName: 'string',\n\n /**\n * This property should store the logo url.\n *\n * @type {string}\n */\n customerLogoUrl: 'string',\n\n /**\n * This property doesn't have any real values, but is sent during device\n * refresh to prevent the **wdm** service from falling back to an iOS device\n * type.\n *\n * @type {string}\n */\n deviceType: 'string',\n\n /**\n * This property should store the help url.\n *\n * @type {string}\n */\n helpUrl: 'string',\n\n /**\n * This property should store the intranet inactivity timer duration.\n *\n * @type {number}\n */\n intranetInactivityDuration: 'number',\n\n /**\n * This property stores the url required to validate if the device is able\n * to actively reach the intranet network.\n *\n * @type {string}\n */\n intranetInactivityCheckUrl: 'string',\n\n /**\n * This property stores the inactivity timer duration, and could possibly\n * deprecate the `intranetInactivityDuration` property.\n *\n * @type {number}\n */\n inNetworkInactivityDuration: 'number',\n\n /**\n * This property stores the ECM (external content management) enabled value\n * for the whole organization.\n *\n * @type {boolean}\n */\n ecmEnabledForAllUsers: ['boolean', false, false],\n\n /**\n * This property stores an array of ECM (external content management)\n * providers that are currently available.\n *\n * @returns {Array<string>}\n */\n ecmSupportedStorageProviders: ['array', false, () => []],\n\n /**\n * This property stores the modification time value retrieved from the\n * **WDM** endpoint formatted as ISO 8601.\n *\n * @type {string}\n */\n modificationTime: 'string',\n\n /**\n * This property stores the navigation bar color.\n *\n * @type {string}\n */\n navigationBarColor: 'string',\n\n /**\n * This property stores the partner company's name when available.\n *\n * @type {string}\n */\n partnerCompanyName: 'string',\n\n /**\n * This property stores the partner company's logo when available.\n *\n * @type {string}\n */\n partnerLogoUrl: 'string',\n\n /**\n * This property stores the availability of people data from the **WDM**\n * service.\n *\n * @type {boolean}\n */\n peopleInsightsEnabled: 'boolean',\n\n /**\n * This property stores the reporting site's description when available.\n *\n * @type {string}\n */\n reportingSiteDesc: 'string',\n\n /**\n * This property stores the reporting site's access url when available.\n *\n * @type {string}\n */\n reportingSiteUrl: 'string',\n\n /**\n * This property stores the encryption key url when available.\n *\n * @type {string}\n */\n searchEncryptionKeyUrl: 'string',\n\n /**\n * This property stores the availability of support-provided text from the\n * **WDM** service.\n *\n * @type {boolean}\n */\n showSupportText: 'boolean',\n\n /**\n * This property stores the support provider's company name when available.\n *\n * @type {string}\n */\n supportProviderCompanyName: 'string',\n\n /**\n * This property stores the support provider's logo url when available.\n *\n * @type {string}\n */\n supportProviderLogoUrl: 'string',\n\n /**\n * This property stores the device's url retrieved from a registration\n * request. This property gets set via the initial registration process by a\n * `this.set()` method.\n *\n * @type {string}\n */\n url: 'string',\n\n /**\n * This property stores the device's userId uuid value, which can also be\n * derived from the device's registerd user's userId retrieved from\n * the **Hydra** service.\n *\n * @type {string}\n */\n userId: 'string',\n\n /**\n * This property stores whether or not file sharing is enabled\n *\n * @type {'BLOCK_BOTH' | 'BLOCK_UPLOAD'}\n */\n webFileShareControl: 'string',\n\n /**\n * This property stores the current web socket url used by the registered\n * device.\n *\n * @type {string}\n */\n webSocketUrl: 'string',\n\n /**\n * This property stores the value indicating whether or not white board file\n * sharing is enabled for the current device.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n whiteboardFileShareControl: 'string',\n },\n\n /**\n * A list of derived properties that populate based when their parent data\n * available via the device's properties.\n *\n * @type {Object}\n */\n derived: {\n /**\n * This property determines if the current device is registered.\n *\n * @type {boolean}\n */\n registered: {\n deps: ['url'],\n\n /**\n * Checks if the device is registered by validating that the url exists.\n * Amperstand does not allow this to method to be written as an arrow\n * function.\n *\n * @returns {boolean}\n */\n fn() {\n return !!this.url;\n },\n },\n },\n\n /**\n * Stores timer data as well as other state details.\n *\n * @type {Object}\n */\n session: {\n /**\n * This property stores the logout timer object\n *\n * @type {any}\n */\n logoutTimer: 'any',\n\n /**\n * This property stores the date for the last activity the user made\n * with the current device.\n *\n * @type {number}\n */\n lastUserActivityDate: 'number',\n\n /**\n * This property stores whether or not the reachability check has been\n * performed to prevent the reachability check from performing its\n * operation more than once after a successful check.\n *\n * @returns {boolean}\n */\n isReachabilityChecked: ['boolean', false, false],\n\n /**\n * This property stores whether or not the next refresh or register request should request energy forecast data\n * in order to prevent over fetching energy forecasts\n *\n * @type {boolean}\n */\n energyForecastConfig: 'boolean',\n\n /**\n * This property stores whether or not the current device is in a meeting\n * to prevent an unneeded timeout of a meeting due to inactivity.\n *\n * @type {boolean}\n */\n isInMeeting: 'boolean',\n\n /**\n * This property identifies if the device is currently in network to prevent\n * the `resetLogoutTimer()` method from being called repeatedly once its\n * known client is connected to the organization's internal network.\n *\n * @type {boolean}\n */\n isInNetwork: 'boolean',\n },\n\n // Event method members.\n\n /**\n * Trigger meeting started event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingStarted() {\n this.webex.trigger('meeting started');\n },\n\n /**\n * Trigger meeting ended event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingEnded() {\n this.webex.trigger('meeting ended');\n },\n\n /**\n * Set the value of energy forecast config for the current registered device.\n * @param {boolean} [energyForecastConfig=false] - fetch an energy forecast on the next refresh/register\n * @returns {void}\n */\n setEnergyForecastConfig(energyForecastConfig = false) {\n this.energyForecastConfig = energyForecastConfig;\n },\n\n // Registration method members\n\n /**\n * Refresh the current registered device if able.\n *\n * @param {DeviceRegistrationOptions} options - The options for refresh.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n refresh(deviceRegistrationOptions = {}) {\n this.logger.info('device: refreshing');\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is not registered and register instead.\n if (!this.registered) {\n this.logger.info('device: device not registered, registering');\n\n return this.register(deviceRegistrationOptions);\n }\n\n // Merge body configurations, overriding defaults.\n const body = {\n ...this.serialize(),\n ...(this.config.body ? this.config.body : {}),\n };\n\n // Remove unneeded properties from the body object.\n delete body.features;\n delete body.mediaCluster;\n delete body.etag;\n\n // Append a ttl value if the device is marked as ephemeral.\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n // If etag is sent, WDM will not send developer feature toggles unless they have changed\n ...(this.etag ? {'If-None-Match': this.etag} : {}),\n };\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n return this.request({\n method: 'PUT',\n uri: this.url,\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .then((response) => this.processRegistrationSuccess(response))\n .catch((reason) => {\n // Handle a 404 error, which indicates that the device is no longer\n // valid and needs to be registered as a new device.\n if (reason.statusCode === 404) {\n this.logger.info('device: refresh failed, device is not valid');\n this.logger.info('device: attempting to register a new device');\n\n this.clear();\n\n return this.register(deviceRegistrationOptions);\n }\n\n return Promise.reject(reason);\n });\n });\n },\n /**\n * Fetches the web devices and deletes the third of them which are not recent devices in use\n * @returns {Promise<void, Error>}\n */\n deleteDevices() {\n // Fetch devices with a GET request\n return this.request({\n method: 'GET',\n service: 'wdm',\n resource: 'devices',\n })\n .then((response) => {\n const {devices} = response.body;\n\n const {deviceType} = this._getBody();\n\n // Filter devices of type deviceType\n const webDevices = devices.filter((item) => item.deviceType === deviceType);\n\n const sortedDevices = orderBy(webDevices, [(item) => new Date(item.modificationTime)]);\n\n // If there are more than two devices, delete the last third\n if (sortedDevices.length > 2) {\n const totalItems = sortedDevices.length;\n const countToDelete = Math.ceil(totalItems / 3);\n const urlsToDelete = sortedDevices.slice(0, countToDelete).map((item) => item.url);\n\n return Promise.race(\n urlsToDelete.map((url) => {\n return this.request({\n uri: url,\n method: 'DELETE',\n });\n })\n );\n }\n\n return Promise.resolve();\n })\n .catch((error) => {\n this.logger.error('Failed to retrieve devices:', error);\n\n return Promise.reject(error);\n });\n },\n\n /**\n * Registers and when fails deletes devices\n */\n @oneFlight\n @waitForValue('@')\n register(deviceRegistrationOptions = {}) {\n return this._registerInternal(deviceRegistrationOptions).catch((error) => {\n if (error?.body?.message === 'User has excessive device registrations') {\n return this.deleteDevices().then(() => {\n return this._registerInternal(deviceRegistrationOptions);\n });\n }\n throw error;\n });\n },\n\n _getBody() {\n return {\n ...(this.config.defaults.body ? this.config.defaults.body : {}),\n ...(this.config.body ? this.config.body : {}),\n };\n },\n\n /**\n * Register or refresh a device depending on the current device state. Device\n * registration utilizes the services plugin to send the request to the\n * **WDM** service.\n *\n * @param {Object} options - The options for registration.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n _registerInternal(deviceRegistrationOptions = {}) {\n this.logger.info('device: registering');\n\n this.webex.internal.newMetrics.callDiagnosticMetrics.setDeviceInfo(this);\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is already registered and refresh instead.\n if (this.registered) {\n this.logger.info('device: device already registered, refreshing');\n\n return this.refresh(deviceRegistrationOptions);\n }\n\n // Merge body configurations, overriding defaults.\n const body = this._getBody();\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n };\n\n // Append a ttl value if the device is marked as ephemeral\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.request',\n });\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n // This will be replaced by a `create()` method.\n return this.request({\n method: 'POST',\n service: 'wdm',\n resource: 'devices',\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .catch((error) => {\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n throw error;\n })\n .then((response) => {\n // Do not add any processing of response above this as that will affect timestamp\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n this.webex.internal.metrics.submitClientMetrics(\n METRICS.JS_SDK_WDM_REGISTRATION_SUCCESSFUL\n );\n\n return this.processRegistrationSuccess(response);\n })\n .catch((error) => {\n this.webex.internal.metrics.submitClientMetrics(METRICS.JS_SDK_WDM_REGISTRATION_FAILED, {\n fields: {error},\n });\n throw error;\n });\n });\n },\n /**\n * Unregister the current registered device if available. Unregistering a\n * device utilizes the services plugin to send the request to the **WDM**\n * service.\n *\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n unregister() {\n this.logger.info('device: unregistering');\n\n if (!this.registered) {\n this.logger.warn('device: not registered');\n\n return Promise.resolve();\n }\n\n return this.request({\n uri: this.url,\n method: 'DELETE',\n }).then(() => this.clear());\n },\n /* eslint-enable require-jsdoc */\n\n // Helper method members\n\n /**\n * Determine if registration methods can be performed. This method utilizes\n * the `services` plugin to confirm if the appropriate service urls are\n * available for device registration.\n *\n * @returns {Promise<void, Error>}\n */\n canRegister() {\n this.logger.info('device: validating if registration can occur');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Wait for the postauth catalog to populate.\n return services.waitForCatalog('postauth', this.config.canRegisterWaitDuration).then(() =>\n // Validate that the service exists after waiting for the catalog.\n services.get('wdm')\n ? Promise.resolve()\n : Promise.reject(\n new Error(\n [\n 'device: cannot register,',\n \"'wdm' service is not available from the postauth catalog\",\n ].join(' ')\n )\n )\n );\n },\n\n /**\n * Check if the device can currently reach the inactivity check url.\n *\n * @returns {Promise<void, Error>}\n */\n checkNetworkReachability() {\n this.logger.info('device: checking network reachability');\n\n // Validate if the device has been checked and reset the logout timer.\n if (this.isReachabilityChecked) {\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n this.isReachabilityChecked = true;\n\n // Validate if the device has a intranet checking url.\n if (!this.intranetInactivityCheckUrl) {\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n // Clear unnecessary headers for reachability request.\n const headers = {\n 'cisco-no-http-redirect': null,\n 'spark-user-agent': null,\n trackingid: null,\n };\n\n // Send the network reachability request.\n return this.request({\n headers,\n method: 'GET',\n uri: this.intranetInactivityCheckUrl,\n })\n .then(() => {\n this.isInNetwork = true;\n\n return Promise.resolve(this.resetLogoutTimer());\n })\n .catch(() => {\n this.logger.info('device: did not reach ping endpoint');\n this.logger.info('device: triggering off-network timer');\n\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n });\n },\n\n /**\n * Clears the registration ttl value if available.\n *\n * @param {Object} options - Values to be cleared.\n * @returns {void}\n */\n clear(...args) {\n this.logger.info('device: clearing registered device');\n\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.clear, this, args);\n },\n\n /**\n * Get the current websocket url with the appropriate priority host.\n *\n * @param {boolean} [wait=false] - Willing to wait on a valid url.\n * @returns {Promise<string, Error>} - The priority-mapped web socket url.\n */\n getWebSocketUrl(wait = false) {\n this.logger.info('device: getting the current websocket url');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Validate if the method should wait for registration.\n if (wait) {\n return this.waitForRegistration()\n .then(() => services.convertUrlToPriorityHostUrl(this.webSocketUrl))\n .catch((error) => {\n this.logger.warn(error.message);\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n });\n }\n\n // Validate if the device is registered.\n if (!this.registered) {\n return Promise.reject(\n new Error('device: cannot get websocket url, device is not registered')\n );\n }\n\n // Attempt to collect the priority-host-mapped web socket URL.\n const wsUrl = services.convertUrlToPriorityHostUrl(this.webSocketUrl);\n\n // Validate that the url was collected.\n if (wsUrl) {\n return Promise.resolve(wsUrl);\n }\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n },\n\n /**\n * Process a successful device registration.\n *\n * @param {Object} response - response object from registration success.\n * @returns {void}\n */\n processRegistrationSuccess(response) {\n this.logger.info('device: received registration payload');\n\n // Clone the response body for service cleaning.\n const body = {...response.body};\n\n // Clean service data.\n delete body.services;\n delete body.serviceHostMap;\n\n const {etag} = response.headers || {};\n\n if (this.etag && etag && this.etag === etag) {\n // If current etag matches the previous one and we have sent\n // If-None-Match header the developer and entitlement feature\n // toggles will not be returned\n const {features} = body;\n\n delete body.features;\n // When using the etag feature cache, user and entitlement features are still returned\n this.features.user.reset(features.user);\n this.features.entitlement.reset(features.entitlement);\n }\n\n // Assign the recieved DTO from **WDM** to this device.\n this.set(body);\n\n // Assign the new etag to this device.\n this.set({etag});\n\n // Validate if device is ephemeral and setup refresh timer.\n if (this.config.ephemeral) {\n this.logger.info('device: enqueuing device refresh');\n\n const delay = (this.config.ephemeralDeviceTTL / 2 + 60) * 1000;\n\n this.refreshTimer = safeSetTimeout(() => this.refresh(), delay);\n }\n\n // Emit the registration:success event.\n this.trigger(DEVICE_EVENT_REGISTRATION_SUCCESS, this);\n },\n\n /**\n * Reset the current local logout timer for the registered device if\n * registered.\n *\n * @returns {void}\n */\n resetLogoutTimer() {\n this.logger.info('device: resetting logout timer');\n\n // Clear current logout timer.\n clearTimeout(this.logoutTimer);\n\n // Remove last activity date event listener.\n this.off('change:lastUserActivityDate');\n\n // Remove the logout timer.\n this.unset('logoutTimer');\n\n // Validate if the device is currently in a meeting and is configured to\n // required inactivity enforcement.\n if (\n !this.isInMeeting &&\n this.config.enableInactivityEnforcement &&\n this.isReachabilityChecked\n ) {\n if (this.isInNetwork) {\n this.setLogoutTimer(this.inNetworkInactivityDuration);\n } else {\n this.setLogoutTimer(this.intranetInactivityDuration);\n }\n }\n },\n\n /**\n * Set the value of the logout timer for the current registered device.\n *\n * @param {number} duration - Value in seconds of the new logout timer.\n * @returns {void}\n */\n setLogoutTimer(duration) {\n this.logger.info('device: setting logout timer');\n\n if (!duration || duration <= 0) {\n return;\n }\n\n // Setup user activity date event listener.\n this.on('change:lastUserActivityDate', () => {\n this.resetLogoutTimer();\n });\n\n // Initialize a new timer.\n this.logoutTimer = safeSetTimeout(() => {\n this.webex.logout();\n }, duration * 1000);\n },\n\n /**\n * Wait for the device to be registered.\n *\n * @param {number} [timeout=10] - The maximum duration to wait, in seconds.\n * @returns {Promise<void, Error>}\n */\n waitForRegistration(timeout = 10) {\n this.logger.info('device: waiting for registration');\n\n return new Promise((resolve, reject) => {\n if (this.registered) {\n resolve();\n }\n\n const timeoutTimer = safeSetTimeout(\n () => reject(new Error('device: timeout occured while waiting for registration')),\n timeout * 1000\n );\n\n this.once(DEVICE_EVENT_REGISTRATION_SUCCESS, () => {\n clearTimeout(timeoutTimer);\n resolve();\n });\n });\n },\n\n // Deprecated methods.\n\n /**\n * Mark a url as failed and get the next priority host url.\n *\n * @param {string} url - The url to mark as failed.\n * @returns {Promise<string>} - The next priority url.\n */\n @deprecated('device#markUrlFailedAndGetNew(): Use services#markFailedUrl()')\n markUrlFailedAndGetNew(url) {\n return Promise.resolve(this.webex.internal.services.markFailedUrl(url));\n },\n\n // Ampersand method members\n\n /* eslint-disable require-jsdoc */\n /**\n * Initializer method for the device plugin.\n *\n * @override\n * @param {Array<any>} args - An array of items to be mapped as properties.\n * @returns {void}\n */\n @persist('@', decider)\n initialize(...args) {\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n\n // Initialize feature events and listeners.\n FEATURE_COLLECTION_NAMES.forEach((collectionName) => {\n this.features.on(`change:${collectionName}`, (model, value, options) => {\n this.trigger('change', this, options);\n this.trigger('change:features', this, this.features, options);\n });\n });\n\n // Initialize network reachability checking event for url change.\n this.on('change:intranetInactivityCheckUrl', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:intranetInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:inNetworkInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize listener for activity checking.\n this.listenTo(this.webex, 'user-activity', () => {\n this.lastUserActivityDate = Date.now();\n });\n\n // Initialize listener for meeting started event.\n this.listenTo(this.webex, 'meeting started', () => {\n this.isInMeeting = true;\n this.resetLogoutTimer();\n });\n\n // Initialize listener for meeting ended event.\n this.listenTo(this.webex, 'meeting ended', () => {\n this.isInMeeting = false;\n this.resetLogoutTimer();\n });\n },\n /* eslint-enable require-jsdoc */\n});\n\nexport default Device;\n"],"mappings":"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"}
|
|
@@ -14,6 +14,12 @@ var _webexCore = require("@webex/webex-core");
|
|
|
14
14
|
* Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
var STATE = {
|
|
18
|
+
INITIAL: 'initial',
|
|
19
|
+
IN_PROGRESS: 'in-progress',
|
|
20
|
+
IDLE: 'idle'
|
|
21
|
+
};
|
|
22
|
+
|
|
17
23
|
/**
|
|
18
24
|
* @class
|
|
19
25
|
*/
|
|
@@ -27,9 +33,11 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
|
|
|
27
33
|
// time [ms] it took to receive first IPv6 candidate
|
|
28
34
|
firstMdns: ['number', true, -1],
|
|
29
35
|
// time [ms] it took to receive first mDNS candidate
|
|
30
|
-
totalTime: ['number', true, -1]
|
|
36
|
+
totalTime: ['number', true, -1],
|
|
37
|
+
// total time [ms] it took to do the last IP network detection
|
|
38
|
+
state: ['string', true, STATE.INITIAL],
|
|
39
|
+
pendingDetection: ['object', false, undefined]
|
|
31
40
|
},
|
|
32
|
-
|
|
33
41
|
derived: {
|
|
34
42
|
/**
|
|
35
43
|
* True if we know we're on an IPv4 network,
|
|
@@ -165,35 +173,59 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
|
|
|
165
173
|
* Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the
|
|
166
174
|
* supportsIpV4 and supportsIpV6 props to find out the result.
|
|
167
175
|
*
|
|
168
|
-
* @
|
|
176
|
+
* @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet
|
|
177
|
+
* @returns {Promise<void>}
|
|
169
178
|
*/
|
|
170
179
|
detect: function detect() {
|
|
171
|
-
var
|
|
180
|
+
var _arguments = arguments,
|
|
181
|
+
_this2 = this;
|
|
172
182
|
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
173
|
-
var results, pc;
|
|
183
|
+
var force, results, pc, forceParam;
|
|
174
184
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
175
185
|
while (1) switch (_context2.prev = _context2.next) {
|
|
176
186
|
case 0:
|
|
177
|
-
|
|
187
|
+
force = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : false;
|
|
188
|
+
if (!(_this2.state === STATE.IN_PROGRESS)) {
|
|
189
|
+
_context2.next = 4;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
_this2.pendingDetection = {
|
|
193
|
+
force: force
|
|
194
|
+
};
|
|
195
|
+
return _context2.abrupt("return");
|
|
196
|
+
case 4:
|
|
197
|
+
if (!(!force && _this2.state !== STATE.INITIAL && !_this2.receivedOnlyMDnsCandidates())) {
|
|
198
|
+
_context2.next = 6;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
return _context2.abrupt("return");
|
|
202
|
+
case 6:
|
|
203
|
+
_context2.prev = 6;
|
|
204
|
+
_this2.state = STATE.IN_PROGRESS;
|
|
178
205
|
pc = new RTCPeerConnection();
|
|
179
|
-
_context2.next =
|
|
206
|
+
_context2.next = 11;
|
|
180
207
|
return _this2.gatherLocalCandidates(pc);
|
|
181
|
-
case
|
|
208
|
+
case 11:
|
|
182
209
|
results = _context2.sent;
|
|
183
|
-
case
|
|
184
|
-
_context2.prev =
|
|
210
|
+
case 12:
|
|
211
|
+
_context2.prev = 12;
|
|
185
212
|
pc.close();
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
213
|
+
_this2.state = STATE.IDLE;
|
|
214
|
+
return _context2.finish(12);
|
|
215
|
+
case 16:
|
|
216
|
+
if (_this2.pendingDetection) {
|
|
217
|
+
forceParam = _this2.pendingDetection.force;
|
|
218
|
+
_this2.pendingDetection = undefined;
|
|
219
|
+
_this2.detect(forceParam);
|
|
220
|
+
}
|
|
221
|
+
case 17:
|
|
190
222
|
case "end":
|
|
191
223
|
return _context2.stop();
|
|
192
224
|
}
|
|
193
|
-
}, _callee2, null, [[
|
|
225
|
+
}, _callee2, null, [[6,, 12, 16]]);
|
|
194
226
|
}))();
|
|
195
227
|
},
|
|
196
|
-
version: "3.
|
|
228
|
+
version: "3.7.0-next.2"
|
|
197
229
|
});
|
|
198
230
|
var _default = exports.default = IpNetworkDetector;
|
|
199
231
|
//# sourceMappingURL=ipNetworkDetector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_webexCore","require","IpNetworkDetector","WebexPlugin","extend","idAttribute","namespace","props","firstIpV4","firstIpV6","firstMdns","totalTime","derived","supportsIpV4","deps","fn","undefined","receivedOnlyMDnsCandidates","supportsIpV6","gatherLocalCandidates","pc","_this","_asyncToGenerator2","default","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","_promise","resolve","reject","done","startTime","performance","now","doneGatheringIceCandidates","onicecandidate","event","_event$candidate","candidate","address","endsWith","includes","onicegatheringstatechange","iceGatheringState","createDataChannel","createOffer","then","offer","setLocalDescription","catch","e","webex","logger","error","stop","detect","_this2","_callee2","results","_callee2$","_context2","RTCPeerConnection","sent","close","finish","version","_default","exports"],"sources":["ipNetworkDetector.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\n\n/**\n * @class\n */\nconst IpNetworkDetector = WebexPlugin.extend({\n idAttribute: 'IpNetworkDetectorId',\n\n namespace: 'Device',\n\n props: {\n firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate\n firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate\n firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate\n totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection\n },\n\n derived: {\n /**\n * True if we know we're on an IPv4 network,\n * False if we know that we are not on an IPv4 network,\n * undefined if we are not sure\n */\n supportsIpV4: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV4 prop\n * @returns {boolean | undefined}\n */\n fn() {\n if (this.firstIpV4 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n /**\n * True if we know we're on an IPv6 network,\n * False if we know that we are not on an IPv6 network,\n * undefined if we are not sure\n */\n supportsIpV6: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV6 prop\n * @returns {boolean | undefined}\n */ fn() {\n if (this.firstIpV6 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n },\n\n /**\n * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions\n *\n * @private\n * @returns {boolean}\n */\n receivedOnlyMDnsCandidates() {\n return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;\n },\n\n /**\n *\n * @param {RTCPeerConnection} pc Peer connection to use\n * @private\n * @returns {Promise<void>}\n */\n async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {\n return new Promise((resolve, reject) => {\n let done = false;\n\n this.firstIpV4 = -1;\n this.firstIpV6 = -1;\n this.firstMdns = -1;\n this.totalTime = -1;\n const startTime = performance.now();\n\n const doneGatheringIceCandidates = () => {\n if (done) {\n return;\n }\n done = true;\n\n this.totalTime = performance.now() - startTime;\n\n resolve();\n };\n\n pc.onicecandidate = (event) => {\n if (event.candidate?.address) {\n if (event.candidate.address.endsWith('.local')) {\n // if we don't have camera/mic permissions, browser just gives us mDNS candidates\n if (this.firstMdns === -1) {\n this.firstMdns = performance.now() - startTime;\n }\n } else if (event.candidate.address.includes(':')) {\n if (this.firstIpV6 === -1) {\n this.firstIpV6 = performance.now() - startTime;\n }\n } else if (this.firstIpV4 === -1) {\n this.firstIpV4 = performance.now() - startTime;\n }\n\n if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {\n // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now\n resolve();\n }\n } else if (event.candidate === null) {\n doneGatheringIceCandidates();\n }\n };\n\n pc.onicegatheringstatechange = () => {\n if (pc.iceGatheringState === 'complete') {\n doneGatheringIceCandidates();\n }\n };\n\n pc.createDataChannel('data');\n\n pc.createOffer()\n .then((offer) => pc.setLocalDescription(offer))\n .catch((e) => {\n this.webex.logger.error('Failed to detect ip network version:', e);\n reject(e);\n });\n });\n },\n\n /**\n * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the\n * supportsIpV4 and supportsIpV6 props to find out the result.\n *\n * @returns {Promise<Object>}\n */\n async detect() {\n let results;\n let pc;\n\n try {\n pc = new RTCPeerConnection();\n\n results = await this.gatherLocalCandidates(pc);\n } finally {\n pc.close();\n }\n\n return results;\n },\n});\n\nexport default IpNetworkDetector;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_webexCore","require","STATE","INITIAL","IN_PROGRESS","IDLE","IpNetworkDetector","WebexPlugin","extend","idAttribute","namespace","props","firstIpV4","firstIpV6","firstMdns","totalTime","state","pendingDetection","undefined","derived","supportsIpV4","deps","fn","receivedOnlyMDnsCandidates","supportsIpV6","gatherLocalCandidates","pc","_this","_asyncToGenerator2","default","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","_promise","resolve","reject","done","startTime","performance","now","doneGatheringIceCandidates","onicecandidate","event","_event$candidate","candidate","address","endsWith","includes","onicegatheringstatechange","iceGatheringState","createDataChannel","createOffer","then","offer","setLocalDescription","catch","e","webex","logger","error","stop","detect","_arguments","arguments","_this2","_callee2","force","results","forceParam","_callee2$","_context2","length","RTCPeerConnection","sent","close","finish","version","_default","exports"],"sources":["ipNetworkDetector.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\n\nconst STATE = {\n INITIAL: 'initial',\n IN_PROGRESS: 'in-progress',\n IDLE: 'idle',\n};\n\n/**\n * @class\n */\nconst IpNetworkDetector = WebexPlugin.extend({\n idAttribute: 'IpNetworkDetectorId',\n\n namespace: 'Device',\n\n props: {\n firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate\n firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate\n firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate\n totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection\n state: ['string', true, STATE.INITIAL],\n pendingDetection: ['object', false, undefined],\n },\n\n derived: {\n /**\n * True if we know we're on an IPv4 network,\n * False if we know that we are not on an IPv4 network,\n * undefined if we are not sure\n */\n supportsIpV4: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV4 prop\n * @returns {boolean | undefined}\n */\n fn() {\n if (this.firstIpV4 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n /**\n * True if we know we're on an IPv6 network,\n * False if we know that we are not on an IPv6 network,\n * undefined if we are not sure\n */\n supportsIpV6: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV6 prop\n * @returns {boolean | undefined}\n */ fn() {\n if (this.firstIpV6 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n },\n\n /**\n * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions\n *\n * @private\n * @returns {boolean}\n */\n receivedOnlyMDnsCandidates() {\n return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;\n },\n\n /**\n *\n * @param {RTCPeerConnection} pc Peer connection to use\n * @private\n * @returns {Promise<void>}\n */\n async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {\n return new Promise((resolve, reject) => {\n let done = false;\n\n this.firstIpV4 = -1;\n this.firstIpV6 = -1;\n this.firstMdns = -1;\n this.totalTime = -1;\n const startTime = performance.now();\n\n const doneGatheringIceCandidates = () => {\n if (done) {\n return;\n }\n done = true;\n\n this.totalTime = performance.now() - startTime;\n\n resolve();\n };\n\n pc.onicecandidate = (event) => {\n if (event.candidate?.address) {\n if (event.candidate.address.endsWith('.local')) {\n // if we don't have camera/mic permissions, browser just gives us mDNS candidates\n if (this.firstMdns === -1) {\n this.firstMdns = performance.now() - startTime;\n }\n } else if (event.candidate.address.includes(':')) {\n if (this.firstIpV6 === -1) {\n this.firstIpV6 = performance.now() - startTime;\n }\n } else if (this.firstIpV4 === -1) {\n this.firstIpV4 = performance.now() - startTime;\n }\n\n if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {\n // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now\n resolve();\n }\n } else if (event.candidate === null) {\n doneGatheringIceCandidates();\n }\n };\n\n pc.onicegatheringstatechange = () => {\n if (pc.iceGatheringState === 'complete') {\n doneGatheringIceCandidates();\n }\n };\n\n pc.createDataChannel('data');\n\n pc.createOffer()\n .then((offer) => pc.setLocalDescription(offer))\n .catch((e) => {\n this.webex.logger.error('Failed to detect ip network version:', e);\n reject(e);\n });\n });\n },\n\n /**\n * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the\n * supportsIpV4 and supportsIpV6 props to find out the result.\n *\n * @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet\n * @returns {Promise<void>}\n */\n async detect(force = false) {\n let results;\n let pc;\n\n if (this.state === STATE.IN_PROGRESS) {\n this.pendingDetection = {force};\n\n return;\n }\n\n if (!force && this.state !== STATE.INITIAL && !this.receivedOnlyMDnsCandidates()) {\n // we already have the results, no need to do the detection again\n return;\n }\n\n try {\n this.state = STATE.IN_PROGRESS;\n\n pc = new RTCPeerConnection();\n\n results = await this.gatherLocalCandidates(pc);\n } finally {\n pc.close();\n this.state = STATE.IDLE;\n }\n\n if (this.pendingDetection) {\n const {force: forceParam} = this.pendingDetection;\n\n this.pendingDetection = undefined;\n this.detect(forceParam);\n }\n },\n});\n\nexport default IpNetworkDetector;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
26
26
|
"@webex/jest-config-legacy": "0.0.0",
|
|
27
27
|
"@webex/legacy-tools": "0.0.0",
|
|
28
|
-
"@webex/test-helper-chai": "3.
|
|
29
|
-
"@webex/test-helper-mocha": "3.
|
|
30
|
-
"@webex/test-helper-mock-webex": "3.
|
|
31
|
-
"@webex/test-helper-test-users": "3.
|
|
28
|
+
"@webex/test-helper-chai": "3.7.0-next.2",
|
|
29
|
+
"@webex/test-helper-mocha": "3.7.0-next.2",
|
|
30
|
+
"@webex/test-helper-mock-webex": "3.7.0-next.2",
|
|
31
|
+
"@webex/test-helper-test-users": "3.7.0-next.2",
|
|
32
32
|
"chai": "^4.3.4",
|
|
33
33
|
"chai-as-promised": "^7.1.1",
|
|
34
34
|
"eslint": "^8.24.0",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"sinon": "^9.2.4"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@webex/common": "3.
|
|
40
|
-
"@webex/common-timers": "3.
|
|
41
|
-
"@webex/http-core": "3.
|
|
42
|
-
"@webex/internal-plugin-metrics": "3.
|
|
43
|
-
"@webex/webex-core": "3.
|
|
39
|
+
"@webex/common": "3.7.0-next.2",
|
|
40
|
+
"@webex/common-timers": "3.7.0-next.2",
|
|
41
|
+
"@webex/http-core": "3.7.0-next.2",
|
|
42
|
+
"@webex/internal-plugin-metrics": "3.7.0-next.2",
|
|
43
|
+
"@webex/webex-core": "3.7.0-next.2",
|
|
44
44
|
"ampersand-collection": "^2.0.2",
|
|
45
45
|
"ampersand-state": "^5.0.3",
|
|
46
46
|
"lodash": "^4.17.21"
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"test:style": "eslint ./src/**/*.*",
|
|
55
55
|
"test:unit": "webex-legacy-tools test --unit --runner jest"
|
|
56
56
|
},
|
|
57
|
-
"version": "3.
|
|
57
|
+
"version": "3.7.0-next.2"
|
|
58
58
|
}
|
package/src/device.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import {deprecated, oneFlight} from '@webex/common';
|
|
3
3
|
import {persist, waitForValue, WebexPlugin} from '@webex/webex-core';
|
|
4
4
|
import {safeSetTimeout} from '@webex/common-timers';
|
|
5
|
+
import {orderBy} from 'lodash';
|
|
5
6
|
|
|
6
7
|
import METRICS from './metrics';
|
|
7
8
|
import {FEATURE_COLLECTION_NAMES, DEVICE_EVENT_REGISTRATION_SUCCESS} from './constants';
|
|
@@ -439,6 +440,74 @@ const Device = WebexPlugin.extend({
|
|
|
439
440
|
});
|
|
440
441
|
});
|
|
441
442
|
},
|
|
443
|
+
/**
|
|
444
|
+
* Fetches the web devices and deletes the third of them which are not recent devices in use
|
|
445
|
+
* @returns {Promise<void, Error>}
|
|
446
|
+
*/
|
|
447
|
+
deleteDevices() {
|
|
448
|
+
// Fetch devices with a GET request
|
|
449
|
+
return this.request({
|
|
450
|
+
method: 'GET',
|
|
451
|
+
service: 'wdm',
|
|
452
|
+
resource: 'devices',
|
|
453
|
+
})
|
|
454
|
+
.then((response) => {
|
|
455
|
+
const {devices} = response.body;
|
|
456
|
+
|
|
457
|
+
const {deviceType} = this._getBody();
|
|
458
|
+
|
|
459
|
+
// Filter devices of type deviceType
|
|
460
|
+
const webDevices = devices.filter((item) => item.deviceType === deviceType);
|
|
461
|
+
|
|
462
|
+
const sortedDevices = orderBy(webDevices, [(item) => new Date(item.modificationTime)]);
|
|
463
|
+
|
|
464
|
+
// If there are more than two devices, delete the last third
|
|
465
|
+
if (sortedDevices.length > 2) {
|
|
466
|
+
const totalItems = sortedDevices.length;
|
|
467
|
+
const countToDelete = Math.ceil(totalItems / 3);
|
|
468
|
+
const urlsToDelete = sortedDevices.slice(0, countToDelete).map((item) => item.url);
|
|
469
|
+
|
|
470
|
+
return Promise.race(
|
|
471
|
+
urlsToDelete.map((url) => {
|
|
472
|
+
return this.request({
|
|
473
|
+
uri: url,
|
|
474
|
+
method: 'DELETE',
|
|
475
|
+
});
|
|
476
|
+
})
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return Promise.resolve();
|
|
481
|
+
})
|
|
482
|
+
.catch((error) => {
|
|
483
|
+
this.logger.error('Failed to retrieve devices:', error);
|
|
484
|
+
|
|
485
|
+
return Promise.reject(error);
|
|
486
|
+
});
|
|
487
|
+
},
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Registers and when fails deletes devices
|
|
491
|
+
*/
|
|
492
|
+
@oneFlight
|
|
493
|
+
@waitForValue('@')
|
|
494
|
+
register(deviceRegistrationOptions = {}) {
|
|
495
|
+
return this._registerInternal(deviceRegistrationOptions).catch((error) => {
|
|
496
|
+
if (error?.body?.message === 'User has excessive device registrations') {
|
|
497
|
+
return this.deleteDevices().then(() => {
|
|
498
|
+
return this._registerInternal(deviceRegistrationOptions);
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
throw error;
|
|
502
|
+
});
|
|
503
|
+
},
|
|
504
|
+
|
|
505
|
+
_getBody() {
|
|
506
|
+
return {
|
|
507
|
+
...(this.config.defaults.body ? this.config.defaults.body : {}),
|
|
508
|
+
...(this.config.body ? this.config.body : {}),
|
|
509
|
+
};
|
|
510
|
+
},
|
|
442
511
|
|
|
443
512
|
/**
|
|
444
513
|
* Register or refresh a device depending on the current device state. Device
|
|
@@ -451,7 +520,7 @@ const Device = WebexPlugin.extend({
|
|
|
451
520
|
*/
|
|
452
521
|
@oneFlight
|
|
453
522
|
@waitForValue('@')
|
|
454
|
-
|
|
523
|
+
_registerInternal(deviceRegistrationOptions = {}) {
|
|
455
524
|
this.logger.info('device: registering');
|
|
456
525
|
|
|
457
526
|
this.webex.internal.newMetrics.callDiagnosticMetrics.setDeviceInfo(this);
|
|
@@ -466,10 +535,7 @@ const Device = WebexPlugin.extend({
|
|
|
466
535
|
}
|
|
467
536
|
|
|
468
537
|
// Merge body configurations, overriding defaults.
|
|
469
|
-
const body =
|
|
470
|
-
...(this.config.defaults.body ? this.config.defaults.body : {}),
|
|
471
|
-
...(this.config.body ? this.config.body : {}),
|
|
472
|
-
};
|
|
538
|
+
const body = this._getBody();
|
|
473
539
|
|
|
474
540
|
// Merge header configurations, overriding defaults.
|
|
475
541
|
const headers = {
|
|
@@ -527,7 +593,6 @@ const Device = WebexPlugin.extend({
|
|
|
527
593
|
});
|
|
528
594
|
});
|
|
529
595
|
},
|
|
530
|
-
|
|
531
596
|
/**
|
|
532
597
|
* Unregister the current registered device if available. Unregistering a
|
|
533
598
|
* device utilizes the services plugin to send the request to the **WDM**
|
package/src/ipNetworkDetector.ts
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import {WebexPlugin} from '@webex/webex-core';
|
|
6
6
|
|
|
7
|
+
const STATE = {
|
|
8
|
+
INITIAL: 'initial',
|
|
9
|
+
IN_PROGRESS: 'in-progress',
|
|
10
|
+
IDLE: 'idle',
|
|
11
|
+
};
|
|
12
|
+
|
|
7
13
|
/**
|
|
8
14
|
* @class
|
|
9
15
|
*/
|
|
@@ -17,6 +23,8 @@ const IpNetworkDetector = WebexPlugin.extend({
|
|
|
17
23
|
firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate
|
|
18
24
|
firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate
|
|
19
25
|
totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection
|
|
26
|
+
state: ['string', true, STATE.INITIAL],
|
|
27
|
+
pendingDetection: ['object', false, undefined],
|
|
20
28
|
},
|
|
21
29
|
|
|
22
30
|
derived: {
|
|
@@ -155,21 +163,41 @@ const IpNetworkDetector = WebexPlugin.extend({
|
|
|
155
163
|
* Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the
|
|
156
164
|
* supportsIpV4 and supportsIpV6 props to find out the result.
|
|
157
165
|
*
|
|
158
|
-
* @
|
|
166
|
+
* @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet
|
|
167
|
+
* @returns {Promise<void>}
|
|
159
168
|
*/
|
|
160
|
-
async detect() {
|
|
169
|
+
async detect(force = false) {
|
|
161
170
|
let results;
|
|
162
171
|
let pc;
|
|
163
172
|
|
|
173
|
+
if (this.state === STATE.IN_PROGRESS) {
|
|
174
|
+
this.pendingDetection = {force};
|
|
175
|
+
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!force && this.state !== STATE.INITIAL && !this.receivedOnlyMDnsCandidates()) {
|
|
180
|
+
// we already have the results, no need to do the detection again
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
164
184
|
try {
|
|
185
|
+
this.state = STATE.IN_PROGRESS;
|
|
186
|
+
|
|
165
187
|
pc = new RTCPeerConnection();
|
|
166
188
|
|
|
167
189
|
results = await this.gatherLocalCandidates(pc);
|
|
168
190
|
} finally {
|
|
169
191
|
pc.close();
|
|
192
|
+
this.state = STATE.IDLE;
|
|
170
193
|
}
|
|
171
194
|
|
|
172
|
-
|
|
195
|
+
if (this.pendingDetection) {
|
|
196
|
+
const {force: forceParam} = this.pendingDetection;
|
|
197
|
+
|
|
198
|
+
this.pendingDetection = undefined;
|
|
199
|
+
this.detect(forceParam);
|
|
200
|
+
}
|
|
173
201
|
},
|
|
174
202
|
});
|
|
175
203
|
|
package/test/unit/spec/device.js
CHANGED
|
@@ -357,6 +357,68 @@ describe('plugin-device', () => {
|
|
|
357
357
|
});
|
|
358
358
|
});
|
|
359
359
|
|
|
360
|
+
describe('deleteDevices()', () => {
|
|
361
|
+
const setup = (deviceType) => {
|
|
362
|
+
device.config.defaults = {body: {deviceType}};
|
|
363
|
+
};
|
|
364
|
+
['WEB', 'WEBCLIENT'].forEach(deviceType => {
|
|
365
|
+
it(`should delete correct number of devices for ${deviceType}`, async () => {
|
|
366
|
+
setup(deviceType);
|
|
367
|
+
const response = {
|
|
368
|
+
body: {
|
|
369
|
+
devices: [
|
|
370
|
+
{url: 'url3', modificationTime: '2023-10-03T10:00:00Z', deviceType},
|
|
371
|
+
{url: 'url4', modificationTime: '2023-10-04T10:00:00Z', deviceType: 'notweb'},
|
|
372
|
+
{url: 'url1', modificationTime: '2023-10-01T10:00:00Z', deviceType},
|
|
373
|
+
{url: 'url2', modificationTime: '2023-10-02T10:00:00Z', deviceType},
|
|
374
|
+
{url: 'url5', modificationTime: '2023-10-00T10:00:00Z', deviceType},
|
|
375
|
+
{url: 'url6', modificationTime: '2023-09-50T10:00:00Z', deviceType},
|
|
376
|
+
{url: 'url7', modificationTime: '2023-09-30T10:00:00Z', deviceType},
|
|
377
|
+
{url: 'url8', modificationTime: '2023-08-30T10:00:00Z', deviceType},
|
|
378
|
+
]
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
const requestStub = sinon.stub(device, 'request');
|
|
382
|
+
requestStub.withArgs(sinon.match({method: 'GET'})).resolves(response);
|
|
383
|
+
requestStub.withArgs(sinon.match({method: 'DELETE'})).resolves();
|
|
384
|
+
|
|
385
|
+
await device.deleteDevices();
|
|
386
|
+
|
|
387
|
+
const expectedDeletions = ['url8', 'url7', 'url1'];
|
|
388
|
+
|
|
389
|
+
expectedDeletions.forEach(url => {
|
|
390
|
+
assert(requestStub.calledWith(sinon.match({uri: url, method: 'DELETE'})));
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const notDeletedUrls = ['url2', 'url3', 'url5', 'url6', 'url4'];
|
|
394
|
+
notDeletedUrls.forEach(url => {
|
|
395
|
+
assert(requestStub.neverCalledWith(sinon.match({uri: url, method: 'DELETE'})));
|
|
396
|
+
});
|
|
397
|
+
});});
|
|
398
|
+
|
|
399
|
+
it('does not delete when there are just 2 devices', async () => {
|
|
400
|
+
setup('WEB');
|
|
401
|
+
const response = {
|
|
402
|
+
body: {
|
|
403
|
+
devices: [
|
|
404
|
+
{url: 'url1', modificationTime: '2023-10-01T10:00:00Z', deviceType: 'WEB'},
|
|
405
|
+
{url: 'url2', modificationTime: '2023-10-02T10:00:00Z', deviceType: 'WEB'},
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
const requestStub = sinon.stub(device, 'request');
|
|
411
|
+
requestStub.withArgs(sinon.match({method: 'GET'})).resolves(response);
|
|
412
|
+
requestStub.withArgs(sinon.match({method: 'DELETE'})).resolves();
|
|
413
|
+
|
|
414
|
+
await device.deleteDevices();
|
|
415
|
+
const notDeletedUrls = ['url1', 'url2'];
|
|
416
|
+
notDeletedUrls.forEach(url => {
|
|
417
|
+
assert(requestStub.neverCalledWith(sinon.match({uri: url, method: 'DELETE'})));
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
|
|
360
422
|
describe('#register()', () => {
|
|
361
423
|
const setup = (config = {}) => {
|
|
362
424
|
webex.internal.metrics.submitClientMetrics = sinon.stub();
|
|
@@ -386,6 +448,40 @@ describe('plugin-device', () => {
|
|
|
386
448
|
});
|
|
387
449
|
});
|
|
388
450
|
|
|
451
|
+
it('calls delete devices when errors with User has excessive device registrations', async () => {
|
|
452
|
+
setup();
|
|
453
|
+
const deleteDeviceSpy = sinon.stub(device, 'deleteDevices').callsFake(() => Promise.resolve());
|
|
454
|
+
const registerStub = sinon.stub(device, '_registerInternal');
|
|
455
|
+
|
|
456
|
+
registerStub.onFirstCall().rejects({body: {message: 'User has excessive device registrations'}});
|
|
457
|
+
registerStub.onSecondCall().callsFake(() => Promise.resolve({exampleKey: 'example response value',}));
|
|
458
|
+
|
|
459
|
+
const result = await device.register();
|
|
460
|
+
|
|
461
|
+
assert.calledOnce(deleteDeviceSpy);
|
|
462
|
+
|
|
463
|
+
assert.equal(registerStub.callCount, 2);
|
|
464
|
+
|
|
465
|
+
assert.deepEqual(result, {exampleKey: 'example response value'});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it('does not call delete devices when some other error', async () => {
|
|
469
|
+
setup();
|
|
470
|
+
|
|
471
|
+
const deleteDeviceSpy = sinon.stub(device, 'deleteDevices').callsFake(() => Promise.resolve());
|
|
472
|
+
const registerStub = sinon.stub(device, '_registerInternal').rejects(new Error('some error'));
|
|
473
|
+
|
|
474
|
+
try {
|
|
475
|
+
await device.register({deleteFlag: true});
|
|
476
|
+
} catch (error) {
|
|
477
|
+
assert.notCalled(deleteDeviceSpy);
|
|
478
|
+
|
|
479
|
+
assert.equal(registerStub.callCount, 1);
|
|
480
|
+
|
|
481
|
+
assert.match(error.message, /some error/, 'Expected error message not matched');
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
|
|
389
485
|
it('checks that submitInternalEvent gets called with internal.register.device.response on error', async () => {
|
|
390
486
|
setup();
|
|
391
487
|
sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
|
|
@@ -3,6 +3,8 @@ import sinon from 'sinon';
|
|
|
3
3
|
import IpNetworkDetector from '@webex/internal-plugin-device/src/ipNetworkDetector';
|
|
4
4
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
5
5
|
|
|
6
|
+
const flushPromises = () => new Promise(setImmediate);
|
|
7
|
+
|
|
6
8
|
describe('plugin-device', () => {
|
|
7
9
|
describe('IpNetworkDetector', () => {
|
|
8
10
|
let webex;
|
|
@@ -326,7 +328,7 @@ describe('plugin-device', () => {
|
|
|
326
328
|
});
|
|
327
329
|
|
|
328
330
|
// now call detect() again
|
|
329
|
-
const promise2 = ipNetworkDetector.detect();
|
|
331
|
+
const promise2 = ipNetworkDetector.detect(true);
|
|
330
332
|
|
|
331
333
|
// everything should have been reset
|
|
332
334
|
assert.equal(ipNetworkDetector.supportsIpV4, undefined);
|
|
@@ -340,6 +342,87 @@ describe('plugin-device', () => {
|
|
|
340
342
|
await promise2;
|
|
341
343
|
});
|
|
342
344
|
|
|
345
|
+
it('queues another detect() call if one is already in progress', async () => {
|
|
346
|
+
const promise = ipNetworkDetector.detect();
|
|
347
|
+
|
|
348
|
+
simulateCandidate(50, '192.168.0.1');
|
|
349
|
+
|
|
350
|
+
await flushPromises();
|
|
351
|
+
|
|
352
|
+
assert.calledOnce(fakePeerConnection.createDataChannel);
|
|
353
|
+
assert.calledOnce(fakePeerConnection.createOffer);
|
|
354
|
+
assert.calledOnce(fakePeerConnection.setLocalDescription);
|
|
355
|
+
|
|
356
|
+
// now call detect() again
|
|
357
|
+
ipNetworkDetector.detect(true);
|
|
358
|
+
|
|
359
|
+
// simulate the end of the detection -> another one should be started
|
|
360
|
+
simulateEndOfCandidateGathering(10);
|
|
361
|
+
|
|
362
|
+
await promise;
|
|
363
|
+
|
|
364
|
+
assert.calledTwice(fakePeerConnection.createDataChannel);
|
|
365
|
+
assert.calledTwice(fakePeerConnection.createOffer);
|
|
366
|
+
assert.calledTwice(fakePeerConnection.setLocalDescription);
|
|
367
|
+
|
|
368
|
+
simulateCandidate(50, '2a02:c7c:a0d0:8a00:db9b:d4de:d1f7:4c49');
|
|
369
|
+
simulateEndOfCandidateGathering(10);
|
|
370
|
+
|
|
371
|
+
// results should reflect the last run detection
|
|
372
|
+
checkResults({
|
|
373
|
+
supportsIpV4: false,
|
|
374
|
+
supportsIpV6: true,
|
|
375
|
+
timings: {
|
|
376
|
+
totalTime: 60,
|
|
377
|
+
ipv4: -1,
|
|
378
|
+
ipv6: 50,
|
|
379
|
+
mdns: -1,
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
await flushPromises();
|
|
384
|
+
|
|
385
|
+
// no more detections should be started
|
|
386
|
+
assert.calledTwice(fakePeerConnection.createDataChannel);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it.each`
|
|
390
|
+
force | state | receivedOnlyMDnsCandidates | expectedToRunDetection
|
|
391
|
+
${true} | ${'initial'} | ${false} | ${true}
|
|
392
|
+
${true} | ${'idle'} | ${false} | ${true}
|
|
393
|
+
${true} | ${'initial'} | ${true} | ${true}
|
|
394
|
+
${true} | ${'idle'} | ${true} | ${true}
|
|
395
|
+
${false} | ${'initial'} | ${false} | ${true}
|
|
396
|
+
${false} | ${'initial'} | ${true} | ${true}
|
|
397
|
+
${false} | ${'idle'} | ${true} | ${true}
|
|
398
|
+
${false} | ${'idle'} | ${false} | ${false}
|
|
399
|
+
`(
|
|
400
|
+
'force=$force, state=$state, receivedOnlyMDnsCandidates=$receivedOnlyMDnsCandidates => expectedToRunDetection=$expectedToRunDetection',
|
|
401
|
+
async ({force, state, receivedOnlyMDnsCandidates, expectedToRunDetection}) => {
|
|
402
|
+
ipNetworkDetector.state = state;
|
|
403
|
+
sinon
|
|
404
|
+
.stub(ipNetworkDetector, 'receivedOnlyMDnsCandidates')
|
|
405
|
+
.returns(receivedOnlyMDnsCandidates);
|
|
406
|
+
|
|
407
|
+
const result = ipNetworkDetector.detect(force);
|
|
408
|
+
|
|
409
|
+
if (expectedToRunDetection) {
|
|
410
|
+
simulateEndOfCandidateGathering(10);
|
|
411
|
+
}
|
|
412
|
+
await result;
|
|
413
|
+
|
|
414
|
+
if (expectedToRunDetection) {
|
|
415
|
+
assert.calledOnce(fakePeerConnection.createDataChannel);
|
|
416
|
+
assert.calledOnce(fakePeerConnection.createOffer);
|
|
417
|
+
assert.calledOnce(fakePeerConnection.setLocalDescription);
|
|
418
|
+
} else {
|
|
419
|
+
assert.notCalled(fakePeerConnection.createDataChannel);
|
|
420
|
+
assert.notCalled(fakePeerConnection.createOffer);
|
|
421
|
+
assert.notCalled(fakePeerConnection.setLocalDescription);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
|
|
343
426
|
it('rejects if one of RTCPeerConnection operations fails', async () => {
|
|
344
427
|
const fakeError = new Error('fake error');
|
|
345
428
|
|