diff --git a/README.md b/README.md index a5b0bc5c..3342fbbe 100644 --- a/README.md +++ b/README.md @@ -108,10 +108,12 @@ likely need `resave: true`. ##### rolling -Force a cookie to be set on every response. This resets the expiration date. +Force a cookie to be set with its [`maxAge`](#cookiemaxage) reset to its original value on every response, thus continually extending the expiration date. The default value is `false`. +**Note** When this option is set to `true` but the [`saveUnitialized` option](#saveUnitialized) is set to `false`, the cookie will only be set on responses _after_ the session has been saved for the first time. + ##### saveUninitialized Forces a session that is "uninitialized" to be saved to the store. A session is diff --git a/index.js b/index.js index ab7bdc93..06293038 100644 --- a/index.js +++ b/index.js @@ -385,14 +385,18 @@ function session(options){ return false; } - // in case of rolling session, always reset the cookie - if (rollingSessions) { - return true; + // For new sessions... + if (cookieId != req.sessionID) { + return saveUninitializedSession || isModified(req.session); + } + // For existing sessions... + else { + // In case of rolling sessions, always extend the cookie's expiration date + if (rollingSessions) { + return true; + } + return req.session.cookie.expires != null && isModified(req.session); } - - return cookieId != req.sessionID - ? saveUninitializedSession || isModified(req.session) - : req.session.cookie.expires != null && isModified(req.session); } // generate a session if the browser doesn't send a sessionID diff --git a/test/session.js b/test/session.js index 9a56ed7f..682cb8d0 100644 --- a/test/session.js +++ b/test/session.js @@ -760,7 +760,6 @@ describe('session()', function(){ var app = express(); app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ - var save = req.session.save; req.session.user = 'bob'; res.end(); }); @@ -782,7 +781,6 @@ describe('session()', function(){ var app = express(); app.use(session({ rolling: true, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ - var save = req.session.save; req.session.user = 'bob'; res.end(); }); @@ -799,6 +797,71 @@ describe('session()', function(){ .expect(200, done) }); }); + + it('should not force cookie on uninitialized session if saveUninitialized option is set to false', function(done){ + var count = 0; + var app = express(); + app.use(session({ rolling: true, saveUninitialized: false, secret: 'keyboard cat', cookie: { maxAge: min }})); + app.use(function(req, res, next){ + var save = req.session.save; + res.setHeader('x-count', count); + req.session.save = function(fn){ + res.setHeader('x-count', ++count); + return save.call(this, fn); + }; + res.end(); + }); + + request(app) + .get('/') + .expect('x-count', '0') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }); + + it('should force cookie and save uninitialized session if saveUninitialized option is set to true', function(done){ + var count = 0; + var app = express(); + app.use(session({ rolling: true, saveUninitialized: true, secret: 'keyboard cat', cookie: { maxAge: min }})); + app.use(function(req, res, next){ + var save = req.session.save; + res.setHeader('x-count', count); + req.session.save = function(fn){ + res.setHeader('x-count', ++count); + return save.call(this, fn); + }; + res.end(); + }); + + request(app) + .get('/') + .expect('x-count', '1') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }); + + it('should force cookie and save modified session even if saveUninitialized option is set to false', function(done){ + var count = 0; + var app = express(); + app.use(session({ rolling: true, saveUninitialized: false, secret: 'keyboard cat', cookie: { maxAge: min }})); + app.use(function(req, res, next){ + var save = req.session.save; + res.setHeader('x-count', count); + req.session.count = count; + req.session.user = 'bob'; + req.session.save = function(fn){ + res.setHeader('x-count', ++count); + return save.call(this, fn); + }; + res.end(); + }); + + request(app) + .get('/') + .expect('x-count', '1') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done); + }); }); describe('resave option', function(){