From 9a439e2bb83452dc0ee3e200262a50bd72485156 Mon Sep 17 00:00:00 2001 From: Eric Kryski Date: Wed, 23 Nov 2016 00:39:48 -0700 Subject: [PATCH 1/2] adding entity id to payload. Ensuring custom named strategies pull from auth config. Closes #2. --- src/index.js | 6 +++++- src/verifier.js | 6 ++++-- test/index.test.js | 27 ++++++++++++++++++++++++++- test/integration.test.js | 2 +- test/verifier.test.js | 10 +++++----- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index 4ce8540..ba449e4 100644 --- a/src/index.js +++ b/src/index.js @@ -30,8 +30,11 @@ export default function init (options = {}) { throw new Error(`Can not find app.passport. Did you initialize feathers-authentication before feathers-authentication-jwt?`); } + let authOptions = app.get('auth') || {}; + let jwtOptions = authOptions[options.name] || {}; + // NOTE (EK): Pull from global auth config to support legacy auth for an easier transition. - let jwtSettings = merge({}, defaults, pick(app.get('auth') || {}, KEYS), omit(options, ['Verifier'])); + let jwtSettings = merge({}, defaults, pick(authOptions, KEYS), jwtOptions, omit(options, ['Verifier'])); if (typeof jwtSettings.header !== 'string') { throw new Error(`You must provide a 'header' in your authentication configuration or pass one explicitly`); @@ -72,6 +75,7 @@ export default function init (options = {}) { // Register 'jwt' strategy with passport debug('Registering jwt authentication strategy with options:', strategyOptions); app.passport.use(jwtSettings.name, new JWTStrategy(strategyOptions, verifier.verify.bind(verifier))); + app.passport.options(jwtSettings.name, jwtSettings); return result; }; diff --git a/src/verifier.js b/src/verifier.js index 038adf8..c74ff14 100644 --- a/src/verifier.js +++ b/src/verifier.js @@ -18,16 +18,18 @@ class JWTVerifier { verify (req, payload, done) { debug('Received JWT payload', payload); - const id = payload[this.service.id]; + const id = payload[`${this.options.entity}Id`]; if (id === undefined) { + debug(`JWT payload does not contain ${this.options.entity}Id`); return done(null, { payload }); } debug(`Looking up ${this.options.entity} by id`, id); this.service.get(id).then(entity => { - return done(null, Object.assign({ payload }, entity)); + const newPayload = { [`${this.options.entity}Id`]: id }; + return done(null, Object.assign({ payload }, entity), newPayload); }) .catch(error => { debug(`Error populating ${this.options.entity} with id ${id}`, error); diff --git a/test/index.test.js b/test/index.test.js index 7f6abde..ad4e548 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -85,6 +85,16 @@ describe('feathers-authentication-jwt', () => { passportJWT.Strategy.restore(); }); + it('registers the strategy options', () => { + sinon.spy(app.passport, 'options'); + app.configure(jwt()); + app.setup(); + + expect(app.passport.options).to.have.been.calledOnce; + + app.passport.options.restore(); + }); + describe('passport strategy options', () => { let authOptions; let args; @@ -164,6 +174,21 @@ describe('feathers-authentication-jwt', () => { passportJWT.Strategy.restore(); }); + it('pulls options from global config with custom name', () => { + sinon.spy(passportJWT, 'Strategy'); + let authOptions = app.get('auth'); + authOptions.custom = { entity: 'device' }; + app.set('auth', authOptions); + + app.configure(jwt({ name: 'custom' })); + app.setup(); + + expect(passportJWT.Strategy.getCall(0).args[0].entity).to.equal('device'); + expect(passportJWT.Strategy.getCall(0).args[0].bodyKey).to.equal('accessToken'); + + passportJWT.Strategy.restore(); + }); + describe('custom Verifier', () => { it('throws an error if a verify function is missing', () => { expect(() => { @@ -190,7 +215,7 @@ describe('feathers-authentication-jwt', () => { class CustomVerifier extends Verifier { verify (req, payload, done) { expect(payload.id).to.equal(Payload.id); - done(null, Payload); + done(null, payload, Payload); } } diff --git a/test/integration.test.js b/test/integration.test.js index a5612f5..427483f 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -23,7 +23,7 @@ describe('integration', () => { return hook => { const app = hook.app; const id = hook.result.id; - return app.passport.createJWT({ id }, app.get('auth')).then(accessToken => { + return app.passport.createJWT({ userId: id }, app.get('auth')).then(accessToken => { hook.result.accessToken = accessToken; return Promise.resolve(hook); }); diff --git a/test/verifier.test.js b/test/verifier.test.js index 4b4a880..7ccfedf 100644 --- a/test/verifier.test.js +++ b/test/verifier.test.js @@ -65,9 +65,9 @@ describe('Verifier', () => { }); describe('verify', () => { - describe('when id is present in payload', () => { + describe('when userId is present in payload', () => { it('calls get on the provided service', done => { - verifier.verify({}, { id: 1 }, () => { + verifier.verify({}, { userId: 1 }, () => { expect(service.get).to.have.been.calledOnce; expect(service.get).to.have.been.calledWith(1); done(); @@ -75,7 +75,7 @@ describe('Verifier', () => { }); it('returns the payload', done => { - const payload = { id: 1 }; + const payload = { userId: 1 }; verifier.verify({}, payload, (error, result) => { expect(error).to.equal(null); expect(result.payload).to.deep.equal(payload); @@ -84,7 +84,7 @@ describe('Verifier', () => { }); it('returns the entity', done => { - verifier.verify({}, { id: 1 }, (error, result) => { + verifier.verify({}, { userId: 1 }, (error, result) => { expect(error).to.equal(null); expect(result.email).to.deep.equal(user.email); done(); @@ -100,7 +100,7 @@ describe('Verifier', () => { options.service = service; const erroringVerifier = new Verifier(app, options); - const payload = { id: 1 }; + const payload = { userId: 1 }; erroringVerifier.verify({}, payload, (error, result) => { expect(error).to.equal(null); expect(result.payload).to.deep.equal(payload); From 01d3a9a658bbc49e0e6bea5bbc3b30d7d975e6a4 Mon Sep 17 00:00:00 2001 From: Eric Kryski Date: Wed, 23 Nov 2016 00:44:02 -0700 Subject: [PATCH 2/2] fixing example --- example/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/app.js b/example/app.js index 86c16e6..1ec80dd 100644 --- a/example/app.js +++ b/example/app.js @@ -27,7 +27,7 @@ const issueJWT = () => { return hook => { const app = hook.app; const id = hook.result.id; - return app.passport.createJWT({ id }, app.get('auth')).then(accessToken => { + return app.passport.createJWT({ userId: id }, app.get('auth')).then(accessToken => { hook.result.accessToken = accessToken; return Promise.resolve(hook); });