mirror of
https://github.com/hanzoai/node-jsonwebtoken.git
synced 2026-09-24 17:00:48 +00:00
Merge pull request #360 from ziluvatar/add-ecdsa-tests
Add tests for ES256
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
MIH3AgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP//////////
|
||||
/////zBbBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6
|
||||
k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsDFQDEnTYIhucEk2pmeOETnSa3gZ9+
|
||||
kARBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLeszoPShOUXYmMKWT+NC4v4af5uO5+tK
|
||||
fA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////AAAAAP//////////vOb6racXnoTz
|
||||
ucrC/GMlUQIBAQ==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIIBaAIBAQQgeg2m9tJJsnURyjTUihohiJahj9ETy3csUIt4EYrV+J2ggfowgfcC
|
||||
AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////
|
||||
MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr
|
||||
vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE
|
||||
axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W
|
||||
K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8
|
||||
YyVRAgEBoUQDQgAEEWluurrkZECnq27UpNauq16f9+5DDMFJZ3HV43Ujc3tcXQ++
|
||||
N1T/0CAA8ve286f32s7rkqX/pPokI/HBpP5p3g==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA
|
||||
AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA////
|
||||
///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd
|
||||
NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5
|
||||
RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA
|
||||
//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABEfZiYJDbghTGQ+KGnHGSl6K
|
||||
yUqK/BL2uJIg7Z0bx48v6+L7Ve8MCS17eptkMT2e4l5B/ZGDVUHb6uZ5xFROLBw=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGjCCAsKgAwIBAgIJANuPNBWwp6wzMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
|
||||
QVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdp
|
||||
dHMgUHR5IEx0ZDAeFw0xNzA2MTAxMTAzMjJaFw0yNzA2MDgxMTAzMjJaMEUxCzAJ
|
||||
BgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5l
|
||||
dCBXaWRnaXRzIFB0eSBMdGQwggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjO
|
||||
PQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAA
|
||||
AAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQaw
|
||||
zFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i8
|
||||
5uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2
|
||||
QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAE
|
||||
EWluurrkZECnq27UpNauq16f9+5DDMFJZ3HV43Ujc3tcXQ++N1T/0CAA8ve286f3
|
||||
2s7rkqX/pPokI/HBpP5p3qOBpzCBpDAdBgNVHQ4EFgQUAF43lnAvCztZZGaGMoxs
|
||||
cp6tpz8wdQYDVR0jBG4wbIAUAF43lnAvCztZZGaGMoxscp6tpz+hSaRHMEUxCzAJ
|
||||
BgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5l
|
||||
dCBXaWRnaXRzIFB0eSBMdGSCCQDbjzQVsKesMzAMBgNVHRMEBTADAQH/MAkGByqG
|
||||
SM49BAEDRwAwRAIgV039oh2RtcSwywQ/0dWAwc20NHxrgmKoQ5A3AS5A9d0CIBCV
|
||||
2AlKDFjmDC7zjldNhWbMcIlSSj71ghhhxeS0F8v1
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA
|
||||
AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA////
|
||||
///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd
|
||||
NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5
|
||||
RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA
|
||||
//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABBFpbrq65GRAp6tu1KTWrqte
|
||||
n/fuQwzBSWdx1eN1I3N7XF0PvjdU/9AgAPL3tvOn99rO65Kl/6T6JCPxwaT+ad4=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,449 @@
|
||||
var jwt = require('../index');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var assert = require('chai').assert;
|
||||
var ms = require('ms');
|
||||
|
||||
function loadKey(filename) {
|
||||
return fs.readFileSync(path.join(__dirname, filename));
|
||||
}
|
||||
|
||||
var algorithms = {
|
||||
RS256: {
|
||||
pub_key: loadKey('pub.pem'),
|
||||
priv_key: loadKey('priv.pem'),
|
||||
invalid_pub_key: loadKey('invalid_pub.pem')
|
||||
},
|
||||
ES256: {
|
||||
// openssl ecparam -name secp256r1 -genkey -param_enc explicit -out ecdsa-private.pem
|
||||
priv_key: loadKey('ecdsa-private.pem'),
|
||||
// openssl ec -in ecdsa-private.pem -pubout -out ecdsa-public.pem
|
||||
pub_key: loadKey('ecdsa-public.pem'),
|
||||
invalid_pub_key: loadKey('ecdsa-public-invalid.pem')
|
||||
}
|
||||
};
|
||||
|
||||
describe('Asymmetric Algorithms', function(){
|
||||
|
||||
Object.keys(algorithms).forEach(function (algorithm) {
|
||||
describe(algorithm, function () {
|
||||
var pub = algorithms[algorithm].pub_key;
|
||||
var priv = algorithms[algorithm].priv_key;
|
||||
|
||||
// "invalid" means it is not the public key for the loaded "priv" key
|
||||
var invalid_pub = algorithms[algorithm].invalid_pub_key;
|
||||
|
||||
describe('when signing a token', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm });
|
||||
|
||||
it('should be syntactically valid', function () {
|
||||
expect(token).to.be.a('string');
|
||||
expect(token.split('.')).to.have.length(3);
|
||||
});
|
||||
|
||||
context('asynchronous', function () {
|
||||
it('should validate with public key', function (done) {
|
||||
jwt.verify(token, pub, function (err, decoded) {
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw with invalid public key', function (done) {
|
||||
jwt.verify(token, invalid_pub, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('synchronous', function () {
|
||||
it('should validate with public key', function () {
|
||||
var decoded = jwt.verify(token, pub);
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
});
|
||||
|
||||
it('should throw with invalid public key', function () {
|
||||
var jwtVerify = jwt.verify.bind(null, token, invalid_pub)
|
||||
assert.throw(jwtVerify, 'invalid signature');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when signing a token with expiration', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, expiresIn: '10m' });
|
||||
|
||||
it('should be valid expiration', function (done) {
|
||||
jwt.verify(token, pub, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be invalid', function (done) {
|
||||
// expired token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, expiresIn: -1 * ms('10m') });
|
||||
|
||||
jwt.verify(token, pub, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'TokenExpiredError');
|
||||
assert.instanceOf(err.expiredAt, Date);
|
||||
assert.instanceOf(err, jwt.TokenExpiredError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT be invalid', function (done) {
|
||||
// expired token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, expiresIn: -1 * ms('10m') });
|
||||
|
||||
jwt.verify(token, pub, { ignoreExpiration: true }, function (err, decoded) {
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when signing a token with not before', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, notBefore: -10 * 3600 });
|
||||
|
||||
it('should be valid expiration', function (done) {
|
||||
jwt.verify(token, pub, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be invalid', function (done) {
|
||||
// not active token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, notBefore: '10m' });
|
||||
|
||||
jwt.verify(token, pub, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'NotBeforeError');
|
||||
assert.instanceOf(err.date, Date);
|
||||
assert.instanceOf(err, jwt.NotBeforeError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should valid when date are equals', function (done) {
|
||||
Date.fix(1451908031);
|
||||
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, notBefore: 0 });
|
||||
|
||||
jwt.verify(token, pub, function (err, decoded) {
|
||||
assert.isNull(err);
|
||||
assert.isNotNull(decoded);
|
||||
Date.unfix();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT be invalid', function (done) {
|
||||
// not active token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, notBefore: '10m' });
|
||||
|
||||
jwt.verify(token, pub, { ignoreNotBefore: true }, function (err, decoded) {
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when signing a token with audience', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, audience: 'urn:foo' });
|
||||
|
||||
it('should check audience', function (done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:foo' }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check audience in array', function (done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:foo', 'urn:other'] }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience', function (done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:wrong' }, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.instanceOf(err, jwt.JsonWebTokenError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience in array', function (done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:wrong', 'urn:morewrong'] }, 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 with array audience', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, audience: ['urn:foo', 'urn:bar'] });
|
||||
|
||||
it('should check audience', function (done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:foo' }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check other audience', function (done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:bar' }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check audience in array', function (done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:foo', 'urn:other'] }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience', function (done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:wrong' }, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.instanceOf(err, jwt.JsonWebTokenError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience in array', function (done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:wrong', 'urn:morewrong'] }, 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 audience', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm });
|
||||
|
||||
it('should check audience', function (done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:wrong' }, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.instanceOf(err, jwt.JsonWebTokenError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check audience in array', function (done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:wrong', 'urn:morewrong'] }, 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 with issuer', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, issuer: 'urn:foo' });
|
||||
|
||||
it('should check issuer', function (done) {
|
||||
jwt.verify(token, pub, { issuer: 'urn:foo' }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check the issuer when providing a list of valid issuers', function (done) {
|
||||
jwt.verify(token, pub, { issuer: ['urn:foo', 'urn:bar'] }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid issuer', function (done) {
|
||||
jwt.verify(token, pub, { issuer: 'urn:wrong' }, 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 issuer', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm });
|
||||
|
||||
it('should check issuer', function (done) {
|
||||
jwt.verify(token, pub, { issuer: 'urn:foo' }, 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 with subject', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm, subject: 'subject' });
|
||||
|
||||
it('should check subject', function (done) {
|
||||
jwt.verify(token, pub, { subject: 'subject' }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid subject', function (done) {
|
||||
jwt.verify(token, pub, { subject: 'wrongSubject' }, 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 subject', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm });
|
||||
|
||||
it('should check subject', function (done) {
|
||||
jwt.verify(token, pub, { subject: 'subject' }, 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 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) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when decoding a jwt token with additional parts', function () {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: algorithm });
|
||||
|
||||
it('should throw', function (done) {
|
||||
jwt.verify(token + '.foo', pub, function (err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when decoding a invalid jwt token', function () {
|
||||
it('should return null', function (done) {
|
||||
var payload = jwt.decode('whatever.token');
|
||||
assert.isNull(payload);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when decoding a valid jwt token', function () {
|
||||
it('should return the payload', function (done) {
|
||||
var obj = { foo: 'bar' };
|
||||
var token = jwt.sign(obj, priv, { algorithm: algorithm });
|
||||
var payload = jwt.decode(token);
|
||||
assert.equal(payload.foo, obj.foo);
|
||||
done();
|
||||
});
|
||||
it('should return the header and payload and signature if complete option is set', function (done) {
|
||||
var obj = { foo: 'bar' };
|
||||
var token = jwt.sign(obj, priv, { algorithm: algorithm });
|
||||
var decoded = jwt.decode(token, { complete: true });
|
||||
assert.equal(decoded.payload.foo, obj.foo);
|
||||
assert.deepEqual(decoded.header, { typ: 'JWT', alg: algorithm });
|
||||
assert.ok(typeof decoded.signature == 'string');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,423 +0,0 @@
|
||||
var jwt = require('../index');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var assert = require('chai').assert;
|
||||
var ms = require('ms');
|
||||
|
||||
describe('RS256', function() {
|
||||
var pub = fs.readFileSync(path.join(__dirname, 'pub.pem'));
|
||||
var priv = fs.readFileSync(path.join(__dirname, 'priv.pem'));
|
||||
var invalid_pub = fs.readFileSync(path.join(__dirname, 'invalid_pub.pem'));
|
||||
|
||||
describe('when signing a token', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256' });
|
||||
|
||||
it('should be syntactically valid', function() {
|
||||
expect(token).to.be.a('string');
|
||||
expect(token.split('.')).to.have.length(3);
|
||||
});
|
||||
|
||||
context('asynchronous', function() {
|
||||
it('should validate with public key', function(done) {
|
||||
jwt.verify(token, pub, function(err, decoded) {
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw with invalid public key', function(done) {
|
||||
jwt.verify(token, invalid_pub, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('synchronous', function() {
|
||||
it('should validate with public key', function() {
|
||||
var decoded = jwt.verify(token, pub);
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
});
|
||||
|
||||
it('should throw with invalid public key', function() {
|
||||
var jwtVerify = jwt.verify.bind(null, token, invalid_pub)
|
||||
assert.throw(jwtVerify, 'invalid signature');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when signing a token with expiration', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', expiresIn: '10m' });
|
||||
|
||||
it('should be valid expiration', function(done) {
|
||||
jwt.verify(token, pub, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be invalid', function(done) {
|
||||
// expired token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', expiresIn: -1 * ms('10m') });
|
||||
|
||||
jwt.verify(token, pub, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'TokenExpiredError');
|
||||
assert.instanceOf(err.expiredAt, Date);
|
||||
assert.instanceOf(err, jwt.TokenExpiredError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT be invalid', function(done) {
|
||||
// expired token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', expiresIn: -1 * ms('10m') });
|
||||
|
||||
jwt.verify(token, pub, { ignoreExpiration: true }, function(err, decoded) {
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when signing a token with not before', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBefore: -10 * 3600 });
|
||||
|
||||
it('should be valid expiration', function(done) {
|
||||
jwt.verify(token, pub, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be invalid', function(done) {
|
||||
// not active token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBefore: '10m' });
|
||||
|
||||
jwt.verify(token, pub, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'NotBeforeError');
|
||||
assert.instanceOf(err.date, Date);
|
||||
assert.instanceOf(err, jwt.NotBeforeError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should valid when date are equals', function(done) {
|
||||
Date.fix(1451908031);
|
||||
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBefore: 0 });
|
||||
|
||||
jwt.verify(token, pub, function(err, decoded) {
|
||||
assert.isNull(err);
|
||||
assert.isNotNull(decoded);
|
||||
Date.unfix();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT be invalid', function(done) {
|
||||
// not active token
|
||||
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBefore: '10m' });
|
||||
|
||||
jwt.verify(token, pub, { ignoreNotBefore: true }, function(err, decoded) {
|
||||
assert.ok(decoded.foo);
|
||||
assert.equal('bar', decoded.foo);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when signing a token with audience', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', audience: 'urn:foo' });
|
||||
|
||||
it('should check audience', function(done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:foo' }, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check audience in array', function(done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:foo', 'urn:other'] }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience', function(done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:wrong' }, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.instanceOf(err, jwt.JsonWebTokenError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience in array', function(done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:wrong', 'urn:morewrong'] }, 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 with array audience', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', audience: [ 'urn:foo', 'urn:bar' ] });
|
||||
|
||||
it('should check audience', function(done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:foo' }, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check other audience', function(done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:bar' }, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check audience in array', function(done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:foo', 'urn:other'] }, function (err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience', function(done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:wrong' }, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.instanceOf(err, jwt.JsonWebTokenError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid audience in array', function(done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:wrong', 'urn:morewrong'] }, 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 audience', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256' });
|
||||
|
||||
it('should check audience', function(done) {
|
||||
jwt.verify(token, pub, { audience: 'urn:wrong' }, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.instanceOf(err, jwt.JsonWebTokenError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check audience in array', function(done) {
|
||||
jwt.verify(token, pub, { audience: ['urn:wrong', 'urn:morewrong'] }, 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 with issuer', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', issuer: 'urn:foo' });
|
||||
|
||||
it('should check issuer', function(done) {
|
||||
jwt.verify(token, pub, { issuer: 'urn:foo' }, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check the issuer when providing a list of valid issuers', function(done) {
|
||||
jwt.verify(token, pub, { issuer: [ 'urn:foo', 'urn:bar' ] }, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid issuer', function(done) {
|
||||
jwt.verify(token, pub, { issuer: 'urn:wrong' }, 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 issuer', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256' });
|
||||
|
||||
it('should check issuer', function(done) {
|
||||
jwt.verify(token, pub, { issuer: 'urn:foo' }, 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 with subject', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', subject: 'subject' });
|
||||
|
||||
it('should check subject', function(done) {
|
||||
jwt.verify(token, pub, { subject: 'subject' }, function(err, decoded) {
|
||||
assert.isNotNull(decoded);
|
||||
assert.isNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid subject', function(done) {
|
||||
jwt.verify(token, pub, { subject: 'wrongSubject' }, 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 subject', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256' });
|
||||
|
||||
it('should check subject', function(done) {
|
||||
jwt.verify(token, pub, { subject: 'subject' }, 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 with jwt id', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', 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: 'RS256' });
|
||||
|
||||
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) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when decoding a jwt token with additional parts', function() {
|
||||
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256' });
|
||||
|
||||
it('should throw', function(done) {
|
||||
jwt.verify(token + '.foo', pub, function(err, decoded) {
|
||||
assert.isUndefined(decoded);
|
||||
assert.isNotNull(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when decoding a invalid jwt token', function() {
|
||||
it('should return null', function(done) {
|
||||
var payload = jwt.decode('whatever.token');
|
||||
assert.isNull(payload);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when decoding a valid jwt token', function() {
|
||||
it('should return the payload', function(done) {
|
||||
var obj = { foo: 'bar' };
|
||||
var token = jwt.sign(obj, priv, { algorithm: 'RS256' });
|
||||
var payload = jwt.decode(token);
|
||||
assert.equal(payload.foo, obj.foo);
|
||||
done();
|
||||
});
|
||||
it('should return the header and payload and signature if complete option is set', function(done) {
|
||||
var obj = { foo: 'bar' };
|
||||
var token = jwt.sign(obj, priv, { algorithm: 'RS256' });
|
||||
var decoded = jwt.decode(token, { complete: true });
|
||||
assert.equal(decoded.payload.foo, obj.foo);
|
||||
assert.deepEqual(decoded.header, { typ: 'JWT', alg: 'RS256' });
|
||||
assert.ok(typeof decoded.signature == 'string');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user