UNPKG

11.4 kBJavaScriptView Raw
1var jwt = require('jsonwebtoken');
2var assert = require('assert');
3
4var expressjwt = require('../lib');
5var UnauthorizedError = require('../lib/errors/UnauthorizedError');
6
7describe('failure tests', function () {
8 var req = {};
9 var res = {};
10
11 it('should throw if options not sent', function() {
12 try {
13 expressjwt();
14 } catch(e) {
15 assert.ok(e);
16 assert.equal(e.message, 'secret should be set');
17 }
18 });
19
20 it('should throw if no authorization header and credentials are required', function() {
21 expressjwt({secret: 'shhhh', credentialsRequired: true})(req, res, function(err) {
22 assert.ok(err);
23 assert.equal(err.code, 'credentials_required');
24 });
25 });
26
27 it('support unless skip', function() {
28 req.originalUrl = '/index.html';
29 expressjwt({secret: 'shhhh'}).unless({path: '/index.html'})(req, res, function(err) {
30 assert.ok(!err);
31 });
32 });
33
34 it('should skip on CORS preflight', function() {
35 var corsReq = {};
36 corsReq.method = 'OPTIONS';
37 corsReq.headers = {
38 'access-control-request-headers': 'sasa, sras, authorization'
39 };
40 expressjwt({secret: 'shhhh'})(corsReq, res, function(err) {
41 assert.ok(!err);
42 });
43 });
44
45 it('should throw if authorization header is malformed', function() {
46 req.headers = {};
47 req.headers.authorization = 'wrong';
48 expressjwt({secret: 'shhhh'})(req, res, function(err) {
49 assert.ok(err);
50 assert.equal(err.code, 'credentials_bad_format');
51 });
52 });
53
54 it('should throw if authorization header is not Bearer', function() {
55 req.headers = {};
56 req.headers.authorization = 'Basic foobar';
57 expressjwt({secret: 'shhhh'})(req, res, function(err) {
58 assert.ok(err);
59 assert.equal(err.code, 'credentials_bad_scheme');
60 });
61 });
62
63 it('should next if authorization header is not Bearer and credentialsRequired is false', function() {
64 req.headers = {};
65 req.headers.authorization = 'Basic foobar';
66 expressjwt({secret: 'shhhh', credentialsRequired: false})(req, res, function(err) {
67 assert.ok(typeof err === 'undefined');
68 });
69 });
70
71 it('should throw if authorization header is not well-formatted jwt', function() {
72 req.headers = {};
73 req.headers.authorization = 'Bearer wrongjwt';
74 expressjwt({secret: 'shhhh'})(req, res, function(err) {
75 assert.ok(err);
76 assert.equal(err.code, 'invalid_token');
77 });
78 });
79
80 it('should throw if jwt is an invalid json', function() {
81 req.headers = {};
82 req.headers.authorization = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.yJ1c2VybmFtZSI6InNhZ3VpYXIiLCJpYXQiOjE0NzEwMTg2MzUsImV4cCI6MTQ3MzYxMDYzNX0.foo';
83 expressjwt({secret: 'shhhh'})(req, res, function(err) {
84 assert.ok(err);
85 assert.equal(err.code, 'invalid_token');
86 });
87 });
88
89 it('should throw if authorization header is not valid jwt', function() {
90 var secret = 'shhhhhh';
91 var token = jwt.sign({foo: 'bar'}, secret);
92
93 req.headers = {};
94 req.headers.authorization = 'Bearer ' + token;
95 expressjwt({secret: 'different-shhhh'})(req, res, function(err) {
96 assert.ok(err);
97 assert.equal(err.code, 'invalid_token');
98 assert.equal(err.message, 'invalid signature');
99 });
100 });
101
102 it('should throw if audience is not expected', function() {
103 var secret = 'shhhhhh';
104 var token = jwt.sign({foo: 'bar', aud: 'expected-audience'}, secret);
105
106 req.headers = {};
107 req.headers.authorization = 'Bearer ' + token;
108 expressjwt({secret: 'shhhhhh', audience: 'not-expected-audience'})(req, res, function(err) {
109 assert.ok(err);
110 assert.equal(err.code, 'invalid_token');
111 assert.equal(err.message, 'jwt audience invalid. expected: not-expected-audience');
112 });
113 });
114
115 it('should throw if token is expired', function() {
116 var secret = 'shhhhhh';
117 var token = jwt.sign({foo: 'bar', exp: 1382412921 }, secret);
118
119 req.headers = {};
120 req.headers.authorization = 'Bearer ' + token;
121 expressjwt({secret: 'shhhhhh'})(req, res, function(err) {
122 assert.ok(err);
123 assert.equal(err.code, 'invalid_token');
124 assert.equal(err.inner.name, 'TokenExpiredError');
125 assert.equal(err.message, 'jwt expired');
126 });
127 });
128
129 it('should throw if token issuer is wrong', function() {
130 var secret = 'shhhhhh';
131 var token = jwt.sign({foo: 'bar', iss: 'http://foo' }, secret);
132
133 req.headers = {};
134 req.headers.authorization = 'Bearer ' + token;
135 expressjwt({secret: 'shhhhhh', issuer: 'http://wrong'})(req, res, function(err) {
136 assert.ok(err);
137 assert.equal(err.code, 'invalid_token');
138 assert.equal(err.message, 'jwt issuer invalid. expected: http://wrong');
139 });
140 });
141
142 it('should use errors thrown from custom getToken function', function() {
143 var secret = 'shhhhhh';
144 var token = jwt.sign({foo: 'bar'}, secret);
145
146 function getTokenThatThrowsError() {
147 throw new UnauthorizedError('invalid_token', { message: 'Invalid token!' });
148 }
149
150 expressjwt({
151 secret: 'shhhhhh',
152 getToken: getTokenThatThrowsError
153 })(req, res, function(err) {
154 assert.ok(err);
155 assert.equal(err.code, 'invalid_token');
156 assert.equal(err.message, 'Invalid token!');
157 });
158 });
159
160
161 it('should throw error when signature is wrong', function() {
162 var secret = "shhh";
163 var token = jwt.sign({foo: 'bar', iss: 'http://www'}, secret);
164 // manipulate the token
165 var newContent = new Buffer("{foo: 'bar', edg: 'ar'}").toString('base64');
166 var splitetToken = token.split(".");
167 splitetToken[1] = newContent;
168 var newToken = splitetToken.join(".");
169
170 // build request
171 req.headers = [];
172 req.headers.authorization = 'Bearer ' + newToken;
173 expressjwt({secret: secret})(req,res, function(err) {
174 assert.ok(err);
175 assert.equal(err.code, 'invalid_token');
176 assert.equal(err.message, 'invalid token');
177 });
178 });
179
180 it('should throw error if token is expired even with when credentials are not required', function() {
181 var secret = 'shhhhhh';
182 var token = jwt.sign({foo: 'bar', exp: 1382412921}, secret);
183
184 req.headers = {};
185 req.headers.authorization = 'Bearer ' + token;
186 expressjwt({ secret: secret, credentialsRequired: false })(req, res, function(err) {
187 assert.ok(err);
188 assert.equal(err.code, 'invalid_token');
189 assert.equal(err.message, 'jwt expired');
190 });
191 });
192
193 it('should throw error if token is invalid even with when credentials are not required', function() {
194 var secret = 'shhhhhh';
195 var token = jwt.sign({foo: 'bar', exp: 1382412921}, secret);
196
197 req.headers = {};
198 req.headers.authorization = 'Bearer ' + token;
199 expressjwt({ secret: "not the secret", credentialsRequired: false })(req, res, function(err) {
200 assert.ok(err);
201 assert.equal(err.code, 'invalid_token');
202 assert.equal(err.message, 'invalid signature');
203 });
204 });
205
206});
207
208describe('work tests', function () {
209 var req = {};
210 var res = {};
211
212 it('should work if authorization header is valid jwt', function() {
213 var secret = 'shhhhhh';
214 var token = jwt.sign({foo: 'bar'}, secret);
215
216 req.headers = {};
217 req.headers.authorization = 'Bearer ' + token;
218 expressjwt({secret: secret})(req, res, function() {
219 assert.equal('bar', req.user.foo);
220 });
221 });
222
223 it('should work with nested properties', function() {
224 var secret = 'shhhhhh';
225 var token = jwt.sign({foo: 'bar'}, secret);
226
227 req.headers = {};
228 req.headers.authorization = 'Bearer ' + token;
229 expressjwt({secret: secret, requestProperty: 'auth.token'})(req, res, function() {
230 assert.equal('bar', req.auth.token.foo);
231 });
232 });
233
234 it('should work if authorization header is valid with a buffer secret', function() {
235 var secret = new Buffer('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 'base64');
236 var token = jwt.sign({foo: 'bar'}, secret);
237
238 req.headers = {};
239 req.headers.authorization = 'Bearer ' + token;
240 expressjwt({secret: secret})(req, res, function() {
241 assert.equal('bar', req.user.foo);
242 });
243 });
244
245 it('should set userProperty if option provided', function() {
246 var secret = 'shhhhhh';
247 var token = jwt.sign({foo: 'bar'}, secret);
248
249 req.headers = {};
250 req.headers.authorization = 'Bearer ' + token;
251 expressjwt({secret: secret, userProperty: 'auth'})(req, res, function() {
252 assert.equal('bar', req.auth.foo);
253 });
254 });
255
256 it('should set resultProperty if option provided', function() {
257 var secret = 'shhhhhh';
258 var token = jwt.sign({foo: 'bar'}, secret);
259
260 req = { };
261 res = { };
262 req.headers = {};
263 req.headers.authorization = 'Bearer ' + token;
264 expressjwt({secret: secret, resultProperty: 'locals.user'})(req, res, function() {
265 assert.equal('bar', res.locals.user.foo);
266 assert.ok(typeof req.user === 'undefined');
267 });
268 });
269
270 it('should ignore userProperty if resultProperty option provided', function() {
271 var secret = 'shhhhhh';
272 var token = jwt.sign({foo: 'bar'}, secret);
273
274 req = { };
275 res = { };
276 req.headers = {};
277 req.headers.authorization = 'Bearer ' + token;
278 expressjwt({secret: secret, userProperty: 'auth', resultProperty: 'locals.user'})(req, res, function() {
279 assert.equal('bar', res.locals.user.foo);
280 assert.ok(typeof req.auth === 'undefined');
281 });
282 });
283
284 it('should work if no authorization header and credentials are not required', function() {
285 req = {};
286 expressjwt({ secret: 'shhhh', credentialsRequired: false })(req, res, function(err) {
287 assert(typeof err === 'undefined');
288 });
289 });
290
291 it('should not work if no authorization header', function() {
292 req = {};
293 expressjwt({ secret: 'shhhh' })(req, res, function(err) {
294 assert(typeof err !== 'undefined');
295 });
296 });
297
298 it('should produce a stack trace that includes the failure reason', function() {
299 var req = {};
300 var token = jwt.sign({foo: 'bar'}, 'secretA');
301 req.headers = {};
302 req.headers.authorization = 'Bearer ' + token;
303
304 expressjwt({secret: 'secretB'})(req, res, function(err) {
305 var index = err.stack.indexOf('UnauthorizedError: invalid signature')
306 assert.equal(index, 0, "Stack trace didn't include 'invalid signature' message.")
307 });
308
309 });
310
311 it('should work with a custom getToken function', function() {
312 var secret = 'shhhhhh';
313 var token = jwt.sign({foo: 'bar'}, secret);
314
315 req.headers = {};
316 req.query = {};
317 req.query.token = token;
318
319 function getTokenFromQuery(req) {
320 return req.query.token;
321 }
322
323 expressjwt({
324 secret: secret,
325 getToken: getTokenFromQuery
326 })(req, res, function() {
327 assert.equal('bar', req.user.foo);
328 });
329 });
330
331 it('should work with a secretCallback function that accepts header argument', function() {
332 var secret = 'shhhhhh';
333 var secretCallback = function(req, headers, payload, cb) {
334 assert.equal(headers.alg, 'HS256');
335 assert.equal(payload.foo, 'bar');
336 process.nextTick(function(){ return cb(null, secret) });
337 }
338 var token = jwt.sign({foo: 'bar'}, secret);
339
340 req.headers = {};
341 req.headers.authorization = 'Bearer ' + token;
342 expressjwt({secret: secretCallback})(req, res, function() {
343 assert.equal('bar', req.user.foo);
344 });
345 });
346});