Socket
Socket
Sign inDemoInstall

jsonwebtoken

Package Overview
Dependencies
Maintainers
8
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsonwebtoken - npm Package Compare versions

Comparing version 7.2.1 to 7.3.0

.history/CHANGELOG_20170213194220.md

14

CHANGELOG.md

@@ -7,2 +7,16 @@ # Change Log

## 7.3.0 - 2017-02-13
- Add more information to `maxAge` option in README ([1b0592e99cc8def293eed177e2575fa7f1cf7aa5](https://github.com/auth0/node-jsonwebtoken/commit/1b0592e99cc8def293eed177e2575fa7f1cf7aa5))
- Add `clockTimestamp` option to `verify()` you can set the current time in seconds with it (#274) ([8fdc1504f4325e7003894ffea078da9cba5208d9](https://github.com/auth0/node-jsonwebtoken/commit/8fdc1504f4325e7003894ffea078da9cba5208d9))
- Fix handling non string tokens on `verify()` input (#305) ([1b6ec8d466504f58c5a6e2dae3360c828bad92fb](https://github.com/auth0/node-jsonwebtoken/commit/1b6ec8d466504f58c5a6e2dae3360c828bad92fb)), closes [#305](https://github.com/auth0/node-jsonwebtoken/issues/305)
- Fixed a simple typo in docs (#287) ([a54240384e24e18c00e75884295306db311d0cb7](https://github.com/auth0/node-jsonwebtoken/commit/a54240384e24e18c00e75884295306db311d0cb7)), closes [#287](https://github.com/auth0/node-jsonwebtoken/issues/287)
- Raise jws.decode error to avoid confusion with "invalid token" error (#294) ([7f68fe06c88d5c5653785bd66bc68c5b20e1bd8e](https://github.com/auth0/node-jsonwebtoken/commit/7f68fe06c88d5c5653785bd66bc68c5b20e1bd8e))
- rauchg/ms.js changed to zeit/ms (#303) ([35d84152a6b716d757cb5b1dd3c79fe3a1bc0628](https://github.com/auth0/node-jsonwebtoken/commit/35d84152a6b716d757cb5b1dd3c79fe3a1bc0628))
## 7.2.1 - 2016-12-07
- add nsp check to find vulnerabilities on npm test ([4219c34b5346811c07f520f10516cc495bcc70dd](https://github.com/auth0/node-jsonwebtoken/commit/4219c34b5346811c07f520f10516cc495bcc70dd))
- revert to joi@^6 to keep ES5 compatibility ([51d4796c07344bf817687f7ccfeef78f00bf5b4f](https://github.com/auth0/node-jsonwebtoken/commit/51d4796c07344bf817687f7ccfeef78f00bf5b4f))
## 7.2.0 - 2016-12-06

@@ -9,0 +23,0 @@

2

package.json
{
"name": "jsonwebtoken",
"version": "7.2.1",
"version": "7.3.0",
"description": "JSON Web Token implementation (symmetric and asymmetric)",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -32,4 +32,4 @@ # jsonwebtoken

* `algorithm` (default: `HS256`)
* `expiresIn`: expressed in seconds or a string describing a time span [rauchg/ms](https://github.com/rauchg/ms.js). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
* `notBefore`: expressed in seconds or a string describing a time span [rauchg/ms](https://github.com/rauchg/ms.js). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
* `expiresIn`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
* `notBefore`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). Eg: `60`, `"2 days"`, `"10h"`, `"7d"`
* `audience`

@@ -82,3 +82,3 @@ * `issuer`

jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 60)
exp: Math.floor(Date.now() / 1000) + (60 * 60),
data: 'foobar'

@@ -121,3 +121,5 @@ }, 'secret');

* `subject`: if you want to check subject (`sub`), provide a value here
* `clockTolerance`: number of second to tolerate when checking the `nbf` and `exp` claims, to deal with small clock differences among different servers
* `clockTolerance`: number of seconds to tolerate when checking the `nbf` and `exp` claims, to deal with small clock differences among different servers
* `maxAge`: the maximum allowed age for tokens to still be valid. Currently it is expressed in milliseconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms). Eg: `1000`, `"2 days"`, `"10h"`, `"7d"`. **We advise against using milliseconds precision, though, since JWTs can only contain seconds. The maximum precision might be reduced to seconds in the future.**
* `clockTimestamp`: the time in seconds that should be used as the current time for all necessary comparisons (also against `maxAge`, so our advise is to avoid using `clockTimestamp` and a `maxAge` in milliseconds together)

@@ -124,0 +126,0 @@

@@ -80,4 +80,19 @@ var jwt = require('../index');

});
});
describe('should fail verification gracefully with trailing space in the jwt', function() {
var secret = 'shhhhhh';
var token = jwt.sign({ foo: 'bar' }, secret, { algorithm: 'HS256' });
it('should return the "invalid token" error', function(done) {
var malformedToken = token + ' '; // corrupt the token by adding a space
jwt.verify(malformedToken, secret, { algorithm: 'HS256', ignoreExpiration: true }, function(err, decoded) {
assert.isNotNull(err);
assert.equal('JsonWebTokenError', err.name);
assert.equal('invalid token', err.message);
done();
});
});
});
});

@@ -192,4 +192,143 @@ var jwt = require('../index');

});
describe('option: clockTimestamp', function () {
var clockTimestamp = 1000000000;
it('should verify unexpired token relative to user-provided clockTimestamp', function (done) {
var token = jwt.sign({foo: 'bar', iat: clockTimestamp, exp: clockTimestamp + 1}, key);
jwt.verify(token, key, {clockTimestamp: clockTimestamp}, function (err, p) {
assert.isNull(err);
done();
});
});
it('should error on expired token relative to user-provided clockTimestamp', function (done) {
var token = jwt.sign({foo: 'bar', iat: clockTimestamp, exp: clockTimestamp + 1}, key);
jwt.verify(token, key, {clockTimestamp: clockTimestamp + 1}, function (err, p) {
assert.equal(err.name, 'TokenExpiredError');
assert.equal(err.message, 'jwt expired');
assert.equal(err.expiredAt.constructor.name, 'Date');
assert.equal(Number(err.expiredAt), (clockTimestamp + 1) * 1000);
assert.isUndefined(p);
done();
});
});
it('should verify clockTimestamp is a number', function (done) {
var token = jwt.sign({foo: 'bar', iat: clockTimestamp, exp: clockTimestamp + 1}, key);
jwt.verify(token, key, {clockTimestamp: 'notANumber'}, function (err, p) {
assert.equal(err.name, 'JsonWebTokenError');
assert.equal(err.message,'clockTimestamp must be a number');
assert.isUndefined(p);
done();
});
});
it('should verify valid token with nbf', function (done) {
var token = jwt.sign({
foo: 'bar',
iat: clockTimestamp,
nbf: clockTimestamp + 1,
exp: clockTimestamp + 2
}, key);
jwt.verify(token, key, {clockTimestamp: clockTimestamp + 1}, function (err, p) {
assert.isNull(err);
done();
});
});
it('should error on token used before nbf', function (done) {
var token = jwt.sign({
foo: 'bar',
iat: clockTimestamp,
nbf: clockTimestamp + 1,
exp: clockTimestamp + 2
}, key);
jwt.verify(token, key, {clockTimestamp: clockTimestamp}, function (err, p) {
assert.equal(err.name, 'NotBeforeError');
assert.equal(err.date.constructor.name, 'Date');
assert.equal(Number(err.date), (clockTimestamp + 1) * 1000);
assert.isUndefined(p);
done();
});
});
});
describe('option: maxAge and clockTimestamp', function () {
// { foo: 'bar', iat: 1437018582, exp: 1437018800 }
var token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE0MzcwMTg1ODIsImV4cCI6MTQzNzAxODgwMH0.AVOsNC7TiT-XVSpCpkwB1240izzCIJ33Lp07gjnXVpA';
it('should error for claims issued before a certain timespan', function (done) {
var clockTimestamp = 1437018682;
var options = {algorithms: ['HS256'], clockTimestamp: clockTimestamp, maxAge: '1m'};
jwt.verify(token, key, options, function (err, p) {
assert.equal(err.name, 'TokenExpiredError');
assert.equal(err.message, 'maxAge exceeded');
assert.equal(err.expiredAt.constructor.name, 'Date');
assert.equal(Number(err.expiredAt), 1437018642000);
assert.isUndefined(p);
done();
});
});
it('should not error for claims issued before a certain timespan but still inside clockTolerance timespan', function (done) {
var clockTimestamp = 1437018582;
var options = {
algorithms: ['HS256'],
clockTimestamp: clockTimestamp,
maxAge: '321ms',
clockTolerance: 100
};
jwt.verify(token, key, options, function (err, p) {
assert.isNull(err);
assert.equal(p.foo, 'bar');
done();
});
});
it('should not error if within maxAge timespan', function (done) {
var clockTimestamp = 1437018582;
var options = {algorithms: ['HS256'], clockTimestamp: clockTimestamp, maxAge: '600ms'};
jwt.verify(token, key, options, function (err, p) {
assert.isNull(err);
assert.equal(p.foo, 'bar');
done();
});
});
it('can be more restrictive than expiration', function (done) {
var clockTimestamp = 1437018588;
var options = {algorithms: ['HS256'], clockTimestamp: clockTimestamp, maxAge: '5s'};
jwt.verify(token, key, options, function (err, p) {
assert.equal(err.name, 'TokenExpiredError');
assert.equal(err.message, 'maxAge exceeded');
assert.equal(err.expiredAt.constructor.name, 'Date');
assert.equal(Number(err.expiredAt), 1437018587000);
assert.isUndefined(p);
done();
});
});
it('cannot be more permissive than expiration', function (done) {
var clockTimestamp = 1437018900;
var options = {algorithms: ['HS256'], clockTimestamp: clockTimestamp, maxAge: '1000y'};
jwt.verify(token, key, options, function (err, p) {
// maxAge not exceded, but still expired
assert.equal(err.name, 'TokenExpiredError');
assert.equal(err.message, 'jwt expired');
assert.equal(err.expiredAt.constructor.name, 'Date');
assert.equal(Number(err.expiredAt), 1437018800000);
assert.isUndefined(p);
done();
});
});
it('should error if maxAge is specified but there is no iat claim', function (done) {
var clockTimestamp = 1437018582;
var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.0MBPd4Bru9-fK_HY3xmuDAc6N_embknmNuhdb9bKL_U';
var options = {algorithms: ['HS256'], clockTimestamp: clockTimestamp, maxAge: '1s'};
jwt.verify(token, key, options, function (err, p) {
assert.equal(err.name, 'JsonWebTokenError');
assert.equal(err.message, 'iat required when maxAge is specified');
assert.isUndefined(p);
done();
});
});
});
});
});

