Files
passport-jwt/test/strategy-validation-test.js
Mike Nicholson d5af311dce Get rid of JWT as the default auth scheme.
Per #87 'jwt' was not a great choice of default value for the
authorization scheme since RFC6750 explicitly states that 'bearer'
is the proper scheme, at least in the context of OAuth 2.0.

Since this change breaks backwards compatibility I tried to be very
explicit.  extractors.fromAuthHeader() was removed and replaced with
the more explicit 'extractors.fromAuthHeaderAsBearerToken()'.

Anyone wanting to maintain passport-jwt 2.* behavior may use the
follinwg extractor instead of fromAuthHeader():

    extractors.fromAuthHeaderWithScheme('jwt')

The legacy (v 1.*) extractor, extractors.versionOneCompatibilit() still
iuses 'JWT' as the default auth scheme.

Fixes #87
2017-08-01 21:55:26 -04:00

183 lines
5.9 KiB
JavaScript

var Strategy = require('../lib/strategy')
, chai = require('chai')
, test_data = require('./testdata')
, sinon = require('sinon')
, extract_jwt = require('../lib/extract_jwt');
describe('Strategy', function() {
describe('calling JWT validation function', function() {
var strategy;
before(function(done) {
verifyStub = sinon.stub();
verifyStub.callsArgWith(1, null, {}, {});
options = {};
options.issuer = "TestIssuer";
options.audience = "TestAudience";
options.secretOrKey = 'secret';
options.algorithms = ["HS256", "HS384"];
options.ignoreExpiration = false;
options.jsonWebTokenOptions = {
clockTolerance: 10,
maxAge: "1h",
};
options.jwtFromRequest = extract_jwt.fromAuthHeaderAsBearerToken();
strategy = new Strategy(options, verifyStub);
Strategy.JwtVerifier = sinon.stub();
Strategy.JwtVerifier.callsArgWith(3, null, test_data.valid_jwt.payload);
chai.passport.use(strategy)
.success(function(u, i) {
done();
})
.req(function(req) {
req.headers['authorization'] = "bearer " + test_data.valid_jwt.token;
})
.authenticate();
});
it('should call with the right secret as an argument', function() {
expect(Strategy.JwtVerifier.args[0][1]).to.equal('secret');
});
it('should call with the right issuer option', function() {
expect(Strategy.JwtVerifier.args[0][2]).to.be.an.object;
expect(Strategy.JwtVerifier.args[0][2].issuer).to.equal('TestIssuer');
});
it('should call with the right audience option', function() {
expect(Strategy.JwtVerifier.args[0][2]).to.be.an.object;
expect(Strategy.JwtVerifier.args[0][2].audience).to.equal('TestAudience');
});
it('should call with the right algorithms option', function() {
expect(Strategy.JwtVerifier.args[0][2]).to.be.an.object;
expect(Strategy.JwtVerifier.args[0][2].algorithms).to.eql(["HS256", "HS384"]);
});
it('should call with the right ignoreExpiration option', function() {
expect(Strategy.JwtVerifier.args[0][2]).to.be.an.object;
expect(Strategy.JwtVerifier.args[0][2].ignoreExpiration).to.be.false;
});
it('should call with the right maxAge option', function() {
expect(Strategy.JwtVerifier.args[0][2]).to.be.an.object;
expect(Strategy.JwtVerifier.args[0][2].maxAge).to.equal('1h');
});
it('should call with the right clockTolerance option', function() {
expect(Strategy.JwtVerifier.args[0][2]).to.be.an.object;
expect(Strategy.JwtVerifier.args[0][2].clockTolerance).to.equal(10);
});
});
describe('handling valid jwt', function() {
var strategy, payload;
before(function(done) {
strategy = new Strategy({jwtFromRequest: extract_jwt.fromAuthHeaderAsBearerToken(), secretOrKey: 'secret'}, function(jwt_payload, next) {
payload = jwt_payload;
next(null, {}, {});
});
// Mock successful verification
Strategy.JwtVerifier = sinon.stub();
Strategy.JwtVerifier.callsArgWith(3, null, test_data.valid_jwt.payload);
chai.passport.use(strategy)
.success(function(u, i) {
done();
})
.req(function(req) {
req.headers['authorization'] = "bearer " + test_data.valid_jwt.token;
})
.authenticate();
});
it('should call verify with the correct payload', function() {
expect(payload).to.deep.equal(test_data.valid_jwt.payload);
});
});
describe('handling failing jwt', function() {
var strategy, info;
var verify_spy = sinon.spy();
before(function(done) {
strategy = new Strategy({jwtFromRequest: extract_jwt.fromAuthHeaderAsBearerToken(), secretOrKey: 'secret'}, verify_spy);
// Mock errored verification
Strategy.JwtVerifier = sinon.stub();
Strategy.JwtVerifier.callsArgWith(3, new Error("jwt expired"), false);
chai.passport.use(strategy)
.fail(function(i) {
info = i;
done();
})
.req(function(req) {
req.headers['authorization'] = "bearer " + test_data.valid_jwt.token;
})
.authenticate();
});
it('should not call verify', function() {
sinon.assert.notCalled(verify_spy);
});
it('should fail with error message.', function() {
expect(info).to.be.an.object;
expect(info.message).to.equal('jwt expired');
});
});
describe('handling an invalid authentication header', function() {
var strategy, info;
var verify_spy = sinon.spy();
before(function(done) {
strategy = new Strategy({jwtFromRequest: extract_jwt.fromAuthHeaderAsBearerToken(), secretOrKey: 'secret'}, verify_spy);
chai.passport.use(strategy)
.fail(function(i) {
info = i;
done();
})
.req(function(req) {
req.headers['authorization'] = "malformed";
})
.authenticate();
});
it('should not call verify', function() {
sinon.assert.notCalled(verify_spy);
});
it('should fail with error message.', function() {
expect(info).to.be.an.object;
expect(info).to.be.an.instanceof(Error);
});
});
});