@webex/internal-plugin-device 2.60.0 → 2.60.1-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,15 +13,17 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpe
13
13
  var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
14
14
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
15
15
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
16
- var _set2 = _interopRequireDefault(require("lodash/set"));
17
16
  var _httpCore = require("@webex/http-core");
17
+ var _lodash = require("lodash");
18
18
  var _constants = require("../constants");
19
19
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
20
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
20
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /*!
21
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
22
+ */
21
23
  /**
22
24
  * Adds 'cisco-device-url' header, as appropriate, to requests
23
25
  */
24
- var DeviceUrlInterceptor = /*#__PURE__*/function (_Interceptor) {
26
+ var DeviceUrlInterceptor = exports.default = /*#__PURE__*/function (_Interceptor) {
25
27
  (0, _inherits2.default)(DeviceUrlInterceptor, _Interceptor);
26
28
  var _super = _createSuper(DeviceUrlInterceptor);
27
29
  function DeviceUrlInterceptor() {
@@ -62,7 +64,7 @@ var DeviceUrlInterceptor = /*#__PURE__*/function (_Interceptor) {
62
64
  // Check if service is not one of the invalid services
63
65
  // Assign the url to the device header
64
66
  if (serviceName && !invalidServices.includes(serviceName)) {
65
- (0, _set2.default)(options, "headers['".concat(_constants.CISCO_DEVICE_URL, "']"), device.url);
67
+ (0, _lodash.set)(options, "headers['".concat(_constants.CISCO_DEVICE_URL, "']"), device.url);
66
68
  }
67
69
  return options;
68
70
  }).catch(function (error) {
@@ -88,5 +90,4 @@ var DeviceUrlInterceptor = /*#__PURE__*/function (_Interceptor) {
88
90
  }]);
89
91
  return DeviceUrlInterceptor;
90
92
  }(_httpCore.Interceptor);
91
- exports.default = DeviceUrlInterceptor;
92
93
  //# sourceMappingURL=device-url.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_httpCore","require","_constants","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","DeviceUrlInterceptor","_Interceptor","_inherits2","_super","_classCallCheck2","_createClass2","key","value","onRequest","options","headers","service","uri","_this$webex$internal","webex","internal","device","services","url","CISCO_DEVICE_URL","_promise","resolve","waitForService","then","_ref","getServiceFromUrl","serviceName","name","invalidServices","includes","_set2","concat","catch","error","message","match","reject","create","Interceptor","exports"],"sources":["device-url.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Interceptor} from '@webex/http-core';\nimport {set} from 'lodash';\n\nimport {CISCO_DEVICE_URL} from '../constants';\n\n/**\n * Adds 'cisco-device-url' header, as appropriate, to requests\n */\nexport default class DeviceUrlInterceptor extends Interceptor {\n /**\n * @returns {DeviceUrlInterceptor}\n */\n static create() {\n /* eslint no-invalid-this: [0] */\n return new DeviceUrlInterceptor({webex: this});\n }\n\n /**\n * @see Interceptor#onRequest\n * @param {Object} options\n * @returns {Object}\n */\n onRequest(options) {\n const {headers, service, uri} = options;\n const {device, services} = this.webex.internal;\n\n // Check if header is already set before moving forward\n if (!device.url || (headers && CISCO_DEVICE_URL in headers && !!headers[CISCO_DEVICE_URL])) {\n return Promise.resolve(options);\n }\n\n // Wait for catalog and service to be defined.\n return services\n .waitForService({service, url: uri})\n .then((url) => {\n // Grab the service name with the url returned from waitForService\n const {name: serviceName} = services.getServiceFromUrl(url) || {};\n const invalidServices = ['idbroker', 'oauth', 'saml'];\n\n // Check if service is not one of the invalid services\n // Assign the url to the device header\n if (serviceName && !invalidServices.includes(serviceName)) {\n set(options, `headers['${CISCO_DEVICE_URL}']`, device.url);\n }\n\n return options;\n })\n .catch((error) => {\n // Validate that the error came from getServiceFromUrl\n if (error.message.match(/was not found after waiting/)) {\n return options;\n }\n\n return Promise.reject(error);\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_httpCore","require","_lodash","_constants","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","DeviceUrlInterceptor","exports","_Interceptor","_inherits2","_super","_classCallCheck2","_createClass2","key","value","onRequest","options","headers","service","uri","_this$webex$internal","webex","internal","device","services","url","CISCO_DEVICE_URL","_promise","resolve","waitForService","then","_ref","getServiceFromUrl","serviceName","name","invalidServices","includes","set","concat","catch","error","message","match","reject","create","Interceptor"],"sources":["device-url.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Interceptor} from '@webex/http-core';\nimport {set} from 'lodash';\n\nimport {CISCO_DEVICE_URL} from '../constants';\n\n/**\n * Adds 'cisco-device-url' header, as appropriate, to requests\n */\nexport default class DeviceUrlInterceptor extends Interceptor {\n /**\n * @returns {DeviceUrlInterceptor}\n */\n static create() {\n /* eslint no-invalid-this: [0] */\n return new DeviceUrlInterceptor({webex: this});\n }\n\n /**\n * @see Interceptor#onRequest\n * @param {Object} options\n * @returns {Object}\n */\n onRequest(options) {\n const {headers, service, uri} = options;\n const {device, services} = this.webex.internal;\n\n // Check if header is already set before moving forward\n if (!device.url || (headers && CISCO_DEVICE_URL in headers && !!headers[CISCO_DEVICE_URL])) {\n return Promise.resolve(options);\n }\n\n // Wait for catalog and service to be defined.\n return services\n .waitForService({service, url: uri})\n .then((url) => {\n // Grab the service name with the url returned from waitForService\n const {name: serviceName} = services.getServiceFromUrl(url) || {};\n const invalidServices = ['idbroker', 'oauth', 'saml'];\n\n // Check if service is not one of the invalid services\n // Assign the url to the device header\n if (serviceName && !invalidServices.includes(serviceName)) {\n set(options, `headers['${CISCO_DEVICE_URL}']`, device.url);\n }\n\n return options;\n })\n .catch((error) => {\n // Validate that the error came from getServiceFromUrl\n if (error.message.match(/was not found after waiting/)) {\n return options;\n }\n\n return Promise.reject(error);\n });\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+
3
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
5
+ _Object$defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
10
+ var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
11
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
12
+ var _webexCore = require("@webex/webex-core");
13
+ /*!
14
+ * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.
15
+ */
16
+
17
+ /**
18
+ * @class
19
+ */
20
+ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
21
+ idAttribute: 'IpNetworkDetectorId',
22
+ namespace: 'Device',
23
+ props: {
24
+ firstIpV4: ['number', true, -1],
25
+ // time [ms] it took to receive first IPv4 candidate
26
+ firstIpV6: ['number', true, -1],
27
+ // time [ms] it took to receive first IPv6 candidate
28
+ firstMdns: ['number', true, -1],
29
+ // time [ms] it took to receive first mDNS candidate
30
+ totalTime: ['number', true, -1] // total time [ms] it took to do the last IP network detection
31
+ },
32
+
33
+ derived: {
34
+ /**
35
+ * True if we know we're on an IPv4 network,
36
+ * False if we know that we are not on an IPv4 network,
37
+ * undefined if we are not sure
38
+ */
39
+ supportsIpV4: {
40
+ deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],
41
+ /**
42
+ * Function for calculating the value of supportsIpV4 prop
43
+ * @returns {boolean | undefined}
44
+ */
45
+ fn: function fn() {
46
+ if (this.firstIpV4 >= 0) {
47
+ return true;
48
+ }
49
+ if (this.totalTime < 0) {
50
+ // we haven't completed the detection, yet
51
+ return undefined;
52
+ }
53
+ if (this.receivedOnlyMDnsCandidates()) {
54
+ return undefined;
55
+ }
56
+ return false;
57
+ }
58
+ },
59
+ /**
60
+ * True if we know we're on an IPv6 network,
61
+ * False if we know that we are not on an IPv6 network,
62
+ * undefined if we are not sure
63
+ */
64
+ supportsIpV6: {
65
+ deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],
66
+ /**
67
+ * Function for calculating the value of supportsIpV6 prop
68
+ * @returns {boolean | undefined}
69
+ */
70
+ fn: function fn() {
71
+ if (this.firstIpV6 >= 0) {
72
+ return true;
73
+ }
74
+ if (this.totalTime < 0) {
75
+ // we haven't completed the detection, yet
76
+ return undefined;
77
+ }
78
+ if (this.receivedOnlyMDnsCandidates()) {
79
+ return undefined;
80
+ }
81
+ return false;
82
+ }
83
+ }
84
+ },
85
+ /**
86
+ * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions
87
+ *
88
+ * @private
89
+ * @returns {boolean}
90
+ */
91
+ receivedOnlyMDnsCandidates: function receivedOnlyMDnsCandidates() {
92
+ return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;
93
+ },
94
+ /**
95
+ *
96
+ * @param {RTCPeerConnection} pc Peer connection to use
97
+ * @private
98
+ * @returns {Promise<void>}
99
+ */
100
+ gatherLocalCandidates: function gatherLocalCandidates(pc) {
101
+ var _this = this;
102
+ return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
103
+ return _regenerator.default.wrap(function _callee$(_context) {
104
+ while (1) switch (_context.prev = _context.next) {
105
+ case 0:
106
+ return _context.abrupt("return", new _promise.default(function (resolve, reject) {
107
+ var done = false;
108
+ _this.firstIpV4 = -1;
109
+ _this.firstIpV6 = -1;
110
+ _this.firstMdns = -1;
111
+ _this.totalTime = -1;
112
+ var startTime = performance.now();
113
+ var doneGatheringIceCandidates = function doneGatheringIceCandidates() {
114
+ if (done) {
115
+ return;
116
+ }
117
+ done = true;
118
+ _this.totalTime = performance.now() - startTime;
119
+ resolve();
120
+ };
121
+ pc.onicecandidate = function (event) {
122
+ var _event$candidate;
123
+ if ((_event$candidate = event.candidate) !== null && _event$candidate !== void 0 && _event$candidate.address) {
124
+ if (event.candidate.address.endsWith('.local')) {
125
+ // if we don't have camera/mic permissions, browser just gives us mDNS candidates
126
+ if (_this.firstMdns === -1) {
127
+ _this.firstMdns = performance.now() - startTime;
128
+ }
129
+ } else if (event.candidate.address.includes(':')) {
130
+ if (_this.firstIpV6 === -1) {
131
+ _this.firstIpV6 = performance.now() - startTime;
132
+ }
133
+ } else if (_this.firstIpV4 === -1) {
134
+ _this.firstIpV4 = performance.now() - startTime;
135
+ }
136
+ if (_this.firstIpV4 >= 0 && _this.firstIpV6 >= 0) {
137
+ // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now
138
+ resolve();
139
+ }
140
+ } else if (event.candidate === null) {
141
+ doneGatheringIceCandidates();
142
+ }
143
+ };
144
+ pc.onicegatheringstatechange = function () {
145
+ if (pc.iceGatheringState === 'complete') {
146
+ doneGatheringIceCandidates();
147
+ }
148
+ };
149
+ pc.createDataChannel('data');
150
+ pc.createOffer().then(function (offer) {
151
+ return pc.setLocalDescription(offer);
152
+ }).catch(function (e) {
153
+ _this.webex.logger.error('Failed to detect ip network version:', e);
154
+ reject(e);
155
+ });
156
+ }));
157
+ case 1:
158
+ case "end":
159
+ return _context.stop();
160
+ }
161
+ }, _callee);
162
+ }))();
163
+ },
164
+ /**
165
+ * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the
166
+ * supportsIpV4 and supportsIpV6 props to find out the result.
167
+ *
168
+ * @returns {Promise<Object>}
169
+ */
170
+ detect: function detect() {
171
+ var _this2 = this;
172
+ return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
173
+ var results, pc;
174
+ return _regenerator.default.wrap(function _callee2$(_context2) {
175
+ while (1) switch (_context2.prev = _context2.next) {
176
+ case 0:
177
+ _context2.prev = 0;
178
+ pc = new RTCPeerConnection();
179
+ _context2.next = 4;
180
+ return _this2.gatherLocalCandidates(pc);
181
+ case 4:
182
+ results = _context2.sent;
183
+ case 5:
184
+ _context2.prev = 5;
185
+ pc.close();
186
+ return _context2.finish(5);
187
+ case 8:
188
+ return _context2.abrupt("return", results);
189
+ case 9:
190
+ case "end":
191
+ return _context2.stop();
192
+ }
193
+ }, _callee2, null, [[0,, 5, 8]]);
194
+ }))();
195
+ },
196
+ version: "2.60.1-next.10"
197
+ });
198
+ var _default = exports.default = IpNetworkDetector;
199
+ //# sourceMappingURL=ipNetworkDetector.js.map
@@ -0,0 +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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"}
package/dist/metrics.js CHANGED
@@ -6,9 +6,8 @@ _Object$defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = void 0;
8
8
  // Metric to do with WDM registration
