Skip to content

Commit

Permalink
Merge pull request #878 from jaredhanson/compat-mode
Browse files Browse the repository at this point in the history
Passport 0.4.x compatibility mode
  • Loading branch information
jaredhanson committed Dec 16, 2021
2 parents 5c29557 + 77ec5b3 commit a1804a1
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
35 changes: 34 additions & 1 deletion lib/middleware/initialize.js
Expand Up @@ -52,7 +52,40 @@ module.exports = function initialize(passport, options) {
if (options.userProperty) {
req._userProperty = options.userProperty;
}


var compat = (options.compat === undefined) ? true : options.compat;
if (compat) {
// `passport@0.5.1` [removed][1] all internal use of `req._passport`.
// From the standpoint of this package, this should have been a
// non-breaking change. However, some strategies (such as `passport-azure-ad`)
// depend directly on `passport@0.4.x` or earlier. `require`-ing earlier
// versions of `passport` has the effect of monkeypatching `http.IncomingMessage`
// with `logIn`, `logOut`, `isAuthenticated` and `isUnauthenticated`
// functions that [expect][2] the `req._passport` property to exist.
// Since pre-existing functions on `req` are given [preference][3], this
// results in [issues][4].
//
// The changes here restore the expected properties needed when earlier
// versions of `passport` are `require`-ed. This compatibility mode is
// enabled by default, and can be disabld by simply not `use`-ing `passport.initialize()`
// middleware or setting `compat: false` as an option to the middleware.
//
// An alternative approach to addressing this issue would be to not
// preferentially use pre-existing functions on `req`, but rather always
// overwrite `req.logIn`, etc. with the versions of those functions shiped
// with `authenticate()` middleware. This option should be reconsidered
// in a future major version release.
//
// [1]: https://github.com/jaredhanson/passport/pull/875
// [2]: https://github.com/jaredhanson/passport/blob/v0.4.1/lib/http/request.js
// [3]: https://github.com/jaredhanson/passport/blob/v0.5.1/lib/middleware/authenticate.js#L96
// [4]: https://github.com/jaredhanson/passport/issues/877
passport._userProperty = options.userProperty || 'user';

req._passport = {};
req._passport.instance = passport;
}

next();
};
};
16 changes: 16 additions & 0 deletions test/authenticator.middleware.test.js
Expand Up @@ -42,6 +42,14 @@ describe('Authenticator', function() {
it('should not initialize namespace within session', function() {
expect(request.session.passport).to.be.undefined;
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.an('object');
expect(request._passport.instance).to.be.an.instanceOf(Authenticator);
expect(request._passport.instance).to.equal(passport);
expect(request._passport.instance._sm).to.be.an('object');
expect(request._passport.instance._userProperty).to.equal('user');
});
});

describe('handling a request with custom user property', function() {
Expand Down Expand Up @@ -72,6 +80,14 @@ describe('Authenticator', function() {
it('should not initialize namespace within session', function() {
expect(request.session.passport).to.be.undefined;
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.an('object');
expect(request._passport.instance).to.be.an.instanceOf(Authenticator);
expect(request._passport.instance).to.equal(passport);
expect(request._passport.instance._sm).to.be.an('object');
expect(request._passport.instance._userProperty).to.equal('currentUser');
});
});

});
Expand Down
63 changes: 63 additions & 0 deletions test/middleware/initialize.test.js
Expand Up @@ -31,6 +31,14 @@ describe('middleware/initialize', function() {
it('should not error', function() {
expect(error).to.be.undefined;
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.an('object');
expect(request._passport.instance).to.be.an.instanceOf(Passport);
expect(request._passport.instance).to.equal(passport);
expect(request._passport.instance._sm).to.be.an('object');
expect(request._passport.instance._userProperty).to.equal('user');
});
});

describe('handling a request with a new session', function() {
Expand Down Expand Up @@ -58,6 +66,14 @@ describe('middleware/initialize', function() {
it('should not initialize namespace within session', function() {
expect(request.session.passport).to.be.undefined;
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.an('object');
expect(request._passport.instance).to.be.an.instanceOf(Passport);
expect(request._passport.instance).to.equal(passport);
expect(request._passport.instance._sm).to.be.an('object');
expect(request._passport.instance._userProperty).to.equal('user');
});
});

describe('handling a request with an existing session', function() {
Expand Down Expand Up @@ -89,6 +105,14 @@ describe('middleware/initialize', function() {
expect(Object.keys(request.session.passport)).to.have.length(1);
expect(request.session.passport.user).to.equal('123456');
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.an('object');
expect(request._passport.instance).to.be.an.instanceOf(Passport);
expect(request._passport.instance).to.equal(passport);
expect(request._passport.instance._sm).to.be.an('object');
expect(request._passport.instance._userProperty).to.equal('user');
});
});

describe('handling a request with an existing session using custom session key', function() {
Expand Down Expand Up @@ -121,6 +145,45 @@ describe('middleware/initialize', function() {
expect(Object.keys(request.session.authentication)).to.have.length(1);
expect(request.session.authentication.user).to.equal('123456');
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.an('object');
expect(request._passport.instance).to.be.an.instanceOf(Passport);
expect(request._passport.instance).to.equal(passport);
expect(request._passport.instance._sm).to.be.an('object');
expect(request._passport.instance._userProperty).to.equal('user');
});
});

describe('handling a request with a new session without compat mode', function() {
var passport = new Passport();
var request, error;

before(function(done) {
chai.connect.use(initialize(passport, { compat: false }))
.req(function(req) {
request = req;

req.session = {};
})
.next(function(err) {
error = err;
done();
})
.dispatch();
});

it('should not error', function() {
expect(error).to.be.undefined;
});

it('should not initialize namespace within session', function() {
expect(request.session.passport).to.be.undefined;
});

it('should expose authenticator on internal request property', function() {
expect(request._passport).to.be.undefined;
});
});

});

0 comments on commit a1804a1

Please sign in to comment.