@webex/webex-core 3.0.0-beta.3 → 3.0.0-beta.300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +1 -11
- package/dist/config.js.map +1 -1
- package/dist/credentials-config.js +44 -64
- package/dist/credentials-config.js.map +1 -1
- package/dist/index.js +0 -76
- package/dist/index.js.map +1 -1
- package/dist/interceptors/auth.js +22 -55
- package/dist/interceptors/auth.js.map +1 -1
- package/dist/interceptors/default-options.js +0 -20
- package/dist/interceptors/default-options.js.map +1 -1
- package/dist/interceptors/embargo.js +0 -21
- package/dist/interceptors/embargo.js.map +1 -1
- package/dist/interceptors/network-timing.js +2 -21
- package/dist/interceptors/network-timing.js.map +1 -1
- package/dist/interceptors/payload-transformer.js +2 -22
- package/dist/interceptors/payload-transformer.js.map +1 -1
- package/dist/interceptors/rate-limit.js +25 -57
- package/dist/interceptors/rate-limit.js.map +1 -1
- package/dist/interceptors/redirect.js +4 -33
- package/dist/interceptors/redirect.js.map +1 -1
- package/dist/interceptors/request-event.js +3 -30
- package/dist/interceptors/request-event.js.map +1 -1
- package/dist/interceptors/request-logger.js +1 -30
- package/dist/interceptors/request-logger.js.map +1 -1
- package/dist/interceptors/request-timing.js +3 -22
- package/dist/interceptors/request-timing.js.map +1 -1
- package/dist/interceptors/response-logger.js +2 -31
- package/dist/interceptors/response-logger.js.map +1 -1
- package/dist/interceptors/user-agent.js +2 -29
- package/dist/interceptors/user-agent.js.map +1 -1
- package/dist/interceptors/webex-tracking-id.js +5 -28
- package/dist/interceptors/webex-tracking-id.js.map +1 -1
- package/dist/interceptors/webex-user-agent.js +5 -38
- package/dist/interceptors/webex-user-agent.js.map +1 -1
- package/dist/lib/batcher.js +3 -51
- package/dist/lib/batcher.js.map +1 -1
- package/dist/lib/constants.js +14 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/credentials/credentials.js +98 -139
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/grant-errors.js +0 -49
- package/dist/lib/credentials/grant-errors.js.map +1 -1
- package/dist/lib/credentials/index.js +1 -13
- package/dist/lib/credentials/index.js.map +1 -1
- package/dist/lib/credentials/scope.js +22 -13
- package/dist/lib/credentials/scope.js.map +1 -1
- package/dist/lib/credentials/token-collection.js +1 -7
- package/dist/lib/credentials/token-collection.js.map +1 -1
- package/dist/lib/credentials/token.js +39 -118
- package/dist/lib/credentials/token.js.map +1 -1
- package/dist/lib/page.js +13 -26
- package/dist/lib/page.js.map +1 -1
- package/dist/lib/services/constants.js +0 -2
- package/dist/lib/services/constants.js.map +1 -1
- package/dist/lib/services/index.js +1 -28
- package/dist/lib/services/index.js.map +1 -1
- package/dist/lib/services/interceptors/server-error.js +2 -23
- package/dist/lib/services/interceptors/server-error.js.map +1 -1
- package/dist/lib/services/interceptors/service.js +15 -35
- package/dist/lib/services/interceptors/service.js.map +1 -1
- package/dist/lib/services/metrics.js +0 -2
- package/dist/lib/services/metrics.js.map +1 -1
- package/dist/lib/services/service-catalog.js +12 -91
- package/dist/lib/services/service-catalog.js.map +1 -1
- package/dist/lib/services/service-fed-ramp.js +0 -2
- package/dist/lib/services/service-fed-ramp.js.map +1 -1
- package/dist/lib/services/service-host.js +47 -62
- package/dist/lib/services/service-host.js.map +1 -1
- package/dist/lib/services/service-registry.js +78 -90
- package/dist/lib/services/service-registry.js.map +1 -1
- package/dist/lib/services/service-state.js +3 -15
- package/dist/lib/services/service-state.js.map +1 -1
- package/dist/lib/services/service-url.js +4 -25
- package/dist/lib/services/service-url.js.map +1 -1
- package/dist/lib/services/services.js +122 -238
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/stateless-webex-plugin.js +5 -28
- package/dist/lib/stateless-webex-plugin.js.map +1 -1
- package/dist/lib/storage/decorators.js +19 -62
- package/dist/lib/storage/decorators.js.map +1 -1
- package/dist/lib/storage/errors.js +0 -23
- package/dist/lib/storage/errors.js.map +1 -1
- package/dist/lib/storage/index.js +2 -16
- package/dist/lib/storage/index.js.map +1 -1
- package/dist/lib/storage/make-webex-plugin-store.js +11 -41
- package/dist/lib/storage/make-webex-plugin-store.js.map +1 -1
- package/dist/lib/storage/make-webex-store.js +8 -30
- package/dist/lib/storage/make-webex-store.js.map +1 -1
- package/dist/lib/storage/memory-store-adapter.js +1 -19
- package/dist/lib/storage/memory-store-adapter.js.map +1 -1
- package/dist/lib/webex-core-plugin-mixin.js +9 -29
- package/dist/lib/webex-core-plugin-mixin.js.map +1 -1
- package/dist/lib/webex-http-error.js +1 -31
- package/dist/lib/webex-http-error.js.map +1 -1
- package/dist/lib/webex-internal-core-plugin-mixin.js +9 -29
- package/dist/lib/webex-internal-core-plugin-mixin.js.map +1 -1
- package/dist/lib/webex-plugin.js +6 -40
- package/dist/lib/webex-plugin.js.map +1 -1
- package/dist/plugins/logger.js +3 -17
- package/dist/plugins/logger.js.map +1 -1
- package/dist/webex-core.js +84 -203
- package/dist/webex-core.js.map +1 -1
- package/dist/webex-internal-core.js +0 -10
- package/dist/webex-internal-core.js.map +1 -1
- package/package.json +14 -14
- package/src/config.js +9 -11
- package/src/credentials-config.js +110 -72
- package/src/index.js +4 -14
- package/src/interceptors/auth.js +36 -37
- package/src/interceptors/default-options.js +0 -1
- package/src/interceptors/embargo.js +1 -1
- package/src/interceptors/payload-transformer.js +1 -2
- package/src/interceptors/rate-limit.js +8 -5
- package/src/interceptors/redirect.js +14 -8
- package/src/interceptors/request-event.js +4 -8
- package/src/interceptors/request-logger.js +8 -5
- package/src/interceptors/response-logger.js +11 -8
- package/src/interceptors/user-agent.js +1 -2
- package/src/interceptors/webex-user-agent.js +3 -9
- package/src/lib/batcher.js +70 -69
- package/src/lib/constants.js +6 -0
- package/src/lib/credentials/credentials.js +173 -141
- package/src/lib/credentials/grant-errors.js +6 -7
- package/src/lib/credentials/index.js +1 -4
- package/src/lib/credentials/scope.js +20 -6
- package/src/lib/credentials/token-collection.js +1 -1
- package/src/lib/credentials/token.js +86 -80
- package/src/lib/page.js +10 -11
- package/src/lib/services/constants.js +3 -13
- package/src/lib/services/index.js +2 -2
- package/src/lib/services/interceptors/server-error.js +12 -7
- package/src/lib/services/interceptors/service.js +7 -6
- package/src/lib/services/metrics.js +1 -1
- package/src/lib/services/service-catalog.js +112 -100
- package/src/lib/services/service-fed-ramp.js +1 -2
- package/src/lib/services/service-host.js +10 -17
- package/src/lib/services/service-registry.js +69 -96
- package/src/lib/services/service-state.js +4 -6
- package/src/lib/services/service-url.js +24 -23
- package/src/lib/services/services.js +260 -251
- package/src/lib/stateless-webex-plugin.js +4 -2
- package/src/lib/storage/decorators.js +68 -66
- package/src/lib/storage/index.js +4 -6
- package/src/lib/storage/make-webex-plugin-store.js +34 -21
- package/src/lib/storage/make-webex-store.js +6 -7
- package/src/lib/storage/memory-store-adapter.js +3 -3
- package/src/lib/webex-core-plugin-mixin.js +10 -7
- package/src/lib/webex-http-error.js +7 -8
- package/src/lib/webex-internal-core-plugin-mixin.js +9 -6
- package/src/lib/webex-plugin.js +41 -34
- package/src/plugins/logger.js +8 -3
- package/src/webex-core.js +198 -117
- package/src/webex-internal-core.js +15 -9
- package/test/integration/spec/credentials/credentials.js +26 -30
- package/test/integration/spec/credentials/token.js +36 -33
- package/test/integration/spec/services/service-catalog.js +177 -156
- package/test/integration/spec/services/services.js +313 -304
- package/test/integration/spec/webex-core.js +98 -86
- package/test/unit/spec/_setup.js +26 -18
- package/test/unit/spec/credentials/credentials.js +352 -162
- package/test/unit/spec/credentials/scope.js +55 -0
- package/test/unit/spec/credentials/token.js +94 -76
- package/test/unit/spec/interceptors/auth.js +294 -243
- package/test/unit/spec/interceptors/default-options.js +36 -24
- package/test/unit/spec/interceptors/embargo.js +32 -27
- package/test/unit/spec/interceptors/network-timing.js +2 -2
- package/test/unit/spec/interceptors/payload-transformer.js +61 -52
- package/test/unit/spec/interceptors/rate-limit.js +104 -75
- package/test/unit/spec/interceptors/redirect.js +22 -20
- package/test/unit/spec/interceptors/request-timing.js +18 -22
- package/test/unit/spec/interceptors/user-agent.js +28 -16
- package/test/unit/spec/interceptors/webex-tracking-id.js +14 -8
- package/test/unit/spec/interceptors/webex-user-agent.js +83 -37
- package/test/unit/spec/lib/batcher.js +36 -32
- package/test/unit/spec/lib/page.js +36 -32
- package/test/unit/spec/lib/webex-plugin.js +1 -1
- package/test/unit/spec/services/interceptors/server-error.js +67 -90
- package/test/unit/spec/services/interceptors/service.js +23 -28
- package/test/unit/spec/services/service-catalog.js +19 -27
- package/test/unit/spec/services/service-host.js +29 -26
- package/test/unit/spec/services/service-registry.js +128 -170
- package/test/unit/spec/services/service-state.js +13 -22
- package/test/unit/spec/services/service-url.js +24 -43
- package/test/unit/spec/services/services.js +85 -41
- package/test/unit/spec/storage/persist.js +6 -9
- package/test/unit/spec/storage/wait-for-value.js +22 -21
- package/test/unit/spec/webex-core.js +90 -57
- package/test/unit/spec/webex-internal-core.js +56 -31
|
@@ -10,14 +10,9 @@ import sinon from 'sinon';
|
|
|
10
10
|
import {browserOnly, nodeOnly} from '@webex/test-helper-mocha';
|
|
11
11
|
import Logger from '@webex/plugin-logger';
|
|
12
12
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
13
|
-
import {
|
|
14
|
-
AuthInterceptor,
|
|
15
|
-
config,
|
|
16
|
-
Credentials,
|
|
17
|
-
WebexHttpError,
|
|
18
|
-
Token
|
|
19
|
-
} from '@webex/webex-core';
|
|
13
|
+
import {AuthInterceptor, config, Credentials, WebexHttpError, Token} from '@webex/webex-core';
|
|
20
14
|
import {cloneDeep, merge} from 'lodash';
|
|
15
|
+
import Metrics from '@webex/internal-plugin-metrics';
|
|
21
16
|
|
|
22
17
|
const {assert} = chai;
|
|
23
18
|
|
|
@@ -33,64 +28,85 @@ describe('webex-core', () => {
|
|
|
33
28
|
webex = new MockWebex({
|
|
34
29
|
children: {
|
|
35
30
|
credentials: Credentials,
|
|
36
|
-
logger: Logger
|
|
31
|
+
logger: Logger,
|
|
32
|
+
metrics: Metrics,
|
|
37
33
|
},
|
|
38
|
-
config: merge(cloneDeep(config), {credentials: {client_secret: 'fake'}})
|
|
34
|
+
config: merge(cloneDeep(config), {credentials: {client_secret: 'fake'}}),
|
|
39
35
|
});
|
|
40
36
|
|
|
41
|
-
webex.credentials.supertoken = new Token(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
webex.credentials.supertoken = new Token(
|
|
38
|
+
{
|
|
39
|
+
access_token: 'ST1',
|
|
40
|
+
token_type: 'Bearer',
|
|
41
|
+
},
|
|
42
|
+
{parent: webex}
|
|
43
|
+
);
|
|
45
44
|
|
|
46
45
|
interceptor = Reflect.apply(AuthInterceptor.create, webex, []);
|
|
46
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
describe('#onRequest()', () => {
|
|
50
|
-
it('does not replace the auth header if one has been provided', () =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
it('does not replace the auth header if one has been provided', () =>
|
|
51
|
+
interceptor
|
|
52
|
+
.onRequest({
|
|
53
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
54
|
+
headers: {
|
|
55
|
+
authorization: 'Bearer Alternate',
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
.then((result) =>
|
|
59
|
+
assert.deepEqual(result, {
|
|
60
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
61
|
+
headers: {
|
|
62
|
+
authorization: 'Bearer Alternate',
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
));
|
|
62
66
|
|
|
63
67
|
[undefined, null, false].forEach((falsey) => {
|
|
64
|
-
it(`does not add an auth header if ${falsey} has been provided`, () =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
it(`does not add an auth header if ${falsey} has been provided`, () =>
|
|
69
|
+
interceptor
|
|
70
|
+
.onRequest({
|
|
71
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
72
|
+
headers: {
|
|
73
|
+
authorization: falsey,
|
|
74
|
+
},
|
|
75
|
+
})
|
|
76
|
+
.then((result) =>
|
|
77
|
+
assert.deepEqual(result, {
|
|
78
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
79
|
+
headers: {},
|
|
80
|
+
})
|
|
81
|
+
));
|
|
74
82
|
});
|
|
75
83
|
|
|
76
84
|
// There should never be a case in which the services plugin is not
|
|
77
85
|
// loaded. But testing for legacy support.
|
|
78
86
|
describe('when the services plugin has not been loaded', () => {
|
|
79
|
-
it('does not add the auth header to hydra requests', () =>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
it('does not add the auth header to hydra requests', () =>
|
|
88
|
+
interceptor
|
|
89
|
+
.onRequest({
|
|
90
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
91
|
+
})
|
|
92
|
+
.then((result) =>
|
|
93
|
+
assert.deepEqual(result, {
|
|
94
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
95
|
+
headers: {},
|
|
96
|
+
})
|
|
97
|
+
));
|
|
98
|
+
|
|
99
|
+
it('does not add the auth header to u2c requests', () =>
|
|
100
|
+
interceptor
|
|
101
|
+
.onRequest({
|
|
102
|
+
uri: `${config.services.discovery.u2c}/ping`,
|
|
103
|
+
})
|
|
104
|
+
.then((result) =>
|
|
105
|
+
assert.deepEqual(result, {
|
|
106
|
+
uri: `${config.services.discovery.u2c}/ping`,
|
|
107
|
+
headers: {},
|
|
108
|
+
})
|
|
109
|
+
));
|
|
94
110
|
});
|
|
95
111
|
|
|
96
112
|
describe('when the services plugin has been loaded', () => {
|
|
@@ -99,17 +115,14 @@ describe('webex-core', () => {
|
|
|
99
115
|
beforeEach(() => {
|
|
100
116
|
services = {
|
|
101
117
|
hydra: 'https://hydra-a.wbx.com',
|
|
102
|
-
example: 'https://service.example.com'
|
|
118
|
+
example: 'https://service.example.com',
|
|
103
119
|
};
|
|
104
120
|
|
|
105
121
|
webex.internal.services = {
|
|
106
122
|
hasService: (service) => Object.keys(services).includes(service),
|
|
107
123
|
hasAllowedDomains: () => true,
|
|
108
|
-
isAllowedDomainUrl: (uri) =>
|
|
109
|
-
.find(
|
|
110
|
-
(host) => uri.includes(host)
|
|
111
|
-
)
|
|
112
|
-
),
|
|
124
|
+
isAllowedDomainUrl: (uri) =>
|
|
125
|
+
!!config.services.allowedDomains.find((host) => uri.includes(host)),
|
|
113
126
|
getServiceFromUrl: (uri) => {
|
|
114
127
|
let targetKey;
|
|
115
128
|
|
|
@@ -120,78 +133,94 @@ describe('webex-core', () => {
|
|
|
120
133
|
});
|
|
121
134
|
|
|
122
135
|
return targetKey ? {name: targetKey} : undefined;
|
|
123
|
-
}
|
|
136
|
+
},
|
|
124
137
|
};
|
|
125
138
|
|
|
126
|
-
webex.internal.services.waitForService = (pto) =>
|
|
127
|
-
services[pto.name] || pto.url
|
|
128
|
-
);
|
|
139
|
+
webex.internal.services.waitForService = (pto) =>
|
|
140
|
+
Promise.resolve(services[pto.name] || pto.url);
|
|
129
141
|
});
|
|
130
142
|
|
|
131
|
-
it('adds the header to hydra requests', () =>
|
|
132
|
-
|
|
133
|
-
.then((result) =>
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
143
|
+
it('adds the header to hydra requests', () =>
|
|
144
|
+
Promise.all([
|
|
145
|
+
interceptor.onRequest({uri: `${services.hydra}/ping`}).then((result) =>
|
|
146
|
+
assert.deepEqual(result, {
|
|
147
|
+
uri: `${services.hydra}/ping`,
|
|
148
|
+
headers: {
|
|
149
|
+
authorization: 'Bearer ST1',
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
),
|
|
153
|
+
interceptor
|
|
154
|
+
.onRequest({
|
|
155
|
+
service: 'hydra',
|
|
156
|
+
resource: 'ping',
|
|
157
|
+
})
|
|
158
|
+
.then((result) =>
|
|
159
|
+
assert.deepEqual(result, {
|
|
160
|
+
service: 'hydra',
|
|
161
|
+
resource: 'ping',
|
|
162
|
+
headers: {
|
|
163
|
+
authorization: 'Bearer ST1',
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
),
|
|
167
|
+
]));
|
|
168
|
+
|
|
169
|
+
it('adds an auth header to uris that are in the service catalog', () =>
|
|
170
|
+
interceptor
|
|
171
|
+
.onRequest({
|
|
157
172
|
uri: `${services.example}/ping`,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
})
|
|
174
|
+
.then((result) =>
|
|
175
|
+
assert.deepEqual(result, {
|
|
176
|
+
uri: `${services.example}/ping`,
|
|
177
|
+
headers: {
|
|
178
|
+
authorization: 'Bearer ST1',
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
));
|
|
162
182
|
|
|
163
|
-
it('adds an auth header to services that are in the service catalog',
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
resource: 'some-resource'
|
|
167
|
-
})
|
|
168
|
-
.then((result) => assert.deepEqual(result, {
|
|
183
|
+
it('adds an auth header to services that are in the service catalog', () =>
|
|
184
|
+
interceptor
|
|
185
|
+
.onRequest({
|
|
169
186
|
service: 'example',
|
|
170
187
|
resource: 'some-resource',
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
})
|
|
189
|
+
.then((result) =>
|
|
190
|
+
assert.deepEqual(result, {
|
|
191
|
+
service: 'example',
|
|
192
|
+
resource: 'some-resource',
|
|
193
|
+
headers: {
|
|
194
|
+
authorization: 'Bearer ST1',
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
));
|
|
198
|
+
|
|
199
|
+
it('does not add an auth header to uris not in the service catalog', () =>
|
|
200
|
+
interceptor
|
|
201
|
+
.onRequest({
|
|
202
|
+
uri: 'https://not-a-service.com/ping',
|
|
203
|
+
})
|
|
204
|
+
.then((result) =>
|
|
205
|
+
assert.deepEqual(result, {
|
|
206
|
+
headers: {},
|
|
207
|
+
uri: 'https://not-a-service.com/ping',
|
|
208
|
+
})
|
|
209
|
+
));
|
|
210
|
+
|
|
211
|
+
it('does not add an auth header to non-existant services', () =>
|
|
212
|
+
interceptor
|
|
213
|
+
.onRequest({
|
|
192
214
|
service: 'non-existant',
|
|
193
|
-
resource: 'no-resource'
|
|
194
|
-
})
|
|
215
|
+
resource: 'no-resource',
|
|
216
|
+
})
|
|
217
|
+
.then((result) =>
|
|
218
|
+
assert.deepEqual(result, {
|
|
219
|
+
headers: {},
|
|
220
|
+
service: 'non-existant',
|
|
221
|
+
resource: 'no-resource',
|
|
222
|
+
})
|
|
223
|
+
));
|
|
195
224
|
});
|
|
196
225
|
});
|
|
197
226
|
|
|
@@ -202,7 +231,7 @@ describe('webex-core', () => {
|
|
|
202
231
|
services = {
|
|
203
232
|
hydra: 'https://hydra-a.wbx.com',
|
|
204
233
|
u2c: 'https://u2c.wbx2.com/u2c/api/v1',
|
|
205
|
-
example: 'https://service.example.com'
|
|
234
|
+
example: 'https://service.example.com',
|
|
206
235
|
};
|
|
207
236
|
|
|
208
237
|
webex.internal.services = {
|
|
@@ -219,17 +248,13 @@ describe('webex-core', () => {
|
|
|
219
248
|
},
|
|
220
249
|
hasService: (service) => Object.keys(services).includes(service),
|
|
221
250
|
hasAllowedDomains: () => true,
|
|
222
|
-
isAllowedDomainUrl: (uri) =>
|
|
223
|
-
.find(
|
|
224
|
-
|
|
225
|
-
)
|
|
226
|
-
),
|
|
227
|
-
validateDomains: true
|
|
251
|
+
isAllowedDomainUrl: (uri) =>
|
|
252
|
+
!!config.services.allowedDomains.find((host) => uri.includes(host)),
|
|
253
|
+
validateDomains: true,
|
|
228
254
|
};
|
|
229
255
|
|
|
230
|
-
webex.internal.services.waitForService = (pto) =>
|
|
231
|
-
services[pto.name] || pto.url
|
|
232
|
-
);
|
|
256
|
+
webex.internal.services.waitForService = (pto) =>
|
|
257
|
+
Promise.resolve(services[pto.name] || pto.url);
|
|
233
258
|
});
|
|
234
259
|
|
|
235
260
|
afterEach('remove services plugin', () => {
|
|
@@ -238,76 +263,84 @@ describe('webex-core', () => {
|
|
|
238
263
|
}
|
|
239
264
|
});
|
|
240
265
|
|
|
241
|
-
it('resolves to false when services plugin does not exist',
|
|
242
|
-
|
|
243
|
-
delete webex.internal.services;
|
|
266
|
+
it('resolves to false when services plugin does not exist', () => {
|
|
267
|
+
delete webex.internal.services;
|
|
244
268
|
|
|
245
|
-
|
|
246
|
-
|
|
269
|
+
return interceptor
|
|
270
|
+
.requiresCredentials({
|
|
271
|
+
uri: `${services.hydra}/ping`,
|
|
247
272
|
})
|
|
248
|
-
|
|
249
|
-
|
|
273
|
+
.then((response) => assert.isFalse(response));
|
|
274
|
+
});
|
|
250
275
|
|
|
251
|
-
it('resolves to true when the u2c service is specified via service',
|
|
252
|
-
|
|
253
|
-
services = {};
|
|
276
|
+
it('resolves to true when the u2c service is specified via service', () => {
|
|
277
|
+
services = {};
|
|
254
278
|
|
|
255
|
-
|
|
279
|
+
return interceptor
|
|
280
|
+
.requiresCredentials({
|
|
256
281
|
service: 'u2c',
|
|
257
|
-
resource: 'something'
|
|
282
|
+
resource: 'something',
|
|
258
283
|
})
|
|
259
|
-
|
|
260
|
-
|
|
284
|
+
.then((response) => assert.isTrue(response));
|
|
285
|
+
});
|
|
261
286
|
|
|
262
|
-
it('resolves to false when the u2c limited service is used via uri',
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
287
|
+
it('resolves to false when the u2c limited service is used via uri', () =>
|
|
288
|
+
interceptor
|
|
289
|
+
.requiresCredentials({
|
|
290
|
+
uri: `${services.u2c}/limited`,
|
|
291
|
+
})
|
|
266
292
|
.then((response) => assert.isFalse(response)));
|
|
267
293
|
|
|
268
|
-
it('resolves to true if the service exists in catalog via service',
|
|
269
|
-
|
|
294
|
+
it('resolves to true if the service exists in catalog via service', () =>
|
|
295
|
+
interceptor
|
|
296
|
+
.requiresCredentials({service: 'hydra'})
|
|
270
297
|
.then((response) => assert.isTrue(response)));
|
|
271
298
|
|
|
272
|
-
it('resolves to true if the service exists in catalog via uri',
|
|
273
|
-
|
|
299
|
+
it('resolves to true if the service exists in catalog via uri', () =>
|
|
300
|
+
interceptor
|
|
301
|
+
.requiresCredentials({uri: services.hydra})
|
|
274
302
|
.then((response) => assert.isTrue(response)));
|
|
275
303
|
|
|
276
|
-
it('resolves to false if that `addAuthHeader` is set to false',
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
304
|
+
it('resolves to false if that `addAuthHeader` is set to false', () =>
|
|
305
|
+
interceptor
|
|
306
|
+
.requiresCredentials({
|
|
307
|
+
addAuthHeader: false,
|
|
308
|
+
service: 'unknown',
|
|
309
|
+
resource: 'ping',
|
|
310
|
+
})
|
|
282
311
|
.then((response) => assert.isFalse(response)));
|
|
283
312
|
|
|
284
|
-
it('resolves to false if `validateDomains` is set to false',
|
|
285
|
-
|
|
286
|
-
webex.internal.services.validateDomains = false;
|
|
313
|
+
it('resolves to false if `validateDomains` is set to false', () => {
|
|
314
|
+
webex.internal.services.validateDomains = false;
|
|
287
315
|
|
|
288
|
-
|
|
289
|
-
|
|
316
|
+
return interceptor
|
|
317
|
+
.requiresCredentials({
|
|
318
|
+
uri: 'https://allowed-uri.com/resource',
|
|
290
319
|
})
|
|
291
|
-
|
|
292
|
-
|
|
320
|
+
.then((response) => assert.isFalse(response));
|
|
321
|
+
});
|
|
293
322
|
|
|
294
|
-
it('resolves to true with an allowed domain uri',
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
323
|
+
it('resolves to true with an allowed domain uri', () =>
|
|
324
|
+
interceptor
|
|
325
|
+
.requiresCredentials({
|
|
326
|
+
uri: `https://${config.services.allowedDomains[0]}/resource`,
|
|
327
|
+
})
|
|
298
328
|
.then((response) => assert.isTrue(response)));
|
|
299
329
|
|
|
300
|
-
it('resolves to false with a non-allowed uri',
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
330
|
+
it('resolves to false with a non-allowed uri', () =>
|
|
331
|
+
interceptor
|
|
332
|
+
.requiresCredentials({
|
|
333
|
+
uri: 'https://not-allowed/resource',
|
|
334
|
+
})
|
|
304
335
|
.then((response) => assert.isFalse(response)));
|
|
305
336
|
|
|
306
337
|
it('should return true if domain exists using isAllowedDomainUrl()', () => {
|
|
307
338
|
webex.internal.services.waitForService = sinon.stub();
|
|
308
339
|
const {isAllowedDomainUrl} = webex.internal.services;
|
|
309
340
|
|
|
310
|
-
const result = isAllowedDomainUrl(
|
|
341
|
+
const result = isAllowedDomainUrl(
|
|
342
|
+
`https://${config.services.allowedDomains[0]}/resource`
|
|
343
|
+
);
|
|
311
344
|
|
|
312
345
|
assert.equal(result, true);
|
|
313
346
|
});
|
|
@@ -315,23 +348,25 @@ describe('webex-core', () => {
|
|
|
315
348
|
it('should return true when called `requiresCredentials` with valid url', () => {
|
|
316
349
|
webex.internal.services.waitForService = sinon.stub();
|
|
317
350
|
|
|
318
|
-
return interceptor
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
351
|
+
return interceptor
|
|
352
|
+
.requiresCredentials({
|
|
353
|
+
uri: `https://${config.services.allowedDomains[0]}/resource`,
|
|
354
|
+
})
|
|
355
|
+
.then((res) => {
|
|
356
|
+
assert.equal(res, true);
|
|
357
|
+
});
|
|
322
358
|
});
|
|
323
359
|
|
|
324
360
|
it('should call waitForService()', () => {
|
|
325
361
|
webex.internal.services.waitForService = sinon.stub();
|
|
326
362
|
const {waitForService} = webex.internal.services;
|
|
327
363
|
|
|
328
|
-
waitForService.resolves(
|
|
329
|
-
`https://${config.services.allowedDomains[0]}/resource`
|
|
330
|
-
);
|
|
364
|
+
waitForService.resolves(`https://${config.services.allowedDomains[0]}/resource`);
|
|
331
365
|
|
|
332
|
-
return interceptor
|
|
333
|
-
|
|
334
|
-
|
|
366
|
+
return interceptor
|
|
367
|
+
.requiresCredentials({
|
|
368
|
+
service: 'locus',
|
|
369
|
+
})
|
|
335
370
|
.then(() => assert.calledOnce(waitForService));
|
|
336
371
|
});
|
|
337
372
|
});
|
|
@@ -339,96 +374,108 @@ describe('webex-core', () => {
|
|
|
339
374
|
describe('#onResponseError()', () => {
|
|
340
375
|
describe('when the server responds with 401', () => {
|
|
341
376
|
nodeOnly(it)('refreshes the access token and replays the request', () => {
|
|
342
|
-
webex.request.onCall(0).returns(
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
377
|
+
webex.request.onCall(0).returns(
|
|
378
|
+
Promise.resolve({
|
|
379
|
+
body: {
|
|
380
|
+
access_token: 'ST2',
|
|
381
|
+
},
|
|
382
|
+
})
|
|
383
|
+
);
|
|
384
|
+
webex.credentials.supertoken = new Token(
|
|
385
|
+
{
|
|
386
|
+
access_token: 'ST1',
|
|
387
|
+
refresh_token: 'RT1',
|
|
388
|
+
},
|
|
389
|
+
{parent: webex}
|
|
390
|
+
);
|
|
351
391
|
|
|
352
392
|
const err = new WebexHttpError.Unauthorized({
|
|
353
393
|
statusCode: 401,
|
|
354
394
|
options: {
|
|
355
395
|
headers: {
|
|
356
|
-
trackingid: 'blarg'
|
|
396
|
+
trackingid: 'blarg',
|
|
357
397
|
},
|
|
358
|
-
uri: `${config.services.discovery.hydra}/ping
|
|
398
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
359
399
|
},
|
|
360
400
|
body: {
|
|
361
|
-
error: 'fake error'
|
|
362
|
-
}
|
|
401
|
+
error: 'fake error',
|
|
402
|
+
},
|
|
363
403
|
});
|
|
364
404
|
|
|
365
405
|
assert.notCalled(webex.request);
|
|
366
406
|
|
|
367
|
-
return interceptor.onResponseError(err.options, err)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
});
|
|
407
|
+
return interceptor.onResponseError(err.options, err).then(() => {
|
|
408
|
+
// once for refresh, once for replay
|
|
409
|
+
assert.calledTwice(webex.request);
|
|
410
|
+
assert.equal(webex.credentials.supertoken.access_token, 'ST2');
|
|
411
|
+
assert.equal(webex.request.args[1][0].replayCount, 1);
|
|
412
|
+
});
|
|
374
413
|
});
|
|
375
414
|
|
|
376
415
|
browserOnly(it)('refreshes the access token and replays the request', () => {
|
|
377
|
-
webex.config.credentials.refreshCallback = sinon.stub().returns(
|
|
378
|
-
|
|
379
|
-
|
|
416
|
+
webex.config.credentials.refreshCallback = sinon.stub().returns(
|
|
417
|
+
Promise.resolve({
|
|
418
|
+
access_token: 'ST2',
|
|
419
|
+
})
|
|
420
|
+
);
|
|
380
421
|
|
|
381
|
-
webex.credentials.supertoken = new Token(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
422
|
+
webex.credentials.supertoken = new Token(
|
|
423
|
+
{
|
|
424
|
+
access_token: 'ST1',
|
|
425
|
+
refresh_token: 'RT1',
|
|
426
|
+
},
|
|
427
|
+
{parent: webex}
|
|
428
|
+
);
|
|
385
429
|
|
|
386
430
|
const err = new WebexHttpError.Unauthorized({
|
|
387
431
|
statusCode: 401,
|
|
388
432
|
options: {
|
|
389
433
|
headers: {
|
|
390
|
-
trackingid: 'blarg'
|
|
434
|
+
trackingid: 'blarg',
|
|
391
435
|
},
|
|
392
|
-
uri: `${config.services.discovery.hydra}/ping
|
|
436
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
393
437
|
},
|
|
394
438
|
body: {
|
|
395
|
-
error: 'fake error'
|
|
396
|
-
}
|
|
439
|
+
error: 'fake error',
|
|
440
|
+
},
|
|
397
441
|
});
|
|
398
442
|
|
|
399
443
|
assert.notCalled(webex.request);
|
|
400
444
|
|
|
401
|
-
return interceptor.onResponseError(err.options, err)
|
|
402
|
-
.then(() => {
|
|
445
|
+
return interceptor.onResponseError(err.options, err).then(() => {
|
|
403
446
|
// once for replay
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
447
|
+
assert.calledOnce(webex.request);
|
|
448
|
+
assert.equal(webex.credentials.supertoken.access_token, 'ST2');
|
|
449
|
+
assert.equal(webex.request.args[0][0].replayCount, 1);
|
|
450
|
+
});
|
|
408
451
|
});
|
|
409
452
|
|
|
410
453
|
describe('when the access token is not refreshable', () => {
|
|
411
454
|
it('responds with the original error', () => {
|
|
412
|
-
webex.credentials.supertoken = new Token(
|
|
413
|
-
|
|
414
|
-
|
|
455
|
+
webex.credentials.supertoken = new Token(
|
|
456
|
+
{
|
|
457
|
+
access_token: 'ST1',
|
|
458
|
+
},
|
|
459
|
+
{parent: webex}
|
|
460
|
+
);
|
|
415
461
|
|
|
416
462
|
const err = new WebexHttpError.Unauthorized({
|
|
417
463
|
statusCode: 401,
|
|
418
464
|
options: {
|
|
419
465
|
headers: {
|
|
420
|
-
trackingid: 'blarg'
|
|
466
|
+
trackingid: 'blarg',
|
|
421
467
|
},
|
|
422
|
-
uri: `${config.services.discovery.hydra}/ping
|
|
468
|
+
uri: `${config.services.discovery.hydra}/ping`,
|
|
423
469
|
},
|
|
424
470
|
body: {
|
|
425
|
-
error: 'fake error'
|
|
426
|
-
}
|
|
471
|
+
error: 'fake error',
|
|
472
|
+
},
|
|
427
473
|
});
|
|
428
474
|
|
|
429
475
|
assert.notCalled(webex.request);
|
|
430
476
|
|
|
431
|
-
return assert
|
|
477
|
+
return assert
|
|
478
|
+
.isRejected(interceptor.onResponseError(err.options, err))
|
|
432
479
|
.then((err2) => {
|
|
433
480
|
assert.equal(err2, err);
|
|
434
481
|
});
|
|
@@ -436,35 +483,39 @@ describe('webex-core', () => {
|
|
|
436
483
|
});
|
|
437
484
|
|
|
438
485
|
it('does not refresh if shouldRefreshAccessToken was false', () => {
|
|
439
|
-
webex.config.credentials.refreshCallback = sinon.stub().returns(
|
|
440
|
-
|
|
441
|
-
|
|
486
|
+
webex.config.credentials.refreshCallback = sinon.stub().returns(
|
|
487
|
+
Promise.resolve({
|
|
488
|
+
access_token: 'ST2',
|
|
489
|
+
})
|
|
490
|
+
);
|
|
442
491
|
|
|
443
|
-
webex.credentials.supertoken = new Token(
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
492
|
+
webex.credentials.supertoken = new Token(
|
|
493
|
+
{
|
|
494
|
+
access_token: 'ST1',
|
|
495
|
+
refresh_token: 'RT1',
|
|
496
|
+
},
|
|
497
|
+
{parent: webex}
|
|
498
|
+
);
|
|
447
499
|
|
|
448
500
|
const err = new WebexHttpError.Unauthorized({
|
|
449
501
|
statusCode: 401,
|
|
450
502
|
options: {
|
|
451
503
|
headers: {
|
|
452
|
-
trackingid: 'blarg'
|
|
504
|
+
trackingid: 'blarg',
|
|
453
505
|
},
|
|
454
506
|
uri: `${config.services.discovery.hydra}/ping`,
|
|
455
|
-
shouldRefreshAccessToken: false
|
|
507
|
+
shouldRefreshAccessToken: false,
|
|
456
508
|
},
|
|
457
509
|
body: {
|
|
458
|
-
error: 'fake error'
|
|
459
|
-
}
|
|
510
|
+
error: 'fake error',
|
|
511
|
+
},
|
|
460
512
|
});
|
|
461
513
|
|
|
462
514
|
assert.notCalled(webex.request);
|
|
463
515
|
|
|
464
|
-
return assert.isRejected(interceptor.onResponseError(err.options, err))
|
|
465
|
-
.
|
|
466
|
-
|
|
467
|
-
});
|
|
516
|
+
return assert.isRejected(interceptor.onResponseError(err.options, err)).then((err2) => {
|
|
517
|
+
assert.equal(err2, err);
|
|
518
|
+
});
|
|
468
519
|
});
|
|
469
520
|
});
|
|
470
521
|
});
|