9
- var _default = {
9
+ var _default = exports.default = {
10
10
  JS_SDK_WDM_REGISTRATION_SUCCESSFUL: 'JS_SDK_WDM_REGISTRATION_SUCCESSFUL',
11
11
  JS_SDK_WDM_REGISTRATION_FAILED: 'JS_SDK_WDM_REGISTRATION_FAILED'
12
12
  };
13
- exports.default = _default;
14
13
  //# sourceMappingURL=metrics.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_default","JS_SDK_WDM_REGISTRATION_SUCCESSFUL","JS_SDK_WDM_REGISTRATION_FAILED","exports","default"],"sources":["metrics.js"],"sourcesContent":["// Metric to do with WDM registration\nexport default {\n JS_SDK_WDM_REGISTRATION_SUCCESSFUL: 'JS_SDK_WDM_REGISTRATION_SUCCESSFUL',\n JS_SDK_WDM_REGISTRATION_FAILED: 'JS_SDK_WDM_REGISTRATION_FAILED',\n};\n"],"mappings":";;;;;;;AAAA;AAAA,IAAAA,QAAA,GACe;EACbC,kCAAkC,EAAE,oCAAoC;EACxEC,8BAA8B,EAAE;AAClC,CAAC;AAAAC,OAAA,CAAAC,OAAA,GAAAJ,QAAA"}
1
+ {"version":3,"names":["_default","exports","default","JS_SDK_WDM_REGISTRATION_SUCCESSFUL","JS_SDK_WDM_REGISTRATION_FAILED"],"sources":["metrics.js"],"sourcesContent":["// Metric to do with WDM registration\nexport default {\n JS_SDK_WDM_REGISTRATION_SUCCESSFUL: 'JS_SDK_WDM_REGISTRATION_SUCCESSFUL',\n JS_SDK_WDM_REGISTRATION_FAILED: 'JS_SDK_WDM_REGISTRATION_FAILED',\n};\n"],"mappings":";;;;;;;AAAA;AAAA,IAAAA,QAAA,GAAAC,OAAA,CAAAC,OAAA,GACe;EACbC,kCAAkC,EAAE,oCAAoC;EACxEC,8BAA8B,EAAE;AAClC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-device",
3
- "version": "2.60.0",
4
3
  "description": "",
5
4
  "license": "MIT",
6
5
  "author": "Timothy Scheuering <timsch@cisco.com>",
@@ -12,7 +11,7 @@
12
11
  "directory": "packages/@webex/internal-plugin-device"
13
12
  },
14
13
  "engines": {
15
- "node": ">=14"
14
+ "node": ">=16"
16
15
  },
17
16
  "browserify": {
18
17
  "transform": [
@@ -22,14 +21,14 @@
22
21
  },
23
22
  "devDependencies": {
24
23
  "@babel/core": "^7.17.10",
25
- "@webex/babel-config-legacy": "2.60.0",
26
- "@webex/eslint-config-legacy": "2.60.0",
27
- "@webex/jest-config-legacy": "2.60.0",
28
- "@webex/legacy-tools": "2.60.0",
29
- "@webex/test-helper-chai": "2.60.0",
30
- "@webex/test-helper-mocha": "2.60.0",
31
- "@webex/test-helper-mock-webex": "2.60.0",
32
- "@webex/test-helper-test-users": "2.60.0",
24
+ "@webex/babel-config-legacy": "0.0.0",
25
+ "@webex/eslint-config-legacy": "0.0.0",
26
+ "@webex/jest-config-legacy": "0.0.0",
27
+ "@webex/legacy-tools": "0.0.0",
28
+ "@webex/test-helper-chai": "2.60.1-next.10",
29
+ "@webex/test-helper-mocha": "2.60.1-next.10",
30
+ "@webex/test-helper-mock-webex": "2.60.1-next.10",
31
+ "@webex/test-helper-test-users": "2.60.1-next.10",
33
32
  "chai": "^4.3.4",
34
33
  "chai-as-promised": "^7.1.1",
35
34
  "eslint": "^8.24.0",
@@ -37,11 +36,11 @@
37
36
  "sinon": "^9.2.4"
38
37
  },
39
38
  "dependencies": {
40
- "@webex/common": "2.60.0",
41
- "@webex/common-timers": "2.60.0",
42
- "@webex/http-core": "2.60.0",
43
- "@webex/internal-plugin-metrics": "2.60.0",
44
- "@webex/webex-core": "2.60.0",
39
+ "@webex/common": "2.60.1-next.10",
40
+ "@webex/common-timers": "2.60.1-next.10",
41
+ "@webex/http-core": "2.60.1-next.10",
42
+ "@webex/internal-plugin-metrics": "2.60.1-next.10",
43
+ "@webex/webex-core": "2.60.1-next.10",
45
44
  "ampersand-collection": "^2.0.2",
46
45
  "ampersand-state": "^5.0.3",
47
46
  "lodash": "^4.17.21"
@@ -49,10 +48,12 @@
49
48
  "scripts": {
50
49
  "build": "yarn build:src",
51
50
  "build:src": "webex-legacy-tools build -dest \"./dist\" -src \"./src\" -js -ts -maps",
51
+ "deploy:npm": "yarn npm publish",
52
52
  "test": "yarn test:style && yarn test:unit && yarn test:integration && yarn test:browser",
53
- "test:browser": "webex-legacy-tools test --integration --unit --runner karma",
53
+ "test:browser:broken": "webex-legacy-tools test --integration --unit --runner karma",
54
54
  "test:integration": "webex-legacy-tools test --integration --runner mocha",
55
55
  "test:style": "eslint ./src/**/*.*",
56
56
  "test:unit": "webex-legacy-tools test --unit --runner jest"
57
- }
58
- }
57
+ },
58
+ "version": "2.60.1-next.10"
59
+ }
package/src/device.js CHANGED
@@ -6,6 +6,7 @@ import {safeSetTimeout} from '@webex/common-timers';
6
6
  import METRICS from './metrics';
