diff --git a/HISTORY.md b/HISTORY.md index cd65b87..cd46958 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Make `isNew` non-enumerable and non-writeable + * Make `req.sessionOptions` a shallow clone to override per-request * deps: debug@~2.2.0 - Fix high intensity foreground color for bold - deps: ms@0.7.0 diff --git a/README.md b/README.md index 29a098b..8009892 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,12 @@ Is `true` if the session is new. Determine if the session has been populated with data or is empty. +### req.sessionOptions + +Represents the session options for the current request. These options are a +shallow clone of what was provided at middleware construction and can be +altered to change cookie setting behavior on a per-request basis. + ### Destroying a session To destroy a session simply set it to `null`: @@ -88,7 +94,7 @@ req.session = null ## Example -View counter example: +### Simple view counter example ```js var cookieSession = require('cookie-session') @@ -112,6 +118,30 @@ app.use(function (req, res, next) { app.listen(3000) ``` +## Per-user sticky max age + +```js +var cookieSession = require('cookie-session') +var express = require('express') + +var app = express() + +app.set('trust proxy', 1) // trust first proxy + +app.use(cookieSession({ + name: 'session', + keys: ['key1', 'key2'] +})) + +// This allows you to set req.session.maxAge to let certain sessions +// have a different value than the default. +app.use(function (req, res, next) { + req.sessionOptions.maxAge = req.session.maxAge || req.sessionOptions.maxAge +}) + +// ... your logic here ... +``` + ## License [MIT](LICENSE) diff --git a/index.js b/index.js index 3727a00..d17971d 100644 --- a/index.js +++ b/index.js @@ -61,8 +61,8 @@ function cookieSession(options) { var sess, json; // to pass to Session() - req.sessionOptions = opts; - req.sessionKey = name; + req.sessionOptions = Object.create(opts) + req.sessionKey = name req.__defineGetter__('session', function(){ // already retrieved @@ -71,7 +71,7 @@ function cookieSession(options) { // unset if (false === sess) return null; - json = cookies.get(name, opts); + json = cookies.get(name, req.sessionOptions) if (json) { debug('parse %s', json); @@ -109,7 +109,7 @@ function cookieSession(options) { try { if (sess === false) { // remove - cookies.set(name, '', opts); + cookies.set(name, '', req.sessionOptions) } else if (!json && !sess.length) { // do nothing if new and not populated } else if (sess.changed(json)) { diff --git a/test/test.js b/test/test.js index d8729b0..eca51a6 100644 --- a/test/test.js +++ b/test/test.js @@ -346,6 +346,50 @@ describe('Cookie Session', function(){ }) }) }) + + describe('req.sessionOptions', function () { + it('should be the session options', function (done) { + var app = App({ name: 'session' }) + app.use(function (req, res, next) { + res.end(String(req.sessionOptions.name)) + }) + + request(app) + .get('/') + .expect(200, 'session', done) + }) + + it('should alter the cookie setting', function (done) { + var app = App({ maxAge: 3600000, name: 'session' }) + app.use(function (req, res, next) { + if (req.url === '/max') { + req.sessionOptions.maxAge = 6500000 + } + + req.session.message = 'hello!' + res.end() + }) + + request(app) + .get('/') + .expect(function (res) { + var date = new Date(res.headers.date) + var expires = new Date(res.headers['set-cookie'][0].match(/expires=([^;]+)/)[1]) + assert.ok(expires - date <= 3600000) + }) + .expect(200, function (err) { + if (err) return done(err) + request(app) + .get('/max') + .expect(function (res) { + var date = new Date(res.headers.date) + var expires = new Date(res.headers['set-cookie'][0].match(/expires=([^;]+)/)[1]) + assert.ok(expires - date > 5000000) + }) + .expect(200, done) + }) + }) + }) }) function App(options) {