Enable hook from module into passport init.

This commit is contained in:
Shane Kilkelly 2016-11-01 14:06:54 +00:00
parent 5c8cdd22cc
commit 9cb3d8c4b8
4 changed files with 77 additions and 16 deletions

View file

@ -30,6 +30,24 @@ module.exports = AuthenticationController =
deserializeUser: (user, cb) ->
cb(null, user)
afterLoginSessionSetup: (req, user, callback=(err)->) ->
req.login user, (err) ->
# Regenerate the session to get a new sessionID (cookie value) to
# protect against session fixation attacks
oldSession = req.session
req.session.destroy()
req.sessionStore.generate(req)
for key, value of oldSession
req.session[key] = value
# copy to the old `session.user` location, for backward-comptability
req.session.user = req.session.passport.user
req.session.save (err) ->
if err?
logger.err {user_id: user._id}, "error saving regenerated session after login"
return callback(err)
UserSessionsManager.trackSession(user, req.sessionID, () ->)
callback(null)
passportLogin: (req, res, next) ->
# This function is middleware which wraps the passport.authenticate middleware,
# so we can send back our custom `{message: {text: "", type: ""}}` responses on failure,
@ -38,22 +56,10 @@ module.exports = AuthenticationController =
if err?
return next(err)
if user # `user` is either a user object or false
req.login user, (err) ->
# Regenerate the session to get a new sessionID (cookie value) to
# protect against session fixation attacks
oldSession = req.session
req.session.destroy()
req.sessionStore.generate(req)
for key, value of oldSession
req.session[key] = value
# copy to the old `session.user` location, for backward-comptability
req.session.user = req.session.passport.user
req.session.save (err) ->
if err?
logger.err {user_id: user._id}, "error saving regenerated session after login"
return next(err)
UserSessionsManager.trackSession(user, req.sessionID, () ->)
res.json {redir: req._redir}
AuthenticationController.afterLoginSessionSetup req, user, (err) ->
if err?
return next(err)
res.json {redir: req._redir}
else
res.json message: info
)(req, res, next)

View file

@ -106,6 +106,10 @@ passport.use(new LocalStrategy(
passport.serializeUser(AuthenticationController.serializeUser)
passport.deserializeUser(AuthenticationController.deserializeUser)
Modules.hooks.fire 'passportSetup', passport, (err) ->
if err?
logger.err {err}, "error setting up passport in modules"
# Measure expiry from last request, not last login
webRouter.use (req, res, next) ->
req.session.touch()

View file

@ -47,6 +47,7 @@
"nodemailer-ses-transport": "^1.3.0",
"optimist": "0.6.1",
"passport": "^0.3.2",
"passport-ldapauth": "^0.6.0",
"passport-local": "^1.0.0",
"pg": "^6.0.3",
"pg-hstore": "^2.3.2",

View file

@ -157,6 +157,56 @@ describe "AuthenticationController", ->
@res.json.callCount.should.equal 1
@res.json.calledWith({message: @info}).should.equal true
describe 'afterLoginSessionSetup', ->
beforeEach ->
@req.login = sinon.stub().callsArgWith(1, null)
@req.session = @session = {passport: {user: @user}}
@req.session =
passport: {user: {_id: "one"}}
@req.session.destroy = sinon.stub()
@req.session.save = sinon.stub().callsArgWith(0, null)
@req.sessionStore = {generate: sinon.stub()}
@UserSessionsManager.trackSession = sinon.stub()
@call = (callback) =>
@AuthenticationController.afterLoginSessionSetup @req, @user, callback
it 'should not produce an error', (done) ->
@call (err) =>
expect(err).to.equal null
done()
it 'should call req.login', (done) ->
@call (err) =>
@req.login.callCount.should.equal 1
done()
it 'should call req.session.save', (done) ->
@call (err) =>
@req.session.save.callCount.should.equal 1
done()
it 'should call UserSessionsManager.trackSession', (done) ->
@call (err) =>
@UserSessionsManager.trackSession.callCount.should.equal 1
done()
describe 'when req.session.save produces an error', ->
beforeEach ->
@req.session.save = sinon.stub().callsArgWith(0, new Error('woops'))
it 'should produce an error', (done) ->
@call (err) =>
expect(err).to.not.be.oneOf [null, undefined]
expect(err).to.be.instanceof Error
done()
it 'should not call UserSessionsManager.trackSession', (done) ->
@call (err) =>
@UserSessionsManager.trackSession.callCount.should.equal 0
done()
describe 'getSessionUser', ->
it 'should get the user object from session', ->