diff --git a/index.js b/index.js index 61f68f6..d9064d8 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ const jwks = require('jwks-rsa') const jwt = require('jsonwebtoken') const { - applyTo: thrush, curryN, dissoc, partialRight, prop + applyTo: thrush, composeP, curryN, dissoc, partialRight, prop, replace } = require('ramda') const { promisify, rename, tapP } = require('@articulate/funky') @@ -27,7 +27,10 @@ const chooseKey = key => const decode = partialRight(jwt.decode, [{ complete: true }]) const enforce = token => - token || Promise.reject(new Error('null token not allowed')) + token || Promise.reject(Boom.unauthorized('null token not allowed')) + +const stripBearer = + replace(/^Bearer /i, '') const unauthorized = err => Promise.reject(Boom.wrap(err, 401)) @@ -54,7 +57,6 @@ const factory = opts => { const authentic = token => Promise.resolve(token) - .then(tapP(enforce)) .then(decode) .then(tapP(checkIss)) .then(getSigningKey) @@ -62,7 +64,7 @@ const factory = opts => { .then(verify(token)) .catch(unauthorized) - return authentic + return composeP(authentic, stripBearer, tapP(enforce)) } module.exports = factory diff --git a/test/index.js b/test/index.js index 608ef37..4510b6b 100644 --- a/test/index.js +++ b/test/index.js @@ -3,10 +3,12 @@ const jwt = require('jsonwebtoken') const nock = require('nock') const property = require('prop-factory') -const bad = require('./fixtures/bad-iss') -const keys = require('./fixtures/keys') -const oidc = require('./fixtures/oidc') -const token = require('./fixtures/token') +const bad = require('./fixtures/bad-iss') +const keys = require('./fixtures/keys') +const oidc = require('./fixtures/oidc') +const token = require('./fixtures/token') +const capitalBearerToken = 'Bearer ' + token +const lowerBearerToken = 'bearer ' + token const { issuer } = oidc @@ -47,6 +49,34 @@ describe('authentic', () => { ) }) + describe('with a valid jwt that starts with Bearer', () => { + beforeEach(() => + authentic(capitalBearerToken).then(res) + ) + + it('validates the jwt against the jwks', () => + expect(res().sub).to.equal('00udjyjssbt2S1QVr0h7') + ) + + it('caches the jwks client', () => + expect(res().sub).to.equal('00udjyjssbt2S1QVr0h7') + ) + }) + + describe('with a valid jwt that starts with bearer', () => { + beforeEach(() => + authentic(lowerBearerToken).then(res) + ) + + it('validates the jwt against the jwks', () => + expect(res().sub).to.equal('00udjyjssbt2S1QVr0h7') + ) + + it('caches the jwks client', () => + expect(res().sub).to.equal('00udjyjssbt2S1QVr0h7') + ) + }) + describe('with an invalid jwt', () => { beforeEach(() => authentic('invalid').catch(res)