1 |
|
2 | ;(function () {
|
3 | var AccessToken, AnvilConnect, IDToken, chai, cwd, expect, nock, path, sinon, sinonChai
|
4 |
|
5 | cwd = process.cwd()
|
6 | path = require('path')
|
7 | chai = require('chai')
|
8 | sinon = require('sinon')
|
9 | sinonChai = require('sinon-chai')
|
10 | expect = chai.expect
|
11 | nock = require('nock')
|
12 |
|
13 | chai.use(sinonChai)
|
14 | chai.should()
|
15 |
|
16 | AnvilConnect = require(path.join(cwd, 'index'))
|
17 | AccessToken = require(path.join(cwd, 'lib', 'AccessToken'))
|
18 | IDToken = require(path.join(cwd, 'lib', 'IDToken'))
|
19 |
|
20 | describe('Anvil Connect Client', function () {
|
21 |
|
22 | var anvil = {}
|
23 | var failure = {}
|
24 | var promise = {}
|
25 | var success = {}
|
26 | var config = {
|
27 | issuer: 'https://connect.anvil.io',
|
28 | client_id: 'uuid',
|
29 | client_secret: 'secret',
|
30 | redirect_uri: 'https://app.example.com/callback'
|
31 | }
|
32 | var openid = {
|
33 | 'issuer': 'https://connect.anvil.io',
|
34 | 'authorization_endpoint': 'https://connect.anvil.io/authorize',
|
35 | 'token_endpoint': 'https://connect.anvil.io/token',
|
36 | 'userinfo_endpoint': 'https://connect.anvil.io/userinfo',
|
37 | 'jwks_uri': 'https://connect.anvil.io/jwks',
|
38 | 'registration_endpoint': 'https://connect.anvil.io/register',
|
39 | 'scopes_supported': ['realm', 'client', 'profile', 'openid'],
|
40 | 'response_types_supported': ['code', 'token id_token'],
|
41 | 'response_modes_supported': [],
|
42 | 'grant_types_supported': ['authorization_code', 'refresh_token'],
|
43 | 'acr_values_supported': [],
|
44 | 'subject_types_supported': ['public'],
|
45 | 'id_token_signing_alg_values_supported': ['RS256'],
|
46 | 'id_token_encryption_alg_values_supported': [],
|
47 | 'id_token_encryption_enc_values_supported': [],
|
48 | 'userinfo_signing_alg_values_supported': ['none'],
|
49 | 'userinfo_encryption_alg_values_supported': [],
|
50 | 'userinfo_encryption_enc_values_supported': [],
|
51 | 'request_object_signing_alg_values_supported': [],
|
52 | 'request_object_encryption_alg_values_supported': [],
|
53 | 'request_object_encryption_enc_values_supported': [],
|
54 | 'token_endpoint_auth_methods_supported': ['client_secret_basic', 'client_secret_post'],
|
55 | 'token_endpoint_auth_signing_alg_values_supported': [],
|
56 | 'display_values_supported': [],
|
57 | 'claim_types_supported': ['normal'],
|
58 | 'claims_supported': ['iss', 'sub', 'aud', 'acr', 'name', 'given_name', 'family_name', 'middle_name', 'nickname', 'preferred_username', 'profile', 'picture', 'website', 'email', 'email_verified', 'zoneinfo', 'locale', 'joined_at', 'updated_at'],
|
59 | 'service_documentation': 'https://anvil.io/docs/connect/',
|
60 | 'claims_locales_supported': [],
|
61 | 'ui_locales_supported': [],
|
62 | 'check_session_iframe': 'https://connect.anvil.io/session',
|
63 | 'end_session_endpoint': 'https://connect.anvil.io/signout'
|
64 | }
|
65 | var jwks = {
|
66 | 'keys': [
|
67 | {
|
68 | 'kty': 'RSA',
|
69 | 'use': 'sig',
|
70 | 'alg': 'RS256',
|
71 | 'n': 'zRchTwN0Ok6suWzaWYsbfZ81qdGVZM_LCqR6dhtlHaYAPpyVKefY3U5ByhbvDgbCm3BQ9OLu1E4OEJFkJVYvapxsyosrnSyY7qjLxHGKC-16AQNhX8qssTZVQCzdnKk67RUyKraM87zPkWNU6Qlw539-O9-g54YICKZV7ESfvA4nVvHQTJr8mem6S0GrRHxma8gEecogAvQCw5c2Hb500lW8eGqQ8qFjiBPQVScf4PZul4UO01KFB-cKiK575bFpxLSgfFBIGvqbjRgxLGkJnYq6IhtRfPQ0LAcM8rjYIINcFtLv9P647JcjrwNrxjP-yG_C84UddJl9L5kdA4_8JHom1sfaR7izF2B2mBFrGNODYDj8LctmWi4FaXBAIKa8XNW9lGv6Olc6G9AHpjzcQOY_lwAYWmULsotRRWfuV7wr49CyMSnthcd2smoA7ABed7qfd4FDCIft4SpONu7Mfba-pf8-0yYbXUcCdQzgaFr4P7MzMre4tcMhmWa89tMDP-XklptjgBmmK7RNdqk_g_Ol2KSXb233bIVd3tL8VgO1_vxwrvSZr_k9169GlsB3Ud50ulG_b6MOQxbpKZb1WEP_ajaZ8RnQOAFvfBKxBBxxT6y0maNtRGtpunYWmkxBPs-eJKZrYpVGLSX0ZwPOoPpQDInOuPcAuCp2Y3sEXK8',
|
72 | 'e': 'AQAB'
|
73 | }, {
|
74 | 'kty': 'RSA',
|
75 | 'use': 'enc',
|
76 | 'alg': 'RS256',
|
77 | 'n': 'xoAIJ40-f5lr07WswyF6XryOtEJSpNYY_RFmMdKWMLoZnZ4dTl9LlBFyXYNunbkKQHXmhTTr_C6FWjUA6JZwCkymtgD5Be8Mz8N8K0RB6nokLzXzUilYrY8m_0G1yLAGAeAv0evGXMJN5GLuHzInB9zPzySr7xsCUB0L5DuEv6WJ4abNw5ylnLKLW9nvGfZDXwJ4YVJOaVre3S8CjvXu1fuTmzBW3VSD9Zttd_NB6uiS0QsvFBifHx-S1PZ_LZNGC52Z3-rs9kMzzneBiBJrhULFsyGF5OQBGBDQD5Ghl_O86DyCXKOGrIDso2l7ZY5vlicL9QD7jeBJnIF9sDnZDugoVneT2yHMBqiDKlFHKjGSE_mKhnD1K-QMolOwbADNytMeu5BDgFYdAkx9hyo1L2f8f4eB7_8XUSCnnQoIR9tb5ie9bSpd4Uel881N97WLVe9hyUVY0YSU3MKHaoNrPYVbGYjRsQrK14-NaZ3bC4Grrwd8eGGFaQeT_a4dIFfBfHtl_wH-DGZIqlTLX9fxfeNu93I4zPky1TlQaTwFiRo-9FXF6I6r2s2WaZKLnFWKdS2c0VrHJQebrkAN0VQNhp9-7jBRQqJmTiNVSg7J5wd7mgCMXIOfktOBHoNiulMRd9rYN21qRxt0xOwFujNZ8mlx2M96gBdhDVq020zJdB0',
|
78 | 'e': 'AQAB'
|
79 | }
|
80 | ]
|
81 | }
|
82 | var registration = {
|
83 | client_name: 'TEST CLIENT',
|
84 | redirect_uris: ['http://app.example.com/callback']
|
85 | }
|
86 | var registrationResponse = {
|
87 | client_id: 'a011bbd4-6171-4d84-ba1a-7db73fd64056',
|
88 | client_secret: 'cd38a23c7a53045cbb64',
|
89 | client_name: registration.client_name,
|
90 | token_endpoint_auth_method: 'client_secret_basic',
|
91 | application_type: 'web',
|
92 | redirect_uris: registration.redirect_uris,
|
93 | client_id_issued_at: 1441564333989
|
94 | }
|
95 | var userinfo = {
|
96 | given_name: 'FAKE',
|
97 | family_name: 'USER'
|
98 | }
|
99 | describe('constructor', function () {
|
100 | before(function () {
|
101 | anvil = new AnvilConnect(config)
|
102 | })
|
103 | it('should set the issuer', function () {
|
104 | return anvil.issuer.should.equal(config.issuer)
|
105 | })
|
106 | it('should set the client id', function () {
|
107 | return anvil.client_id.should.equal(config.client_id)
|
108 | })
|
109 | it('should set the client secret', function () {
|
110 | return anvil.client_secret.should.equal(config.client_secret)
|
111 | })
|
112 | it('should set the redirect uri', function () {
|
113 | anvil.redirect_uri = config.redirect_uri
|
114 | return anvil.redirect_uri
|
115 | })
|
116 | it('should set default scope', function () {
|
117 | return anvil.scope.should.equal('openid profile')
|
118 | })
|
119 | it('should set scope from an array', function () {
|
120 | anvil = new AnvilConnect({
|
121 | scope: ['realm']
|
122 | })
|
123 | return anvil.scope.should.contain('realm')
|
124 | })
|
125 | return it('should set scope from a string', function () {
|
126 | anvil = new AnvilConnect({
|
127 | scope: 'realm extra'
|
128 | })
|
129 | anvil.scope.should.contain('realm')
|
130 | return anvil.scope.should.contain('extra')
|
131 | })
|
132 | })
|
133 | describe('discover', function () {
|
134 | describe('with a successful response', function () {
|
135 | beforeEach(function (done) {
|
136 | anvil = new AnvilConnect(config)
|
137 | nock(anvil.issuer).get('/.well-known/openid-configuration').reply(200, openid)
|
138 | success = sinon.spy(function () {
|
139 | return done()
|
140 | })
|
141 | failure = sinon.spy(function () {
|
142 | return done()
|
143 | })
|
144 | promise = anvil.discover().then(success)['catch'](failure)
|
145 | return promise
|
146 | })
|
147 | after(function () {
|
148 | return nock.cleanAll()
|
149 | })
|
150 | it('should return a promise', function () {
|
151 | return promise.should.be['instanceof'](Promise)
|
152 | })
|
153 | it('should provide the openid configuration', function () {
|
154 | return success.should.have.been.calledWith(sinon.match({
|
155 | issuer: anvil.issuer
|
156 | }))
|
157 | })
|
158 | it('should set configuration', function () {
|
159 | return anvil.configuration.should.eql(openid)
|
160 | })
|
161 | return it('should not catch an error', function () {
|
162 | return failure.should.not.have.been.called
|
163 | })
|
164 | })
|
165 | describe('with a failure response', function () {
|
166 | beforeEach(function (done) {
|
167 |
|
168 |
|
169 |
|
170 | anvil = new AnvilConnect(config)
|
171 | nock(anvil.issuer)
|
172 | .get('/.well-known/openid-configuration')
|
173 | .reply(404, 'Not found')
|
174 | success = sinon.spy(function () {
|
175 | return done()
|
176 | })
|
177 | failure = sinon.spy(function () {
|
178 | return done()
|
179 | })
|
180 | promise = anvil.discover().then(success)['catch'](failure)
|
181 | return promise
|
182 | })
|
183 | after(function () {
|
184 | return nock.cleanAll()
|
185 | })
|
186 | it('should return a promise', function () {
|
187 | return promise.should.be['instanceof'](Promise)
|
188 | })
|
189 | it('should not provide the openid configuration', function () {
|
190 | return success.should.not.have.been.called
|
191 | })
|
192 | it('should not set configuration', function () {
|
193 | return expect(anvil.configuration).to.be.undefined
|
194 | })
|
195 | return it('should not catch an error', function () {
|
196 | return failure.should.have.been.called
|
197 | })
|
198 | })
|
199 | return describe('with an invalid response', function () {
|
200 | beforeEach(function (done) {
|
201 |
|
202 |
|
203 |
|
204 | anvil = new AnvilConnect(config)
|
205 | nock(anvil.issuer).get('/.well-known/openid-configuration').reply(200, "This isn't JSON!")
|
206 | success = sinon.spy(function () {
|
207 | return done()
|
208 | })
|
209 | failure = sinon.spy(function () {
|
210 | return done()
|
211 | })
|
212 | promise = anvil.discover().then(success)['catch'](failure)
|
213 | return promise
|
214 | })
|
215 | after(function () {
|
216 | return nock.cleanAll()
|
217 | })
|
218 | it('should return a promise', function () {
|
219 | return promise.should.be['instanceof'](Promise)
|
220 | })
|
221 | it('should not provide the openid configuration', function () {
|
222 | return success.should.not.have.been.called
|
223 | })
|
224 | it('should not set configuration', function () {
|
225 | return expect(anvil.configuration).to.be.undefined
|
226 | })
|
227 | return it('should not catch an error', function () {
|
228 | return failure.should.have.been.called
|
229 | })
|
230 | })
|
231 | })
|
232 | describe('jwks', function () {
|
233 | describe('with a successful response', function () {
|
234 | beforeEach(function (done) {
|
235 | anvil = new AnvilConnect(config)
|
236 | anvil.configuration = openid
|
237 | nock(anvil.issuer).get('/jwks').reply(200, jwks)
|
238 | success = sinon.spy(function () {
|
239 | return done()
|
240 | })
|
241 | failure = sinon.spy(function () {
|
242 | return done()
|
243 | })
|
244 | promise = anvil.getJWKs().then(success)['catch'](failure)
|
245 | return promise
|
246 | })
|
247 | after(function () {
|
248 | return nock.cleanAll()
|
249 | })
|
250 | it('should return a promise', function () {
|
251 | return promise.should.be['instanceof'](Promise)
|
252 | })
|
253 | it('should provide the JWK set', function () {
|
254 | return success.should.have.been.calledWith(sinon.match(jwks))
|
255 | })
|
256 | it('should set jwks', function () {
|
257 | return anvil.jwks.keys.should.eql(jwks.keys)
|
258 | })
|
259 | it('should set signature jwk', function () {
|
260 | return anvil.jwks.sig.should.eql(jwks.keys[0])
|
261 | })
|
262 | return it('should not catch an error', function () {
|
263 | return failure.should.not.have.been.called
|
264 | })
|
265 | })
|
266 | return describe('with a failure response', function () {
|
267 | beforeEach(function (done) {
|
268 | anvil = new AnvilConnect(config)
|
269 | anvil.configuration = openid
|
270 | nock(anvil.issuer).get('/jwks').reply(404, 'Not found')
|
271 | success = sinon.spy(function () {
|
272 | return done()
|
273 | })
|
274 | failure = sinon.spy(function () {
|
275 | return done()
|
276 | })
|
277 | promise = anvil.getJWKs().then(success)['catch'](failure)
|
278 | return promise
|
279 | })
|
280 | after(function () {
|
281 | return nock.cleanAll()
|
282 | })
|
283 | it('should return a promise', function () {
|
284 | return promise.should.be['instanceof'](Promise)
|
285 | })
|
286 | it('should not provide the JWK set', function () {
|
287 | return success.should.not.have.been.called
|
288 | })
|
289 | it('should not set jwks', function () {
|
290 | return expect(anvil.jwks).to.be.undefined
|
291 | })
|
292 | return it('should catch an error', function () {
|
293 | return failure.should.have.been.called
|
294 | })
|
295 | })
|
296 | })
|
297 | describe('register', function () {
|
298 | describe('with a successful response', function () {
|
299 | beforeEach(function (done) {
|
300 | anvil = new AnvilConnect(config)
|
301 | anvil.configuration = openid
|
302 | nock(anvil.issuer).post('/register', registration).reply(201, registrationResponse)
|
303 | success = sinon.spy(function () {
|
304 | return done()
|
305 | })
|
306 | failure = sinon.spy(function () {
|
307 | return done()
|
308 | })
|
309 | promise = anvil.register(registration).then(success)['catch'](failure)
|
310 | return promise
|
311 | })
|
312 | after(function () {
|
313 | return nock.cleanAll()
|
314 | })
|
315 | it('should return a promise', function () {
|
316 | return promise.should.be['instanceof'](Promise)
|
317 | })
|
318 | it('should provide the registration response', function () {
|
319 | return success.should.have.been.calledWith(sinon.match(registrationResponse))
|
320 | })
|
321 | return it('should not catch an error', function () {
|
322 | return failure.should.not.have.been.called
|
323 | })
|
324 | })
|
325 | return describe('with a failure response', function () {
|
326 | beforeEach(function (done) {
|
327 | anvil = new AnvilConnect(config)
|
328 | anvil.configuration = openid
|
329 | nock(anvil.issuer).post('/register', registration).reply(400, {
|
330 | error: 'whatever'
|
331 | })
|
332 | success = sinon.spy(function () {
|
333 | return done()
|
334 | })
|
335 | failure = sinon.spy(function () {
|
336 | return done()
|
337 | })
|
338 | promise = anvil.register(registration).then(success)['catch'](failure)
|
339 | return promise
|
340 | })
|
341 | after(function () {
|
342 | return nock.cleanAll()
|
343 | })
|
344 | it('should return a promise', function () {
|
345 | return promise.should.be['instanceof'](Promise)
|
346 | })
|
347 | it('should not provide the registration response', function () {
|
348 | return success.should.have.not.been.called
|
349 | })
|
350 | return it('should catch an error', function () {
|
351 | return failure.should.have.been.called
|
352 | })
|
353 | })
|
354 | })
|
355 | describe('authorizationUri', function () {
|
356 | beforeEach(function () {
|
357 | anvil = new AnvilConnect(config)
|
358 | anvil.configuration = openid
|
359 | })
|
360 | describe('with no endpoint in the argument', function () {
|
361 | return it('should use the "authorize" endpoint', function () {
|
362 | return anvil.authorizationUri().should.contain('/authorize?')
|
363 | })
|
364 | })
|
365 | describe('with a string argument', function () {
|
366 | return it('should use the argument as the endpoint', function () {
|
367 | return anvil.authorizationUri('signin').should.contain('/signin?')
|
368 | })
|
369 | })
|
370 | return describe('with an options argument', function () {
|
371 | it('should set the optional endpoint', function () {
|
372 | var uri
|
373 | uri = anvil.authorizationUri({
|
374 | endpoint: 'connect/google'
|
375 | })
|
376 | return uri.should.contain('/connect/google?')
|
377 | })
|
378 | it('should set default authorization params', function () {
|
379 | var uri
|
380 | uri = anvil.authorizationUri({
|
381 | endpoint: 'connect/google'
|
382 | })
|
383 | uri.should.contain('response_type=code')
|
384 | uri.should.contain('client_id=' + config.client_id)
|
385 | uri.should.contain('redirect_uri=' + (encodeURIComponent(config.redirect_uri)))
|
386 | return uri.should.contain('scope=' + (encodeURIComponent(anvil.scope)))
|
387 | })
|
388 | return it('should set optional authorization params', function () {
|
389 | var uri
|
390 | uri = anvil.authorizationUri({
|
391 | endpoint: 'signin',
|
392 | provider: 'password',
|
393 | max_age: 2600
|
394 | })
|
395 | uri.should.contain('provider=password')
|
396 | return uri.should.contain('max_age=2600')
|
397 | })
|
398 | })
|
399 | })
|
400 | describe('authorizationParams', function () {
|
401 | beforeEach(function () {
|
402 | anvil = new AnvilConnect(config)
|
403 | anvil.configuration = openid
|
404 | })
|
405 | it('should set default response type', function () {
|
406 | return anvil.authorizationParams().response_type.should.equal('code')
|
407 | })
|
408 | it('should set optional response type', function () {
|
409 | return anvil.authorizationParams({
|
410 | response_type: 'id_token token'
|
411 | }).response_type.should.equal('id_token token')
|
412 | })
|
413 | it('should set client id', function () {
|
414 | return anvil.authorizationParams().client_id.should.equal(config.client_id)
|
415 | })
|
416 | it('should set configured redirect uri', function () {
|
417 | return anvil.authorizationParams().redirect_uri.should.equal(config.redirect_uri)
|
418 | })
|
419 | it('should set optional redirect uri', function () {
|
420 | var uri
|
421 | uri = 'https://app.example.com/other'
|
422 | return anvil.authorizationParams({
|
423 | redirect_uri: uri
|
424 | }).redirect_uri.should.equal(uri)
|
425 | })
|
426 | it('should set configured scope', function () {
|
427 | return anvil.authorizationParams().scope.should.equal(anvil.scope)
|
428 | })
|
429 | it('should set optional scope', function () {
|
430 | return anvil.authorizationParams({
|
431 | scope: 'foo bar'
|
432 | }).scope.should.equal('foo bar')
|
433 | })
|
434 | it('should set optional parameters', function () {
|
435 | return anvil.authorizationParams({
|
436 | prompt: 'none'
|
437 | }).prompt.should.equal('none')
|
438 | })
|
439 | return it('should ignore unknown parameters', function () {
|
440 | var params
|
441 | params = anvil.authorizationParams({
|
442 | unknown: 'forgetme'
|
443 | })
|
444 | return expect(params.unknown).to.be.undefined
|
445 | })
|
446 | })
|
447 | describe('refresh', function () {
|
448 | describe('with missing options argument', function () {
|
449 | beforeEach(function (done) {
|
450 | anvil = new AnvilConnect(config)
|
451 | anvil.configuration = openid
|
452 | success = sinon.spy(function () {
|
453 | return done()
|
454 | })
|
455 | failure = sinon.spy(function () {
|
456 | return done()
|
457 | })
|
458 | promise = anvil.refresh().then(success)['catch'](failure)
|
459 | return promise
|
460 | })
|
461 | it('should return a promise', function () {
|
462 | return promise.should.be['instanceof'](Promise)
|
463 | })
|
464 | it('should not provide the tokens', function () {
|
465 | return success.should.not.have.been.called
|
466 | })
|
467 | return it('should catch an error', function () {
|
468 | return failure.should.have.been.calledWith(sinon.match({
|
469 | message: 'Missing refresh_token'
|
470 | }))
|
471 | })
|
472 | })
|
473 | describe('with error response', function () {
|
474 | beforeEach(function (done) {
|
475 | anvil = new AnvilConnect(config)
|
476 | anvil.configuration = openid
|
477 | nock(anvil.issuer).post('/token', {
|
478 | grant_type: 'refresh_token',
|
479 | refresh_token: 'random'
|
480 | }).basicAuth({
|
481 | user: config.client_id,
|
482 | pass: config.client_secret
|
483 | }).reply(400, {
|
484 | error: 'invalid_request'
|
485 | })
|
486 | success = sinon.spy(function () {
|
487 | return done()
|
488 | })
|
489 | failure = sinon.spy(function () {
|
490 | return done()
|
491 | })
|
492 | promise = anvil.refresh({
|
493 | refresh_token: 'random'
|
494 | }).then(success)['catch'](failure)
|
495 | return promise
|
496 | })
|
497 | after(function () {
|
498 | return nock.cleanAll()
|
499 | })
|
500 | it('should return a promise', function () {
|
501 | return promise.should.be['instanceof'](Promise)
|
502 | })
|
503 | it('should not provide the tokens', function () {
|
504 | return success.should.not.have.been.called
|
505 | })
|
506 | return it('should catch an error', function () {
|
507 | return failure.should.have.been.called
|
508 | })
|
509 | })
|
510 | describe('with token response and signature ko', function () {
|
511 | beforeEach(function (done) {
|
512 | anvil = new AnvilConnect(config)
|
513 | anvil.configuration = openid
|
514 | anvil.jwks = jwks
|
515 | anvil.tokens = {
|
516 | access_token: 'jwt1',
|
517 | id_token: 'jwt2'
|
518 | }
|
519 | nock(anvil.issuer).post('/token', {
|
520 | grant_type: 'refresh_token',
|
521 | refresh_token: 'fake_refresh_token'
|
522 | }).basicAuth({
|
523 | user: config.client_id,
|
524 | pass: config.client_secret
|
525 | }).reply(200, anvil.tokens)
|
526 | sinon.stub(AccessToken, 'refresh').callsArgWith(2, null, anvil.tokens)
|
527 | sinon.stub(AccessToken, 'verify').callsArgWith(2, new Error(), null)
|
528 | success = sinon.spy(function () {
|
529 | return done()
|
530 | })
|
531 | failure = sinon.spy(function () {
|
532 | return done()
|
533 | })
|
534 | promise = anvil.refresh({
|
535 | refresh_token: 'fake_refresh_token'
|
536 | }).then(success)['catch'](failure)
|
537 | return promise
|
538 | })
|
539 | after(function () {
|
540 | return nock.cleanAll()
|
541 | })
|
542 | afterEach(function () {
|
543 | AccessToken.refresh.restore()
|
544 | return AccessToken.verify.restore()
|
545 | })
|
546 | it('should return a promise', function () {
|
547 | return promise.should.be['instanceof'](Promise)
|
548 | })
|
549 | it('should not provide the tokens', function () {
|
550 | return success.should.not.have.been.called
|
551 | })
|
552 | it('should catch an error', function () {
|
553 | return failure.should.have.been.called
|
554 | })
|
555 | it('should AccessToken.refresh called once', function () {
|
556 | return AccessToken.refresh.should.have.been.calledOnce
|
557 | })
|
558 | return it('should AccessToken.verify called once', function () {
|
559 | return AccessToken.verify.should.have.been.calledOnce
|
560 | })
|
561 | })
|
562 | return describe('with token response and signature ok', function () {
|
563 | beforeEach(function (done) {
|
564 | anvil = new AnvilConnect(config)
|
565 | anvil.configuration = openid
|
566 | anvil.jwks = jwks
|
567 | anvil.jwks.keys[0] = jwks.keys[0]
|
568 | anvil.tokens = {
|
569 | access_token: 'jwt1',
|
570 | id_token: 'jwt2'
|
571 | }
|
572 | nock(anvil.issuer).post('/token', {
|
573 | grant_type: 'refresh_token',
|
574 | refresh_token: 'fake_refresh_token'
|
575 | }).basicAuth({
|
576 | user: config.client_id,
|
577 | pass: config.client_secret
|
578 | }).reply(200, anvil.tokens)
|
579 | sinon.stub(AccessToken, 'refresh').callsArgWith(2, null, anvil.tokens)
|
580 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, anvil.tokens)
|
581 | success = sinon.spy(function () {
|
582 | return done()
|
583 | })
|
584 | failure = sinon.spy(function () {
|
585 | return done()
|
586 | })
|
587 | promise = anvil.refresh({
|
588 | refresh_token: 'fake_refresh_token'
|
589 | }).then(success)['catch'](failure)
|
590 | return promise
|
591 | })
|
592 | after(function () {
|
593 | return nock.cleanAll()
|
594 | })
|
595 | afterEach(function () {
|
596 | AccessToken.refresh.restore()
|
597 | return AccessToken.verify.restore()
|
598 | })
|
599 | it('should return a promise', function () {
|
600 | return promise.should.be['instanceof'](Promise)
|
601 | })
|
602 | it('should provide the tokens', function () {
|
603 | return success.should.have.been.called
|
604 | })
|
605 | it('should not catch an error', function () {
|
606 | return failure.should.not.have.been.called
|
607 | })
|
608 | it('should AccessToken.refresh called once', function () {
|
609 | return AccessToken.refresh.should.have.been.calledOnce
|
610 | })
|
611 | it('should AccessToken.verify called once', function () {
|
612 | return AccessToken.verify.should.have.been.calledOnce
|
613 | })
|
614 | return it('should provide the tokens', function () {
|
615 | return success.should.have.been.calledWith(sinon.match(anvil.tokens))
|
616 | })
|
617 | })
|
618 | })
|
619 | describe('token', function () {
|
620 | describe('with missing options argument', function () {
|
621 | beforeEach(function (done) {
|
622 | anvil = new AnvilConnect(config)
|
623 | anvil.configuration = openid
|
624 | success = sinon.spy(function () {
|
625 | return done()
|
626 | })
|
627 | failure = sinon.spy(function () {
|
628 | return done()
|
629 | })
|
630 | promise = anvil.token().then(success)['catch'](failure)
|
631 | return promise
|
632 | })
|
633 | it('should return a promise', function () {
|
634 | return promise.should.be['instanceof'](Promise)
|
635 | })
|
636 | it('should not provide the tokens', function () {
|
637 | return success.should.not.have.been.called
|
638 | })
|
639 | return it('should catch an error', function () {
|
640 | return failure.should.have.been.calledWith(sinon.match({
|
641 | message: 'Missing authorization code'
|
642 | }))
|
643 | })
|
644 | })
|
645 | describe('with missing authorization code', function () {
|
646 | beforeEach(function (done) {
|
647 | anvil = new AnvilConnect(config)
|
648 | anvil.configuration = openid
|
649 | success = sinon.spy(function () {
|
650 | return done()
|
651 | })
|
652 | failure = sinon.spy(function () {
|
653 | return done()
|
654 | })
|
655 | promise = anvil.token({}).then(success)['catch'](failure)
|
656 | return promise
|
657 | })
|
658 | it('should return a promise', function () {
|
659 | return promise.should.be['instanceof'](Promise)
|
660 | })
|
661 | it('should not provide the tokens', function () {
|
662 | return success.should.not.have.been.called
|
663 | })
|
664 | return it('should catch an error', function () {
|
665 | return failure.should.have.been.calledWith(sinon.match({
|
666 | message: 'Missing authorization code'
|
667 | }))
|
668 | })
|
669 | })
|
670 | describe('with error response', function () {
|
671 | beforeEach(function (done) {
|
672 | anvil = new AnvilConnect(config)
|
673 | anvil.configuration = openid
|
674 | anvil.tokens = {
|
675 | access_token: 'jwt1',
|
676 | id_token: 'jwt2'
|
677 | }
|
678 | nock(anvil.issuer).post('/token', {
|
679 | grant_type: 'authorization_code',
|
680 | code: 'random',
|
681 | redirect_uri: config.redirect_uri
|
682 | }).basicAuth({
|
683 | user: config.client_id,
|
684 | pass: config.client_secret
|
685 | }).reply(400, {
|
686 | error: 'invalid_request'
|
687 | })
|
688 | success = sinon.spy(function () {
|
689 | return done()
|
690 | })
|
691 | failure = sinon.spy(function () {
|
692 | return done()
|
693 | })
|
694 | promise = anvil.token({
|
695 | code: 'random'
|
696 | }).then(success)['catch'](failure)
|
697 | return promise
|
698 | })
|
699 | after(function () {
|
700 | return nock.cleanAll()
|
701 | })
|
702 | it('should return a promise', function () {
|
703 | return promise.should.be['instanceof'](Promise)
|
704 | })
|
705 | it('should not provide the tokens', function () {
|
706 | return success.should.not.have.been.called
|
707 | })
|
708 | return it('should catch an error', function () {
|
709 | return failure.should.have.been.called
|
710 | })
|
711 | })
|
712 | describe('with unverifiable id token', function () {
|
713 | var tokens
|
714 | tokens = {}.tokens
|
715 | before(function (done) {
|
716 |
|
717 |
|
718 |
|
719 | anvil = new AnvilConnect(config)
|
720 | anvil.configuration = openid
|
721 | anvil.jwks = jwks
|
722 | anvil.jwks.sig = jwks.keys[0]
|
723 | tokens = {
|
724 | id_token: 'invalid.id.token',
|
725 | access_token: 'valid.access.token'
|
726 | }
|
727 | nock(anvil.issuer).post('/token', {
|
728 | grant_type: 'authorization_code',
|
729 | code: 'random',
|
730 | redirect_uri: config.redirect_uri
|
731 | }).basicAuth({
|
732 | user: config.client_id,
|
733 | pass: config.client_secret
|
734 | }).reply(200, tokens)
|
735 | sinon.stub(IDToken, 'verify').callsArgWith(2, new Error())
|
736 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, {})
|
737 | success = sinon.spy(function () {
|
738 | return done()
|
739 | })
|
740 | failure = sinon.spy(function () {
|
741 | return done()
|
742 | })
|
743 | promise = anvil.token({
|
744 | code: 'random'
|
745 | }).then(success)['catch'](failure)
|
746 | return promise
|
747 | })
|
748 | after(function () {
|
749 | IDToken.verify.restore()
|
750 | AccessToken.verify.restore()
|
751 | return nock.cleanAll()
|
752 | })
|
753 | it('should return a promise', function () {
|
754 | return promise.should.be['instanceof'](Promise)
|
755 | })
|
756 | it('should verify the id token', function () {
|
757 | return IDToken.verify.should.have.been.calledWith(tokens.id_token)
|
758 | })
|
759 | it('should verify the access token', function () {
|
760 | return AccessToken.verify.should.have.been.calledWith(tokens.access_token)
|
761 | })
|
762 | it('should not provide the id claims', function () {
|
763 | return success.should.not.have.been.called
|
764 | })
|
765 | return it('should not catch an error', function () {
|
766 | return failure.should.have.been.called
|
767 | })
|
768 | })
|
769 | describe('with unverifiable access token', function () {
|
770 | var tokens
|
771 | tokens = {}.tokens
|
772 | before(function (done) {
|
773 |
|
774 |
|
775 |
|
776 | anvil = new AnvilConnect(config)
|
777 | anvil.configuration = openid
|
778 | anvil.jwks = jwks
|
779 | anvil.jwks.sig = jwks.keys[0]
|
780 | tokens = {
|
781 | id_token: 'valid.id.token',
|
782 | access_token: 'invalid.access.token'
|
783 | }
|
784 | nock(anvil.issuer).post('/token', {
|
785 | grant_type: 'authorization_code',
|
786 | code: 'random',
|
787 | redirect_uri: config.redirect_uri
|
788 | }).basicAuth({
|
789 | user: config.client_id,
|
790 | pass: config.client_secret
|
791 | }).reply(200, tokens)
|
792 | sinon.stub(AccessToken, 'verify').callsArgWith(2, new Error())
|
793 | sinon.stub(IDToken, 'verify').callsArgWith(2, null, {})
|
794 | success = sinon.spy(function () {
|
795 | return done()
|
796 | })
|
797 | failure = sinon.spy(function () {
|
798 | return done()
|
799 | })
|
800 | promise = anvil.token({
|
801 | code: 'random'
|
802 | }).then(success)['catch'](failure)
|
803 | return promise
|
804 | })
|
805 | after(function () {
|
806 | AccessToken.verify.restore()
|
807 | IDToken.verify.restore()
|
808 | return nock.cleanAll()
|
809 | })
|
810 | it('should return a promise', function () {
|
811 | return promise.should.be['instanceof'](Promise)
|
812 | })
|
813 | it('should verify the id token', function () {
|
814 | return IDToken.verify.should.have.been.calledWith(tokens.id_token)
|
815 | })
|
816 | it('should verify the access token', function () {
|
817 | return AccessToken.verify.should.have.been.calledWith(tokens.access_token)
|
818 | })
|
819 | it('should not provide the id claims', function () {
|
820 | return success.should.not.have.been.called
|
821 | })
|
822 | return it('should not catch an error', function () {
|
823 | return failure.should.have.been.called
|
824 | })
|
825 | })
|
826 | describe('with valid token response', function () {
|
827 | var tokens
|
828 | tokens = {}.tokens
|
829 | beforeEach(function (done) {
|
830 | anvil = new AnvilConnect(config)
|
831 | anvil.configuration = openid
|
832 | anvil.jwks = jwks
|
833 | anvil.jwks.sig = jwks.keys[0]
|
834 | tokens = {
|
835 | id_token: 'valid.id.token',
|
836 | access_token: 'valid.access.token'
|
837 | }
|
838 | nock(anvil.issuer).post('/token', {
|
839 | grant_type: 'authorization_code',
|
840 | code: 'random',
|
841 | redirect_uri: config.redirect_uri
|
842 | }).basicAuth({
|
843 | user: config.client_id,
|
844 | pass: config.client_secret
|
845 | }).reply(200, tokens)
|
846 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, {
|
847 | aud: config.client_id
|
848 | })
|
849 | sinon.stub(IDToken, 'verify').callsArgWith(2, null, {
|
850 | payload: {
|
851 | iss: config.issuer
|
852 | }
|
853 | })
|
854 | success = sinon.spy(function () {
|
855 | return done()
|
856 | })
|
857 | failure = sinon.spy(function () {
|
858 | return done()
|
859 | })
|
860 | promise = anvil.token({
|
861 | code: 'random'
|
862 | }).then(success)['catch'](failure)
|
863 | return promise
|
864 | })
|
865 | afterEach(function () {
|
866 | AccessToken.verify.restore()
|
867 | IDToken.verify.restore()
|
868 | return nock.cleanAll()
|
869 | })
|
870 | it('should return a promise', function () {
|
871 | return promise.should.be['instanceof'](Promise)
|
872 | })
|
873 | it('should verify the id token', function () {
|
874 | return IDToken.verify.should.have.been.calledWith(tokens.id_token)
|
875 | })
|
876 | it('should verify the access token', function () {
|
877 | return AccessToken.verify.should.have.been.calledWith(tokens.access_token)
|
878 | })
|
879 | it('should provide the tokens', function () {
|
880 | return success.should.have.been.calledWith(sinon.match(tokens))
|
881 | })
|
882 | it('should provide the id claims', function () {
|
883 | return success.should.have.been.calledWith(sinon.match({
|
884 | id_claims: {
|
885 | iss: config.issuer
|
886 | }
|
887 | }))
|
888 | })
|
889 | it('should provide the access claims', function () {
|
890 | return success.should.have.been.calledWith(sinon.match({
|
891 | access_claims: {
|
892 | aud: config.client_id
|
893 | }
|
894 | }))
|
895 | })
|
896 | return it('should not catch an error', function () {
|
897 | return failure.should.not.have.been.called
|
898 | })
|
899 | })
|
900 | describe('with response uri', function () {
|
901 | var tokens
|
902 | tokens = {}.tokens
|
903 | beforeEach(function (done) {
|
904 | anvil = new AnvilConnect(config)
|
905 | anvil.configuration = openid
|
906 | anvil.jwks = jwks
|
907 | anvil.jwks.sig = jwks.keys[0]
|
908 | tokens = {
|
909 | id_token: 'valid.id.token',
|
910 | access_token: 'valid.access.token'
|
911 | }
|
912 | nock(anvil.issuer).post('/token', {
|
913 | grant_type: 'authorization_code',
|
914 | code: 'random',
|
915 | redirect_uri: config.redirect_uri
|
916 | }).basicAuth({
|
917 | user: config.client_id,
|
918 | pass: config.client_secret
|
919 | }).reply(200, tokens)
|
920 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, {
|
921 | aud: config.client_id
|
922 | })
|
923 | sinon.stub(IDToken, 'verify').callsArgWith(2, null, {
|
924 | payload: {
|
925 | iss: config.issuer
|
926 | }
|
927 | })
|
928 | success = sinon.spy(function () {
|
929 | return done()
|
930 | })
|
931 | failure = sinon.spy(function (err) {
|
932 | console.log(err)
|
933 | return done()
|
934 | })
|
935 | promise = anvil.token({
|
936 | responseUri: 'https://app.example.com/callback?code=random'
|
937 | }).then(success)['catch'](failure)
|
938 | return promise
|
939 | })
|
940 | afterEach(function () {
|
941 | AccessToken.verify.restore()
|
942 | IDToken.verify.restore()
|
943 | return nock.cleanAll()
|
944 | })
|
945 | it('should return a promise', function () {
|
946 | return promise.should.be['instanceof'](Promise)
|
947 | })
|
948 | it('should verify the id token', function () {
|
949 | return IDToken.verify.should.have.been.calledWith(tokens.id_token)
|
950 | })
|
951 | it('should verify the access token', function () {
|
952 | return AccessToken.verify.should.have.been.calledWith(tokens.access_token)
|
953 | })
|
954 | it('should provide the tokens', function () {
|
955 | return success.should.have.been.calledWith(sinon.match(tokens))
|
956 | })
|
957 | it('should provide the id claims', function () {
|
958 | return success.should.have.been.calledWith(sinon.match({
|
959 | id_claims: {
|
960 | iss: config.issuer
|
961 | }
|
962 | }))
|
963 | })
|
964 | it('should provide the access claims', function () {
|
965 | return success.should.have.been.calledWith(sinon.match({
|
966 | access_claims: {
|
967 | aud: config.client_id
|
968 | }
|
969 | }))
|
970 | })
|
971 | return it('should not catch an error', function () {
|
972 | return failure.should.not.have.been.called
|
973 | })
|
974 | })
|
975 | return describe('with client_credentials grant', function () {
|
976 | var tokens
|
977 | tokens = {}.tokens
|
978 | beforeEach(function (done) {
|
979 | anvil = new AnvilConnect(config)
|
980 | anvil.configuration = openid
|
981 | anvil.jwks = jwks
|
982 | anvil.jwks.sig = jwks.keys[0]
|
983 | tokens = {
|
984 | access_token: 'valid.access.token'
|
985 | }
|
986 | nock(anvil.issuer).post('/token', {
|
987 | grant_type: 'client_credentials',
|
988 | scope: 'realm'
|
989 | }).basicAuth({
|
990 | user: config.client_id,
|
991 | pass: config.client_secret
|
992 | }).reply(200, tokens)
|
993 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, {
|
994 | aud: config.client_id
|
995 | })
|
996 | sinon.stub(IDToken, 'verify')
|
997 | success = sinon.spy(function () {
|
998 | return done()
|
999 | })
|
1000 | failure = sinon.spy(function () {
|
1001 | return done()
|
1002 | })
|
1003 | promise = anvil.token({
|
1004 | grant_type: 'client_credentials',
|
1005 | scope: 'realm'
|
1006 | }).then(success)['catch'](failure)
|
1007 | return promise
|
1008 | })
|
1009 | afterEach(function () {
|
1010 | AccessToken.verify.restore()
|
1011 | IDToken.verify.restore()
|
1012 | return nock.cleanAll()
|
1013 | })
|
1014 | it('should return a promise', function () {
|
1015 | return promise.should.be['instanceof'](Promise)
|
1016 | })
|
1017 | it('should NOT receive an id token', function () {
|
1018 | return IDToken.verify.should.not.have.been.called
|
1019 | })
|
1020 | it('should verify the access token', function () {
|
1021 | return AccessToken.verify.should.have.been.calledWith(tokens.access_token)
|
1022 | })
|
1023 | it('should provide the tokens', function () {
|
1024 | return success.should.have.been.calledWith(sinon.match(tokens))
|
1025 | })
|
1026 | it('should NOT provide the id claims', function () {
|
1027 | return success.should.not.have.been.calledWith(sinon.match({
|
1028 | id_claims: {
|
1029 | iss: config.issuer
|
1030 | }
|
1031 | }))
|
1032 | })
|
1033 | it('should provide the access claims', function () {
|
1034 | return success.should.have.been.calledWith(sinon.match({
|
1035 | access_claims: {
|
1036 | aud: config.client_id
|
1037 | }
|
1038 | }))
|
1039 | })
|
1040 | return it('should not catch an error', function () {
|
1041 | return failure.should.not.have.been.called
|
1042 | })
|
1043 | })
|
1044 | })
|
1045 | describe('userInfo', function () {
|
1046 | describe('with a missing access token', function () {
|
1047 | beforeEach(function (done) {
|
1048 | anvil = new AnvilConnect(config)
|
1049 | anvil.configuration = openid
|
1050 | success = sinon.spy(function () {
|
1051 | return done()
|
1052 | })
|
1053 | failure = sinon.spy(function () {
|
1054 | return done()
|
1055 | })
|
1056 | promise = anvil.userInfo().then(success, failure)
|
1057 | return promise
|
1058 | })
|
1059 | it('should return a promise', function () {
|
1060 | return promise.should.be['instanceof'](Promise)
|
1061 | })
|
1062 | it('should not provide userInfo', function () {
|
1063 | return success.should.not.have.been.called
|
1064 | })
|
1065 | return it('should catch an error', function () {
|
1066 | return failure.should.have.been.calledWith(sinon.match.instanceOf(Error))
|
1067 | })
|
1068 | })
|
1069 | describe('with a successful response', function () {
|
1070 | beforeEach(function (done) {
|
1071 | anvil = new AnvilConnect(config)
|
1072 | anvil.configuration = openid
|
1073 | nock(anvil.issuer).get('/userinfo').reply(200, userinfo)
|
1074 | success = sinon.spy(function () {
|
1075 | return done()
|
1076 | })
|
1077 | failure = sinon.spy(function () {
|
1078 | return done()
|
1079 | })
|
1080 | promise = anvil.userInfo({
|
1081 | token: 'token'
|
1082 | }).then(success)['catch'](failure)
|
1083 | return promise
|
1084 | })
|
1085 | afterEach(function () {
|
1086 | return nock.cleanAll()
|
1087 | })
|
1088 | it('should return a promise', function () {
|
1089 | return promise.should.be['instanceof'](Promise)
|
1090 | })
|
1091 | it('should provide the userinfo', function () {
|
1092 | return success.should.have.been.calledWith(sinon.match(userinfo))
|
1093 | })
|
1094 | return it('should not catch an error', function () {
|
1095 | return failure.should.not.have.been.called
|
1096 | })
|
1097 | })
|
1098 | return describe('with a failure response', function () {
|
1099 | beforeEach(function (done) {
|
1100 | anvil = new AnvilConnect(config)
|
1101 | anvil.configuration = openid
|
1102 | nock(anvil.issuer).get('/userinfo').reply(404, 'Not found')
|
1103 | success = sinon.spy(function () {
|
1104 | return done()
|
1105 | })
|
1106 | failure = sinon.spy(function () {
|
1107 | return done()
|
1108 | })
|
1109 | promise = anvil.userInfo({
|
1110 | token: 'token'
|
1111 | }).then(success)['catch'](failure)
|
1112 | return promise
|
1113 | })
|
1114 | after(function () {
|
1115 | return nock.cleanAll()
|
1116 | })
|
1117 | it('should return a promise', function () {
|
1118 | return promise.should.be['instanceof'](Promise)
|
1119 | })
|
1120 | it('should not provide the userinfo', function () {
|
1121 | return success.should.not.have.been.called
|
1122 | })
|
1123 | return it('should catch an error', function () {
|
1124 | return failure.should.have.been.calledWith(sinon.match.instanceOf(Error))
|
1125 | })
|
1126 | })
|
1127 | })
|
1128 | return describe('verify', function () {
|
1129 | var ref1 = {}
|
1130 | var claims = ref1.claims
|
1131 | var options = ref1.options
|
1132 | describe('with defaults and invalid token', function () {
|
1133 | before(function (done) {
|
1134 | anvil = new AnvilConnect(config)
|
1135 | anvil.configuration = openid
|
1136 | anvil.jwks = jwks
|
1137 | anvil.jwks.sig = jwks.keys[0]
|
1138 | sinon.stub(AccessToken, 'verify').callsArgWith(2, new Error())
|
1139 | success = sinon.spy(function () {
|
1140 | return done()
|
1141 | })
|
1142 | failure = sinon.spy(function () {
|
1143 | return done()
|
1144 | })
|
1145 | promise = anvil.verify('invalid.access.token')
|
1146 | .then(success)['catch'](failure)
|
1147 | return promise
|
1148 | })
|
1149 | after(function () {
|
1150 | return AccessToken.verify.restore()
|
1151 | })
|
1152 | it('should return a promise', function () {
|
1153 | return promise.should.be['instanceof'](Promise)
|
1154 | })
|
1155 | it('should not provide the claims', function () {
|
1156 | return success.should.have.not.been.called
|
1157 | })
|
1158 | return it('should catch an error', function () {
|
1159 | return failure.should.have.been.called
|
1160 | })
|
1161 | })
|
1162 | describe('with defaults and valid token', function () {
|
1163 | before(function (done) {
|
1164 | anvil = new AnvilConnect(config)
|
1165 | anvil.configuration = openid
|
1166 | anvil.jwks = jwks
|
1167 | anvil.jwks.sig = jwks.keys[0]
|
1168 | claims = {
|
1169 | sub: 'uuid'
|
1170 | }
|
1171 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, claims)
|
1172 | success = sinon.spy(function () {
|
1173 | return done()
|
1174 | })
|
1175 | failure = sinon.spy(function () {
|
1176 | return done()
|
1177 | })
|
1178 | promise = anvil.verify('valid.access.token')
|
1179 | .then(success)['catch'](failure)
|
1180 | return promise
|
1181 | })
|
1182 | after(function () {
|
1183 | return AccessToken.verify.restore()
|
1184 | })
|
1185 | it('should return a promise', function () {
|
1186 | return promise.should.be['instanceof'](Promise)
|
1187 | })
|
1188 | it('should provide the claims', function () {
|
1189 | return success.should.have.been.calledWith(sinon.match(claims))
|
1190 | })
|
1191 | return it('should not catch an error', function () {
|
1192 | return failure.should.not.have.been.called
|
1193 | })
|
1194 | })
|
1195 | describe('with options and invalid token', function () {
|
1196 | before(function (done) {
|
1197 | anvil = new AnvilConnect(config)
|
1198 | anvil.configuration = openid
|
1199 | anvil.jwks = jwks
|
1200 | anvil.jwks.sig = jwks.keys[0]
|
1201 | sinon.stub(AccessToken, 'verify').callsArgWith(2, new Error())
|
1202 | options = {
|
1203 | scope: 'realm'
|
1204 | }
|
1205 | success = sinon.spy(function () {
|
1206 | return done()
|
1207 | })
|
1208 | failure = sinon.spy(function () {
|
1209 | return done()
|
1210 | })
|
1211 | promise = anvil.verify('invalid.access.token', options)
|
1212 | .then(success)['catch'](failure)
|
1213 | return promise
|
1214 | })
|
1215 | after(function () {
|
1216 | return AccessToken.verify.restore()
|
1217 | })
|
1218 | it('should return a promise', function () {
|
1219 | return promise.should.be['instanceof'](Promise)
|
1220 | })
|
1221 | it('should pass the options to verify', function () {
|
1222 | return AccessToken.verify.should.have.been.calledWith(sinon.match.string, sinon.match(options))
|
1223 | })
|
1224 | it('should not provide the claims', function () {
|
1225 | return success.should.have.not.been.called
|
1226 | })
|
1227 | return it('should catch an error', function () {
|
1228 | return failure.should.have.been.called
|
1229 | })
|
1230 | })
|
1231 | return describe('with options and valid token', function () {
|
1232 | before(function (done) {
|
1233 | anvil = new AnvilConnect(config)
|
1234 | anvil.configuration = openid
|
1235 | anvil.jwks = jwks
|
1236 | anvil.jwks.sig = jwks.keys[0]
|
1237 | claims = {
|
1238 | sub: 'uuid'
|
1239 | }
|
1240 | sinon.stub(AccessToken, 'verify').callsArgWith(2, null, claims)
|
1241 | options = {
|
1242 | scope: 'realm'
|
1243 | }
|
1244 | success = sinon.spy(function () {
|
1245 | return done()
|
1246 | })
|
1247 | failure = sinon.spy(function () {
|
1248 | return done()
|
1249 | })
|
1250 | promise = anvil.verify('valid.access.token', options)
|
1251 | .then(success)['catch'](failure)
|
1252 | return promise
|
1253 | })
|
1254 | after(function () {
|
1255 | return AccessToken.verify.restore()
|
1256 | })
|
1257 | it('should return a promise', function () {
|
1258 | return promise.should.be['instanceof'](Promise)
|
1259 | })
|
1260 | it('should pass the options to verify', function () {
|
1261 | return AccessToken.verify.should.have.been.calledWith(sinon.match.string, sinon.match(options))
|
1262 | })
|
1263 | it('should provide the claims', function () {
|
1264 | return success.should.have.been.calledWith(sinon.match(claims))
|
1265 | })
|
1266 | return it('should not catch an error', function () {
|
1267 | return failure.should.not.have.been.called
|
1268 | })
|
1269 | })
|
1270 | })
|
1271 | })
|
1272 | }).call(this)
|