From e5721b3a2198d5ecf0102a40099cea02bcdf5036 Mon Sep 17 00:00:00 2001 From: Tim Oram Date: Tue, 23 Oct 2018 00:09:29 -0230 Subject: [PATCH] Refactor tests related to jti and jwtid This change extracts all tests related to the jti claim and the jwtid option into a single test file. Additional tests were added that were missing. --- test/claim-jti.test.js | 155 +++++++++++++++++++++++++++ test/jwt.asymmetric_signing.tests.js | 36 ------- 2 files changed, 155 insertions(+), 36 deletions(-) create mode 100644 test/claim-jti.test.js diff --git a/test/claim-jti.test.js b/test/claim-jti.test.js new file mode 100644 index 0000000..a10a9b5 --- /dev/null +++ b/test/claim-jti.test.js @@ -0,0 +1,155 @@ +'use strict'; + +const jwt = require('../'); +const expect = require('chai').expect; +const util = require('util'); +const testUtils = require('./test-utils'); + +function signWithJWTId(jwtid, payload, callback) { + const options = {algorithm: 'none'}; + if (jwtid !== undefined) { + options.jwtid = jwtid; + } + testUtils.signJWTHelper(payload, 'secret', options, callback); +} + +describe('jwtid', function() { + describe('`jwt.sign` "jwtid" option validation', function () { + [ + true, + false, + null, + -1, + 0, + 1, + -1.1, + 1.1, + -Infinity, + Infinity, + NaN, + [], + ['foo'], + {}, + {foo: 'bar'}, + ].forEach((jwtid) => { + it(`should error with with value ${util.inspect(jwtid)}`, function (done) { + signWithJWTId(jwtid, {}, (err) => { + testUtils.asyncCheck(done, () => { + expect(err).to.be.instanceOf(Error); + expect(err).to.have.property('message', '"jwtid" must be a string'); + }); + }); + }); + }); + + // undefined needs special treatment because {} is not the same as {jwtid: undefined} + it('should error with with value undefined', function (done) { + testUtils.signJWTHelper({}, undefined, {jwtid: undefined, algorithm: 'none'}, (err) => { + testUtils.asyncCheck(done, () => { + expect(err).to.be.instanceOf(Error); + expect(err).to.have.property('message', '"jwtid" must be a string'); + }); + }); + }); + + it('should error when "jti" is in payload', function (done) { + signWithJWTId('foo', {jti: 'bar'}, (err) => { + testUtils.asyncCheck(done, () => { + expect(err).to.be.instanceOf(Error); + expect(err).to.have.property( + 'message', + 'Bad "options.jwtid" option. The payload already has an "jti" property.' + ); + }); + }); + }); + + it('should error with a string payload', function (done) { + signWithJWTId('foo', 'a string payload', (err) => { + testUtils.asyncCheck(done, () => { + expect(err).to.be.instanceOf(Error); + expect(err).to.have.property( + 'message', + 'invalid jwtid option for string payload' + ); + }); + }); + }); + + it('should error with a Buffer payload', function (done) { + signWithJWTId('foo', new Buffer('a Buffer payload'), (err) => { + testUtils.asyncCheck(done, () => { + expect(err).to.be.instanceOf(Error); + expect(err).to.have.property( + 'message', + 'invalid jwtid option for object payload' + ); + }); + }); + }); + }); + + describe('when signing and verifying a token', function () { + it('should not verify "jti" if verify "jwtid" option not provided', function(done) { + signWithJWTId(undefined, {jti: 'foo'}, (e1, token) => { + testUtils.verifyJWTHelper(token, undefined, {}, (e2, decoded) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.null; + expect(decoded).to.have.property('jti', 'foo'); + }); + }) + }); + }); + + describe('with "jwtid" option', function () { + it('should verify with "jwtid" option', function (done) { + signWithJWTId('foo', {}, (e1, token) => { + testUtils.verifyJWTHelper(token, undefined, {jwtid: 'foo'}, (e2, decoded) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.null; + expect(decoded).to.have.property('jti', 'foo'); + }); + }) + }); + }); + + it('should verify with "jti" in payload', function (done) { + signWithJWTId(undefined, {jti: 'foo'}, (e1, token) => { + testUtils.verifyJWTHelper(token, undefined, {jetid: 'foo'}, (e2, decoded) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.null; + expect(decoded).to.have.property('jti', 'foo'); + }); + }) + }); + }); + + it('should error if "jti" does not match verify "jwtid" option', function(done) { + signWithJWTId(undefined, {jti: 'bar'}, (e1, token) => { + testUtils.verifyJWTHelper(token, undefined, {jwtid: 'foo'}, (e2) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.instanceOf(jwt.JsonWebTokenError); + expect(e2).to.have.property('message', 'jwt jwtid invalid. expected: foo'); + }); + }) + }); + }); + + it('should error without "jti" and with verify "jwtid" option', function(done) { + signWithJWTId(undefined, {}, (e1, token) => { + testUtils.verifyJWTHelper(token, undefined, {jwtid: 'foo'}, (e2) => { + testUtils.asyncCheck(done, () => { + expect(e1).to.be.null; + expect(e2).to.be.instanceOf(jwt.JsonWebTokenError); + expect(e2).to.have.property('message', 'jwt jwtid invalid. expected: foo'); + }); + }) + }); + }); + }); + }); +}); diff --git a/test/jwt.asymmetric_signing.tests.js b/test/jwt.asymmetric_signing.tests.js index dd6f27e..49b9ed0 100644 --- a/test/jwt.asymmetric_signing.tests.js +++ b/test/jwt.asymmetric_signing.tests.js @@ -113,42 +113,6 @@ describe('Asymmetric Algorithms', function(){ }); }); - describe('when signing a token with jwt id', function () { - var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, jwtid: 'jwtid' }); - - it('should check jwt id', function (done) { - jwt.verify(token, pub, { jwtid: 'jwtid' }, function (err, decoded) { - assert.isNotNull(decoded); - assert.isNull(err); - done(); - }); - }); - - it('should throw when invalid jwt id', function (done) { - jwt.verify(token, pub, { jwtid: 'wrongJwtid' }, function (err, decoded) { - assert.isUndefined(decoded); - assert.isNotNull(err); - assert.equal(err.name, 'JsonWebTokenError'); - assert.instanceOf(err, jwt.JsonWebTokenError); - done(); - }); - }); - }); - - describe('when signing a token without jwt id', function () { - var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm }); - - it('should check jwt id', function (done) { - jwt.verify(token, pub, { jwtid: 'jwtid' }, function (err, decoded) { - assert.isUndefined(decoded); - assert.isNotNull(err); - assert.equal(err.name, 'JsonWebTokenError'); - assert.instanceOf(err, jwt.JsonWebTokenError); - done(); - }); - }); - }); - describe('when verifying a malformed token', function () { it('should throw', function (done) { jwt.verify('fruit.fruit.fruit', pub, function (err, decoded) {