1 | import nock from 'nock';
|
2 | import { expect } from 'chai';
|
3 |
|
4 | import { jwksEndpoint } from './mocks/jwks';
|
5 | import { publicKey, privateKey, randomPublicKey1 } from './mocks/keys';
|
6 | import { createToken, createSymmetricToken } from './mocks/tokens';
|
7 |
|
8 | const jwksRsa = require('../src');
|
9 | const expressJwt = require('express-jwt');
|
10 |
|
11 | describe('expressJwtSecret', () => {
|
12 | it('should throw error if options is null', () => {
|
13 | let err = null;
|
14 |
|
15 | try {
|
16 | new jwksRsa.expressJwtSecret();
|
17 | } catch (e) {
|
18 | err = e;
|
19 | }
|
20 |
|
21 | expect(err instanceof jwksRsa.ArgumentError).to.be.true;
|
22 | });
|
23 |
|
24 | describe('#expressJwt', () => {
|
25 | beforeEach(() => {
|
26 | nock.cleanAll();
|
27 | });
|
28 |
|
29 | it('should accept the secret function', () => {
|
30 | expressJwt({
|
31 | secret: jwksRsa.expressJwtSecret({
|
32 | jwksUri: 'http://localhost/.well-known/jwks.json'
|
33 | })
|
34 | });
|
35 | });
|
36 |
|
37 | it('should not provide a key if token is invalid', () => {
|
38 | const middleware = expressJwt({
|
39 | secret: jwksRsa.expressJwtSecret({
|
40 | jwksUri: 'http://localhost/.well-known/jwks.json'
|
41 | })
|
42 | });
|
43 |
|
44 | middleware({ headers: { authorization: 'Bearer abc' } }, { }, function(err) {
|
45 | expect(err.code).to.equal('invalid_token');
|
46 | });
|
47 | });
|
48 |
|
49 | it('should not provide a key if token is HS256', (done) => {
|
50 | const middleware = expressJwt({
|
51 | secret: jwksRsa.expressJwtSecret({
|
52 | jwksUri: 'http://localhost/.well-known/jwks.json'
|
53 | })
|
54 | });
|
55 |
|
56 | const token = createSymmetricToken('mykey', { sub: 'john' });
|
57 | middleware({ headers: { authorization: `Bearer ${token}` } }, { }, function(err) {
|
58 | expect(err.code).to.equal('invalid_token');
|
59 | done();
|
60 | });
|
61 | });
|
62 |
|
63 | it('should not provide a key if token is RS256 and no KID was provided', (done) => {
|
64 | const middleware = expressJwt({
|
65 | secret: jwksRsa.expressJwtSecret({
|
66 | jwksUri: 'http://localhost/.well-known/jwks.json'
|
67 | })
|
68 | });
|
69 |
|
70 | jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
|
71 |
|
72 | const token = createToken(privateKey, null, { sub: 'john' });
|
73 | middleware({ headers: { authorization: `Bearer ${token}` } }, { }, function(err) {
|
74 | expect(err.message).to.equal('secret or public key must be provided');
|
75 | done();
|
76 | });
|
77 | });
|
78 |
|
79 | it('should not provide a key if token is RS256 and invalid KID was provided', (done) => {
|
80 | const middleware = expressJwt({
|
81 | secret: jwksRsa.expressJwtSecret({
|
82 | jwksUri: 'http://localhost/.well-known/jwks.json'
|
83 | })
|
84 | });
|
85 |
|
86 | jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
|
87 |
|
88 | const token = createToken(privateKey, '456', { sub: 'john' });
|
89 | middleware({ headers: { authorization: `Bearer ${token}` } }, { }, function(err) {
|
90 | expect(err.message).to.equal('secret or public key must be provided');
|
91 | done();
|
92 | });
|
93 | });
|
94 |
|
95 | it('should not authenticate the user if KID matches but the keys dont', (done) => {
|
96 | const middleware = expressJwt({
|
97 | secret: jwksRsa.expressJwtSecret({
|
98 | jwksUri: 'http://localhost/.well-known/jwks.json'
|
99 | })
|
100 | });
|
101 |
|
102 | jwksEndpoint('http://localhost', [ { pub: randomPublicKey1, kid: '123' } ]);
|
103 |
|
104 | const token = createToken(privateKey, '123', { sub: 'john' });
|
105 | middleware({ headers: { authorization: `Bearer ${token}` } }, { }, function(err) {
|
106 | expect(err.message).to.equal('invalid signature');
|
107 | done();
|
108 | });
|
109 | });
|
110 |
|
111 | it('should allow returning an error if key not found', (done) => {
|
112 | const middleware = expressJwt({
|
113 | secret: jwksRsa.expressJwtSecret({
|
114 | jwksUri: 'http://localhost/.well-known/jwks.json',
|
115 | handleSigningKeyError: (err, cb) => {
|
116 | if (err instanceof jwksRsa.SigningKeyNotFoundError) {
|
117 | cb(new Error('This is bad'));
|
118 | }
|
119 | }
|
120 | })
|
121 | });
|
122 |
|
123 | jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
|
124 |
|
125 | const token = createToken(privateKey, '456', { sub: 'john' });
|
126 | middleware({ headers: { authorization: `Bearer ${token}` } }, { }, function(err) {
|
127 | expect(err.message).to.equal('This is bad');
|
128 | done();
|
129 | });
|
130 | });
|
131 |
|
132 | it('should work if the token matches a signing key', (done) => {
|
133 | const middleware = expressJwt({
|
134 | secret: jwksRsa.expressJwtSecret({
|
135 | jwksUri: 'http://localhost/.well-known/jwks.json',
|
136 | handleSigningKeyError: (err, cb) => {
|
137 | if (err instanceof jwksRsa.SigningKeyNotFoundError) {
|
138 | cb(new Error('This is bad'));
|
139 | }
|
140 | }
|
141 | })
|
142 | });
|
143 |
|
144 | jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
|
145 |
|
146 | const token = createToken(privateKey, '123', { sub: 'john' });
|
147 | const req = { headers: { authorization: `Bearer ${token}` } };
|
148 | middleware(req, { }, function(err) {
|
149 | expect(err).to.be.undefined;
|
150 | expect(req.user.sub).to.equal('john');
|
151 | done();
|
152 | });
|
153 | });
|
154 |
|
155 | });
|
156 | });
|