@@ -37,2 +37,8 @@ var JsonWebTokenError = require('./lib/JsonWebTokenError');

if (options.clockTimestamp && typeof options.clockTimestamp !== 'number') {
return done(new JsonWebTokenError('clockTimestamp must be a number'));
}
var clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000);
if (!jwtString){

@@ -42,2 +48,6 @@ return done(new JsonWebTokenError('jwt must be provided'));

if (typeof jwtString !== 'string') {
return done(new JsonWebTokenError('jwt must be a string'));
}
var parts = jwtString.split('.');

@@ -77,3 +87,3 @@

} catch(err) {
return done(new JsonWebTokenError('invalid token'));
return done(err);
}

@@ -114,3 +124,3 @@

}
if (payload.nbf > Math.floor(Date.now() / 1000) + (options.clockTolerance || 0)) {
if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) {
return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));

@@ -124,3 +134,3 @@ }

}
if (Math.floor(Date.now() / 1000) >= payload.exp + (options.clockTolerance || 0)) {
if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) {
return done(new TokenExpiredError('jwt expired', new Date(payload.exp * 1000)));

@@ -167,3 +177,6 @@ }

}
if (Date.now() - (payload.iat * 1000) > maxAge + (options.clockTolerance || 0) * 1000) {
// We have to compare against either options.clockTimestamp or the currentDate _with_ millis
// to not change behaviour (version 7.2.1). Should be resolve somehow for next major.
var nowOrClockTimestamp = ((options.clockTimestamp || 0) * 1000) || Date.now();
if (nowOrClockTimestamp - (payload.iat * 1000) > maxAge + (options.clockTolerance || 0) * 1000) {
return done(new TokenExpiredError('maxAge exceeded', new Date(payload.iat * 1000 + maxAge)));

@@ -170,0 +183,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc