From 399fee90c3a7ac386eb033e8e8a63b7e882fbdce Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sat, 24 Dec 2016 12:30:08 -0800 Subject: [PATCH 1/7] export Parser and test --- index.js | 4 ++++ test/parser.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 test/parser.js diff --git a/index.js b/index.js index 87246ea..21f802d 100644 --- a/index.js +++ b/index.js @@ -258,6 +258,9 @@ Jwt.prototype.isNotBefore = function() { }; function Parser(options){ + if(!(this instanceof Parser)){ + return new Parser(options); + } return this; } @@ -402,6 +405,7 @@ var jwtLib = { Jwt: Jwt, JwtBody: JwtBody, JwtHeader: JwtHeader, + Parser: Parser, Verifier: Verifier, base64urlEncode: base64urlEncode, base64urlUnescape:base64urlUnescape, diff --git a/test/parser.js b/test/parser.js new file mode 100644 index 0000000..b20b1c4 --- /dev/null +++ b/test/parser.js @@ -0,0 +1,29 @@ +var assert = require('chai').assert; +var uuid = require('uuid'); +var nJwt = require('../'); + + +describe('Parser', function () { + it('should construct itself if called without new', function () { + assert(nJwt.Parser() instanceof nJwt.Parser); + }); +}); +describe('Parser.parse()', function () { + var result = null + var claims = {hello: 'world'} + before(function(done){ + var token = new nJwt.Jwt(claims, false) + .setSigningAlgorithm('none') + .compact(); + var parser = nJwt.Parser(); + parser.parse(token, function(err,res){ + result = [err,res]; + done(); + }); + }); + it('should parse a valid token', function () { + assert.isNull(result[0], 'An error was not returned'); + assert.equal(result[1].body.hello,claims.hello); + }); + +}); \ No newline at end of file From a73fc3abd031f6120caac20c853c6e14ecab89cd Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sat, 24 Dec 2016 13:35:58 -0800 Subject: [PATCH 2/7] allow Verifier.verify to accept a Jwt as a parameter to bypass parsing --- index.js | 14 +++++++++----- test/parser.js | 30 ++++++++++++++++++++++-------- test/verifier.js | 23 +++++++++++++++++++++++ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 21f802d..776d610 100644 --- a/index.js +++ b/index.js @@ -331,12 +331,16 @@ Verifier.prototype.verify = function verify(jwtString,cb){ var done = handleError.bind(null,cb); - try { - jwt = new Parser().parse(jwtString); - } catch(e) { - return done(e); + if (jwtString instanceof Jwt) { + jwt = jwtString; + // console.log(jwt) + } else { + try { + jwt = new Parser().parse(jwtString); + } catch(e) { + return done(e); + } } - var body = jwt.body; var header = jwt.header; var signature = jwt.signature; diff --git a/test/parser.js b/test/parser.js index b20b1c4..c1628ee 100644 --- a/test/parser.js +++ b/test/parser.js @@ -8,22 +8,36 @@ describe('Parser', function () { assert(nJwt.Parser() instanceof nJwt.Parser); }); }); -describe('Parser.parse()', function () { + +describe('Parser.parse(token)', function () { + var result = null + var claims = { hello: 'world' } + var token = new nJwt.Jwt(claims, false) + .setSigningAlgorithm('none') + .compact(); + it('should parse a valid token', function () { + var jwt = new nJwt.Parser().parse(token); + assert.equal(jwt.body.hello, claims.hello); + }); + +}); + +describe('Parser.parse(token, cb)', function () { var result = null - var claims = {hello: 'world'} - before(function(done){ + var claims = { hello: 'world' } + before(function (done) { var token = new nJwt.Jwt(claims, false) .setSigningAlgorithm('none') .compact(); var parser = nJwt.Parser(); - parser.parse(token, function(err,res){ - result = [err,res]; - done(); + parser.parse(token, function (err, res) { + result = [err, res]; + done(); }); }); it('should parse a valid token', function () { - assert.isNull(result[0], 'An error was not returned'); - assert.equal(result[1].body.hello,claims.hello); + assert.isNull(result[0], 'An error was not returned'); + assert.equal(result[1].body.hello, claims.hello); }); }); \ No newline at end of file diff --git a/test/verifier.js b/test/verifier.js index de3fd01..4c15c9f 100644 --- a/test/verifier.js +++ b/test/verifier.js @@ -328,4 +328,27 @@ describe('Verifier().verify() ',function(){ assert.equal(result[0].userMessage,properties.errors.SIGNATURE_MISMTACH); }); }); + + describe('verify and existing Jwt object', function () { + var result = null + var claims = { hello: 'world' } + + before(function(done){ + var token = new nJwt.Jwt(claims, false) + .setSigningAlgorithm('none') + .compact(); + var jwt = new nJwt.Parser().parse(token); + var verifier = new nJwt.Verifier() + .setSigningAlgorithm('none') + verifier.verify(jwt, function(err,res){ + result = [err,res]; + done(); + }); + }); + it('should accept a valid Jwt as first param', function () { + assert.equal(result[1].body.hello, claims.hello); + }); + + }); + }); From efbaab32549554adffddd4cd5d6bdb5b781bcfb4 Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sat, 24 Dec 2016 15:28:28 -0800 Subject: [PATCH 3/7] add setter for keyid and test --- index.js | 5 +++++ test/jwt.js | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/index.js b/index.js index 776d610..1f911d7 100644 --- a/index.js +++ b/index.js @@ -192,6 +192,11 @@ Jwt.prototype.setSigningKey = function setSigningKey(key) { this.signingKey = key; return this; }; +Jwt.prototype.setSigningKeyId = function setSigningKeyId(keyid) { + this.header.keyid = keyid; + return this; +}; + Jwt.prototype.setSigningAlgorithm = function setSigningAlgorithm(alg) { if(!this.isSupportedAlg(alg)){ throw new JwtError(properties.errors.UNSUPPORTED_SIGNING_ALG); diff --git a/test/jwt.js b/test/jwt.js index cecbfb5..5b07b73 100644 --- a/test/jwt.js +++ b/test/jwt.js @@ -83,6 +83,15 @@ describe('Jwt',function() { }); }); + describe('.setSigningKeyId()',function(){ + it('should accept a keyid key',function(){ + var keyid = '1234' + var jwt = new nJwt.Jwt({}, false) + .setSigningKeyId(keyid); + assert.equal(jwt.header.keyid, keyid); + }); + }); + describe('.sign()',function(){ it('should throw if you give it an unknown algoritm',function(){ assert.throws(function(){ From a53b1d608495f1b97492c138b308206b0c4411ab Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sat, 24 Dec 2016 17:06:35 -0800 Subject: [PATCH 4/7] added test and example in README for using a keyid for a lookup --- README.md | 33 ++++++++++++++++++++- test/key-lookup.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++ test/verifier.js | 2 +- 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 test/key-lookup.js diff --git a/README.md b/README.md index 052980e..dd87aa6 100644 --- a/README.md +++ b/README.md @@ -234,9 +234,40 @@ ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm none | No digital signature or MAC value included +## Key Lookup + +```javascript + var claims = {hello: 'world'} + + var keys = [ + {keyid: 'key1', secret: '12345'}, + {keyid: 'key2',secret: 'abcd'} + ]; + var currentKey = 0 + + // create a token + var token = new nJwt.Jwt(claims) + .setSigningAlgorithm('HS256') + .setSigningKey(keys[currentKey].secret) + .setSigningKeyId(keys[currentKey].keyid) + .compact(); + + // Parse the tokent + var jwt = new nJwt.Parser().parse(token); + // lookup the key + var found = keys.find(k => k.keyid === jwt.header.keyid) + // then verify + var verifier = new nJwt.Verifier() + .setSigningAlgorithm('HS256') + .setSigningKey(found.secret) + .verify(token, function (err, res) { + if (res.body.hello !== claims.hello) + throw(new Error('lookup didnt work')) + }); +``` + ## Unsupported features The following features are not yet supported by this library: * Encrypting the JWT (aka JWE) -* Signing key resolver (using the `kid` field) diff --git a/test/key-lookup.js b/test/key-lookup.js new file mode 100644 index 0000000..95ad79a --- /dev/null +++ b/test/key-lookup.js @@ -0,0 +1,73 @@ +var assert = require('chai').assert; +var uuid = require('uuid'); +var nJwt = require('../'); + +describe('demonstrate a key lookup on verify', function () { + describe('and given an signed token', function () { + var result; + var claims = {hello: 'world'} + var keys = [ + {keyid: 'key1', secret: '12345'}, + {keyid: 'key2',secret: 'abcd'} + ]; + var currentKey = 0 + var expectedSecret = keys[currentKey].secret + + var token = new nJwt.Jwt(claims) + .setSigningAlgorithm('HS256') + .setSigningKey(expectedSecret) + .setSigningKeyId(keys[currentKey].keyid) + .compact(); + + var jwt = new nJwt.Parser().parse(token); + var found = keys.find(k => k.keyid === jwt.header.keyid) + + assert.equal(found.secret, expectedSecret); + + before(function (done) { + var verifier = new nJwt.Verifier() + .setSigningAlgorithm('HS256') + .setSigningKey(found.secret) + verifier.verify(token, function (err, res) { + result = [err, res]; + done(); + }); + }); + + it('the jwt should be equal', function () { + assert.equal(result[1].body.hello, claims.hello); + }); + }); + + + describe('demo key lookup', function () { + var claims = {hello: 'world'} + + var keys = [ + {keyid: 'key1', secret: '12345'}, + {keyid: 'key2',secret: 'abcd'} + ]; + var currentKey = 0 + + // create a token + var token = new nJwt.Jwt(claims) + .setSigningAlgorithm('HS256') + .setSigningKey(keys[currentKey].secret) + .setSigningKeyId(keys[currentKey].keyid) + .compact(); + + // Parse the tokent + var jwt = new nJwt.Parser().parse(token); + // lookup the key + var found = keys.find(k => k.keyid === jwt.header.keyid) + // then verify + var verifier = new nJwt.Verifier() + .setSigningAlgorithm('HS256') + .setSigningKey(found.secret) + .verify(token, function (err, res) { + if (res.body.hello !== claims.hello) + throw(new Error('lookup didnt work')) + }); + }); + +}); \ No newline at end of file diff --git a/test/verifier.js b/test/verifier.js index 4c15c9f..6b2f801 100644 --- a/test/verifier.js +++ b/test/verifier.js @@ -329,7 +329,7 @@ describe('Verifier().verify() ',function(){ }); }); - describe('verify and existing Jwt object', function () { + describe('verify an existing Jwt object', function () { var result = null var claims = { hello: 'world' } From cdeaa68543c3d6635dfbfd37157122740ca23d33 Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sat, 24 Dec 2016 17:23:13 -0800 Subject: [PATCH 5/7] Per RFC changed from keyid to kid --- README.md | 8 ++++---- index.js | 4 ++-- test/jwt.js | 8 ++++---- test/key-lookup.js | 16 ++++++++-------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index dd87aa6..c75829b 100644 --- a/README.md +++ b/README.md @@ -240,8 +240,8 @@ none | No digital signature or MAC value included var claims = {hello: 'world'} var keys = [ - {keyid: 'key1', secret: '12345'}, - {keyid: 'key2',secret: 'abcd'} + {kid: 'key1', secret: '12345'}, + {kid: 'key2',secret: 'abcd'} ]; var currentKey = 0 @@ -249,13 +249,13 @@ none | No digital signature or MAC value included var token = new nJwt.Jwt(claims) .setSigningAlgorithm('HS256') .setSigningKey(keys[currentKey].secret) - .setSigningKeyId(keys[currentKey].keyid) + .setSigningkid(keys[currentKey].kid) .compact(); // Parse the tokent var jwt = new nJwt.Parser().parse(token); // lookup the key - var found = keys.find(k => k.keyid === jwt.header.keyid) + var found = keys.find(k => k.kid === jwt.header.kid) // then verify var verifier = new nJwt.Verifier() .setSigningAlgorithm('HS256') diff --git a/index.js b/index.js index 1f911d7..1f62c26 100644 --- a/index.js +++ b/index.js @@ -192,8 +192,8 @@ Jwt.prototype.setSigningKey = function setSigningKey(key) { this.signingKey = key; return this; }; -Jwt.prototype.setSigningKeyId = function setSigningKeyId(keyid) { - this.header.keyid = keyid; +Jwt.prototype.setSigningKeyId = function setSigningKeyId(kid) { + this.header.kid = kid; return this; }; diff --git a/test/jwt.js b/test/jwt.js index 5b07b73..8a952c0 100644 --- a/test/jwt.js +++ b/test/jwt.js @@ -84,11 +84,11 @@ describe('Jwt',function() { }); describe('.setSigningKeyId()',function(){ - it('should accept a keyid key',function(){ - var keyid = '1234' + it('should accept a kid',function(){ + var kid = '1234' var jwt = new nJwt.Jwt({}, false) - .setSigningKeyId(keyid); - assert.equal(jwt.header.keyid, keyid); + .setSigningKeyId(kid); + assert.equal(jwt.header.kid, kid); }); }); diff --git a/test/key-lookup.js b/test/key-lookup.js index 95ad79a..9732be7 100644 --- a/test/key-lookup.js +++ b/test/key-lookup.js @@ -7,8 +7,8 @@ describe('demonstrate a key lookup on verify', function () { var result; var claims = {hello: 'world'} var keys = [ - {keyid: 'key1', secret: '12345'}, - {keyid: 'key2',secret: 'abcd'} + {kid: 'key1', secret: '12345'}, + {kid: 'key2',secret: 'abcd'} ]; var currentKey = 0 var expectedSecret = keys[currentKey].secret @@ -16,11 +16,11 @@ describe('demonstrate a key lookup on verify', function () { var token = new nJwt.Jwt(claims) .setSigningAlgorithm('HS256') .setSigningKey(expectedSecret) - .setSigningKeyId(keys[currentKey].keyid) + .setSigningKeyId(keys[currentKey].kid) .compact(); var jwt = new nJwt.Parser().parse(token); - var found = keys.find(k => k.keyid === jwt.header.keyid) + var found = keys.find(k => k.kid === jwt.header.kid) assert.equal(found.secret, expectedSecret); @@ -44,8 +44,8 @@ describe('demonstrate a key lookup on verify', function () { var claims = {hello: 'world'} var keys = [ - {keyid: 'key1', secret: '12345'}, - {keyid: 'key2',secret: 'abcd'} + {kid: 'key1', secret: '12345'}, + {kid: 'key2',secret: 'abcd'} ]; var currentKey = 0 @@ -53,13 +53,13 @@ describe('demonstrate a key lookup on verify', function () { var token = new nJwt.Jwt(claims) .setSigningAlgorithm('HS256') .setSigningKey(keys[currentKey].secret) - .setSigningKeyId(keys[currentKey].keyid) + .setSigningKeyId(keys[currentKey].kid) .compact(); // Parse the tokent var jwt = new nJwt.Parser().parse(token); // lookup the key - var found = keys.find(k => k.keyid === jwt.header.keyid) + var found = keys.find(k => k.kid === jwt.header.kid) // then verify var verifier = new nJwt.Verifier() .setSigningAlgorithm('HS256') From 30de4008960838f511e8490226cd4812c9ca5391 Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sun, 25 Dec 2016 05:18:49 -0800 Subject: [PATCH 6/7] added comment and trigger travis --- test/key-lookup.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/key-lookup.js b/test/key-lookup.js index 9732be7..4b2fefa 100644 --- a/test/key-lookup.js +++ b/test/key-lookup.js @@ -49,6 +49,7 @@ describe('demonstrate a key lookup on verify', function () { ]; var currentKey = 0 + // ENCODE // create a token var token = new nJwt.Jwt(claims) .setSigningAlgorithm('HS256') @@ -56,6 +57,7 @@ describe('demonstrate a key lookup on verify', function () { .setSigningKeyId(keys[currentKey].kid) .compact(); + // DECODE // Parse the tokent var jwt = new nJwt.Parser().parse(token); // lookup the key From b41cb5d1827e12efae84c70ab97200363de923b6 Mon Sep 17 00:00:00 2001 From: jkevlin Date: Sun, 25 Dec 2016 05:33:59 -0800 Subject: [PATCH 7/7] fixed typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c75829b..cc41192 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ none | No digital signature or MAC value included var token = new nJwt.Jwt(claims) .setSigningAlgorithm('HS256') .setSigningKey(keys[currentKey].secret) - .setSigningkid(keys[currentKey].kid) + .setSigningKeyId(keys[currentKey].kid) .compact(); // Parse the tokent