@webex/plugin-authorization-browser-first-party 3.0.0-beta.4 → 3.0.0-beta.400
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/authorization.js +10 -75
- package/dist/authorization.js.map +1 -1
- package/dist/config.js +0 -3
- package/dist/config.js.map +1 -1
- package/dist/index.js +1 -8
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/src/authorization.js +36 -36
- package/src/config.js +18 -17
- package/src/index.js +2 -5
- package/test/automation/fixtures/app.js +15 -15
- package/test/automation/fixtures/index.html +18 -15
- package/test/automation/spec/authorization-code-grant.js +86 -68
- package/test/unit/spec/authorization.js +202 -155
|
@@ -19,28 +19,28 @@ import Authorization from '@webex/plugin-authorization-browser-first-party';
|
|
|
19
19
|
// Necessary to require lodash this way in order to stub the method
|
|
20
20
|
const lodash = require('lodash');
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
24
23
|
describe('Authorization', () => {
|
|
25
|
-
function makeWebex(
|
|
24
|
+
function makeWebex(
|
|
25
|
+
href = 'https://example.com',
|
|
26
|
+
csrfToken = undefined,
|
|
27
|
+
pkceVerifier = undefined,
|
|
28
|
+
config = {}
|
|
29
|
+
) {
|
|
26
30
|
const mockWindow = {
|
|
27
31
|
history: {
|
|
28
32
|
replaceState(a, b, location) {
|
|
29
33
|
mockWindow.location.href = location;
|
|
30
|
-
}
|
|
34
|
+
},
|
|
31
35
|
},
|
|
32
36
|
location: {
|
|
33
|
-
href
|
|
37
|
+
href,
|
|
34
38
|
},
|
|
35
39
|
sessionStorage: {
|
|
36
|
-
getItem: sinon.stub()
|
|
37
|
-
.onCall(0)
|
|
38
|
-
.returns(pkceVerifier)
|
|
39
|
-
.onCall(1)
|
|
40
|
-
.returns(csrfToken),
|
|
40
|
+
getItem: sinon.stub().onCall(0).returns(pkceVerifier).onCall(1).returns(csrfToken),
|
|
41
41
|
removeItem: sinon.spy(),
|
|
42
|
-
setItem: sinon.spy()
|
|
43
|
-
}
|
|
42
|
+
setItem: sinon.spy(),
|
|
43
|
+
},
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
sinon.spy(mockWindow.history, 'replaceState');
|
|
@@ -49,42 +49,61 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
49
49
|
children: {
|
|
50
50
|
authorization: Authorization,
|
|
51
51
|
credentials: Credentials,
|
|
52
|
-
services: Services
|
|
52
|
+
services: Services,
|
|
53
53
|
},
|
|
54
|
-
request: sinon
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
request: sinon
|
|
55
|
+
.stub()
|
|
56
|
+
.returns(
|
|
57
|
+
Promise.resolve({body: {access_token: 'AT', token_type: 'Fake', refresh_token: 'RT'}})
|
|
58
|
+
),
|
|
59
|
+
config: merge(
|
|
60
|
+
{
|
|
61
|
+
credentials: {
|
|
62
|
+
idbroker: {
|
|
63
|
+
url: process.env.IDBROKER_BASE_URL,
|
|
64
|
+
defaultUrl: process.env.IDBROKER_BASE_URL,
|
|
65
|
+
},
|
|
66
|
+
identity: {
|
|
67
|
+
url: process.env.IDENTITY_BASE_URL,
|
|
68
|
+
defaultUrl: process.env.IDENTITY_BASE_URL,
|
|
69
|
+
},
|
|
70
|
+
activationUrl: `${
|
|
71
|
+
process.env.IDBROKER_BASE_URL || 'https://idbroker.webex.com'
|
|
72
|
+
}/idb/token/v1/actions/UserActivation/invoke`,
|
|
73
|
+
authorizeUrl: `${
|
|
74
|
+
process.env.IDBROKER_BASE_URL || 'https://idbroker.webex.com'
|
|
75
|
+
}/idb/oauth2/v1/authorize`,
|
|
76
|
+
setPasswordUrl: `${
|
|
77
|
+
process.env.IDBROKER_BASE_URL || 'https://identity.webex.com'
|
|
78
|
+
}/identity/scim/v1/Users`,
|
|
79
|
+
logoutUrl: `${
|
|
80
|
+
process.env.IDBROKER_BASE_URL || 'https://idbroker.webex.com'
|
|
81
|
+
}/idb/oauth2/v1/logout`,
|
|
82
|
+
// eslint-disable-next-line camelcase
|
|
83
|
+
client_id: 'fake',
|
|
84
|
+
// eslint-disable-next-line camelcase
|
|
85
|
+
client_secret: 'fake',
|
|
86
|
+
// eslint-disable-next-line camelcase
|
|
87
|
+
redirect_uri: 'http://example.com',
|
|
88
|
+
// eslint-disable-next-line camelcase
|
|
89
|
+
scope: 'scope:one',
|
|
90
|
+
refreshCallback: () => Promise.resolve(),
|
|
60
91
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
activationUrl: `${process.env.IDBROKER_BASE_URL || 'https://idbroker.webex.com'}/idb/token/v1/actions/UserActivation/invoke`,
|
|
66
|
-
authorizeUrl: `${process.env.IDBROKER_BASE_URL || 'https://idbroker.webex.com'}/idb/oauth2/v1/authorize`,
|
|
67
|
-
setPasswordUrl: `${process.env.IDBROKER_BASE_URL || 'https://identity.webex.com'}/identity/scim/v1/Users`,
|
|
68
|
-
logoutUrl: `${process.env.IDBROKER_BASE_URL || 'https://idbroker.webex.com'}/idb/oauth2/v1/logout`,
|
|
69
|
-
// eslint-disable-next-line camelcase
|
|
70
|
-
client_id: 'fake',
|
|
71
|
-
// eslint-disable-next-line camelcase
|
|
72
|
-
client_secret: 'fake',
|
|
73
|
-
// eslint-disable-next-line camelcase
|
|
74
|
-
redirect_uri: 'http://example.com',
|
|
75
|
-
// eslint-disable-next-line camelcase
|
|
76
|
-
scope: 'scope:one',
|
|
77
|
-
refreshCallback: () => Promise.resolve()
|
|
78
|
-
}
|
|
79
|
-
}, config),
|
|
92
|
+
},
|
|
93
|
+
config
|
|
94
|
+
),
|
|
80
95
|
getWindow() {
|
|
81
96
|
return mockWindow;
|
|
82
|
-
}
|
|
97
|
+
},
|
|
83
98
|
});
|
|
84
99
|
|
|
85
100
|
return webex;
|
|
86
101
|
}
|
|
87
102
|
|
|
103
|
+
afterEach(() => {
|
|
104
|
+
sinon.restore();
|
|
105
|
+
});
|
|
106
|
+
|
|
88
107
|
describe('#initialize()', () => {
|
|
89
108
|
describe('when there is a code in the url', () => {
|
|
90
109
|
it('exchanges it for an access token and sets ready', () => {
|
|
@@ -93,15 +112,14 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
93
112
|
assert.isFalse(webex.authorization.ready);
|
|
94
113
|
assert.isFalse(webex.credentials.canAuthorize);
|
|
95
114
|
|
|
96
|
-
return webex.authorization.when('change:ready')
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
});
|
|
115
|
+
return webex.authorization.when('change:ready').then(() => {
|
|
116
|
+
// Webex request gets called twice:
|
|
117
|
+
// once for the pre-auth catalog
|
|
118
|
+
// once for auth token exchange
|
|
119
|
+
assert.calledTwice(webex.request);
|
|
120
|
+
assert.isTrue(webex.authorization.ready);
|
|
121
|
+
assert.isTrue(webex.credentials.canAuthorize);
|
|
122
|
+
});
|
|
105
123
|
});
|
|
106
124
|
|
|
107
125
|
it('validates the csrf token', () => {
|
|
@@ -109,12 +127,20 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
109
127
|
|
|
110
128
|
assert.throws(() => {
|
|
111
129
|
// eslint-disable-next-line no-unused-vars
|
|
112
|
-
const webex = makeWebex(
|
|
130
|
+
const webex = makeWebex(
|
|
131
|
+
`http://example.com/?code=5&state=${base64.encode(
|
|
132
|
+
JSON.stringify({csrf_token: 'someothertoken'})
|
|
133
|
+
)}`,
|
|
134
|
+
csrfToken
|
|
135
|
+
);
|
|
113
136
|
}, /CSRF token someothertoken does not match stored token abcd/);
|
|
114
137
|
|
|
115
138
|
assert.throws(() => {
|
|
116
139
|
// eslint-disable-next-line no-unused-vars
|
|
117
|
-
const webex = makeWebex(
|
|
140
|
+
const webex = makeWebex(
|
|
141
|
+
`http://example.com/?code=5&state=${base64.encode(JSON.stringify({}))}`,
|
|
142
|
+
csrfToken
|
|
143
|
+
);
|
|
118
144
|
}, /Expected CSRF token abcd, but not found in redirect query/);
|
|
119
145
|
|
|
120
146
|
assert.throws(() => {
|
|
@@ -122,33 +148,67 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
122
148
|
const webex = makeWebex('http://example.com/?code=5', csrfToken);
|
|
123
149
|
}, /Expected CSRF token abcd, but not found in redirect query/);
|
|
124
150
|
|
|
125
|
-
const webex = makeWebex(
|
|
151
|
+
const webex = makeWebex(
|
|
152
|
+
`http://example.com/?code=5&state=${base64.encode(
|
|
153
|
+
JSON.stringify({csrf_token: csrfToken})
|
|
154
|
+
)}`,
|
|
155
|
+
csrfToken
|
|
156
|
+
);
|
|
126
157
|
|
|
127
|
-
return webex.authorization.when('change:ready')
|
|
128
|
-
.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
158
|
+
return webex.authorization.when('change:ready').then(() => {
|
|
159
|
+
assert.isTrue(webex.credentials.canAuthorize);
|
|
160
|
+
assert.called(webex.getWindow().sessionStorage.removeItem);
|
|
161
|
+
});
|
|
132
162
|
});
|
|
133
163
|
|
|
134
164
|
it('removes the oauth parameters from the url', () => {
|
|
135
165
|
const csrfToken = 'abcd';
|
|
136
166
|
|
|
137
|
-
const webex = makeWebex(
|
|
167
|
+
const webex = makeWebex(
|
|
168
|
+
`http://example.com/?code=5&state=${base64.encode(
|
|
169
|
+
JSON.stringify({csrf_token: csrfToken, something: true})
|
|
170
|
+
)}`,
|
|
171
|
+
csrfToken
|
|
172
|
+
);
|
|
138
173
|
|
|
139
|
-
return webex.authorization.when('change:ready')
|
|
140
|
-
.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
174
|
+
return webex.authorization.when('change:ready').then(() => {
|
|
175
|
+
assert.isTrue(webex.credentials.canAuthorize);
|
|
176
|
+
assert.called(webex.getWindow().sessionStorage.removeItem);
|
|
177
|
+
assert.called(webex.getWindow().history.replaceState);
|
|
178
|
+
assert.equal(
|
|
179
|
+
webex.getWindow().location.href,
|
|
180
|
+
`http://example.com/?state=${base64.encode(JSON.stringify({something: true}))}`
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('handles an error when exchanging an authorization code and becomes ready', () => {
|
|
186
|
+
const code = 'errors-when-exchanging';
|
|
187
|
+
const error = new Error('something bad happened');
|
|
188
|
+
const requestAuthorizationCodeGrantStub = sinon
|
|
189
|
+
.stub(Authorization.prototype, 'requestAuthorizationCodeGrant')
|
|
190
|
+
.throws(error);
|
|
191
|
+
|
|
192
|
+
const webex = makeWebex(`http://example.com?code=${code}`);
|
|
193
|
+
|
|
194
|
+
return webex.authorization.when('change:ready').then(() => {
|
|
195
|
+
assert.calledOnce(requestAuthorizationCodeGrantStub);
|
|
196
|
+
assert.calledWith(requestAuthorizationCodeGrantStub, {code, codeVerifier: undefined});
|
|
197
|
+
assert.calledOnce(webex.logger.warn);
|
|
198
|
+
assert.calledWith(
|
|
199
|
+
webex.logger.warn,
|
|
200
|
+
'authorization: failed initial authorization code grant request',
|
|
201
|
+
error
|
|
202
|
+
);
|
|
203
|
+
});
|
|
146
204
|
});
|
|
147
205
|
});
|
|
148
206
|
describe('when the url contains an error', () => {
|
|
149
207
|
it('throws a grant error', () => {
|
|
150
208
|
assert.throws(() => {
|
|
151
|
-
makeWebex(
|
|
209
|
+
makeWebex(
|
|
210
|
+
'http://127.0.0.1:8000/?error=invalid_scope&error_description=The%20requested%20scope%20is%20invalid.'
|
|
211
|
+
);
|
|
152
212
|
}, /The requested scope is invalid./);
|
|
153
213
|
});
|
|
154
214
|
});
|
|
@@ -166,28 +226,14 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
166
226
|
it('passes codeVerifier to requestAuthorizationCodeGrant', () => {
|
|
167
227
|
const expectedVerifier = 'test verifier';
|
|
168
228
|
|
|
169
|
-
const webex = makeWebex(
|
|
170
|
-
'http://example.com?code=5',
|
|
171
|
-
undefined,
|
|
172
|
-
expectedVerifier
|
|
173
|
-
);
|
|
229
|
+
const webex = makeWebex('http://example.com?code=5', undefined, expectedVerifier);
|
|
174
230
|
|
|
175
|
-
return webex.authorization.when('change:ready')
|
|
176
|
-
.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
);
|
|
182
|
-
assert.calledWith(
|
|
183
|
-
webex.getWindow().sessionStorage.removeItem,
|
|
184
|
-
'oauth2-code-verifier'
|
|
185
|
-
);
|
|
186
|
-
assert.equal(
|
|
187
|
-
webex.request.getCall(1).args[0].form.code_verifier,
|
|
188
|
-
expectedVerifier
|
|
189
|
-
);
|
|
190
|
-
});
|
|
231
|
+
return webex.authorization.when('change:ready').then(() => {
|
|
232
|
+
assert.calledTwice(webex.request);
|
|
233
|
+
assert.calledWith(webex.getWindow().sessionStorage.getItem, 'oauth2-code-verifier');
|
|
234
|
+
assert.calledWith(webex.getWindow().sessionStorage.removeItem, 'oauth2-code-verifier');
|
|
235
|
+
assert.equal(webex.request.getCall(1).args[0].form.code_verifier, expectedVerifier);
|
|
236
|
+
});
|
|
191
237
|
});
|
|
192
238
|
});
|
|
193
239
|
});
|
|
@@ -196,95 +242,97 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
196
242
|
it('calls #initiateAuthorizationCodeGrant()', () => {
|
|
197
243
|
const webex = makeWebex(undefined, undefined, {
|
|
198
244
|
credentials: {
|
|
199
|
-
clientType: 'confidential'
|
|
200
|
-
}
|
|
245
|
+
clientType: 'confidential',
|
|
246
|
+
},
|
|
201
247
|
});
|
|
202
248
|
|
|
203
249
|
sinon.spy(webex.authorization, 'initiateAuthorizationCodeGrant');
|
|
204
250
|
|
|
205
|
-
return webex.authorization.initiateLogin()
|
|
206
|
-
.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
});
|
|
251
|
+
return webex.authorization.initiateLogin().then(() => {
|
|
252
|
+
assert.called(webex.authorization.initiateAuthorizationCodeGrant);
|
|
253
|
+
assert.include(webex.getWindow().location, 'response_type=code');
|
|
254
|
+
});
|
|
210
255
|
});
|
|
211
256
|
|
|
212
257
|
it('adds a csrf_token to the login url and sessionStorage', () => {
|
|
213
258
|
const webex = makeWebex(undefined, undefined, {
|
|
214
259
|
credentials: {
|
|
215
|
-
clientType: 'confidential'
|
|
216
|
-
}
|
|
260
|
+
clientType: 'confidential',
|
|
261
|
+
},
|
|
217
262
|
});
|
|
218
263
|
|
|
219
264
|
sinon.spy(webex.authorization, 'initiateAuthorizationCodeGrant');
|
|
220
265
|
|
|
221
|
-
return webex.authorization.initiateLogin()
|
|
222
|
-
.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
266
|
+
return webex.authorization.initiateLogin().then(() => {
|
|
267
|
+
assert.called(webex.authorization.initiateAuthorizationCodeGrant);
|
|
268
|
+
assert.include(webex.getWindow().location, 'response_type=code');
|
|
269
|
+
const {query} = url.parse(webex.getWindow().location, true);
|
|
270
|
+
let {state} = query;
|
|
271
|
+
|
|
272
|
+
state = JSON.parse(base64.decode(state));
|
|
273
|
+
assert.property(state, 'csrf_token');
|
|
274
|
+
assert.isDefined(state.csrf_token);
|
|
275
|
+
assert.match(state.csrf_token, patterns.uuid);
|
|
276
|
+
assert.called(webex.getWindow().sessionStorage.setItem);
|
|
277
|
+
assert.calledWith(
|
|
278
|
+
webex.getWindow().sessionStorage.setItem,
|
|
279
|
+
'oauth2-csrf-token',
|
|
280
|
+
state.csrf_token
|
|
281
|
+
);
|
|
282
|
+
});
|
|
235
283
|
});
|
|
236
284
|
|
|
237
285
|
it('adds a pkce code challenge', () => {
|
|
238
286
|
const webex = makeWebex(undefined, undefined, {
|
|
239
287
|
credentials: {
|
|
240
|
-
clientType: 'confidential'
|
|
241
|
-
}
|
|
288
|
+
clientType: 'confidential',
|
|
289
|
+
},
|
|
242
290
|
});
|
|
243
291
|
|
|
244
292
|
const expectedCodeChallenge = 'test challenge';
|
|
245
293
|
|
|
246
294
|
sinon.spy(webex.authorization, 'initiateAuthorizationCodeGrant');
|
|
247
|
-
sinon.stub(webex.authorization, '_generateCodeChallenge')
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
});
|
|
295
|
+
sinon.stub(webex.authorization, '_generateCodeChallenge').returns(expectedCodeChallenge);
|
|
296
|
+
|
|
297
|
+
return webex.authorization.initiateLogin().then(() => {
|
|
298
|
+
assert.called(webex.authorization.initiateAuthorizationCodeGrant);
|
|
299
|
+
const grantOptions =
|
|
300
|
+
webex.authorization.initiateAuthorizationCodeGrant.getCall(0).args[0];
|
|
301
|
+
|
|
302
|
+
assert.equal(grantOptions.code_challenge, expectedCodeChallenge);
|
|
303
|
+
assert.equal(grantOptions.code_challenge_method, 'S256');
|
|
304
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
305
|
+
assert.calledWith(webex.authorization._generateCodeChallenge);
|
|
306
|
+
});
|
|
260
307
|
});
|
|
261
308
|
|
|
262
309
|
it('adds emailHash', () => {
|
|
263
310
|
const webex = makeWebex(undefined, undefined, {
|
|
264
311
|
credentials: {
|
|
265
|
-
clientType: 'confidential'
|
|
266
|
-
}
|
|
312
|
+
clientType: 'confidential',
|
|
313
|
+
},
|
|
267
314
|
});
|
|
268
315
|
|
|
269
|
-
const expectedEmailHash =
|
|
316
|
+
const expectedEmailHash =
|
|
317
|
+
'73062d872926c2a556f17b36f50e328ddf9bff9d403939bd14b6c3b7f5a33fc2';
|
|
270
318
|
|
|
271
319
|
sinon.spy(webex.authorization, 'initiateAuthorizationCodeGrant');
|
|
272
320
|
|
|
273
|
-
return webex.authorization.initiateLogin({email: 'test@email.com'})
|
|
274
|
-
.
|
|
275
|
-
|
|
276
|
-
|
|
321
|
+
return webex.authorization.initiateLogin({email: 'test@email.com'}).then(() => {
|
|
322
|
+
assert.called(webex.authorization.initiateAuthorizationCodeGrant);
|
|
323
|
+
const grantOptions =
|
|
324
|
+
webex.authorization.initiateAuthorizationCodeGrant.getCall(0).args[0];
|
|
277
325
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
326
|
+
assert.equal(grantOptions.emailHash, expectedEmailHash);
|
|
327
|
+
assert.isUndefined(grantOptions.email);
|
|
328
|
+
});
|
|
281
329
|
});
|
|
282
330
|
|
|
283
331
|
it('sets #isAuthorizing', () => {
|
|
284
332
|
const webex = makeWebex(undefined, undefined, {
|
|
285
333
|
credentials: {
|
|
286
|
-
clientType: 'confidential'
|
|
287
|
-
}
|
|
334
|
+
clientType: 'confidential',
|
|
335
|
+
},
|
|
288
336
|
});
|
|
289
337
|
|
|
290
338
|
assert.isFalse(webex.authorization.isAuthorizing);
|
|
@@ -298,8 +346,8 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
298
346
|
it('sets #isAuthenticating', () => {
|
|
299
347
|
const webex = makeWebex(undefined, undefined, {
|
|
300
348
|
credentials: {
|
|
301
|
-
clientType: 'confidential'
|
|
302
|
-
}
|
|
349
|
+
clientType: 'confidential',
|
|
350
|
+
},
|
|
303
351
|
});
|
|
304
352
|
|
|
305
353
|
assert.isFalse(webex.authorization.isAuthenticating);
|
|
@@ -315,17 +363,16 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
315
363
|
it('redirects to the login page with response_type=code', () => {
|
|
316
364
|
const webex = makeWebex(undefined, undefined, {
|
|
317
365
|
credentials: {
|
|
318
|
-
clientType: 'confidential'
|
|
319
|
-
}
|
|
366
|
+
clientType: 'confidential',
|
|
367
|
+
},
|
|
320
368
|
});
|
|
321
369
|
|
|
322
370
|
sinon.spy(webex.authorization, 'initiateAuthorizationCodeGrant');
|
|
323
371
|
|
|
324
|
-
return webex.authorization.initiateLogin()
|
|
325
|
-
.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
});
|
|
372
|
+
return webex.authorization.initiateLogin().then(() => {
|
|
373
|
+
assert.called(webex.authorization.initiateAuthorizationCodeGrant);
|
|
374
|
+
assert.include(webex.getWindow().location, 'response_type=code');
|
|
375
|
+
});
|
|
329
376
|
});
|
|
330
377
|
});
|
|
331
378
|
|
|
@@ -342,7 +389,7 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
342
389
|
const toStringStub = sinon.stub().returns(expectedCodeChallenge);
|
|
343
390
|
const randomStub = sinon.stub(lodash, 'random').returns(0);
|
|
344
391
|
const sha256Stub = sinon.stub(CryptoJS, 'SHA256').returns({
|
|
345
|
-
toString: toStringStub
|
|
392
|
+
toString: toStringStub,
|
|
346
393
|
});
|
|
347
394
|
|
|
348
395
|
// eslint-disable-next-line no-underscore-dangle
|
|
@@ -365,16 +412,16 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
365
412
|
it('removes the state parameter when it has no keys', () => {
|
|
366
413
|
const webex = makeWebex(undefined, undefined, {
|
|
367
414
|
credentials: {
|
|
368
|
-
clientType: 'confidential'
|
|
369
|
-
}
|
|
415
|
+
clientType: 'confidential',
|
|
416
|
+
},
|
|
370
417
|
});
|
|
371
418
|
const location = {
|
|
372
419
|
query: {
|
|
373
420
|
code: 'code',
|
|
374
421
|
state: {
|
|
375
|
-
csrf_token: 'token'
|
|
376
|
-
}
|
|
377
|
-
}
|
|
422
|
+
csrf_token: 'token',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
378
425
|
};
|
|
379
426
|
|
|
380
427
|
sinon.spy(webex.authorization, '_cleanUrl');
|
|
@@ -386,17 +433,17 @@ browserOnly(describe)('plugin-authorization-browser-first-party', () => {
|
|
|
386
433
|
it('keeps the parameter when it has keys', () => {
|
|
387
434
|
const webex = makeWebex(undefined, undefined, {
|
|
388
435
|
credentials: {
|
|
389
|
-
clientType: 'confidential'
|
|
390
|
-
}
|
|
436
|
+
clientType: 'confidential',
|
|
437
|
+
},
|
|
391
438
|
});
|
|
392
439
|
const location = {
|
|
393
440
|
query: {
|
|
394
441
|
code: 'code',
|
|
395
442
|
state: {
|
|
396
443
|
csrf_token: 'token',
|
|
397
|
-
key: 'value'
|
|
398
|
-
}
|
|
399
|
-
}
|
|
444
|
+
key: 'value',
|
|
445
|
+
},
|
|
446
|
+
},
|
|
400
447
|
};
|
|
401
448
|
|
|
402
449
|
sinon.spy(webex.authorization, '_cleanUrl');
|