UNPKG

8.73 kBJavaScriptView Raw
1import request from 'supertest';
2import { expect } from 'chai';
3
4import { jwksEndpoint } from './mocks/jwks';
5import { publicKey, privateKey, randomPublicKey1 } from './mocks/keys';
6import { createToken, createSymmetricToken } from './mocks/tokens';
7
8const Express = require('express');
9const passport = require('passport');
10const JwtStrategy = require('passport-jwt').Strategy;
11const ExtractJwt = require('passport-jwt').ExtractJwt;
12
13const jwksRsa = require('../src');
14
15describe('passportJwtSecret', () => {
16 it('should throw error if options.jwksUri is null', () => {
17 let err = null;
18
19 try {
20 new jwksRsa.passportJwtSecret();
21 } catch (e) {
22 err = e;
23 }
24
25 expect(err instanceof jwksRsa.ArgumentError).to.be.true;
26 });
27
28 it('should accept the secret function', () => {
29 new JwtStrategy(
30 {
31 secretOrKeyProvider: jwksRsa.passportJwtSecret({
32 jwksUri: 'http://localhost/.well-known/jwks.json'
33 }),
34 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
35 },
36 (jwt_payload, done) => done(null, jwt_payload)
37 );
38 });
39
40 it('should not provide a key if token is invalid', done => {
41 const app = new Express();
42 passport.use(
43 new JwtStrategy(
44 {
45 secretOrKeyProvider: jwksRsa.passportJwtSecret({
46 jwksUri: 'http://localhost/.well-known/jwks.json'
47 }),
48 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
49 },
50 (jwt_payload, done) => done(null, jwt_payload)
51 )
52 );
53
54 app.get(
55 '/',
56 (req, res, next) => {
57 req.flash = (type, msg) => {
58 res.send(msg);
59 };
60 next();
61 },
62 passport.authenticate('jwt', { session: false, failureFlash: true }),
63 (req, res) => {
64 res.send('OK');
65 }
66 );
67
68 request(app.listen())
69 .get('/')
70 .set('Authorization', 'Bearer abc')
71 .expect(401)
72 .end((err, res) => {
73 expect(res.text).to.equal('jwt malformed');
74 done();
75 });
76 });
77
78 it('should not provide a key if token is HS256', done => {
79 const app = new Express();
80 passport.use(
81 new JwtStrategy(
82 {
83 secretOrKeyProvider: jwksRsa.passportJwtSecret({
84 jwksUri: 'http://localhost/.well-known/jwks.json'
85 }),
86 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
87 },
88 (jwt_payload, done) => done(null, jwt_payload)
89 )
90 );
91
92 app.get(
93 '/',
94 (req, res, next) => {
95 req.flash = (type, msg) => {
96 res.send(msg);
97 };
98 next();
99 },
100 passport.authenticate('jwt', { session: false, failureFlash: true }),
101 (req, res) => {
102 res.send('OK');
103 }
104 );
105
106 const token = createSymmetricToken('mykey', { sub: 'john' });
107
108 request(app.listen())
109 .get('/')
110 .set('Authorization', `Bearer ${token}`)
111 .expect(401)
112 .end((err, res) => {
113 expect(res.text).to.equal('secret or public key must be provided');
114 done();
115 });
116 });
117
118 it('should not provide a key if token is RS256 and no KID was provided', done => {
119 const app = new Express();
120 passport.use(
121 new JwtStrategy(
122 {
123 secretOrKeyProvider: jwksRsa.passportJwtSecret({
124 jwksUri: 'http://localhost/.well-known/jwks.json'
125 }),
126 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
127 },
128 (jwt_payload, done) => done(null, jwt_payload)
129 )
130 );
131
132 app.get(
133 '/',
134 (req, res, next) => {
135 req.flash = (type, msg) => {
136 res.send(msg);
137 };
138 next();
139 },
140 passport.authenticate('jwt', { session: false, failureFlash: true }),
141 (req, res) => {
142 res.send('OK');
143 }
144 );
145
146 const token = createToken(privateKey, null, { sub: 'john' });
147 jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
148
149 request(app.listen())
150 .get('/')
151 .set('Authorization', `Bearer ${token}`)
152 .expect(401)
153 .end((err, res) => {
154 expect(res.text).to.equal('secret or public key must be provided');
155 done();
156 });
157 });
158
159 it('should not provide a key if token is RS256 and invalid KID was provided', done => {
160 const app = new Express();
161 passport.use(
162 new JwtStrategy(
163 {
164 secretOrKeyProvider: jwksRsa.passportJwtSecret({
165 jwksUri: 'http://localhost/.well-known/jwks.json'
166 }),
167 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
168 },
169 (jwt_payload, done) => {
170 done(null, jwt_payload);
171 }
172 )
173 );
174
175 app.get(
176 '/',
177 (req, res, next) => {
178 req.flash = (type, msg) => {
179 res.send(msg);
180 };
181 next();
182 },
183 passport.authenticate('jwt', { session: false, failureFlash: true }),
184 (req, res) => {
185 res.send('OK');
186 }
187 );
188
189 const token = createToken(privateKey, '456', { sub: 'john' });
190 jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
191
192 request(app.listen())
193 .get('/')
194 .set('Authorization', `Bearer ${token}`)
195 .expect(401)
196 .end((err, res) => {
197 expect(res.text).to.equal('secret or public key must be provided');
198 done();
199 });
200 });
201
202 it('should not authenticate the user if KID matches but the keys don\'t', done => {
203 const app = new Express();
204 passport.use(
205 new JwtStrategy(
206 {
207 secretOrKeyProvider: jwksRsa.passportJwtSecret({
208 jwksUri: 'http://localhost/.well-known/jwks.json'
209 }),
210 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
211 },
212 (jwt_payload, done) => {
213 done(null, jwt_payload);
214 }
215 )
216 );
217
218 app.get(
219 '/',
220 (req, res, next) => {
221 req.flash = (type, msg) => {
222 res.send(msg);
223 };
224 next();
225 },
226 passport.authenticate('jwt', { session: false, failureFlash: true }),
227 (req, res) => {
228 res.send('OK');
229 }
230 );
231
232 const token = createToken(privateKey, '123', { sub: 'john' });
233 jwksEndpoint('http://localhost', [ { pub: randomPublicKey1, kid: '123' } ]);
234
235 request(app.listen())
236 .get('/')
237 .set('Authorization', `Bearer ${token}`)
238 .expect(401)
239 .end((err, res) => {
240 expect(res.text).to.equal('invalid signature');
241 done();
242 });
243 });
244
245 it('should allow returning an error if key not found', done => {
246 const app = new Express();
247 passport.use(
248 new JwtStrategy(
249 {
250 secretOrKeyProvider: jwksRsa.passportJwtSecret({
251 jwksUri: 'http://localhost/.well-known/jwks.json',
252 handleSigningKeyError: (err, cb) => {
253 if (err instanceof jwksRsa.SigningKeyNotFoundError) {
254 return cb(new Error('this is bad'));
255 }
256 }
257 }),
258 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
259 },
260 (jwt_payload, done) => done(null, jwt_payload)
261 )
262 );
263
264 app.get(
265 '/',
266 (req, res, next) => {
267 req.flash = (type, msg) => {
268 res.send(msg);
269 };
270 next();
271 },
272 passport.authenticate('jwt', { session: false, failureFlash: true }),
273 (req, res) => {
274 res.send('OK');
275 }
276 );
277
278 const token = createToken(privateKey, '456', { sub: 'john' });
279 jwksEndpoint('http://localhost', [ { pub: randomPublicKey1, kid: '123' } ]);
280
281 request(app.listen())
282 .get('/')
283 .set('Authorization', `Bearer ${token}`)
284 .expect(401)
285 .end((err, res) => {
286 expect(res.text).to.equal('this is bad');
287 done();
288 });
289 });
290
291 it('should work if the token matches a signing key', done => {
292 const app = new Express();
293 passport.use(
294 new JwtStrategy(
295 {
296 secretOrKeyProvider: jwksRsa.passportJwtSecret({
297 jwksUri: 'http://localhost/.well-known/jwks.json'
298 }),
299 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
300 algorithms: [ 'RS256' ]
301 },
302 (jwt_payload, done) => done(null, jwt_payload)
303 )
304 );
305
306 app.get(
307 '/',
308 passport.authenticate('jwt', { session: false }),
309 (req, res) => {
310 res.json(req.user);
311 }
312 );
313
314 const token = createToken(privateKey, '123', { sub: 'john' });
315 jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
316
317 request(app.listen())
318 .get('/')
319 .set('Authorization', `Bearer ${token}`)
320 .expect(200)
321 .end((err, res) => {
322 expect(res.body.sub).to.equal('john');
323 done();
324 });
325 });
326});