@webex/webex-core 2.59.2 → 2.59.3-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -6
- package/README.md +79 -79
- package/babel.config.js +3 -3
- package/dist/config.js +24 -24
- package/dist/config.js.map +1 -1
- package/dist/credentials-config.js +56 -56
- package/dist/credentials-config.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/auth.js +28 -28
- package/dist/interceptors/auth.js.map +1 -1
- package/dist/interceptors/default-options.js +24 -24
- package/dist/interceptors/default-options.js.map +1 -1
- package/dist/interceptors/embargo.js +9 -9
- package/dist/interceptors/embargo.js.map +1 -1
- package/dist/interceptors/network-timing.js +19 -19
- package/dist/interceptors/network-timing.js.map +1 -1
- package/dist/interceptors/payload-transformer.js +19 -19
- package/dist/interceptors/payload-transformer.js.map +1 -1
- package/dist/interceptors/rate-limit.js +40 -40
- package/dist/interceptors/rate-limit.js.map +1 -1
- package/dist/interceptors/redirect.js +13 -13
- package/dist/interceptors/redirect.js.map +1 -1
- package/dist/interceptors/request-event.js +23 -23
- package/dist/interceptors/request-event.js.map +1 -1
- package/dist/interceptors/request-logger.js +13 -13
- package/dist/interceptors/request-logger.js.map +1 -1
- package/dist/interceptors/request-timing.js +23 -23
- package/dist/interceptors/request-timing.js.map +1 -1
- package/dist/interceptors/response-logger.js +19 -19
- package/dist/interceptors/response-logger.js.map +1 -1
- package/dist/interceptors/user-agent.js +29 -29
- package/dist/interceptors/user-agent.js.map +1 -1
- package/dist/interceptors/webex-tracking-id.js +15 -15
- package/dist/interceptors/webex-tracking-id.js.map +1 -1
- package/dist/interceptors/webex-user-agent.js +13 -13
- package/dist/interceptors/webex-user-agent.js.map +1 -1
- package/dist/lib/batcher.js +83 -83
- package/dist/lib/batcher.js.map +1 -1
- package/dist/lib/credentials/credentials.js +103 -103
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/grant-errors.js +17 -17
- package/dist/lib/credentials/grant-errors.js.map +1 -1
- package/dist/lib/credentials/index.js +2 -2
- package/dist/lib/credentials/index.js.map +1 -1
- package/dist/lib/credentials/scope.js +11 -11
- package/dist/lib/credentials/scope.js.map +1 -1
- package/dist/lib/credentials/token-collection.js +2 -2
- package/dist/lib/credentials/token-collection.js.map +1 -1
- package/dist/lib/credentials/token.js +145 -145
- package/dist/lib/credentials/token.js.map +1 -1
- package/dist/lib/page.js +49 -49
- package/dist/lib/page.js.map +1 -1
- package/dist/lib/services/constants.js.map +1 -1
- package/dist/lib/services/index.js +2 -2
- package/dist/lib/services/index.js.map +1 -1
- package/dist/lib/services/interceptors/server-error.js +9 -9
- package/dist/lib/services/interceptors/server-error.js.map +1 -1
- package/dist/lib/services/interceptors/service.js +24 -24
- package/dist/lib/services/interceptors/service.js.map +1 -1
- package/dist/lib/services/metrics.js.map +1 -1
- package/dist/lib/services/service-catalog.js +104 -104
- package/dist/lib/services/service-catalog.js.map +1 -1
- package/dist/lib/services/service-fed-ramp.js.map +1 -1
- package/dist/lib/services/service-host.js +134 -134
- package/dist/lib/services/service-host.js.map +1 -1
- package/dist/lib/services/service-registry.js +175 -175
- package/dist/lib/services/service-registry.js.map +1 -1
- package/dist/lib/services/service-state.js +38 -38
- package/dist/lib/services/service-state.js.map +1 -1
- package/dist/lib/services/service-url.js +31 -31
- package/dist/lib/services/service-url.js.map +1 -1
- package/dist/lib/services/services.js +245 -245
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/stateless-webex-plugin.js +28 -28
- package/dist/lib/stateless-webex-plugin.js.map +1 -1
- package/dist/lib/storage/decorators.js +27 -27
- package/dist/lib/storage/decorators.js.map +1 -1
- package/dist/lib/storage/errors.js +4 -4
- package/dist/lib/storage/errors.js.map +1 -1
- package/dist/lib/storage/index.js.map +1 -1
- package/dist/lib/storage/make-webex-plugin-store.js +44 -44
- package/dist/lib/storage/make-webex-plugin-store.js.map +1 -1
- package/dist/lib/storage/make-webex-store.js +40 -40
- package/dist/lib/storage/make-webex-store.js.map +1 -1
- package/dist/lib/storage/memory-store-adapter.js +9 -9
- package/dist/lib/storage/memory-store-adapter.js.map +1 -1
- package/dist/lib/webex-core-plugin-mixin.js +13 -13
- package/dist/lib/webex-core-plugin-mixin.js.map +1 -1
- package/dist/lib/webex-http-error.js +9 -9
- package/dist/lib/webex-http-error.js.map +1 -1
- package/dist/lib/webex-internal-core-plugin-mixin.js +13 -13
- package/dist/lib/webex-internal-core-plugin-mixin.js.map +1 -1
- package/dist/lib/webex-plugin.js +36 -36
- package/dist/lib/webex-plugin.js.map +1 -1
- package/dist/plugins/logger.js +9 -9
- package/dist/plugins/logger.js.map +1 -1
- package/dist/webex-core.js +104 -104
- package/dist/webex-core.js.map +1 -1
- package/dist/webex-internal-core.js +12 -12
- package/dist/webex-internal-core.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +20 -19
- package/process +1 -1
- package/src/config.js +90 -90
- package/src/credentials-config.js +212 -212
- package/src/index.js +62 -62
- package/src/interceptors/auth.js +186 -186
- package/src/interceptors/default-options.js +55 -55
- package/src/interceptors/embargo.js +43 -43
- package/src/interceptors/network-timing.js +54 -54
- package/src/interceptors/payload-transformer.js +55 -55
- package/src/interceptors/rate-limit.js +169 -169
- package/src/interceptors/redirect.js +106 -106
- package/src/interceptors/request-event.js +93 -93
- package/src/interceptors/request-logger.js +78 -78
- package/src/interceptors/request-timing.js +65 -65
- package/src/interceptors/response-logger.js +98 -98
- package/src/interceptors/user-agent.js +77 -77
- package/src/interceptors/webex-tracking-id.js +73 -73
- package/src/interceptors/webex-user-agent.js +79 -79
- package/src/lib/batcher.js +307 -307
- package/src/lib/credentials/credentials.js +552 -552
- package/src/lib/credentials/grant-errors.js +92 -92
- package/src/lib/credentials/index.js +16 -16
- package/src/lib/credentials/scope.js +34 -34
- package/src/lib/credentials/token-collection.js +17 -17
- package/src/lib/credentials/token.js +559 -559
- package/src/lib/page.js +159 -159
- package/src/lib/services/constants.js +9 -9
- package/src/lib/services/index.js +26 -26
- package/src/lib/services/interceptors/server-error.js +48 -48
- package/src/lib/services/interceptors/service.js +101 -101
- package/src/lib/services/metrics.js +4 -4
- package/src/lib/services/service-catalog.js +435 -435
- package/src/lib/services/service-fed-ramp.js +4 -4
- package/src/lib/services/service-host.js +267 -267
- package/src/lib/services/service-registry.js +465 -465
- package/src/lib/services/service-state.js +78 -78
- package/src/lib/services/service-url.js +124 -124
- package/src/lib/services/services.js +1018 -1018
- package/src/lib/stateless-webex-plugin.js +98 -98
- package/src/lib/storage/decorators.js +220 -220
- package/src/lib/storage/errors.js +15 -15
- package/src/lib/storage/index.js +10 -10
- package/src/lib/storage/make-webex-plugin-store.js +211 -211
- package/src/lib/storage/make-webex-store.js +140 -140
- package/src/lib/storage/memory-store-adapter.js +79 -79
- package/src/lib/webex-core-plugin-mixin.js +114 -114
- package/src/lib/webex-http-error.js +61 -61
- package/src/lib/webex-internal-core-plugin-mixin.js +107 -107
- package/src/lib/webex-plugin.js +222 -222
- package/src/plugins/logger.js +60 -60
- package/src/webex-core.js +745 -745
- package/src/webex-internal-core.js +46 -46
- package/test/integration/spec/credentials/credentials.js +139 -139
- package/test/integration/spec/credentials/token.js +102 -102
- package/test/integration/spec/services/service-catalog.js +838 -838
- package/test/integration/spec/services/services.js +1221 -1221
- package/test/integration/spec/webex-core.js +178 -178
- package/test/unit/spec/_setup.js +44 -44
- package/test/unit/spec/credentials/credentials.js +1017 -1017
- package/test/unit/spec/credentials/token.js +441 -441
- package/test/unit/spec/interceptors/auth.js +521 -521
- package/test/unit/spec/interceptors/default-options.js +84 -84
- package/test/unit/spec/interceptors/embargo.js +144 -144
- package/test/unit/spec/interceptors/network-timing.js +49 -49
- package/test/unit/spec/interceptors/payload-transformer.js +155 -155
- package/test/unit/spec/interceptors/rate-limit.js +302 -302
- package/test/unit/spec/interceptors/redirect.js +102 -102
- package/test/unit/spec/interceptors/request-timing.js +92 -92
- package/test/unit/spec/interceptors/user-agent.js +76 -76
- package/test/unit/spec/interceptors/webex-tracking-id.js +76 -76
- package/test/unit/spec/interceptors/webex-user-agent.js +159 -159
- package/test/unit/spec/lib/batcher.js +330 -330
- package/test/unit/spec/lib/page.js +148 -148
- package/test/unit/spec/lib/webex-plugin.js +48 -48
- package/test/unit/spec/services/interceptors/server-error.js +204 -204
- package/test/unit/spec/services/interceptors/service.js +188 -188
- package/test/unit/spec/services/service-catalog.js +194 -194
- package/test/unit/spec/services/service-host.js +260 -260
- package/test/unit/spec/services/service-registry.js +747 -747
- package/test/unit/spec/services/service-state.js +60 -60
- package/test/unit/spec/services/service-url.js +258 -258
- package/test/unit/spec/services/services.js +348 -348
- package/test/unit/spec/storage/persist.js +50 -50
- package/test/unit/spec/storage/storage-adapter.js +12 -12
- package/test/unit/spec/storage/wait-for-value.js +81 -81
- package/test/unit/spec/webex-core.js +253 -253
- package/test/unit/spec/webex-internal-core.js +91 -91
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {Interceptor} from '@webex/http-core';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @class
|
|
9
|
-
*/
|
|
10
|
-
export default class EmbargoInterceptor extends Interceptor {
|
|
11
|
-
/**
|
|
12
|
-
* @returns {EmbargoInterceptor}
|
|
13
|
-
*/
|
|
14
|
-
static create() {
|
|
15
|
-
/* eslint no-invalid-this: [0] */
|
|
16
|
-
return new EmbargoInterceptor({webex: this});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @see Interceptor#onResponseError
|
|
21
|
-
* @param {Object} options
|
|
22
|
-
* @param {Error} reason
|
|
23
|
-
* @returns {Promise}
|
|
24
|
-
*/
|
|
25
|
-
onResponseError(options, reason) {
|
|
26
|
-
if (reason.statusCode === 451) {
|
|
27
|
-
const {device} = this.webex.internal;
|
|
28
|
-
const loggerMessage = [
|
|
29
|
-
'Received `HTTP 451 Unavailable For Legal Reasons`, ',
|
|
30
|
-
'discarding credentials and device registration',
|
|
31
|
-
].join('');
|
|
32
|
-
|
|
33
|
-
if (device) {
|
|
34
|
-
this.webex.internal.device.clear();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.webex.credentials.clear();
|
|
38
|
-
this.webex.logger.info(loggerMessage);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return Promise.reject(reason);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {Interceptor} from '@webex/http-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @class
|
|
9
|
+
*/
|
|
10
|
+
export default class EmbargoInterceptor extends Interceptor {
|
|
11
|
+
/**
|
|
12
|
+
* @returns {EmbargoInterceptor}
|
|
13
|
+
*/
|
|
14
|
+
static create() {
|
|
15
|
+
/* eslint no-invalid-this: [0] */
|
|
16
|
+
return new EmbargoInterceptor({webex: this});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @see Interceptor#onResponseError
|
|
21
|
+
* @param {Object} options
|
|
22
|
+
* @param {Error} reason
|
|
23
|
+
* @returns {Promise}
|
|
24
|
+
*/
|
|
25
|
+
onResponseError(options, reason) {
|
|
26
|
+
if (reason.statusCode === 451) {
|
|
27
|
+
const {device} = this.webex.internal;
|
|
28
|
+
const loggerMessage = [
|
|
29
|
+
'Received `HTTP 451 Unavailable For Legal Reasons`, ',
|
|
30
|
+
'discarding credentials and device registration',
|
|
31
|
+
].join('');
|
|
32
|
+
|
|
33
|
+
if (device) {
|
|
34
|
+
this.webex.internal.device.clear();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.webex.credentials.clear();
|
|
38
|
+
this.webex.logger.info(loggerMessage);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return Promise.reject(reason);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {Interceptor} from '@webex/http-core';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @class
|
|
9
|
-
*/
|
|
10
|
-
export default class NetworkTimingInterceptor extends Interceptor {
|
|
11
|
-
/**
|
|
12
|
-
* @param {Object} options
|
|
13
|
-
* @returns {NetworkTimingInterceptor}
|
|
14
|
-
*/
|
|
15
|
-
static create(options) {
|
|
16
|
-
return new NetworkTimingInterceptor(this, options);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @see Interceptor#onRequest
|
|
21
|
-
* @param {Object} options
|
|
22
|
-
* @returns {Object}
|
|
23
|
-
*/
|
|
24
|
-
onRequest(options) {
|
|
25
|
-
options.$timings = options.$timings || {};
|
|
26
|
-
options.$timings.networkStart = Date.now();
|
|
27
|
-
|
|
28
|
-
return options;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @see Interceptor#onResponse
|
|
33
|
-
* @param {Object} options
|
|
34
|
-
* @param {HttpResponse} response
|
|
35
|
-
* @returns {Object}
|
|
36
|
-
*/
|
|
37
|
-
onResponse(options, response) {
|
|
38
|
-
options.$timings.networkEnd = Date.now();
|
|
39
|
-
|
|
40
|
-
return response;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @see Interceptor#onResponseError
|
|
45
|
-
* @param {Object} options
|
|
46
|
-
* @param {Error} reason
|
|
47
|
-
* @returns {Object}
|
|
48
|
-
*/
|
|
49
|
-
onResponseError(options, reason) {
|
|
50
|
-
options.$timings.networkEnd = Date.now();
|
|
51
|
-
|
|
52
|
-
return Promise.reject(reason);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {Interceptor} from '@webex/http-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @class
|
|
9
|
+
*/
|
|
10
|
+
export default class NetworkTimingInterceptor extends Interceptor {
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object} options
|
|
13
|
+
* @returns {NetworkTimingInterceptor}
|
|
14
|
+
*/
|
|
15
|
+
static create(options) {
|
|
16
|
+
return new NetworkTimingInterceptor(this, options);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @see Interceptor#onRequest
|
|
21
|
+
* @param {Object} options
|
|
22
|
+
* @returns {Object}
|
|
23
|
+
*/
|
|
24
|
+
onRequest(options) {
|
|
25
|
+
options.$timings = options.$timings || {};
|
|
26
|
+
options.$timings.networkStart = Date.now();
|
|
27
|
+
|
|
28
|
+
return options;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @see Interceptor#onResponse
|
|
33
|
+
* @param {Object} options
|
|
34
|
+
* @param {HttpResponse} response
|
|
35
|
+
* @returns {Object}
|
|
36
|
+
*/
|
|
37
|
+
onResponse(options, response) {
|
|
38
|
+
options.$timings.networkEnd = Date.now();
|
|
39
|
+
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @see Interceptor#onResponseError
|
|
45
|
+
* @param {Object} options
|
|
46
|
+
* @param {Error} reason
|
|
47
|
+
* @returns {Object}
|
|
48
|
+
*/
|
|
49
|
+
onResponseError(options, reason) {
|
|
50
|
+
options.$timings.networkEnd = Date.now();
|
|
51
|
+
|
|
52
|
+
return Promise.reject(reason);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {Interceptor} from '@webex/http-core';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @class
|
|
9
|
-
*/
|
|
10
|
-
export default class PayloadTransformerInterceptor extends Interceptor {
|
|
11
|
-
/**
|
|
12
|
-
* @param {Object} options
|
|
13
|
-
* @returns {PayloadTransformerInterceptor}
|
|
14
|
-
*/
|
|
15
|
-
static create() {
|
|
16
|
-
return new PayloadTransformerInterceptor({webex: this});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @see Interceptor#onRequest
|
|
21
|
-
* @param {Object} options
|
|
22
|
-
* @returns {Object}
|
|
23
|
-
*/
|
|
24
|
-
onRequest(options) {
|
|
25
|
-
if (options.noTransform) {
|
|
26
|
-
return options;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return this.webex.transform('outbound', options);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @see Interceptor#onResponse
|
|
34
|
-
* @param {Object} options
|
|
35
|
-
* @param {HttpResponse} response
|
|
36
|
-
* @returns {Object}
|
|
37
|
-
*/
|
|
38
|
-
onResponse(options, response) {
|
|
39
|
-
if (options.disableTransform) {
|
|
40
|
-
return response;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return this.webex.transform('inbound', response);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @see Interceptor#onResponseError
|
|
48
|
-
* @param {Object} options
|
|
49
|
-
* @param {Error} reason
|
|
50
|
-
* @returns {Object}
|
|
51
|
-
*/
|
|
52
|
-
onResponseError(options, reason) {
|
|
53
|
-
return this.webex.transform('inbound', reason).then((r) => Promise.reject(r || reason));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {Interceptor} from '@webex/http-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @class
|
|
9
|
+
*/
|
|
10
|
+
export default class PayloadTransformerInterceptor extends Interceptor {
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object} options
|
|
13
|
+
* @returns {PayloadTransformerInterceptor}
|
|
14
|
+
*/
|
|
15
|
+
static create() {
|
|
16
|
+
return new PayloadTransformerInterceptor({webex: this});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @see Interceptor#onRequest
|
|
21
|
+
* @param {Object} options
|
|
22
|
+
* @returns {Object}
|
|
23
|
+
*/
|
|
24
|
+
onRequest(options) {
|
|
25
|
+
if (options.noTransform) {
|
|
26
|
+
return options;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return this.webex.transform('outbound', options);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @see Interceptor#onResponse
|
|
34
|
+
* @param {Object} options
|
|
35
|
+
* @param {HttpResponse} response
|
|
36
|
+
* @returns {Object}
|
|
37
|
+
*/
|
|
38
|
+
onResponse(options, response) {
|
|
39
|
+
if (options.disableTransform) {
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return this.webex.transform('inbound', response);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @see Interceptor#onResponseError
|
|
48
|
+
* @param {Object} options
|
|
49
|
+
* @param {Error} reason
|
|
50
|
+
* @returns {Object}
|
|
51
|
+
*/
|
|
52
|
+
onResponseError(options, reason) {
|
|
53
|
+
return this.webex.transform('inbound', reason).then((r) => Promise.reject(r || reason));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,169 +1,169 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {Interceptor} from '@webex/http-core';
|
|
6
|
-
|
|
7
|
-
// contains the system time in milliseconds at which the retry after associated with a 429 expires
|
|
8
|
-
// mapped by the API name, e.g.: idbroker.webex.com/doStuff would be mapped as 'doStuff'
|
|
9
|
-
const rateLimitExpiryTime = new WeakMap();
|
|
10
|
-
|
|
11
|
-
// extracts the common identity API being called
|
|
12
|
-
const idBrokerRegex = /.*(idbroker|identity)(bts)?.ciscospark.com\/([^/]+)/;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @class
|
|
16
|
-
*/
|
|
17
|
-
export default class RateLimitInterceptor extends Interceptor {
|
|
18
|
-
/**
|
|
19
|
-
* @returns {RateLimitInterceptor}
|
|
20
|
-
*/
|
|
21
|
-
static create() {
|
|
22
|
-
return new RateLimitInterceptor({webex: this});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* constructor
|
|
27
|
-
* @param {mixed} args
|
|
28
|
-
* @returns {Exception}
|
|
29
|
-
*/
|
|
30
|
-
constructor(...args) {
|
|
31
|
-
super(...args);
|
|
32
|
-
rateLimitExpiryTime.set(this, new Map());
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @see {@link Interceptor#onRequest}
|
|
37
|
-
* @param {Object} options
|
|
38
|
-
* @returns {Object}
|
|
39
|
-
*/
|
|
40
|
-
onRequest(options) {
|
|
41
|
-
if (this.isRateLimited(options.uri)) {
|
|
42
|
-
return Promise.reject(new Error(`API rate limited ${options.uri}`));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return Promise.resolve(options);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @see {@link Interceptor#onResponseError}
|
|
50
|
-
* @param {Object} options
|
|
51
|
-
* @param {Error} reason
|
|
52
|
-
* @returns {Object}
|
|
53
|
-
*/
|
|
54
|
-
onResponseError(options, reason) {
|
|
55
|
-
if (
|
|
56
|
-
reason.statusCode === 429 &&
|
|
57
|
-
(options.uri.includes('idbroker') || options.uri.includes('identity'))
|
|
58
|
-
) {
|
|
59
|
-
// set the retry after in the map, setting to milliseconds
|
|
60
|
-
this.setRateLimitExpiry(options.uri, this.extractRetryAfterTime(options));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return Promise.reject(reason);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @param {object} options associated with the request
|
|
68
|
-
* @returns {number} retry after time in milliseconds
|
|
69
|
-
*/
|
|
70
|
-
extractRetryAfterTime(options) {
|
|
71
|
-
// 1S * 1K === 1MS
|
|
72
|
-
const milliMultiplier = 1000;
|
|
73
|
-
const retryAfter = options.headers['retry-after'] || null;
|
|
74
|
-
|
|
75
|
-
// set 60 retry if no usable time defined
|
|
76
|
-
if (retryAfter === null || retryAfter <= 0) {
|
|
77
|
-
return 60 * milliMultiplier;
|
|
78
|
-
}
|
|
79
|
-
// set max to 3600 S (1 hour) if greater than 1 hour
|
|
80
|
-
if (retryAfter > 3600) {
|
|
81
|
-
return 3600 * milliMultiplier;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return retryAfter * milliMultiplier;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Set the system time at which the rate limiting
|
|
89
|
-
* will expire in the rateLimitExpiryTime map.
|
|
90
|
-
* Assumes retryAfter is in milliseconds
|
|
91
|
-
* @param {string} uri API issuing the rate limiting
|
|
92
|
-
* @param {number} retryAfter milliseconds until rate limiting expires
|
|
93
|
-
* @returns {bool} true is value was successfully set
|
|
94
|
-
*/
|
|
95
|
-
setRateLimitExpiry(uri, retryAfter) {
|
|
96
|
-
const apiName = this.getApiName(uri);
|
|
97
|
-
|
|
98
|
-
if (!apiName) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const currTimeMilli = new Date().getTime();
|
|
103
|
-
const expiry = currTimeMilli + retryAfter;
|
|
104
|
-
const dict = rateLimitExpiryTime.get(this);
|
|
105
|
-
|
|
106
|
-
return dict.set(apiName, expiry);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* returns true if the API is currently rate limited
|
|
111
|
-
* @param {string} uri
|
|
112
|
-
* @returns {Boolean} indicates whether or not the API is rate currently rate limited
|
|
113
|
-
*/
|
|
114
|
-
getRateLimitStatus(uri) {
|
|
115
|
-
const apiName = this.getApiName(uri);
|
|
116
|
-
|
|
117
|
-
if (!apiName) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const currTimeMilli = new Date().getTime();
|
|
122
|
-
const dict = rateLimitExpiryTime.get(this);
|
|
123
|
-
const expiryTime = dict.get(apiName);
|
|
124
|
-
|
|
125
|
-
// if no rate limit expiry has been registered in the map, return false.
|
|
126
|
-
if (expiryTime === undefined) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// return true, indicating rate limiting, if the system time is less than the expiry time
|
|
131
|
-
return currTimeMilli < dict.get(apiName);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* split the URI and returns the API name of idBroker
|
|
136
|
-
* @param {string} uri
|
|
137
|
-
* @returns {string}
|
|
138
|
-
*/
|
|
139
|
-
getApiName(uri) {
|
|
140
|
-
if (!uri) {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const results = uri.match(idBrokerRegex);
|
|
145
|
-
|
|
146
|
-
if (!results) {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// group 0 = full match of URL, group 1 = identity or idbroker base
|
|
151
|
-
// group 2 = api name
|
|
152
|
-
return results[2];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* check URI against list of currently rate limited
|
|
157
|
-
* URIs, and determines if retry-after
|
|
158
|
-
* @param {String} uri pattern to check
|
|
159
|
-
* @returns {bool}
|
|
160
|
-
*/
|
|
161
|
-
isRateLimited(uri) {
|
|
162
|
-
// determine if the URI is associated with a common identity API
|
|
163
|
-
if (uri && (uri.includes('idbroker') || uri.includes('identity'))) {
|
|
164
|
-
return this.getRateLimitStatus(uri);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {Interceptor} from '@webex/http-core';
|
|
6
|
+
|
|
7
|
+
// contains the system time in milliseconds at which the retry after associated with a 429 expires
|
|
8
|
+
// mapped by the API name, e.g.: idbroker.webex.com/doStuff would be mapped as 'doStuff'
|
|
9
|
+
const rateLimitExpiryTime = new WeakMap();
|
|
10
|
+
|
|
11
|
+
// extracts the common identity API being called
|
|
12
|
+
const idBrokerRegex = /.*(idbroker|identity)(bts)?.ciscospark.com\/([^/]+)/;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @class
|
|
16
|
+
*/
|
|
17
|
+
export default class RateLimitInterceptor extends Interceptor {
|
|
18
|
+
/**
|
|
19
|
+
* @returns {RateLimitInterceptor}
|
|
20
|
+
*/
|
|
21
|
+
static create() {
|
|
22
|
+
return new RateLimitInterceptor({webex: this});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* constructor
|
|
27
|
+
* @param {mixed} args
|
|
28
|
+
* @returns {Exception}
|
|
29
|
+
*/
|
|
30
|
+
constructor(...args) {
|
|
31
|
+
super(...args);
|
|
32
|
+
rateLimitExpiryTime.set(this, new Map());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @see {@link Interceptor#onRequest}
|
|
37
|
+
* @param {Object} options
|
|
38
|
+
* @returns {Object}
|
|
39
|
+
*/
|
|
40
|
+
onRequest(options) {
|
|
41
|
+
if (this.isRateLimited(options.uri)) {
|
|
42
|
+
return Promise.reject(new Error(`API rate limited ${options.uri}`));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return Promise.resolve(options);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @see {@link Interceptor#onResponseError}
|
|
50
|
+
* @param {Object} options
|
|
51
|
+
* @param {Error} reason
|
|
52
|
+
* @returns {Object}
|
|
53
|
+
*/
|
|
54
|
+
onResponseError(options, reason) {
|
|
55
|
+
if (
|
|
56
|
+
reason.statusCode === 429 &&
|
|
57
|
+
(options.uri.includes('idbroker') || options.uri.includes('identity'))
|
|
58
|
+
) {
|
|
59
|
+
// set the retry after in the map, setting to milliseconds
|
|
60
|
+
this.setRateLimitExpiry(options.uri, this.extractRetryAfterTime(options));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return Promise.reject(reason);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {object} options associated with the request
|
|
68
|
+
* @returns {number} retry after time in milliseconds
|
|
69
|
+
*/
|
|
70
|
+
extractRetryAfterTime(options) {
|
|
71
|
+
// 1S * 1K === 1MS
|
|
72
|
+
const milliMultiplier = 1000;
|
|
73
|
+
const retryAfter = options.headers['retry-after'] || null;
|
|
74
|
+
|
|
75
|
+
// set 60 retry if no usable time defined
|
|
76
|
+
if (retryAfter === null || retryAfter <= 0) {
|
|
77
|
+
return 60 * milliMultiplier;
|
|
78
|
+
}
|
|
79
|
+
// set max to 3600 S (1 hour) if greater than 1 hour
|
|
80
|
+
if (retryAfter > 3600) {
|
|
81
|
+
return 3600 * milliMultiplier;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return retryAfter * milliMultiplier;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Set the system time at which the rate limiting
|
|
89
|
+
* will expire in the rateLimitExpiryTime map.
|
|
90
|
+
* Assumes retryAfter is in milliseconds
|
|
91
|
+
* @param {string} uri API issuing the rate limiting
|
|
92
|
+
* @param {number} retryAfter milliseconds until rate limiting expires
|
|
93
|
+
* @returns {bool} true is value was successfully set
|
|
94
|
+
*/
|
|
95
|
+
setRateLimitExpiry(uri, retryAfter) {
|
|
96
|
+
const apiName = this.getApiName(uri);
|
|
97
|
+
|
|
98
|
+
if (!apiName) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const currTimeMilli = new Date().getTime();
|
|
103
|
+
const expiry = currTimeMilli + retryAfter;
|
|
104
|
+
const dict = rateLimitExpiryTime.get(this);
|
|
105
|
+
|
|
106
|
+
return dict.set(apiName, expiry);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* returns true if the API is currently rate limited
|
|
111
|
+
* @param {string} uri
|
|
112
|
+
* @returns {Boolean} indicates whether or not the API is rate currently rate limited
|
|
113
|
+
*/
|
|
114
|
+
getRateLimitStatus(uri) {
|
|
115
|
+
const apiName = this.getApiName(uri);
|
|
116
|
+
|
|
117
|
+
if (!apiName) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const currTimeMilli = new Date().getTime();
|
|
122
|
+
const dict = rateLimitExpiryTime.get(this);
|
|
123
|
+
const expiryTime = dict.get(apiName);
|
|
124
|
+
|
|
125
|
+
// if no rate limit expiry has been registered in the map, return false.
|
|
126
|
+
if (expiryTime === undefined) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// return true, indicating rate limiting, if the system time is less than the expiry time
|
|
131
|
+
return currTimeMilli < dict.get(apiName);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* split the URI and returns the API name of idBroker
|
|
136
|
+
* @param {string} uri
|
|
137
|
+
* @returns {string}
|
|
138
|
+
*/
|
|
139
|
+
getApiName(uri) {
|
|
140
|
+
if (!uri) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const results = uri.match(idBrokerRegex);
|
|
145
|
+
|
|
146
|
+
if (!results) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// group 0 = full match of URL, group 1 = identity or idbroker base
|
|
151
|
+
// group 2 = api name
|
|
152
|
+
return results[2];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* check URI against list of currently rate limited
|
|
157
|
+
* URIs, and determines if retry-after
|
|
158
|
+
* @param {String} uri pattern to check
|
|
159
|
+
* @returns {bool}
|
|
160
|
+
*/
|
|
161
|
+
isRateLimited(uri) {
|
|
162
|
+
// determine if the URI is associated with a common identity API
|
|
163
|
+
if (uri && (uri.includes('idbroker') || uri.includes('identity'))) {
|
|
164
|
+
return this.getRateLimitStatus(uri);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|