diff --git a/test/claim-nbf.test.js b/test/claim-nbf.test.js index 72397de1..d4957241 100644 --- a/test/claim-nbf.test.js +++ b/test/claim-nbf.test.js @@ -273,6 +273,32 @@ describe('not before', function() { }); }); + it('should accept a fractional "nbf" that is already active within the current second', function (done) { + signWithNotBefore(undefined, {nbf: 60.111}, (e1, token) => { + fakeClock.tick(999); + testUtils.verifyJWTHelper(token, 'secret', {}, (e2, decoded) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.null; + expect(decoded).to.have.property('nbf', 60.111); + }); + }) + }); + }); + + it('should error on verify if a fractional "nbf" is after current time within the same second', function (done) { + signWithNotBefore(undefined, {nbf: 60.5}, (e1, token) => { + fakeClock.tick(200); + testUtils.verifyJWTHelper(token, 'secret', {}, (e2) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.instanceOf(jwt.NotBeforeError); + expect(e2).to.have.property('message', 'jwt not active'); + }); + }) + }); + }); + it('should verify "nbf" using "clockTimestamp"', function (done) { signWithNotBefore(10, {}, (e1, token) => { testUtils.verifyJWTHelper(token, 'secret', {clockTimestamp: 70}, (e2, decoded) => { diff --git a/verify.js b/verify.js index cdbfdc45..3d7417bc 100644 --- a/verify.js +++ b/verify.js @@ -54,7 +54,9 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) { return done(new JsonWebTokenError('allowInvalidAsymmetricKeyTypes must be a boolean')); } - const clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000); + const now = Date.now() / 1000; + const clockTimestamp = options.clockTimestamp || Math.floor(now); + const notBeforeTimestamp = options.clockTimestamp || now; if (!jwtString){ return done(new JsonWebTokenError('jwt must be provided')); @@ -177,7 +179,7 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) { if (typeof payload.nbf !== 'number') { return done(new JsonWebTokenError('invalid nbf value')); } - if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) { + if (payload.nbf > notBeforeTimestamp + (options.clockTolerance || 0)) { return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000))); } }