From 49ebffde6dddf50ace7c83e1b0325d6d63bafca2 Mon Sep 17 00:00:00 2001 From: Gabriel Foust Date: Wed, 2 Mar 2016 14:54:08 -0600 Subject: [PATCH 1/3] Defining built-in properties as non-enumerable. --- session/session.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/session/session.js b/session/session.js index c3c0f15a..031a7884 100644 --- a/session/session.js +++ b/session/session.js @@ -24,6 +24,7 @@ module.exports = Session; function Session(req, data) { Object.defineProperty(this, 'req', { value: req }); Object.defineProperty(this, 'id', { value: req.sessionID }); + Object.defineProperty(this, 'cookie', { value: undefined, writable: true }) if (typeof data === 'object' && data !== null) { // merge data into this, ignoring prototype properties @@ -44,9 +45,9 @@ function Session(req, data) { * @api public */ -Session.prototype.touch = function(){ +Object.defineProperty(Session.prototype, 'touch', { value: function(){ return this.resetMaxAge(); -}; +} }); /** * Reset `.maxAge` to `.originalMaxAge`. @@ -55,10 +56,10 @@ Session.prototype.touch = function(){ * @api public */ -Session.prototype.resetMaxAge = function(){ +Object.defineProperty(Session.prototype, 'resetMaxAge', { value: function(){ this.cookie.maxAge = this.cookie.originalMaxAge; return this; -}; +} }); /** * Save the session data with optional callback `fn(err)`. @@ -68,10 +69,10 @@ Session.prototype.resetMaxAge = function(){ * @api public */ -Session.prototype.save = function(fn){ +Object.defineProperty(Session.prototype, 'save', { value: function(fn){ this.req.sessionStore.set(this.id, this, fn || function(){}); return this; -}; +} }); /** * Re-loads the session data _without_ altering @@ -85,7 +86,7 @@ Session.prototype.save = function(fn){ * @api public */ -Session.prototype.reload = function(fn){ +Object.defineProperty(Session.prototype, 'reload', { value: function(fn){ var req = this.req , store = this.req.sessionStore; store.get(this.id, function(err, sess){ @@ -95,7 +96,7 @@ Session.prototype.reload = function(fn){ fn(); }); return this; -}; +} }); /** * Destroy `this` session. @@ -105,11 +106,11 @@ Session.prototype.reload = function(fn){ * @api public */ -Session.prototype.destroy = function(fn){ +Object.defineProperty(Session.prototype, 'destroy', { value: function(fn){ delete this.req.session; this.req.sessionStore.destroy(this.id, fn); return this; -}; +} }); /** * Regenerate this request's session. @@ -119,7 +120,7 @@ Session.prototype.destroy = function(fn){ * @api public */ -Session.prototype.regenerate = function(fn){ +Object.defineProperty(Session.prototype, 'regenerate', { value: function(fn){ this.req.sessionStore.regenerate(this.req, fn); return this; -}; +} }); From 4da5a1edfd28dbbaf6bbe64332c91f97754dd6a3 Mon Sep 17 00:00:00 2001 From: Gabriel Foust Date: Wed, 2 Mar 2016 16:08:10 -0600 Subject: [PATCH 2/3] Test case for non-enumerable properties --- session/session.js | 1 - test/session.js | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/session/session.js b/session/session.js index 031a7884..71972b7d 100644 --- a/session/session.js +++ b/session/session.js @@ -24,7 +24,6 @@ module.exports = Session; function Session(req, data) { Object.defineProperty(this, 'req', { value: req }); Object.defineProperty(this, 'id', { value: req.sessionID }); - Object.defineProperty(this, 'cookie', { value: undefined, writable: true }) if (typeof data === 'object' && data !== null) { // merge data into this, ignoring prototype properties diff --git a/test/session.js b/test/session.js index 682cb8d0..f37dfe7e 100644 --- a/test/session.js +++ b/test/session.js @@ -1420,6 +1420,24 @@ describe('session()', function(){ }); }) + it('should have only non-enumeable properties, excepting "cookie"', 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() From 918221fc639bd083eb1d971923903512e7529713 Mon Sep 17 00:00:00 2001 From: Gabriel Foust Date: Thu, 3 Mar 2016 22:01:38 -0600 Subject: [PATCH 3/3] Making session methods configurable/writable --- session/session.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/session/session.js b/session/session.js index 71972b7d..01c95a5c 100644 --- a/session/session.js +++ b/session/session.js @@ -44,7 +44,10 @@ function Session(req, data) { * @api public */ -Object.defineProperty(Session.prototype, 'touch', { value: function(){ +Object.defineProperty(Session.prototype, 'touch', { configurable: true, + writable: true, + enumerable: false, + value: function(){ return this.resetMaxAge(); } }); @@ -55,7 +58,10 @@ Object.defineProperty(Session.prototype, 'touch', { value: function(){ * @api public */ -Object.defineProperty(Session.prototype, 'resetMaxAge', { value: function(){ +Object.defineProperty(Session.prototype, 'resetMaxAge', { configurable: true, + writable: true, + enumerable: false, + value: function(){ this.cookie.maxAge = this.cookie.originalMaxAge; return this; } }); @@ -68,7 +74,10 @@ Object.defineProperty(Session.prototype, 'resetMaxAge', { value: function(){ * @api public */ -Object.defineProperty(Session.prototype, 'save', { value: function(fn){ +Object.defineProperty(Session.prototype, 'save', { configurable: true, + writable: true, + enumerable: false, + value: function(fn){ this.req.sessionStore.set(this.id, this, fn || function(){}); return this; } }); @@ -85,7 +94,10 @@ Object.defineProperty(Session.prototype, 'save', { value: function(fn){ * @api public */ -Object.defineProperty(Session.prototype, 'reload', { value: function(fn){ +Object.defineProperty(Session.prototype, 'reload', { configurable: true, + writable: true, + enumerable: false, + value: function(fn){ var req = this.req , store = this.req.sessionStore; store.get(this.id, function(err, sess){ @@ -105,7 +117,10 @@ Object.defineProperty(Session.prototype, 'reload', { value: function(fn){ * @api public */ -Object.defineProperty(Session.prototype, 'destroy', { value: function(fn){ +Object.defineProperty(Session.prototype, 'destroy', { configurable: true, + writable: true, + enumerable: false, + value: function(fn){ delete this.req.session; this.req.sessionStore.destroy(this.id, fn); return this; @@ -119,7 +134,10 @@ Object.defineProperty(Session.prototype, 'destroy', { value: function(fn){ * @api public */ -Object.defineProperty(Session.prototype, 'regenerate', { value: function(fn){ +Object.defineProperty(Session.prototype, 'regenerate', { configurable: true, + writable: true, + enumerable: false, + value: function(fn){ this.req.sessionStore.regenerate(this.req, fn); return this; } });