7
7
  import {FEATURE_COLLECTION_NAMES, DEVICE_EVENT_REGISTRATION_SUCCESS} from './constants';
8
8
  import FeaturesModel from './features/features-model';
9
+ import IpNetworkDetector from './ipNetworkDetector';
9
10
 
10
11
  /**
11
12
  * Determine if the plugin should be initialized based on cached storage.
@@ -34,6 +35,12 @@ const Device = WebexPlugin.extend({
34
35
  * @type {FeaturesModel}
35
36
  */
36
37
  features: FeaturesModel,
38
+ /**
39
+ * Helper class for detecting what IP network version (ipv4, ipv6) we're on.
40
+ *
41
+ * @type {IpNetworkDetector}
42
+ */
43
+ ipNetworkDetector: IpNetworkDetector,
37
44
  },
38
45
 
39
46
  /**
@@ -444,6 +451,9 @@ const Device = WebexPlugin.extend({
444
451
  if (this.config.ephemeral) {
445
452
  body.ttl = this.config.ephemeralDeviceTTL;
446
453
  }
454
+ this.webex.internal.newMetrics.submitInternalEvent({
455
+ name: 'internal.register.device.request',
456
+ });
447
457
 
448
458
  // This will be replaced by a `create()` method.
449
459
  return this.request({
@@ -453,7 +463,19 @@ const Device = WebexPlugin.extend({
453
463
  body,
454
464
  headers,
455
465
  })
466
+ .catch((error) => {
467
+ this.webex.internal.newMetrics.submitInternalEvent({
468
+ name: 'internal.register.device.response',
469
+ });
470
+
471
+ throw error;
472
+ })
456
473
  .then((response) => {
474
+ // Do not add any processing of response above this as that will affect timestamp
475
+ this.webex.internal.newMetrics.submitInternalEvent({
476
+ name: 'internal.register.device.response',
477
+ });
478
+
457
479
  this.webex.internal.metrics.submitClientMetrics(
458
480
  METRICS.JS_SDK_WDM_REGISTRATION_SUCCESSFUL
459
481
  );
@@ -0,0 +1,176 @@
1
+ /*!
2
+ * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import {WebexPlugin} from '@webex/webex-core';
6
+
7
+ /**
8
+ * @class
9
+ */
10
+ const IpNetworkDetector = WebexPlugin.extend({
11
+ idAttribute: 'IpNetworkDetectorId',
12
+
13
+ namespace: 'Device',
14
+
15
+ props: {
16
+ firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate
17
+ firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate
18
+ firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate
19
+ totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection
20
+ },
21
+
22
+ derived: {
23
+ /**
24
+ * True if we know we're on an IPv4 network,
25
+ * False if we know that we are not on an IPv4 network,
26
+ * undefined if we are not sure
27
+ */
28
+ supportsIpV4: {
29
+ deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],
30
+ /**
31
+ * Function for calculating the value of supportsIpV4 prop
32
+ * @returns {boolean | undefined}
33
+ */
34
+ fn() {
35
+ if (this.firstIpV4 >= 0) {
36
+ return true;
37
+ }
38
+ if (this.totalTime < 0) {
39
+ // we haven't completed the detection, yet
40
+ return undefined;
41
+ }
42
+ if (this.receivedOnlyMDnsCandidates()) {
43
+ return undefined;
44
+ }
45
+
46
+ return false;
47
+ },
48
+ },
49
+ /**
50
+ * True if we know we're on an IPv6 network,
51
+ * False if we know that we are not on an IPv6 network,
52
+ * undefined if we are not sure
53
+ */
54
+ supportsIpV6: {
55
+ deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],
56
+ /**
57
+ * Function for calculating the value of supportsIpV6 prop
58
+ * @returns {boolean | undefined}
59
+ */ fn() {
60
+ if (this.firstIpV6 >= 0) {
61
+ return true;
62
+ }
63
+ if (this.totalTime < 0) {
64
+ // we haven't completed the detection, yet
65
+ return undefined;
66
+ }
67
+ if (this.receivedOnlyMDnsCandidates()) {
68
+ return undefined;
69
+ }
70
+
71
+ return false;
72
+ },
73
+ },
74
+ },
75
+
76
+ /**
77
+ * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions
78
+ *
79
+ * @private
80
+ * @returns {boolean}
81
+ */
82
+ receivedOnlyMDnsCandidates() {
83
+ return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;
84
+ },
85
+
86
+ /**
87
+ *
88
+ * @param {RTCPeerConnection} pc Peer connection to use
89
+ * @private
90
+ * @returns {Promise<void>}
91
+ */
92
+ async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {
93
+ return new Promise((resolve, reject) => {
94
+ let done = false;
95
+
96
+ this.firstIpV4 = -1;
97
+ this.firstIpV6 = -1;
98
+ this.firstMdns = -1;
99
+ this.totalTime = -1;
100
+ const startTime = performance.now();
101
+
102
+ const doneGatheringIceCandidates = () => {
103
+ if (done) {
104
+ return;
105
+ }
106
+ done = true;
107
+
108
+ this.totalTime = performance.now() - startTime;
109
+
110
+ resolve();
111
+ };
112
+
113
+ pc.onicecandidate = (event) => {
114
+ if (event.candidate?.address) {
115
+ if (event.candidate.address.endsWith('.local')) {
116
+ // if we don't have camera/mic permissions, browser just gives us mDNS candidates
117
+ if (this.firstMdns === -1) {
118
+ this.firstMdns = performance.now() - startTime;
119
+ }
120
+ } else if (event.candidate.address.includes(':')) {
121
+ if (this.firstIpV6 === -1) {
122
+ this.firstIpV6 = performance.now() - startTime;
123
+ }
124
+ } else if (this.firstIpV4 === -1) {
125
+ this.firstIpV4 = performance.now() - startTime;
126
+ }
127
+
128
+ if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {
129
+ // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now
130
+ resolve();
131
+ }
132
+ } else if (event.candidate === null) {
133
+ doneGatheringIceCandidates();
134
+ }
135
+ };
136
+
137
+ pc.onicegatheringstatechange = () => {
138
+ if (pc.iceGatheringState === 'complete') {
139
+ doneGatheringIceCandidates();
140
+ }
141
+ };
142
+
143
+ pc.createDataChannel('data');
144
+
145
+ pc.createOffer()
146
+ .then((offer) => pc.setLocalDescription(offer))
147
+ .catch((e) => {
148
+ this.webex.logger.error('Failed to detect ip network version:', e);
149
+ reject(e);
150
+ });
151
+ });
152
+ },
153
+
154
+ /**
155
+ * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the
156
+ * supportsIpV4 and supportsIpV6 props to find out the result.
157
+ *
158
+ * @returns {Promise<Object>}
159
+ */
160
+ async detect() {
161
+ let results;
162
+ let pc;
163
+
164
+ try {
165
+ pc = new RTCPeerConnection();
166
+
167
+ results = await this.gatherLocalCandidates(pc);
168
+ } finally {
169
+ pc.close();
170
+ }
171
+
172
+ return results;
173
+ },
174
+ });
175
+
176
+ export default IpNetworkDetector;