Skip to content

Commit 304a1c5

Browse files
author
Marcos Castany
committedJun 25, 2020
Made algorithms mandatory
1 parent e9ed6d2 commit 304a1c5

6 files changed

+57
-33
lines changed
 

‎lib/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ function wrapStaticSecretInCallback(secret){
1919
module.exports = function(options) {
2020
if (!options || !options.secret) throw new Error('secret should be set');
2121

22+
if (!options.algorithms) throw new Error('algorithms should be set');
23+
if (!Array.isArray(options.algorithms)) throw new Error('algorithms must be an array');
24+
2225
var secretCallback = options.secret;
2326

2427
if (!isFunction(secretCallback)){

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"mocha": "^7.1.1"
4040
},
4141
"engines": {
42-
"node": ">= 0.4.0"
42+
"node": ">= 8.0.0"
4343
},
4444
"scripts": {
4545
"test": "node_modules/.bin/mocha --reporter spec"

‎test/jwt.test.js

+46-29
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,34 @@ describe('failure tests', function () {
1717
}
1818
});
1919

20+
it('should throw if algorithms is not sent', function() {
21+
try {
22+
expressjwt({ secret: 'shhhh' });
23+
} catch(e) {
24+
assert.ok(e);
25+
assert.equal(e.message, 'algorithms should be set');
26+
}
27+
});
28+
29+
it('should throw if algorithms is not an array', function() {
30+
try {
31+
expressjwt({ secret: 'shhhh', algorithms: 'foo' });
32+
} catch(e) {
33+
assert.ok(e);
34+
assert.equal(e.message, 'algorithms must be an array');
35+
}
36+
});
37+
2038
it('should throw if no authorization header and credentials are required', function() {
21-
expressjwt({secret: 'shhhh', credentialsRequired: true})(req, res, function(err) {
39+
expressjwt({secret: 'shhhh', credentialsRequired: true, algorithms: ['HS256']})(req, res, function(err) {
2240
assert.ok(err);
2341
assert.equal(err.code, 'credentials_required');
2442
});
2543
});
2644

2745
it('support unless skip', function() {
2846
req.originalUrl = '/index.html';
29-
expressjwt({secret: 'shhhh'}).unless({path: '/index.html'})(req, res, function(err) {
47+
expressjwt({secret: 'shhhh', algorithms: ['HS256'], algorithms: ['HS256']}).unless({path: '/index.html'})(req, res, function(err) {
3048
assert.ok(!err);
3149
});
3250
});
@@ -37,15 +55,15 @@ describe('failure tests', function () {
3755
corsReq.headers = {
3856
'access-control-request-headers': 'sasa, sras, authorization'
3957
};
40-
expressjwt({secret: 'shhhh'})(corsReq, res, function(err) {
58+
expressjwt({secret: 'shhhh', algorithms: ['HS256']})(corsReq, res, function(err) {
4159
assert.ok(!err);
4260
});
4361
});
4462

4563
it('should throw if authorization header is malformed', function() {
4664
req.headers = {};
4765
req.headers.authorization = 'wrong';
48-
expressjwt({secret: 'shhhh'})(req, res, function(err) {
66+
expressjwt({secret: 'shhhh', algorithms: ['HS256']})(req, res, function(err) {
4967
assert.ok(err);
5068
assert.equal(err.code, 'credentials_bad_format');
5169
});
@@ -54,7 +72,7 @@ describe('failure tests', function () {
5472
it('should throw if authorization header is not Bearer', function() {
5573
req.headers = {};
5674
req.headers.authorization = 'Basic foobar';
57-
expressjwt({secret: 'shhhh'})(req, res, function(err) {
75+
expressjwt({secret: 'shhhh', algorithms: ['HS256']})(req, res, function(err) {
5876
assert.ok(err);
5977
assert.equal(err.code, 'credentials_bad_scheme');
6078
});
@@ -63,15 +81,15 @@ describe('failure tests', function () {
6381
it('should next if authorization header is not Bearer and credentialsRequired is false', function() {
6482
req.headers = {};
6583
req.headers.authorization = 'Basic foobar';
66-
expressjwt({secret: 'shhhh', credentialsRequired: false})(req, res, function(err) {
84+
expressjwt({secret: 'shhhh', algorithms: ['HS256'], credentialsRequired: false})(req, res, function(err) {
6785
assert.ok(typeof err === 'undefined');
6886
});
6987
});
7088

7189
it('should throw if authorization header is not well-formatted jwt', function() {
7290
req.headers = {};
7391
req.headers.authorization = 'Bearer wrongjwt';
74-
expressjwt({secret: 'shhhh'})(req, res, function(err) {
92+
expressjwt({secret: 'shhhh', algorithms: ['HS256']})(req, res, function(err) {
7593
assert.ok(err);
7694
assert.equal(err.code, 'invalid_token');
7795
});
@@ -80,7 +98,7 @@ describe('failure tests', function () {
8098
it('should throw if jwt is an invalid json', function() {
8199
req.headers = {};
82100
req.headers.authorization = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.yJ1c2VybmFtZSI6InNhZ3VpYXIiLCJpYXQiOjE0NzEwMTg2MzUsImV4cCI6MTQ3MzYxMDYzNX0.foo';
83-
expressjwt({secret: 'shhhh'})(req, res, function(err) {
101+
expressjwt({secret: 'shhhh', algorithms: ['HS256']})(req, res, function(err) {
84102
assert.ok(err);
85103
assert.equal(err.code, 'invalid_token');
86104
});
@@ -92,7 +110,7 @@ describe('failure tests', function () {
92110

93111
req.headers = {};
94112
req.headers.authorization = 'Bearer ' + token;
95-
expressjwt({secret: 'different-shhhh'})(req, res, function(err) {
113+
expressjwt({secret: 'different-shhhh', algorithms: ['HS256'] })(req, res, function(err) {
96114
assert.ok(err);
97115
assert.equal(err.code, 'invalid_token');
98116
assert.equal(err.message, 'invalid signature');
@@ -101,11 +119,11 @@ describe('failure tests', function () {
101119

102120
it('should throw if audience is not expected', function() {
103121
var secret = 'shhhhhh';
104-
var token = jwt.sign({foo: 'bar', aud: 'expected-audience'}, secret);
122+
var token = jwt.sign({foo: 'bar', aud: 'expected-audience'}, secret, { expiresIn: 500});
105123

106124
req.headers = {};
107125
req.headers.authorization = 'Bearer ' + token;
108-
expressjwt({secret: 'shhhhhh', audience: 'not-expected-audience'})(req, res, function(err) {
126+
expressjwt({secret: 'shhhhhh', algorithms: ['HS256'], audience: 'not-expected-audience'})(req, res, function(err) {
109127
assert.ok(err);
110128
assert.equal(err.code, 'invalid_token');
111129
assert.equal(err.message, 'jwt audience invalid. expected: not-expected-audience');
@@ -118,7 +136,7 @@ describe('failure tests', function () {
118136

119137
req.headers = {};
120138
req.headers.authorization = 'Bearer ' + token;
121-
expressjwt({secret: 'shhhhhh'})(req, res, function(err) {
139+
expressjwt({secret: 'shhhhhh', algorithms: ['HS256']})(req, res, function(err) {
122140
assert.ok(err);
123141
assert.equal(err.code, 'invalid_token');
124142
assert.equal(err.inner.name, 'TokenExpiredError');
@@ -132,7 +150,7 @@ describe('failure tests', function () {
132150

133151
req.headers = {};
134152
req.headers.authorization = 'Bearer ' + token;
135-
expressjwt({secret: 'shhhhhh', issuer: 'http://wrong'})(req, res, function(err) {
153+
expressjwt({secret: 'shhhhhh', algorithms: ['HS256'], issuer: 'http://wrong'})(req, res, function(err) {
136154
assert.ok(err);
137155
assert.equal(err.code, 'invalid_token');
138156
assert.equal(err.message, 'jwt issuer invalid. expected: http://wrong');
@@ -141,14 +159,13 @@ describe('failure tests', function () {
141159

142160
it('should use errors thrown from custom getToken function', function() {
143161
var secret = 'shhhhhh';
144-
var token = jwt.sign({foo: 'bar'}, secret);
145162

146163
function getTokenThatThrowsError() {
147164
throw new UnauthorizedError('invalid_token', { message: 'Invalid token!' });
148165
}
149166

150167
expressjwt({
151-
secret: 'shhhhhh',
168+
secret: 'shhhhhh', algorithms: ['HS256'],
152169
getToken: getTokenThatThrowsError
153170
})(req, res, function(err) {
154171
assert.ok(err);
@@ -157,7 +174,6 @@ describe('failure tests', function () {
157174
});
158175
});
159176

160-
161177
it('should throw error when signature is wrong', function() {
162178
var secret = "shhh";
163179
var token = jwt.sign({foo: 'bar', iss: 'http://www'}, secret);
@@ -170,7 +186,7 @@ describe('failure tests', function () {
170186
// build request
171187
req.headers = [];
172188
req.headers.authorization = 'Bearer ' + newToken;
173-
expressjwt({secret: secret})(req,res, function(err) {
189+
expressjwt({secret: secret, algorithms: ['HS256']})(req,res, function(err) {
174190
assert.ok(err);
175191
assert.equal(err.code, 'invalid_token');
176192
assert.equal(err.message, 'invalid token');
@@ -183,7 +199,7 @@ describe('failure tests', function () {
183199

184200
req.headers = {};
185201
req.headers.authorization = 'Bearer ' + token;
186-
expressjwt({ secret: secret, credentialsRequired: false })(req, res, function(err) {
202+
expressjwt({ secret: secret, credentialsRequired: false, algorithms: ['HS256'] })(req, res, function(err) {
187203
assert.ok(err);
188204
assert.equal(err.code, 'invalid_token');
189205
assert.equal(err.message, 'jwt expired');
@@ -196,7 +212,7 @@ describe('failure tests', function () {
196212

197213
req.headers = {};
198214
req.headers.authorization = 'Bearer ' + token;
199-
expressjwt({ secret: "not the secret", credentialsRequired: false })(req, res, function(err) {
215+
expressjwt({ secret: "not the secret", algorithms: ['HS256'], credentialsRequired: false })(req, res, function(err) {
200216
assert.ok(err);
201217
assert.equal(err.code, 'invalid_token');
202218
assert.equal(err.message, 'invalid signature');
@@ -215,7 +231,7 @@ describe('work tests', function () {
215231

216232
req.headers = {};
217233
req.headers.authorization = 'Bearer ' + token;
218-
expressjwt({secret: secret})(req, res, function() {
234+
expressjwt({secret: secret, algorithms: ['HS256']})(req, res, function() {
219235
assert.equal('bar', req.user.foo);
220236
});
221237
});
@@ -226,7 +242,7 @@ describe('work tests', function () {
226242

227243
req.headers = {};
228244
req.headers.authorization = 'Bearer ' + token;
229-
expressjwt({secret: secret, requestProperty: 'auth.token'})(req, res, function() {
245+
expressjwt({secret: secret, algorithms: ['HS256'], requestProperty: 'auth.token'})(req, res, function() {
230246
assert.equal('bar', req.auth.token.foo);
231247
});
232248
});
@@ -237,7 +253,7 @@ describe('work tests', function () {
237253

238254
req.headers = {};
239255
req.headers.authorization = 'Bearer ' + token;
240-
expressjwt({secret: secret})(req, res, function() {
256+
expressjwt({secret: secret, algorithms: ['HS256']})(req, res, function() {
241257
assert.equal('bar', req.user.foo);
242258
});
243259
});
@@ -248,7 +264,7 @@ describe('work tests', function () {
248264

249265
req.headers = {};
250266
req.headers.authorization = 'Bearer ' + token;
251-
expressjwt({secret: secret, userProperty: 'auth'})(req, res, function() {
267+
expressjwt({secret: secret, algorithms: ['HS256'], userProperty: 'auth'})(req, res, function() {
252268
assert.equal('bar', req.auth.foo);
253269
});
254270
});
@@ -261,7 +277,7 @@ describe('work tests', function () {
261277
res = { };
262278
req.headers = {};
263279
req.headers.authorization = 'Bearer ' + token;
264-
expressjwt({secret: secret, resultProperty: 'locals.user'})(req, res, function() {
280+
expressjwt({secret: secret, algorithms: ['HS256'], resultProperty: 'locals.user'})(req, res, function() {
265281
assert.equal('bar', res.locals.user.foo);
266282
assert.ok(typeof req.user === 'undefined');
267283
});
@@ -275,22 +291,22 @@ describe('work tests', function () {
275291
res = { };
276292
req.headers = {};
277293
req.headers.authorization = 'Bearer ' + token;
278-
expressjwt({secret: secret, userProperty: 'auth', resultProperty: 'locals.user'})(req, res, function() {
294+
expressjwt({secret: secret, algorithms: ['HS256'], userProperty: 'auth', resultProperty: 'locals.user'})(req, res, function() {
279295
assert.equal('bar', res.locals.user.foo);
280296
assert.ok(typeof req.auth === 'undefined');
281297
});
282298
});
283299

284300
it('should work if no authorization header and credentials are not required', function() {
285301
req = {};
286-
expressjwt({ secret: 'shhhh', credentialsRequired: false })(req, res, function(err) {
302+
expressjwt({ secret: 'shhhh', algorithms: ['HS256'], credentialsRequired: false })(req, res, function(err) {
287303
assert(typeof err === 'undefined');
288304
});
289305
});
290306

291307
it('should not work if no authorization header', function() {
292308
req = {};
293-
expressjwt({ secret: 'shhhh' })(req, res, function(err) {
309+
expressjwt({ secret: 'shhhh', algorithms: ['HS256'] })(req, res, function(err) {
294310
assert(typeof err !== 'undefined');
295311
});
296312
});
@@ -301,7 +317,7 @@ describe('work tests', function () {
301317
req.headers = {};
302318
req.headers.authorization = 'Bearer ' + token;
303319

304-
expressjwt({secret: 'secretB'})(req, res, function(err) {
320+
expressjwt({secret: 'secretB', algorithms: ['HS256']})(req, res, function(err) {
305321
var index = err.stack.indexOf('UnauthorizedError: invalid signature')
306322
assert.equal(index, 0, "Stack trace didn't include 'invalid signature' message.")
307323
});
@@ -322,6 +338,7 @@ describe('work tests', function () {
322338

323339
expressjwt({
324340
secret: secret,
341+
algorithms: ['HS256'],
325342
getToken: getTokenFromQuery
326343
})(req, res, function() {
327344
assert.equal('bar', req.user.foo);
@@ -339,7 +356,7 @@ describe('work tests', function () {
339356

340357
req.headers = {};
341358
req.headers.authorization = 'Bearer ' + token;
342-
expressjwt({secret: secretCallback})(req, res, function() {
359+
expressjwt({secret: secretCallback, algorithms: ['HS256']})(req, res, function() {
343360
assert.equal('bar', req.user.foo);
344361
});
345362
});

‎test/multitenancy.test.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ describe('multitenancy', function(){
2525
};
2626

2727
var middleware = expressjwt({
28-
secret: secretCallback
28+
secret: secretCallback,
29+
algorithms: ['HS256']
2930
});
3031

3132
it ('should retrieve secret using callback', function(){
@@ -59,8 +60,9 @@ describe('multitenancy', function(){
5960
req.headers = {};
6061
req.headers.authorization = 'Bearer ' + token;
6162

62-
var middleware = expressjwt({
63+
expressjwt({
6364
secret: secretCallback,
65+
algorithms: ['HS256'],
6466
isRevoked: function(req, payload, done){
6567
done(null, true);
6668
}

‎test/revocation.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ describe('revoked jwts', function(){
1111

1212
var middleware = expressjwt({
1313
secret: secret,
14+
algorithms: ['HS256'],
1415
isRevoked: function(req, payload, done){
1516
done(null, payload.jti && payload.jti === revoked_id);
1617
}
@@ -54,6 +55,7 @@ describe('revoked jwts', function(){
5455

5556
expressjwt({
5657
secret: secret,
58+
algorithms: ['HS256'],
5759
isRevoked: function(req, payload, done){
5860
done(new Error('An error ocurred'));
5961
}

‎test/string_token.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe('string tokens', function () {
1414

1515
req.headers = {};
1616
req.headers.authorization = 'Bearer ' + token;
17-
expressjwt({secret: secret})(req, res, function() {
17+
expressjwt({secret: secret, algorithms: ['HS256']})(req, res, function() {
1818
assert.equal('foo', req.user);
1919
});
2020
});

0 commit comments

Comments
 (0)
Please sign in to comment.