diff --git a/HISTORY.md b/HISTORY.md index ffb63d71..4145b4fd 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Methods are no longer enumerable on `req.session` object + 1.13.1 / 2016-01-29 =================== diff --git a/session/session.js b/session/session.js index c3c0f15a..2eacde60 100644 --- a/session/session.js +++ b/session/session.js @@ -44,9 +44,9 @@ function Session(req, data) { * @api public */ -Session.prototype.touch = function(){ +defineMethod(Session.prototype, 'touch', function touch() { return this.resetMaxAge(); -}; +}); /** * Reset `.maxAge` to `.originalMaxAge`. @@ -55,10 +55,10 @@ Session.prototype.touch = function(){ * @api public */ -Session.prototype.resetMaxAge = function(){ +defineMethod(Session.prototype, 'resetMaxAge', function resetMaxAge() { this.cookie.maxAge = this.cookie.originalMaxAge; return this; -}; +}); /** * Save the session data with optional callback `fn(err)`. @@ -68,10 +68,10 @@ Session.prototype.resetMaxAge = function(){ * @api public */ -Session.prototype.save = function(fn){ +defineMethod(Session.prototype, 'save', function save(fn) { this.req.sessionStore.set(this.id, this, fn || function(){}); return this; -}; +}); /** * Re-loads the session data _without_ altering @@ -85,7 +85,7 @@ Session.prototype.save = function(fn){ * @api public */ -Session.prototype.reload = function(fn){ +defineMethod(Session.prototype, 'reload', function reload(fn) { var req = this.req , store = this.req.sessionStore; store.get(this.id, function(err, sess){ @@ -95,7 +95,7 @@ Session.prototype.reload = function(fn){ fn(); }); return this; -}; +}); /** * Destroy `this` session. @@ -105,11 +105,11 @@ Session.prototype.reload = function(fn){ * @api public */ -Session.prototype.destroy = function(fn){ +defineMethod(Session.prototype, 'destroy', function destroy(fn) { delete this.req.session; this.req.sessionStore.destroy(this.id, fn); return this; -}; +}); /** * Regenerate this request's session. @@ -119,7 +119,24 @@ Session.prototype.destroy = function(fn){ * @api public */ -Session.prototype.regenerate = function(fn){ +defineMethod(Session.prototype, 'regenerate', function regenerate(fn) { this.req.sessionStore.regenerate(this.req, fn); return this; +}); + +/** + * Helper function for creating a method on a prototype. + * + * @param {Object} obj + * @param {String} name + * @param {Function} fn + * @private + */ +function defineMethod(obj, name, fn) { + Object.defineProperty(obj, name, { + configurable: true, + enumerable: false, + value: fn, + writable: true + }); }; diff --git a/test/session.js b/test/session.js index 682cb8d0..35f20de2 100644 --- a/test/session.js +++ b/test/session.js @@ -1420,6 +1420,24 @@ describe('session()', function(){ }); }) + it('should not have enumerable methods', function (done) { + var app = express() + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(function(req, res, next) { + req.session.foo = 'foo'; + req.session.bar = 'bar'; + var keys = []; + for (var key in req.session) { + keys.push(key); + } + res.end(keys.sort().join(',')); + }); + + request(app) + .get('/') + .expect(200, 'bar,cookie,foo', done); + }); + describe('.destroy()', function(){ it('should destroy the previous session', function(done){ var app = express()