@webex/webex-core 2.59.3-next.1 → 2.59.4
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 +19 -20
- 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
package/src/index.js
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*
|
|
4
|
-
* Services is currently a part of webex-core due to how the contents of
|
|
5
|
-
* the original internal-plugin-services needed to be accessed when webex-core
|
|
6
|
-
* is initialized. As a plugin outside of webex-core, it would initialize after
|
|
7
|
-
* credentials, causing all requests prior to its initialization to fail
|
|
8
|
-
* federation requirements, and instead send requests to the environmentally-
|
|
9
|
-
* assigned urls.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import './plugins/logger';
|
|
13
|
-
import './lib/credentials';
|
|
14
|
-
import './lib/services';
|
|
15
|
-
|
|
16
|
-
export {Credentials, filterScope, grantErrors, sortScope, Token} from './lib/credentials';
|
|
17
|
-
|
|
18
|
-
export {
|
|
19
|
-
constants as serviceConstants,
|
|
20
|
-
ServiceCatalog,
|
|
21
|
-
ServiceRegistry,
|
|
22
|
-
ServiceState,
|
|
23
|
-
ServiceInterceptor,
|
|
24
|
-
ServerErrorInterceptor,
|
|
25
|
-
Services,
|
|
26
|
-
ServiceHost,
|
|
27
|
-
ServiceUrl,
|
|
28
|
-
} from './lib/services';
|
|
29
|
-
|
|
30
|
-
export {
|
|
31
|
-
makeWebexStore,
|
|
32
|
-
makeWebexPluginStore,
|
|
33
|
-
MemoryStoreAdapter,
|
|
34
|
-
NotFoundError,
|
|
35
|
-
persist,
|
|
36
|
-
StorageError,
|
|
37
|
-
waitForValue,
|
|
38
|
-
} from './lib/storage';
|
|
39
|
-
|
|
40
|
-
export {default, registerPlugin, registerInternalPlugin} from './webex-core';
|
|
41
|
-
|
|
42
|
-
export {default as WebexHttpError} from './lib/webex-http-error';
|
|
43
|
-
export {default as StatelessWebexPlugin} from './lib/stateless-webex-plugin';
|
|
44
|
-
export {default as WebexPlugin} from './lib/webex-plugin';
|
|
45
|
-
export {default as AuthInterceptor} from './interceptors/auth';
|
|
46
|
-
export {default as NetworkTimingInterceptor} from './interceptors/network-timing';
|
|
47
|
-
export {default as PayloadTransformerInterceptor} from './interceptors/payload-transformer';
|
|
48
|
-
export {default as RedirectInterceptor} from './interceptors/redirect';
|
|
49
|
-
export {default as ResponseLoggerInterceptor} from './interceptors/response-logger';
|
|
50
|
-
export {default as RequestEventInterceptor} from './interceptors/request-event';
|
|
51
|
-
export {default as RequestLoggerInterceptor} from './interceptors/request-logger';
|
|
52
|
-
export {default as RequestTimingInterceptor} from './interceptors/request-timing';
|
|
53
|
-
export {default as UserAgentInterceptor} from './interceptors/user-agent';
|
|
54
|
-
export {default as WebexTrackingIdInterceptor} from './interceptors/webex-tracking-id';
|
|
55
|
-
export {default as WebexUserAgentInterceptor} from './interceptors/webex-user-agent';
|
|
56
|
-
export {default as RateLimitInterceptor} from './interceptors/rate-limit';
|
|
57
|
-
export {default as EmbargoInterceptor} from './interceptors/embargo';
|
|
58
|
-
export {default as DefaultOptionsInterceptor} from './interceptors/default-options';
|
|
59
|
-
|
|
60
|
-
export {default as Batcher} from './lib/batcher';
|
|
61
|
-
export {default as Page} from './lib/page';
|
|
62
|
-
export {default as config} from './config';
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*
|
|
4
|
+
* Services is currently a part of webex-core due to how the contents of
|
|
5
|
+
* the original internal-plugin-services needed to be accessed when webex-core
|
|
6
|
+
* is initialized. As a plugin outside of webex-core, it would initialize after
|
|
7
|
+
* credentials, causing all requests prior to its initialization to fail
|
|
8
|
+
* federation requirements, and instead send requests to the environmentally-
|
|
9
|
+
* assigned urls.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import './plugins/logger';
|
|
13
|
+
import './lib/credentials';
|
|
14
|
+
import './lib/services';
|
|
15
|
+
|
|
16
|
+
export {Credentials, filterScope, grantErrors, sortScope, Token} from './lib/credentials';
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
constants as serviceConstants,
|
|
20
|
+
ServiceCatalog,
|
|
21
|
+
ServiceRegistry,
|
|
22
|
+
ServiceState,
|
|
23
|
+
ServiceInterceptor,
|
|
24
|
+
ServerErrorInterceptor,
|
|
25
|
+
Services,
|
|
26
|
+
ServiceHost,
|
|
27
|
+
ServiceUrl,
|
|
28
|
+
} from './lib/services';
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
makeWebexStore,
|
|
32
|
+
makeWebexPluginStore,
|
|
33
|
+
MemoryStoreAdapter,
|
|
34
|
+
NotFoundError,
|
|
35
|
+
persist,
|
|
36
|
+
StorageError,
|
|
37
|
+
waitForValue,
|
|
38
|
+
} from './lib/storage';
|
|
39
|
+
|
|
40
|
+
export {default, registerPlugin, registerInternalPlugin} from './webex-core';
|
|
41
|
+
|
|
42
|
+
export {default as WebexHttpError} from './lib/webex-http-error';
|
|
43
|
+
export {default as StatelessWebexPlugin} from './lib/stateless-webex-plugin';
|
|
44
|
+
export {default as WebexPlugin} from './lib/webex-plugin';
|
|
45
|
+
export {default as AuthInterceptor} from './interceptors/auth';
|
|
46
|
+
export {default as NetworkTimingInterceptor} from './interceptors/network-timing';
|
|
47
|
+
export {default as PayloadTransformerInterceptor} from './interceptors/payload-transformer';
|
|
48
|
+
export {default as RedirectInterceptor} from './interceptors/redirect';
|
|
49
|
+
export {default as ResponseLoggerInterceptor} from './interceptors/response-logger';
|
|
50
|
+
export {default as RequestEventInterceptor} from './interceptors/request-event';
|
|
51
|
+
export {default as RequestLoggerInterceptor} from './interceptors/request-logger';
|
|
52
|
+
export {default as RequestTimingInterceptor} from './interceptors/request-timing';
|
|
53
|
+
export {default as UserAgentInterceptor} from './interceptors/user-agent';
|
|
54
|
+
export {default as WebexTrackingIdInterceptor} from './interceptors/webex-tracking-id';
|
|
55
|
+
export {default as WebexUserAgentInterceptor} from './interceptors/webex-user-agent';
|
|
56
|
+
export {default as RateLimitInterceptor} from './interceptors/rate-limit';
|
|
57
|
+
export {default as EmbargoInterceptor} from './interceptors/embargo';
|
|
58
|
+
export {default as DefaultOptionsInterceptor} from './interceptors/default-options';
|
|
59
|
+
|
|
60
|
+
export {default as Batcher} from './lib/batcher';
|
|
61
|
+
export {default as Page} from './lib/page';
|
|
62
|
+
export {default as config} from './config';
|
package/src/interceptors/auth.js
CHANGED
|
@@ -1,186 +1,186 @@
|
|
|
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 AuthInterceptor extends Interceptor {
|
|
11
|
-
/**
|
|
12
|
-
* @returns {AuthInterceptor}
|
|
13
|
-
*/
|
|
14
|
-
static create() {
|
|
15
|
-
return new AuthInterceptor({webex: this});
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @see {@link Interceptor#onRequest}
|
|
20
|
-
* @param {Object} options
|
|
21
|
-
* @returns {Object}
|
|
22
|
-
*/
|
|
23
|
-
onRequest(options) {
|
|
24
|
-
options.headers = options.headers || {};
|
|
25
|
-
|
|
26
|
-
// If Authorizations is already set, don't overwrite it
|
|
27
|
-
if ('authorization' in options.headers || 'auth' in options) {
|
|
28
|
-
// If Authorization is set to null, false, or undefined, delete it to
|
|
29
|
-
// prevent a CORS preflight.
|
|
30
|
-
if (!options.headers.authorization) {
|
|
31
|
-
Reflect.deleteProperty(options.headers, 'authorization');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return Promise.resolve(options);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return this.requiresCredentials(options).then((requires) => {
|
|
38
|
-
if (!requires) {
|
|
39
|
-
return options;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return this.webex.credentials.getUserToken().then((token) => {
|
|
43
|
-
options.headers.authorization = token.toString();
|
|
44
|
-
|
|
45
|
-
return options;
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Determines if the provided options object needs an authorization header.
|
|
52
|
-
*
|
|
53
|
-
* @param {Object} options
|
|
54
|
-
* @returns {Promise<boolean>}
|
|
55
|
-
*/
|
|
56
|
-
requiresCredentials(options) {
|
|
57
|
-
// Validate that authorization is necessary.
|
|
58
|
-
if (options.addAuthHeader === false) {
|
|
59
|
-
return Promise.resolve(false);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Validate that the services plugin has been loaded before proceeding.
|
|
63
|
-
if (!this.webex.internal.services) {
|
|
64
|
-
return Promise.resolve(false);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Destructure webex instance to isolate services plugin.
|
|
68
|
-
const {services} = this.webex.internal;
|
|
69
|
-
|
|
70
|
-
// Store the current service details if available and destructure details.
|
|
71
|
-
const details = services.getServiceFromUrl(options.uri || '');
|
|
72
|
-
const {name} = details || {};
|
|
73
|
-
const {resource, uri} = options;
|
|
74
|
-
const service = options.service || options.api;
|
|
75
|
-
|
|
76
|
-
// Unique validation for the u2c service.
|
|
77
|
-
if ((service && service === 'u2c') || (name && name === 'u2c')) {
|
|
78
|
-
if ((resource && resource.includes('limited')) || (uri && uri.includes('limited'))) {
|
|
79
|
-
return Promise.resolve(false);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return Promise.resolve(true);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Validate that the allowed domains can be utilized.
|
|
86
|
-
if (
|
|
87
|
-
services.validateDomains &&
|
|
88
|
-
services.hasAllowedDomains() &&
|
|
89
|
-
uri &&
|
|
90
|
-
services.isAllowedDomainUrl(uri)
|
|
91
|
-
) {
|
|
92
|
-
return Promise.resolve(true);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Perform an additional validation in case the service does not exist yet.
|
|
96
|
-
return services
|
|
97
|
-
.waitForService({name: service, url: uri})
|
|
98
|
-
.then((detectedUrl) => {
|
|
99
|
-
// Validate that the url exists in the catalog.
|
|
100
|
-
if (services.getServiceFromUrl(detectedUrl)) {
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Return false to indicate authentication is not required.
|
|
105
|
-
return false;
|
|
106
|
-
})
|
|
107
|
-
.catch((error) => {
|
|
108
|
-
this.webex.logger.warn(
|
|
109
|
-
'auth-interceptor: failed to validate service exists in catalog',
|
|
110
|
-
error
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
return false;
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @see {@link Interceptor#onResponseError}
|
|
119
|
-
* @param {Object} options
|
|
120
|
-
* @param {Error} reason
|
|
121
|
-
* @returns {Object}
|
|
122
|
-
*/
|
|
123
|
-
onResponseError(options, reason) {
|
|
124
|
-
return this.shouldAttemptReauth(reason, options).then((shouldAttemptReauth) => {
|
|
125
|
-
if (shouldAttemptReauth) {
|
|
126
|
-
this.webex.logger.info('auth: received 401, attempting to reauthenticate');
|
|
127
|
-
|
|
128
|
-
if (reason.options.headers) {
|
|
129
|
-
Reflect.deleteProperty(reason.options.headers, 'authorization');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (this.webex.credentials.canRefresh) {
|
|
133
|
-
return this.webex.credentials.refresh().then(() => this.replay(options));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return Promise.reject(reason);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Replays the request
|
|
143
|
-
* @param {Object} options
|
|
144
|
-
* @returns {Object}
|
|
145
|
-
*/
|
|
146
|
-
replay(options) {
|
|
147
|
-
if (options.replayCount) {
|
|
148
|
-
options.replayCount += 1;
|
|
149
|
-
} else {
|
|
150
|
-
options.replayCount = 1;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (options.replayCount > this.webex.config.maxAuthenticationReplays) {
|
|
154
|
-
this.webex.logger.error(
|
|
155
|
-
`auth: failed after ${this.webex.config.maxAuthenticationReplays} replay attempts`
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
return Promise.reject(
|
|
159
|
-
new Error(`Failed after ${this.webex.config.maxAuthenticationReplays} replay attempts`)
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
this.webex.logger.info(`auth: replaying request ${options.replayCount} time`);
|
|
164
|
-
|
|
165
|
-
return this.webex.request(options);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Indicates whether or not the current request should refresh its access
|
|
170
|
-
* token in event of a 401
|
|
171
|
-
* @param {Error} reason
|
|
172
|
-
* @param {Object} options
|
|
173
|
-
* @returns {Promise<boolean>}
|
|
174
|
-
*/
|
|
175
|
-
shouldAttemptReauth(reason, options) {
|
|
176
|
-
if (options && options.shouldRefreshAccessToken === false) {
|
|
177
|
-
return Promise.resolve(false);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (reason.statusCode === 401) {
|
|
181
|
-
return Promise.resolve(true);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return Promise.resolve(false);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
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 AuthInterceptor extends Interceptor {
|
|
11
|
+
/**
|
|
12
|
+
* @returns {AuthInterceptor}
|
|
13
|
+
*/
|
|
14
|
+
static create() {
|
|
15
|
+
return new AuthInterceptor({webex: this});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @see {@link Interceptor#onRequest}
|
|
20
|
+
* @param {Object} options
|
|
21
|
+
* @returns {Object}
|
|
22
|
+
*/
|
|
23
|
+
onRequest(options) {
|
|
24
|
+
options.headers = options.headers || {};
|
|
25
|
+
|
|
26
|
+
// If Authorizations is already set, don't overwrite it
|
|
27
|
+
if ('authorization' in options.headers || 'auth' in options) {
|
|
28
|
+
// If Authorization is set to null, false, or undefined, delete it to
|
|
29
|
+
// prevent a CORS preflight.
|
|
30
|
+
if (!options.headers.authorization) {
|
|
31
|
+
Reflect.deleteProperty(options.headers, 'authorization');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return Promise.resolve(options);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return this.requiresCredentials(options).then((requires) => {
|
|
38
|
+
if (!requires) {
|
|
39
|
+
return options;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return this.webex.credentials.getUserToken().then((token) => {
|
|
43
|
+
options.headers.authorization = token.toString();
|
|
44
|
+
|
|
45
|
+
return options;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Determines if the provided options object needs an authorization header.
|
|
52
|
+
*
|
|
53
|
+
* @param {Object} options
|
|
54
|
+
* @returns {Promise<boolean>}
|
|
55
|
+
*/
|
|
56
|
+
requiresCredentials(options) {
|
|
57
|
+
// Validate that authorization is necessary.
|
|
58
|
+
if (options.addAuthHeader === false) {
|
|
59
|
+
return Promise.resolve(false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Validate that the services plugin has been loaded before proceeding.
|
|
63
|
+
if (!this.webex.internal.services) {
|
|
64
|
+
return Promise.resolve(false);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Destructure webex instance to isolate services plugin.
|
|
68
|
+
const {services} = this.webex.internal;
|
|
69
|
+
|
|
70
|
+
// Store the current service details if available and destructure details.
|
|
71
|
+
const details = services.getServiceFromUrl(options.uri || '');
|
|
72
|
+
const {name} = details || {};
|
|
73
|
+
const {resource, uri} = options;
|
|
74
|
+
const service = options.service || options.api;
|
|
75
|
+
|
|
76
|
+
// Unique validation for the u2c service.
|
|
77
|
+
if ((service && service === 'u2c') || (name && name === 'u2c')) {
|
|
78
|
+
if ((resource && resource.includes('limited')) || (uri && uri.includes('limited'))) {
|
|
79
|
+
return Promise.resolve(false);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return Promise.resolve(true);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Validate that the allowed domains can be utilized.
|
|
86
|
+
if (
|
|
87
|
+
services.validateDomains &&
|
|
88
|
+
services.hasAllowedDomains() &&
|
|
89
|
+
uri &&
|
|
90
|
+
services.isAllowedDomainUrl(uri)
|
|
91
|
+
) {
|
|
92
|
+
return Promise.resolve(true);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Perform an additional validation in case the service does not exist yet.
|
|
96
|
+
return services
|
|
97
|
+
.waitForService({name: service, url: uri})
|
|
98
|
+
.then((detectedUrl) => {
|
|
99
|
+
// Validate that the url exists in the catalog.
|
|
100
|
+
if (services.getServiceFromUrl(detectedUrl)) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Return false to indicate authentication is not required.
|
|
105
|
+
return false;
|
|
106
|
+
})
|
|
107
|
+
.catch((error) => {
|
|
108
|
+
this.webex.logger.warn(
|
|
109
|
+
'auth-interceptor: failed to validate service exists in catalog',
|
|
110
|
+
error
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
return false;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @see {@link Interceptor#onResponseError}
|
|
119
|
+
* @param {Object} options
|
|
120
|
+
* @param {Error} reason
|
|
121
|
+
* @returns {Object}
|
|
122
|
+
*/
|
|
123
|
+
onResponseError(options, reason) {
|
|
124
|
+
return this.shouldAttemptReauth(reason, options).then((shouldAttemptReauth) => {
|
|
125
|
+
if (shouldAttemptReauth) {
|
|
126
|
+
this.webex.logger.info('auth: received 401, attempting to reauthenticate');
|
|
127
|
+
|
|
128
|
+
if (reason.options.headers) {
|
|
129
|
+
Reflect.deleteProperty(reason.options.headers, 'authorization');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (this.webex.credentials.canRefresh) {
|
|
133
|
+
return this.webex.credentials.refresh().then(() => this.replay(options));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return Promise.reject(reason);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Replays the request
|
|
143
|
+
* @param {Object} options
|
|
144
|
+
* @returns {Object}
|
|
145
|
+
*/
|
|
146
|
+
replay(options) {
|
|
147
|
+
if (options.replayCount) {
|
|
148
|
+
options.replayCount += 1;
|
|
149
|
+
} else {
|
|
150
|
+
options.replayCount = 1;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (options.replayCount > this.webex.config.maxAuthenticationReplays) {
|
|
154
|
+
this.webex.logger.error(
|
|
155
|
+
`auth: failed after ${this.webex.config.maxAuthenticationReplays} replay attempts`
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
return Promise.reject(
|
|
159
|
+
new Error(`Failed after ${this.webex.config.maxAuthenticationReplays} replay attempts`)
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.webex.logger.info(`auth: replaying request ${options.replayCount} time`);
|
|
164
|
+
|
|
165
|
+
return this.webex.request(options);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Indicates whether or not the current request should refresh its access
|
|
170
|
+
* token in event of a 401
|
|
171
|
+
* @param {Error} reason
|
|
172
|
+
* @param {Object} options
|
|
173
|
+
* @returns {Promise<boolean>}
|
|
174
|
+
*/
|
|
175
|
+
shouldAttemptReauth(reason, options) {
|
|
176
|
+
if (options && options.shouldRefreshAccessToken === false) {
|
|
177
|
+
return Promise.resolve(false);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (reason.statusCode === 401) {
|
|
181
|
+
return Promise.resolve(true);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return Promise.resolve(false);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -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
|
-
* Allows the user of the SDK to set default options that apply every http request made by the SDK
|
|
9
|
-
* For example a default timeout could be set for all requests like this :
|
|
10
|
-
*
|
|
11
|
-
* webex = WebexSdk.init({
|
|
12
|
-
* credentials: {
|
|
13
|
-
* supertoken: superToken
|
|
14
|
-
* },
|
|
15
|
-
* config: {
|
|
16
|
-
* credentials: {
|
|
17
|
-
* client_id,
|
|
18
|
-
* client_secret
|
|
19
|
-
* },
|
|
20
|
-
* defaultRequestOptions: {
|
|
21
|
-
* timeout: 15000
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
* });
|
|
25
|
-
*/
|
|
26
|
-
export default class DefaultOptionsInterceptor extends Interceptor {
|
|
27
|
-
/**
|
|
28
|
-
* @returns {DefaultOptionsInterceptor}
|
|
29
|
-
*/
|
|
30
|
-
static create() {
|
|
31
|
-
return new DefaultOptionsInterceptor({webex: this});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @see Interceptor#onRequest
|
|
36
|
-
* @param {Object} options
|
|
37
|
-
* @returns {Object}
|
|
38
|
-
*/
|
|
39
|
-
onRequest(options) {
|
|
40
|
-
const {defaultRequestOptions: defaultOptions} = this.webex.config;
|
|
41
|
-
|
|
42
|
-
if (!defaultOptions) {
|
|
43
|
-
return options;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
Object.keys(defaultOptions).forEach((key) => {
|
|
47
|
-
// don't override any existing option properties
|
|
48
|
-
if (!Object.keys(options).includes(key)) {
|
|
49
|
-
options[key] = defaultOptions[key];
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
return options;
|
|
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
|
+
* Allows the user of the SDK to set default options that apply every http request made by the SDK
|
|
9
|
+
* For example a default timeout could be set for all requests like this :
|
|
10
|
+
*
|
|
11
|
+
* webex = WebexSdk.init({
|
|
12
|
+
* credentials: {
|
|
13
|
+
* supertoken: superToken
|
|
14
|
+
* },
|
|
15
|
+
* config: {
|
|
16
|
+
* credentials: {
|
|
17
|
+
* client_id,
|
|
18
|
+
* client_secret
|
|
19
|
+
* },
|
|
20
|
+
* defaultRequestOptions: {
|
|
21
|
+
* timeout: 15000
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
export default class DefaultOptionsInterceptor extends Interceptor {
|
|
27
|
+
/**
|
|
28
|
+
* @returns {DefaultOptionsInterceptor}
|
|
29
|
+
*/
|
|
30
|
+
static create() {
|
|
31
|
+
return new DefaultOptionsInterceptor({webex: this});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @see Interceptor#onRequest
|
|
36
|
+
* @param {Object} options
|
|
37
|
+
* @returns {Object}
|
|
38
|
+
*/
|
|
39
|
+
onRequest(options) {
|
|
40
|
+
const {defaultRequestOptions: defaultOptions} = this.webex.config;
|
|
41
|
+
|
|
42
|
+
if (!defaultOptions) {
|
|
43
|
+
return options;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Object.keys(defaultOptions).forEach((key) => {
|
|
47
|
+
// don't override any existing option properties
|
|
48
|
+
if (!Object.keys(options).includes(key)) {
|
|
49
|
+
options[key] = defaultOptions[key];
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return options;
|
|
54
|
+
}
|
|
55
|
+
}
|