From 1ab6ab329d6fd2d3b464c392a0576630ccc2f21e Mon Sep 17 00:00:00 2001 From: Rowan Wookey <admin@rwky.net> Date: Wed, 11 Dec 2019 13:42:25 +0000 Subject: [PATCH] Feature: Pass instantiated strategy to authenticate. Merged from upstream https://github.com/jaredhanson/passport/pull/749/files --- lib/middleware/authenticate.js | 12 +++++--- test/authenticator.middleware.test.js | 44 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/lib/middleware/authenticate.js b/lib/middleware/authenticate.js index 5ceb5c8b..964c6625 100644 --- a/lib/middleware/authenticate.js +++ b/lib/middleware/authenticate.js @@ -177,6 +177,7 @@ module.exports = function authenticate(passport, name, options, callback) { // eslint-disable-next-line consistent-return (function attempt(i) { + let strategy; const layer = name[i]; // If no more strategies exist in the chain, authentication has failed. if (!layer) { return allFailed(); } @@ -184,11 +185,14 @@ module.exports = function authenticate(passport, name, options, callback) { // Get the strategy, which will be used as prototype from which to create // a new instance. Action functions will then be bound to the strategy // within the context of the HTTP request/response pair. - const prototype = passport._strategy(layer); - if (!prototype) { return next(new Error(`Unknown authentication strategy "${layer}"`)); } - - const strategy = Object.create(prototype); + if (typeof layer.authenticate === 'function') { + strategy = layer; + } else { + const prototype = passport._strategy(layer); + if (!prototype) { return next(new Error(`Unknown authentication strategy "${layer}"`)); } + strategy = Object.create(prototype); + } // ----- BEGIN STRATEGY AUGMENTATION ----- // Augment the new strategy instance with action functions. These action diff --git a/test/authenticator.middleware.test.js b/test/authenticator.middleware.test.js index 519ca5db..12247a43 100644 --- a/test/authenticator.middleware.test.js +++ b/test/authenticator.middleware.test.js @@ -151,6 +151,50 @@ describe('Authenticator', () => { expect(request.user.username).to.equal('jaredhanson'); }); + it('should set authInfo', () => { + expect(request.authInfo).to.be.an('object'); + expect(Object.keys(request.authInfo)).to.have.length(0); + }); + }); + describe('handling a request with instantiated strategy', () => { + function Strategy() { + } + Strategy.prototype.authenticate = function authenticate() { + const user = { id: '1', username: 'jaredhanson' }; + this.success(user); + }; + + const passport = new Authenticator(); + + let request, error; + + before((done) => { + chai.connect.use(passport.authenticate(new Strategy())).req((req) => { + request = req; + + req.logIn = function logIn(user, options, done) { + this.user = user; + done(); + }; + }) + .next((err) => { + error = err; + done(); + }) + .dispatch(); + }); + + it('should not error', () => { + // eslint-disable-next-line no-unused-expressions + expect(error).to.be.undefined; + }); + + it('should set user', () => { + expect(request.user).to.be.an('object'); + expect(request.user.id).to.equal('1'); + expect(request.user.username).to.equal('jaredhanson'); + }); + it('should set authInfo', () => { expect(request.authInfo).to.be.an('object'); expect(Object.keys(request.authInfo)).to.have.length(0);