From d694cef29c62a6cba9c98b4fa6f3886a4d4c057f Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 3 Apr 2014 10:13:19 +0200 Subject: [PATCH 001/766] Updated example Ok, the example made me waste 10+ hours trying to figure why my login didn't work. Not all people understand 100% the library and the example is just plain wrong. The example used `secure: true` and copy-pasting it on a non-https site would fail to work always. Also, the **Options** doesn't include anything about **cookie secure**, so i updated the example to make it working and simple, and also updated **Options** to include `secure` defaults. --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8be275b1..5fab8cb3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! # express-session @@ -13,7 +12,7 @@ middleware _before_ `session()`. ```js app.use(connect.cookieParser()) - app.use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) + app.use(connect.session({ secret: 'keyboard cat', key: 'sid' })) ``` **Options** @@ -21,7 +20,7 @@ middleware _before_ `session()`. - `key` cookie name defaulting to `connect.sid` - `store` session store instance - `secret` session cookie is signed with this secret to prevent tampering - - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` + - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, secure: false, maxAge: null }` - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") **Cookie options** From 8d590d53a1eae7149c31fd48bb1691ee007a696c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zsi?= Date: Mon, 7 Apr 2014 17:58:49 +0300 Subject: [PATCH 002/766] Fix example. The required module name is wrong, it should be 'express-session', not 'session'. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ce973376..1cba8721 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! # express-session @@ -13,7 +12,7 @@ middleware _before_ `session()`. ```js var cookieParser = require('cookie-parser'); -var session = require('session'); +var session = require('express-session'); app.use(cookieParser()) app.use(session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) From 0f69668f2e35138b5ffaf8c24134a947e1d941fa Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Fri, 14 Mar 2014 10:39:27 -0700 Subject: [PATCH 003/766] Moving from connect to express 4.0.0-rc3 Because if this project is meant to replace the bundled middleware in 3.x for those who have moved to 4.x, it should be tested against 4.x. Also, connect patches core http methods so behavior is in fact different now between express and connect. Signed-off-by: Brian White --- package.json | 2 +- test/session.js | 50 ++++++++++++++++++++++++------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 520fa305..7223b2cf 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "mocha": "~1.17.0", - "connect": "2.13.0", + "express": "4.0.0-rc3", "supertest": "0.9.0", "should": "3.1.2", "cookie-parser": "1.0.0" diff --git a/test/session.js b/test/session.js index f93bec52..20ed96ca 100644 --- a/test/session.js +++ b/test/session.js @@ -1,5 +1,5 @@ -var connect = require('connect') +var express = require('express') , assert = require('assert') , request = require('supertest') , should = require('should') @@ -22,7 +22,7 @@ function expires(res) { return res.headers['set-cookie'][0].match(/Expires=([^;]+)/)[1]; } -var app = connect() +var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(respond); @@ -37,7 +37,7 @@ describe('session()', function(){ describe('proxy option', function(){ describe('when enabled', function(){ it('should trust X-Forwarded-Proto when string', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) .use(respond); @@ -52,7 +52,7 @@ describe('session()', function(){ }) it('should trust X-Forwarded-Proto when comma-separated list', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) .use(respond); @@ -69,7 +69,7 @@ describe('session()', function(){ describe('when disabled', function(){ it('should not trust X-Forwarded-Proto', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) .use(respond); @@ -97,7 +97,7 @@ describe('session()', function(){ }) it('should allow overriding', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', key: 'sid', cookie: { maxAge: min }})) .use(respond); @@ -115,7 +115,7 @@ describe('session()', function(){ it('should retain the sid', function(done){ var n = 0; - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res){ @@ -153,7 +153,7 @@ describe('session()', function(){ it('should issue separate sids', function(done){ var n = 0; - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res){ @@ -184,7 +184,7 @@ describe('session()', function(){ describe('req.session', function(){ it('should persist', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min, httpOnly: false }})) .use(function(req, res, next){ @@ -214,7 +214,7 @@ describe('session()', function(){ it('should only set-cookie when modified', function(done){ var modify = true; - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res, next){ @@ -261,7 +261,7 @@ describe('session()', function(){ describe('.destroy()', function(){ it('should destroy the previous session', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ @@ -283,7 +283,7 @@ describe('session()', function(){ describe('.regenerate()', function(){ it('should destroy/replace the previous session', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res, next){ @@ -315,7 +315,7 @@ describe('session()', function(){ describe('.cookie', function(){ describe('.*', function(){ it('should serialize as parameters', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { maxAge: min }})) .use(function(req, res, next){ @@ -335,7 +335,7 @@ describe('session()', function(){ }) it('should default to a browser-session length cookie', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) .use(function(req, res, next){ @@ -352,7 +352,7 @@ describe('session()', function(){ }) it('should Set-Cookie only once for browser-session cookies', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) .use(function(req, res, next){ @@ -375,7 +375,7 @@ describe('session()', function(){ }) it('should override defaults', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/admin', httpOnly: false, secure: true, maxAge: 5000 }})) .use(function(req, res, next){ @@ -398,7 +398,7 @@ describe('session()', function(){ describe('.secure', function(){ it('should not set-cookie when insecure', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ @@ -417,7 +417,7 @@ describe('session()', function(){ describe('when the pathname does not match cookie.path', function(){ it('should not set-cookie', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ @@ -438,7 +438,7 @@ describe('session()', function(){ }) it('should not set-cookie even for FQDN', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ @@ -463,7 +463,7 @@ describe('session()', function(){ describe('when the pathname does match cookie.path', function(){ it('should set-cookie', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ @@ -480,7 +480,7 @@ describe('session()', function(){ }) it('should set-cookie even for FQDN', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ @@ -501,7 +501,7 @@ describe('session()', function(){ describe('.maxAge', function(){ var id; - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: 2000 }})) .use(function(req, res, next){ @@ -573,7 +573,7 @@ describe('session()', function(){ describe('.expires', function(){ describe('when given a Date', function(){ it('should set absolute', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ @@ -592,7 +592,7 @@ describe('session()', function(){ describe('when null', function(){ it('should be a browser-session cookie', function(done){ - var app = connect() + var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ @@ -612,7 +612,7 @@ describe('session()', function(){ }) it('should support req.signedCookies', function(done){ - var app = connect() + var app = express() .use(cookieParser('keyboard cat')) .use(session()) .use(function(req, res, next){ From 7c99ee53e46ab98ff616ea38aa32732a65b4e688 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Fri, 14 Mar 2014 10:43:23 -0700 Subject: [PATCH 004/766] Add new test verifying prevented cookie overwrite This is an example of something that the connect unbundling changed. res.setHeader, when connect has been loaded, properly checks the previous value and creates an array or adds to the existing array. Express 4.x, without connect, doesn't have this built-in collision prevention logic. Signed-off-by: Brian White --- test/session.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/session.js b/test/session.js index 20ed96ca..7e05b024 100644 --- a/test/session.js +++ b/test/session.js @@ -5,6 +5,7 @@ var express = require('express') , should = require('should') , cookieParser = require('cookie-parser') , session = require('../') + , Cookie = require('../session/cookie') var min = 60 * 1000; @@ -394,6 +395,30 @@ describe('session()', function(){ done(); }); }) + + it('should preserve cookies set before writeHead is called', function(done){ + function getPreviousCookie(res) { + var val = res.headers['set-cookie']; + if (!val) return ''; + return /previous=([^;]+);/.exec(val[0])[1]; + } + + var app = express() + .use(cookieParser('keyboard cat')) + .use(session()) + .use(function(req, res, next){ + var cookie = new Cookie(); + res.setHeader('Set-Cookie', cookie.serialize('previous', 'cookieValue')); + res.end(); + }); + + request(app) + .get('/') + .end(function(err, res){ + getPreviousCookie(res).should.equal('cookieValue'); + done(); + }); + }) }) describe('.secure', function(){ From 602fdb70a67acebb535cc20cb0b6a893ece7dc19 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sat, 19 Apr 2014 18:52:30 -0400 Subject: [PATCH 005/766] bump express dev dep to 4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7223b2cf..9ec4754d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "mocha": "~1.17.0", - "express": "4.0.0-rc3", + "express": "4.0.0", "supertest": "0.9.0", "should": "3.1.2", "cookie-parser": "1.0.0" From 154138f389a8fb5a18dfc72c8993ee73e4ad2669 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sat, 19 Apr 2014 19:14:37 -0400 Subject: [PATCH 006/766] Use res.cookie() instead of res.setHeader() Fixes #16 --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 7d83b08c..67efa418 100644 --- a/index.js +++ b/index.js @@ -288,9 +288,8 @@ function session(options){ } var val = 's:' + signature.sign(req.sessionID, secret); - val = cookie.serialize(key, val); debug('set-cookie %s', val); - res.setHeader('Set-Cookie', val); + res.cookie(key, val, cookie.data); writeHead.apply(res, arguments); }; From 3e65f411e736ba75b6430480117f9c3e41d180d8 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sat, 19 Apr 2014 19:18:43 -0400 Subject: [PATCH 007/766] Update dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9ec4754d..09c59896 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "utils-merge": "1.0.0", - "cookie": "0.1.0", + "cookie": "0.1.2", "cookie-signature": "1.0.3", "uid2": "0.0.3", "buffer-crc32": "0.2.1", @@ -20,7 +20,7 @@ "express": "4.0.0", "supertest": "0.9.0", "should": "3.1.2", - "cookie-parser": "1.0.0" + "cookie-parser": "1.0.1" }, "scripts": { "test": "mocha --bail --ui bdd --reporter list -- test/*.js" From 5211e070a58cb859f58faaeda22784991ce0fa85 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sat, 19 Apr 2014 19:19:02 -0400 Subject: [PATCH 008/766] Bump version to 1.0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 09c59896..002581b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.0.2", + "version": "1.0.3", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "main": "./index.js", "repository": { From 7732a9c4df5df728d1b698b5b7bd93c1ad50f2cf Mon Sep 17 00:00:00 2001 From: Ricardo Barros Date: Mon, 21 Apr 2014 18:20:23 +0100 Subject: [PATCH 009/766] #Fix - Readme.md Manipulation of session variables must be before res.end() or it will take no effect. Tested with express 4.0.0, session using connect-redis, but with cookies it should have the same issue. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cba8721..2cb02fee 100644 --- a/README.md +++ b/README.md @@ -45,11 +45,11 @@ app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) app.use(function(req, res, next){ var sess = req.session; if (sess.views) { + sess.views++; res.setHeader('Content-Type', 'text/html'); res.write('

views: ' + sess.views + '

'); res.write('

expires in: ' + (sess.cookie.maxAge / 1000) + 's

'); res.end(); - sess.views++; } else { sess.views = 1; res.end('welcome to the session demo. refresh!'); From 8d1862a4d49c6b4ffcdee894991656f86d5eb44d Mon Sep 17 00:00:00 2001 From: Jonathan Freeman Date: Thu, 24 Apr 2014 11:59:39 -0500 Subject: [PATCH 010/766] Updating the link to cookie-parser Fixes #24. Linking to the new cookie-parser repository in the expressjs org. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cb02fee..1cee7747 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REP Setup session store with the given `options`. Session data is _not_ saved in the cookie itself, however -cookies are used, so we must use the [cookieParser()](cookieParser.html) +cookies are used, so we must use the [cookieParser()](https://github.com/expressjs/cookie-parser) middleware _before_ `session()`. ## Example From 758b5e68103f570dd74eb5f36ba2a6308355ec7e Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Thu, 24 Apr 2014 15:00:44 -0400 Subject: [PATCH 011/766] Cleaner docs. Add build and npm module badges. Cleaned some comments. --- README.md | 103 ++++++++++++++++++++-------------------- index.js | 139 +++--------------------------------------------------- 2 files changed, 60 insertions(+), 182 deletions(-) diff --git a/README.md b/README.md index 1cee7747..ab2cbc38 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,42 @@ THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! -# express-session +# express-session [![Build Status](https://travis-ci.org/expressjs/session.svg)](https://travis-ci.org/expressjs/session) [![NPM version](https://badge.fury.io/js/session.svg)](http://badge.fury.io/js/session) -Setup session store with the given `options`. - -Session data is _not_ saved in the cookie itself, however -cookies are used, so we must use the [cookieParser()](https://github.com/expressjs/cookie-parser) -middleware _before_ `session()`. - -## Example +## API ```js -var cookieParser = require('cookie-parser'); -var session = require('express-session'); +var express = require('express') + , cookieParser = require('cookie-parser') + , session = require('express-session') + , app = express() -app.use(cookieParser()) +app.use(cookieParser()) // required before session. app.use(session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) ``` -**Options** +### session(options) + +Setup session store with the given `options`. + +Session data is _not_ saved in the cookie itself, however +cookies are used, so we must use the [cookie-parser](https://github.com/expressjs/cookie-parser) +middleware _before_ `session()`. + +#### Options - - `key` cookie name defaulting to `connect.sid` - - `store` session store instance - - `secret` session cookie is signed with this secret to prevent tampering - - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` - - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") + - `key` - cookie name defaulting to `connect.sid`. + - `store` - session store instance. + - `secret` - session cookie is signed with this secret to prevent tampering. + - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). + - - `cookie` - session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`. -**Cookie options** +#### Cookie options By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set so the cookie becomes a browser-session cookie. When the user closes the browser the cookie (and session) will be removed. -## req.session +### req.session To store or access session data, simply use the request property `req.session`, which is (generally) serialized as JSON by the store, so nested objects @@ -42,75 +46,73 @@ are typically fine. For example below is a user-specific view counter: app.use(cookieParser()) app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) -app.use(function(req, res, next){ - var sess = req.session; +app.use(function(req, res, next) { + var sess = req.session if (sess.views) { - sess.views++; - res.setHeader('Content-Type', 'text/html'); - res.write('

views: ' + sess.views + '

'); - res.write('

expires in: ' + (sess.cookie.maxAge / 1000) + 's

'); - res.end(); + sess.views++ + res.setHeader('Content-Type', 'text/html') + res.write('

views: ' + sess.views + '

') + res.write('

expires in: ' + (sess.cookie.maxAge / 1000) + 's

') + res.end() } else { - sess.views = 1; - res.end('welcome to the session demo. refresh!'); + sess.views = 1 + res.end('welcome to the session demo. refresh!') } }) ``` -## Session#regenerate() +#### Session.regenerate() To regenerate the session simply invoke the method, once complete a new SID and `Session` instance will be initialized at `req.session`. ```js -req.session.regenerate(function(err){ +req.session.regenerate(function(err) { // will have a new session here -}); +}) ``` -## Session#destroy() +#### Session.destroy() Destroys the session, removing `req.session`, will be re-generated next request. ```js -req.session.destroy(function(err){ +req.session.destroy(function(err) { // cannot access session here -}); +}) ``` -## Session#reload() +#### Session.reload() Reloads the session data. ```js -req.session.reload(function(err){ +req.session.reload(function(err) { // session updated -}); +}) ``` -## Session#save() - -Save the session. +#### Session.save() ```js -req.session.save(function(err){ +req.session.save(function(err) { // session saved -}); +}) ``` -## Session#touch() +#### Session.touch() Updates the `.maxAge` property. Typically this is not necessary to call, as the session middleware does this for you. -## Session#cookie +### req.session.cookie Each session has a unique cookie object accompany it. This allows you to alter the session cookie per visitor. For example we can set `req.session.cookie.expires` to `false` to enable the cookie to remain for only the duration of the user-agent. -## Session#maxAge +#### Cookie.maxAge Alternatively `req.session.cookie.maxAge` will return the time remaining in milliseconds, which we may also re-assign a new value @@ -118,9 +120,9 @@ to adjust the `.expires` property appropriately. The following are essentially equivalent ```js -var hour = 3600000; -req.session.cookie.expires = new Date(Date.now() + hour); -req.session.cookie.maxAge = hour; +var hour = 3600000 +req.session.cookie.expires = new Date(Date.now() + hour) +req.session.cookie.maxAge = hour ``` For example when `maxAge` is set to `60000` (one minute), and 30 seconds @@ -129,8 +131,7 @@ at which time `req.session.touch()` is called to reset `req.session.maxAge` to its original value. ```js -req.session.cookie.maxAge; -// => 30000 +req.session.cookie.maxAge // => 30000 ``` ## Session Store Implementation @@ -145,3 +146,5 @@ Recommended methods include, but are not limited to: - `.length(callback)` - `.clear(callback)` + +For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. diff --git a/index.js b/index.js index 67efa418..c6ad1288 100644 --- a/index.js +++ b/index.js @@ -48,140 +48,16 @@ var warning = 'Warning: connect.session() MemoryStore is not\n' + 'memory, and will not scale past a single process.'; /** - * Session: + * Setup session store with the given `options`. * - * Setup session store with the given `options`. + * See README.md for documentation of options and formatting. * - * Session data is _not_ saved in the cookie itself, however - * cookies are used, so we must use the [cookieParser()](cookieParser.html) - * middleware _before_ `session()`. - * - * Examples: - * - * connect() - * .use(connect.cookieParser()) - * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) - * - * Options: - * - * - `key` cookie name defaulting to `connect.sid` - * - `store` session store instance - * - `secret` session cookie is signed with this secret to prevent tampering - * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` - * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") - * - * Cookie option: - * - * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set - * so the cookie becomes a browser-session cookie. When the user closes the - * browser the cookie (and session) will be removed. - * - * ## req.session - * - * To store or access session data, simply use the request property `req.session`, - * which is (generally) serialized as JSON by the store, so nested objects - * are typically fine. For example below is a user-specific view counter: - * - * connect() - * .use(connect.favicon()) - * .use(connect.cookieParser()) - * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) - * .use(function(req, res, next){ - * var sess = req.session; - * if (sess.views) { - * res.setHeader('Content-Type', 'text/html'); - * res.write('

views: ' + sess.views + '

'); - * res.write('

expires in: ' + (sess.cookie.maxAge / 1000) + 's

'); - * res.end(); - * sess.views++; - * } else { - * sess.views = 1; - * res.end('welcome to the session demo. refresh!'); - * } - * } - * )).listen(3000); - * - * ## Session#regenerate() - * - * To regenerate the session simply invoke the method, once complete - * a new SID and `Session` instance will be initialized at `req.session`. - * - * req.session.regenerate(function(err){ - * // will have a new session here - * }); - * - * ## Session#destroy() - * - * Destroys the session, removing `req.session`, will be re-generated next request. - * - * req.session.destroy(function(err){ - * // cannot access session here - * }); - * - * ## Session#reload() - * - * Reloads the session data. - * - * req.session.reload(function(err){ - * // session updated - * }); - * - * ## Session#save() - * - * Save the session. - * - * req.session.save(function(err){ - * // session saved - * }); - * - * ## Session#touch() - * - * Updates the `.maxAge` property. Typically this is - * not necessary to call, as the session middleware does this for you. - * - * ## Session#cookie - * - * Each session has a unique cookie object accompany it. This allows - * you to alter the session cookie per visitor. For example we can - * set `req.session.cookie.expires` to `false` to enable the cookie - * to remain for only the duration of the user-agent. - * - * ## Session#maxAge - * - * Alternatively `req.session.cookie.maxAge` will return the time - * remaining in milliseconds, which we may also re-assign a new value - * to adjust the `.expires` property appropriately. The following - * are essentially equivalent - * - * var hour = 3600000; - * req.session.cookie.expires = new Date(Date.now() + hour); - * req.session.cookie.maxAge = hour; - * - * For example when `maxAge` is set to `60000` (one minute), and 30 seconds - * has elapsed it will return `30000` until the current request has completed, - * at which time `req.session.touch()` is called to reset `req.session.maxAge` - * to its original value. - * - * req.session.cookie.maxAge; - * // => 30000 - * - * Session Store Implementation: - * - * Every session store _must_ implement the following methods - * - * - `.get(sid, callback)` - * - `.set(sid, session, callback)` - * - `.destroy(sid, callback)` - * - * Recommended methods include, but are not limited to: - * - * - `.length(callback)` - * - `.clear(callback)` - * - * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. + * Session data is _not_ saved in the cookie itself, however cookies are used, + * so you must use the cookie-parser middleware _before_ `session()`. + * [https://github.com/expressjs/cookie-parser] * * @param {Object} options - * @return {Function} + * @return {Function} middleware * @api public */ @@ -353,8 +229,7 @@ function session(options){ }; /** - * Hash the given `sess` object omitting changes - * to `.cookie`. + * Hash the given `sess` object omitting changes to `.cookie`. * * @param {Object} sess * @return {String} From 554065709c68c3d84c85dec364ce7a7d6462dda8 Mon Sep 17 00:00:00 2001 From: Azat Mardanov Date: Sat, 26 Apr 2014 19:22:09 -0700 Subject: [PATCH 012/766] Update README.md remove an extra line --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ff337093..ad5f5c67 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,6 @@ If for development or other reasons security is not a concern, just use: ``` app.use(connect.cookieParser()) app.use(connect.session({ secret: 'keyboard cat', key: 'sid' })) - ``` By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set From aae60e769222b67e194458165b670314085d2172 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sun, 27 Apr 2014 19:58:59 -0400 Subject: [PATCH 013/766] add node engine to package.json --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 002581b4..e9dc4569 100644 --- a/package.json +++ b/package.json @@ -25,5 +25,8 @@ "scripts": { "test": "mocha --bail --ui bdd --reporter list -- test/*.js" }, + "engines": { + "node": ">= 0.10.0" + }, "license": "MIT" } From 4e71f961b2b752ef3971f039b03a170cfac7bd19 Mon Sep 17 00:00:00 2001 From: Justin Dickow Date: Sun, 27 Apr 2014 20:09:46 -0400 Subject: [PATCH 014/766] memory store: fix node 0.8 compatibility fixes #30 closes #31 --- .travis.yml | 1 + package.json | 2 +- session/memory.js | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05d299e6..99cdc743 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: node_js node_js: + - "0.8" - "0.10" - "0.11" diff --git a/package.json b/package.json index e9dc4569..028367b7 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "test": "mocha --bail --ui bdd --reporter list -- test/*.js" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 0.8.0" }, "license": "MIT" } diff --git a/session/memory.js b/session/memory.js index b79147f4..fb939392 100644 --- a/session/memory.js +++ b/session/memory.js @@ -38,7 +38,7 @@ MemoryStore.prototype.__proto__ = Store.prototype; MemoryStore.prototype.get = function(sid, fn){ var self = this; - setImmediate(function(){ + process.nextTick(function(){ var expires , sess = self.sessions[sid]; if (sess) { @@ -68,7 +68,7 @@ MemoryStore.prototype.get = function(sid, fn){ MemoryStore.prototype.set = function(sid, sess, fn){ var self = this; - setImmediate(function(){ + process.nextTick(function(){ self.sessions[sid] = JSON.stringify(sess); fn && fn(); }); @@ -83,7 +83,7 @@ MemoryStore.prototype.set = function(sid, sess, fn){ MemoryStore.prototype.destroy = function(sid, fn){ var self = this; - setImmediate(function(){ + process.nextTick(function(){ delete self.sessions[sid]; fn && fn(); }); From 5a623b236e61b3c3c491a3dab46826f4ab284853 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Apr 2014 20:24:38 -0400 Subject: [PATCH 015/766] build: add .npmignore --- .npmignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..cefaa67a --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +test/ +.travis.yml \ No newline at end of file From ebce1a9ab0acddba1d2b26e0c5b37d1af52a0eab Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Apr 2014 20:28:12 -0400 Subject: [PATCH 016/766] deps: debug@0.8.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 028367b7..2d2cb008 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie-signature": "1.0.3", "uid2": "0.0.3", "buffer-crc32": "0.2.1", - "debug": "0.7.4" + "debug": "0.8.1" }, "devDependencies": { "mocha": "~1.17.0", From 451f94163b9e9055a0b5adb5e99ea488ff987d7f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Apr 2014 20:28:32 -0400 Subject: [PATCH 017/766] 1.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2d2cb008..cfbec530 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.0.3", + "version": "1.0.4", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "main": "./index.js", "repository": { From f4abf78eb1897ddc054717c3cdb217a62ef00076 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Apr 2014 20:30:24 -0400 Subject: [PATCH 018/766] require node.js >= 0.10 --- .travis.yml | 1 - package.json | 2 +- session/memory.js | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99cdc743..05d299e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: node_js node_js: - - "0.8" - "0.10" - "0.11" diff --git a/package.json b/package.json index cfbec530..fae6346d 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "test": "mocha --bail --ui bdd --reporter list -- test/*.js" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.10.0" }, "license": "MIT" } diff --git a/session/memory.js b/session/memory.js index fb939392..b79147f4 100644 --- a/session/memory.js +++ b/session/memory.js @@ -38,7 +38,7 @@ MemoryStore.prototype.__proto__ = Store.prototype; MemoryStore.prototype.get = function(sid, fn){ var self = this; - process.nextTick(function(){ + setImmediate(function(){ var expires , sess = self.sessions[sid]; if (sess) { @@ -68,7 +68,7 @@ MemoryStore.prototype.get = function(sid, fn){ MemoryStore.prototype.set = function(sid, sess, fn){ var self = this; - process.nextTick(function(){ + setImmediate(function(){ self.sessions[sid] = JSON.stringify(sess); fn && fn(); }); @@ -83,7 +83,7 @@ MemoryStore.prototype.set = function(sid, sess, fn){ MemoryStore.prototype.destroy = function(sid, fn){ var self = this; - process.nextTick(function(){ + setImmediate(function(){ delete self.sessions[sid]; fn && fn(); }); From e0711a3710eb1c8cc2f8d885c9121b353e0339dc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Apr 2014 20:38:17 -0400 Subject: [PATCH 019/766] docs: add History --- History.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 History.md diff --git a/History.md b/History.md new file mode 100644 index 00000000..b28a396d --- /dev/null +++ b/History.md @@ -0,0 +1,26 @@ +1.0.4 / 2014-04-27 +================== + + * only version compatible with node.js 0.8 + * deps: debug@0.8.1 + +1.0.3 / 2014-04-19 +================== + + * Use `res.cookie()` instead of `res.setHeader()` + * deps: cookie@0.1.2 + +1.0.2 / 2014-02-23 +================== + + * Add missing dependency to `package.json` + +1.0.1 / 2014-02-15 +================== + + * Add missing dependencies to `package.json` + +1.0.0 / 2014-02-15 +================== + + * Genesis from `connect` From 78bffdb76256d112be87509e0576014bc64c60f5 Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Wed, 7 May 2014 20:47:37 -0400 Subject: [PATCH 020/766] docs: update to newer style & fixes Fix npm badge. Fixes #33 --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ad5f5c67..f32689a0 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! -# express-session [![Build Status](https://travis-ci.org/expressjs/session.svg)](https://travis-ci.org/expressjs/session) [![NPM version](https://badge.fury.io/js/session.svg)](http://badge.fury.io/js/session) +# express-session [![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) [![NPM Version](https://badge.fury.io/js/express-session.svg)](https://badge.fury.io/js/express-session) ## API ```js var express = require('express') - , cookieParser = require('cookie-parser') - , session = require('express-session') - , app = express() +var cookieParser = require('cookie-parser') +var session = require('express-session') + +var app = express() app.use(cookieParser()) // required before session. app.use(session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) @@ -25,11 +26,13 @@ middleware _before_ `session()`. #### Options - - `key` - cookie name defaulting to `connect.sid`. + - `key` - cookie name. (default: `connect.sid`) - `store` - session store instance. - `secret` - session cookie is signed with this secret to prevent tampering. - - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). - - `cookie` - session cookie settings, defaulting to `{ path: '/', httpOnly: true, secure: false, maxAge: null }` + - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) + - `cookie` - session cookie settings. + - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) + - `rolling` - forces a cookie reset on response. The reset affects the expiration date. (default: `false`) #### Cookie options @@ -37,9 +40,13 @@ middleware _before_ `session()`. Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If for development or other reasons security is not a concern, just use: -``` +```js app.use(connect.cookieParser()) -app.use(connect.session({ secret: 'keyboard cat', key: 'sid' })) +app.use(connect.session({ + secret: 'keyboard cat' + , key: 'sid' + , proxy: true // if you do SSL outside of node. +})) ``` By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set From b9c077315a7901293024a95ef257836ee49269f5 Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Wed, 7 May 2014 20:49:53 -0400 Subject: [PATCH 021/766] Explicitly default `options.proxy` to false. --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index c6ad1288..2b1f0168 100644 --- a/index.js +++ b/index.js @@ -66,7 +66,7 @@ function session(options){ , key = options.key || 'connect.sid' , store = options.store || new MemoryStore , cookie = options.cookie || {} - , trustProxy = options.proxy + , trustProxy = options.proxy || false , storeReady = true , rollingSessions = options.rolling || false; From fc4bd2aa2bc487291ae8b735794ad9f90d9cf54a Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Mon, 12 May 2014 14:59:25 -0400 Subject: [PATCH 022/766] Rename `key` to `name`. Prioritize `options.name` Fallback to `options.key` if `options.name` does not exist. Closes #34 --- README.md | 2 +- index.js | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f32689a0..3a28d05c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ middleware _before_ `session()`. #### Options - - `key` - cookie name. (default: `connect.sid`) + - `name` - cookie name. (default: `connect.sid`) - `store` - session store instance. - `secret` - session cookie is signed with this secret to prevent tampering. - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) diff --git a/index.js b/index.js index 2b1f0168..b5b64656 100644 --- a/index.js +++ b/index.js @@ -63,7 +63,8 @@ var warning = 'Warning: connect.session() MemoryStore is not\n' function session(options){ var options = options || {} - , key = options.key || 'connect.sid' + // name - previously "options.key" + , name = options.name || options.key || 'connect.sid' , store = options.store || new MemoryStore , cookie = options.cookie || {} , trustProxy = options.proxy || false @@ -112,10 +113,10 @@ function session(options){ req.sessionStore = store; // grab the session cookie value and check the signature - var rawCookie = req.cookies[key]; + var rawCookie = req.cookies[name]; // get signedCookies for backwards compat with signed cookies - var unsignedCookie = req.signedCookies[key]; + var unsignedCookie = req.signedCookies[name]; if (!unsignedCookie && rawCookie) { unsignedCookie = (0 == rawCookie.indexOf('s:')) @@ -165,7 +166,7 @@ function session(options){ var val = 's:' + signature.sign(req.sessionID, secret); debug('set-cookie %s', val); - res.cookie(key, val, cookie.data); + res.cookie(name, val, cookie.data); writeHead.apply(res, arguments); }; From 9849af713995647b04c3717b9030fe9c01cbe45d Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Mon, 12 May 2014 14:59:52 -0400 Subject: [PATCH 023/766] readme: fix trailing whitespace --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3a28d05c..cd543157 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ middleware _before_ `session()`. - `store` - session store instance. - `secret` - session cookie is signed with this secret to prevent tampering. - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) - - `cookie` - session cookie settings. + - `cookie` - session cookie settings. - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - `rolling` - forces a cookie reset on response. The reset affects the expiration date. (default: `false`) @@ -42,9 +42,9 @@ If for development or other reasons security is not a concern, just use: ```js app.use(connect.cookieParser()) -app.use(connect.session({ +app.use(connect.session({ secret: 'keyboard cat' - , key: 'sid' + , key: 'sid' , proxy: true // if you do SSL outside of node. })) ``` From a81ef4454101409e5a8ba9cbb00278ac598d8126 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 May 2014 16:09:09 -0400 Subject: [PATCH 024/766] build: suport node.js 0.8 again --- .travis.yml | 1 + History.md | 1 - package.json | 2 +- session/memory.js | 14 +++++++++++--- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05d299e6..99cdc743 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: node_js node_js: + - "0.8" - "0.10" - "0.11" diff --git a/History.md b/History.md index b28a396d..49e68929 100644 --- a/History.md +++ b/History.md @@ -1,7 +1,6 @@ 1.0.4 / 2014-04-27 ================== - * only version compatible with node.js 0.8 * deps: debug@0.8.1 1.0.3 / 2014-04-19 diff --git a/package.json b/package.json index fae6346d..cfbec530 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "test": "mocha --bail --ui bdd --reporter list -- test/*.js" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 0.8.0" }, "license": "MIT" } diff --git a/session/memory.js b/session/memory.js index b79147f4..9720b061 100644 --- a/session/memory.js +++ b/session/memory.js @@ -12,6 +12,14 @@ var Store = require('./store'); +/** + * Shim setImmediate for node.js < 0.10 + */ + +var asyncTick = typeof setImmediate === 'function' + ? setImmediate + : process.nextTick; + /** * Initialize a new `MemoryStore`. * @@ -38,7 +46,7 @@ MemoryStore.prototype.__proto__ = Store.prototype; MemoryStore.prototype.get = function(sid, fn){ var self = this; - setImmediate(function(){ + asyncTick(function(){ var expires , sess = self.sessions[sid]; if (sess) { @@ -68,7 +76,7 @@ MemoryStore.prototype.get = function(sid, fn){ MemoryStore.prototype.set = function(sid, sess, fn){ var self = this; - setImmediate(function(){ + asyncTick(function(){ self.sessions[sid] = JSON.stringify(sess); fn && fn(); }); @@ -83,7 +91,7 @@ MemoryStore.prototype.set = function(sid, sess, fn){ MemoryStore.prototype.destroy = function(sid, fn){ var self = this; - setImmediate(function(){ + asyncTick(function(){ delete self.sessions[sid]; fn && fn(); }); From 5d326b857e126a40448b45786997680412d04d95 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 May 2014 16:11:25 -0400 Subject: [PATCH 025/766] deps: update test dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cfbec530..0024ec47 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "debug": "0.8.1" }, "devDependencies": { - "mocha": "~1.17.0", "express": "4.0.0", - "supertest": "0.9.0", - "should": "3.1.2", + "mocha": "~1.18.2", + "should": "~3.3.1", + "supertest": "~0.12.1", "cookie-parser": "1.0.1" }, "scripts": { From f5ac80d8c70dbba12b2b604a3b2e494d210f9964 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 May 2014 16:18:39 -0400 Subject: [PATCH 026/766] 1.1.0 --- History.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 49e68929..c44ab618 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +1.1.0 / 2014-05-12 +================== + + * Add `name` option; replacement for `key` option + * Use `setImmediate` in MemoryStore for node.js >= 0.10 + 1.0.4 / 2014-04-27 ================== diff --git a/package.json b/package.json index 0024ec47..1f6a44d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.0.4", + "version": "1.1.0", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "main": "./index.js", "repository": { From d9726bc0d5c55560c939bf565591d575d56ee6bf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 13 May 2014 23:02:13 -0400 Subject: [PATCH 027/766] build: soft testing on node.js 0.11 --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 99cdc743..65cf4bc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,7 @@ node_js: - "0.8" - "0.10" - "0.11" +matrix: + allow_failures: + - node_js: "0.11" + fast_finish: true From 75789dee53ec30b727cb7ab33d87e0943b7be6b2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 13 May 2014 23:03:38 -0400 Subject: [PATCH 028/766] build: run tests in spec format --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f6a44d5..eab63199 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "cookie-parser": "1.0.1" }, "scripts": { - "test": "mocha --bail --ui bdd --reporter list -- test/*.js" + "test": "mocha --bail --ui bdd --reporter spec -- test/*.js" }, "engines": { "node": ">= 0.8.0" From 5f0e07f76c8ef1f812d3d245672edb6c4835cec8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 13 May 2014 23:09:18 -0400 Subject: [PATCH 029/766] use on-headers instead of patching writeHead --- index.js | 11 +++-------- package.json | 1 + 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index b5b64656..4d057fa0 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ */ var uid = require('uid2') + , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') , parse = require('url').parse , signature = require('cookie-signature') @@ -125,11 +126,9 @@ function session(options){ } // set-cookie - var writeHead = res.writeHead; - res.writeHead = function(){ + onHeaders(res, function(){ if (!req.session) { debug('no session'); - writeHead.apply(res, arguments); return; } @@ -141,7 +140,6 @@ function session(options){ // only send secure cookies via https if (cookie.secure && !tls) { debug('not secured'); - writeHead.apply(res, arguments); return; } @@ -152,13 +150,11 @@ function session(options){ if (null == cookie.expires) { if (!isNew) { debug('already set browser-session cookie'); - writeHead.apply(res, arguments); return } // compare hashes and ids } else if (originalHash == hash(req.session) && originalId == req.session.id) { debug('unmodified session'); - writeHead.apply(res, arguments); return } @@ -167,8 +163,7 @@ function session(options){ var val = 's:' + signature.sign(req.sessionID, secret); debug('set-cookie %s', val); res.cookie(name, val, cookie.data); - writeHead.apply(res, arguments); - }; + }); // proxy end() to commit the session var end = res.end; diff --git a/package.json b/package.json index eab63199..b6367894 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "utils-merge": "1.0.0", "cookie": "0.1.2", "cookie-signature": "1.0.3", + "on-headers": "0.0.0", "uid2": "0.0.3", "buffer-crc32": "0.2.1", "debug": "0.8.1" From 179e3689802a30e3d89f93f117087a7721b616b3 Mon Sep 17 00:00:00 2001 From: Ryan Seys Date: Wed, 14 May 2014 10:43:34 -0700 Subject: [PATCH 030/766] docs: fix typos in example closes #36 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd543157..e79f7e87 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ Please note that `secure: true` is a **recommended** option. However, it require If for development or other reasons security is not a concern, just use: ```js -app.use(connect.cookieParser()) -app.use(connect.session({ +app.use(cookieParser()) +app.use(session({ secret: 'keyboard cat' , key: 'sid' , proxy: true // if you do SSL outside of node. From 198ad7ae1acc95e43cd10184d29a6c34a19601ec Mon Sep 17 00:00:00 2001 From: thepumpkin1979 Date: Fri, 16 May 2014 22:59:20 -0500 Subject: [PATCH 031/766] docs: replace use of 'key' with 'name' closes #37 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e79f7e87..605200e0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ var session = require('express-session') var app = express() app.use(cookieParser()) // required before session. -app.use(session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) +app.use(session({ secret: 'keyboard cat', name: 'sid', cookie: { secure: true }})) ``` @@ -26,7 +26,7 @@ middleware _before_ `session()`. #### Options - - `name` - cookie name. (default: `connect.sid`) + - `name` - cookie name (formerly known as `key`). (default: `connect.sid`) - `store` - session store instance. - `secret` - session cookie is signed with this secret to prevent tampering. - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) @@ -44,7 +44,7 @@ If for development or other reasons security is not a concern, just use: app.use(cookieParser()) app.use(session({ secret: 'keyboard cat' - , key: 'sid' + , name: 'sid' , proxy: true // if you do SSL outside of node. })) ``` From 6cc95c9f161ab6f14cab264e196c78d22248404c Mon Sep 17 00:00:00 2001 From: Joe Wagner Date: Sun, 18 May 2014 22:27:29 -0600 Subject: [PATCH 032/766] option to prevent session save when unmodified fixes #7 closes #38 --- History.md | 5 +++ README.md | 1 + index.js | 29 ++++++++++++---- test/session.js | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 7 deletions(-) diff --git a/History.md b/History.md index c44ab618..a1b4e0b9 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Add `resave` option to control saving unmodified sessions + 1.1.0 / 2014-05-12 ================== diff --git a/README.md b/README.md index 605200e0..a4a8810e 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ middleware _before_ `session()`. - `cookie` - session cookie settings. - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - `rolling` - forces a cookie reset on response. The reset affects the expiration date. (default: `false`) + - `resave` - forces session to be saved even when unmodified. (default: `true`) #### Cookie options diff --git a/index.js b/index.js index 4d057fa0..abfe723d 100644 --- a/index.js +++ b/index.js @@ -72,6 +72,11 @@ function session(options){ , storeReady = true , rollingSessions = options.rolling || false; + // TODO: switch default to false on next major + var resaveSession = options.resave === undefined + ? true + : false; + // notify user that this store is not // meant for a production environment if ('production' == env && store instanceof MemoryStore) { @@ -153,7 +158,7 @@ function session(options){ return } // compare hashes and ids - } else if (originalHash == hash(req.session) && originalId == req.session.id) { + } else if (!isModified(req.session)) { debug('unmodified session'); return } @@ -170,13 +175,18 @@ function session(options){ res.end = function(data, encoding){ res.end = end; if (!req.session) return res.end(data, encoding); - debug('saving'); req.session.resetMaxAge(); - req.session.save(function(err){ - if (err) console.error(err.stack); - debug('saved'); - res.end(data, encoding); - }); + + if (resaveSession || isModified(req.session)) { + debug('saving'); + return req.session.save(function(err){ + if (err) console.error(err.stack); + debug('saved'); + res.end(data, encoding); + }); + } + + res.end(data, encoding); }; // generate the session @@ -184,6 +194,11 @@ function session(options){ store.generate(req); } + // check if session has been modified + function isModified(sess) { + return originalHash != hash(sess) || originalId != sess.id; + } + // get the sessionID from the cookie req.sessionID = unsignedCookie; diff --git a/test/session.js b/test/session.js index 7e05b024..bfdda072 100644 --- a/test/session.js +++ b/test/session.js @@ -113,6 +113,96 @@ describe('session()', function(){ }) }) + describe('resave option', function(){ + it('should default to true', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); + app.use(function(req, res, next){ + var save = req.session.save; + res.setHeader('x-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(200, function(err, res){ + if (err) return done(err); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect('x-count', '2') + .expect(200, done); + }); + }); + + it('should prevent save on unmodified session', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ resave: 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.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(200, function(err, res){ + if (err) return done(err); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect('x-count', '1') + .expect(200, done); + }); + }); + + it('should still save modified session', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ resave: 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(200, function(err, res){ + if (err) return done(err); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect('x-count', '2') + .expect(200, done); + }); + }); + }); + it('should retain the sid', function(done){ var n = 0; From 9b65699799f85fd40635c3eb199446611d3b3405 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 19 May 2014 15:43:51 -0400 Subject: [PATCH 033/766] 1.2.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index a1b4e0b9..50e303b2 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.2.0 / 2014-05-19 +================== * Add `resave` option to control saving unmodified sessions diff --git a/package.json b/package.json index b6367894..f5132684 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.1.0", + "version": "1.2.0", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "main": "./index.js", "repository": { From 135e4cde401e596ea635382d076510b09a735c9c Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Tue, 27 May 2014 10:34:34 -0400 Subject: [PATCH 034/766] readme: clarify options, esp. regarding security. See also: expressjs/csurf#12 --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a4a8810e..9714d47d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,10 @@ var session = require('express-session') var app = express() app.use(cookieParser()) // required before session. -app.use(session({ secret: 'keyboard cat', name: 'sid', cookie: { secure: true }})) +app.use(session({ + secret: 'keyboard cat' + , proxy: true // if you do SSL outside of node. +})) ``` @@ -26,26 +29,27 @@ middleware _before_ `session()`. #### Options - - `name` - cookie name (formerly known as `key`). (default: `connect.sid`) + - `name` - cookie name (formerly known as `key`). (default: `'connect.sid'`) - `store` - session store instance. - `secret` - session cookie is signed with this secret to prevent tampering. - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) - `cookie` - session cookie settings. - - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - - `rolling` - forces a cookie reset on response. The reset affects the expiration date. (default: `false`) + - (default: `{ path: '/', httpOnly: true, secure: (auto detects https), maxAge: null }`) + - `secure` defaults to `true` if the connection is using https. + - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`) #### Cookie options Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. -If for development or other reasons security is not a concern, just use: +If `secure` is not set, `session` will default to it when using https. +For development, or if your SSL is done outside of your node server, use the `proxy` option: ```js app.use(cookieParser()) app.use(session({ secret: 'keyboard cat' - , name: 'sid' , proxy: true // if you do SSL outside of node. })) ``` From 5155bda6740303879d41367a33dd4cf888dd4bb8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 27 May 2014 14:53:38 -0400 Subject: [PATCH 035/766] docs: fix secure documentation closes #43 --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9714d47d..3fa42369 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,7 @@ middleware _before_ `session()`. - `secret` - session cookie is signed with this secret to prevent tampering. - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) - `cookie` - session cookie settings. - - (default: `{ path: '/', httpOnly: true, secure: (auto detects https), maxAge: null }`) - - `secure` defaults to `true` if the connection is using https. + - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`) @@ -43,14 +42,14 @@ middleware _before_ `session()`. #### Cookie options Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. -If `secure` is not set, `session` will default to it when using https. -For development, or if your SSL is done outside of your node server, use the `proxy` option: +If `secure` is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to enable the `proxy` option: ```js app.use(cookieParser()) app.use(session({ secret: 'keyboard cat' , proxy: true // if you do SSL outside of node. + , cookie: { secure: true } })) ``` From 7e7b3a760bc47b93689f330fcc30606d40f3c384 Mon Sep 17 00:00:00 2001 From: Joe Wagner Date: Tue, 27 May 2014 16:04:00 -0600 Subject: [PATCH 036/766] Fix parsing logic around resave option closes #44 --- History.md | 5 +++++ index.js | 2 +- test/session.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 50e303b2..14298513 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix `resave` such that `resave: true` works + 1.2.0 / 2014-05-19 ================== diff --git a/index.js b/index.js index abfe723d..bf311a7f 100644 --- a/index.js +++ b/index.js @@ -75,7 +75,7 @@ function session(options){ // TODO: switch default to false on next major var resaveSession = options.resave === undefined ? true - : false; + : options.resave; // notify user that this store is not // meant for a production environment diff --git a/test/session.js b/test/session.js index bfdda072..738bcce5 100644 --- a/test/session.js +++ b/test/session.js @@ -143,6 +143,35 @@ describe('session()', function(){ }); }); + it('should force save on unmodified session', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ resave: 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.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(200, function(err, res){ + if (err) return done(err); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect('x-count', '2') + .expect(200, done); + }); + }); + it('should prevent save on unmodified session', function(done){ var count = 0; var app = express(); From 5b91d4797073e1c57119de0c9c660712ede8178d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 27 May 2014 18:23:03 -0400 Subject: [PATCH 037/766] deps: update test dependencies --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f5132684..4b29a955 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,11 @@ "debug": "0.8.1" }, "devDependencies": { - "express": "4.0.0", - "mocha": "~1.18.2", + "cookie-parser": "1.1.0", + "express": "~4.3.0", + "mocha": "~1.19.0", "should": "~3.3.1", - "supertest": "~0.12.1", - "cookie-parser": "1.0.1" + "supertest": "~0.13.0" }, "scripts": { "test": "mocha --bail --ui bdd --reporter spec -- test/*.js" From d5cc31327b4d7806653e702f38f743ce39de219c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 27 May 2014 18:23:42 -0400 Subject: [PATCH 038/766] 1.2.1 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 14298513..1c4df081 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.2.1 / 2014-05-27 +================== * Fix `resave` such that `resave: true` works diff --git a/package.json b/package.json index 4b29a955..ed505410 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.2.0", + "version": "1.2.1", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "main": "./index.js", "repository": { From 308b8b2998ae5ec352d256eb3682b501b8bba9fa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 13:01:47 -0400 Subject: [PATCH 039/766] deps: debug@1.0.2 --- History.md | 5 +++++ package.json | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 1c4df081..800536e9 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@1.0.2 + 1.2.1 / 2014-05-27 ================== diff --git a/package.json b/package.json index ed505410..51ea1b58 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ "url": "git://github.com/expressjs/session.git" }, "dependencies": { - "utils-merge": "1.0.0", + "buffer-crc32": "0.2.1", "cookie": "0.1.2", "cookie-signature": "1.0.3", + "debug": "1.0.2", "on-headers": "0.0.0", "uid2": "0.0.3", - "buffer-crc32": "0.2.1", - "debug": "0.8.1" + "utils-merge": "1.0.0" }, "devDependencies": { "cookie-parser": "1.1.0", From 276ff3faba3a08b426c3e8dc72dbdc4955af3c19 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 13:14:54 -0400 Subject: [PATCH 040/766] deps: update testing dependencies --- package.json | 6 ++--- test/session.js | 62 ++++++++++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 51ea1b58..5ee60974 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,9 @@ }, "devDependencies": { "cookie-parser": "1.1.0", - "express": "~4.3.0", - "mocha": "~1.19.0", - "should": "~3.3.1", + "express": "~4.4.0", + "mocha": "~1.20.1", + "should": "~4.0.4", "supertest": "~0.13.0" }, "scripts": { diff --git a/test/session.js b/test/session.js index 738bcce5..0a2f849e 100644 --- a/test/session.js +++ b/test/session.js @@ -13,16 +13,6 @@ function respond(req, res) { res.end(); } -function sid(res) { - var val = res.headers['set-cookie']; - if (!val) return ''; - return /^connect\.sid=([^;]+);/.exec(val[0])[1]; -} - -function expires(res) { - return res.headers['set-cookie'][0].match(/Expires=([^;]+)/)[1]; -} - var app = express() .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) @@ -362,7 +352,7 @@ describe('session()', function(){ .get('/') .set('Cookie', 'connect.sid=' + sid(res)) .end(function(err, res){ - sid(res).should.be.empty; + should(sid(res)).be.empty; res.text.should.equal('2'); modify = true; @@ -447,9 +437,11 @@ describe('session()', function(){ request(app) .get('/') .set('X-Forwarded-Proto', 'https') - .end(function(err, res){ - res.headers['set-cookie'][0].should.not.include('HttpOnly'); - res.headers['set-cookie'][0].should.include('Secure'); + .expect(200, function(err, res){ + if (err) return done(err); + var val = cookie(res); + should(val).not.containEql('HttpOnly'); + should(val).containEql('Secure'); done(); }); }) @@ -464,9 +456,10 @@ describe('session()', function(){ request(app) .get('/admin') - .end(function(err, res){ - var cookie = res.headers['set-cookie'][0]; - cookie.should.not.include('Expires'); + .expect(200, function(err, res){ + if (err) return done(err); + var val = cookie(res); + should(val).not.containEql('Expires'); done(); }); }) @@ -505,12 +498,13 @@ describe('session()', function(){ request(app) .get('/admin') - .end(function(err, res){ - var cookie = res.headers['set-cookie'][0]; - cookie.should.not.include('HttpOnly'); - cookie.should.not.include('Secure'); - cookie.should.include('Path=/admin'); - cookie.should.include('Expires'); + .expect(200, function(err, res){ + if (err) return done(err); + var val = cookie(res); + should(val).not.containEql('HttpOnly'); + should(val).not.containEql('Secure'); + should(val).containEql('Path=/admin'); + should(val).containEql('Expires'); done(); }); }) @@ -746,8 +740,10 @@ describe('session()', function(){ request(app) .get('/') - .end(function(err, res){ - res.headers['set-cookie'][0].should.not.include('Expires='); + .expect(200, function(err, res){ + if (err) return done(err); + var val = cookie(res); + should(val).not.containEql('Expires='); done(); }); }) @@ -779,6 +775,20 @@ describe('session()', function(){ }); }); }) - }) }) + +function cookie(res) { + var setCookie = res.headers['set-cookie']; + return (setCookie && setCookie[0]) || undefined; +} + +function expires(res) { + var match = /Expires=([^;]+)/.exec(cookie(res)); + return match ? match[1] : undefined; +} + +function sid(res) { + var match = /^connect\.sid=([^;]+);/.exec(cookie(res)); + return match ? match[1] : undefined; +} From 7f9a193a74c03988e2cb2fd10541703da5c8b1c5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 13:17:04 -0400 Subject: [PATCH 041/766] build: fix name in comment --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index bf311a7f..aceec0eb 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ /*! - * Connect - session + * express-session * Copyright(c) 2010 Sencha Inc. * Copyright(c) 2011 TJ Holowaychuk * MIT Licensed From 34de96aa1640ad33e0f69e4a0677d823d871407a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 13:17:57 -0400 Subject: [PATCH 042/766] build: use compact formats in package --- package.json | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 5ee60974..4d0443e8 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,8 @@ "name": "express-session", "version": "1.2.1", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", - "main": "./index.js", - "repository": { - "type": "git", - "url": "git://github.com/expressjs/session.git" - }, + "repository": "expressjs/session", + "license": "MIT", "dependencies": { "buffer-crc32": "0.2.1", "cookie": "0.1.2", @@ -23,11 +20,10 @@ "should": "~4.0.4", "supertest": "~0.13.0" }, - "scripts": { - "test": "mocha --bail --ui bdd --reporter spec -- test/*.js" - }, "engines": { "node": ">= 0.8.0" }, - "license": "MIT" + "scripts": { + "test": "mocha --bail --ui bdd --reporter spec -- test/*.js" + } } From 7d5b00c0f0af50ed24cb22ab104f798bc64d1774 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 13:59:24 -0400 Subject: [PATCH 043/766] docs: move badges --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3fa42369..8ea2c587 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! -# express-session [![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) [![NPM Version](https://badge.fury.io/js/express-session.svg)](https://badge.fury.io/js/express-session) +# express-session + +[![NPM Version](https://badge.fury.io/js/express-session.svg)](https://badge.fury.io/js/express-session) +[![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) ## API From f32472bc58d15cc0f608f32787e048d7d190582f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 14:00:07 -0400 Subject: [PATCH 044/766] docs: move maintainer note --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ea2c587..583a2482 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! - # express-session [![NPM Version](https://badge.fury.io/js/express-session.svg)](https://badge.fury.io/js/express-session) [![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) +THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! + ## API ```js From f09254573355ffafeba7dc85a43245e9db0b0d11 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 14:03:23 -0400 Subject: [PATCH 045/766] build: test coverage with istanbul --- .gitignore | 2 ++ .npmignore | 3 ++- .travis.yml | 1 + package.json | 5 ++++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3c3629e6..df9af16b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ +coverage node_modules +npm-debug.log diff --git a/.npmignore b/.npmignore index cefaa67a..cd39b772 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,3 @@ +coverage/ test/ -.travis.yml \ No newline at end of file +.travis.yml diff --git a/.travis.yml b/.travis.yml index 65cf4bc2..bb47c1b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,3 +7,4 @@ matrix: allow_failures: - node_js: "0.11" fast_finish: true +script: "npm run-script test-travis" diff --git a/package.json b/package.json index 4d0443e8..4173c127 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "devDependencies": { "cookie-parser": "1.1.0", + "istanbul": "0.2.10", "express": "~4.4.0", "mocha": "~1.20.1", "should": "~4.0.4", @@ -24,6 +25,8 @@ "node": ">= 0.8.0" }, "scripts": { - "test": "mocha --bail --ui bdd --reporter spec -- test/*.js" + "test": "mocha --bail --reporter spec test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/" } } From ca999cd425ab9dfc0eff2f426f596079c43ec2bc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 14:20:47 -0400 Subject: [PATCH 046/766] Integrate with express "trust proxy" by default closes #48 --- History.md | 1 + README.md | 30 +++++++++++++----- index.js | 49 +++++++++++++++++++++++++---- test/session.js | 82 +++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 143 insertions(+), 19 deletions(-) diff --git a/History.md b/History.md index 800536e9..3e15d813 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Integrate with express "trust proxy" by default * deps: debug@1.0.2 1.2.1 / 2014-05-27 diff --git a/README.md b/README.md index 583a2482..2905768c 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,7 @@ var session = require('express-session') var app = express() app.use(cookieParser()) // required before session. -app.use(session({ - secret: 'keyboard cat' - , proxy: true // if you do SSL outside of node. -})) +app.use(session({secret: 'keyboard cat'})) ``` @@ -35,27 +32,46 @@ middleware _before_ `session()`. - `name` - cookie name (formerly known as `key`). (default: `'connect.sid'`) - `store` - session store instance. - `secret` - session cookie is signed with this secret to prevent tampering. - - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto"). (default: `false`) - `cookie` - session cookie settings. - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`) + - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) #### Cookie options Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. -If `secure` is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to enable the `proxy` option: +If `secure` is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set "trust proxy" in express: ```js +var app = express() +app.set('trust proxy', 1) // trust first proxy app.use(cookieParser()) app.use(session({ secret: 'keyboard cat' - , proxy: true // if you do SSL outside of node. , cookie: { secure: true } })) ``` +For using secure cookies in production, but allowing for testing in development, the following is an example of enabling this setup based on `NODE_ENV` in express: + +```js +var app = express() +var sess = { + secret: 'keyboard cat' + cookie: {} +} + +if (app.get('env') === 'production') { + app.set('trust proxy', 1) // trust first proxy + sess.cookie.secure = true // serve secure cookies +} + +app.use(cookieParser()) +app.use(session(sess)) +``` + By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set so the cookie becomes a browser-session cookie. When the user closes the browser the cookie (and session) will be removed. diff --git a/index.js b/index.js index aceec0eb..d48bcd12 100644 --- a/index.js +++ b/index.js @@ -68,7 +68,7 @@ function session(options){ , name = options.name || options.key || 'connect.sid' , store = options.store || new MemoryStore , cookie = options.cookie || {} - , trustProxy = options.proxy || false + , trustProxy = options.proxy , storeReady = true , rollingSessions = options.rolling || false; @@ -137,17 +137,16 @@ function session(options){ return; } - var cookie = req.session.cookie - , proto = (req.headers['x-forwarded-proto'] || '').split(',')[0].toLowerCase().trim() - , tls = req.connection.encrypted || (trustProxy && 'https' == proto) - , isNew = unsignedCookie != req.sessionID; + var cookie = req.session.cookie; // only send secure cookies via https - if (cookie.secure && !tls) { + if (cookie.secure && !issecure(req, trustProxy)) { debug('not secured'); return; } + var isNew = unsignedCookie != req.sessionID; + // in case of rolling session, always reset the cookie if (!rollingSessions) { @@ -252,3 +251,41 @@ function hash(sess) { if ('cookie' != key) return val; })); } + +/** + * Determine if request is secure. + * + * @param {Object} req + * @param {Boolean} [trustProxy] + * @return {Boolean} + * @api private + */ + +function issecure(req, trustProxy) { + // socket is https server + if (req.connection && req.connection.encrypted) { + return true; + } + + // do not trust proxy + if (trustProxy === false) { + return false; + } + + // no explicit trust; try req.secure from express + if (trustProxy !== true) { + var secure = req.secure; + return typeof secure === 'boolean' + ? secure + : false; + } + + // read the proto from x-forwarded-proto header + var header = req.headers['x-forwarded-proto'] || ''; + var index = header.indexOf(','); + var proto = index !== -1 + ? header.substr(0, index).toLowerCase().trim() + : header.toLowerCase().trim() + + return proto === 'https'; +} diff --git a/test/session.js b/test/session.js index 0a2f849e..54622bf2 100644 --- a/test/session.js +++ b/test/session.js @@ -36,8 +36,9 @@ describe('session()', function(){ request(app) .get('/') .set('X-Forwarded-Proto', 'https') - .end(function(err, res){ - res.headers.should.have.property('set-cookie'); + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).not.be.empty; done(); }); }) @@ -51,14 +52,65 @@ describe('session()', function(){ request(app) .get('/') .set('X-Forwarded-Proto', 'https,http') - .end(function(err, res){ - res.headers.should.have.property('set-cookie'); + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).not.be.empty; + done(); + }); + }) + + it('should work when no header', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) + .use(respond); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; done(); }); }) }) describe('when disabled', function(){ + it('should not trust X-Forwarded-Proto', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', proxy: false, cookie: { secure: true, maxAge: min }})) + .use(respond); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; + done(); + }); + }) + + it('should ignore req.secure from express', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', proxy: false, cookie: { secure: true, maxAge: min }})) + .use(function(req, res) { res.json(req.secure); }); + app.enable('trust proxy'); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(200, 'true', function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; + done(); + }); + }) + }) + + describe('when unspecified', function(){ it('should not trust X-Forwarded-Proto', function(done){ var app = express() .use(cookieParser()) @@ -68,8 +120,26 @@ describe('session()', function(){ request(app) .get('/') .set('X-Forwarded-Proto', 'https') - .end(function(err, res){ - res.headers.should.not.have.property('set-cookie'); + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; + done(); + }); + }) + + it('should use req.secure from express', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) + .use(function(req, res) { res.json(req.secure); }); + app.enable('trust proxy'); + + request(app) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(200, 'true', function(err, res){ + if (err) return done(err); + should(cookie(res)).not.be.empty; done(); }); }) From c08fd27294f786b642ce5c6d1274aee504c3f95a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 14:28:51 -0400 Subject: [PATCH 047/766] 1.3.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 3e15d813..4aaf1bad 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.3.0 / 2014-06-14 +================== * Integrate with express "trust proxy" by default * deps: debug@1.0.2 diff --git a/package.json b/package.json index 4173c127..9f62ecf3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.2.1", + "version": "1.3.0", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "repository": "expressjs/session", "license": "MIT", From 289dcd1fcd4a29756e47c858ad341caa9a39c6b3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 14:40:02 -0400 Subject: [PATCH 048/766] build: add description in package --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 9f62ecf3..6c29667e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "express-session", "version": "1.3.0", + "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "repository": "expressjs/session", "license": "MIT", From d5ad47c18838824531f8c6891d220b559b37e390 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jun 2014 14:40:41 -0400 Subject: [PATCH 049/766] 1.3.1 --- History.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 4aaf1bad..df529d24 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +1.3.1 / 2014-06-14 +================== + + * Add description in package for npmjs.org listing + 1.3.0 / 2014-06-14 ================== diff --git a/package.json b/package.json index 6c29667e..df44c60a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.3.0", + "version": "1.3.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "repository": "expressjs/session", From a9e92c1c480f103d468ac2ceaa595addc3cafaf9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 18:25:47 -0400 Subject: [PATCH 050/766] deps: buffer-crc32@0.2.3 --- History.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index df529d24..6bb28a38 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: buffer-crc32@0.2.3 + 1.3.1 / 2014-06-14 ================== diff --git a/package.json b/package.json index df44c60a..a29c1b47 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "buffer-crc32": "0.2.1", + "buffer-crc32": "0.2.3", "cookie": "0.1.2", "cookie-signature": "1.0.3", "debug": "1.0.2", From 0c6e45cc0c954e8f94e0f3316f603e90b2d239d9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 18:39:46 -0400 Subject: [PATCH 051/766] tests: add a couple more tests --- test/session.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/session.js b/test/session.js index 54622bf2..402a88ca 100644 --- a/test/session.js +++ b/test/session.js @@ -25,6 +25,46 @@ describe('session()', function(){ session.MemoryStore.should.be.a.Function; }) + it('should do nothing if req.session exists', function(done){ + var app = express() + .use(function(req, res, next){ req.session = {}; next(); }) + .use(cookieParser()) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(respond); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; + done(); + }); + }) + + it('should error without secret', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ cookie: { maxAge: min }})) + .use(respond); + app.set('env', 'test'); + + request(app) + .get('/') + .expect(500, /secret.*required/, done); + }) + + it('should reqd secret from req.secret', function(done){ + var app = express() + .use(cookieParser('keyboard cat')) + .use(session({ cookie: { maxAge: min }})) + .use(respond); + app.set('env', 'test'); + + request(app) + .get('/') + .expect(200, done); + }) + describe('proxy option', function(){ describe('when enabled', function(){ it('should trust X-Forwarded-Proto when string', function(done){ From 0b29e29ab9384205ba9cd6e39bfae1b682233a6e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 20:23:32 -0400 Subject: [PATCH 052/766] tests: add basic test for rolling option --- test/session.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/test/session.js b/test/session.js index 402a88ca..5528e777 100644 --- a/test/session.js +++ b/test/session.js @@ -53,7 +53,7 @@ describe('session()', function(){ .expect(500, /secret.*required/, done); }) - it('should reqd secret from req.secret', function(done){ + it('should get secret from req.secret', function(done){ var app = express() .use(cookieParser('keyboard cat')) .use(session({ cookie: { maxAge: min }})) @@ -213,6 +213,60 @@ describe('session()', function(){ }) }) + describe('rolling option', function(){ + it('should default to false', function(done){ + var app = express(); + app.use(cookieParser()); + 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(); + }); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).not.be.empty; + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; + done(); + }); + }); + }); + + it('should force cookie on unmodified session', function(done){ + var app = express(); + app.use(cookieParser()); + 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(); + }); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).not.be.empty; + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).not.be.empty; + done(); + }); + }); + }); + }); + describe('resave option', function(){ it('should default to true', function(done){ var count = 0; From 5567e1d1130ce8c7255349dbfa3370f73964ef86 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 20:37:16 -0400 Subject: [PATCH 053/766] Add option to control saving uninitialized sessions to storage closes #8 closes #45 --- History.md | 1 + README.md | 1 + index.js | 46 ++++++++++++++---------- test/session.js | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 18 deletions(-) diff --git a/History.md b/History.md index 6bb28a38..bb8862e9 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Add `saveUninitialized` option to control saving uninitialized sessions * deps: buffer-crc32@0.2.3 1.3.1 / 2014-06-14 diff --git a/README.md b/README.md index 2905768c..b65816ec 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ middleware _before_ `session()`. - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) + - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. This is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. (default: `true`) #### Cookie options diff --git a/index.js b/index.js index d48bcd12..95bdee18 100644 --- a/index.js +++ b/index.js @@ -77,6 +77,10 @@ function session(options){ ? true : options.resave; + var saveUninitializedSession = options.saveUninitialized === undefined + ? true + : options.saveUninitialized; + // notify user that this store is not // meant for a production environment if ('production' == env && store instanceof MemoryStore) { @@ -145,23 +149,8 @@ function session(options){ return; } - var isNew = unsignedCookie != req.sessionID; - - // in case of rolling session, always reset the cookie - if (!rollingSessions) { - - // browser-session length cookie - if (null == cookie.expires) { - if (!isNew) { - debug('already set browser-session cookie'); - return - } - // compare hashes and ids - } else if (!isModified(req.session)) { - debug('unmodified session'); - return - } - + if (!shouldSetCookie(req)) { + return; } var val = 's:' + signature.sign(req.sessionID, secret); @@ -176,7 +165,7 @@ function session(options){ if (!req.session) return res.end(data, encoding); req.session.resetMaxAge(); - if (resaveSession || isModified(req.session)) { + if (shouldSave(req)) { debug('saving'); return req.session.save(function(err){ if (err) console.error(err.stack); @@ -191,6 +180,8 @@ function session(options){ // generate the session function generate() { store.generate(req); + originalId = req.sessionID; + originalHash = hash(req.session); } // check if session has been modified @@ -198,6 +189,25 @@ function session(options){ return originalHash != hash(sess) || originalId != sess.id; } + // determine if session should be saved to store + function shouldSave(req) { + return unsignedCookie != req.sessionID + ? saveUninitializedSession || isModified(req.session) + : resaveSession || isModified(req.session); + } + + // determine if cookie should be set on response + function shouldSetCookie(req) { + // in case of rolling session, always reset the cookie + if (rollingSessions) { + return true; + } + + return unsignedCookie != req.sessionID + ? saveUninitializedSession || isModified(req.session) + : req.session.cookie.expires != null && isModified(req.session); + } + // get the sessionID from the cookie req.sessionID = unsignedCookie; diff --git a/test/session.js b/test/session.js index 5528e777..bc3f0368 100644 --- a/test/session.js +++ b/test/session.js @@ -386,6 +386,101 @@ describe('session()', function(){ }); }); + describe('saveUninitialized option', function(){ + it('should default to true', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ 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('set-cookie', /connect\.sid=/) + .expect(200, done); + }); + + it('should force save of uninitialized session', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ 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('set-cookie', /connect\.sid=/) + .expect(200, done); + }); + + it('should prevent save of uninitialized session', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ 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(200, function(err, res){ + if (err) return done(err); + should(cookie(res)).be.empty; + done(); + }); + }); + + it('should still save modified session', function(done){ + var count = 0; + var app = express(); + app.use(cookieParser()); + app.use(session({ 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('set-cookie', /connect\.sid=/) + .expect(200, done); + }); + }); + it('should retain the sid', function(done){ var n = 0; From 383a94693dbe2e26acb40eb159e7b0ce13933598 Mon Sep 17 00:00:00 2001 From: Joe Wagner Date: Tue, 17 Jun 2014 15:55:21 -0600 Subject: [PATCH 054/766] Add option to destroy session on req.session unset closes #6 closes #50 --- History.md | 1 + README.md | 1 + index.js | 30 ++++++++++++++- test/session.js | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index bb8862e9..f514c1b9 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,7 @@ unreleased ========== * Add `saveUninitialized` option to control saving uninitialized sessions + * Add `unset` option to control unsetting `req.session` * deps: buffer-crc32@0.2.3 1.3.1 / 2014-06-14 diff --git a/README.md b/README.md index b65816ec..3bb68e86 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ middleware _before_ `session()`. - `resave` - forces session to be saved even when unmodified. (default: `true`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. This is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. (default: `true`) + - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) #### Cookie options diff --git a/index.js b/index.js index 95bdee18..db20d65c 100644 --- a/index.js +++ b/index.js @@ -81,6 +81,13 @@ function session(options){ ? true : options.saveUninitialized; + if (options.unset && options.unset !== 'destroy' && options.unset !== 'keep') { + throw new TypeError('unset option must be "destroy" or "keep"'); + } + + // TODO: switch to "destroy" on next major + var unsetDestroy = options.unset === 'destroy'; + // notify user that this store is not // meant for a production environment if ('production' == env && store instanceof MemoryStore) { @@ -162,7 +169,23 @@ function session(options){ var end = res.end; res.end = function(data, encoding){ res.end = end; - if (!req.session) return res.end(data, encoding); + + if (shouldDestroy(req)) { + // destroy session + debug('destroying'); + store.destroy(req.sessionID, function(err){ + if (err) console.error(err.stack); + debug('destroyed'); + res.end(data, encoding); + }); + } + + // no session to save + if (!req.session) { + debug('no session'); + return res.end(data, encoding); + } + req.session.resetMaxAge(); if (shouldSave(req)) { @@ -189,6 +212,11 @@ function session(options){ return originalHash != hash(sess) || originalId != sess.id; } + // determine if session should be destroyed + function shouldDestroy(req) { + return req.sessionID && unsetDestroy && req.session == null; + } + // determine if session should be saved to store function shouldSave(req) { return unsignedCookie != req.sessionID diff --git a/test/session.js b/test/session.js index bc3f0368..78e52517 100644 --- a/test/session.js +++ b/test/session.js @@ -481,6 +481,103 @@ describe('session()', function(){ }); }); + describe('unset option', function () { + it('should reject unknown values', function(){ + session.bind(null, { unset: 'bogus!' }).should.throw(/unset.*must/); + }); + + it('should default to keep', function(done){ + var store = new session.MemoryStore(); + var app = express() + .use(cookieParser()) + .use(session({ store: store, secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.count = req.session.count || 0; + req.session.count++; + if (req.session.count === 2) req.session = null; + res.end(); + }); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + store.length(function(err, len){ + if (err) return done(err); + len.should.equal(1); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect(200, function(err, res){ + if (err) return done(err); + store.length(function(err, len){ + if (err) return done(err); + len.should.equal(1); + done(); + }); + }); + }); + }); + }); + + it('should allow destroy on req.session = null', function(done){ + var store = new session.MemoryStore(); + var app = express() + .use(cookieParser()) + .use(session({ store: store, unset: 'destroy', secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.count = req.session.count || 0; + req.session.count++; + if (req.session.count === 2) req.session = null; + res.end(); + }); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + store.length(function(err, len){ + if (err) return done(err); + len.should.equal(1); + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .expect(200, function(err, res){ + if (err) return done(err); + store.length(function(err, len){ + if (err) return done(err); + len.should.equal(0); + done(); + }); + }); + }); + }); + }); + + it('should not set cookie if initial session destroyed', function(done){ + var store = new session.MemoryStore(); + var app = express() + .use(cookieParser()) + .use(session({ store: store, unset: 'destroy', secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session = null; + res.end(); + }); + + request(app) + .get('/') + .expect(200, function(err, res){ + if (err) return done(err); + store.length(function(err, len){ + if (err) return done(err); + len.should.equal(0); + should(cookie(res)).be.empty; + done(); + }); + }); + }); + }); + it('should retain the sid', function(done){ var n = 0; From 5fc7b090c9256e9362f7973f019c3bae3e8d2a29 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 21:34:10 -0400 Subject: [PATCH 055/766] Clean up of MemoryStore --- session/memory.js | 62 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/session/memory.js b/session/memory.js index 9720b061..6555bd36 100644 --- a/session/memory.js +++ b/session/memory.js @@ -16,9 +16,10 @@ var Store = require('./store'); * Shim setImmediate for node.js < 0.10 */ -var asyncTick = typeof setImmediate === 'function' +/* istanbul ignore next */ +var defer = typeof setImmediate === 'function' ? setImmediate - : process.nextTick; + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } /** * Initialize a new `MemoryStore`. @@ -46,23 +47,25 @@ MemoryStore.prototype.__proto__ = Store.prototype; MemoryStore.prototype.get = function(sid, fn){ var self = this; - asyncTick(function(){ - var expires - , sess = self.sessions[sid]; - if (sess) { - sess = JSON.parse(sess); - expires = 'string' == typeof sess.cookie.expires - ? new Date(sess.cookie.expires) - : sess.cookie.expires; - if (!expires || new Date < expires) { - fn(null, sess); - } else { - self.destroy(sid, fn); - } - } else { - fn(); - } - }); + var sess = self.sessions[sid]; + + if (!sess) { + return defer(fn); + } + + // parse + sess = JSON.parse(sess); + + var expires = typeof sess.cookie.expires === 'string' + ? new Date(sess.cookie.expires) + : sess.cookie.expires; + + // destroy expired session + if (expires && expires <= Date.now()) { + return self.destroy(sid, fn); + } + + defer(fn, null, sess); }; /** @@ -75,11 +78,8 @@ MemoryStore.prototype.get = function(sid, fn){ */ MemoryStore.prototype.set = function(sid, sess, fn){ - var self = this; - asyncTick(function(){ - self.sessions[sid] = JSON.stringify(sess); - fn && fn(); - }); + this.sessions[sid] = JSON.stringify(sess); + fn && defer(fn); }; /** @@ -90,11 +90,8 @@ MemoryStore.prototype.set = function(sid, sess, fn){ */ MemoryStore.prototype.destroy = function(sid, fn){ - var self = this; - asyncTick(function(){ - delete self.sessions[sid]; - fn && fn(); - }); + delete this.sessions[sid]; + fn && defer(fn); }; /** @@ -110,7 +107,7 @@ MemoryStore.prototype.all = function(fn){ for (var i = 0, len = keys.length; i < len; ++i) { arr.push(this.sessions[keys[i]]); } - fn(null, arr); + fn && defer(fn); }; /** @@ -122,7 +119,7 @@ MemoryStore.prototype.all = function(fn){ MemoryStore.prototype.clear = function(fn){ this.sessions = {}; - fn && fn(); + fn && defer(fn); }; /** @@ -133,5 +130,6 @@ MemoryStore.prototype.clear = function(fn){ */ MemoryStore.prototype.length = function(fn){ - fn(null, Object.keys(this.sessions).length); + var len = Object.keys(this.sessions).length; + defer(fn, null, len); }; From a8bda70b34abc31fd957321b567855407ee8d607 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 22:22:51 -0400 Subject: [PATCH 056/766] Add genid option to generate custom session IDs closes #47 closes #49 --- History.md | 1 + README.md | 15 +++++++++++++++ index.js | 19 ++++++++++++++++++- test/session.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index f514c1b9..0b568ef9 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Add `genid` option to generate custom session IDs * Add `saveUninitialized` option to control saving uninitialized sessions * Add `unset` option to control unsetting `req.session` * deps: buffer-crc32@0.2.3 diff --git a/README.md b/README.md index 3bb68e86..fa3a64af 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,27 @@ middleware _before_ `session()`. - `secret` - session cookie is signed with this secret to prevent tampering. - `cookie` - session cookie settings. - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) + - `genid` - function to call to generate a new session ID. (default: uses `uid2` library) - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. This is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. (default: `true`) - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) +#### options.genid + +Generate a custom session ID for new sessions. Provide a function that returns a string that will be used as a session ID. The function is given `req` as the first argument if you want to use some value attached to `req` when generating the ID. + +**NOTE** be careful you generate unique IDs so your sessions do not conflict. + +```js +app.use(session({ + genid: function(req) { + return genuuid(); // use UUIDs for session IDs + }, + secret: 'keyboard cat' +})) +``` #### Cookie options diff --git a/index.js b/index.js index db20d65c..cfc7ed3d 100644 --- a/index.js +++ b/index.js @@ -72,6 +72,12 @@ function session(options){ , storeReady = true , rollingSessions = options.rolling || false; + var generateId = options.genid || generateSessionId; + + if (typeof generateId !== 'function') { + throw new TypeError('genid option must be a function'); + } + // TODO: switch default to false on next major var resaveSession = options.resave === undefined ? true @@ -96,7 +102,7 @@ function session(options){ // generates the new session store.generate = function(req){ - req.sessionID = uid(24); + req.sessionID = generateId(req); req.session = new Session(req); req.session.cookie = new Cookie(cookie); }; @@ -276,6 +282,17 @@ function session(options){ }; }; +/** + * Generate a session ID for a new session. + * + * @return {String} + * @api private + */ + +function generateSessionId(sess) { + return uid(24); +} + /** * Hash the given `sess` object omitting changes to `.cookie`. * diff --git a/test/session.js b/test/session.js index 78e52517..0c8ed37f 100644 --- a/test/session.js +++ b/test/session.js @@ -186,6 +186,55 @@ describe('session()', function(){ }) }) + describe('genid option', function(){ + it('should reject non-function values', function(){ + session.bind(null, { genid: 'bogus!' }).should.throw(/genid.*must/); + }); + + it('should provide default generator', function(done){ + request(app) + .get('/') + .expect('set-cookie', /connect\.sid=s%3A([^\.]{24})\./i) + .expect(200, done); + }); + + it('should allow custom function', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ genid: function(){ return 'a' }, secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(respond); + + request(app) + .get('/') + .expect('set-cookie', /connect\.sid=s%3Aa\./i) + .expect(200, done); + }); + + it('should encode unsafe chars', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ genid: function(){ return '%' }, secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(respond); + + request(app) + .get('/') + .expect('set-cookie', /connect\.sid=s%3A%25\./i) + .expect(200, done); + }); + + it('should provide req argument', function(done){ + var app = express() + .use(cookieParser()) + .use(session({ genid: function(req){ return req.url }, secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(respond); + + request(app) + .get('/foo') + .expect('set-cookie', /connect\.sid=s%3A%2Ffoo\./i) + .expect(200, done); + }); + }); + describe('key option', function(){ it('should default to "connect.sid"', function(done){ request(app) From 2a1f96ff399ce7d809c02f63b9f49c5473ccd7b4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 22:29:51 -0400 Subject: [PATCH 057/766] build: add coverage reporting --- .travis.yml | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index bb47c1b0..1ff243c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,3 +8,4 @@ matrix: - node_js: "0.11" fast_finish: true script: "npm run-script test-travis" +after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/README.md b/README.md index fa3a64af..5e7a6095 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![NPM Version](https://badge.fury.io/js/express-session.svg)](https://badge.fury.io/js/express-session) [![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) +[![Coverage Status](https://img.shields.io/coveralls/expressjs/session.svg?branch=master)](https://coveralls.io/r/expressjs/session) THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! From 44af16635dc51cf78b839d643d370b58b2b6fe8a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 22:32:28 -0400 Subject: [PATCH 058/766] build: update package contributors --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index a29c1b47..f9969da0 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "version": "1.3.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", + "contributors": [ + "Douglas Christopher Wilson ", + "Joe Wagner " + ], "repository": "expressjs/session", "license": "MIT", "dependencies": { From 380f0b7e3059742719f42c69ec7e863d71a52406 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 22:42:55 -0400 Subject: [PATCH 059/766] Generate session IDs with rand-token by default closes #49 --- History.md | 1 + index.js | 2 +- package.json | 2 +- test/session.js | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 0b568ef9..a9f9c06b 100644 --- a/History.md +++ b/History.md @@ -4,6 +4,7 @@ unreleased * Add `genid` option to generate custom session IDs * Add `saveUninitialized` option to control saving uninitialized sessions * Add `unset` option to control unsetting `req.session` + * Generate session IDs with `rand-token` by default; reduce collisions * deps: buffer-crc32@0.2.3 1.3.1 / 2014-06-14 diff --git a/index.js b/index.js index cfc7ed3d..21c3887b 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ * Module dependencies. */ -var uid = require('uid2') +var uid = require('rand-token').suid , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') , parse = require('url').parse diff --git a/package.json b/package.json index f9969da0..632712cd 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "cookie-signature": "1.0.3", "debug": "1.0.2", "on-headers": "0.0.0", - "uid2": "0.0.3", + "rand-token": "0.2.1", "utils-merge": "1.0.0" }, "devDependencies": { diff --git a/test/session.js b/test/session.js index 0c8ed37f..ec572e6d 100644 --- a/test/session.js +++ b/test/session.js @@ -194,7 +194,7 @@ describe('session()', function(){ it('should provide default generator', function(done){ request(app) .get('/') - .expect('set-cookie', /connect\.sid=s%3A([^\.]{24})\./i) + .expect('set-cookie', /connect\.sid=s%3A([^\.]+)\./i) .expect(200, done); }); From 54ff0efb05e2ef54186502c4786da66c6fd4c8c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Jun 2014 22:58:29 -0400 Subject: [PATCH 060/766] 1.4.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index a9f9c06b..640c4c65 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.4.0 / 2014-06-17 +================== * Add `genid` option to generate custom session IDs * Add `saveUninitialized` option to control saving uninitialized sessions diff --git a/package.json b/package.json index 632712cd..bfe94741 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.3.1", + "version": "1.4.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 27160a9468711f1955d7dcc779beda54b38bdf57 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:02:21 -0400 Subject: [PATCH 061/766] Generate session IDs with uid-safe closes #51 --- History.md | 5 +++++ index.js | 2 +- package.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/History.md b/History.md index 640c4c65..bca88b61 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Generate session IDs with `uid-safe`, faster and even less collisions + 1.4.0 / 2014-06-17 ================== diff --git a/index.js b/index.js index 21c3887b..b7d944e1 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ * Module dependencies. */ -var uid = require('rand-token').suid +var uid = require('uid-safe').sync , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') , parse = require('url').parse diff --git a/package.json b/package.json index bfe94741..7268faa9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "cookie-signature": "1.0.3", "debug": "1.0.2", "on-headers": "0.0.0", - "rand-token": "0.2.1", + "uid-safe": "1.0.1", "utils-merge": "1.0.0" }, "devDependencies": { From 737211b5629cb8eda4672023b99c763a92b3623b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:31:11 -0400 Subject: [PATCH 062/766] Directly read cookies fixes #53 --- History.md | 1 + README.md | 13 +++-------- index.js | 60 ++++++++++++++++++++++++++++++++++++------------- test/session.js | 55 +++++---------------------------------------- 4 files changed, 53 insertions(+), 76 deletions(-) diff --git a/History.md b/History.md index bca88b61..d2fd559a 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Directly read cookies; `cookie-parser` no longer required * Generate session IDs with `uid-safe`, faster and even less collisions 1.4.0 / 2014-06-17 diff --git a/README.md b/README.md index 5e7a6095..fa2bc829 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,11 @@ THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REP ## API ```js -var express = require('express') -var cookieParser = require('cookie-parser') -var session = require('express-session') +var express = require('express') +var session = require('express-session') var app = express() -app.use(cookieParser()) // required before session. app.use(session({secret: 'keyboard cat'})) ``` @@ -24,9 +22,7 @@ app.use(session({secret: 'keyboard cat'})) Setup session store with the given `options`. -Session data is _not_ saved in the cookie itself, however -cookies are used, so we must use the [cookie-parser](https://github.com/expressjs/cookie-parser) -middleware _before_ `session()`. +Session data is _not_ saved in the cookie itself, just the session ID. #### Options @@ -65,7 +61,6 @@ If `secure` is set, and you access your site over HTTP, the cookie will not be s ```js var app = express() app.set('trust proxy', 1) // trust first proxy -app.use(cookieParser()) app.use(session({ secret: 'keyboard cat' , cookie: { secure: true } @@ -86,7 +81,6 @@ if (app.get('env') === 'production') { sess.cookie.secure = true // serve secure cookies } -app.use(cookieParser()) app.use(session(sess)) ``` @@ -101,7 +95,6 @@ which is (generally) serialized as JSON by the store, so nested objects are typically fine. For example below is a user-specific view counter: ```js -app.use(cookieParser()) app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) app.use(function(req, res, next) { diff --git a/index.js b/index.js index b7d944e1..eee2037b 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,7 @@ * Module dependencies. */ +var cookie = require('cookie'); var uid = require('uid-safe').sync , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') @@ -135,17 +136,8 @@ function session(options){ // expose store req.sessionStore = store; - // grab the session cookie value and check the signature - var rawCookie = req.cookies[name]; - - // get signedCookies for backwards compat with signed cookies - var unsignedCookie = req.signedCookies[name]; - - if (!unsignedCookie && rawCookie) { - unsignedCookie = (0 == rawCookie.indexOf('s:')) - ? signature.unsign(rawCookie.slice(2), secret) - : rawCookie; - } + // get the session ID from the cookie + var cookieId = req.sessionID = getcookie(req, name, secret); // set-cookie onHeaders(res, function(){ @@ -225,7 +217,7 @@ function session(options){ // determine if session should be saved to store function shouldSave(req) { - return unsignedCookie != req.sessionID + return cookieId != req.sessionID ? saveUninitializedSession || isModified(req.session) : resaveSession || isModified(req.session); } @@ -237,14 +229,11 @@ function session(options){ return true; } - return unsignedCookie != req.sessionID + return cookieId != req.sessionID ? saveUninitializedSession || isModified(req.session) : req.session.cookie.expires != null && isModified(req.session); } - // get the sessionID from the cookie - req.sessionID = unsignedCookie; - // generate a session if the browser doesn't send a sessionID if (!req.sessionID) { debug('no SID sent, generating session'); @@ -293,6 +282,45 @@ function generateSessionId(sess) { return uid(24); } +/** + * Get the session ID cookie from request. + * + * @return {string} + * @api private + */ + +function getcookie(req, name, secret) { + var header = req.headers.cookie; + var val; + + // read from cookie header + if (header) { + var cookies = cookie.parse(header); + + val = cookies[name]; + + if (val && val.substr(0, 2) === 's:') { + val = signature.unsign(val.slice(2), secret); + } + } + + // back-compat read from cookieParser() signedCookies data + if (!val && req.signedCookies) { + val = req.signedCookies[name]; + } + + // back-compat read from cookieParser() cookies data + if (!val && req.cookies) { + val = req.cookies[name]; + + if (val && val.substr(0, 2) === 's:') { + val = signature.unsign(val.slice(2), secret); + } + } + + return val; +} + /** * Hash the given `sess` object omitting changes to `.cookie`. * diff --git a/test/session.js b/test/session.js index ec572e6d..00ab903b 100644 --- a/test/session.js +++ b/test/session.js @@ -14,7 +14,6 @@ function respond(req, res) { } var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(respond); @@ -28,7 +27,6 @@ describe('session()', function(){ it('should do nothing if req.session exists', function(done){ var app = express() .use(function(req, res, next){ req.session = {}; next(); }) - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(respond); @@ -43,7 +41,6 @@ describe('session()', function(){ it('should error without secret', function(done){ var app = express() - .use(cookieParser()) .use(session({ cookie: { maxAge: min }})) .use(respond); app.set('env', 'test'); @@ -55,21 +52,20 @@ describe('session()', function(){ it('should get secret from req.secret', function(done){ var app = express() - .use(cookieParser('keyboard cat')) + .use(function(req, res, next){ req.secret = 'keyboard cat'; next(); }) .use(session({ cookie: { maxAge: min }})) .use(respond); app.set('env', 'test'); request(app) .get('/') - .expect(200, done); + .expect(200, '', done); }) describe('proxy option', function(){ describe('when enabled', function(){ it('should trust X-Forwarded-Proto when string', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) .use(respond); @@ -85,7 +81,6 @@ describe('session()', function(){ it('should trust X-Forwarded-Proto when comma-separated list', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) .use(respond); @@ -101,7 +96,6 @@ describe('session()', function(){ it('should work when no header', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) .use(respond); @@ -118,7 +112,6 @@ describe('session()', function(){ describe('when disabled', function(){ it('should not trust X-Forwarded-Proto', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: false, cookie: { secure: true, maxAge: min }})) .use(respond); @@ -134,7 +127,6 @@ describe('session()', function(){ it('should ignore req.secure from express', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: false, cookie: { secure: true, maxAge: min }})) .use(function(req, res) { res.json(req.secure); }); app.enable('trust proxy'); @@ -153,7 +145,6 @@ describe('session()', function(){ describe('when unspecified', function(){ it('should not trust X-Forwarded-Proto', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) .use(respond); @@ -169,7 +160,6 @@ describe('session()', function(){ it('should use req.secure from express', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) .use(function(req, res) { res.json(req.secure); }); app.enable('trust proxy'); @@ -200,7 +190,6 @@ describe('session()', function(){ it('should allow custom function', function(done){ var app = express() - .use(cookieParser()) .use(session({ genid: function(){ return 'a' }, secret: 'keyboard cat', cookie: { maxAge: min }})) .use(respond); @@ -212,7 +201,6 @@ describe('session()', function(){ it('should encode unsafe chars', function(done){ var app = express() - .use(cookieParser()) .use(session({ genid: function(){ return '%' }, secret: 'keyboard cat', cookie: { maxAge: min }})) .use(respond); @@ -224,7 +212,6 @@ describe('session()', function(){ it('should provide req argument', function(done){ var app = express() - .use(cookieParser()) .use(session({ genid: function(req){ return req.url }, secret: 'keyboard cat', cookie: { maxAge: min }})) .use(respond); @@ -248,7 +235,6 @@ describe('session()', function(){ it('should allow overriding', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', key: 'sid', cookie: { maxAge: min }})) .use(respond); @@ -265,7 +251,6 @@ describe('session()', function(){ describe('rolling option', function(){ it('should default to false', function(done){ var app = express(); - app.use(cookieParser()); app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -291,7 +276,6 @@ describe('session()', function(){ it('should force cookie on unmodified session', function(done){ var app = express(); - app.use(cookieParser()); app.use(session({ rolling: true, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -320,7 +304,6 @@ describe('session()', function(){ it('should default to true', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -349,7 +332,6 @@ describe('session()', function(){ it('should force save on unmodified session', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ resave: true, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -378,7 +360,6 @@ describe('session()', function(){ it('should prevent save on unmodified session', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ resave: false, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -407,7 +388,6 @@ describe('session()', function(){ it('should still save modified session', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ resave: false, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -439,7 +419,6 @@ describe('session()', function(){ it('should default to true', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -461,7 +440,6 @@ describe('session()', function(){ it('should force save of uninitialized session', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ saveUninitialized: true, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -483,7 +461,6 @@ describe('session()', function(){ it('should prevent save of uninitialized session', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ saveUninitialized: false, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -508,7 +485,6 @@ describe('session()', function(){ it('should still save modified session', function(done){ var count = 0; var app = express(); - app.use(cookieParser()); app.use(session({ saveUninitialized: false, secret: 'keyboard cat', cookie: { maxAge: min }})); app.use(function(req, res, next){ var save = req.session.save; @@ -538,7 +514,6 @@ describe('session()', function(){ it('should default to keep', function(done){ var store = new session.MemoryStore(); var app = express() - .use(cookieParser()) .use(session({ store: store, secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.count = req.session.count || 0; @@ -572,7 +547,6 @@ describe('session()', function(){ it('should allow destroy on req.session = null', function(done){ var store = new session.MemoryStore(); var app = express() - .use(cookieParser()) .use(session({ store: store, unset: 'destroy', secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.count = req.session.count || 0; @@ -606,7 +580,6 @@ describe('session()', function(){ it('should not set cookie if initial session destroyed', function(done){ var store = new session.MemoryStore(); var app = express() - .use(cookieParser()) .use(session({ store: store, unset: 'destroy', secret: 'keyboard cat' })) .use(function(req, res, next){ req.session = null; @@ -631,7 +604,6 @@ describe('session()', function(){ var n = 0; var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res){ req.session.count = ++n; @@ -669,7 +641,6 @@ describe('session()', function(){ var n = 0; var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res){ req.session.count = ++n; @@ -700,7 +671,6 @@ describe('session()', function(){ describe('req.session', function(){ it('should persist', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min, httpOnly: false }})) .use(function(req, res, next){ // checks that cookie options persisted @@ -730,7 +700,6 @@ describe('session()', function(){ var modify = true; var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res, next){ if (modify) { @@ -777,7 +746,6 @@ describe('session()', function(){ describe('.destroy()', function(){ it('should destroy the previous session', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.destroy(function(err){ @@ -799,7 +767,6 @@ describe('session()', function(){ describe('.regenerate()', function(){ it('should destroy/replace the previous session', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) .use(function(req, res, next){ var id = req.session.id; @@ -831,7 +798,6 @@ describe('session()', function(){ describe('.*', function(){ it('should serialize as parameters', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', proxy: true, cookie: { maxAge: min }})) .use(function(req, res, next){ req.session.cookie.httpOnly = false; @@ -853,7 +819,6 @@ describe('session()', function(){ it('should default to a browser-session length cookie', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) .use(function(req, res, next){ res.end(); @@ -871,7 +836,6 @@ describe('session()', function(){ it('should Set-Cookie only once for browser-session cookies', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) .use(function(req, res, next){ res.end(); @@ -894,7 +858,6 @@ describe('session()', function(){ it('should override defaults', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/admin', httpOnly: false, secure: true, maxAge: 5000 }})) .use(function(req, res, next){ req.session.cookie.secure = false; @@ -922,8 +885,7 @@ describe('session()', function(){ } var app = express() - .use(cookieParser('keyboard cat')) - .use(session()) + .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ var cookie = new Cookie(); res.setHeader('Set-Cookie', cookie.serialize('previous', 'cookieValue')); @@ -942,7 +904,6 @@ describe('session()', function(){ describe('.secure', function(){ it('should not set-cookie when insecure', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.cookie.secure = true; @@ -961,7 +922,6 @@ describe('session()', function(){ describe('when the pathname does not match cookie.path', function(){ it('should not set-cookie', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ if (!req.session) { @@ -982,7 +942,6 @@ describe('session()', function(){ it('should not set-cookie even for FQDN', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ if (!req.session) { @@ -1007,7 +966,6 @@ describe('session()', function(){ describe('when the pathname does match cookie.path', function(){ it('should set-cookie', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ req.session.foo = Math.random(); @@ -1024,7 +982,6 @@ describe('session()', function(){ it('should set-cookie even for FQDN', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) .use(function(req, res, next){ req.session.foo = Math.random(); @@ -1045,7 +1002,6 @@ describe('session()', function(){ describe('.maxAge', function(){ var id; var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat', cookie: { maxAge: 2000 }})) .use(function(req, res, next){ req.session.count = req.session.count || 0; @@ -1117,7 +1073,6 @@ describe('session()', function(){ describe('when given a Date', function(){ it('should set absolute', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.cookie.expires = new Date(0); @@ -1136,7 +1091,6 @@ describe('session()', function(){ describe('when null', function(){ it('should be a browser-session cookie', function(done){ var app = express() - .use(cookieParser()) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.cookie.expires = null; @@ -1156,9 +1110,10 @@ describe('session()', function(){ }) }) - it('should support req.signedCookies', function(done){ + it('should support cookieParser()', function(done){ var app = express() .use(cookieParser('keyboard cat')) + .use(function(req, res, next){ delete req.headers.cookie; next(); }) .use(session()) .use(function(req, res, next){ req.session.count = req.session.count || 0; From 931f7c42a093131eaeb227e3e27c3470480756ac Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:35:58 -0400 Subject: [PATCH 063/766] Deprecate looking for secret in req.secret --- History.md | 1 + index.js | 5 +++++ package.json | 1 + test/session.js | 2 ++ 4 files changed, 9 insertions(+) diff --git a/History.md b/History.md index d2fd559a..34857fc9 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Deprecate looking for secret in `req.secret` * Directly read cookies; `cookie-parser` no longer required * Generate session IDs with `uid-safe`, faster and even less collisions diff --git a/index.js b/index.js index eee2037b..d16cbfbb 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ */ var cookie = require('cookie'); +var deprecate = require('depd')('express-session'); var uid = require('uid-safe').sync , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') @@ -127,6 +128,10 @@ function session(options){ // req.secret is passed from the cookie parser middleware var secret = options.secret || req.secret; + if (!options.secret && req.secret) { + deprecate('pass secret option; do not use req.secret'); + } + // ensure secret is available or bail if (!secret) throw new Error('`secret` option required for sessions'); diff --git a/package.json b/package.json index 7268faa9..c447a55a 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.3", "debug": "1.0.2", + "depd": "0.3.0", "on-headers": "0.0.0", "uid-safe": "1.0.1", "utils-merge": "1.0.0" diff --git a/test/session.js b/test/session.js index 00ab903b..42e8cbf3 100644 --- a/test/session.js +++ b/test/session.js @@ -1,4 +1,6 @@ +process.env.NO_DEPRECATION = 'express-session'; + var express = require('express') , assert = require('assert') , request = require('supertest') From e9523cb1df579ef6e87c4aaccb537290bd7c421c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:38:00 -0400 Subject: [PATCH 064/766] Deprecate integration with cookie-parser middleware --- History.md | 1 + index.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/History.md b/History.md index 34857fc9..c3a5a821 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Deprecate integration with `cookie-parser` middleware * Deprecate looking for secret in `req.secret` * Directly read cookies; `cookie-parser` no longer required * Generate session IDs with `uid-safe`, faster and even less collisions diff --git a/index.js b/index.js index d16cbfbb..d09def85 100644 --- a/index.js +++ b/index.js @@ -312,6 +312,10 @@ function getcookie(req, name, secret) { // back-compat read from cookieParser() signedCookies data if (!val && req.signedCookies) { val = req.signedCookies[name]; + + if (val) { + deprecate('cookie should be available in req.headers.cookie'); + } } // back-compat read from cookieParser() cookies data @@ -321,6 +325,10 @@ function getcookie(req, name, secret) { if (val && val.substr(0, 2) === 's:') { val = signature.unsign(val.slice(2), secret); } + + if (val) { + deprecate('cookie should be available in req.headers.cookie'); + } } return val; From 14b876aa43d1fd1f502cd117803cf301b89250ea Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:41:34 -0400 Subject: [PATCH 065/766] test: add additional cookieParser test --- test/session.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/session.js b/test/session.js index 42e8cbf3..cfd3e660 100644 --- a/test/session.js +++ b/test/session.js @@ -1113,6 +1113,32 @@ describe('session()', function(){ }) it('should support cookieParser()', function(done){ + var app = express() + .use(cookieParser()) + .use(function(req, res, next){ delete req.headers.cookie; next(); }) + .use(session({ secret: 'keyboard cat' })) + .use(function(req, res, next){ + req.session.count = req.session.count || 0; + req.session.count++; + res.end(req.session.count.toString()); + }); + + request(app) + .get('/') + .end(function(err, res){ + res.text.should.equal('1'); + + request(app) + .get('/') + .set('Cookie', 'connect.sid=' + sid(res)) + .end(function(err, res){ + res.text.should.equal('2'); + done(); + }); + }); + }) + + it('should support cookieParser(secret)', function(done){ var app = express() .use(cookieParser('keyboard cat')) .use(function(req, res, next){ delete req.headers.cookie; next(); }) From 6563e25f07e0470867c940dc90c25b922d4eae36 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:58:09 -0400 Subject: [PATCH 066/766] Directly set cookies --- History.md | 2 ++ index.js | 20 ++++++++++++++++---- test/session.js | 1 + 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/History.md b/History.md index c3a5a821..79cc12db 100644 --- a/History.md +++ b/History.md @@ -1,9 +1,11 @@ unreleased ========== + * Debug name is now "express-session" * Deprecate integration with `cookie-parser` middleware * Deprecate looking for secret in `req.secret` * Directly read cookies; `cookie-parser` no longer required + * Directly set cookies; `res.cookie` no longer required * Generate session IDs with `uid-safe`, faster and even less collisions 1.4.0 / 2014-06-17 diff --git a/index.js b/index.js index d09def85..33b2b8f5 100644 --- a/index.js +++ b/index.js @@ -10,13 +10,13 @@ */ var cookie = require('cookie'); +var debug = require('debug')('express-session'); var deprecate = require('depd')('express-session'); var uid = require('uid-safe').sync , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') , parse = require('url').parse , signature = require('cookie-signature') - , debug = require('debug')('session') var Session = require('./session/session') , MemoryStore = require('./session/memory') @@ -163,9 +163,7 @@ function session(options){ return; } - var val = 's:' + signature.sign(req.sessionID, secret); - debug('set-cookie %s', val); - res.cookie(name, val, cookie.data); + setcookie(res, name, req.sessionID, secret, cookie.data); }); // proxy end() to commit the session @@ -385,3 +383,17 @@ function issecure(req, trustProxy) { return proto === 'https'; } + +function setcookie(res, name, val, secret, options) { + var signed = 's:' + signature.sign(val, secret); + var data = cookie.serialize(name, signed, options); + + debug('set-cookie %s', data); + + var prev = res.getHeader('set-cookie') || []; + var header = Array.isArray(prev) ? prev.concat(data) + : Array.isArray(data) ? [prev].concat(data) + : [prev, data]; + + res.setHeader('set-cookie', header) +} diff --git a/test/session.js b/test/session.js index cfd3e660..77de17e0 100644 --- a/test/session.js +++ b/test/session.js @@ -621,6 +621,7 @@ describe('session()', function(){ .get('/') .set('Cookie', 'connect.sid=' + id) .end(function(err, res){ + if (err) return done(err); sid(res).should.equal(id); done(); }); From 32d99d097408ad1f060012a098d2c56b18be7ba9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Jun 2014 01:59:05 -0400 Subject: [PATCH 067/766] 1.5.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 79cc12db..cbf990f4 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.5.0 / 2014-06-19 +================== * Debug name is now "express-session" * Deprecate integration with `cookie-parser` middleware diff --git a/package.json b/package.json index c447a55a..b791f558 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.4.0", + "version": "1.5.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 7dd75d0a7ce895c9b55afbdc987b93a4642fd7ee Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Jun 2014 22:01:05 -0400 Subject: [PATCH 068/766] Move hard-to-track-down req.secret deprecation message --- History.md | 5 +++++ index.js | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/History.md b/History.md index cbf990f4..42c87fc4 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Move hard-to-track-down `req.secret` deprecation message + 1.5.0 / 2014-06-19 ================== diff --git a/index.js b/index.js index 33b2b8f5..61f39af2 100644 --- a/index.js +++ b/index.js @@ -112,6 +112,10 @@ function session(options){ store.on('disconnect', function(){ storeReady = false; }); store.on('connect', function(){ storeReady = true; }); + if (!options.secret) { + deprecate('pass secret option; do not use req.secret'); + } + return function session(req, res, next) { // self-awareness if (req.session) return next(); @@ -128,10 +132,6 @@ function session(options){ // req.secret is passed from the cookie parser middleware var secret = options.secret || req.secret; - if (!options.secret && req.secret) { - deprecate('pass secret option; do not use req.secret'); - } - // ensure secret is available or bail if (!secret) throw new Error('`secret` option required for sessions'); From 9e54d152452b9b422d5a2c6f5b0cbd2f476a56c1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Jun 2014 22:02:23 -0400 Subject: [PATCH 069/766] 1.5.1 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 42c87fc4..b700eca5 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.5.1 / 2014-06-21 +================== * Move hard-to-track-down `req.secret` deprecation message diff --git a/package.json b/package.json index b791f558..3f8a6bf6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.5.0", + "version": "1.5.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 3d86d386466a41dfec9c084b08659f7b707975f8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 26 Jun 2014 13:44:54 -0400 Subject: [PATCH 070/766] deps: cookie-signature@1.0.4 --- History.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index b700eca5..e7a160a5 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: cookie-signature@1.0.4 + - fix for timing attacks + 1.5.1 / 2014-06-21 ================== diff --git a/package.json b/package.json index 3f8a6bf6..793196ac 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "buffer-crc32": "0.2.3", "cookie": "0.1.2", - "cookie-signature": "1.0.3", + "cookie-signature": "1.0.4", "debug": "1.0.2", "depd": "0.3.0", "on-headers": "0.0.0", From 392f5e0095b2e3135785f093e5856467e9a74703 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 26 Jun 2014 13:45:45 -0400 Subject: [PATCH 071/766] deps: istanbul@0.2.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 793196ac..ce2423d1 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "cookie-parser": "1.1.0", - "istanbul": "0.2.10", + "istanbul": "0.2.12", "express": "~4.4.0", "mocha": "~1.20.1", "should": "~4.0.4", From 8ac7ea453fb70337a86e70dd25f33cc34e31ca9e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 26 Jun 2014 13:46:50 -0400 Subject: [PATCH 072/766] deps: cookie-parser@1.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce2423d1..42724102 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "utils-merge": "1.0.0" }, "devDependencies": { - "cookie-parser": "1.1.0", + "cookie-parser": "1.3.2", "istanbul": "0.2.12", "express": "~4.4.0", "mocha": "~1.20.1", From dfbc4bd0c9a19023db0f9058236ca89bca818371 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 26 Jun 2014 13:50:44 -0400 Subject: [PATCH 073/766] 1.5.2 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index e7a160a5..9b1e1e0c 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.5.2 / 2014-06-26 +================== * deps: cookie-signature@1.0.4 - fix for timing attacks diff --git a/package.json b/package.json index 42724102..a588271e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.5.1", + "version": "1.5.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 7077190a76cf4bb3fcec3c2a040094901994785f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 11:29:42 -0400 Subject: [PATCH 074/766] Fix res.end patch fixes #55 --- History.md | 6 ++++++ index.js | 25 ++++++++++++++++++------- test/session.js | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/History.md b/History.md index 9b1e1e0c..5677e0b1 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +unreleased +========== + + * Fix `res.end` patch to return correct value + * Fix `res.end` patch to handle multiple `res.end` calls + 1.5.2 / 2014-06-26 ================== diff --git a/index.js b/index.js index 61f39af2..460e3d82 100644 --- a/index.js +++ b/index.js @@ -168,8 +168,17 @@ function session(options){ // proxy end() to commit the session var end = res.end; - res.end = function(data, encoding){ - res.end = end; + var ended = false; + res.end = function(chunk, encoding){ + if (ended) { + return false; + } + + if (chunk === undefined) { + chunk = ''; + } + + ended = true; if (shouldDestroy(req)) { // destroy session @@ -177,28 +186,30 @@ function session(options){ store.destroy(req.sessionID, function(err){ if (err) console.error(err.stack); debug('destroyed'); - res.end(data, encoding); + end.call(res); }); + return res.write(chunk, encoding); } // no session to save if (!req.session) { debug('no session'); - return res.end(data, encoding); + return end.call(res, chunk, encoding); } req.session.resetMaxAge(); if (shouldSave(req)) { debug('saving'); - return req.session.save(function(err){ + req.session.save(function(err){ if (err) console.error(err.stack); debug('saved'); - res.end(data, encoding); + end.call(res); }); + return res.write(chunk, encoding); } - res.end(data, encoding); + return end.call(res, chunk, encoding); }; // generate the session diff --git a/test/session.js b/test/session.js index 77de17e0..afccc42f 100644 --- a/test/session.js +++ b/test/session.js @@ -64,6 +64,22 @@ describe('session()', function(){ .expect(200, '', done); }) + it('should handle multiple res.end calls', function(done){ + var app = express() + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(function(req, res){ + res.setHeader('Content-Type', 'text/plain'); + res.end('Hello, world!'); + res.end(); + }); + app.set('env', 'test'); + + request(app) + .get('/') + .expect('Content-Type', 'text/plain') + .expect(200, 'Hello, world!', done); + }) + describe('proxy option', function(){ describe('when enabled', function(){ it('should trust X-Forwarded-Proto when string', function(done){ From 1b966ed4778acdacf57b1a4cc4ed23d9a709d058 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 11:37:32 -0400 Subject: [PATCH 075/766] Add deprecation message to undefined resave option --- History.md | 1 + index.js | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/History.md b/History.md index 5677e0b1..453e43b9 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ unreleased ========== + * Add deprecation message to undefined `resave` option * Fix `res.end` patch to return correct value * Fix `res.end` patch to handle multiple `res.end` calls diff --git a/index.js b/index.js index 460e3d82..2f6d900b 100644 --- a/index.js +++ b/index.js @@ -73,6 +73,7 @@ function session(options){ , trustProxy = options.proxy , storeReady = true , rollingSessions = options.rolling || false; + var resaveSession = options.resave; var generateId = options.genid || generateSessionId; @@ -80,10 +81,10 @@ function session(options){ throw new TypeError('genid option must be a function'); } - // TODO: switch default to false on next major - var resaveSession = options.resave === undefined - ? true - : options.resave; + if (resaveSession === undefined) { + deprecate('pass resave option; default value will change'); + resaveSession = true; + } var saveUninitializedSession = options.saveUninitialized === undefined ? true From c0363035410cdc5ba8f1a4c37aa28f600015919d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 11:38:00 -0400 Subject: [PATCH 076/766] Add deprecation message to undefined saveUninitialized option closes #54 --- History.md | 1 + index.js | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 453e43b9..3b9079bc 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,7 @@ unreleased ========== * Add deprecation message to undefined `resave` option + * Add deprecation message to undefined `saveUninitialized` option * Fix `res.end` patch to return correct value * Fix `res.end` patch to handle multiple `res.end` calls diff --git a/index.js b/index.js index 2f6d900b..afa61873 100644 --- a/index.js +++ b/index.js @@ -74,6 +74,7 @@ function session(options){ , storeReady = true , rollingSessions = options.rolling || false; var resaveSession = options.resave; + var saveUninitializedSession = options.saveUninitialized; var generateId = options.genid || generateSessionId; @@ -86,9 +87,10 @@ function session(options){ resaveSession = true; } - var saveUninitializedSession = options.saveUninitialized === undefined - ? true - : options.saveUninitialized; + if (saveUninitializedSession === undefined) { + deprecate('pass resave saveUninitialized; default value will change'); + saveUninitializedSession = true; + } if (options.unset && options.unset !== 'destroy' && options.unset !== 'keep') { throw new TypeError('unset option must be "destroy" or "keep"'); From 0488a4014119b0230976065f352d49d3d7e0c2df Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 13:01:55 -0400 Subject: [PATCH 077/766] tests: add more tests --- package.json | 1 + session/memory.js | 26 +++- test/session.js | 389 ++++++++++++++++++++++++++++++---------------- 3 files changed, 280 insertions(+), 136 deletions(-) diff --git a/package.json b/package.json index a588271e..6db6dc77 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "utils-merge": "1.0.0" }, "devDependencies": { + "after": "0.8.1", "cookie-parser": "1.3.2", "istanbul": "0.2.12", "express": "~4.4.0", diff --git a/session/memory.js b/session/memory.js index 6555bd36..4efe99da 100644 --- a/session/memory.js +++ b/session/memory.js @@ -28,7 +28,7 @@ var defer = typeof setImmediate === 'function' */ var MemoryStore = module.exports = function MemoryStore() { - this.sessions = {}; + this.sessions = Object.create(null); }; /** @@ -102,12 +102,28 @@ MemoryStore.prototype.destroy = function(sid, fn){ */ MemoryStore.prototype.all = function(fn){ - var arr = [] - , keys = Object.keys(this.sessions); + var keys = Object.keys(this.sessions); + var now = Date.now(); + var obj = Object.create(null); + var sess; + var sid; + for (var i = 0, len = keys.length; i < len; ++i) { - arr.push(this.sessions[keys[i]]); + sid = keys[i]; + + // parse + sess = JSON.parse(this.sessions[sid]); + + expires = typeof sess.cookie.expires === 'string' + ? new Date(sess.cookie.expires) + : sess.cookie.expires; + + if (!expires || expires > now) { + obj[sid] = sess; + } } - fn && defer(fn); + + fn && defer(fn, null, obj); }; /** diff --git a/test/session.js b/test/session.js index afccc42f..1f210609 100644 --- a/test/session.js +++ b/test/session.js @@ -1,6 +1,7 @@ process.env.NO_DEPRECATION = 'express-session'; +var after = require('after') var express = require('express') , assert = require('assert') , request = require('supertest') @@ -8,17 +9,10 @@ var express = require('express') , cookieParser = require('cookie-parser') , session = require('../') , Cookie = require('../session/cookie') +var http = require('http'); var min = 60 * 1000; -function respond(req, res) { - res.end(); -} - -var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(respond); - describe('session()', function(){ it('should export constructors', function(){ session.Session.should.be.a.Function; @@ -30,7 +24,7 @@ describe('session()', function(){ var app = express() .use(function(req, res, next){ req.session = {}; next(); }) .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(respond); + .use(end); request(app) .get('/') @@ -42,21 +36,16 @@ describe('session()', function(){ }) it('should error without secret', function(done){ - var app = express() - .use(session({ cookie: { maxAge: min }})) - .use(respond); - app.set('env', 'test'); - - request(app) - .get('/') - .expect(500, /secret.*required/, done); + request(createServer({ secret: undefined })) + .get('/') + .expect(500, /secret.*required/, done) }) it('should get secret from req.secret', function(done){ var app = express() .use(function(req, res, next){ req.secret = 'keyboard cat'; next(); }) .use(session({ cookie: { maxAge: min }})) - .use(respond); + .use(end); app.set('env', 'test'); request(app) @@ -64,6 +53,73 @@ describe('session()', function(){ .expect(200, '', done); }) + it('should create a new session', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.active = true + res.end('session active') + }); + + request(server) + .get('/') + .expect(200, 'session active', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + store.length(function (err, len) { + if (err) return done(err) + len.should.equal(1) + done() + }) + }) + }) + + it('should load session from cookie sid', function (done) { + var count = 0 + var server = createServer(null, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }); + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session 1', done) + }) + }) + + it('should create multiple sessions', function (done) { + var cb = after(2, check) + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + var isnew = req.session.num === undefined + req.session.num = req.session.num || ++count + res.end('session ' + (isnew ? 'created' : 'updated')) + }); + + function check(err) { + if (err) return done(err) + store.all(function (err, sess) { + if (err) return done(err) + Object.keys(sess).should.have.length(2) + done() + }) + } + + request(server) + .get('/') + .expect(200, 'session created', cb) + + request(server) + .get('/') + .expect(200, 'session created', cb) + }) + it('should handle multiple res.end calls', function(done){ var app = express() .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) @@ -80,14 +136,145 @@ describe('session()', function(){ .expect(200, 'Hello, world!', done); }) + describe('when sid not in store', function () { + it('should create a new session', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }); + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + store.clear(function (err) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session 2', done) + }) + }) + }) + + it('should have a new sid', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }); + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + var val = sid(res) + should(val).not.be.empty + store.clear(function (err) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session 2', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + should(sid(res)).not.equal(val) + done() + }) + }) + }) + }) + }) + + describe('when session expired in store', function () { + it('should create a new session', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store, cookie: { maxAge: 5 } }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }); + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + setTimeout(function () { + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session 2', done) + }, 10) + }) + }) + + it('should have a new sid', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store, cookie: { maxAge: 5 } }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }); + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + var val = sid(res) + should(val).not.be.empty + setTimeout(function () { + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session 2', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + should(sid(res)).not.equal(val) + done() + }) + }, 10) + }) + }) + + it('should not exist in store', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store, cookie: { maxAge: 5 } }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }); + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + var val = sid(res) + should(val).not.be.empty + setTimeout(function () { + store.all(function (err, sess) { + if (err) return done(err) + Object.keys(sess).should.have.length(0) + done() + }) + }, 10) + }) + }) + }) + describe('proxy option', function(){ describe('when enabled', function(){ - it('should trust X-Forwarded-Proto when string', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) - .use(respond); + var server + before(function () { + server = createServer({ proxy: true, cookie: { secure: true, maxAge: 5 }}) + }) - request(app) + it('should trust X-Forwarded-Proto when string', function(done){ + request(server) .get('/') .set('X-Forwarded-Proto', 'https') .expect(200, function(err, res){ @@ -98,11 +285,7 @@ describe('session()', function(){ }) it('should trust X-Forwarded-Proto when comma-separated list', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) - .use(respond); - - request(app) + request(server) .get('/') .set('X-Forwarded-Proto', 'https,http') .expect(200, function(err, res){ @@ -113,11 +296,7 @@ describe('session()', function(){ }) it('should work when no header', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', proxy: true, cookie: { secure: true, maxAge: 5 }})) - .use(respond); - - request(app) + request(server) .get('/') .expect(200, function(err, res){ if (err) return done(err); @@ -128,12 +307,13 @@ describe('session()', function(){ }) describe('when disabled', function(){ - it('should not trust X-Forwarded-Proto', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', proxy: false, cookie: { secure: true, maxAge: min }})) - .use(respond); + var server + before(function () { + server = createServer({ proxy: false, cookie: { secure: true, maxAge: 5 }}) + }) - request(app) + it('should not trust X-Forwarded-Proto', function(done){ + request(server) .get('/') .set('X-Forwarded-Proto', 'https') .expect(200, function(err, res){ @@ -161,12 +341,13 @@ describe('session()', function(){ }) describe('when unspecified', function(){ - it('should not trust X-Forwarded-Proto', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) - .use(respond); + var server + before(function () { + server = createServer({ cookie: { secure: true, maxAge: 5 }}) + }) - request(app) + it('should not trust X-Forwarded-Proto', function(done){ + request(server) .get('/') .set('X-Forwarded-Proto', 'https') .expect(200, function(err, res){ @@ -200,40 +381,36 @@ describe('session()', function(){ }); it('should provide default generator', function(done){ - request(app) + var server = createServer() + + request(server) .get('/') .expect('set-cookie', /connect\.sid=s%3A([^\.]+)\./i) .expect(200, done); }); it('should allow custom function', function(done){ - var app = express() - .use(session({ genid: function(){ return 'a' }, secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(respond); + var server = createServer({ genid: function(){ return 'a' }}) - request(app) + request(server) .get('/') .expect('set-cookie', /connect\.sid=s%3Aa\./i) .expect(200, done); }); it('should encode unsafe chars', function(done){ - var app = express() - .use(session({ genid: function(){ return '%' }, secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(respond); + var server = createServer({ genid: function(){ return '%' }}) - request(app) + request(server) .get('/') .expect('set-cookie', /connect\.sid=s%3A%25\./i) .expect(200, done); }); it('should provide req argument', function(done){ - var app = express() - .use(session({ genid: function(req){ return req.url }, secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(respond); + var server = createServer({ genid: function(req){ return req.url }}) - request(app) + request(server) .get('/foo') .expect('set-cookie', /connect\.sid=s%3A%2Ffoo\./i) .expect(200, done); @@ -242,7 +419,7 @@ describe('session()', function(){ describe('key option', function(){ it('should default to "connect.sid"', function(done){ - request(app) + request(createServer()) .get('/') .end(function(err, res){ res.headers['set-cookie'].should.have.length(1); @@ -252,11 +429,7 @@ describe('session()', function(){ }) it('should allow overriding', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', key: 'sid', cookie: { maxAge: min }})) - .use(respond); - - request(app) + request(createServer({ key: 'sid' })) .get('/') .end(function(err, res){ res.headers['set-cookie'].should.have.length(1); @@ -618,75 +791,6 @@ describe('session()', function(){ }); }); - it('should retain the sid', function(done){ - var n = 0; - - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(function(req, res){ - req.session.count = ++n; - res.end(); - }) - - request(app) - .get('/') - .end(function(err, res){ - - var id = sid(res); - request(app) - .get('/') - .set('Cookie', 'connect.sid=' + id) - .end(function(err, res){ - if (err) return done(err); - sid(res).should.equal(id); - done(); - }); - }); - }) - - describe('when an invalid sid is given', function(){ - it('should generate a new one', function(done){ - request(app) - .get('/') - .set('Cookie', 'connect.sid=foobarbaz') - .end(function(err, res){ - sid(res).should.not.equal('foobarbaz'); - done(); - }); - }) - }) - - it('should issue separate sids', function(done){ - var n = 0; - - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(function(req, res){ - req.session.count = ++n; - res.end(); - }) - - request(app) - .get('/') - .end(function(err, res){ - - var id = sid(res); - request(app) - .get('/') - .set('Cookie', 'connect.sid=' + id) - .end(function(err, res){ - sid(res).should.equal(id); - - request(app) - .get('/') - .end(function(err, res){ - sid(res).should.not.equal(id); - done(); - }); - }); - }); - }) - describe('req.session', function(){ it('should persist', function(done){ var app = express() @@ -1188,6 +1292,29 @@ function cookie(res) { return (setCookie && setCookie[0]) || undefined; } +function createServer(opts, fn) { + var app = express() + var options = opts || {} + + if (!('cookie' in options)) { + options.cookie = { maxAge: 60 * 1000 } + } + + if (!('secret' in options)) { + options.secret = 'keyboard cat' + } + + app.set('env', 'test') + app.use(session(options)) + app.use(fn || end) + + return http.createServer(app) +} + +function end(req, res) { + res.end() +} + function expires(res) { var match = /Expires=([^;]+)/.exec(cookie(res)); return match ? match[1] : undefined; From d2c9a064d836ee44cae571531de3d84693342d5d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 13:51:14 -0400 Subject: [PATCH 078/766] Reject cookies with missing signatures --- History.md | 1 + index.js | 35 +++++-- test/session.js | 242 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 197 insertions(+), 81 deletions(-) diff --git a/History.md b/History.md index 3b9079bc..452b6408 100644 --- a/History.md +++ b/History.md @@ -5,6 +5,7 @@ unreleased * Add deprecation message to undefined `saveUninitialized` option * Fix `res.end` patch to return correct value * Fix `res.end` patch to handle multiple `res.end` calls + * Reject cookies with missing signatures 1.5.2 / 2014-06-26 ================== diff --git a/index.js b/index.js index afa61873..a66cad6a 100644 --- a/index.js +++ b/index.js @@ -308,16 +308,26 @@ function generateSessionId(sess) { function getcookie(req, name, secret) { var header = req.headers.cookie; + var raw; var val; // read from cookie header if (header) { var cookies = cookie.parse(header); - val = cookies[name]; + raw = cookies[name]; - if (val && val.substr(0, 2) === 's:') { - val = signature.unsign(val.slice(2), secret); + if (raw) { + if (raw.substr(0, 2) === 's:') { + val = signature.unsign(raw.slice(2), secret); + + if (val === false) { + debug('cookie signature invalid'); + val = undefined; + } + } else { + debug('cookie unsigned') + } } } @@ -332,14 +342,23 @@ function getcookie(req, name, secret) { // back-compat read from cookieParser() cookies data if (!val && req.cookies) { - val = req.cookies[name]; + raw = req.cookies[name]; - if (val && val.substr(0, 2) === 's:') { - val = signature.unsign(val.slice(2), secret); + if (raw) { + deprecate('cookie should be available in req.headers.cookie'); } - if (val) { - deprecate('cookie should be available in req.headers.cookie'); + if (raw) { + if (raw.substr(0, 2) === 's:') { + val = signature.unsign(raw.slice(2), secret); + + if (val === false) { + debug('cookie signature invalid'); + val = undefined; + } + } else { + debug('cookie unsigned') + } } } diff --git a/test/session.js b/test/session.js index 1f210609..5e2376ab 100644 --- a/test/session.js +++ b/test/session.js @@ -190,6 +190,51 @@ describe('session()', function(){ }) }) + describe('when sid not properly signed', function () { + it('should generate new session', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, key: 'sessid' }, function (req, res) { + var isnew = req.session.active === undefined + req.session.active = true + res.end('session ' + (isnew ? 'created' : 'read')) + }) + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + var val = sid(res) + should(val).not.be.empty + request(server) + .get('/') + .set('Cookie', 'sessid=' + val) + .expect(200, 'session created', done) + }) + }) + + it('should not attempt fetch from store', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, key: 'sessid' }, function (req, res) { + var isnew = req.session.active === undefined + req.session.active = true + res.end('session ' + (isnew ? 'created' : 'read')) + }) + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + var val = cookie(res).replace(/...\./, '.') + + should(val).not.be.empty + request(server) + .get('/') + .set('Cookie', val) + .expect(200, 'session created', done) + }) + }) + }) + describe('when session expired in store', function () { it('should create a new session', function (done) { var count = 0 @@ -381,39 +426,49 @@ describe('session()', function(){ }); it('should provide default generator', function(done){ - var server = createServer() - - request(server) + request(createServer()) .get('/') - .expect('set-cookie', /connect\.sid=s%3A([^\.]+)\./i) - .expect(200, done); + .expect(200, function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + done() + }) }); it('should allow custom function', function(done){ - var server = createServer({ genid: function(){ return 'a' }}) + function genid() { return 'apple' } - request(server) + request(createServer({ genid: genid })) .get('/') - .expect('set-cookie', /connect\.sid=s%3Aa\./i) - .expect(200, done); + .expect(200, function (err, res) { + if (err) return done(err) + should(sid(res)).equal('apple') + done() + }) }); it('should encode unsafe chars', function(done){ - var server = createServer({ genid: function(){ return '%' }}) + function genid() { return '%' } - request(server) + request(createServer({ genid: genid })) .get('/') - .expect('set-cookie', /connect\.sid=s%3A%25\./i) - .expect(200, done); + .expect(200, function (err, res) { + if (err) return done(err) + should(sid(res)).equal('%25') + done() + }) }); it('should provide req argument', function(done){ - var server = createServer({ genid: function(req){ return req.url }}) + function genid(req) { return req.url } - request(server) + request(createServer({ genid: genid })) .get('/foo') - .expect('set-cookie', /connect\.sid=s%3A%2Ffoo\./i) - .expect(200, done); + .expect(200, function (err, res) { + if (err) return done(err) + should(sid(res)).equal('%2Ffoo') + done() + }) }); }); @@ -456,7 +511,7 @@ describe('session()', function(){ should(cookie(res)).not.be.empty; request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect(200, function(err, res){ if (err) return done(err); should(cookie(res)).be.empty; @@ -481,7 +536,7 @@ describe('session()', function(){ should(cookie(res)).not.be.empty; request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect(200, function(err, res){ if (err) return done(err); should(cookie(res)).not.be.empty; @@ -514,7 +569,7 @@ describe('session()', function(){ if (err) return done(err); request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect('x-count', '2') .expect(200, done); }); @@ -542,7 +597,7 @@ describe('session()', function(){ if (err) return done(err); request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect('x-count', '2') .expect(200, done); }); @@ -570,7 +625,7 @@ describe('session()', function(){ if (err) return done(err); request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect('x-count', '1') .expect(200, done); }); @@ -599,7 +654,7 @@ describe('session()', function(){ if (err) return done(err); request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect('x-count', '2') .expect(200, done); }); @@ -722,7 +777,7 @@ describe('session()', function(){ len.should.equal(1); request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect(200, function(err, res){ if (err) return done(err); store.length(function(err, len){ @@ -755,7 +810,7 @@ describe('session()', function(){ len.should.equal(1); request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .expect(200, function(err, res){ if (err) return done(err); store.length(function(err, len){ @@ -811,7 +866,7 @@ describe('session()', function(){ request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .end(function(err, res){ res.text.should.equal('2'); done(); @@ -839,15 +894,15 @@ describe('session()', function(){ request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .end(function(err, res){ - var id = sid(res); + var val = cookie(res); res.text.should.equal('2'); modify = false; request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', val) .end(function(err, res){ should(sid(res)).be.empty; res.text.should.equal('2'); @@ -855,7 +910,7 @@ describe('session()', function(){ request(app) .get('/') - .set('Cookie', 'connect.sid=' + id) + .set('Cookie', val) .end(function(err, res){ sid(res).should.not.be.empty; res.text.should.equal('3'); @@ -903,14 +958,15 @@ describe('session()', function(){ request(app) .get('/') .end(function(err, res){ - var id = sid(res); - + if (err) return done(err) + var id = sid(res) request(app) .get('/') - .set('Cookie', 'connect.sid=' + id) + .set('Cookie', cookie(res)) .end(function(err, res){ - sid(res).should.not.equal(''); - sid(res).should.not.equal(id); + if (err) return done(err) + should(sid(res)).not.be.empty + should(sid(res)).should.not.equal(id) done(); }); }); @@ -971,7 +1027,7 @@ describe('session()', function(){ request(app) .get('/admin') - .set('Cookie', 'connect.sid=' + sid(res)) + .set('Cookie', cookie(res)) .end(function(err, res){ res.headers.should.not.have.property('set-cookie'); done(); @@ -1123,7 +1179,7 @@ describe('session()', function(){ }) describe('.maxAge', function(){ - var id; + var val; var app = express() .use(session({ secret: 'keyboard cat', cookie: { maxAge: 2000 }})) .use(function(req, res, next){ @@ -1141,7 +1197,7 @@ describe('session()', function(){ var a = new Date(expires(res)) , b = new Date; - id = sid(res); + val = cookie(res); a.getYear().should.equal(b.getYear()); a.getMonth().should.equal(b.getMonth()); @@ -1157,12 +1213,12 @@ describe('session()', function(){ it('should modify cookie when changed', function(done){ request(app) .get('/') - .set('Cookie', 'connect.sid=' + id) + .set('Cookie', val) .end(function(err, res){ var a = new Date(expires(res)) , b = new Date; - id = sid(res); + val = cookie(res); a.getYear().should.equal(b.getYear()); a.getMonth().should.equal(b.getMonth()); @@ -1177,12 +1233,12 @@ describe('session()', function(){ it('should modify cookie when changed to large value', function(done){ request(app) .get('/') - .set('Cookie', 'connect.sid=' + id) + .set('Cookie', val) .end(function(err, res){ var a = new Date(expires(res)) , b = new Date; - id = sid(res); + val = cookie(res); var delta = a.valueOf() - b.valueOf(); (delta > 2999999000 && delta < 3000000000).should.be.ok; @@ -1232,57 +1288,96 @@ describe('session()', function(){ }) }) }) + }) - it('should support cookieParser()', function(done){ + describe('cookieParser()', function () { + it('should read from req.cookies', function(done){ var app = express() .use(cookieParser()) - .use(function(req, res, next){ delete req.headers.cookie; next(); }) + .use(function(req, res, next){ req.headers.cookie = 'foo=bar'; next() }) .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ - req.session.count = req.session.count || 0; - req.session.count++; - res.end(req.session.count.toString()); - }); + req.session.count = req.session.count || 0 + req.session.count++ + res.end(req.session.count.toString()) + }) request(app) .get('/') - .end(function(err, res){ - res.text.should.equal('1'); + .expect(200, '1', function (err, res) { + if (err) return done(err) + request(app) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, '2', done) + }) + }) + + it('should reject unsigned from req.cookies', function(done){ + var app = express() + .use(cookieParser()) + .use(function(req, res, next){ req.headers.cookie = 'foo=bar'; next() }) + .use(session({ secret: 'keyboard cat', key: 'sessid' })) + .use(function(req, res, next){ + req.session.count = req.session.count || 0 + req.session.count++ + res.end(req.session.count.toString()) + }) + request(app) + .get('/') + .expect(200, '1', function (err, res) { + if (err) return done(err) request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) - .end(function(err, res){ - res.text.should.equal('2'); - done(); - }); - }); + .set('Cookie', 'sessid=' + sid(res)) + .expect(200, '1', done) + }) + }) + + it('should reject invalid signature from req.cookies', function(done){ + var app = express() + .use(cookieParser()) + .use(function(req, res, next){ req.headers.cookie = 'foo=bar'; next() }) + .use(session({ secret: 'keyboard cat', key: 'sessid' })) + .use(function(req, res, next){ + req.session.count = req.session.count || 0 + req.session.count++ + res.end(req.session.count.toString()) + }) + + request(app) + .get('/') + .expect(200, '1', function (err, res) { + if (err) return done(err) + var val = cookie(res).replace(/...\./, '.') + request(app) + .get('/') + .set('Cookie', val) + .expect(200, '1', done) + }) }) - it('should support cookieParser(secret)', function(done){ + it('should read from req.signedCookies', function(done){ var app = express() .use(cookieParser('keyboard cat')) - .use(function(req, res, next){ delete req.headers.cookie; next(); }) + .use(function(req, res, next){ delete req.headers.cookie; next() }) .use(session()) .use(function(req, res, next){ - req.session.count = req.session.count || 0; - req.session.count++; - res.end(req.session.count.toString()); - }); + req.session.count = req.session.count || 0 + req.session.count++ + res.end(req.session.count.toString()) + }) request(app) .get('/') - .end(function(err, res){ - res.text.should.equal('1'); - + .expect(200, '1', function (err, res) { + if (err) return done(err) request(app) .get('/') - .set('Cookie', 'connect.sid=' + sid(res)) - .end(function(err, res){ - res.text.should.equal('2'); - done(); - }); - }); + .set('Cookie', cookie(res)) + .expect(200, '2', done) + }) }) }) }) @@ -1321,6 +1416,7 @@ function expires(res) { } function sid(res) { - var match = /^connect\.sid=([^;]+);/.exec(cookie(res)); - return match ? match[1] : undefined; + var match = /^[^=]+=s%3A([^;\.]+)[\.;]/.exec(cookie(res)) + var val = match ? match[1] : undefined + return val } From 2593eeb66cebb74d573bb9475b39a98c66d6bc24 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 14:23:06 -0400 Subject: [PATCH 079/766] tests: add test for session.reload() --- test/session.js | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/test/session.js b/test/session.js index 5e2376ab..2fbf551d 100644 --- a/test/session.js +++ b/test/session.js @@ -973,6 +973,77 @@ describe('session()', function(){ }) }) + describe('.reload()', function () { + it('should reload session from store', function (done) { + var server = createServer(null, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + req.session.url = req.url + + if (req.url === '/bar') { + res.end('saw ' + req.session.url) + return + } + + request(server) + .get('/bar') + .set('Cookie', val) + .expect(200, 'saw /bar', function (err, resp) { + if (err) return done(err) + req.session.reload(function (err) { + if (err) return done(err) + res.end('saw ' + req.session.url) + }) + }) + }) + var val + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + val = cookie(res) + request(server) + .get('/foo') + .set('Cookie', val) + .expect(200, 'saw /bar', done) + }) + }) + + it('should error is session missing', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + store.clear(function (err) { + if (err) return done(err) + req.session.reload(function (err) { + res.statusCode = err ? 500 : 200 + res.end(err ? err.message : '') + }) + }) + }) + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + request(server) + .get('/foo') + .set('Cookie', cookie(res)) + .expect(500, 'failed to load session', done) + }) + }) + }) + describe('.cookie', function(){ describe('.*', function(){ it('should serialize as parameters', function(done){ From 4a891bfa6682bd6aaa62a082f0707d3632ddee1f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 14:35:33 -0400 Subject: [PATCH 080/766] tests: improve persist test --- test/session.js | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/test/session.js b/test/session.js index 2fbf551d..c429a8c2 100644 --- a/test/session.js +++ b/test/session.js @@ -848,30 +848,26 @@ describe('session()', function(){ describe('req.session', function(){ it('should persist', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min, httpOnly: false }})) - .use(function(req, res, next){ - // checks that cookie options persisted - req.session.cookie.httpOnly.should.equal(false); - - req.session.count = req.session.count || 0; - req.session.count++; - res.end(req.session.count.toString()); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + res.end('hits: ' + req.session.count) + }) - request(app) + request(server) .get('/') - .end(function(err, res){ - res.text.should.equal('1'); - - request(app) - .get('/') - .set('Cookie', cookie(res)) - .end(function(err, res){ - res.text.should.equal('2'); - done(); - }); - }); + .expect(200, 'hits: 1', function (err, res) { + if (err) return done(err) + store.load(sid(res), function (err, sess) { + if (err) return done(err) + should(sess).not.be.empty + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'hits: 2', done) + }) + }) }) it('should only set-cookie when modified', function(done){ From a42270815c6fce3bfc7fecac8e276f12d94db069 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 16:31:28 -0400 Subject: [PATCH 081/766] 1.6.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 452b6408..5383e2f7 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.6.0 / 2014-06-28 +================== * Add deprecation message to undefined `resave` option * Add deprecation message to undefined `saveUninitialized` option diff --git a/package.json b/package.json index 6db6dc77..19d0c04e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.5.2", + "version": "1.6.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 5aeb2c6c7ce1e01c5448e307c82c4eae09b7fa80 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 20:40:31 -0400 Subject: [PATCH 082/766] Fix saveUninitialized deprecation message --- History.md | 5 +++++ index.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 5383e2f7..61724ac7 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix saveUninitialized deprecation message + 1.6.0 / 2014-06-28 ================== diff --git a/index.js b/index.js index a66cad6a..7ea33245 100644 --- a/index.js +++ b/index.js @@ -88,7 +88,7 @@ function session(options){ } if (saveUninitializedSession === undefined) { - deprecate('pass resave saveUninitialized; default value will change'); + deprecate('pass saveUninitialized option; default value will change'); saveUninitializedSession = true; } From 61e5e6b8d887292e15674f17c73ff36790112a39 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 28 Jun 2014 20:40:54 -0400 Subject: [PATCH 083/766] 1.6.1 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 61724ac7..fb5ad584 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.6.1 / 2014-06-28 +================== * Fix saveUninitialized deprecation message diff --git a/package.json b/package.json index 19d0c04e..cf0b89cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.6.0", + "version": "1.6.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 2b969b6f796034f08658db6f189d62b7a4a6dc70 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 4 Jul 2014 16:25:21 -0400 Subject: [PATCH 084/766] Fix confusing option deprecation messages --- History.md | 5 +++++ index.js | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index fb5ad584..d3150cac 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix confusing option deprecation messages + 1.6.1 / 2014-06-28 ================== diff --git a/index.js b/index.js index 7ea33245..71e0ed9e 100644 --- a/index.js +++ b/index.js @@ -83,12 +83,12 @@ function session(options){ } if (resaveSession === undefined) { - deprecate('pass resave option; default value will change'); + deprecate('undefined resaveSession option; provide resave option'); resaveSession = true; } if (saveUninitializedSession === undefined) { - deprecate('pass saveUninitialized option; default value will change'); + deprecate('undefined saveUninitialized option; provide saveUninitialized option'); saveUninitializedSession = true; } @@ -116,7 +116,7 @@ function session(options){ store.on('connect', function(){ storeReady = true; }); if (!options.secret) { - deprecate('pass secret option; do not use req.secret'); + deprecate('req.secret; provide secret option'); } return function session(req, res, next) { From 4efc388231b51e747300db74752f7800d5ca46bc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 4 Jul 2014 16:25:59 -0400 Subject: [PATCH 085/766] 1.6.2 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index d3150cac..c76dd09b 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.6.2 / 2014-07-04 +================== * Fix confusing option deprecation messages diff --git a/package.json b/package.json index cf0b89cf..fc64859b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.6.1", + "version": "1.6.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From fb3c6b1b4e649350d4da6118e2ad064a012743a8 Mon Sep 17 00:00:00 2001 From: Joe Wagner Date: Fri, 4 Jul 2014 15:25:05 -0600 Subject: [PATCH 086/766] Fix typo in deprecate message for resave option fixes #60 --- History.md | 5 +++++ index.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index c76dd09b..f4a5a136 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix resave deprecation message + 1.6.2 / 2014-07-04 ================== diff --git a/index.js b/index.js index 71e0ed9e..9fd030bc 100644 --- a/index.js +++ b/index.js @@ -83,7 +83,7 @@ function session(options){ } if (resaveSession === undefined) { - deprecate('undefined resaveSession option; provide resave option'); + deprecate('undefined resave option; provide resave option'); resaveSession = true; } From 78b2db52785bf3fe70a2035f47606f6d16c0b789 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 4 Jul 2014 17:32:57 -0400 Subject: [PATCH 087/766] 1.6.3 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index f4a5a136..c094fe67 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.6.3 / 2014-07-04 +================== * Fix resave deprecation message diff --git a/package.json b/package.json index fc64859b..159911a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.6.2", + "version": "1.6.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 901c8e062c8789d3963ebe175a75d25d3c229245 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 7 Jul 2014 10:28:56 -0400 Subject: [PATCH 088/766] Fix blank responses for store with synchronous ops fixes #61 --- History.md | 5 +++++ index.js | 33 ++++++++++++++++++++++++++-- test/session.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/History.md b/History.md index c094fe67..3b62162a 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix blank responses for stores with synchronous operations + 1.6.3 / 2014-07-04 ================== diff --git a/index.js b/index.js index 9fd030bc..05762ca4 100644 --- a/index.js +++ b/index.js @@ -177,6 +177,9 @@ function session(options){ return false; } + var ret; + var sync = true; + if (chunk === undefined) { chunk = ''; } @@ -189,9 +192,22 @@ function session(options){ store.destroy(req.sessionID, function(err){ if (err) console.error(err.stack); debug('destroyed'); + + if (sync) { + ret = end.call(res, chunk, encoding); + sync = false; + return; + } + end.call(res); }); - return res.write(chunk, encoding); + + if (sync) { + ret = res.write(chunk, encoding); + sync = false; + } + + return ret; } // no session to save @@ -207,9 +223,22 @@ function session(options){ req.session.save(function(err){ if (err) console.error(err.stack); debug('saved'); + + if (sync) { + ret = end.call(res, chunk, encoding); + sync = false; + return; + } + end.call(res); }); - return res.write(chunk, encoding); + + if (sync) { + ret = res.write(chunk, encoding); + sync = false; + } + + return ret; } return end.call(res, chunk, encoding); diff --git a/test/session.js b/test/session.js index c429a8c2..017c4126 100644 --- a/test/session.js +++ b/test/session.js @@ -1357,6 +1357,44 @@ describe('session()', function(){ }) }) + describe('synchronous store', function(){ + it('should respond correctly on save', function(done){ + var store = new SyncStore() + var server = createServer({ store: store }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + res.end('hits: ' + req.session.count) + }) + + request(server) + .get('/') + .expect(200, 'hits: 1', done) + }) + + it('should respond correctly on destroy', function(done){ + var store = new SyncStore() + var server = createServer({ store: store, unset: 'destroy' }, function (req, res) { + req.session.count = req.session.count || 0 + var count = ++req.session.count + if (req.session.count > 1) { + req.session = null + res.write('destroyed\n') + } + res.end('hits: ' + count) + }) + + request(server) + .get('/') + .expect(200, 'hits: 1', function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'destroyed\nhits: 2', done) + }) + }) + }) + describe('cookieParser()', function () { it('should read from req.cookies', function(done){ var app = express() @@ -1487,3 +1525,23 @@ function sid(res) { var val = match ? match[1] : undefined return val } + +function SyncStore() { + this.sessions = Object.create(null); +} + +SyncStore.prototype.__proto__ = session.Store.prototype; + +SyncStore.prototype.destroy = function destroy(sid, callback) { + delete this.sessions[sid]; + callback(); +}; + +SyncStore.prototype.get = function get(sid, callback) { + callback(null, JSON.parse(this.sessions[sid])); +}; + +SyncStore.prototype.set = function set(sid, sess, callback) { + this.sessions[sid] = JSON.stringify(sess); + callback(); +}; From 9a13dc329dc689a7a7b8c7185ff64b37864cd908 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 7 Jul 2014 11:09:50 -0400 Subject: [PATCH 089/766] 1.6.4 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 3b62162a..0e8ad055 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.6.4 / 2014-07-07 +================== * Fix blank responses for stores with synchronous operations diff --git a/package.json b/package.json index 159911a7..7b0c5743 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.6.3", + "version": "1.6.4", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 8287ab38f8348f7383c564f8cbb7b4639d1a669f Mon Sep 17 00:00:00 2001 From: vmakhaev Date: Wed, 2 Jul 2014 08:33:43 +0400 Subject: [PATCH 090/766] Do not require req.originalUrl closes #57 --- History.md | 5 +++++ index.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 0e8ad055..aeb59718 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Do not require `req.originalUrl` + 1.6.4 / 2014-07-07 ================== diff --git a/index.js b/index.js index 05762ca4..4a0d3af1 100644 --- a/index.js +++ b/index.js @@ -128,7 +128,7 @@ function session(options){ if (!storeReady) return debug('store is disconnected'), next(); // pathname mismatch - var originalPath = parse(req.originalUrl).pathname; + var originalPath = parse(req.originalUrl || req.url).pathname; if (0 != originalPath.indexOf(cookie.path || '/')) return next(); // backwards compatibility for signed cookies From 362af9cc48574649aab74a33e561457f2d3cb736 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Jul 2014 23:24:41 -0400 Subject: [PATCH 091/766] tests: change the majority of the tests to not use express --- index.js | 2 +- test/session.js | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 4a0d3af1..5927c72d 100644 --- a/index.js +++ b/index.js @@ -136,7 +136,7 @@ function session(options){ var secret = options.secret || req.secret; // ensure secret is available or bail - if (!secret) throw new Error('`secret` option required for sessions'); + if (!secret) next(new Error('`secret` option required for sessions')); var originalHash , originalId; diff --git a/test/session.js b/test/session.js index 017c4126..5ad8b4b1 100644 --- a/test/session.js +++ b/test/session.js @@ -1493,8 +1493,8 @@ function cookie(res) { } function createServer(opts, fn) { - var app = express() var options = opts || {} + var respond = fn || end if (!('cookie' in options)) { options.cookie = { maxAge: 60 * 1000 } @@ -1504,11 +1504,19 @@ function createServer(opts, fn) { options.secret = 'keyboard cat' } - app.set('env', 'test') - app.use(session(options)) - app.use(fn || end) + var _session = session(options) - return http.createServer(app) + return http.createServer(function (req, res) { + _session(req, res, function (err) { + if (err) { + res.statusCode = err.status || 500 + res.end(err.message) + return + } + + respond(req, res) + }) + }) } function end(req, res) { From 3ffa6a6f942590c4d881dc4daa0cecb8f9f5c973 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Jul 2014 23:25:49 -0400 Subject: [PATCH 092/766] deps: istanbul@0.2.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b0c5743..7f40a5c5 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "1.3.2", - "istanbul": "0.2.12", + "istanbul": "0.2.16", "express": "~4.4.0", "mocha": "~1.20.1", "should": "~4.0.4", From a8e634e8288d07d2d6b727f1af0d190df0415ba9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 8 Jul 2014 19:09:38 -0400 Subject: [PATCH 093/766] Move req.cookies warning after validating signature fixes #62 --- index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 5927c72d..29c740b9 100644 --- a/index.js +++ b/index.js @@ -373,14 +373,14 @@ function getcookie(req, name, secret) { if (!val && req.cookies) { raw = req.cookies[name]; - if (raw) { - deprecate('cookie should be available in req.headers.cookie'); - } - if (raw) { if (raw.substr(0, 2) === 's:') { val = signature.unsign(raw.slice(2), secret); + if (val) { + deprecate('cookie should be available in req.headers.cookie'); + } + if (val === false) { debug('cookie signature invalid'); val = undefined; From 269bd4b9e575a055b5b3f2a52d81e0a51f1192bf Mon Sep 17 00:00:00 2001 From: Fishrock123 Date: Wed, 9 Jul 2014 11:13:00 -0400 Subject: [PATCH 094/766] would-be maintainers: use your own initiative! --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fa2bc829..dd1ba7ac 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ [![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) [![Coverage Status](https://img.shields.io/coveralls/expressjs/session.svg?branch=master)](https://coveralls.io/r/expressjs/session) -THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAINING THIS REPOSITORY, PLEASE LET US KNOW! +THIS REPOSITORY NEEDS A MAINTAINER. +If you are interested in maintaining this module, please start contributing by making PRs and solving / discussing unsolved issues. ## API From 97f35a450bb1c1eec5f17dbe829d65c8a5fac48c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 11 Jul 2014 20:38:03 -0400 Subject: [PATCH 095/766] deps: debug@1.0.3 --- History.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index aeb59718..880ef2e1 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,8 @@ unreleased ========== * Do not require `req.originalUrl` + * deps: debug@1.0.3 + - Add support for multiple wildcards in namespaces 1.6.4 / 2014-07-07 ================== diff --git a/package.json b/package.json index 7f40a5c5..0be44580 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "buffer-crc32": "0.2.3", "cookie": "0.1.2", "cookie-signature": "1.0.4", - "debug": "1.0.2", + "debug": "1.0.3", "depd": "0.3.0", "on-headers": "0.0.0", "uid-safe": "1.0.1", From 7cbba629470c7bfe8f26458f55b6fea586ff656f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 11 Jul 2014 20:38:21 -0400 Subject: [PATCH 096/766] deps: istanbul@0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0be44580..ae66850d 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "1.3.2", - "istanbul": "0.2.16", + "istanbul": "0.3.0", "express": "~4.4.0", "mocha": "~1.20.1", "should": "~4.0.4", From 52736dce14b4c3c22984e04d3edcba2cb77d43e8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 11 Jul 2014 20:38:52 -0400 Subject: [PATCH 097/766] deps: express@~4.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae66850d..703a3059 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.1", "cookie-parser": "1.3.2", "istanbul": "0.3.0", - "express": "~4.4.0", + "express": "~4.5.0", "mocha": "~1.20.1", "should": "~4.0.4", "supertest": "~0.13.0" From 5258d07af8acd3bb51c5401f1854ae96caab01af Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 11 Jul 2014 20:40:15 -0400 Subject: [PATCH 098/766] 1.6.5 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 880ef2e1..51636357 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.6.5 / 2014-07-11 +================== * Do not require `req.originalUrl` * deps: debug@1.0.3 diff --git a/package.json b/package.json index 703a3059..74acbb64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.6.4", + "version": "1.6.5", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 2f5d99a2b52fab1fe5038b7afdf8d8d9491c0198 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jul 2014 23:07:38 -0400 Subject: [PATCH 099/766] deps: express@~4.6.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74acbb64..1e41946d 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.1", "cookie-parser": "1.3.2", "istanbul": "0.3.0", - "express": "~4.5.0", + "express": "~4.6.1", "mocha": "~1.20.1", "should": "~4.0.4", "supertest": "~0.13.0" From faf46027bb1ecde40c4ec69b63b23721421dc5d2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jul 2014 23:10:09 -0400 Subject: [PATCH 100/766] deps: debug@1.0.4 --- History.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 51636357..416a8c12 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@1.0.4 + 1.6.5 / 2014-07-11 ================== diff --git a/package.json b/package.json index 1e41946d..4442fa85 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "buffer-crc32": "0.2.3", "cookie": "0.1.2", "cookie-signature": "1.0.4", - "debug": "1.0.3", + "debug": "1.0.4", "depd": "0.3.0", "on-headers": "0.0.0", "uid-safe": "1.0.1", From 3aa77da8872935d2807a42e07247f6304ff4bc06 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jul 2014 23:10:39 -0400 Subject: [PATCH 101/766] deps: depd@0.4.2 --- History.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 416a8c12..49ddb6af 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,11 @@ unreleased ========== * deps: debug@1.0.4 + * deps: depd@0.4.2 + - Add `TRACE_DEPRECATION` environment variable + - Remove non-standard grey color from color output + - Support `--no-deprecation` argument + - Support `--trace-deprecation` argument 1.6.5 / 2014-07-11 ================== diff --git a/package.json b/package.json index 4442fa85..b71598d5 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.4", "debug": "1.0.4", - "depd": "0.3.0", + "depd": "0.4.2", "on-headers": "0.0.0", "uid-safe": "1.0.1", "utils-merge": "1.0.0" From 88e8a66df5979f99d76820389a7b4fe5d714989a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 22 Jul 2014 00:13:27 -0400 Subject: [PATCH 102/766] Improve session-ending error handling closes #66 --- History.md | 2 + index.js | 23 +++++++++-- test/session.js | 102 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 6 deletions(-) diff --git a/History.md b/History.md index 49ddb6af..983cf831 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,8 @@ unreleased ========== + * Improve session-ending error handling + - Errors are passed to `next(err)` instead of `console.error` * deps: debug@1.0.4 * deps: depd@0.4.2 - Add `TRACE_DEPRECATION` environment variable diff --git a/index.js b/index.js index 29c740b9..2b886ae0 100644 --- a/index.js +++ b/index.js @@ -50,6 +50,15 @@ var warning = 'Warning: connect.session() MemoryStore is not\n' + 'designed for a production environment, as it will leak\n' + 'memory, and will not scale past a single process.'; +/** + * Node.js 0.8+ async implementation. + */ + +/* istanbul ignore next */ +var defer = typeof setImmediate === 'function' + ? setImmediate + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } + /** * Setup session store with the given `options`. * @@ -189,8 +198,11 @@ function session(options){ if (shouldDestroy(req)) { // destroy session debug('destroying'); - store.destroy(req.sessionID, function(err){ - if (err) console.error(err.stack); + store.destroy(req.sessionID, function ondestroy(err) { + if (err) { + defer(next, err); + } + debug('destroyed'); if (sync) { @@ -220,8 +232,11 @@ function session(options){ if (shouldSave(req)) { debug('saving'); - req.session.save(function(err){ - if (err) console.error(err.stack); + req.session.save(function onsave(err) { + if (err) { + defer(next, err); + } + debug('saved'); if (sync) { diff --git a/test/session.js b/test/session.js index 5ad8b4b1..20fc8caa 100644 --- a/test/session.js +++ b/test/session.js @@ -92,6 +92,54 @@ describe('session()', function(){ }) }) + it('should pass session fetch error', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + res.end('hello, world') + }) + + store.get = function destroy(sid, callback) { + callback(new Error('boom!')) + } + + request(server) + .get('/') + .expect(200, 'hello, world', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(500, 'boom!', done) + }) + }) + + it('should treat ENOENT session fetch error as not found', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }) + + store.get = function destroy(sid, callback) { + var err = new Error('boom!') + err.code = 'ENOENT' + callback(err) + } + + request(server) + .get('/') + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + should(sid(res)).not.be.empty + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session 2', done) + }) + }) + it('should create multiple sessions', function (done) { var cb = after(2, check) var count = 0 @@ -750,6 +798,27 @@ describe('session()', function(){ .expect('set-cookie', /connect\.sid=/) .expect(200, done); }); + + it('should pass session save error', function (done) { + var cb = after(2, done) + var store = new session.MemoryStore() + var server = createServer({ store: store, saveUninitialized: true }, function (req, res) { + res.end('session saved') + }) + + store.set = function destroy(sid, sess, callback) { + callback(new Error('boom!')) + } + + server.on('error', function onerror(err) { + err.message.should.equal('boom!') + cb() + }) + + request(server) + .get('/') + .expect(200, 'session saved', cb) + }) }); describe('unset option', function () { @@ -844,6 +913,28 @@ describe('session()', function(){ }); }); }); + + it('should pass session destroy error', function (done) { + var cb = after(2, done) + var store = new session.MemoryStore() + var server = createServer({ store: store, unset: 'destroy' }, function (req, res) { + req.session = null + res.end('session destroyed') + }) + + store.destroy = function destroy(sid, callback) { + callback(new Error('boom!')) + } + + server.on('error', function onerror(err) { + err.message.should.equal('boom!') + cb() + }) + + request(server) + .get('/') + .expect(200, 'session destroyed', cb) + }) }); describe('req.session', function(){ @@ -1506,17 +1597,24 @@ function createServer(opts, fn) { var _session = session(options) - return http.createServer(function (req, res) { + var server = http.createServer(function (req, res) { _session(req, res, function (err) { - if (err) { + if (err && !res._header) { res.statusCode = err.status || 500 res.end(err.message) return } + if (err) { + server.emit('error', err) + return + } + respond(req, res) }) }) + + return server } function end(req, res) { From 32731035c55dad0259ce942bffdfdda5ae7e814c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 22 Jul 2014 11:12:33 -0400 Subject: [PATCH 103/766] 1.7.0 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 983cf831..a994dc50 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.0 / 2014-07-22 +================== * Improve session-ending error handling - Errors are passed to `next(err)` instead of `console.error` diff --git a/package.json b/package.json index b71598d5..520fb84c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.6.5", + "version": "1.7.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From e87d4857cbd86bd36327e2174b42789da7aea596 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 Jul 2014 16:20:38 -0400 Subject: [PATCH 104/766] deps: mocha@~1.21.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 520fb84c..0e4c4c00 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "cookie-parser": "1.3.2", "istanbul": "0.3.0", "express": "~4.6.1", - "mocha": "~1.20.1", + "mocha": "~1.21.0", "should": "~4.0.4", "supertest": "~0.13.0" }, From 7f3d6b21aa53f475de2947cd2b2dba70354429ef Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 Jul 2014 16:21:44 -0400 Subject: [PATCH 105/766] deps: depd@0.4.3 --- History.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index a994dc50..2f725e6d 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: depd@0.4.3 + - Fix exception when global `Error.stackTraceLimit` is too low + 1.7.0 / 2014-07-22 ================== diff --git a/package.json b/package.json index 0e4c4c00..4427b6c4 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.4", "debug": "1.0.4", - "depd": "0.4.2", + "depd": "0.4.3", "on-headers": "0.0.0", "uid-safe": "1.0.1", "utils-merge": "1.0.0" From a0287b693665327945a00f36ca75aae1dc9ca853 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 Jul 2014 16:23:41 -0400 Subject: [PATCH 106/766] 1.7.1 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 2f725e6d..0d138f5b 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.1 / 2014-07-26 +================== * deps: depd@0.4.3 - Fix exception when global `Error.stackTraceLimit` is too low diff --git a/package.json b/package.json index 4427b6c4..9d5e7550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.0", + "version": "1.7.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From fe89208563a3bfe325292e56e032ae1d030bb6be Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Jul 2014 15:22:20 -0400 Subject: [PATCH 107/766] deps: depd@0.4.4 --- History.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 0d138f5b..59ffce71 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: depd@0.4.4 + - Work-around v8 generating empty stack traces + 1.7.1 / 2014-07-26 ================== diff --git a/package.json b/package.json index 9d5e7550..cb4c526e 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.4", "debug": "1.0.4", - "depd": "0.4.3", + "depd": "0.4.4", "on-headers": "0.0.0", "uid-safe": "1.0.1", "utils-merge": "1.0.0" From c5c1ac88cedb70df67550d9b9ffc8ea199e3ea21 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Jul 2014 15:22:22 -0400 Subject: [PATCH 108/766] 1.7.2 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 59ffce71..5a4750d6 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.2 / 2014-07-27 +================== * deps: depd@0.4.4 - Work-around v8 generating empty stack traces diff --git a/package.json b/package.json index cb4c526e..9392bb88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.1", + "version": "1.7.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 64be0b19e3eb596f6b18cc593983caa7b8028768 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 5 Aug 2014 21:35:10 -0400 Subject: [PATCH 109/766] Fix res.end patch to call correct upstream res.write fixes #72 --- History.md | 5 +++ index.js | 21 +++++++------ test/session.js | 83 ++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 88 insertions(+), 21 deletions(-) diff --git a/History.md b/History.md index 5a4750d6..ab78a08d 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix `res.end` patch to call correct upstream `res.write` + 1.7.2 / 2014-07-27 ================== diff --git a/index.js b/index.js index 2b886ae0..9aaf4022 100644 --- a/index.js +++ b/index.js @@ -179,9 +179,10 @@ function session(options){ }); // proxy end() to commit the session - var end = res.end; + var _end = res.end; + var _write = res.write; var ended = false; - res.end = function(chunk, encoding){ + res.end = function end(chunk, encoding) { if (ended) { return false; } @@ -206,16 +207,16 @@ function session(options){ debug('destroyed'); if (sync) { - ret = end.call(res, chunk, encoding); + ret = _end.call(res, chunk, encoding); sync = false; return; } - end.call(res); + _end.call(res); }); if (sync) { - ret = res.write(chunk, encoding); + ret = _write.call(res, chunk, encoding); sync = false; } @@ -225,7 +226,7 @@ function session(options){ // no session to save if (!req.session) { debug('no session'); - return end.call(res, chunk, encoding); + return _end.call(res, chunk, encoding); } req.session.resetMaxAge(); @@ -240,23 +241,23 @@ function session(options){ debug('saved'); if (sync) { - ret = end.call(res, chunk, encoding); + ret = _end.call(res, chunk, encoding); sync = false; return; } - end.call(res); + _end.call(res); }); if (sync) { - ret = res.write(chunk, encoding); + ret = _write.call(res, chunk, encoding); sync = false; } return ret; } - return end.call(res, chunk, encoding); + return _end.call(res, chunk, encoding); }; // generate the session diff --git a/test/session.js b/test/session.js index 20fc8caa..9d5b277f 100644 --- a/test/session.js +++ b/test/session.js @@ -937,6 +937,40 @@ describe('session()', function(){ }) }); + describe('res.end patch', function () { + it('should correctly handle res.end/res.write patched prior', function (done) { + var app = express() + + app.use(writePatch()) + app.use(createSession()) + app.use(function (req, res) { + req.session.hit = true + res.write('hello, ') + res.end('world') + }) + + request(app) + .get('/') + .expect(200, 'hello, world', done) + }) + + it('should correctly handle res.end/res.write patched after', function (done) { + var app = express() + + app.use(createSession()) + app.use(writePatch()) + app.use(function (req, res) { + req.session.hit = true + res.write('hello, ') + res.end('world') + }) + + request(app) + .get('/') + .expect(200, 'hello, world', done) + }) + }) + describe('req.session', function(){ it('should persist', function(done){ var store = new session.MemoryStore() @@ -1584,19 +1618,9 @@ function cookie(res) { } function createServer(opts, fn) { - var options = opts || {} + var _session = createSession(opts) var respond = fn || end - if (!('cookie' in options)) { - options.cookie = { maxAge: 60 * 1000 } - } - - if (!('secret' in options)) { - options.secret = 'keyboard cat' - } - - var _session = session(options) - var server = http.createServer(function (req, res) { _session(req, res, function (err) { if (err && !res._header) { @@ -1617,6 +1641,20 @@ function createServer(opts, fn) { return server } +function createSession(opts) { + var options = opts || {} + + if (!('cookie' in options)) { + options.cookie = { maxAge: 60 * 1000 } + } + + if (!('secret' in options)) { + options.secret = 'keyboard cat' + } + + return session(options) +} + function end(req, res) { res.end() } @@ -1632,6 +1670,29 @@ function sid(res) { return val } +function writePatch() { + var ended = false + return function addWritePatch(req, res, next) { + var _end = res.end + var _write = res.write + + res.end = function end() { + ended = true + return _end.apply(this, arguments) + } + + res.write = function write() { + if (ended) { + throw new Error('write after end') + } + + return _write.apply(this, arguments) + } + + next() + } +} + function SyncStore() { this.sessions = Object.create(null); } From 67b07004198396ff2a59b4e459ff6b26dba48aa8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 5 Aug 2014 21:42:24 -0400 Subject: [PATCH 110/766] 1.7.3 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index ab78a08d..307655a1 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.3 / 2014-08-05 +================== * Fix `res.end` patch to call correct upstream `res.write` diff --git a/package.json b/package.json index 9392bb88..349b6fef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.2", + "version": "1.7.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 5c503e7552ea48342f4ce4ce1322606eb8ee217c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 5 Aug 2014 22:46:42 -0400 Subject: [PATCH 111/766] Fix response end delay for non-chunked responses fixes #69 --- History.md | 5 +++ index.js | 72 ++++++++++++++++++------------ test/session.js | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 29 deletions(-) diff --git a/History.md b/History.md index 307655a1..03b5c82f 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix response end delay for non-chunked responses + 1.7.3 / 2014-08-05 ================== diff --git a/index.js b/index.js index 9aaf4022..55bf3678 100644 --- a/index.js +++ b/index.js @@ -187,6 +187,8 @@ function session(options){ return false; } + ended = true; + var ret; var sync = true; @@ -194,7 +196,43 @@ function session(options){ chunk = ''; } - ended = true; + function writeend() { + if (sync) { + ret = _end.call(res, chunk, encoding); + sync = false; + return; + } + + _end.call(res); + } + + function writetop() { + if (!sync) { + return ret; + } + + var contentLength = Number(res.getHeader('Content-Length')); + + if (!isNaN(contentLength) && contentLength > 0) { + // measure chunk + chunk = !Buffer.isBuffer(chunk) + ? new Buffer(chunk, encoding) + : chunk; + encoding = undefined; + + if (chunk.length !== 0) { + debug('split response'); + ret = _write.call(res, chunk.slice(0, chunk.length - 1)); + chunk = chunk.slice(chunk.length - 1, chunk.length); + return ret; + } + } + + ret = _write.call(res, chunk, encoding); + sync = false; + + return ret; + } if (shouldDestroy(req)) { // destroy session @@ -205,22 +243,10 @@ function session(options){ } debug('destroyed'); - - if (sync) { - ret = _end.call(res, chunk, encoding); - sync = false; - return; - } - - _end.call(res); + writeend(); }); - if (sync) { - ret = _write.call(res, chunk, encoding); - sync = false; - } - - return ret; + return writetop(); } // no session to save @@ -239,22 +265,10 @@ function session(options){ } debug('saved'); - - if (sync) { - ret = _end.call(res, chunk, encoding); - sync = false; - return; - } - - _end.call(res); + writeend(); }); - if (sync) { - ret = _write.call(res, chunk, encoding); - sync = false; - } - - return ret; + return writetop(); } return _end.call(res, chunk, encoding); diff --git a/test/session.js b/test/session.js index 9d5b277f..0481d78c 100644 --- a/test/session.js +++ b/test/session.js @@ -184,6 +184,120 @@ describe('session()', function(){ .expect(200, 'Hello, world!', done); }) + describe('when response ended', function () { + it('should have saved session', function (done) { + var saved = false + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + res.end('session saved') + }) + + var _set = store.set + store.set = function set(sid, sess, callback) { + setTimeout(function () { + _set.call(store, sid, sess, function (err) { + saved = true + callback(err) + }) + }, 200) + } + + request(server) + .get('/') + .expect(200, 'session saved', function (err) { + if (err) return done(err) + saved.should.be.true + done() + }) + }) + + it('should have saved session even with empty response', function (done) { + var saved = false + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + res.setHeader('Content-Length', '0') + res.end() + }) + + var _set = store.set + store.set = function set(sid, sess, callback) { + setTimeout(function () { + _set.call(store, sid, sess, function (err) { + saved = true + callback(err) + }) + }, 200) + } + + request(server) + .get('/') + .expect(200, '', function (err) { + if (err) return done(err) + saved.should.be.true + done() + }) + }) + + it('should have saved session even with multi-write', function (done) { + var saved = false + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + res.setHeader('Content-Length', '12') + res.write('hello, ') + res.end('world') + }) + + var _set = store.set + store.set = function set(sid, sess, callback) { + setTimeout(function () { + _set.call(store, sid, sess, function (err) { + saved = true + callback(err) + }) + }, 200) + } + + request(server) + .get('/') + .expect(200, 'hello, world', function (err) { + if (err) return done(err) + saved.should.be.true + done() + }) + }) + + it('should have saved session even with non-chunked response', function (done) { + var saved = false + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + res.setHeader('Content-Length', '13') + res.end('session saved') + }) + + var _set = store.set + store.set = function set(sid, sess, callback) { + setTimeout(function () { + _set.call(store, sid, sess, function (err) { + saved = true + callback(err) + }) + }, 200) + } + + request(server) + .get('/') + .expect(200, 'session saved', function (err) { + if (err) return done(err) + saved.should.be.true + done() + }) + }) + }) + describe('when sid not in store', function () { it('should create a new session', function (done) { var count = 0 From 9eade9bd6289ea7ce6d72c8271feb7f99d09fa77 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 5 Aug 2014 22:49:23 -0400 Subject: [PATCH 112/766] 1.7.4 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 03b5c82f..0bdf5cde 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.4 / 2014-08-05 +================== * Fix response end delay for non-chunked responses diff --git a/package.json b/package.json index 349b6fef..4d1aafb7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.3", + "version": "1.7.4", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From e0d168aa4a93c7a41e579101bb3ab1c28f971633 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Aug 2014 20:54:31 -0400 Subject: [PATCH 113/766] build: update copyright --- LICENSE | 4 +++- index.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index a7693b07..f24497a5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,8 @@ (The MIT License) -Copyright (c) 2014 TJ Holowaychuk +Copyright (c) 2010 Sencha Inc. +Copyright (c) 2011 TJ Holowaychuk +Copyright (c) 2014 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/index.js b/index.js index 55bf3678..2c0050b2 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ * express-session * Copyright(c) 2010 Sencha Inc. * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2014 Douglas Christopher Wilson * MIT Licensed */ From 7d64dd1446b84d280e7b54e7f718d6c4267d5e8a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Aug 2014 20:55:02 -0400 Subject: [PATCH 114/766] deps: on-headers@~1.0.0 --- History.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 0bdf5cde..c61ecc58 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: on-headers@~1.0.0 + 1.7.4 / 2014-08-05 ================== diff --git a/package.json b/package.json index 4d1aafb7..6aa8aeb9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "cookie-signature": "1.0.4", "debug": "1.0.4", "depd": "0.4.4", - "on-headers": "0.0.0", + "on-headers": "~1.0.0", "uid-safe": "1.0.1", "utils-merge": "1.0.0" }, From 9020fea5326879b089b6fd4ffb4f8640b020d14c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Aug 2014 21:03:35 -0400 Subject: [PATCH 115/766] Fix parsing original URL --- History.md | 2 ++ index.js | 4 ++-- package.json | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/History.md b/History.md index c61ecc58..f0406857 100644 --- a/History.md +++ b/History.md @@ -1,7 +1,9 @@ unreleased ========== + * Fix parsing original URL * deps: on-headers@~1.0.0 + * deps: parseurl@~1.3.0 1.7.4 / 2014-08-05 ================== diff --git a/index.js b/index.js index 2c0050b2..35ea5a84 100644 --- a/index.js +++ b/index.js @@ -13,10 +13,10 @@ var cookie = require('cookie'); var debug = require('debug')('express-session'); var deprecate = require('depd')('express-session'); +var parseUrl = require('parseurl'); var uid = require('uid-safe').sync , onHeaders = require('on-headers') , crc32 = require('buffer-crc32') - , parse = require('url').parse , signature = require('cookie-signature') var Session = require('./session/session') @@ -138,7 +138,7 @@ function session(options){ if (!storeReady) return debug('store is disconnected'), next(); // pathname mismatch - var originalPath = parse(req.originalUrl || req.url).pathname; + var originalPath = parseUrl.original(req).pathname; if (0 != originalPath.indexOf(cookie.path || '/')) return next(); // backwards compatibility for signed cookies diff --git a/package.json b/package.json index 6aa8aeb9..a1717d1e 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "debug": "1.0.4", "depd": "0.4.4", "on-headers": "~1.0.0", + "parseurl": "~1.3.0", "uid-safe": "1.0.1", "utils-merge": "1.0.0" }, From 84e64d185d5e5a95328979d0bef4a4bf673f6be1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Aug 2014 21:05:14 -0400 Subject: [PATCH 116/766] deps: express@~4.8.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a1717d1e..e0127500 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "1.3.2", "istanbul": "0.3.0", - "express": "~4.6.1", + "express": "~4.8.2", "mocha": "~1.21.0", "should": "~4.0.4", "supertest": "~0.13.0" From 4556a23f105c2b1ac1fa1741b577a1cd4d3f40b0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Aug 2014 21:11:15 -0400 Subject: [PATCH 117/766] 1.7.5 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index f0406857..90b654e2 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.5 / 2014-08-10 +================== * Fix parsing original URL * deps: on-headers@~1.0.0 diff --git a/package.json b/package.json index e0127500..38a92d58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.4", + "version": "1.7.5", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 66db2da03ecc389f5643fc047fe915f4a6e553a7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 Aug 2014 13:45:56 -0400 Subject: [PATCH 118/766] Fix exception on res.end(null) calls fixes #75 --- History.md | 5 +++++ index.js | 2 +- test/session.js | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/History.md b/History.md index 90b654e2..4d0f2fc5 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix exception on `res.end(null)` calls + 1.7.5 / 2014-08-10 ================== diff --git a/index.js b/index.js index 35ea5a84..a84f60d5 100644 --- a/index.js +++ b/index.js @@ -193,7 +193,7 @@ function session(options){ var ret; var sync = true; - if (chunk === undefined) { + if (chunk == null) { chunk = ''; } diff --git a/test/session.js b/test/session.js index 0481d78c..a15f4ef5 100644 --- a/test/session.js +++ b/test/session.js @@ -184,6 +184,16 @@ describe('session()', function(){ .expect(200, 'Hello, world!', done); }) + it('should handle res.end(null) calls', function (done) { + var server = createServer(null, function (req, res) { + res.end(null) + }) + + request(server) + .get('/') + .expect(200, '', done) + }) + describe('when response ended', function () { it('should have saved session', function (done) { var saved = false From aff4daf63a8a989e26c8e2bfd144fd69c753425b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 Aug 2014 14:26:21 -0400 Subject: [PATCH 119/766] 1.7.6 --- History.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/History.md b/History.md index 4d0f2fc5..736d64e9 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,5 @@ -unreleased -========== +1.7.6 / 2014-08-18 +================== * Fix exception on `res.end(null)` calls diff --git a/package.json b/package.json index 38a92d58..7494c9f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.5", + "version": "1.7.6", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 544622565216fdaaf298f8a72be9a5a3deb8f115 Mon Sep 17 00:00:00 2001 From: RafaDev7 Date: Wed, 20 Aug 2014 09:54:29 -0300 Subject: [PATCH 120/766] docs: fix example code commas Closes #80 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dd1ba7ac..a83e8fd7 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,8 @@ If `secure` is set, and you access your site over HTTP, the cookie will not be s var app = express() app.set('trust proxy', 1) // trust first proxy app.use(session({ - secret: 'keyboard cat' - , cookie: { secure: true } + secret: 'keyboard cat', + cookie: { secure: true } })) ``` @@ -73,7 +73,7 @@ For using secure cookies in production, but allowing for testing in development, ```js var app = express() var sess = { - secret: 'keyboard cat' + secret: 'keyboard cat', cookie: {} } From 08f666c43dcf7656d2f72d87e5a922d98d020926 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:38:59 -0400 Subject: [PATCH 121/766] docs: add installation instructions closes #83 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a83e8fd7..945deac6 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,12 @@ THIS REPOSITORY NEEDS A MAINTAINER. If you are interested in maintaining this module, please start contributing by making PRs and solving / discussing unsolved issues. +## Installation + +```bash +$ npm install express-session +``` + ## API ```js From d4c3b7e2d4bd866b44d721ffec65be717a7da517 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:40:31 -0400 Subject: [PATCH 122/766] deps: istanbul@0.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7494c9f6..4622148a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "1.3.2", - "istanbul": "0.3.0", + "istanbul": "0.3.2", "express": "~4.8.2", "mocha": "~1.21.0", "should": "~4.0.4", From b80250ec066e17e6ab96c1a26bad143ff91ba991 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:41:36 -0400 Subject: [PATCH 123/766] build: change capitalization of history file --- History.md => HISTORY.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename History.md => HISTORY.md (100%) diff --git a/History.md b/HISTORY.md similarity index 100% rename from History.md rename to HISTORY.md From c3c87928d729013518333085cda2cac9db446da9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:42:53 -0400 Subject: [PATCH 124/766] deps: update testing dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 4622148a..6002da8e 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,10 @@ }, "devDependencies": { "after": "0.8.1", - "cookie-parser": "1.3.2", + "cookie-parser": "~1.3.3", "istanbul": "0.3.2", - "express": "~4.8.2", - "mocha": "~1.21.0", + "express": "~4.8.8", + "mocha": "~1.21.4", "should": "~4.0.4", "supertest": "~0.13.0" }, From 18493c64b32b2749cb8ef04a6553a242edd72376 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:44:11 -0400 Subject: [PATCH 125/766] deps: cookie-signature@1.0.5 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 736d64e9..7308237b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: cookie-signature@1.0.5 + 1.7.6 / 2014-08-18 ================== diff --git a/package.json b/package.json index 6002da8e..e4ee592e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "buffer-crc32": "0.2.3", "cookie": "0.1.2", - "cookie-signature": "1.0.4", + "cookie-signature": "1.0.5", "debug": "1.0.4", "depd": "0.4.4", "on-headers": "~1.0.0", From a44d3881b34bff14566c9416c208654733eaac40 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:48:16 -0400 Subject: [PATCH 126/766] deps: debug@~2.0.0 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 7308237b..185514b2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * deps: cookie-signature@1.0.5 + * deps: debug@~2.0.0 1.7.6 / 2014-08-18 ================== diff --git a/package.json b/package.json index e4ee592e..33cbac1c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "buffer-crc32": "0.2.3", "cookie": "0.1.2", "cookie-signature": "1.0.5", - "debug": "1.0.4", + "debug": "~2.0.0", "depd": "0.4.4", "on-headers": "~1.0.0", "parseurl": "~1.3.0", From b28b6c69c4aa7f727ab30e66a5c3e6cf62d42a5e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 22:51:15 -0400 Subject: [PATCH 127/766] docs: update badges --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 945deac6..dda00a3a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # express-session -[![NPM Version](https://badge.fury.io/js/express-session.svg)](https://badge.fury.io/js/express-session) -[![Build Status](https://travis-ci.org/expressjs/session.svg?branch=master)](https://travis-ci.org/expressjs/session) -[![Coverage Status](https://img.shields.io/coveralls/expressjs/session.svg?branch=master)](https://coveralls.io/r/expressjs/session) +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] THIS REPOSITORY NEEDS A MAINTAINER. If you are interested in maintaining this module, please start contributing by making PRs and solving / discussing unsolved issues. @@ -206,3 +207,12 @@ Recommended methods include, but are not limited to: - `.clear(callback)` For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. + +[npm-image]: https://img.shields.io/npm/v/express-session.svg?style=flat +[npm-url]: https://npmjs.org/package/express-session +[travis-image]: https://img.shields.io/travis/expressjs/session.svg?style=flat +[travis-url]: https://travis-ci.org/expressjs/session +[coveralls-image]: https://img.shields.io/coveralls/expressjs/session.svg?style=flat +[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master +[downloads-image]: http://img.shields.io/npm/dm/express-session.svg?style=flat +[downloads-url]: https://npmjs.org/package/express-session From c4eafd34efdd59fbbb1df239e485e31048842b58 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 23:02:42 -0400 Subject: [PATCH 128/766] docs: link to license --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dda00a3a..31f4ab42 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,10 @@ Recommended methods include, but are not limited to: For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. +## License + +[MIT](LICENSE) + [npm-image]: https://img.shields.io/npm/v/express-session.svg?style=flat [npm-url]: https://npmjs.org/package/express-session [travis-image]: https://img.shields.io/travis/expressjs/session.svg?style=flat From 34a5c8d058ee43c81e311d5c8f8971174a0de6f8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 23:07:37 -0400 Subject: [PATCH 129/766] Call session.touch instead of session.resetMaxAge --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index a84f60d5..e68dc374 100644 --- a/index.js +++ b/index.js @@ -256,7 +256,8 @@ function session(options){ return _end.call(res, chunk, encoding); } - req.session.resetMaxAge(); + // touch session + req.session.touch(); if (shouldSave(req)) { debug('saving'); From 4f499c78a8e046ef03a3a58eac27bb36c6381472 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 23:16:52 -0400 Subject: [PATCH 130/766] build: remove npmignore file --- .npmignore | 3 --- package.json | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 .npmignore diff --git a/.npmignore b/.npmignore deleted file mode 100644 index cd39b772..00000000 --- a/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -coverage/ -test/ -.travis.yml diff --git a/package.json b/package.json index 33cbac1c..3f53b4d2 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,12 @@ "should": "~4.0.4", "supertest": "~0.13.0" }, + "files": [ + "session/", + "HISTORY.md", + "LICENSE", + "index.js" + ], "engines": { "node": ">= 0.8.0" }, From 268a136f7e2205d1199c4b58833a56de0fd62aad Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 6 Sep 2014 23:50:19 -0400 Subject: [PATCH 131/766] tests: add req.session.save() test --- test/session.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/session.js b/test/session.js index a15f4ef5..aee41140 100644 --- a/test/session.js +++ b/test/session.js @@ -1289,6 +1289,26 @@ describe('session()', function(){ }) }) + describe('.save()', function () { + it('should save session to store', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + req.session.save(function (err) { + if (err) return res.end(err.message) + store.get(req.session.id, function (err, sess) { + if (err) return res.end(err.message) + res.end(sess ? 'stored' : 'empty') + }) + }) + }) + + request(server) + .get('/') + .expect(200, 'stored', done) + }) + }) + describe('.cookie', function(){ describe('.*', function(){ it('should serialize as parameters', function(done){ From 09d6f3ddcc5dbebb6537d0a4ba55f502066057c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 7 Sep 2014 00:50:42 -0400 Subject: [PATCH 132/766] Do not resave already-saved session at end of request closes #74 --- HISTORY.md | 1 + index.js | 50 +++++++++++++++++++++++++++++++++++-------------- test/session.js | 34 +++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 185514b2..fa74d480 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Do not resave already-saved session at end of request * deps: cookie-signature@1.0.5 * deps: debug@~2.0.0 diff --git a/index.js b/index.js index e68dc374..14e2a8ea 100644 --- a/index.js +++ b/index.js @@ -148,8 +148,9 @@ function session(options){ // ensure secret is available or bail if (!secret) next(new Error('`secret` option required for sessions')); - var originalHash - , originalId; + var originalHash; + var originalId; + var savedHash; // expose store req.sessionStore = store; @@ -260,13 +261,11 @@ function session(options){ req.session.touch(); if (shouldSave(req)) { - debug('saving'); req.session.save(function onsave(err) { if (err) { defer(next, err); } - debug('saved'); writeend(); }); @@ -281,11 +280,27 @@ function session(options){ store.generate(req); originalId = req.sessionID; originalHash = hash(req.session); + wrapmethods(req.session); + } + + // wrap session methods + function wrapmethods(sess) { + var _save = sess.save; + sess.save = function save() { + debug('saving %s', this.id); + savedHash = hash(this); + _save.apply(this, arguments); + }; } // check if session has been modified function isModified(sess) { - return originalHash != hash(sess) || originalId != sess.id; + return originalId !== sess.id || originalHash !== hash(sess); + } + + // check if session has been saved + function isSaved(sess) { + return originalId === sess.id && savedHash === hash(sess); } // determine if session should be destroyed @@ -295,9 +310,9 @@ function session(options){ // determine if session should be saved to store function shouldSave(req) { - return cookieId != req.sessionID - ? saveUninitializedSession || isModified(req.session) - : resaveSession || isModified(req.session); + return !saveUninitializedSession && cookieId !== req.sessionID + ? isModified(req.session) + : !isSaved(req.session) } // determine if cookie should be set on response @@ -326,25 +341,32 @@ function session(options){ // error handling if (err) { debug('error %j', err); - if ('ENOENT' == err.code) { - generate(); - next(); - } else { + + if (err.code !== 'ENOENT') { next(err); + return; } + + generate(); // no session } else if (!sess) { debug('no session found'); generate(); - next(); // populate req.session } else { debug('session found'); store.createSession(req, sess); originalId = req.sessionID; originalHash = hash(sess); - next(); + + if (!resaveSession) { + savedHash = originalHash + } + + wrapmethods(req.session); } + + next(); }); }; }; diff --git a/test/session.js b/test/session.js index aee41140..e49557b6 100644 --- a/test/session.js +++ b/test/session.js @@ -1307,6 +1307,40 @@ describe('session()', function(){ .get('/') .expect(200, 'stored', done) }) + + it('should prevent end-of-request save', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + req.session.save(function (err) { + if (err) return res.end(err.message) + res.end('saved') + }) + }) + + var _set = store.set + store.set = function set(sid, sess, callback) { + count++ + _set.call(store, sid, sess, callback) + } + + request(server) + .get('/') + .expect(200, 'saved', function (err, res) { + if (err) return done(err) + count.should.equal(1) + count = 0 + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'saved', function (err) { + if (err) return done(err) + count.should.equal(1) + done() + }) + }) + }) }) describe('.cookie', function(){ From 5936c250f1ff9c0325d93557e76eeec71cbec074 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 7 Sep 2014 00:54:35 -0400 Subject: [PATCH 133/766] docs: i'm basically maintaining this --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 31f4ab42..4b350003 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] - -THIS REPOSITORY NEEDS A MAINTAINER. -If you are interested in maintaining this module, please start contributing by making PRs and solving / discussing unsolved issues. +[![Gratipay][gratipay-image]][gratipay-url] ## Installation @@ -220,3 +218,5 @@ For an example implementation view the [connect-redis](http://github.com/visionm [coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master [downloads-image]: http://img.shields.io/npm/dm/express-session.svg?style=flat [downloads-url]: https://npmjs.org/package/express-session +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat +[gratipay-url]: https://gratipay.com/dougwilson/ From 8abd65d8974c2f1931497a5b3ab4ff12315d9625 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 7 Sep 2014 23:09:49 -0400 Subject: [PATCH 134/766] 1.8.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index fa74d480..57e7e8c4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.8.0 / 2014-09-07 +================== * Do not resave already-saved session at end of request * deps: cookie-signature@1.0.5 diff --git a/package.json b/package.json index 3f53b4d2..e1a31dff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.7.6", + "version": "1.8.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From cd6b0879af2792aeb832bf072dd73327f54adde6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 8 Sep 2014 16:38:26 -0400 Subject: [PATCH 135/766] Prevent session prototype methods from being overwritten fixes #85 --- HISTORY.md | 5 +++++ session/session.js | 18 +++++++++++++----- test/session.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 57e7e8c4..ddf6b13b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Prevent session prototype methods from being overwritten + 1.8.0 / 2014-09-07 ================== diff --git a/session/session.js b/session/session.js index 891f31c7..4647f9da 100644 --- a/session/session.js +++ b/session/session.js @@ -7,10 +7,10 @@ */ /** - * Module dependencies. + * Expose Session. */ -var merge = require('utils-merge') +module.exports = Session; /** * Create a new `Session` with the given request and `data`. @@ -20,11 +20,19 @@ var merge = require('utils-merge') * @api private */ -var Session = module.exports = function Session(req, data) { +function Session(req, data) { Object.defineProperty(this, 'req', { value: req }); Object.defineProperty(this, 'id', { value: req.sessionID }); - if ('object' == typeof data) merge(this, data); -}; + + if (typeof data === 'object' && data !== null) { + // merge data into this, ignoring prototype properties + for (var prop in data) { + if (!(prop in this)) { + this[prop] = data[prop] + } + } + } +} /** * Update reset `.cookie.maxAge` to prevent diff --git a/test/session.js b/test/session.js index e49557b6..31e0f5e7 100644 --- a/test/session.js +++ b/test/session.js @@ -194,6 +194,35 @@ describe('session()', function(){ .expect(200, '', done) }) + it('should handle reserved properties in storage', function (done) { + var count = 0 + var sid + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + sid = req.session.id + req.session.num = req.session.num || ++count + res.end('session saved') + }) + + request(server) + .get('/') + .expect(200, 'session saved', function (err, res) { + if (err) return done(err) + store.get(sid, function (err, sess) { + if (err) return done(err) + // save is reserved + sess.save = 'nope' + store.set(sid, sess, function (err) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'session saved', done) + }) + }) + }) + }) + describe('when response ended', function () { it('should have saved session', function (done) { var saved = false From 5bc59f16a0e61582ba4d926cfbb6448f0c137a52 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 8 Sep 2014 17:00:45 -0400 Subject: [PATCH 136/766] Keep req.session.save non-enumerable --- HISTORY.md | 1 + index.js | 12 ++++++++++-- test/session.js | 14 +++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ddf6b13b..f391a999 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Keep `req.session.save` non-enumerable * Prevent session prototype methods from being overwritten 1.8.0 / 2014-09-07 diff --git a/index.js b/index.js index 14e2a8ea..e7c95823 100644 --- a/index.js +++ b/index.js @@ -286,11 +286,19 @@ function session(options){ // wrap session methods function wrapmethods(sess) { var _save = sess.save; - sess.save = function save() { + + function save() { debug('saving %s', this.id); savedHash = hash(this); _save.apply(this, arguments); - }; + } + + Object.defineProperty(sess, 'save', { + configurable: true, + enumerable: false, + value: save, + writable: true + }); } // check if session has been modified diff --git a/test/session.js b/test/session.js index 31e0f5e7..82383f5c 100644 --- a/test/session.js +++ b/test/session.js @@ -223,6 +223,18 @@ describe('session()', function(){ }) }) + it('should only have session data enumerable (and cookie)', function (done) { + var server = createServer(null, function (req, res) { + req.session.test1 = 1 + req.session.test2 = 'b' + res.end(Object.keys(req.session).sort().join(',')) + }) + + request(server) + .get('/') + .expect(200, 'cookie,test1,test2', done) + }) + describe('when response ended', function () { it('should have saved session', function (done) { var saved = false @@ -483,7 +495,7 @@ describe('session()', function(){ should(sid(res)).not.equal(val) done() }) - }, 10) + }, 15) }) }) From 31f3056c7d50f2467982139cc0b2cf412a26c6e0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 8 Sep 2014 17:19:17 -0400 Subject: [PATCH 137/766] docs: fix non-https badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b350003..5e889faa 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ For an example implementation view the [connect-redis](http://github.com/visionm [travis-url]: https://travis-ci.org/expressjs/session [coveralls-image]: https://img.shields.io/coveralls/expressjs/session.svg?style=flat [coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master -[downloads-image]: http://img.shields.io/npm/dm/express-session.svg?style=flat +[downloads-image]: https://img.shields.io/npm/dm/express-session.svg?style=flat [downloads-url]: https://npmjs.org/package/express-session [gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat [gratipay-url]: https://gratipay.com/dougwilson/ From 4162de30bd642a3cfbdc74e69c1ffbf611c750db Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 8 Sep 2014 17:24:43 -0400 Subject: [PATCH 138/766] 1.8.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f391a999..8f73c60c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.8.1 / 2014-09-08 +================== * Keep `req.session.save` non-enumerable * Prevent session prototype methods from being overwritten diff --git a/package.json b/package.json index e1a31dff..d10c0d71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.8.0", + "version": "1.8.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 45e936bd5326cceca5f08ff4e16cc1a6d5d2be65 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Sep 2014 23:02:52 -0700 Subject: [PATCH 139/766] deps: depd@0.4.5 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8f73c60c..e2052199 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: depd@0.4.5 + 1.8.1 / 2014-09-08 ================== diff --git a/package.json b/package.json index d10c0d71..db07afca 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.5", "debug": "~2.0.0", - "depd": "0.4.4", + "depd": "0.4.5", "on-headers": "~1.0.0", "parseurl": "~1.3.0", "uid-safe": "1.0.1", From f7697d71ce30aefdd49c54603cbaf49c11c9daa5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Sep 2014 23:08:21 -0700 Subject: [PATCH 140/766] Use crc instead of buffer-crc32 for speed --- HISTORY.md | 1 + index.js | 8 +++++--- package.json | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e2052199..cfe7e981 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Use `crc` instead of `buffer-crc32` for speed * deps: depd@0.4.5 1.8.1 / 2014-09-08 diff --git a/index.js b/index.js index e7c95823..156b97dd 100644 --- a/index.js +++ b/index.js @@ -11,12 +11,12 @@ */ var cookie = require('cookie'); +var crc = require('crc').crc32; var debug = require('debug')('express-session'); var deprecate = require('depd')('express-session'); var parseUrl = require('parseurl'); var uid = require('uid-safe').sync , onHeaders = require('on-headers') - , crc32 = require('buffer-crc32') , signature = require('cookie-signature') var Session = require('./session/session') @@ -465,8 +465,10 @@ function getcookie(req, name, secret) { */ function hash(sess) { - return crc32.signed(JSON.stringify(sess, function(key, val){ - if ('cookie' != key) return val; + return crc(JSON.stringify(sess, function (key, val) { + if (key !== 'cookie') { + return val; + } })); } diff --git a/package.json b/package.json index db07afca..7c3fc930 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,9 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "buffer-crc32": "0.2.3", "cookie": "0.1.2", "cookie-signature": "1.0.5", + "crc": "3.0.0", "debug": "~2.0.0", "depd": "0.4.5", "on-headers": "~1.0.0", From 1754869a0de23dc87e0e2d4826fe702cc13b0515 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Sep 2014 23:11:21 -0700 Subject: [PATCH 141/766] 1.8.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index cfe7e981..4721c9c6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.8.2 / 2014-09-15 +================== * Use `crc` instead of `buffer-crc32` for speed * deps: depd@0.4.5 diff --git a/package.json b/package.json index 7c3fc930..3a344e26 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.8.1", + "version": "1.8.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 5c2d4ff904affe62ea615c2a7dc3dc727f512c7b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Oct 2014 00:56:40 -0400 Subject: [PATCH 142/766] deps: supertest@~0.14.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a344e26..7e9c4816 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "~4.8.8", "mocha": "~1.21.4", "should": "~4.0.4", - "supertest": "~0.13.0" + "supertest": "~0.14.0" }, "files": [ "session/", From 7193f8d2fe56387a494b2e7da8f788a347ebbd79 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 17 Oct 2014 01:35:36 -0400 Subject: [PATCH 143/766] deps: depd@~1.0.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 4721c9c6..6e914cda 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: depd@~1.0.0 + 1.8.2 / 2014-09-15 ================== diff --git a/package.json b/package.json index 7e9c4816..d2cb1f46 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.5", "crc": "3.0.0", "debug": "~2.0.0", - "depd": "0.4.5", + "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", "uid-safe": "1.0.1", From f5d1057b37ce8aa188bd971aa7954263b4ecb175 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 17 Oct 2014 01:36:17 -0400 Subject: [PATCH 144/766] deps: debug@~2.1.0 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6e914cda..9d3ad5e7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * deps: debug@~2.1.0 + - Implement `DEBUG_FD` env variable support * deps: depd@~1.0.0 1.8.2 / 2014-09-15 diff --git a/package.json b/package.json index d2cb1f46..d22f8677 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.5", "crc": "3.0.0", - "debug": "~2.0.0", + "debug": "~2.1.0", "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", From ff14bac227216093c75035a65a95c3cc673b8e21 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 17 Oct 2014 01:36:42 -0400 Subject: [PATCH 145/766] deps: mocha@~1.21.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d22f8677..945d52f3 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.3", "istanbul": "0.3.2", "express": "~4.8.8", - "mocha": "~1.21.4", + "mocha": "~1.21.5", "should": "~4.0.4", "supertest": "~0.14.0" }, From 4fc45034c5a6e067c92cbf6d12b3931f3ca01968 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 17 Oct 2014 01:37:05 -0400 Subject: [PATCH 146/766] deps: express@~4.9.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 945d52f3..bd21c8d3 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.3.3", "istanbul": "0.3.2", - "express": "~4.8.8", + "express": "~4.9.7", "mocha": "~1.21.5", "should": "~4.0.4", "supertest": "~0.14.0" From 5a1c65859730d013f11f37b5ceef14e9d186f0fb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 17 Oct 2014 01:45:19 -0400 Subject: [PATCH 147/766] build: improve jsdoc comments --- index.js | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index 156b97dd..1eb180f0 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ /** * Module dependencies. + * @private */ var cookie = require('cookie'); @@ -45,6 +46,7 @@ exports.MemoryStore = MemoryStore; /** * Warning message for `MemoryStore` usage in production. + * @private */ var warning = 'Warning: connect.session() MemoryStore is not\n' @@ -53,6 +55,7 @@ var warning = 'Warning: connect.session() MemoryStore is not\n' /** * Node.js 0.8+ async implementation. + * @private */ /* istanbul ignore next */ @@ -63,15 +66,19 @@ var defer = typeof setImmediate === 'function' /** * Setup session store with the given `options`. * - * See README.md for documentation of options and formatting. - * - * Session data is _not_ saved in the cookie itself, however cookies are used, - * so you must use the cookie-parser middleware _before_ `session()`. - * [https://github.com/expressjs/cookie-parser] - * - * @param {Object} options + * @param {Object} [options] + * @param {Object} [options.cookie] Options for cookie + * @param {Function} [options.genid] + * @param {String} [options.name=connect.sid] Session ID cookie name + * @param {Boolean} [options.proxy] + * @param {Boolean} [options.resave] Resave unmodified sessions back to the store + * @param {Boolean} [options.rolling] Enable/disable rolling session expiration + * @param {Boolean} [options.saveUninitialized] Save uninitialized sessions to the store + * @param {String} [options.secret] Secret for signing session ID + * @param {Object} [options.store=MemoryStore] Session store + * @param {String} [options.unset] * @return {Function} middleware - * @api public + * @public */ function session(options){ @@ -383,7 +390,7 @@ function session(options){ * Generate a session ID for a new session. * * @return {String} - * @api private + * @private */ function generateSessionId(sess) { @@ -394,7 +401,7 @@ function generateSessionId(sess) { * Get the session ID cookie from request. * * @return {string} - * @api private + * @private */ function getcookie(req, name, secret) { @@ -461,7 +468,7 @@ function getcookie(req, name, secret) { * * @param {Object} sess * @return {String} - * @api private + * @private */ function hash(sess) { @@ -478,7 +485,7 @@ function hash(sess) { * @param {Object} req * @param {Boolean} [trustProxy] * @return {Boolean} - * @api private + * @private */ function issecure(req, trustProxy) { @@ -510,6 +517,12 @@ function issecure(req, trustProxy) { return proto === 'https'; } +/** + * Set cookie on response. + * + * @private + */ + function setcookie(res, name, val, secret, options) { var signed = 's:' + signature.sign(val, secret); var data = cookie.serialize(name, signed, options); From 3fe48f0523c43804d7ebd55aea9d10d4a83f8f8e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 17 Oct 2014 02:19:28 -0400 Subject: [PATCH 148/766] 1.9.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9d3ad5e7..e719c3ad 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.9.0 / 2014-09-16 +================== * deps: debug@~2.1.0 - Implement `DEBUG_FD` env variable support diff --git a/package.json b/package.json index bd21c8d3..bd297f51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.8.2", + "version": "1.9.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From a7fc04b0e486f3d11487bb886840ffb18651ee7b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 22 Oct 2014 17:13:51 -0400 Subject: [PATCH 149/766] deps: mocha@~2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd297f51..880606f9 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.3", "istanbul": "0.3.2", "express": "~4.9.7", - "mocha": "~1.21.5", + "mocha": "~2.0.0", "should": "~4.0.4", "supertest": "~0.14.0" }, From 6ede05cb1538fa927a3a9cb8e7bb4ae6d4280e82 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 22 Oct 2014 17:14:24 -0400 Subject: [PATCH 150/766] deps: should@~4.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 880606f9..7d89ed5d 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "istanbul": "0.3.2", "express": "~4.9.7", "mocha": "~2.0.0", - "should": "~4.0.4", + "should": "~4.1.0", "supertest": "~0.14.0" }, "files": [ From 6a0cd2d0a297fed2926d12480ad491923d58a373 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 22 Oct 2014 17:39:19 -0400 Subject: [PATCH 151/766] Remove unnecessary empty write call --- HISTORY.md | 7 +++++++ index.js | 9 +++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e719c3ad..6f1fc555 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * Remove unnecessary empty write call + - Fixes Node.js 0.11.14 behavior change + - Helps work-around Node.js 0.10.1 zlib bug + 1.9.0 / 2014-09-16 ================== diff --git a/index.js b/index.js index 1eb180f0..eaf7036c 100644 --- a/index.js +++ b/index.js @@ -201,10 +201,6 @@ function session(options){ var ret; var sync = true; - if (chunk == null) { - chunk = ''; - } - function writeend() { if (sync) { ret = _end.call(res, chunk, encoding); @@ -220,6 +216,11 @@ function session(options){ return ret; } + if (chunk == null) { + ret = true; + return ret; + } + var contentLength = Number(res.getHeader('Content-Length')); if (!isNaN(contentLength) && contentLength > 0) { From 4d042270a9774ddfaacfdea197f8c3a2e740172c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 22 Oct 2014 17:49:42 -0400 Subject: [PATCH 152/766] 1.9.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6f1fc555..d66ddd19 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.9.1 / 2014-10-22 +================== * Remove unnecessary empty write call - Fixes Node.js 0.11.14 behavior change diff --git a/package.json b/package.json index 7d89ed5d..9418b4da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.9.0", + "version": "1.9.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 9e443b5767932f7951cb1fcaa5a116afb0444fac Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 00:16:50 -0500 Subject: [PATCH 153/766] deps: supertest@~0.15.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9418b4da..9c7ac789 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "~4.9.7", "mocha": "~2.0.0", "should": "~4.1.0", - "supertest": "~0.14.0" + "supertest": "~0.15.0" }, "files": [ "session/", From f2343ff0de690a374e4185f46d835f3d4118a162 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 00:19:11 -0500 Subject: [PATCH 154/766] deps: mocha@~2.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c7ac789..2a511abc 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.3", "istanbul": "0.3.2", "express": "~4.9.7", - "mocha": "~2.0.0", + "mocha": "~2.0.1", "should": "~4.1.0", "supertest": "~0.15.0" }, From 1776e209d95a80d5649313e3d1c9866d08627830 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 00:24:06 -0500 Subject: [PATCH 155/766] deps: should@~4.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a511abc..2bfe80b5 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "istanbul": "0.3.2", "express": "~4.9.7", "mocha": "~2.0.1", - "should": "~4.1.0", + "should": "~4.3.0", "supertest": "~0.15.0" }, "files": [ From 1f4f65ee8de76efeb4709e46a02cf78955dcb221 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 00:26:39 -0500 Subject: [PATCH 156/766] tests: increase flaky test timeout --- test/session.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/session.js b/test/session.js index 82383f5c..a9e870aa 100644 --- a/test/session.js +++ b/test/session.js @@ -467,7 +467,7 @@ describe('session()', function(){ .get('/') .set('Cookie', cookie(res)) .expect(200, 'session 2', done) - }, 10) + }, 20) }) }) From ecdda698907eb79480dae5f334ad540bc6459ff5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 00:28:58 -0500 Subject: [PATCH 157/766] deps: crc@3.2.1 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d66ddd19..4ddfa276 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: crc@3.2.1 + - Minor fixes + 1.9.1 / 2014-10-22 ================== diff --git a/package.json b/package.json index 2bfe80b5..016af2a2 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.1.2", "cookie-signature": "1.0.5", - "crc": "3.0.0", + "crc": "3.2.1", "debug": "~2.1.0", "depd": "~1.0.0", "on-headers": "~1.0.0", From a52e0740539204caa278bce16563472c5c868b83 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 00:53:34 -0500 Subject: [PATCH 158/766] tests: add https server test --- test/fixtures/server.crt | 14 +++++++++ test/fixtures/server.key | 15 +++++++++ test/session.js | 68 ++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 test/fixtures/server.crt create mode 100644 test/fixtures/server.key diff --git a/test/fixtures/server.crt b/test/fixtures/server.crt new file mode 100644 index 00000000..c019198a --- /dev/null +++ b/test/fixtures/server.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICMzCCAZwCCQCJTms0qcIZgDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHSW5kaWFuYTEdMBsGA1UEChMUbm9kZS1leHByZXNzLXNlc3Np +b24xHjAcBgNVBAMTFWV4cHJlc3Mtc2Vzc2lvbi5sb2NhbDAeFw0xNDExMjMwNTQ3 +MzlaFw0yNDExMjAwNTQ3MzlaMF4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdJbmRp +YW5hMR0wGwYDVQQKExRub2RlLWV4cHJlc3Mtc2Vzc2lvbjEeMBwGA1UEAxMVZXhw +cmVzcy1zZXNzaW9uLmxvY2FsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY +G398zqN6Yv/FAx77eoLLje4VNCYDXUciWBzceaZ5u/rtP/XshTQWDKFfUbb/kmni +DazsCasSoNsUCrcqQPJF1jF3F9XjsZxcggDab8MAbAMhnhJax2l3yPJsWnB/8mrY +cdsdQNPXJxQW9MMZgUxz73gIY5/rEeayU9owgcnVcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBADi0XXsZlQAKxOyD4qvdJNWJXlfqhr1q53dZmfF7nikDaMDiMspczTS/ +pxNbq2UaMc7g+6qmXPaPQoN3laQQtMdyVfSh6EIJHbzXXzdcCT4fDBYX7iwvh0Gg +DUpjmxmCzFCaob9+hZzwbJi5MFQ4Qq12LW1aYHMs8wgLboHml1WL +-----END CERTIFICATE----- diff --git a/test/fixtures/server.key b/test/fixtures/server.key new file mode 100644 index 00000000..dabf2b83 --- /dev/null +++ b/test/fixtures/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDYG398zqN6Yv/FAx77eoLLje4VNCYDXUciWBzceaZ5u/rtP/Xs +hTQWDKFfUbb/kmniDazsCasSoNsUCrcqQPJF1jF3F9XjsZxcggDab8MAbAMhnhJa +x2l3yPJsWnB/8mrYcdsdQNPXJxQW9MMZgUxz73gIY5/rEeayU9owgcnVcQIDAQAB +AoGBALB8HGw/kPA1Ay3Qc6/qCADWYvW8BcM/nQUmMkO3sUW/R5gTYPIMglHzdKIU +aL9kwcXTZ0HIT4ZCCUffzF/cdD0lqCZjwGl0aM4xUZcPbaM/KmZOUcP92ymsN+rF +uuJXks6hxrmJ5hh5D6FXdlQjTCdG3u9w0+KD4n1BkBkEaqflAkEA9q4TBt1bLOvV +bbwz7bunI6bwS5eD7sVn1qUqrm6hcirhF1xCv75pO/uqAyccbguxjp8y2LNuN+cO +IgSwr+Jq1wJBAOBFuKSMAcg2WmJ4IAT7143yhoHKMgA8Nl4sfLFwFl2/hw+fdEBe +gndRfKHT4IV/YLcnS7d/H6mEMSAusWx5QPcCQQDTYaF+TWrW2JRAf3jEK/xyiZf6 +PrDYh6KOhWRIqxZ/fYz69p1gL6t/sg0ivH4ZMr4JKBRrK360OrOapQg+/7drAkB6 +3pfPRok/aE/SfN+F+3fX49Q/TUhhipt6ssLJ74/BYsobDBADqAOwXSt7+XmbifKx +xUydRn9RPwQvDoXT2QZ3AkAdnwR9PMEHAsaibrPyzBztKjPL2rWBRk1QAmcdrTpt +XL99XfmkERWtiBA/Lz2K332qYOa/zo5c/SADx9fm7+HP +-----END RSA PRIVATE KEY----- diff --git a/test/session.js b/test/session.js index a9e870aa..883f2572 100644 --- a/test/session.js +++ b/test/session.js @@ -2,14 +2,16 @@ process.env.NO_DEPRECATION = 'express-session'; var after = require('after') +var assert = require('assert') var express = require('express') - , assert = require('assert') , request = require('supertest') , should = require('should') , cookieParser = require('cookie-parser') , session = require('../') , Cookie = require('../session/cookie') -var http = require('http'); +var fs = require('fs') +var http = require('http') +var https = require('https') var min = 60 * 1000; @@ -1492,20 +1494,42 @@ describe('session()', function(){ }) describe('.secure', function(){ + var app + + before(function () { + app = createRequestListener({ secret: 'keyboard cat', cookie: { secure: true } }) + }) + + it('should set cookie when secure', function (done) { + var cert = fs.readFileSync(__dirname + '/fixtures/server.crt', 'ascii') + var server = https.createServer({ + key: fs.readFileSync(__dirname + '/fixtures/server.key', 'ascii'), + cert: cert + }) + + server.on('request', app) + + var agent = new https.Agent({ca: cert}) + var createConnection = agent.createConnection + + agent.createConnection = function (options) { + options.servername = 'express-session.local' + return createConnection.call(this, options) + } + + var req = request(server).get('/') + req.agent(agent) + req.expect('Set-Cookie', /connect\.sid=/) + req.expect(200, done) + }) + it('should not set-cookie when insecure', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat' })) - .use(function(req, res, next){ - req.session.cookie.secure = true; - res.end(); - }); + var server = http.createServer(app) - request(app) + request(server) .get('/') - .end(function(err, res){ - res.headers.should.not.have.property('set-cookie'); - done(); - }); + .expect(doesNotHaveHeader('Set-Cookie')) + .expect(200, done) }) }) @@ -1837,10 +1861,16 @@ function cookie(res) { } function createServer(opts, fn) { + return http.createServer(createRequestListener(opts, fn)) +} + +function createRequestListener(opts, fn) { var _session = createSession(opts) var respond = fn || end - var server = http.createServer(function (req, res) { + return function onRequest(req, res) { + var server = this + _session(req, res, function (err) { if (err && !res._header) { res.statusCode = err.status || 500 @@ -1855,9 +1885,7 @@ function createServer(opts, fn) { respond(req, res) }) - }) - - return server + } } function createSession(opts) { @@ -1874,6 +1902,12 @@ function createSession(opts) { return session(options) } +function doesNotHaveHeader(header) { + return function (res) { + assert.ok(!(header.toLowerCase() in res.headers), 'should not have ' + header + ' header') + } +} + function end(req, res) { res.end() } From b7f57dc7d353998015fcbb77f58b286ef0b4a452 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 01:23:59 -0500 Subject: [PATCH 159/766] tests: minor test clean up --- test/session.js | 78 ++++++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/test/session.js b/test/session.js index 883f2572..704b8de2 100644 --- a/test/session.js +++ b/test/session.js @@ -691,21 +691,15 @@ describe('session()', function(){ it('should default to "connect.sid"', function(done){ request(createServer()) .get('/') - .end(function(err, res){ - res.headers['set-cookie'].should.have.length(1); - res.headers['set-cookie'][0].should.match(/^connect\.sid/); - done(); - }); + .expect('Set-Cookie', /connect\.sid=/) + .expect(200, done) }) it('should allow overriding', function(done){ - request(createServer({ key: 'sid' })) + request(createServer({ key: 'session_id' })) .get('/') - .end(function(err, res){ - res.headers['set-cookie'].should.have.length(1); - res.headers['set-cookie'][0].should.match(/^sid/); - done(); - }); + .expect('Set-Cookie', /session_id=/) + .expect(200, done) }) }) @@ -1177,31 +1171,30 @@ describe('session()', function(){ request(app) .get('/') - .end(function(err, res){ - res.text.should.equal('1'); - + .expect(200, '1', function (err, res) { + if (err) return done(err) request(app) .get('/') .set('Cookie', cookie(res)) - .end(function(err, res){ + .expect(200, '2', function (err, res) { + if (err) return done(err) var val = cookie(res); - res.text.should.equal('2'); modify = false; request(app) .get('/') .set('Cookie', val) - .end(function(err, res){ + .expect(200, '2', function (err, res) { + if (err) return done(err) should(sid(res)).be.empty; - res.text.should.equal('2'); modify = true; request(app) .get('/') .set('Cookie', val) - .end(function(err, res){ + .expect(200, '3', function (err, res) { + if (err) return done(err) sid(res).should.not.be.empty; - res.text.should.equal('3'); done(); }); }); @@ -1223,10 +1216,8 @@ describe('session()', function(){ request(app) .get('/') - .end(function(err, res){ - res.headers.should.not.have.property('set-cookie'); - done(); - }); + .expect(doesNotHaveHeader('Set-Cookie')) + .expect(200, done) }) }) @@ -1435,16 +1426,14 @@ describe('session()', function(){ request(app) .get('/admin/foo') - .end(function(err, res){ - res.headers.should.have.property('set-cookie'); - + .expect('Set-Cookie', /connect\.sid=/) + .expect(200, function (err, res) { + if (err) return done(err) request(app) .get('/admin') .set('Cookie', cookie(res)) - .end(function(err, res){ - res.headers.should.not.have.property('set-cookie'); - done(); - }) + .expect(doesNotHaveHeader('Set-Cookie')) + .expect(200, done) }); }) @@ -1547,11 +1536,8 @@ describe('session()', function(){ request(app) .get('/') - .end(function(err, res){ - res.status.should.equal(200); - res.headers.should.not.have.property('set-cookie'); - done(); - }); + .expect(doesNotHaveHeader('Set-Cookie')) + .expect(200, done) }) it('should not set-cookie even for FQDN', function(done){ @@ -1569,11 +1555,8 @@ describe('session()', function(){ request(app) .get('/') .set('host', 'http://foo/bar') - .end(function(err, res){ - res.status.should.equal(200); - res.headers.should.not.have.property('set-cookie'); - done(); - }); + .expect(doesNotHaveHeader('Set-Cookie')) + .expect(200, done) }) }) @@ -1588,10 +1571,8 @@ describe('session()', function(){ request(app) .get('/foo/bar/baz') - .end(function(err, res){ - res.headers.should.have.property('set-cookie'); - done(); - }); + .expect('Set-Cookie', /connect\.sid=/) + .expect(200, done) }) it('should set-cookie even for FQDN', function(done){ @@ -1605,11 +1586,8 @@ describe('session()', function(){ request(app) .get('/foo/bar/baz') .set('host', 'http://example.com') - .end(function(err, res){ - res.status.should.equal(200); - res.headers.should.have.property('set-cookie'); - done(); - }); + .expect('Set-Cookie', /connect\.sid=/) + .expect(200, done) }) }) From 558ed15add6428762512f55a649def0d92d44d23 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 01:27:48 -0500 Subject: [PATCH 160/766] 1.9.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 4ddfa276..ec99141f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.9.2 / 2014-11-22 +================== * deps: crc@3.2.1 - Minor fixes diff --git a/package.json b/package.json index 016af2a2..5dc8af9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.9.1", + "version": "1.9.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 3a6939e84b33999e0a075870e2d82a86ef19792c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 13:13:40 -0500 Subject: [PATCH 161/766] docs: add more information about resave option --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e889faa..a1e10a08 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,10 @@ var session = require('express-session') var app = express() -app.use(session({secret: 'keyboard cat'})) +app.use(session({ + secret: 'keyboard cat', + resave: false +})) ``` @@ -39,7 +42,7 @@ Session data is _not_ saved in the cookie itself, just the session ID. - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - `genid` - function to call to generate a new session ID. (default: uses `uid2` library) - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - - `resave` - forces session to be saved even when unmodified. (default: `true`) + - `resave` - forces session to be saved even when unmodified. (default: `true`, but using the default has been deprecated. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. This is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. (default: `true`) - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) @@ -59,6 +62,10 @@ app.use(session({ })) ``` +#### options.resave + +Forces the session to be saved back to the session store, even if the session was never modified during the request. Depending on your store this may be necessary, but it can also create race conditions where a client has two parallel requests to your server and changes made to the session in one request may get overwritten when the other request ends, even if it made no changes (this behavior also depends on what store you're using). + #### Cookie options Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. @@ -69,6 +76,7 @@ var app = express() app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 'keyboard cat', + resave: false, cookie: { secure: true } })) ``` From 3b44b8c9a4b847e7e0ffcad24e21fd98915ce634 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 13:17:54 -0500 Subject: [PATCH 162/766] docs: add more information about saveUninitialized option --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1e10a08..779b2043 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ var app = express() app.use(session({ secret: 'keyboard cat', - resave: false + resave: false, + saveUninitialized: true })) ``` @@ -44,7 +45,7 @@ Session data is _not_ saved in the cookie itself, just the session ID. - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`, but using the default has been deprecated. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. This is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. (default: `true`) + - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. (default: `true`, but using the default has been deprecated. Please research into this setting and choose what is appropriate to your use-case) - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) #### options.genid @@ -66,6 +67,10 @@ app.use(session({ Forces the session to be saved back to the session store, even if the session was never modified during the request. Depending on your store this may be necessary, but it can also create race conditions where a client has two parallel requests to your server and changes made to the session in one request may get overwritten when the other request ends, even if it made no changes (this behavior also depends on what store you're using). +#### options.saveUninitialized + +Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choose `false` will also help with race conditions where a client makes multiple parallel requests without a session. + #### Cookie options Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. @@ -77,6 +82,7 @@ app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 'keyboard cat', resave: false, + saveUninitialized: true, cookie: { secure: true } })) ``` From 4a2af29a79efffe5ed096b6bb1b0c8bf19edf02d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 23 Nov 2014 14:43:31 -0500 Subject: [PATCH 163/766] docs: add future change note --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 779b2043..9565b49e 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ Session data is _not_ saved in the cookie itself, just the session ID. - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - `genid` - function to call to generate a new session ID. (default: uses `uid2` library) - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - - `resave` - forces session to be saved even when unmodified. (default: `true`, but using the default has been deprecated. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`) + - `resave` - forces session to be saved even when unmodified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. (default: `true`, but using the default has been deprecated. Please research into this setting and choose what is appropriate to your use-case) + - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case) - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) #### options.genid From ce714b9fdb01d39033698f97367fb66cf23fe51b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 2 Dec 2014 22:59:27 -0500 Subject: [PATCH 164/766] Fix error when req.sessionID contains a non-string value fixes #103 --- HISTORY.md | 5 +++++ index.js | 11 +++++++++++ test/session.js | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index ec99141f..dec5ce20 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix error when `req.sessionID` contains a non-string value + 1.9.2 / 2014-11-22 ================== diff --git a/index.js b/index.js index eaf7036c..e48a879b 100644 --- a/index.js +++ b/index.js @@ -326,6 +326,12 @@ function session(options){ // determine if session should be saved to store function shouldSave(req) { + // cannot set cookie without a session ID + if (typeof req.sessionID !== 'string') { + debug('session ignored because of bogus req.sessionID %o', req.sessionID); + return false; + } + return !saveUninitializedSession && cookieId !== req.sessionID ? isModified(req.session) : !isSaved(req.session) @@ -333,6 +339,11 @@ function session(options){ // determine if cookie should be set on response function shouldSetCookie(req) { + // cannot set cookie without a session ID + if (typeof req.sessionID !== 'string') { + return false; + } + // in case of rolling session, always reset the cookie if (rollingSessions) { return true; diff --git a/test/session.js b/test/session.js index 704b8de2..e7b4f92d 100644 --- a/test/session.js +++ b/test/session.js @@ -237,6 +237,28 @@ describe('session()', function(){ .expect(200, 'cookie,test1,test2', done) }) + it('should not save with bogus req.sessionID', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.sessionID = function () {} + req.session.test1 = 1 + req.session.test2 = 'b' + res.end() + }) + + request(server) + .get('/') + .expect(doesNotHaveHeader('Set-Cookie')) + .expect(200, function (err) { + if (err) return done(err) + store.length(function (err, length) { + if (err) return done(err) + assert.equal(length, 0) + done() + }) + }) + }) + describe('when response ended', function () { it('should have saved session', function (done) { var saved = false From 945e2acfa5fc96d722cd84bff424f3d6f93afc95 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 2 Dec 2014 23:01:40 -0500 Subject: [PATCH 165/766] 1.9.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index dec5ce20..6e0aabb1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.9.3 / 2014-12-02 +================== * Fix error when `req.sessionID` contains a non-string value diff --git a/package.json b/package.json index 5dc8af9c..373866cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.9.2", + "version": "1.9.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 523556457f716acef82a5e4ea3a172a6ad09a397 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 4 Jan 2015 20:13:44 -0500 Subject: [PATCH 166/766] deps: debug@~2.1.1 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6e0aabb1..41f5a7ef 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@~2.1.1 + 1.9.3 / 2014-12-02 ================== diff --git a/package.json b/package.json index 373866cc..49ac9b36 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.5", "crc": "3.2.1", - "debug": "~2.1.0", + "debug": "~2.1.1", "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", From 94973069dc870b6f8f8801d73c881536ffb88ca2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 4 Jan 2015 20:14:22 -0500 Subject: [PATCH 167/766] deps: istanbul@0.3.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 49ac9b36..f5a7920d 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.3", - "istanbul": "0.3.2", + "istanbul": "0.3.5", "express": "~4.9.7", "mocha": "~2.0.1", "should": "~4.3.0", From 0692b816e09dd8d181bfaf478d38a1a7eb52c40d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 4 Jan 2015 20:14:43 -0500 Subject: [PATCH 168/766] deps: mocha@~2.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f5a7920d..44a8f6b1 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.3", "istanbul": "0.3.5", "express": "~4.9.7", - "mocha": "~2.0.1", + "mocha": "~2.1.0", "should": "~4.3.0", "supertest": "~0.15.0" }, From 532c737910cb23049c92f14dbcef3059e2815c82 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 4 Jan 2015 21:28:25 -0500 Subject: [PATCH 169/766] tests: use assert instead of should --- package.json | 1 - test/session.js | 346 +++++++++++++++++++++--------------------------- 2 files changed, 153 insertions(+), 194 deletions(-) diff --git a/package.json b/package.json index 44a8f6b1..b91a1aa1 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "istanbul": "0.3.5", "express": "~4.9.7", "mocha": "~2.1.0", - "should": "~4.3.0", "supertest": "~0.15.0" }, "files": [ diff --git a/test/session.js b/test/session.js index e7b4f92d..8e5ae205 100644 --- a/test/session.js +++ b/test/session.js @@ -5,7 +5,6 @@ var after = require('after') var assert = require('assert') var express = require('express') , request = require('supertest') - , should = require('should') , cookieParser = require('cookie-parser') , session = require('../') , Cookie = require('../session/cookie') @@ -17,9 +16,9 @@ var min = 60 * 1000; describe('session()', function(){ it('should export constructors', function(){ - session.Session.should.be.a.Function; - session.Store.should.be.a.Function; - session.MemoryStore.should.be.a.Function; + assert.equal(typeof session.Session, 'function') + assert.equal(typeof session.Store, 'function') + assert.equal(typeof session.MemoryStore, 'function') }) it('should do nothing if req.session exists', function(done){ @@ -30,11 +29,8 @@ describe('session()', function(){ request(app) .get('/') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }) it('should error without secret', function(done){ @@ -50,9 +46,9 @@ describe('session()', function(){ .use(end); app.set('env', 'test'); - request(app) - .get('/') - .expect(200, '', done); + request(app) + .get('/') + .expect(200, '', done) }) it('should create a new session', function (done) { @@ -64,12 +60,12 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session active', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty store.length(function (err, len) { if (err) return done(err) - len.should.equal(1) + assert.equal(len, 1) done() }) }) @@ -84,9 +80,9 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty request(server) .get('/') .set('Cookie', cookie(res)) @@ -106,9 +102,9 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'hello, world', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty request(server) .get('/') .set('Cookie', cookie(res)) @@ -132,9 +128,9 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty request(server) .get('/') .set('Cookie', cookie(res)) @@ -156,7 +152,7 @@ describe('session()', function(){ if (err) return done(err) store.all(function (err, sess) { if (err) return done(err) - Object.keys(sess).should.have.length(2) + assert.equal(Object.keys(sess).length, 2) done() }) } @@ -248,7 +244,7 @@ describe('session()', function(){ request(server) .get('/') - .expect(doesNotHaveHeader('Set-Cookie')) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, function (err) { if (err) return done(err) store.length(function (err, length) { @@ -282,7 +278,7 @@ describe('session()', function(){ .get('/') .expect(200, 'session saved', function (err) { if (err) return done(err) - saved.should.be.true + assert.ok(saved) done() }) }) @@ -310,7 +306,7 @@ describe('session()', function(){ .get('/') .expect(200, '', function (err) { if (err) return done(err) - saved.should.be.true + assert.ok(saved) done() }) }) @@ -339,7 +335,7 @@ describe('session()', function(){ .get('/') .expect(200, 'hello, world', function (err) { if (err) return done(err) - saved.should.be.true + assert.ok(saved) done() }) }) @@ -367,7 +363,7 @@ describe('session()', function(){ .get('/') .expect(200, 'session saved', function (err) { if (err) return done(err) - saved.should.be.true + assert.ok(saved) done() }) }) @@ -384,9 +380,9 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty store.clear(function (err) { if (err) return done(err) request(server) @@ -407,19 +403,20 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) var val = sid(res) - should(val).not.be.empty + assert.ok(val) store.clear(function (err) { if (err) return done(err) request(server) .get('/') .set('Cookie', cookie(res)) + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 2', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty - should(sid(res)).not.equal(val) + assert.notEqual(sid(res), val) done() }) }) @@ -438,13 +435,15 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('sessid')) .expect(200, 'session created', function (err, res) { if (err) return done(err) var val = sid(res) - should(val).not.be.empty + assert.ok(val) request(server) .get('/') .set('Cookie', 'sessid=' + val) + .expect(shouldSetCookie('sessid')) .expect(200, 'session created', done) }) }) @@ -459,14 +458,16 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('sessid')) .expect(200, 'session created', function (err, res) { if (err) return done(err) var val = cookie(res).replace(/...\./, '.') - should(val).not.be.empty + assert.ok(val) request(server) .get('/') .set('Cookie', val) + .expect(shouldSetCookie('sessid')) .expect(200, 'session created', done) }) }) @@ -483,13 +484,14 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty setTimeout(function () { request(server) .get('/') .set('Cookie', cookie(res)) + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 2', done) }, 20) }) @@ -505,18 +507,19 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) var val = sid(res) - should(val).not.be.empty + assert.ok(val) setTimeout(function () { request(server) .get('/') .set('Cookie', cookie(res)) + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 2', function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty - should(sid(res)).not.equal(val) + assert.notEqual(sid(res), val) done() }) }, 15) @@ -533,14 +536,13 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - var val = sid(res) - should(val).not.be.empty setTimeout(function () { store.all(function (err, sess) { if (err) return done(err) - Object.keys(sess).should.have.length(0) + assert.equal(Object.keys(sess).length, 0) done() }) }, 10) @@ -559,32 +561,23 @@ describe('session()', function(){ request(server) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).not.be.empty; - done(); - }); + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) }) it('should trust X-Forwarded-Proto when comma-separated list', function(done){ request(server) .get('/') .set('X-Forwarded-Proto', 'https,http') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).not.be.empty; - done(); - }); + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) }) it('should work when no header', function(done){ request(server) .get('/') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }) }) @@ -598,11 +591,8 @@ describe('session()', function(){ request(server) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }) it('should ignore req.secure from express', function(done){ @@ -614,11 +604,8 @@ describe('session()', function(){ request(app) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(200, 'true', function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'true', done) }) }) @@ -632,11 +619,8 @@ describe('session()', function(){ request(server) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }) it('should use req.secure from express', function(done){ @@ -648,28 +632,22 @@ describe('session()', function(){ request(app) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(200, 'true', function(err, res){ - if (err) return done(err); - should(cookie(res)).not.be.empty; - done(); - }); + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'true', done) }) }) }) describe('genid option', function(){ it('should reject non-function values', function(){ - session.bind(null, { genid: 'bogus!' }).should.throw(/genid.*must/); + assert.throws(session.bind(null, { genid: 'bogus!' }), /genid.*must/) }); it('should provide default generator', function(done){ request(createServer()) .get('/') - .expect(200, function (err, res) { - if (err) return done(err) - should(sid(res)).not.be.empty - done() - }) + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) }); it('should allow custom function', function(done){ @@ -677,11 +655,8 @@ describe('session()', function(){ request(createServer({ genid: genid })) .get('/') - .expect(200, function (err, res) { - if (err) return done(err) - should(sid(res)).equal('apple') - done() - }) + .expect(shouldSetCookieToValue('connect.sid', 's%3Aapple.D8Y%2BpkTAmeR0PobOhY4G97PRW%2Bj7bUnP%2F5m6%2FOn1MCU')) + .expect(200, done) }); it('should encode unsafe chars', function(done){ @@ -689,11 +664,8 @@ describe('session()', function(){ request(createServer({ genid: genid })) .get('/') - .expect(200, function (err, res) { - if (err) return done(err) - should(sid(res)).equal('%25') - done() - }) + .expect(shouldSetCookieToValue('connect.sid', 's%3A%25.kzQ6x52kKVdF35Qh62AWk4ZekS28K5XYCXKa%2FOTZ01g')) + .expect(200, done) }); it('should provide req argument', function(done){ @@ -701,11 +673,8 @@ describe('session()', function(){ request(createServer({ genid: genid })) .get('/foo') - .expect(200, function (err, res) { - if (err) return done(err) - should(sid(res)).equal('%2Ffoo') - done() - }) + .expect(shouldSetCookieToValue('connect.sid', 's%3A%2Ffoo.paEKBtAHbV5s1IB8B2zPnzAgYmmnRPIqObW4VRYj%2FMQ')) + .expect(200, done) }); }); @@ -713,14 +682,14 @@ describe('session()', function(){ it('should default to "connect.sid"', function(done){ request(createServer()) .get('/') - .expect('Set-Cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, done) }) it('should allow overriding', function(done){ request(createServer({ key: 'session_id' })) .get('/') - .expect('Set-Cookie', /session_id=/) + .expect(shouldSetCookie('session_id')) .expect(200, done) }) }) @@ -737,17 +706,14 @@ describe('session()', function(){ request(app) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, function(err, res){ if (err) return done(err); - should(cookie(res)).not.be.empty; request(app) .get('/') .set('Cookie', cookie(res)) - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }); }); @@ -762,17 +728,14 @@ describe('session()', function(){ request(app) .get('/') + .expect(shouldSetCookie('connect.sid')) .expect(200, function(err, res){ if (err) return done(err); - should(cookie(res)).not.be.empty; request(app) .get('/') .set('Cookie', cookie(res)) - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).not.be.empty; - done(); - }); + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) }); }); }); @@ -910,7 +873,7 @@ describe('session()', function(){ request(app) .get('/') .expect('x-count', '1') - .expect('set-cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); @@ -931,7 +894,7 @@ describe('session()', function(){ request(app) .get('/') .expect('x-count', '1') - .expect('set-cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); @@ -952,11 +915,8 @@ describe('session()', function(){ request(app) .get('/') .expect('x-count', '0') - .expect(200, function(err, res){ - if (err) return done(err); - should(cookie(res)).be.empty; - done(); - }); + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }); it('should still save modified session', function(done){ @@ -978,7 +938,7 @@ describe('session()', function(){ request(app) .get('/') .expect('x-count', '1') - .expect('set-cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); @@ -994,7 +954,8 @@ describe('session()', function(){ } server.on('error', function onerror(err) { - err.message.should.equal('boom!') + assert.ok(err) + assert.equal(err.message, 'boom!') cb() }) @@ -1006,7 +967,7 @@ describe('session()', function(){ describe('unset option', function () { it('should reject unknown values', function(){ - session.bind(null, { unset: 'bogus!' }).should.throw(/unset.*must/); + assert.throws(session.bind(null, { unset: 'bogus!' }), /unset.*must/) }); it('should default to keep', function(done){ @@ -1026,7 +987,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - len.should.equal(1); + assert.equal(len, 1) request(app) .get('/') .set('Cookie', cookie(res)) @@ -1034,7 +995,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - len.should.equal(1); + assert.equal(len, 1) done(); }); }); @@ -1059,7 +1020,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - len.should.equal(1); + assert.equal(len, 1) request(app) .get('/') .set('Cookie', cookie(res)) @@ -1067,7 +1028,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - len.should.equal(0); + assert.equal(len, 0) done(); }); }); @@ -1086,12 +1047,12 @@ describe('session()', function(){ request(app) .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, function(err, res){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - len.should.equal(0); - should(cookie(res)).be.empty; + assert.equal(len, 0) done(); }); }); @@ -1110,7 +1071,8 @@ describe('session()', function(){ } server.on('error', function onerror(err) { - err.message.should.equal('boom!') + assert.ok(err) + assert.equal(err.message, 'boom!') cb() }) @@ -1169,7 +1131,7 @@ describe('session()', function(){ if (err) return done(err) store.load(sid(res), function (err, sess) { if (err) return done(err) - should(sess).not.be.empty + assert.ok(sess) request(server) .get('/') .set('Cookie', cookie(res)) @@ -1206,19 +1168,16 @@ describe('session()', function(){ request(app) .get('/') .set('Cookie', val) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, '2', function (err, res) { if (err) return done(err) - should(sid(res)).be.empty; modify = true; request(app) .get('/') .set('Cookie', val) - .expect(200, '3', function (err, res) { - if (err) return done(err) - sid(res).should.not.be.empty; - done(); - }); + .expect(shouldSetCookie('connect.sid')) + .expect(200, '3', done) }); }); }); @@ -1238,7 +1197,7 @@ describe('session()', function(){ request(app) .get('/') - .expect(doesNotHaveHeader('Set-Cookie')) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) }) @@ -1251,23 +1210,24 @@ describe('session()', function(){ var id = req.session.id; req.session.regenerate(function(err){ if (err) throw err; - id.should.not.equal(req.session.id); + assert.notEqual(id, req.session.id) res.end(); }); }); request(app) .get('/') - .end(function(err, res){ + .expect(shouldSetCookie('connect.sid')) + .expect(200, function (err, res) { if (err) return done(err) var id = sid(res) request(app) .get('/') .set('Cookie', cookie(res)) - .end(function(err, res){ + .expect(shouldSetCookie('connect.sid')) + .expect(200, function (err, res) { if (err) return done(err) - should(sid(res)).not.be.empty - should(sid(res)).should.not.equal(id) + assert.notEqual(sid(res), id) done(); }); }); @@ -1385,14 +1345,14 @@ describe('session()', function(){ .get('/') .expect(200, 'saved', function (err, res) { if (err) return done(err) - count.should.equal(1) + assert.equal(count, 1) count = 0 request(server) .get('/') .set('Cookie', cookie(res)) .expect(200, 'saved', function (err) { if (err) return done(err) - count.should.equal(1) + assert.equal(count, 1) done() }) }) @@ -1416,8 +1376,8 @@ describe('session()', function(){ .expect(200, function(err, res){ if (err) return done(err); var val = cookie(res); - should(val).not.containEql('HttpOnly'); - should(val).containEql('Secure'); + assert.equal(val.indexOf('HttpOnly'), -1, 'should not be HttpOnly cookie') + assert.notEqual(val.indexOf('Secure'), -1, 'should be Secure cookie') done(); }); }) @@ -1434,7 +1394,7 @@ describe('session()', function(){ .expect(200, function(err, res){ if (err) return done(err); var val = cookie(res); - should(val).not.containEql('Expires'); + assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') done(); }); }) @@ -1448,13 +1408,13 @@ describe('session()', function(){ request(app) .get('/admin/foo') - .expect('Set-Cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, function (err, res) { if (err) return done(err) request(app) .get('/admin') .set('Cookie', cookie(res)) - .expect(doesNotHaveHeader('Set-Cookie')) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }); }) @@ -1472,21 +1432,15 @@ describe('session()', function(){ .expect(200, function(err, res){ if (err) return done(err); var val = cookie(res); - should(val).not.containEql('HttpOnly'); - should(val).not.containEql('Secure'); - should(val).containEql('Path=/admin'); - should(val).containEql('Expires'); + assert.equal(val.indexOf('HttpOnly'), -1, 'should not be HttpOnly cookie') + assert.equal(val.indexOf('Secure'), -1, 'should not be Secure cookie') + assert.notEqual(val.indexOf('Path=/admin'), -1, 'should have cookie path /admin') + assert.notEqual(val.indexOf('Expires'), -1, 'should have cookie Expires') done(); }); }) it('should preserve cookies set before writeHead is called', function(done){ - function getPreviousCookie(res) { - var val = res.headers['set-cookie']; - if (!val) return ''; - return /previous=([^;]+);/.exec(val[0])[1]; - } - var app = express() .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ @@ -1497,10 +1451,8 @@ describe('session()', function(){ request(app) .get('/') - .end(function(err, res){ - getPreviousCookie(res).should.equal('cookieValue'); - done(); - }); + .expect(shouldSetCookieToValue('previous', 'cookieValue')) + .expect(200, done) }) }) @@ -1530,7 +1482,7 @@ describe('session()', function(){ var req = request(server).get('/') req.agent(agent) - req.expect('Set-Cookie', /connect\.sid=/) + req.expect(shouldSetCookie('connect.sid')) req.expect(200, done) }) @@ -1539,7 +1491,7 @@ describe('session()', function(){ request(server) .get('/') - .expect(doesNotHaveHeader('Set-Cookie')) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) }) @@ -1558,7 +1510,7 @@ describe('session()', function(){ request(app) .get('/') - .expect(doesNotHaveHeader('Set-Cookie')) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) @@ -1577,7 +1529,7 @@ describe('session()', function(){ request(app) .get('/') .set('host', 'http://foo/bar') - .expect(doesNotHaveHeader('Set-Cookie')) + .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) }) @@ -1593,7 +1545,7 @@ describe('session()', function(){ request(app) .get('/foo/bar/baz') - .expect('Set-Cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, done) }) @@ -1608,7 +1560,7 @@ describe('session()', function(){ request(app) .get('/foo/bar/baz') .set('host', 'http://example.com') - .expect('Set-Cookie', /connect\.sid=/) + .expect(shouldSetCookie('connect.sid')) .expect(200, done) }) }) @@ -1628,19 +1580,14 @@ describe('session()', function(){ it('should set relative in milliseconds', function(done){ request(app) .get('/') - .end(function(err, res){ + .expect(200, '1', function (err, res) { var a = new Date(expires(res)) - , b = new Date; + var b = new Date + var delta = a.valueOf() - b.valueOf() val = cookie(res); - a.getYear().should.equal(b.getYear()); - a.getMonth().should.equal(b.getMonth()); - a.getDate().should.equal(b.getDate()); - a.getSeconds().should.not.equal(b.getSeconds()); - var delta = a.valueOf() - b.valueOf(); - (delta > 1000 && delta < 2000).should.be.ok; - res.text.should.equal('1'); + assert.ok(delta > 1000 && delta < 2000) done(); }); }); @@ -1649,18 +1596,14 @@ describe('session()', function(){ request(app) .get('/') .set('Cookie', val) - .end(function(err, res){ + .expect(200, '2', function (err, res) { var a = new Date(expires(res)) - , b = new Date; + var b = new Date + var delta = a.valueOf() - b.valueOf() val = cookie(res); - a.getYear().should.equal(b.getYear()); - a.getMonth().should.equal(b.getMonth()); - a.getSeconds().should.not.equal(b.getSeconds()); - var delta = a.valueOf() - b.valueOf(); - (delta > 4000 && delta < 5000).should.be.ok; - res.text.should.equal('2'); + assert.ok(delta > 4000 && delta < 5000) done(); }); }); @@ -1669,15 +1612,14 @@ describe('session()', function(){ request(app) .get('/') .set('Cookie', val) - .end(function(err, res){ + .expect(200, '3', function (err, res) { var a = new Date(expires(res)) - , b = new Date; + var b = new Date + var delta = a.valueOf() - b.valueOf() val = cookie(res); - var delta = a.valueOf() - b.valueOf(); - (delta > 2999999000 && delta < 3000000000).should.be.ok; - res.text.should.equal('3'); + assert.ok(delta > 2999999000 && delta < 3000000000) done(); }); }); @@ -1696,7 +1638,8 @@ describe('session()', function(){ request(app) .get('/') .end(function(err, res){ - expires(res).should.equal('Thu, 01 Jan 1970 00:00:00 GMT'); + if (err) return done(err) + assert.equal(expires(res), 'Thu, 01 Jan 1970 00:00:00 GMT') done(); }); }) @@ -1716,7 +1659,7 @@ describe('session()', function(){ .expect(200, function(err, res){ if (err) return done(err); var val = cookie(res); - should(val).not.containEql('Expires='); + assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') done(); }); }) @@ -1902,12 +1845,6 @@ function createSession(opts) { return session(options) } -function doesNotHaveHeader(header) { - return function (res) { - assert.ok(!(header.toLowerCase() in res.headers), 'should not have ' + header + ' header') - } -} - function end(req, res) { res.end() } @@ -1917,6 +1854,29 @@ function expires(res) { return match ? match[1] : undefined; } +function shouldNotHaveHeader(header) { + return function (res) { + assert.ok(!(header.toLowerCase() in res.headers), 'should not have ' + header + ' header') + } +} + +function shouldSetCookie(name) { + return function (res) { + var header = cookie(res) + assert.ok(header, 'should have a cookie header') + assert.equal(header.split('=')[0], name, 'should set cookie ' + name) + } +} + +function shouldSetCookieToValue(name, val) { + return function (res) { + var header = cookie(res); + assert.ok(header, 'should have a cookie header') + assert.equal(header.split('=')[0], name, 'should set cookie ' + name) + assert.equal(header.split('=')[1].split(';')[0], val, 'should set cookie ' + name + ' to ' + val) + } +} + function sid(res) { var match = /^[^=]+=s%3A([^;\.]+)[\.;]/.exec(cookie(res)) var val = match ? match[1] : undefined From dc0cad4abad78a3e79650f44d9b5a00e66d63ea9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 4 Jan 2015 21:53:42 -0500 Subject: [PATCH 170/766] deps: express@~4.10.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b91a1aa1..7021b8e7 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.3", + "express": "~4.10.7", "istanbul": "0.3.5", - "express": "~4.9.7", "mocha": "~2.1.0", "supertest": "~0.15.0" }, From b5e63324ed83c1c1401029e9ad2a97bf9f052c2c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 4 Jan 2015 23:02:52 -0500 Subject: [PATCH 171/766] Add store.touch interface for session stores closes #105 --- HISTORY.md | 2 ++ README.md | 1 + index.js | 25 +++++++++++++++ session/memory.js | 35 +++++++++++++++++++++ test/session.js | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 41f5a7ef..ace2db62 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * Add `store.touch` interface for session stores + * Fix `MemoryStore` expiration with `resave: false` * deps: debug@~2.1.1 1.9.3 / 2014-12-02 diff --git a/README.md b/README.md index 9565b49e..d2b542d9 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ Every session store _must_ implement the following methods Recommended methods include, but are not limited to: + - `.touch(sid, session, callback)` - `.length(callback)` - `.clear(callback)` diff --git a/index.js b/index.js index e48a879b..43d70e16 100644 --- a/index.js +++ b/index.js @@ -129,6 +129,7 @@ function session(options){ req.session.cookie = new Cookie(cookie); }; + var storeImplementsTouch = typeof store.touch === 'function'; store.on('disconnect', function(){ storeReady = false; }); store.on('connect', function(){ storeReady = true; }); @@ -277,6 +278,19 @@ function session(options){ writeend(); }); + return writetop(); + } else if (storeImplementsTouch && shouldTouch(req)) { + // store implements touch method + debug('touching'); + store.touch(req.sessionID, req.session, function ontouch(err) { + if (err) { + defer(next, err); + } + + debug('touched'); + writeend(); + }); + return writetop(); } @@ -337,6 +351,17 @@ function session(options){ : !isSaved(req.session) } + // determine if session should be touched + function shouldTouch(req) { + // cannot set cookie without a session ID + if (typeof req.sessionID !== 'string') { + debug('session ignored because of bogus req.sessionID %o', req.sessionID); + return false; + } + + return cookieId === req.sessionID && !shouldSave(req); + } + // determine if cookie should be set on response function shouldSetCookie(req) { // cannot set cookie without a session ID diff --git a/session/memory.js b/session/memory.js index 4efe99da..575965c4 100644 --- a/session/memory.js +++ b/session/memory.js @@ -82,6 +82,41 @@ MemoryStore.prototype.set = function(sid, sess, fn){ fn && defer(fn); }; +/** + * Touch the given `sess` object associated with the given `sid`. + * + * @param {String} sid + * @param {Session} sess + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.touch = function touch(sid, sess, fn) { + var curr = this.sessions[sid]; + + if (!curr) { + return defer(fn); + } + + // parse + curr = JSON.parse(curr); + + var expires = typeof curr.cookie.expires === 'string' + ? new Date(curr.cookie.expires) + : curr.cookie.expires; + + // destroy expired session + if (expires && expires <= Date.now()) { + return self.destroy(sid, fn); + } + + // update expiration + curr.cookie = sess.cookie; + this.sessions[sid] = JSON.stringify(curr); + + fn && defer(fn); +}; + /** * Destroy the session associated with the given `sid`. * diff --git a/test/session.js b/test/session.js index 8e5ae205..b88e047a 100644 --- a/test/session.js +++ b/test/session.js @@ -853,6 +853,35 @@ describe('session()', function(){ .expect(200, done); }); }); + + it('should pass session touch error', function (done) { + var cb = after(2, done) + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.hit = true + res.end('session saved') + }) + + store.touch = function touch(sid, sess, callback) { + callback(new Error('boom!')) + } + + server.on('error', function onerror(err) { + assert.ok(err) + assert.equal(err.message, 'boom!') + cb() + }) + + request(server) + .get('/') + .expect(200, 'session saved', function (err, res) { + if (err) return cb(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .end(cb) + }) + }) }); describe('saveUninitialized option', function(){ @@ -963,6 +992,22 @@ describe('session()', function(){ .get('/') .expect(200, 'session saved', cb) }) + + it('should prevent uninitialized session from being touched', function (done) { + var cb = after(1, done) + var store = new session.MemoryStore() + var server = createServer({ saveUninitialized: false, store: store, cookie: { maxAge: min } }, function (req, res) { + res.end() + }) + + store.touch = function () { + cb(new Error('should not be called')) + } + + request(server) + .get('/') + .expect(200, cb) + }) }); describe('unset option', function () { @@ -1359,6 +1404,41 @@ describe('session()', function(){ }) }) + describe('.touch()', function () { + it('should reset session expiration', function (done) { + var store = new session.MemoryStore() + var server = createServer({ resave: false, store: store, cookie: { maxAge: min } }, function (req, res) { + req.session.hit = true + req.session.touch() + res.end() + }) + + request(server) + .get('/') + .expect(200, function (err, res) { + if (err) return done(err) + var id = sid(res) + store.get(id, function (err, sess) { + if (err) return done(err) + var exp = new Date(sess.cookie.expires) + setTimeout(function () { + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, function (err, res) { + if (err) return done(err); + store.get(id, function (err, sess) { + if (err) return done(err) + assert.notEqual(new Date(sess.cookie.expires).getTime(), exp.getTime()) + done() + }) + }) + }, 100) + }) + }) + }) + }) + describe('.cookie', function(){ describe('.*', function(){ it('should serialize as parameters', function(done){ From a7f7f6766f0877930b8c5dd09b59186ded0ce9c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Jan 2015 14:55:17 -0500 Subject: [PATCH 172/766] Clean up MemoryStore implementation --- session/memory.js | 229 +++++++++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 116 deletions(-) diff --git a/session/memory.js b/session/memory.js index 575965c4..9887680d 100644 --- a/session/memory.js +++ b/session/memory.js @@ -1,19 +1,22 @@ - /*! - * Connect - session - MemoryStore + * express-session * Copyright(c) 2010 Sencha Inc. * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ /** * Module dependencies. + * @private */ -var Store = require('./store'); +var Store = require('./store') +var util = require('util') /** * Shim setImmediate for node.js < 0.10 + * @private */ /* istanbul ignore next */ @@ -22,165 +25,159 @@ var defer = typeof setImmediate === 'function' : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } /** - * Initialize a new `MemoryStore`. - * - * @api public + * Module exports. */ -var MemoryStore = module.exports = function MemoryStore() { - this.sessions = Object.create(null); -}; +module.exports = MemoryStore /** - * Inherit from `Store.prototype`. + * A session store in memory. + * @public */ -MemoryStore.prototype.__proto__ = Store.prototype; +function MemoryStore() { + Store.call(this) + this.sessions = Object.create(null) +} /** - * Attempt to fetch session by the given `sid`. - * - * @param {String} sid - * @param {Function} fn - * @api public + * Inherit from Store. */ -MemoryStore.prototype.get = function(sid, fn){ - var self = this; - var sess = self.sessions[sid]; +util.inherits(MemoryStore, Store) - if (!sess) { - return defer(fn); - } +/** + * Get all active sessions. + * + * @param {function} callback + * @public + */ - // parse - sess = JSON.parse(sess); +MemoryStore.prototype.all = function all(callback) { + var sessionIds = Object.keys(this.sessions) + var sessions = Object.create(null) - var expires = typeof sess.cookie.expires === 'string' - ? new Date(sess.cookie.expires) - : sess.cookie.expires; + for (var i = 0; i < sessionIds.length; i++) { + var sessionId = sessionIds[i] + var session = getSession.call(this, sessionId) - // destroy expired session - if (expires && expires <= Date.now()) { - return self.destroy(sid, fn); + if (session) { + sessions[sessionId] = session; + } } - defer(fn, null, sess); -}; + callback && defer(callback, null, sessions) +} /** - * Commit the given `sess` object associated with the given `sid`. + * Clear all sessions. * - * @param {String} sid - * @param {Session} sess - * @param {Function} fn - * @api public + * @param {function} callback + * @public */ -MemoryStore.prototype.set = function(sid, sess, fn){ - this.sessions[sid] = JSON.stringify(sess); - fn && defer(fn); -}; +MemoryStore.prototype.clear = function clear(callback) { + this.sessions = Object.create(null) + callback && defer(callback) +} /** - * Touch the given `sess` object associated with the given `sid`. + * Destroy the session associated with the given session ID. * - * @param {String} sid - * @param {Session} sess - * @param {Function} fn - * @api public + * @param {string} sessionId + * @public */ -MemoryStore.prototype.touch = function touch(sid, sess, fn) { - var curr = this.sessions[sid]; - - if (!curr) { - return defer(fn); - } - - // parse - curr = JSON.parse(curr); - - var expires = typeof curr.cookie.expires === 'string' - ? new Date(curr.cookie.expires) - : curr.cookie.expires; - - // destroy expired session - if (expires && expires <= Date.now()) { - return self.destroy(sid, fn); - } +MemoryStore.prototype.destroy = function destroy(sessionId, callback) { + delete this.sessions[sessionId] + callback && defer(callback) +} - // update expiration - curr.cookie = sess.cookie; - this.sessions[sid] = JSON.stringify(curr); +/** + * Fetch session by the given session ID. + * + * @param {string} sessionId + * @param {function} callback + * @public + */ - fn && defer(fn); -}; +MemoryStore.prototype.get = function get(sessionId, callback) { + defer(callback, null, getSession.call(this, sessionId)) +} /** - * Destroy the session associated with the given `sid`. + * Commit the given session associated with the given sessionId to the store. * - * @param {String} sid - * @api public + * @param {string} sessionId + * @param {object} session + * @param {function} callback + * @public */ -MemoryStore.prototype.destroy = function(sid, fn){ - delete this.sessions[sid]; - fn && defer(fn); -}; - /** - * Invoke the given callback `fn` with all active sessions. + * Get number of active sessions. * - * @param {Function} fn - * @api public + * @param {function} callback + * @public */ -MemoryStore.prototype.all = function(fn){ - var keys = Object.keys(this.sessions); - var now = Date.now(); - var obj = Object.create(null); - var sess; - var sid; +MemoryStore.prototype.length = function length(callback) { + this.all(function (err, sessions) { + if (err) return callback(err) + callback(null, Object.keys(sessions).length) + }) +} - for (var i = 0, len = keys.length; i < len; ++i) { - sid = keys[i]; +MemoryStore.prototype.set = function set(sessionId, session, callback) { + this.sessions[sessionId] = JSON.stringify(session) + callback && defer(callback) +} - // parse - sess = JSON.parse(this.sessions[sid]); +/** + * Touch the given session object associated with the given session ID. + * + * @param {string} sessionId + * @param {object} session + * @param {function} callback + * @public + */ - expires = typeof sess.cookie.expires === 'string' - ? new Date(sess.cookie.expires) - : sess.cookie.expires; +MemoryStore.prototype.touch = function touch(sessionId, session, callback) { + var currentSession = getSession.call(this, sessionId) - if (!expires || expires > now) { - obj[sid] = sess; - } + if (currentSession) { + // update expiration + currentSession.cookie = session.cookie + this.sessions[sessionId] = JSON.stringify(currentSession) } - fn && defer(fn, null, obj); -}; + callback && defer(callback) +} /** - * Clear all sessions. - * - * @param {Function} fn - * @api public + * Get session from the store. + * @private */ -MemoryStore.prototype.clear = function(fn){ - this.sessions = {}; - fn && defer(fn); -}; +function getSession(sessionId) { + var sess = this.sessions[sessionId] -/** - * Fetch number of sessions. - * - * @param {Function} fn - * @api public - */ + if (!sess) { + return + } + + // parse + sess = JSON.parse(sess) + + var expires = typeof sess.cookie.expires === 'string' + ? new Date(sess.cookie.expires) + : sess.cookie.expires + + // destroy expired session + if (expires && expires <= Date.now()) { + delete this.sessions[sessionId] + return + } -MemoryStore.prototype.length = function(fn){ - var len = Object.keys(this.sessions).length; - defer(fn, null, len); -}; + return sess +} From 506af318ccbb53fff4dc0a96785b9c1814f27cd1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Jan 2015 15:19:38 -0500 Subject: [PATCH 173/766] docs: add EventEmitter requirement to readme closes #110 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d2b542d9..0f0bafef 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,8 @@ req.session.cookie.maxAge // => 30000 ## Session Store Implementation -Every session store _must_ implement the following methods +Every session store _must_ be an `EventEmitter` and implement the following +methods: - `.get(sid, callback)` - `.set(sid, session, callback)` From f25831715003f8b9c5b1cc512be7b8c33d172da9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Jan 2015 15:35:10 -0500 Subject: [PATCH 174/766] 1.10.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ace2db62..e3920f7f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.10.0 / 2015-01-05 +=================== * Add `store.touch` interface for session stores * Fix `MemoryStore` expiration with `resave: false` diff --git a/package.json b/package.json index 7021b8e7..c18acbf6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.9.3", + "version": "1.10.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From e78c3b7e071ae14469617a1b07b229f0cbf396fa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Jan 2015 19:20:01 -0500 Subject: [PATCH 175/766] deps: uid-safe@1.0.2 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e3920f7f..ee9ad01e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: uid-safe@1.0.2 + - Remove dependency on `mz` + 1.10.0 / 2015-01-05 =================== diff --git a/package.json b/package.json index c18acbf6..cfa1e15d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", - "uid-safe": "1.0.1", + "uid-safe": "1.0.2", "utils-merge": "1.0.0" }, "devDependencies": { From b145afa0b14a2f66a3a705f6a448fec1d840ba36 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Jan 2015 20:29:17 -0500 Subject: [PATCH 176/766] 1.10.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ee9ad01e..08abb0e4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.10.1 / 2015-01-08 +=================== * deps: uid-safe@1.0.2 - Remove dependency on `mz` diff --git a/package.json b/package.json index cfa1e15d..25ef4aca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.10.0", + "version": "1.10.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 9ef8d547203dd311dcc44a1fc22a37f86de78df5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 31 Jan 2015 23:21:04 -0500 Subject: [PATCH 177/766] deps: uid-safe@1.0.3 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 08abb0e4..ca23da8c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * deps: uid-safe@1.0.3 + - Fix error branch that would throw + - deps: base64-url@1.2.0 + 1.10.1 / 2015-01-08 =================== diff --git a/package.json b/package.json index 25ef4aca..dcc19498 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", - "uid-safe": "1.0.2", + "uid-safe": "1.0.3", "utils-merge": "1.0.0" }, "devDependencies": { From 8eae5a2d9cfefd5e9bdfd778bf3fcc7b977eac82 Mon Sep 17 00:00:00 2001 From: Ben Heymink Date: Thu, 29 Jan 2015 15:34:31 +0000 Subject: [PATCH 178/766] docs: add a note for a PassportJS pitfall closes #118 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f0bafef..c625bbce 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Session data is _not_ saved in the cookie itself, just the session ID. - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - `resave` - forces session to be saved even when unmodified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`) - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case) + - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case). **Note** if you are using Session in conjunction with PassportJS, Passport will add an empty Passport object to the session for use after a user is authenticated, which will be treated as a modification to the session, causing it to be saved. - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) #### options.genid From d9dec25be2196df19aba70f904b1b34c83c97827 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 31 Jan 2015 23:49:27 -0500 Subject: [PATCH 179/766] docs: expand and move down example --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c625bbce..26cf3825 100644 --- a/README.md +++ b/README.md @@ -15,19 +15,9 @@ $ npm install express-session ## API ```js -var express = require('express') var session = require('express-session') - -var app = express() - -app.use(session({ - secret: 'keyboard cat', - resave: false, - saveUninitialized: true -})) ``` - ### session(options) Setup session store with the given `options`. @@ -222,6 +212,48 @@ Recommended methods include, but are not limited to: For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. +## Example + +A simple example using `express-session` to store page views for a user. + +```js +var express = require('express') +var parseurl = require('parseurl') +var session = require('express-session') + +var app = express() + +app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true +})) + +app.use(function (req, res, next) { + var views = req.session.views + + if (!views) { + views = req.session.views = {} + } + + // get the url pathname + var pathname = parseurl(req).pathname + + // count the views + views[pathname] = (views[pathname] || 0) + 1 + + next() +}) + +app.get('/foo', function (req, res, next) { + res.send('you viewed this page ' + req.session.views['/foo'] + ' times') +}) + +app.get('/bar', function (req, res, next) { + res.send('you viewed this page ' + req.session.views['/bar'] + ' times') +}) +``` + ## License [MIT](LICENSE) From 9129f4c4ad3b6f4f3e2d97708e4b3c770be834e0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 1 Feb 2015 00:08:45 -0500 Subject: [PATCH 180/766] docs: change layout of options --- README.md | 113 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 26cf3825..6533cce8 100644 --- a/README.md +++ b/README.md @@ -20,46 +20,119 @@ var session = require('express-session') ### session(options) -Setup session store with the given `options`. +Create a session middleware with the given `options`. -Session data is _not_ saved in the cookie itself, just the session ID. +**Note** session data is _not_ saved in the cookie itself, just the session ID. +Session data is stored server-side. #### Options - - `name` - cookie name (formerly known as `key`). (default: `'connect.sid'`) - - `store` - session store instance. - - `secret` - session cookie is signed with this secret to prevent tampering. - - `cookie` - session cookie settings. - - (default: `{ path: '/', httpOnly: true, secure: false, maxAge: null }`) - - `genid` - function to call to generate a new session ID. (default: uses `uid2` library) - - `rolling` - forces a cookie set on every response. This resets the expiration date. (default: `false`) - - `resave` - forces session to be saved even when unmodified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`) - - `proxy` - trust the reverse proxy when setting secure cookies (via "x-forwarded-proto" header). When set to `true`, the "x-forwarded-proto" header will be used. When set to `false`, all headers are ignored. When left unset, will use the "trust proxy" setting from express. (default: `undefined`) - - `saveUninitialized` - forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. (default: `true`, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case). **Note** if you are using Session in conjunction with PassportJS, Passport will add an empty Passport object to the session for use after a user is authenticated, which will be treated as a modification to the session, causing it to be saved. - - `unset` - controls result of unsetting `req.session` (through `delete`, setting to `null`, etc.). This can be "keep" to keep the session in the store but ignore modifications or "destroy" to destroy the stored session. (default: `'keep'`) +`express-session` accepts these properties in the options object. -#### options.genid +##### cookie -Generate a custom session ID for new sessions. Provide a function that returns a string that will be used as a session ID. The function is given `req` as the first argument if you want to use some value attached to `req` when generating the ID. +Settings for the session ID cookie. See the "Cookie options" section below for +more information on the different values. + +The default value is `{ path: '/', httpOnly: true, secure: false, maxAge: null }`. + +##### genid + +Function to call to generate a new session ID. Provide a function that returns +a string that will be used as a session ID. The function is given `req` as the +first argument if you want to use some value attached to `req` when generating +the ID. + +The default valuses uses the `uid2` library to generate IDs. **NOTE** be careful you generate unique IDs so your sessions do not conflict. ```js app.use(session({ genid: function(req) { - return genuuid(); // use UUIDs for session IDs + return genuuid() // use UUIDs for session IDs }, secret: 'keyboard cat' })) ``` -#### options.resave +##### name + +The name of the session ID cookie to set in the response (and read from in the +request). + +The default value is `'connect.sid'`. + +##### proxy + +Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto" +header). + +The default value is `undefined`. + + - `true` The "X-Forwarded-Proto" header will be used. + - `false` All headers are ignored and the connection is considered secure only + if there is a direct TLS/SSL connection. + - `undefined` Use the "trust proxy" setting from express + +##### resave + +Forces the session to be saved back to the session store, even if the session +was never modified during the request. Depending on your store this may be +necessary, but it can also create race conditions where a client has two +parallel requests to your server and changes made to the session in one +request may get overwritten when the other request ends, even if it made no +changes (this behavior also depends on what store you're using). + +The default value is `true`, but using the default has been deprecated, +as the default will change in the future. Please research into this setting +and choose what is appropriate to your use-case. Typically, you'll want +`false`. + +##### rolling + +Force a cookie to be set on every response. This resets the expiration date. + +The default value is `false`. + +##### saveUninitialized + +Forces a session that is "uninitialized" to be saved to the store. A session is +uninitialized when it is new but not modified. Choosing `false` is useful for +implementing login sessions, reducing server storage usage, or complying with +laws that require permission before setting a cookie. Choose `false` will also +help with race conditions where a client makes multiple parallel requests +without a session. + +The default value is `true`, but using the default has been deprecated, as the +default will change in the future. Please research into this setting and +choose what is appropriate to your use-case. + +**Note** if you are using Session in conjunction with PassportJS, Passport +will add an empty Passport object to the session for use after a user is +authenticated, which will be treated as a modification to the session, causing +it to be saved. + +##### secret + +**Required option** + +This is the secret used to sign the session ID cookie. + +##### store + +The session store instance, defaults to a new `MemoryStore` instance. + +##### unset -Forces the session to be saved back to the session store, even if the session was never modified during the request. Depending on your store this may be necessary, but it can also create race conditions where a client has two parallel requests to your server and changes made to the session in one request may get overwritten when the other request ends, even if it made no changes (this behavior also depends on what store you're using). +Control the result of unsetting `req.session` (through `delete`, setting to `null`, +etc.). -#### options.saveUninitialized +The default value is `'keep'`. -Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choose `false` will also help with race conditions where a client makes multiple parallel requests without a session. + - `'destroy'` The session will be destroyed (deleted) when the response ends. + - `'keep'` The session in the store will be ketp, but modifications made during + the request are ignored and not saved. #### Cookie options From 4ebb4a990afd7b6b80e5d6161913ea7b7681efc7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 1 Feb 2015 00:24:01 -0500 Subject: [PATCH 181/766] 1.10.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ca23da8c..b3a6d6dd 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.10.2 / 2015-01-31 +=================== * deps: uid-safe@1.0.3 - Fix error branch that would throw diff --git a/package.json b/package.json index dcc19498..f08ccff2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.10.1", + "version": "1.10.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From d0766edc0eee6448350571f21bd36406050fd950 Mon Sep 17 00:00:00 2001 From: jub3i Date: Mon, 9 Feb 2015 13:23:31 +0200 Subject: [PATCH 182/766] docs: fix typo in readme closes #119 closes #120 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6533cce8..5b093ddd 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ a string that will be used as a session ID. The function is given `req` as the first argument if you want to use some value attached to `req` when generating the ID. -The default valuses uses the `uid2` library to generate IDs. +The default value is a function which uses the `uid2` library to generate IDs. **NOTE** be careful you generate unique IDs so your sessions do not conflict. @@ -131,7 +131,7 @@ etc.). The default value is `'keep'`. - `'destroy'` The session will be destroyed (deleted) when the response ends. - - `'keep'` The session in the store will be ketp, but modifications made during + - `'keep'` The session in the store will be kept, but modifications made during the request are ignored and not saved. #### Cookie options From ebdf2dbed0adbd7853b7793db0eb384edc3c6e07 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 22:56:08 -0500 Subject: [PATCH 183/766] build: use Travis CI container infrastructure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 1ff243c5..852ac641 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,6 @@ matrix: allow_failures: - node_js: "0.11" fast_finish: true +sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 4ef1eec1f9717516d7797b59ef4c1419a3849bee Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 22:59:29 -0500 Subject: [PATCH 184/766] build: support Node.js 0.12 --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 852ac641..4af6d31b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,7 @@ language: node_js node_js: - "0.8" - "0.10" - - "0.11" -matrix: - allow_failures: - - node_js: "0.11" - fast_finish: true + - "0.12" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 48d2f120acaa96421ae1c7ead0dc8d98203e17bd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 23:01:55 -0500 Subject: [PATCH 185/766] deps: cookie-parser@~1.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f08ccff2..f2417d7f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "after": "0.8.1", - "cookie-parser": "~1.3.3", + "cookie-parser": "~1.3.4", "express": "~4.10.7", "istanbul": "0.3.5", "mocha": "~2.1.0", From f1051046b26ca6cd7c742f0c0feabe47a0e78231 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 23:03:35 -0500 Subject: [PATCH 186/766] deps: uid-safe@1.1.0 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b3a6d6dd..7d2eebf1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * deps: uid-safe@1.1.0 + - Use `crypto.randomBytes`, if available + - deps: base64-url@1.2.1 + 1.10.2 / 2015-01-31 =================== diff --git a/package.json b/package.json index f2417d7f..ad6643f8 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", - "uid-safe": "1.0.3", + "uid-safe": "1.1.0", "utils-merge": "1.0.0" }, "devDependencies": { From dbb20942bf6e1af9a29572ca2d225744d659309a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 23:04:03 -0500 Subject: [PATCH 187/766] deps: cookie-signature@1.0.6 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 7d2eebf1..61a8eaab 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * deps: cookie-signature@1.0.6 * deps: uid-safe@1.1.0 - Use `crypto.randomBytes`, if available - deps: base64-url@1.2.1 diff --git a/package.json b/package.json index ad6643f8..a2e542cb 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "license": "MIT", "dependencies": { "cookie": "0.1.2", - "cookie-signature": "1.0.5", + "cookie-signature": "1.0.6", "crc": "3.2.1", "debug": "~2.1.1", "depd": "~1.0.0", From e1b20329a55e3ead77290ebe65c53a3503c05f7d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 23:04:43 -0500 Subject: [PATCH 188/766] deps: express@~4.10.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a2e542cb..176c643b 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.4", - "express": "~4.10.7", + "express": "~4.10.8", "istanbul": "0.3.5", "mocha": "~2.1.0", "supertest": "~0.15.0" From 60e8bd31e4da793c351f6c82e4df47bbf226aacc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 23:10:42 -0500 Subject: [PATCH 189/766] 1.10.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 61a8eaab..68efdb1a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.10.3 / 2015-02-16 +=================== * deps: cookie-signature@1.0.6 * deps: uid-safe@1.1.0 diff --git a/package.json b/package.json index 176c643b..789ae1b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.10.2", + "version": "1.10.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 8271fb1d460cc0145ff6c7dc8b20b4dbde705544 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 10 Mar 2015 19:27:59 -0400 Subject: [PATCH 190/766] deps: mocha@~2.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 789ae1b0..24d74cd7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.4", "express": "~4.10.8", "istanbul": "0.3.5", - "mocha": "~2.1.0", + "mocha": "~2.2.1", "supertest": "~0.15.0" }, "files": [ From 57a747c738c1561319bd11e1b9e1934eaf12ab8a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 10 Mar 2015 19:28:34 -0400 Subject: [PATCH 191/766] deps: istanbul@0.3.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24d74cd7..c4f7b70c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.3.4", "express": "~4.10.8", - "istanbul": "0.3.5", + "istanbul": "0.3.7", "mocha": "~2.2.1", "supertest": "~0.15.0" }, From 2fc5359ea83ccbf7171865fb799f4b9814eb2143 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 15 Mar 2015 22:12:04 -0400 Subject: [PATCH 192/766] build: support io.js 1.x --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4af6d31b..49d202c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ node_js: - "0.8" - "0.10" - "0.12" + - "1.0" + - "1.5" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 45b8dbabe157d71e4673e4298e003accc7cabf4d Mon Sep 17 00:00:00 2001 From: Lindsay MacVean Date: Thu, 12 Mar 2015 15:50:19 +0000 Subject: [PATCH 193/766] docs: add warning about default store limitations closes #134 --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b093ddd..b01211da 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,14 @@ var session = require('express-session') Create a session middleware with the given `options`. -**Note** session data is _not_ saved in the cookie itself, just the session ID. +**Note** Session data is _not_ saved in the cookie itself, just the session ID. Session data is stored server-side. +**Warning** The default server-side session storage, `MemoryStore`, is _purposely_ +not designed for a production environment. It will leak memory under most +conditions, does not scale past a single process, and it meant for debugging and +developing. + #### Options `express-session` accepts these properties in the options object. From 46e941df23933edb496e0cfbfd59a4b48edc449d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 15 Mar 2015 22:37:18 -0400 Subject: [PATCH 194/766] docs: add a list of compatible session stores closes #129 --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b01211da..605eca01 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,15 @@ var session = require('express-session') Create a session middleware with the given `options`. **Note** Session data is _not_ saved in the cookie itself, just the session ID. -Session data is stored server-side. +Session hdata is stored server-side. **Warning** The default server-side session storage, `MemoryStore`, is _purposely_ not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and it meant for debugging and developing. +For a list of stores, see [compatible session stores](#compatible-session-stores). + #### Options `express-session` accepts these properties in the options object. @@ -290,6 +292,14 @@ Recommended methods include, but are not limited to: For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. +## Compatible Session Stores + +The following modules implement a session store that is compatible with this +module. Please make a PR to add additional modules :) + + * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based + session store. + ## Example A simple example using `express-session` to store page views for a user. From 0e7b0b72b67755be395ddc6656c44ec11f99e283 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 15 Mar 2015 22:42:59 -0400 Subject: [PATCH 195/766] deps: debug@~2.1.3 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 68efdb1a..b8fdc7c5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + 1.10.3 / 2015-02-16 =================== diff --git a/package.json b/package.json index c4f7b70c..0489b83a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.6", "crc": "3.2.1", - "debug": "~2.1.1", + "debug": "~2.1.3", "depd": "~1.0.0", "on-headers": "~1.0.0", "parseurl": "~1.3.0", From e9e683b229c0c7e5587371124f4fa2250179c3e0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 15 Mar 2015 22:46:07 -0400 Subject: [PATCH 196/766] tests: fix a delta range in test --- test/session.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/session.js b/test/session.js index b88e047a..73be6b00 100644 --- a/test/session.js +++ b/test/session.js @@ -1667,7 +1667,7 @@ describe('session()', function(){ val = cookie(res); - assert.ok(delta > 1000 && delta < 2000) + assert.ok(delta > 1000 && delta <= 2000) done(); }); }); @@ -1683,7 +1683,7 @@ describe('session()', function(){ val = cookie(res); - assert.ok(delta > 4000 && delta < 5000) + assert.ok(delta > 4000 && delta <= 5000) done(); }); }); @@ -1699,7 +1699,7 @@ describe('session()', function(){ val = cookie(res); - assert.ok(delta > 2999999000 && delta < 3000000000) + assert.ok(delta > 2999999000 && delta <= 3000000000) done(); }); }); From 91ad72f10415896dfde6d4b32a1d310312575555 Mon Sep 17 00:00:00 2001 From: Lindsay MacVean Date: Sat, 14 Mar 2015 11:12:07 +0000 Subject: [PATCH 197/766] docs: note that cookie-parser middleware no longer required closes #136 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 605eca01..0dc70a96 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,11 @@ The default value is `'keep'`. #### Cookie options +**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser) +no longer needs to be used for this module to work. This module now directly reads +and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues +if the `secret` is not the same between this module and `cookie-parser`. + Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure` is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set "trust proxy" in express: From c68354c307361f39dadcf92f1a73e49bf45375bf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 15 Mar 2015 23:53:56 -0400 Subject: [PATCH 198/766] deps: express@~4.11.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0489b83a..dc49a0ea 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.4", - "express": "~4.10.8", + "express": "~4.11.2", "istanbul": "0.3.7", "mocha": "~2.2.1", "supertest": "~0.15.0" From 7dbf7b4f9678bf67cf2272258039d6903c4b6ed2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 15 Mar 2015 23:57:37 -0400 Subject: [PATCH 199/766] docs: expand info on resave option closes #126 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0dc70a96..895116a6 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,12 @@ as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case. Typically, you'll want `false`. +How do I know if this is necessary for my store? The best way to know is to +check with your store if it implements the `touch` method. If it does, then +you can safely set `resave: false`. If it does not implement the `touch` +method and your store sets an expiration date on stored sessions, then you +likely need `resave: true`. + ##### rolling Force a cookie to be set on every response. This resets the expiration date. From 3f5951a45e03bc7a80ac7580faceab14fdfcde37 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Mar 2015 00:06:54 -0400 Subject: [PATCH 200/766] docs: add additional note to name option closes #124 --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 895116a6..1414295f 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,10 @@ request). The default value is `'connect.sid'`. +**Note** if you have multiple apps running on the same host (hostname + port), +then you need to separate the session cookies from each other. The simplest +method is to simply set different `name`s per app. + ##### proxy Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto" @@ -100,7 +104,7 @@ How do I know if this is necessary for my store? The best way to know is to check with your store if it implements the `touch` method. If it does, then you can safely set `resave: false`. If it does not implement the `touch` method and your store sets an expiration date on stored sessions, then you -likely need `resave: true`. +likely need `resave: true`.h ##### rolling From b3f9352d6a16a3a2d01ee04c1b1ffd53bd0fc522 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Mar 2015 00:08:59 -0400 Subject: [PATCH 201/766] 1.10.4 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b8fdc7c5..399cf076 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.10.4 / 2015-03-15 +=================== * deps: debug@~2.1.3 - Fix high intensity foreground color for bold diff --git a/package.json b/package.json index dc49a0ea..d6a3fabf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.10.3", + "version": "1.10.4", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From f7da010bd4bd6c71e663d007e60a58cf01c3c476 Mon Sep 17 00:00:00 2001 From: Joe Wagner Date: Mon, 16 Mar 2015 07:44:40 -0600 Subject: [PATCH 202/766] docs: add connect-mongo to list of session stores closes #138 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1414295f..ce01faa3 100644 --- a/README.md +++ b/README.md @@ -312,6 +312,8 @@ For an example implementation view the [connect-redis](http://github.com/visionm The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :) + * [connect-mongo](https://www.npmjs.com/package/connect-mongo) A MongoDB-based + session store. * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based session store. From cbe6b8456f754170c83ba1fd71486a9b4628b340 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 23 Mar 2015 21:12:34 -0400 Subject: [PATCH 203/766] build: io.js@1.6 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 49d202c9..f8b221cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ node_js: - "0.10" - "0.12" - "1.0" - - "1.5" + - "1.6" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 6150f003ad42313928d40586bd28bfcb2bf3071a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 23 Mar 2015 21:13:00 -0400 Subject: [PATCH 204/766] deps: istanbul@0.3.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d6a3fabf..2afa6f1b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.3.4", "express": "~4.11.2", - "istanbul": "0.3.7", + "istanbul": "0.3.8", "mocha": "~2.2.1", "supertest": "~0.15.0" }, From f08a763499058786b84ee65b620192baa6dc6f92 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 23 Mar 2015 21:19:22 -0400 Subject: [PATCH 205/766] docs: fix readme typos --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce01faa3..d2f3bbb5 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ var session = require('express-session') Create a session middleware with the given `options`. **Note** Session data is _not_ saved in the cookie itself, just the session ID. -Session hdata is stored server-side. +Session data is stored server-side. **Warning** The default server-side session storage, `MemoryStore`, is _purposely_ not designed for a production environment. It will leak memory under most @@ -104,7 +104,7 @@ How do I know if this is necessary for my store? The best way to know is to check with your store if it implements the `touch` method. If it does, then you can safely set `resave: false`. If it does not implement the `touch` method and your store sets an expiration date on stored sessions, then you -likely need `resave: true`.h +likely need `resave: true`. ##### rolling From 7c6da9c9b3b5d53c9310f816bf5c30def05b5ebe Mon Sep 17 00:00:00 2001 From: Guillaume Zurbach Date: Thu, 12 Mar 2015 18:59:16 -0700 Subject: [PATCH 206/766] Support an array in secret option for key rotation closes #127 closes #135 --- HISTORY.md | 5 ++++ README.md | 5 +++- index.js | 60 +++++++++++++++++++++++++++++++++---------- test/session.js | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 15 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 399cf076..fd56158a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Support an array in `secret` option for key rotation + 1.10.4 / 2015-03-15 =================== diff --git a/README.md b/README.md index d2f3bbb5..f36596e3 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,10 @@ it to be saved. **Required option** -This is the secret used to sign the session ID cookie. +This is the secret used to sign the session ID cookie. This can be either a string +for a single secret, or an array of multiple secrets. If an array of secrets is +provided, only the first element will be used to sign the session ID cookie, while +all the elements will be considered when verifying the signature in requests. ##### store diff --git a/index.js b/index.js index 43d70e16..8236508e 100644 --- a/index.js +++ b/index.js @@ -74,7 +74,7 @@ var defer = typeof setImmediate === 'function' * @param {Boolean} [options.resave] Resave unmodified sessions back to the store * @param {Boolean} [options.rolling] Enable/disable rolling session expiration * @param {Boolean} [options.saveUninitialized] Save uninitialized sessions to the store - * @param {String} [options.secret] Secret for signing session ID + * @param {String|Array} [options.secret] Secret for signing session ID * @param {Object} [options.store=MemoryStore] Session store * @param {String} [options.unset] * @return {Function} middleware @@ -116,6 +116,19 @@ function session(options){ // TODO: switch to "destroy" on next major var unsetDestroy = options.unset === 'destroy'; + if (Array.isArray(options.secret) && options.secret.length === 0) { + throw new TypeError('secret option array must contain one or more strings'); + } + + if (options.secret && !Array.isArray(options.secret)) { + options.secret = [options.secret]; + } + + if (!options.secret) { + deprecate('req.secret; provide secret option'); + options.secret = undefined; + } + // notify user that this store is not // meant for a production environment if ('production' == env && store instanceof MemoryStore) { @@ -133,10 +146,6 @@ function session(options){ store.on('disconnect', function(){ storeReady = false; }); store.on('connect', function(){ storeReady = true; }); - if (!options.secret) { - deprecate('req.secret; provide secret option'); - } - return function session(req, res, next) { // self-awareness if (req.session) return next(); @@ -149,12 +158,15 @@ function session(options){ var originalPath = parseUrl.original(req).pathname; if (0 != originalPath.indexOf(cookie.path || '/')) return next(); + // ensure a secret is available or bail + if (!options.secret && !req.secret) { + next(new Error('secret option required for sessions')); + return; + } + // backwards compatibility for signed cookies // req.secret is passed from the cookie parser middleware - var secret = options.secret || req.secret; - - // ensure secret is available or bail - if (!secret) next(new Error('`secret` option required for sessions')); + var secrets = options.secret || [req.secret]; var originalHash; var originalId; @@ -164,7 +176,7 @@ function session(options){ req.sessionStore = store; // get the session ID from the cookie - var cookieId = req.sessionID = getcookie(req, name, secret); + var cookieId = req.sessionID = getcookie(req, name, secrets); // set-cookie onHeaders(res, function(){ @@ -185,7 +197,7 @@ function session(options){ return; } - setcookie(res, name, req.sessionID, secret, cookie.data); + setcookie(res, name, req.sessionID, secrets[0], cookie.data); }); // proxy end() to commit the session @@ -441,7 +453,7 @@ function generateSessionId(sess) { * @private */ -function getcookie(req, name, secret) { +function getcookie(req, name, secrets) { var header = req.headers.cookie; var raw; var val; @@ -454,7 +466,7 @@ function getcookie(req, name, secret) { if (raw) { if (raw.substr(0, 2) === 's:') { - val = signature.unsign(raw.slice(2), secret); + val = unsigncookie(raw.slice(2), secrets); if (val === false) { debug('cookie signature invalid'); @@ -481,7 +493,7 @@ function getcookie(req, name, secret) { if (raw) { if (raw.substr(0, 2) === 's:') { - val = signature.unsign(raw.slice(2), secret); + val = unsigncookie(raw.slice(2), secrets); if (val) { deprecate('cookie should be available in req.headers.cookie'); @@ -573,3 +585,23 @@ function setcookie(res, name, val, secret, options) { res.setHeader('set-cookie', header) } + +/** + * Verify and decode the given `val` with `secrets`. + * + * @param {String} val + * @param {Array} secrets + * @returns {String|Boolean} + * @private + */ +function unsigncookie(val, secrets) { + for (var i = 0; i < secrets.length; i++) { + var result = signature.unsign(val, secrets[i]); + + if (result !== false) { + return result; + } + } + + return false; +} diff --git a/test/session.js b/test/session.js index 73be6b00..3289a425 100644 --- a/test/session.js +++ b/test/session.js @@ -1010,6 +1010,74 @@ describe('session()', function(){ }) }); + describe('secret option', function () { + it('should reject empty arrays', function () { + assert.throws(createServer.bind(null, { secret: [] }), /secret option array/); + }) + + describe('when an array', function () { + it('should sign cookies', function (done) { + var server = createServer({ secret: ['keyboard cat', 'nyan cat'] }, function (req, res) { + req.session.user = 'bob'; + res.end(req.session.user); + }); + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'bob', done); + }) + + it('should sign cookies with first element', function (done) { + var store = new session.MemoryStore(); + + var server1 = createServer({ secret: ['keyboard cat', 'nyan cat'], store: store }, function (req, res) { + req.session.user = 'bob'; + res.end(req.session.user); + }); + + var server2 = createServer({ secret: 'nyan cat', store: store }, function (req, res) { + res.end(String(req.session.user)); + }); + + request(server1) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'bob', function (err, res) { + if (err) return done(err); + request(server2) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'undefined', done); + }); + }); + + it('should read cookies using all elements', function (done) { + var store = new session.MemoryStore(); + + var server1 = createServer({ secret: 'nyan cat', store: store }, function (req, res) { + req.session.user = 'bob'; + res.end(req.session.user); + }); + + var server2 = createServer({ secret: ['keyboard cat', 'nyan cat'], store: store }, function (req, res) { + res.end(String(req.session.user)); + }); + + request(server1) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'bob', function (err, res) { + if (err) return done(err); + request(server2) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'bob', done); + }); + }); + }) + }) + describe('unset option', function () { it('should reject unknown values', function(){ assert.throws(session.bind(null, { unset: 'bogus!' }), /unset.*must/) From 20f0b1db3335b88a4c707674d398c600b5cebe5c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 29 Mar 2015 20:59:32 -0400 Subject: [PATCH 207/766] docs: add session-file-store to list of session stores closes #139 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f36596e3..8060de25 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,8 @@ module. Please make a PR to add additional modules :) session store. * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based session store. + * [session-file-store](https://www.npmjs.com/package/session-file-store) A file + system-based session store. ## Example From c486130af77df810a4ffb7fb516b140d243b7c58 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Apr 2015 22:37:34 -0400 Subject: [PATCH 208/766] deps: depd@~1.0.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index fd56158a..18d1759f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Support an array in `secret` option for key rotation + * deps: depd@~1.0.1 1.10.4 / 2015-03-15 =================== diff --git a/package.json b/package.json index 2afa6f1b..34ac0cda 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.6", "crc": "3.2.1", "debug": "~2.1.3", - "depd": "~1.0.0", + "depd": "~1.0.1", "on-headers": "~1.0.0", "parseurl": "~1.3.0", "uid-safe": "1.1.0", From 7a63374395ab253c74da0ceafe22e0a1fd8d8c6e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Apr 2015 22:58:11 -0400 Subject: [PATCH 209/766] 1.11.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 18d1759f..031f8562 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.11.0 / 2015-04-07 +=================== * Support an array in `secret` option for key rotation * deps: depd@~1.0.1 diff --git a/package.json b/package.json index 34ac0cda..f95a3039 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.10.4", + "version": "1.11.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 61974bf84c3284788b20e0fb1a5cfb2798e19d66 Mon Sep 17 00:00:00 2001 From: Simon Bartlett Date: Wed, 8 Apr 2015 12:12:47 -0400 Subject: [PATCH 210/766] Fix mutating options.secret value fixes #141 --- HISTORY.md | 5 +++++ index.js | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 031f8562..f9b900f3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix mutating `options.secret` value + 1.11.0 / 2015-04-07 =================== diff --git a/index.js b/index.js index 8236508e..6f6d1b52 100644 --- a/index.js +++ b/index.js @@ -92,6 +92,7 @@ function session(options){ , rollingSessions = options.rolling || false; var resaveSession = options.resave; var saveUninitializedSession = options.saveUninitialized; + var secret = options.secret; var generateId = options.genid || generateSessionId; @@ -116,17 +117,16 @@ function session(options){ // TODO: switch to "destroy" on next major var unsetDestroy = options.unset === 'destroy'; - if (Array.isArray(options.secret) && options.secret.length === 0) { + if (Array.isArray(secret) && secret.length === 0) { throw new TypeError('secret option array must contain one or more strings'); } - if (options.secret && !Array.isArray(options.secret)) { - options.secret = [options.secret]; + if (secret && !Array.isArray(secret)) { + secret = [secret]; } - if (!options.secret) { + if (!secret) { deprecate('req.secret; provide secret option'); - options.secret = undefined; } // notify user that this store is not @@ -159,14 +159,14 @@ function session(options){ if (0 != originalPath.indexOf(cookie.path || '/')) return next(); // ensure a secret is available or bail - if (!options.secret && !req.secret) { + if (!secret && !req.secret) { next(new Error('secret option required for sessions')); return; } // backwards compatibility for signed cookies // req.secret is passed from the cookie parser middleware - var secrets = options.secret || [req.secret]; + var secrets = secret || [req.secret]; var originalHash; var originalId; From a06db382c373d069496d4fe7d7236a77870b263a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 8 Apr 2015 12:31:27 -0400 Subject: [PATCH 211/766] deps: mocha@~2.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f95a3039..b5244e6e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.4", "express": "~4.11.2", "istanbul": "0.3.8", - "mocha": "~2.2.1", + "mocha": "~2.2.4", "supertest": "~0.15.0" }, "files": [ From fa89a8dd6adb81f63583e0ab7ff65d0550162cbe Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 8 Apr 2015 12:33:43 -0400 Subject: [PATCH 212/766] 1.11.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f9b900f3..77859a7f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.11.1 / 2015-04-08 +=================== * Fix mutating `options.secret` value diff --git a/package.json b/package.json index b5244e6e..bf69317d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.11.0", + "version": "1.11.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From c10ce8d2654760fa33793e19c4eb677cf113047d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 12 Apr 2015 22:09:12 -0400 Subject: [PATCH 213/766] deps: istanbul@0.3.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf69317d..b4b4485b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.3.4", "express": "~4.11.2", - "istanbul": "0.3.8", + "istanbul": "0.3.9", "mocha": "~2.2.4", "supertest": "~0.15.0" }, From 7c2fc3f3c91aa0a29371981e31004a9e802783b0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Apr 2015 22:12:44 -0400 Subject: [PATCH 214/766] build: io.js@1.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f8b221cf..2f8efc5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ node_js: - "0.10" - "0.12" - "1.0" - - "1.6" + - "1.7" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From df8e95cc09bb32ec887af5984e0f2438a81e9dd2 Mon Sep 17 00:00:00 2001 From: Alan Sun Date: Mon, 13 Apr 2015 13:36:55 -0700 Subject: [PATCH 215/766] docs: fix typo in readme closes #142 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8060de25..9846d074 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ The default value is `false`. Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with -laws that require permission before setting a cookie. Choose `false` will also +laws that require permission before setting a cookie. Choosing `false` will also help with race conditions where a client makes multiple parallel requests without a session. From 58515fe68249dcca5607fd79a4526cbbe791623a Mon Sep 17 00:00:00 2001 From: Michael Cheng Date: Tue, 14 Apr 2015 22:01:09 -0500 Subject: [PATCH 216/766] docs: fix a typo in readme closes #144 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9846d074..5b8395f5 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Session data is stored server-side. **Warning** The default server-side session storage, `MemoryStore`, is _purposely_ not designed for a production environment. It will leak memory under most -conditions, does not scale past a single process, and it meant for debugging and +conditions, does not scale past a single process, and is meant for debugging and developing. For a list of stores, see [compatible session stores](#compatible-session-stores). From 6ee0902128f0a23acdfcfc1f2d601df11023cf41 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Sat, 25 Apr 2015 17:45:38 -0400 Subject: [PATCH 217/766] docs: add level-session-store to list of session stores closes #150 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5b8395f5..8e3fa8fc 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,8 @@ module. Please make a PR to add additional modules :) session store. * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based session store. + * [level-session-store](https://www.npmjs.com/package/level-session-store) + A LevelDB-based session store. * [session-file-store](https://www.npmjs.com/package/session-file-store) A file system-based session store. From 38184d1a0964527f78342f6047952f768890f73f Mon Sep 17 00:00:00 2001 From: Paulo Diniz Date: Mon, 20 Apr 2015 12:18:21 -0700 Subject: [PATCH 218/766] docs: fix some typos in the readme closes #146 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8e3fa8fc..3f811612 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ the ID. The default value is a function which uses the `uid2` library to generate IDs. -**NOTE** be careful you generate unique IDs so your sessions do not conflict. +**NOTE** be careful to generate unique IDs so your sessions do not conflict. ```js app.use(session({ @@ -84,13 +84,13 @@ The default value is `undefined`. - `true` The "X-Forwarded-Proto" header will be used. - `false` All headers are ignored and the connection is considered secure only if there is a direct TLS/SSL connection. - - `undefined` Use the "trust proxy" setting from express + - `undefined` Uses the "trust proxy" setting from express ##### resave Forces the session to be saved back to the session store, even if the session was never modified during the request. Depending on your store this may be -necessary, but it can also create race conditions where a client has two +necessary, but it can also create race conditions where a client makes two parallel requests to your server and changes made to the session in one request may get overwritten when the other request ends, even if it made no changes (this behavior also depends on what store you're using). From 1897dc4539586ba360076fa47d0af382c8c61771 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 25 Apr 2015 23:22:30 -0400 Subject: [PATCH 219/766] docs: add cassandra-store to list of session stores closes #149 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3f811612..d8f55c8e 100644 --- a/README.md +++ b/README.md @@ -315,6 +315,8 @@ For an example implementation view the [connect-redis](http://github.com/visionm The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :) + * [cassandra-store](https://www.npmjs.com/package/cassandra-store) An Apache + Cassandra-based session store. * [connect-mongo](https://www.npmjs.com/package/connect-mongo) A MongoDB-based session store. * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based From 98fba1593d82d059d81a76cd7771d71a583f231c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 25 Apr 2015 23:44:27 -0400 Subject: [PATCH 220/766] build: io.js@1.8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f8efc5b..3a330f9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ node_js: - "0.10" - "0.12" - "1.0" - - "1.7" + - "1.8" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From df021bb924f4e8804b9385e229e01bfb6d81d48e Mon Sep 17 00:00:00 2001 From: John Wathen Date: Sun, 3 May 2015 14:37:30 -0700 Subject: [PATCH 221/766] docs: add two mssql stores closes #152 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d8f55c8e..2f134ba3 100644 --- a/README.md +++ b/README.md @@ -317,12 +317,16 @@ module. Please make a PR to add additional modules :) * [cassandra-store](https://www.npmjs.com/package/cassandra-store) An Apache Cassandra-based session store. + * [connect-mssql](https://www.npmjs.com/package/connect-mssql) A SQL Server-based + session store. * [connect-mongo](https://www.npmjs.com/package/connect-mongo) A MongoDB-based session store. * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based session store. * [level-session-store](https://www.npmjs.com/package/level-session-store) A LevelDB-based session store. + * [mssql-session-store](https://www.npmjs.com/package/mssql-session-store) A + SQL Server-based session store. * [session-file-store](https://www.npmjs.com/package/session-file-store) A file system-based session store. From 08b834e7ad4ef36d1afbbb1e6c40a02bf1edf36c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 4 May 2015 20:53:49 -0400 Subject: [PATCH 222/766] docs: update badges --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2f134ba3..1ce90e70 100644 --- a/README.md +++ b/README.md @@ -376,13 +376,13 @@ app.get('/bar', function (req, res, next) { [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/express-session.svg?style=flat +[npm-image]: https://img.shields.io/npm/v/express-session.svg [npm-url]: https://npmjs.org/package/express-session -[travis-image]: https://img.shields.io/travis/expressjs/session.svg?style=flat +[travis-image]: https://img.shields.io/travis/expressjs/session/master.svg [travis-url]: https://travis-ci.org/expressjs/session -[coveralls-image]: https://img.shields.io/coveralls/expressjs/session.svg?style=flat +[coveralls-image]: https://img.shields.io/coveralls/expressjs/session/master.svg [coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master -[downloads-image]: https://img.shields.io/npm/dm/express-session.svg?style=flat +[downloads-image]: https://img.shields.io/npm/dm/express-session.svg [downloads-url]: https://npmjs.org/package/express-session -[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg [gratipay-url]: https://gratipay.com/dougwilson/ From 996574fceb4dd406d56321929f105a6ccb364201 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 4 May 2015 22:58:25 -0400 Subject: [PATCH 223/766] docs: add Github stars to each compatible session store --- README.md | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1ce90e70..c0ae5524 100644 --- a/README.md +++ b/README.md @@ -315,20 +315,33 @@ For an example implementation view the [connect-redis](http://github.com/visionm The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :) - * [cassandra-store](https://www.npmjs.com/package/cassandra-store) An Apache - Cassandra-based session store. - * [connect-mssql](https://www.npmjs.com/package/connect-mssql) A SQL Server-based - session store. - * [connect-mongo](https://www.npmjs.com/package/connect-mongo) A MongoDB-based - session store. - * [connect-redis](https://www.npmjs.com/package/connect-redis) A Redis-based - session store. - * [level-session-store](https://www.npmjs.com/package/level-session-store) - A LevelDB-based session store. - * [mssql-session-store](https://www.npmjs.com/package/mssql-session-store) A - SQL Server-based session store. - * [session-file-store](https://www.npmjs.com/package/session-file-store) A file - system-based session store. +[![Github Stars][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. +[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store +[cassandra-store-image]: https://img.shields.io/github/stars/webcc/cassandra-store.svg?label=%E2%98%85 + +[![Github Stars][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. +[connect-mssql-url]: https://www.npmjs.com/package/connect-mssql +[connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 + +[![Github Stars][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store. +[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo +[connect-mongo-image]: https://img.shields.io/github/stars/kcbanner/connect-mongo.svg?label=%E2%98%85 + +[![Github Stars][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. +[connect-redis-url]: https://www.npmjs.com/package/connect-redis +[connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 + +[![Github Stars][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. +[level-session-store-url]: https://www.npmjs.com/package/level-session-store +[level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 + +[![Github Stars][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. +[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store +[mssql-session-store-image]: https://img.shields.io/github/stars/jwathen/mssql-session-store.svg?label=%E2%98%85 + +[![Github Stars][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. +[session-file-store-url]: https://www.npmjs.com/package/session-file-store +[session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 ## Example From 8a363a5e7252178c81f98288e9f77319a7444141 Mon Sep 17 00:00:00 2001 From: llambda Date: Thu, 7 May 2015 20:55:46 -0500 Subject: [PATCH 224/766] docs: add connect-session-knex to list of session stores closes #153 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c0ae5524..4245ab1d 100644 --- a/README.md +++ b/README.md @@ -331,6 +331,11 @@ module. Please make a PR to add additional modules :) [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 +[![Github Stars][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using +[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. +[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex +[connect-session-knex-image]: https://img.shields.io/github/stars/llambda/connect-session-knex.svg?label=%E2%98%85 + [![Github Stars][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 From 998ace120f06fef70281472d49e6fbc665a9c8dd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 7 May 2015 23:08:36 -0400 Subject: [PATCH 225/766] build: support io.js@2.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3a330f9c..01b92ea2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ node_js: - "0.12" - "1.0" - "1.8" + - "2.0" sudo: false script: "npm run-script test-travis" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 394588f0c03150f81bf0894b15a8231a4573dcca Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 9 May 2015 15:07:47 -0400 Subject: [PATCH 226/766] tests: add session cookie reset tests --- test/session.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/session.js b/test/session.js index 3289a425..f592ef3f 100644 --- a/test/session.js +++ b/test/session.js @@ -1811,6 +1811,53 @@ describe('session()', function(){ done(); }); }) + + it('should not reset cookie', function (done) { + var server = createServer(null, function (req, res) { + req.session.cookie.expires = null; + res.end(); + }); + + request(server) + .get('/') + .expect(200, function (err, res) { + if (err) return done(err); + var val = cookie(res); + assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') + request(server) + .get('/') + .set('Cookie', val) + .expect(200, function (err, res) { + if (err) return done(err); + assert.ok(!cookie(res)); + done(); + }); + }); + }) + + it('should not reset cookie when modified', function (done) { + var server = createServer(null, function (req, res) { + req.session.cookie.expires = null; + req.session.hit = (req.session.hit || 0) + 1; + res.end(); + }); + + request(server) + .get('/') + .expect(200, function (err, res) { + if (err) return done(err); + var val = cookie(res); + assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') + request(server) + .get('/') + .set('Cookie', val) + .expect(200, function (err, res) { + if (err) return done(err); + assert.ok(!cookie(res)); + done(); + }); + }); + }) }) }) }) From 54b6e890f9840d345dae4ca2a9fac2622cb4545d Mon Sep 17 00:00:00 2001 From: llambda Date: Sun, 10 May 2015 13:33:47 -0500 Subject: [PATCH 227/766] docs: add session-rethinkdb to list of session stores closes #155 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4245ab1d..239d49b7 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,10 @@ module. Please make a PR to add additional modules :) [session-file-store-url]: https://www.npmjs.com/package/session-file-store [session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 +[![Github Stars][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. +[session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb +[session-rethinkdb-image]: https://img.shields.io/github/stars/llambda/session-rethinkdb.svg?label=%E2%98%85 + ## Example A simple example using `express-session` to store page views for a user. From d27bb148d7b63392ef5797a565670b52ccddf040 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 May 2015 20:06:39 -0400 Subject: [PATCH 228/766] deps: uid-safe@~2.0.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 77859a7f..96e22d53 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: uid-safe@~2.0.0 + 1.11.1 / 2015-04-08 =================== diff --git a/package.json b/package.json index b4b4485b..75d35af3 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.0.1", "on-headers": "~1.0.0", "parseurl": "~1.3.0", - "uid-safe": "1.1.0", + "uid-safe": "~2.0.0", "utils-merge": "1.0.0" }, "devDependencies": { From 53175ee5de601f2686f8adc0436f1625003e4479 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 May 2015 20:07:13 -0400 Subject: [PATCH 229/766] deps: debug@~2.2.0 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 96e22d53..ba7c5b2d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * deps: debug@~2.2.0 + - deps: ms@0.7.1 * deps: uid-safe@~2.0.0 1.11.1 / 2015-04-08 diff --git a/package.json b/package.json index 75d35af3..3a1834ea 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.1.2", "cookie-signature": "1.0.6", "crc": "3.2.1", - "debug": "~2.1.3", + "debug": "~2.2.0", "depd": "~1.0.1", "on-headers": "~1.0.0", "parseurl": "~1.3.0", From 01a2f4c36df85c2ecbaef9267cafd87fdc58f049 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 May 2015 23:07:24 -0400 Subject: [PATCH 230/766] deps: express@~4.12.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a1834ea..cb682882 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.4", - "express": "~4.11.2", + "express": "~4.12.3", "istanbul": "0.3.9", "mocha": "~2.2.4", "supertest": "~0.15.0" From cda52fcdac4c84f6c54d161e0380fe5fbb9b93ae Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 May 2015 23:09:15 -0400 Subject: [PATCH 231/766] 1.11.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ba7c5b2d..f2e76ef4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.11.2 / 2015-05-10 +=================== * deps: debug@~2.2.0 - deps: ms@0.7.1 diff --git a/package.json b/package.json index cb682882..93fd112b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.11.1", + "version": "1.11.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 583fbb9504847494b9096c0e08cfc35f1a091a29 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 22 May 2015 12:55:09 -0400 Subject: [PATCH 232/766] docs: add connect-mongodb-session to list of session stores closes #160 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 239d49b7..0902d8d6 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,10 @@ module. Please make a PR to add additional modules :) [connect-mongo-url]: https://www.npmjs.com/package/connect-mongo [connect-mongo-image]: https://img.shields.io/github/stars/kcbanner/connect-mongo.svg?label=%E2%98%85 +[![Github Stars][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB. +[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session +[connect-mongodb-session-image]: https://img.shields.io/github/stars/mongodb-js/connect-mongodb-session.svg?label=%E2%98%85 + [![Github Stars][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 From 8b8095e7bb1b87c362410325c38334a48cefcd24 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 May 2015 14:20:55 -0400 Subject: [PATCH 233/766] deps: mocha@2.2.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93fd112b..cfa4d44f 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.4", "express": "~4.12.3", "istanbul": "0.3.9", - "mocha": "~2.2.4", + "mocha": "2.2.5", "supertest": "~0.15.0" }, "files": [ From 8443f37999b06244a34be0986eb8429a09f8df9e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 May 2015 14:22:14 -0400 Subject: [PATCH 234/766] deps: express@~4.12.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cfa4d44f..d2687fc2 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.4", - "express": "~4.12.3", + "express": "~4.12.4", "istanbul": "0.3.9", "mocha": "2.2.5", "supertest": "~0.15.0" From c60cec9819d4e85cc245eb1e3e82dd9f0008586f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 May 2015 14:22:57 -0400 Subject: [PATCH 235/766] deps: supertest@1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d2687fc2..bcab6c81 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "express": "~4.12.4", "istanbul": "0.3.9", "mocha": "2.2.5", - "supertest": "~0.15.0" + "supertest": "1.0.1" }, "files": [ "session/", From 7a00f0226a41b5bf31ae1debb6790d09297d536a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 May 2015 14:23:56 -0400 Subject: [PATCH 236/766] deps: cookie-parser@~1.3.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bcab6c81..04efa91f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "after": "0.8.1", - "cookie-parser": "~1.3.4", + "cookie-parser": "~1.3.5", "express": "~4.12.4", "istanbul": "0.3.9", "mocha": "2.2.5", From dfdbdbfe7cfb759dba1805bece2024029e3b1508 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 May 2015 14:25:22 -0400 Subject: [PATCH 237/766] deps: cookie@0.1.3 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f2e76ef4..0d60507c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: cookie@0.1.3 + - Slight optimizations + 1.11.2 / 2015-05-10 =================== diff --git a/package.json b/package.json index 04efa91f..ee978bbe 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.1.2", + "cookie": "0.1.3", "cookie-signature": "1.0.6", "crc": "3.2.1", "debug": "~2.2.0", From 4330611b9fcb6b15b6ad54d96e14d2cfff4d6171 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2015 21:31:08 -0400 Subject: [PATCH 238/766] build: skip istanbul coverage on Node.js 0.8 --- .travis.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 01b92ea2..23d5c798 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,12 @@ node_js: - "1.8" - "2.0" sudo: false -script: "npm run-script test-travis" -after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" +before_install: + # Setup Node.js version-specific dependencies + - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" +script: + # Run test script, depending on istanbul install + - "test -n $(npm -ps ls istanbul) || npm test" + - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" +after_script: + - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" From 168cae2fdc8d6d8a84b69ffdd5d6b0618e034187 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2015 21:31:33 -0400 Subject: [PATCH 239/766] build: io.js@2.2 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 23d5c798..5835742a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ node_js: - "1.0" - "1.8" - "2.0" + - "2.2" sudo: false before_install: # Setup Node.js version-specific dependencies From 7407316d0809d13e507b3feee82587b2daddb32e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2015 21:34:56 -0400 Subject: [PATCH 240/766] build: istanbul@0.3.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ee978bbe..9ecc8faf 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.3.5", "express": "~4.12.4", - "istanbul": "0.3.9", + "istanbul": "0.3.15", "mocha": "2.2.5", "supertest": "1.0.1" }, From 41b71b022161116209deec1dfca4817850e1dccd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2015 21:46:25 -0400 Subject: [PATCH 241/766] docs: update license --- LICENSE | 2 +- index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index f24497a5..9b59ff85 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ Copyright (c) 2010 Sencha Inc. Copyright (c) 2011 TJ Holowaychuk -Copyright (c) 2014 Douglas Christopher Wilson +Copyright (c) 2014-2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/index.js b/index.js index 6f6d1b52..5e12c9fc 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ * express-session * Copyright(c) 2010 Sencha Inc. * Copyright(c) 2011 TJ Holowaychuk - * Copyright(c) 2014 Douglas Christopher Wilson + * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ From f4ddfb1e02dec0fbc67997b37bba14c34a0e54b1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2015 21:53:09 -0400 Subject: [PATCH 242/766] deps: crc@3.3.0 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 0d60507c..53c9c411 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,7 @@ unreleased * deps: cookie@0.1.3 - Slight optimizations + * deps: crc@3.3.0 1.11.2 / 2015-05-10 =================== diff --git a/package.json b/package.json index 9ecc8faf..b4651787 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.1.3", "cookie-signature": "1.0.6", - "crc": "3.2.1", + "crc": "3.3.0", "debug": "~2.2.0", "depd": "~1.0.1", "on-headers": "~1.0.0", From 64e2e7a2d21da881ea53ab984f9eff4be58d7caf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2015 21:54:03 -0400 Subject: [PATCH 243/766] 1.11.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 53c9c411..c0842e09 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.11.3 / 2015-05-22 +=================== * deps: cookie@0.1.3 - Slight optimizations diff --git a/package.json b/package.json index b4651787..242ffe73 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.11.2", + "version": "1.11.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 1b15e969e570c7331f7feab417ba7a214389fea9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 29 Jun 2015 23:23:16 -0400 Subject: [PATCH 244/766] build: istanbul@0.3.17 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 242ffe73..aceffe15 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.3.5", "express": "~4.12.4", - "istanbul": "0.3.15", + "istanbul": "0.3.17", "mocha": "2.2.5", "supertest": "1.0.1" }, From 05375000add28b9259c8db1ab34d52c719329ab4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 29 Jun 2015 23:23:41 -0400 Subject: [PATCH 245/766] build: express@~4.13.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aceffe15..f5860496 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.5", - "express": "~4.12.4", + "express": "~4.13.0", "istanbul": "0.3.17", "mocha": "2.2.5", "supertest": "1.0.1" From 40b22dc8738f2b85992c75d275b4726f566539b6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 29 Jun 2015 23:24:29 -0400 Subject: [PATCH 246/766] build: io.js@2.3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5835742a..d03ff37c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.0" - "1.8" - "2.0" - - "2.2" + - "2.3" sudo: false before_install: # Setup Node.js version-specific dependencies From 458f9da24c26ca54d9d8d144816ab391826203ed Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 29 Jun 2015 23:31:42 -0400 Subject: [PATCH 247/766] docs: add req.sessionID closes #178 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0902d8d6..745d0a66 100644 --- a/README.md +++ b/README.md @@ -293,6 +293,12 @@ to its original value. req.session.cookie.maxAge // => 30000 ``` +### req.sessionID + +To get the ID of the loaded session, access the request property +`req.sessionID`. This is simply a read-only value set when a session +is loaded/created. + ## Session Store Implementation Every session store _must_ be an `EventEmitter` and implement the following From a0f07f5d88a2c72a01f5869175633e4b999af825 Mon Sep 17 00:00:00 2001 From: Robin Cijvat Date: Wed, 24 Jun 2015 18:36:17 +0200 Subject: [PATCH 248/766] docs: add connect-monetdb to list of session stores --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 745d0a66..5a3d0b65 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,10 @@ module. Please make a PR to add additional modules :) [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql [connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 +[![Github Stars][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store. +[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb +[connect-monetdb-image]: https://img.shields.io/github/stars/MonetDB/npm-connect-monetdb.svg?label=%E2%98%85 + [![Github Stars][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store. [connect-mongo-url]: https://www.npmjs.com/package/connect-mongo [connect-mongo-image]: https://img.shields.io/github/stars/kcbanner/connect-mongo.svg?label=%E2%98%85 From 3db8535e2fb1e672bc08233a9ab2d4afa1a8d7e2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jul 2015 22:17:06 -0400 Subject: [PATCH 249/766] build: express@~4.13.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f5860496..b0c3108f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.3.5", - "express": "~4.13.0", + "express": "~4.13.1", "istanbul": "0.3.17", "mocha": "2.2.5", "supertest": "1.0.1" From a8fb6da01dfd920732f4f5020bdc79103a49f8ca Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jul 2015 22:31:42 -0400 Subject: [PATCH 250/766] docs: expand on session store implementation closes #147 --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5a3d0b65..1c528a2f 100644 --- a/README.md +++ b/README.md @@ -301,20 +301,70 @@ is loaded/created. ## Session Store Implementation -Every session store _must_ be an `EventEmitter` and implement the following -methods: +Every session store _must_ be an `EventEmitter` and implement specific +methods. The following methods are the list of **required**, **recommended**, +and **optional**. - - `.get(sid, callback)` - - `.set(sid, session, callback)` - - `.destroy(sid, callback)` + * Required methods are ones that this module will always call on the store. + * Recommended methods are ones that this module will call on the store if + available. + * Optional methods are ones this module does not call at all, but helps + present uniform stores to users. -Recommended methods include, but are not limited to: +For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. - - `.touch(sid, session, callback)` - - `.length(callback)` - - `.clear(callback)` +### store.destroy(sid, callback) -For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. +**Required** + +This required method is used to destroy/delete a session from the store given +a session ID (`sid`). The `callback` should be called as `callback(error)` once +the session is destroyed. + +### store.clear(callback) + +**Optional** + +This optional method is used to delete all sessions from the store. The +`callback` should be called as `callback(error)` once the store is cleared. + +### store.length(callback) + +**Optional** + +This optional method is used to get the count of all sessions in the store. +The `callback` should be called as `callback(error, len)`. + +### store.get(sid, callback) + +**Required** + +This required method is used to get a session from the store given a session +ID (`sid`). The `callback` should be called as `callback(error, session)`. + +The `session` argument should be a session if found, otherwise `null` or +`undefined` if the session was not found (and there was no error). A special +case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`. + +### store.set(sid, session, callback) + +**Required** + +This required method is used to upsert a session into the store given a +session ID (`sid`) and session (`session`) object. The callback should be +called as `callback(error)` once the session has been set in the store. + +### store.touch(sid, session, callback) + +**Recommended** + +This recommended method is used to "touch" a given session given a +session ID (`sid`) and session (`session`) object. The `callback` should be +called as `callback(error)` once the session has been touched. + +This is primarily used when the store will automatically delete idle sessions +and this method is used to signal to the store the given session is active, +potentially resetting the idle timer. ## Compatible Session Stores From 94f20daa0ae71f1092e1bdd6304a57cff77a8e2d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jul 2015 22:33:44 -0400 Subject: [PATCH 251/766] docs: add store.all() as an optional listed method closes #184 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 1c528a2f..07aedbdf 100644 --- a/README.md +++ b/README.md @@ -313,6 +313,13 @@ and **optional**. For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. +### store.all(callback) + +**Optional** + +This optional method is used to get all sessions in the store as an array. The +`callback` should be called as `callback(error, sessions)`. + ### store.destroy(sid, callback) **Required** From 98a9723af7d532e9b306395e3f2b7bbfa3130b97 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 6 Aug 2015 22:09:11 -0400 Subject: [PATCH 252/766] build: fix running Node.js 0.8 tests on Travis CI --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d03ff37c..b6fa08fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" script: # Run test script, depending on istanbul install - - "test -n $(npm -ps ls istanbul) || npm test" - - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" + - "test ! -z $(npm -ps ls istanbul) || npm test" + - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" after_script: - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" From b72054c2d2775a5f1ab6134ff8451fe8246a186c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 6 Aug 2015 22:09:57 -0400 Subject: [PATCH 253/766] build: io.js@2.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b6fa08fa..b9c20bbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.0" - "1.8" - "2.0" - - "2.3" + - "2.5" sudo: false before_install: # Setup Node.js version-specific dependencies From 85df0b7b3378671dda78f7813bffc1c877aa12ef Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 26 Jul 2015 02:05:56 -0600 Subject: [PATCH 254/766] docs: add cluster-store to list of session stores closes #187 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 07aedbdf..649fa28b 100644 --- a/README.md +++ b/README.md @@ -382,6 +382,12 @@ module. Please make a PR to add additional modules :) [cassandra-store-url]: https://www.npmjs.com/package/cassandra-store [cassandra-store-image]: https://img.shields.io/github/stars/webcc/cassandra-store.svg?label=%E2%98%85 +[![Github Stars][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded +stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2 +and other multi-core embedded devices). +[cluster-store-url]: https://www.npmjs.com/package/cluster-store +[cluster-store-image]: https://img.shields.io/github/stars/coolaj86/cluster-store.svg?label=%E2%98%85 + [![Github Stars][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql [connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 From c1da3f70826f3b543f3faf39f21ecc1d22bdd6f9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 11 Aug 2015 14:01:18 -0400 Subject: [PATCH 255/766] build: support io.js 3.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b9c20bbe..86391141 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ node_js: - "1.8" - "2.0" - "2.5" + - "3.0" sudo: false before_install: # Setup Node.js version-specific dependencies From 977a39be97851c970e9c8ea2624db783bb2d6fb3 Mon Sep 17 00:00:00 2001 From: Carlos Cardona Date: Mon, 10 Aug 2015 15:45:31 -0700 Subject: [PATCH 256/766] docs: add connect-couchbase to list of session stores closes #192 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 649fa28b..8afdcc55 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,10 @@ and other multi-core embedded devices). [cluster-store-url]: https://www.npmjs.com/package/cluster-store [cluster-store-image]: https://img.shields.io/github/stars/coolaj86/cluster-store.svg?label=%E2%98%85 +[![Github Stars][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. +[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase +[connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 + [![Github Stars][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql [connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 From dad99efb59ac3ab70c91d480539f171a0448095e Mon Sep 17 00:00:00 2001 From: Konstantin Kitmanov Date: Tue, 11 Aug 2015 20:48:05 +0300 Subject: [PATCH 257/766] docs: add connect-session-sequelize to list of session stores closes #195 closes #196 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 8afdcc55..44c3d963 100644 --- a/README.md +++ b/README.md @@ -417,6 +417,11 @@ and other multi-core embedded devices). [connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex [connect-session-knex-image]: https://img.shields.io/github/stars/llambda/connect-session-knex.svg?label=%E2%98%85 +[![Github Stars][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using +[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL. +[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize +[connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 + [![Github Stars][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 From e6386a806f509c55de85994ba03aba1482c0714d Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Wed, 12 Aug 2015 14:31:22 -0400 Subject: [PATCH 258/766] docs: readme grammar tweaks closes #197 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 44c3d963..a54fba54 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ app.use(function(req, res, next) { #### Session.regenerate() -To regenerate the session simply invoke the method, once complete +To regenerate the session simply invoke the method. Once complete, a new SID and `Session` instance will be initialized at `req.session`. ```js @@ -233,7 +233,7 @@ req.session.regenerate(function(err) { #### Session.destroy() -Destroys the session, removing `req.session`, will be re-generated next request. +Destroys the session, removing `req.session`; will be re-generated next request. ```js req.session.destroy(function(err) { From 86def481609d9e932fd873b43ced062d8f8c5117 Mon Sep 17 00:00:00 2001 From: Pelle Wessman Date: Sat, 22 Aug 2015 18:51:04 +0200 Subject: [PATCH 259/766] docs: add connect-pg-simple to list of session stores closes #199 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index a54fba54..abcd337b 100644 --- a/README.md +++ b/README.md @@ -408,6 +408,10 @@ and other multi-core embedded devices). [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session [connect-mongodb-session-image]: https://img.shields.io/github/stars/mongodb-js/connect-mongodb-session.svg?label=%E2%98%85 +[![Github Stars][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. +[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple +[connect-pg-simple-image]: https://img.shields.io/github/stars/voxpelli/node-connect-pg-simple.svg?label=%E2%98%85 + [![Github Stars][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 From 1fe84a45b8bbbd99e6d686cfeae916b07b459cf1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:08:48 -0400 Subject: [PATCH 260/766] deps: on-headers@~1.0.1 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index c0842e09..4f00b30f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: on-headers@~1.0.1 + - perf: enable strict mode + 1.11.3 / 2015-05-22 =================== diff --git a/package.json b/package.json index b0c3108f..cb14e6e9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "crc": "3.3.0", "debug": "~2.2.0", "depd": "~1.0.1", - "on-headers": "~1.0.0", + "on-headers": "~1.0.1", "parseurl": "~1.3.0", "uid-safe": "~2.0.0", "utils-merge": "1.0.0" From 7f56905193fd2adf9d7b5b10156750a2d6e532fa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:10:16 -0400 Subject: [PATCH 261/766] build: mocha@2.3.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb14e6e9..8e63a0d9 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.3.5", "express": "~4.13.1", "istanbul": "0.3.17", - "mocha": "2.2.5", + "mocha": "2.3.3", "supertest": "1.0.1" }, "files": [ From 5b1837b3566650b3fa6d3d0760b9be6bbd14e29a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:10:59 -0400 Subject: [PATCH 262/766] build: supertest@1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8e63a0d9..e8d3e5e5 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "express": "~4.13.1", "istanbul": "0.3.17", "mocha": "2.3.3", - "supertest": "1.0.1" + "supertest": "1.1.0" }, "files": [ "session/", From a32ec03475b1adcea9fe59f698ca5818ab82e511 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:11:20 -0400 Subject: [PATCH 263/766] deps: depd@~1.1.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 4f00b30f..12e18ffa 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,9 @@ unreleased ========== + * deps: depd@~1.1.0 + - Enable strict mode in more places + - Support web browser loading * deps: on-headers@~1.0.1 - perf: enable strict mode diff --git a/package.json b/package.json index e8d3e5e5..570408fc 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.6", "crc": "3.3.0", "debug": "~2.2.0", - "depd": "~1.0.1", + "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.0", "uid-safe": "~2.0.0", From f002713dd7760398f79e86a03325a5d964a180b2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:14:31 -0400 Subject: [PATCH 264/766] deps: cookie@0.2.2 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 12e18ffa..9bb23753 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * deps: cookie@0.2.2 + - Throw on invalid values provided to `serialize` * deps: depd@~1.1.0 - Enable strict mode in more places - Support web browser loading diff --git a/package.json b/package.json index 570408fc..b8b642f4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.1.3", + "cookie": "0.2.2", "cookie-signature": "1.0.6", "crc": "3.3.0", "debug": "~2.2.0", From 1be6318f112bebfe5e978e9317bc18a9286de73f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:26:44 -0400 Subject: [PATCH 265/766] build: cookie-parser@~1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8b642f4..f3b200a2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "after": "0.8.1", - "cookie-parser": "~1.3.5", + "cookie-parser": "~1.4.0", "express": "~4.13.1", "istanbul": "0.3.17", "mocha": "2.3.3", From 468e13323e8d5e5bfffd1c99cd544c97b9323414 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2015 19:27:40 -0400 Subject: [PATCH 266/766] build: express@~4.13.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f3b200a2..513f5c4a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "~1.4.0", - "express": "~4.13.1", + "express": "~4.13.3", "istanbul": "0.3.17", "mocha": "2.3.3", "supertest": "1.1.0" From dd1214800002d6659d6749b4f442bb7ab6a05742 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 9 Oct 2015 10:05:43 -0400 Subject: [PATCH 267/766] build: io.js@3.3 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 86391141..43c43e91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ node_js: - "2.0" - "2.5" - "3.0" + - "3.3" sudo: false before_install: # Setup Node.js version-specific dependencies From 396ef9b60fcaeb6fa573bd55d1fe79744bda0e8c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 25 Oct 2015 17:54:11 -0400 Subject: [PATCH 268/766] build: support Node.js 4.x --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 43c43e91..803d78d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,8 @@ node_js: - "2.5" - "3.0" - "3.3" + - "4.0" + - "4.2" sudo: false before_install: # Setup Node.js version-specific dependencies From 8d26b760d94baea8ae5626c35ebcabb095b28da0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 25 Oct 2015 17:54:29 -0400 Subject: [PATCH 269/766] build: istanbul@0.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 513f5c4a..c3846f2c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.4.0", "express": "~4.13.3", - "istanbul": "0.3.17", + "istanbul": "0.4.0", "mocha": "2.3.3", "supertest": "1.1.0" }, From 7824746eb65b6a0927126d2b1b796883752cd048 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 25 Oct 2015 17:56:54 -0400 Subject: [PATCH 270/766] docs: document req.session.id closes #217 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index abcd337b..dfa078a5 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,11 @@ req.session.save(function(err) { Updates the `.maxAge` property. Typically this is not necessary to call, as the session middleware does this for you. +### req.session.id + +Each session has a unique ID associated with it. This property will +contain the session ID and cannot be modified. + ### req.session.cookie Each session has a unique cookie object accompany it. This allows From a34fd39f5cc0232510eda7a1a598fac7fc39819a Mon Sep 17 00:00:00 2001 From: "Merrifield, Jay" Date: Tue, 15 Sep 2015 15:06:50 -0400 Subject: [PATCH 271/766] Support the value "auto" in the "cookie.secure" option closes #209 --- HISTORY.md | 1 + README.md | 7 +++++ index.js | 10 +++++-- test/session.js | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9bb23753..bcde1b77 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Support the value `'auto'` in the `cookie.secure` option * deps: cookie@0.2.2 - Throw on invalid values provided to `serialize` * deps: depd@~1.1.0 diff --git a/README.md b/README.md index dfa078a5..13b7cc56 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,13 @@ if (app.get('env') === 'production') { app.use(session(sess)) ``` +The `cookie.secure` option can also be set to the special value `'auto'` to have +this setting automatically match the determined security of the connection. Be +careful when using this setting if the site is available both as HTTP and HTTPS, +as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This +is useful when the Express `"trust proxy"` setting is properly setup to simplify +development vs production configuration. + By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set so the cookie becomes a browser-session cookie. When the user closes the browser the cookie (and session) will be removed. diff --git a/index.js b/index.js index 5e12c9fc..ab7bdc93 100644 --- a/index.js +++ b/index.js @@ -86,10 +86,10 @@ function session(options){ // name - previously "options.key" , name = options.name || options.key || 'connect.sid' , store = options.store || new MemoryStore - , cookie = options.cookie || {} , trustProxy = options.proxy , storeReady = true , rollingSessions = options.rolling || false; + var cookieOptions = options.cookie || {}; var resaveSession = options.resave; var saveUninitializedSession = options.saveUninitialized; var secret = options.secret; @@ -139,7 +139,11 @@ function session(options){ store.generate = function(req){ req.sessionID = generateId(req); req.session = new Session(req); - req.session.cookie = new Cookie(cookie); + req.session.cookie = new Cookie(cookieOptions); + + if (cookieOptions.secure === 'auto') { + req.session.cookie.secure = issecure(req, trustProxy); + } }; var storeImplementsTouch = typeof store.touch === 'function'; @@ -156,7 +160,7 @@ function session(options){ // pathname mismatch var originalPath = parseUrl.original(req).pathname; - if (0 != originalPath.indexOf(cookie.path || '/')) return next(); + if (originalPath.indexOf(cookieOptions.path || '/') !== 0) return next(); // ensure a secret is available or bail if (!secret && !req.secret) { diff --git a/test/session.js b/test/session.js index f592ef3f..9a56ed7f 100644 --- a/test/session.js +++ b/test/session.js @@ -638,6 +638,67 @@ describe('session()', function(){ }) }) + describe('cookie option', function () { + describe('when "secure" set to "auto"', function () { + describe('when "proxy" is "true"', function () { + before(function () { + this.server = createServer({ proxy: true, cookie: { maxAge: 5, secure: 'auto' }}) + }) + + it('should set secure when X-Forwarded-Proto is https', function (done) { + request(this.server) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(shouldSetCookie('connect.sid')) + .expect(shouldSetSecureCookie('connect.sid')) + .expect(200, done) + }) + }) + + describe('when "proxy" is "false"', function () { + before(function () { + this.server = createServer({ proxy: false, cookie: { maxAge: 5, secure: 'auto' }}) + }) + + it('should not set secure when X-Forwarded-Proto is https', function (done) { + request(this.server) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(shouldSetCookie('connect.sid')) + .expect(shouldNotSetSecureCookie('connect.sid')) + .expect(200, done) + }) + }) + + describe('when "proxy" is undefined', function() { + before(function () { + this.app = express() + .use(function(req, res, next) { Object.defineProperty(req, 'secure', { value: JSON.parse(req.headers['x-secure']) }); next(); }) + .use(session({ secret: 'keyboard cat', cookie: { maxAge: min, secure: 'auto' }})) + .use(function(req, res) { res.json(req.secure); }); + }) + + it('should set secure if req.secure = true', function (done) { + request(this.app) + .get('/') + .set('X-Secure', 'true') + .expect(shouldSetCookie('connect.sid')) + .expect(shouldSetSecureCookie('connect.sid')) + .expect(200, 'true', done) + }) + + it('should not set secure if req.secure = false', function (done) { + request(this.app) + .get('/') + .set('X-Secure', 'false') + .expect(shouldSetCookie('connect.sid')) + .expect(shouldNotSetSecureCookie('connect.sid')) + .expect(200, 'false', done) + }) + }) + }) + }) + describe('genid option', function(){ it('should reject non-function values', function(){ assert.throws(session.bind(null, { genid: 'bogus!' }), /genid.*must/) @@ -2055,6 +2116,15 @@ function shouldNotHaveHeader(header) { } } +function shouldNotSetSecureCookie(name) { + return function (res) { + var header = cookie(res) + assert.ok(header, 'should have a cookie header') + assert.equal(header.split('=')[0], name, 'should set cookie ' + name) + assert.ok(header.toLowerCase().split(/; */).every(function (k) { return k !== 'secure'; }), 'should not set secure cookie') + } +} + function shouldSetCookie(name) { return function (res) { var header = cookie(res) @@ -2072,6 +2142,15 @@ function shouldSetCookieToValue(name, val) { } } +function shouldSetSecureCookie(name) { + return function (res) { + var header = cookie(res) + assert.ok(header, 'should have a cookie header') + assert.equal(header.split('=')[0], name, 'should set cookie ' + name) + assert.ok(header.toLowerCase().split(/; */).some(function (k) { return k === 'secure'; }), 'should set secure cookie') + } +} + function sid(res) { var match = /^[^=]+=s%3A([^;\.]+)[\.;]/.exec(cookie(res)) var val = match ? match[1] : undefined From 0112953322f163f51d5f700dc95bce7412e8122f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 25 Oct 2015 20:30:00 -0400 Subject: [PATCH 272/766] 1.12.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index bcde1b77..4f7f2b80 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.12.0 / 2015-10-25 +=================== * Support the value `'auto'` in the `cookie.secure` option * deps: cookie@0.2.2 diff --git a/package.json b/package.json index c3846f2c..c911154f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.11.3", + "version": "1.12.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 9b84f883d8b3cc79951318c1329c34d98d864b5d Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Wed, 28 Oct 2015 09:53:27 +0100 Subject: [PATCH 273/766] docs: add express-nedb-session to list of session stores closes #219 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 13b7cc56..a5b0bc5c 100644 --- a/README.md +++ b/README.md @@ -438,6 +438,10 @@ and other multi-core embedded devices). [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 +[![Github Stars][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. +[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session +[express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 + [![Github Stars][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 From 61e45f98b08e149ac7be05b3dd06bd5673f24d49 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 29 Oct 2015 11:00:45 -0400 Subject: [PATCH 274/766] deps: cookie@0.2.3 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 4f7f2b80..a8d2a6e5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: cookie@0.2.3 + - Fix cookie `Max-Age` to never be a floating point number + 1.12.0 / 2015-10-25 =================== diff --git a/package.json b/package.json index c911154f..c58c4814 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.2.2", + "cookie": "0.2.3", "cookie-signature": "1.0.6", "crc": "3.3.0", "debug": "~2.2.0", From 3c7a35bde7b364917581fb86f566c697fc174a1b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 29 Oct 2015 11:01:50 -0400 Subject: [PATCH 275/766] 1.12.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a8d2a6e5..5585b036 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.12.1 / 2015-10-29 +=================== * deps: cookie@0.2.3 - Fix cookie `Max-Age` to never be a floating point number diff --git a/package.json b/package.json index c58c4814..f3fc14e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.12.0", + "version": "1.12.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 4311dc9b093385b8b22ee8acc78bf5a61fde8609 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Nov 2015 23:09:46 -0500 Subject: [PATCH 276/766] build: reduce runtime versions to one per major --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 803d78d3..2d149ab7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,9 @@ node_js: - "0.8" - "0.10" - "0.12" - - "1.0" - "1.8" - - "2.0" - "2.5" - - "3.0" - "3.3" - - "4.0" - "4.2" sudo: false before_install: From a04a4730eeaf47ad3d9aea370e9b0ff19ae15061 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Dec 2015 23:33:02 -0500 Subject: [PATCH 277/766] build: istanbul@0.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f3fc14e3..fc5a972f 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "~1.4.0", "express": "~4.13.3", - "istanbul": "0.4.0", + "istanbul": "0.4.1", "mocha": "2.3.3", "supertest": "1.1.0" }, From fdf84fb6b3b93553e9ad9fd8788916dc2ed6e220 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Dec 2015 23:34:34 -0500 Subject: [PATCH 278/766] build: mocha@2.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc5a972f..73973feb 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "~1.4.0", "express": "~4.13.3", "istanbul": "0.4.1", - "mocha": "2.3.3", + "mocha": "2.3.4", "supertest": "1.1.0" }, "files": [ From 06262c9f2f09015940c7bc6858db9594366b71bd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Dec 2015 23:38:21 -0500 Subject: [PATCH 279/766] deps: crc@3.4.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 5585b036..03cd90e1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: crc@3.4.0 + 1.12.1 / 2015-10-29 =================== diff --git a/package.json b/package.json index 73973feb..a77324ae 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.2.3", "cookie-signature": "1.0.6", - "crc": "3.3.0", + "crc": "3.4.0", "debug": "~2.2.0", "depd": "~1.1.0", "on-headers": "~1.0.1", From 34471a4adab6d213e17a5d84df7dd1686ddbfac4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Dec 2015 23:44:48 -0500 Subject: [PATCH 280/766] tests: remove unused varaibles --- test/session.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/session.js b/test/session.js index 9a56ed7f..4cb47306 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(); }); From 85667685a518fb73f2ac6a4cd97d482a3a536584 Mon Sep 17 00:00:00 2001 From: "James M. Greene" Date: Thu, 10 Dec 2015 09:19:32 -0600 Subject: [PATCH 281/766] Fix rolling: true to not set cookie without session fixes #239 closes #240 --- README.md | 8 +++++- index.js | 7 +----- test/session.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a5b0bc5c..04521bd9 100644 --- a/README.md +++ b/README.md @@ -108,10 +108,16 @@ likely need `resave: true`. ##### rolling -Force a cookie to be set on every response. This resets the expiration date. +Force a session identifier cookie to be set on every response. The expiration +is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration +countdown. The default value is `false`. +**Note** When this option is set to `true` but the `saveUnitialized` option is +set to `false`, the cookie will not be set on a response with an uninitialized +session. + ##### 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..3077cd72 100644 --- a/index.js +++ b/index.js @@ -385,14 +385,9 @@ function session(options){ return false; } - // in case of rolling session, always reset the cookie - if (rollingSessions) { - return true; - } - return cookieId != req.sessionID ? saveUninitializedSession || isModified(req.session) - : req.session.cookie.expires != null && isModified(req.session); + : rollingSessions || 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 4cb47306..682cb8d0 100644 --- a/test/session.js +++ b/test/session.js @@ -797,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(){ From ada97acf3849c06420d9d0a26e8b98f3e8391271 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Dec 2015 23:58:56 -0500 Subject: [PATCH 282/766] docs: fix default genid documentation fixes #233 --- HISTORY.md | 2 ++ README.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 03cd90e1..755292c8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * Fix `rolling: true` to not set cookie when no session exists + - Better `saveUninitialized: false` + `rolling: true` behavior * deps: crc@3.4.0 1.12.1 / 2015-10-29 diff --git a/README.md b/README.md index 04521bd9..3daf2f50 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ a string that will be used as a session ID. The function is given `req` as the first argument if you want to use some value attached to `req` when generating the ID. -The default value is a function which uses the `uid2` library to generate IDs. +The default value is a function which uses the `uid-safe` library to generate IDs. **NOTE** be careful to generate unique IDs so your sessions do not conflict. From b5b231b4b0dbd61b6621283b4c91865e86d2536d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 15 Dec 2015 00:03:29 -0500 Subject: [PATCH 283/766] docs: update req.session example for specific URL closes #231 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3daf2f50..50db7640 100644 --- a/README.md +++ b/README.md @@ -216,9 +216,11 @@ which is (generally) serialized as JSON by the store, so nested objects are typically fine. For example below is a user-specific view counter: ```js +// Use the session middleware app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) -app.use(function(req, res, next) { +// Access the session as req.session +app.get('/', function(req, res, next) { var sess = req.session if (sess.views) { sess.views++ From 79273aeca8e36e7483d343a9fea98c7abf61a8a2 Mon Sep 17 00:00:00 2001 From: "James M. Greene" Date: Thu, 10 Dec 2015 12:59:18 -0600 Subject: [PATCH 284/766] docs: add nedb-session-store to list of session stores closes #243 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 50db7640..096d0472 100644 --- a/README.md +++ b/README.md @@ -458,6 +458,10 @@ and other multi-core embedded devices). [mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store [mssql-session-store-image]: https://img.shields.io/github/stars/jwathen/mssql-session-store.svg?label=%E2%98%85 +[![Github Stars][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store. +[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store +[nedb-session-store-image]: https://img.shields.io/github/stars/JamesMGreene/nedb-session-store.svg?label=%E2%98%85 + [![Github Stars][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. [session-file-store-url]: https://www.npmjs.com/package/session-file-store [session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 From 5720c9e8b42e8152807dad311604f9f5ad34100f Mon Sep 17 00:00:00 2001 From: Valeri Vicneanschi Date: Wed, 16 Dec 2015 11:29:05 -0500 Subject: [PATCH 285/766] docs: add connect-sqlite3 to list of session stores closes #245 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 096d0472..49a49da6 100644 --- a/README.md +++ b/README.md @@ -446,6 +446,10 @@ and other multi-core embedded devices). [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 +[![Github Stars][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. +[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 +[connect-sqlite3-image]: https://img.shields.io/github/stars/rawberg/connect-sqlite3.svg?label=%E2%98%85 + [![Github Stars][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session [express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 From ead2b9f58dd1d2f7e071e507a2b9aba00f607955 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Dec 2015 20:27:32 -0500 Subject: [PATCH 286/766] build: support Node.js 5.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 2d149ab7..01d447a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ node_js: - "2.5" - "3.3" - "4.2" + - "5.2" sudo: false before_install: # Setup Node.js version-specific dependencies From 77f931401d45c33b1fb69b0a445a5a6f6c672819 Mon Sep 17 00:00:00 2001 From: Tomek Paprocki Date: Mon, 4 Jan 2016 15:40:27 +0100 Subject: [PATCH 287/766] docs: add connect-memcached to list of session stores closes #247 closes #249 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 49a49da6..0f57a99f 100644 --- a/README.md +++ b/README.md @@ -436,6 +436,10 @@ and other multi-core embedded devices). [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 +[![Github Stars][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. +[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached +[connect-memcached-image]: https://img.shields.io/github/stars/balor/connect-memcached.svg?label=%E2%98%85 + [![Github Stars][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using [Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. [connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex From b8329e8edc37ce2e11b09bf0d61a2bf45b03f610 Mon Sep 17 00:00:00 2001 From: Matt McFarland Date: Wed, 6 Jan 2016 20:40:58 -0500 Subject: [PATCH 288/766] docs: add sequelstore-connect to list of session stores closes #250 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 0f57a99f..7f1229e0 100644 --- a/README.md +++ b/README.md @@ -470,6 +470,10 @@ and other multi-core embedded devices). [nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store [nedb-session-store-image]: https://img.shields.io/github/stars/JamesMGreene/nedb-session-store.svg?label=%E2%98%85 +[![Github Stars][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). +[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect +[sequelstore-connect-image]: https://img.shields.io/github/stars/MattMcFarland/sequelstore-connect.svg?label=%E2%98%85 + [![Github Stars][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. [session-file-store-url]: https://www.npmjs.com/package/session-file-store [session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 From c34a3f3609f2eec78bb78a86944e59b906f8d3da Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Jan 2016 22:23:10 -0500 Subject: [PATCH 289/766] docs: add better alt text to GitHub stars badges --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 7f1229e0..6ce0010e 100644 --- a/README.md +++ b/README.md @@ -398,87 +398,87 @@ potentially resetting the idle timer. The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :) -[![Github Stars][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. +[![โ˜…][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. [cassandra-store-url]: https://www.npmjs.com/package/cassandra-store [cassandra-store-image]: https://img.shields.io/github/stars/webcc/cassandra-store.svg?label=%E2%98%85 -[![Github Stars][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded +[![โ˜…][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2 and other multi-core embedded devices). [cluster-store-url]: https://www.npmjs.com/package/cluster-store [cluster-store-image]: https://img.shields.io/github/stars/coolaj86/cluster-store.svg?label=%E2%98%85 -[![Github Stars][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. +[![โ˜…][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase [connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 -[![Github Stars][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. +[![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql [connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 -[![Github Stars][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store. +[![โ˜…][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store. [connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb [connect-monetdb-image]: https://img.shields.io/github/stars/MonetDB/npm-connect-monetdb.svg?label=%E2%98%85 -[![Github Stars][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store. +[![โ˜…][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store. [connect-mongo-url]: https://www.npmjs.com/package/connect-mongo [connect-mongo-image]: https://img.shields.io/github/stars/kcbanner/connect-mongo.svg?label=%E2%98%85 -[![Github Stars][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB. +[![โ˜…][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB. [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session [connect-mongodb-session-image]: https://img.shields.io/github/stars/mongodb-js/connect-mongodb-session.svg?label=%E2%98%85 -[![Github Stars][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. +[![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple [connect-pg-simple-image]: https://img.shields.io/github/stars/voxpelli/node-connect-pg-simple.svg?label=%E2%98%85 -[![Github Stars][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. +[![โ˜…][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 -[![Github Stars][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. +[![โ˜…][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. [connect-memcached-url]: https://www.npmjs.com/package/connect-memcached [connect-memcached-image]: https://img.shields.io/github/stars/balor/connect-memcached.svg?label=%E2%98%85 -[![Github Stars][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using +[![โ˜…][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using [Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. [connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex [connect-session-knex-image]: https://img.shields.io/github/stars/llambda/connect-session-knex.svg?label=%E2%98%85 -[![Github Stars][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using +[![โ˜…][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using [Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL. [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 -[![Github Stars][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. +[![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 [connect-sqlite3-image]: https://img.shields.io/github/stars/rawberg/connect-sqlite3.svg?label=%E2%98%85 -[![Github Stars][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. +[![โ˜…][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session [express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 -[![Github Stars][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. +[![โ˜…][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 -[![Github Stars][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. +[![โ˜…][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. [mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store [mssql-session-store-image]: https://img.shields.io/github/stars/jwathen/mssql-session-store.svg?label=%E2%98%85 -[![Github Stars][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store. +[![โ˜…][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store. [nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store [nedb-session-store-image]: https://img.shields.io/github/stars/JamesMGreene/nedb-session-store.svg?label=%E2%98%85 -[![Github Stars][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). +[![โ˜…][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). [sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect [sequelstore-connect-image]: https://img.shields.io/github/stars/MattMcFarland/sequelstore-connect.svg?label=%E2%98%85 -[![Github Stars][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. +[![โ˜…][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. [session-file-store-url]: https://www.npmjs.com/package/session-file-store [session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 -[![Github Stars][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. +[![โ˜…][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb [session-rethinkdb-image]: https://img.shields.io/github/stars/llambda/session-rethinkdb.svg?label=%E2%98%85 From b1ee74ebc3e808d8886fc378cf4cff3b3a2427df Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Jan 2016 22:36:42 -0500 Subject: [PATCH 290/766] docs: expand session.save() documentation closes #208 --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 6ce0010e..c62f4298 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,18 @@ req.session.reload(function(err) { #### Session.save() +Save the session back to the store, replacing the contents on the store with the +contents in memory (though a store may do something else--consult the store's +documentation for exact behavior). + +This method is automatically called at the end of the HTTP response if the +session data has been altered (though this behavior can be altered with various +options in the middleware constructor). Because of this, typically this method +does not need to be called. + +There are some cases where it is useful to call this method, for example, long- +lived requests or in WebSockets. + ```js req.session.save(function(err) { // session saved From 222b30ddeb9589ec700ae53b4e70b47a95114b77 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Jan 2016 23:45:31 -0500 Subject: [PATCH 291/766] 1.13.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 755292c8..68e8eed4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.13.0 / 2016-01-10 +=================== * Fix `rolling: true` to not set cookie when no session exists - Better `saveUninitialized: false` + `rolling: true` behavior diff --git a/package.json b/package.json index a77324ae..f63ebb2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.12.1", + "version": "1.13.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 22a3bafde16c81fcb17d05aae5322c053ac47eeb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 11 Jan 2016 10:14:25 -0500 Subject: [PATCH 292/766] build: cookie-parser@1.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f63ebb2d..41a966aa 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "after": "0.8.1", - "cookie-parser": "~1.4.0", + "cookie-parser": "1.4.1", "express": "~4.13.3", "istanbul": "0.4.1", "mocha": "2.3.4", From 07e7c30ecd0e8853f589667740188c97fc68a7d1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 11 Jan 2016 10:15:43 -0500 Subject: [PATCH 293/766] build: istanbul@0.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41a966aa..e5a65dc3 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "1.4.1", "express": "~4.13.3", - "istanbul": "0.4.1", + "istanbul": "0.4.2", "mocha": "2.3.4", "supertest": "1.1.0" }, From 3e19c88ea01c2636dd0aca7968f90a79564044b3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 11 Jan 2016 10:18:31 -0500 Subject: [PATCH 294/766] build: Node.js@5.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 01d447a5..0280df88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.2" - - "5.2" + - "5.4" sudo: false before_install: # Setup Node.js version-specific dependencies From 6eeec0e6a5a8e04503a2092bde2cbc3fcdcd37c9 Mon Sep 17 00:00:00 2001 From: Paul Esson Date: Fri, 22 Jan 2016 14:57:00 +1100 Subject: [PATCH 295/766] docs: fix note about overlapping cookie names closes #260 --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c62f4298..3c71dae9 100644 --- a/README.md +++ b/README.md @@ -70,9 +70,10 @@ request). The default value is `'connect.sid'`. -**Note** if you have multiple apps running on the same host (hostname + port), -then you need to separate the session cookies from each other. The simplest -method is to simply set different `name`s per app. +**Note** if you have multiple apps running on the same hostname (this is just +the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not +name a different hostname), then you need to separate the session cookies from +each other. The simplest method is to simply set different `name`s per app. ##### proxy From a69509d8987f32bb43ba1debf17d632c6b3ecc0b Mon Sep 17 00:00:00 2001 From: Ryan Tran Date: Wed, 27 Jan 2016 14:06:31 -0800 Subject: [PATCH 296/766] docs: fix typo of option name closes #263 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c71dae9..857f754c 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ countdown. The default value is `false`. -**Note** When this option is set to `true` but the `saveUnitialized` option is +**Note** When this option is set to `true` but the `saveUninitialized` option is set to `false`, the cookie will not be set on a response with an uninitialized session. From faa1a4ce166180329b591369ad444983ea779345 Mon Sep 17 00:00:00 2001 From: Michael Irigoyen Date: Fri, 29 Jan 2016 11:01:15 -0500 Subject: [PATCH 297/766] docs: add connect-dynamodb to list of session stores closes #265 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 857f754c..f81381f2 100644 --- a/README.md +++ b/README.md @@ -425,6 +425,10 @@ and other multi-core embedded devices). [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase [connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 +[![โ˜…][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store. +[connect-dynamodb-url]: https://github.com/ca98am79/connect-dynamodb +[connect-dynamodb-image]: https://img.shields.io/github/stars/ca98am79/connect-dynamodb.svg?label=%E2%98%85 + [![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql [connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 From 328476b37e3830b25a788fb4f26b7c375c835c2e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Jan 2016 13:15:20 -0500 Subject: [PATCH 298/766] build: mocha@2.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5a65dc3..77e00b97 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "1.4.1", "express": "~4.13.3", "istanbul": "0.4.2", - "mocha": "2.3.4", + "mocha": "2.4.5", "supertest": "1.1.0" }, "files": [ From 00422dddf5a8c2205508749cf9dd0839eced4f67 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Jan 2016 13:16:02 -0500 Subject: [PATCH 299/766] build: express@4.13.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77e00b97..76c063f7 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "1.4.1", - "express": "~4.13.3", + "express": "4.13.4", "istanbul": "0.4.2", "mocha": "2.4.5", "supertest": "1.1.0" From 9a9faf9198d217ffe2873adbfa93d6dd98d11f21 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Jan 2016 13:17:47 -0500 Subject: [PATCH 300/766] deps: parseurl@~1.3.1 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 68e8eed4..2db17e1d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: parseurl@~1.3.1 + - perf: enable strict mode + 1.13.0 / 2016-01-10 =================== diff --git a/package.json b/package.json index 76c063f7..43f95fe7 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "debug": "~2.2.0", "depd": "~1.1.0", "on-headers": "~1.0.1", - "parseurl": "~1.3.0", + "parseurl": "~1.3.1", "uid-safe": "~2.0.0", "utils-merge": "1.0.0" }, From f2044eb86f8f389e9a84245335947171853cec88 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Jan 2016 13:20:00 -0500 Subject: [PATCH 301/766] deps: uid-safe@~2.1.0 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 2db17e1d..210d6853 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,8 @@ unreleased * deps: parseurl@~1.3.1 - perf: enable strict mode + * deps: uid-safe@~2.1.0 + - Use `random-bytes` for byte source 1.13.0 / 2016-01-10 =================== diff --git a/package.json b/package.json index 43f95fe7..8b945f2e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", - "uid-safe": "~2.0.0", + "uid-safe": "~2.1.0", "utils-merge": "1.0.0" }, "devDependencies": { From 9de44c668aafd99ab7fe5b99f1aaf7d4b1b05eaf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Jan 2016 13:21:24 -0500 Subject: [PATCH 302/766] build: Node.js@5.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0280df88..d28b24e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.2" - - "5.4" + - "5.5" sudo: false before_install: # Setup Node.js version-specific dependencies From fb381f26c7d10ee1f8cd374cb5cecf95773513fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Jan 2016 13:22:47 -0500 Subject: [PATCH 303/766] perf: enable strict mode --- HISTORY.md | 1 + index.js | 2 ++ session/cookie.js | 3 ++- session/memory.js | 2 ++ session/session.js | 3 ++- session/store.js | 3 ++- 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 210d6853..727834eb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,7 @@ unreleased - perf: enable strict mode * deps: uid-safe@~2.1.0 - Use `random-bytes` for byte source + * perf: enable strict mode 1.13.0 / 2016-01-10 =================== diff --git a/index.js b/index.js index 3077cd72..0de7c62f 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,8 @@ * MIT Licensed */ +'use strict'; + /** * Module dependencies. * @private diff --git a/session/cookie.js b/session/cookie.js index 86591de3..a4dbd8a8 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -1,4 +1,3 @@ - /*! * Connect - session - Cookie * Copyright(c) 2010 Sencha Inc. @@ -6,6 +5,8 @@ * MIT Licensed */ +'use strict'; + /** * Module dependencies. */ diff --git a/session/memory.js b/session/memory.js index 9887680d..ae2175ba 100644 --- a/session/memory.js +++ b/session/memory.js @@ -6,6 +6,8 @@ * MIT Licensed */ +'use strict'; + /** * Module dependencies. * @private diff --git a/session/session.js b/session/session.js index 4647f9da..c3c0f15a 100644 --- a/session/session.js +++ b/session/session.js @@ -1,4 +1,3 @@ - /*! * Connect - session - Session * Copyright(c) 2010 Sencha Inc. @@ -6,6 +5,8 @@ * MIT Licensed */ +'use strict'; + /** * Expose Session. */ diff --git a/session/store.js b/session/store.js index 54294cbd..ca3d4a9d 100644 --- a/session/store.js +++ b/session/store.js @@ -1,4 +1,3 @@ - /*! * Connect - session - Store * Copyright(c) 2010 Sencha Inc. @@ -6,6 +5,8 @@ * MIT Licensed */ +'use strict'; + /** * Module dependencies. */ From a9fa4b0d3c7c34fe7d36f5a197dd0ed9b2da91b4 Mon Sep 17 00:00:00 2001 From: Cian Clarke Date: Tue, 1 Mar 2016 10:33:18 -0500 Subject: [PATCH 304/766] docs: fix session store list for CommonMark spec fixes #248 closes #280 --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index f81381f2..f2a6df6b 100644 --- a/README.md +++ b/README.md @@ -412,90 +412,111 @@ The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :) [![โ˜…][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. + [cassandra-store-url]: https://www.npmjs.com/package/cassandra-store [cassandra-store-image]: https://img.shields.io/github/stars/webcc/cassandra-store.svg?label=%E2%98%85 [![โ˜…][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2 and other multi-core embedded devices). + [cluster-store-url]: https://www.npmjs.com/package/cluster-store [cluster-store-image]: https://img.shields.io/github/stars/coolaj86/cluster-store.svg?label=%E2%98%85 [![โ˜…][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. + [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase [connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 [![โ˜…][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store. + [connect-dynamodb-url]: https://github.com/ca98am79/connect-dynamodb [connect-dynamodb-image]: https://img.shields.io/github/stars/ca98am79/connect-dynamodb.svg?label=%E2%98%85 [![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. + [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql [connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 [![โ˜…][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store. + [connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb [connect-monetdb-image]: https://img.shields.io/github/stars/MonetDB/npm-connect-monetdb.svg?label=%E2%98%85 [![โ˜…][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store. + [connect-mongo-url]: https://www.npmjs.com/package/connect-mongo [connect-mongo-image]: https://img.shields.io/github/stars/kcbanner/connect-mongo.svg?label=%E2%98%85 [![โ˜…][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB. + [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session [connect-mongodb-session-image]: https://img.shields.io/github/stars/mongodb-js/connect-mongodb-session.svg?label=%E2%98%85 [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. + [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple [connect-pg-simple-image]: https://img.shields.io/github/stars/voxpelli/node-connect-pg-simple.svg?label=%E2%98%85 [![โ˜…][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. + [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 [![โ˜…][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. + [connect-memcached-url]: https://www.npmjs.com/package/connect-memcached [connect-memcached-image]: https://img.shields.io/github/stars/balor/connect-memcached.svg?label=%E2%98%85 [![โ˜…][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using [Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. + [connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex [connect-session-knex-image]: https://img.shields.io/github/stars/llambda/connect-session-knex.svg?label=%E2%98%85 [![โ˜…][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using [Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL. + [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 [![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. + [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 [connect-sqlite3-image]: https://img.shields.io/github/stars/rawberg/connect-sqlite3.svg?label=%E2%98%85 [![โ˜…][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. + [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session [express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 [![โ˜…][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. + [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 [![โ˜…][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. + [mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store [mssql-session-store-image]: https://img.shields.io/github/stars/jwathen/mssql-session-store.svg?label=%E2%98%85 [![โ˜…][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store. + [nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store [nedb-session-store-image]: https://img.shields.io/github/stars/JamesMGreene/nedb-session-store.svg?label=%E2%98%85 [![โ˜…][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). + [sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect [sequelstore-connect-image]: https://img.shields.io/github/stars/MattMcFarland/sequelstore-connect.svg?label=%E2%98%85 [![โ˜…][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. + [session-file-store-url]: https://www.npmjs.com/package/session-file-store [session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 [![โ˜…][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. + [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb [session-rethinkdb-image]: https://img.shields.io/github/stars/llambda/session-rethinkdb.svg?label=%E2%98%85 From 3ff41846fa618bf89d355a138f8e0e2ff4c4a091 Mon Sep 17 00:00:00 2001 From: Mike Goodwin Date: Sun, 6 Mar 2016 23:00:31 +0000 Subject: [PATCH 305/766] docs: add connect-azuretables to list of session stores closes #285 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f2a6df6b..56e47732 100644 --- a/README.md +++ b/README.md @@ -423,6 +423,11 @@ and other multi-core embedded devices). [cluster-store-url]: https://www.npmjs.com/package/cluster-store [cluster-store-image]: https://img.shields.io/github/stars/coolaj86/cluster-store.svg?label=%E2%98%85 +[![โ˜…][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store. + +[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables +[connect-azuretables-image]: https://img.shields.io/github/stars/mike-goodwin/connect-azuretables.svg?label=%E2%98%85 + [![โ˜…][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase From 7d085d5154f31972791835639ecea0d98c27d5c0 Mon Sep 17 00:00:00 2001 From: Charles Hill Date: Tue, 2 Feb 2016 16:11:51 +0100 Subject: [PATCH 306/766] docs: add express-mysql-session to list of session stores closes #268 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 56e47732..ca9da9d1 100644 --- a/README.md +++ b/README.md @@ -485,6 +485,12 @@ and other multi-core embedded devices). [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 +[![โ˜…][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native +[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module. + +[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session +[express-mysql-session-image]: https://img.shields.io/github/stars/chill117/express-mysql-session.svg?label=%E2%98%85 + [![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 From 27be0879fbce1e9601cad7ed60f400f100bd1994 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 Apr 2016 22:04:36 -0400 Subject: [PATCH 307/766] build: Node.js@4.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d28b24e4..af57a7f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.2" + - "4.4" - "5.5" sudo: false before_install: From 454b64bd167a41450ee8ce8a726c4dea5f5c2b93 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 Apr 2016 22:06:51 -0400 Subject: [PATCH 308/766] build: Node.js@5.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index af57a7f6..86e88f36 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.4" - - "5.5" + - "5.10" sudo: false before_install: # Setup Node.js version-specific dependencies From ecb41b5cec04fd174e08fb02a799b18fed4262e0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 Apr 2016 22:10:44 -0400 Subject: [PATCH 309/766] build: cache node_modules on Travis CI --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 86e88f36..96f65184 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,15 @@ node_js: - "4.4" - "5.10" sudo: false +cache: + directories: + - node_modules before_install: # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" + # Update Node.js modules + - "test ! -d node_modules || npm prune" + - "test ! -d node_modules || npm rebuild" script: # Run test script, depending on istanbul install - "test ! -z $(npm -ps ls istanbul) || npm test" From bce5eb6d1875a71c3a697bee3330fa5b3a5a6f43 Mon Sep 17 00:00:00 2001 From: Brendon Date: Wed, 18 May 2016 14:59:30 -0400 Subject: [PATCH 310/766] docs: add note that PassportJS has fixed empty object closes #314 closes #316 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca9da9d1..2e7f8c96 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ choose what is appropriate to your use-case. **Note** if you are using Session in conjunction with PassportJS, Passport will add an empty Passport object to the session for use after a user is authenticated, which will be treated as a modification to the session, causing -it to be saved. +it to be saved. *This has been fixed in PassportJS 0.3.0* ##### secret From 0b735d4d2b0252a60951f33a703a48a0cc784487 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 12 Jun 2016 23:14:36 -0400 Subject: [PATCH 311/766] build: cookie-parser@1.4.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8b945f2e..4f1fa617 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "after": "0.8.1", - "cookie-parser": "1.4.1", + "cookie-parser": "1.4.3", "express": "4.13.4", "istanbul": "0.4.2", "mocha": "2.4.5", From a4d27229091c195253e8f78d30151a6ad5e052c3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 12 Jun 2016 23:15:05 -0400 Subject: [PATCH 312/766] build: istanbul@0.4.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4f1fa617..9e5aa6c3 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "1.4.3", "express": "4.13.4", - "istanbul": "0.4.2", + "istanbul": "0.4.3", "mocha": "2.4.5", "supertest": "1.1.0" }, From 2869dec5b264b4b2ca0d8af579920c7d646d3bbc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 12 Jun 2016 23:15:37 -0400 Subject: [PATCH 313/766] build: mocha@2.5.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9e5aa6c3..2cd0a55e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "1.4.3", "express": "4.13.4", "istanbul": "0.4.3", - "mocha": "2.4.5", + "mocha": "2.5.3", "supertest": "1.1.0" }, "files": [ From 0cccca2c825de5861d75960cc882eee794eb65dd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 12 Jun 2016 23:16:01 -0400 Subject: [PATCH 314/766] build: Node.js@5.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96f65184..388f282d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.4" - - "5.10" + - "5.11" sudo: false cache: directories: From 839959036c0f6add53166f4a4d73edfc126d5ab7 Mon Sep 17 00:00:00 2001 From: Gabriel Foust Date: Wed, 2 Mar 2016 14:54:08 -0600 Subject: [PATCH 315/766] Methods are no longer enumerable on req.session object closes #282 --- HISTORY.md | 1 + session/session.js | 39 ++++++++++++++++++++++++++++----------- test/session.js | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 727834eb..a44eebf0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Methods are no longer enumerable on `req.session` object * deps: parseurl@~1.3.1 - perf: enable strict mode * deps: uid-safe@~2.1.0 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() From 76f8fcbc0f976e4450dc1d6065b314d9639aad02 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 12 Jun 2016 23:36:05 -0400 Subject: [PATCH 316/766] deps: cookie@0.3.1 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index a44eebf0..3d6753c0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,13 @@ unreleased ========== * Methods are no longer enumerable on `req.session` object + * deps: cookie@0.3.1 + - Add `sameSite` option + - Improve error message when `encode` is not a function + - Improve error message when `expires` is not a `Date` + - perf: enable strict mode + - perf: use for loop in parse + - perf: use string concatination for serialization * deps: parseurl@~1.3.1 - perf: enable strict mode * deps: uid-safe@~2.1.0 diff --git a/package.json b/package.json index 2cd0a55e..af85d794 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.2.3", + "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.0", "debug": "~2.2.0", From 650a0fecd1d0466d3aa582f3ca9f4d0eb8391e5b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Jun 2016 00:25:20 -0400 Subject: [PATCH 317/766] docs: move cookie-parser note to the top --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2e7f8c96..b85066c2 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,11 @@ Create a session middleware with the given `options`. **Note** Session data is _not_ saved in the cookie itself, just the session ID. Session data is stored server-side. +**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser) +no longer needs to be used for this module to work. This module now directly reads +and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues +if the `secret` is not the same between this module and `cookie-parser`. + **Warning** The default server-side session storage, `MemoryStore`, is _purposely_ not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and @@ -163,11 +168,6 @@ The default value is `'keep'`. #### Cookie options -**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser) -no longer needs to be used for this module to work. This module now directly reads -and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues -if the `secret` is not the same between this module and `cookie-parser`. - Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure` is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set "trust proxy" in express: From 3fb472d0249cbe58f78ecac8c77b08d656e67a98 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Jun 2016 00:28:52 -0400 Subject: [PATCH 318/766] docs: move cookies documentation under cookie section --- README.md | 93 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index b85066c2..f3b47eb9 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,56 @@ For a list of stores, see [compatible session stores](#compatible-session-stores ##### cookie -Settings for the session ID cookie. See the "Cookie options" section below for -more information on the different values. +Settings for the session ID cookie. The default value is `{ path: '/', httpOnly: true, secure: false, maxAge: null }`. +Please note that `secure: true` is a **recommended** option. However, it requires +an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure` +is set, and you access your site over HTTP, the cookie will not be set. If you +have your node.js behind a proxy and are using `secure: true`, you need to set +"trust proxy" in express: + +```js +var app = express() +app.set('trust proxy', 1) // trust first proxy +app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true, + cookie: { secure: true } +})) +``` + +For using secure cookies in production, but allowing for testing in development, +the following is an example of enabling this setup based on `NODE_ENV` in express: + +```js +var app = express() +var sess = { + secret: 'keyboard cat', + cookie: {} +} + +if (app.get('env') === 'production') { + app.set('trust proxy', 1) // trust first proxy + sess.cookie.secure = true // serve secure cookies +} + +app.use(session(sess)) +``` + +The `cookie.secure` option can also be set to the special value `'auto'` to have +this setting automatically match the determined security of the connection. Be +careful when using this setting if the site is available both as HTTP and HTTPS, +as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This +is useful when the Express `"trust proxy"` setting is properly setup to simplify +development vs production configuration. + +By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set +so the cookie becomes a browser-session cookie. When the user closes the +browser the cookie (and session) will be removed. + ##### genid Function to call to generate a new session ID. Provide a function that returns @@ -166,50 +211,6 @@ The default value is `'keep'`. - `'keep'` The session in the store will be kept, but modifications made during the request are ignored and not saved. -#### Cookie options - -Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. -If `secure` is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set "trust proxy" in express: - -```js -var app = express() -app.set('trust proxy', 1) // trust first proxy -app.use(session({ - secret: 'keyboard cat', - resave: false, - saveUninitialized: true, - cookie: { secure: true } -})) -``` - -For using secure cookies in production, but allowing for testing in development, the following is an example of enabling this setup based on `NODE_ENV` in express: - -```js -var app = express() -var sess = { - secret: 'keyboard cat', - cookie: {} -} - -if (app.get('env') === 'production') { - app.set('trust proxy', 1) // trust first proxy - sess.cookie.secure = true // serve secure cookies -} - -app.use(session(sess)) -``` - -The `cookie.secure` option can also be set to the special value `'auto'` to have -this setting automatically match the determined security of the connection. Be -careful when using this setting if the site is available both as HTTP and HTTPS, -as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This -is useful when the Express `"trust proxy"` setting is properly setup to simplify -development vs production configuration. - -By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set -so the cookie becomes a browser-session cookie. When the user closes the -browser the cookie (and session) will be removed. - ### req.session To store or access session data, simply use the request property `req.session`, From 40afdb04bf83448b82bcc681293c12c620b9856c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Jun 2016 00:37:22 -0400 Subject: [PATCH 319/766] docs: add full documentation on the cookie option --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f3b47eb9..02a41b8a 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,77 @@ For a list of stores, see [compatible session stores](#compatible-session-stores ##### cookie -Settings for the session ID cookie. +Settings object for the session ID cookie. The default value is +`{ path: '/', httpOnly: true, secure: false, maxAge: null }`. -The default value is `{ path: '/', httpOnly: true, secure: false, maxAge: null }`. +The following are options that can be set in this object. + +###### domain + +Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain +is set, and most clients will consider the cookie to apply to only the current +domain. + +###### expires + +Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute. +By default, no expiration is set, and most clients will consider this a +"non-persistent cookie" and will delete it on a condition like exiting a web browser +application. + +**Note** The cookie storage model specification states that if both `expires` and +`magAge` are set, then `maxAge` takes precedence, but it is possiblke not all +clients by obey this, so if both are set, they should point to the same date and +time. + +###### httpOnly + +Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy, +the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` +attribute is set. + +**Note** be careful when setting this to `true`, as compliant clients will not allow +client-side JavaScript to see the cookie in `document.cookie`. + +###### maxAge + +Specifies the `number` (in seconds) to be the value for the `Max-Age` `Set-Cookie` attribute. +The given number will be converted to an integer by rounding down. By default, no maximum +age is set. + +**Note** the cookie storage model specification states that if both `expires` and `magAge` +are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, +so if both are set, they should point to the same date and time. + +###### path + +Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which +is the root path of the domain. + +###### sameSite + +Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute. + + - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. + - `false` will not set the `SameSite` attribute. + - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. + - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. + +More information about the different enforcement levels can be found in the specification +https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1.1 + +**Note** This is an attribute that has not yet been fully standardized, and may change in +the future. This also means many clients may ignore this attribute until they understand it. + +###### secure + +Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy, +the `Secure` attribute is set, otherwise it is not. By default, the `Secure` +attribute is not set. + +**Note** be careful when setting this to `true`, as compliant clients will not send +the cookie back to the server in the future if the browser does not have an HTTPS +connection. Please note that `secure: true` is a **recommended** option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure` @@ -89,10 +157,6 @@ as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This is useful when the Express `"trust proxy"` setting is properly setup to simplify development vs production configuration. -By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set -so the cookie becomes a browser-session cookie. When the user closes the -browser the cookie (and session) will be removed. - ##### genid Function to call to generate a new session ID. Provide a function that returns From 87300c0f57903553fa5ed14374ce9c3ac6141e04 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Jun 2016 00:44:55 -0400 Subject: [PATCH 320/766] tests: ignore production warning in coverage --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 0de7c62f..4f465609 100644 --- a/index.js +++ b/index.js @@ -134,6 +134,7 @@ function session(options){ // notify user that this store is not // meant for a production environment if ('production' == env && store instanceof MemoryStore) { + /* istanbul ignore next: not tested */ console.warn(warning); } From 1b424378781d13d2baa54c2e66b894934f1f9d03 Mon Sep 17 00:00:00 2001 From: Gabriel D Date: Mon, 13 Jun 2016 20:53:13 -0400 Subject: [PATCH 321/766] docs: fix typo in readme closes #321 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 02a41b8a..dbd1e081 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ By default, no expiration is set, and most clients will consider this a application. **Note** The cookie storage model specification states that if both `expires` and -`magAge` are set, then `maxAge` takes precedence, but it is possiblke not all +`magAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, so if both are set, they should point to the same date and time. From 1940ce9abc00e123967c2b11c4426da48c3681c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Jun 2016 21:03:09 -0400 Subject: [PATCH 322/766] docs: fix cookie expires/maxAge documentation fixes #320 --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index dbd1e081..b88ed824 100644 --- a/README.md +++ b/README.md @@ -61,10 +61,11 @@ By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and will delete it on a condition like exiting a web browser application. -**Note** The cookie storage model specification states that if both `expires` and -`magAge` are set, then `maxAge` takes precedence, but it is possible not all -clients by obey this, so if both are set, they should point to the same date and -time. +**Note** If both `expires` and `maxAge` are set in the options, then the last one +defined in the object is what is used. + +**Note** The `expires` option should not be set directly; instead only use the `maxAge` +option. ###### httpOnly @@ -77,13 +78,13 @@ client-side JavaScript to see the cookie in `document.cookie`. ###### maxAge -Specifies the `number` (in seconds) to be the value for the `Max-Age` `Set-Cookie` attribute. -The given number will be converted to an integer by rounding down. By default, no maximum -age is set. +Specifies the `number` (in milliseconds) to use when calculating the `Expires` +`Set-Cookie` attribute. This is done by taking the current server time and adding +`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default, +no maximum age is set. -**Note** the cookie storage model specification states that if both `expires` and `magAge` -are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, -so if both are set, they should point to the same date and time. +**Note** If both `expires` and `maxAge` are set in the options, then the last one +defined in the object is what is used. ###### path From 50cdae238a3806df75302f73ed280e361f13eebb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 Jun 2016 22:12:40 -0400 Subject: [PATCH 323/766] Fix issue where Set-Cookie Expires was not always updated closes #276 closes #277 closes #296 --- HISTORY.md | 1 + index.js | 17 ++++++++--------- test/session.js | 28 ++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 3d6753c0..27694bbe 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix issue where `Set-Cookie` `Expires` was not always updated * Methods are no longer enumerable on `req.session` object * deps: cookie@0.3.1 - Add `sameSite` option diff --git a/index.js b/index.js index 4f465609..8bec911d 100644 --- a/index.js +++ b/index.js @@ -192,19 +192,21 @@ function session(options){ return; } - var cookie = req.session.cookie; + if (!shouldSetCookie(req)) { + return; + } // only send secure cookies via https - if (cookie.secure && !issecure(req, trustProxy)) { + if (req.session.cookie.secure && !issecure(req, trustProxy)) { debug('not secured'); return; } - if (!shouldSetCookie(req)) { - return; - } + // touch session + req.session.touch(); - setcookie(res, name, req.sessionID, secrets[0], cookie.data); + // set cookie + setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data); }); // proxy end() to commit the session @@ -285,9 +287,6 @@ function session(options){ return _end.call(res, chunk, encoding); } - // touch session - req.session.touch(); - if (shouldSave(req)) { req.session.save(function onsave(err) { if (err) { diff --git a/test/session.js b/test/session.js index 35f20de2..b6b6f01d 100644 --- a/test/session.js +++ b/test/session.js @@ -255,6 +255,34 @@ describe('session()', function(){ }) }) + it('should update cookie expiration when slow write', function (done) { + var app = express(); + app.use(session({ rolling: true, secret: 'keyboard cat', cookie: { maxAge: min }})); + app.use(function (req, res, next) { + req.session.user = 'bob'; + res.write('hello, '); + setTimeout(function () { + res.end('world!'); + }, 200); + }); + + request(app) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, function (err, res) { + if (err) return done(err); + var originalExpires = expires(res); + setTimeout(function () { + request(app) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetCookie('connect.sid')) + .expect(function (res) { assert.notEqual(originalExpires, expires(res)); }) + .expect(200, done); + }, (1000 - (Date.now() % 1000) + 200)); + }); + }); + describe('when response ended', function () { it('should have saved session', function (done) { var saved = false From 68709738dcb895c91f88e84bc1d50481f95bb8d7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Jun 2016 13:18:22 -0400 Subject: [PATCH 324/766] deps: uid-safe@~2.1.1 --- HISTORY.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 27694bbe..f48a6b4d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -12,8 +12,9 @@ unreleased - perf: use string concatination for serialization * deps: parseurl@~1.3.1 - perf: enable strict mode - * deps: uid-safe@~2.1.0 + * deps: uid-safe@~2.1.1 - Use `random-bytes` for byte source + - deps: base64-url@1.2.2 * perf: enable strict mode 1.13.0 / 2016-01-10 diff --git a/package.json b/package.json index af85d794..f5763b5a 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", - "uid-safe": "~2.1.0", + "uid-safe": "~2.1.1", "utils-merge": "1.0.0" }, "devDependencies": { From f2a820345a1816639196d7f89688d024e042df50 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Jun 2016 13:18:50 -0400 Subject: [PATCH 325/766] build: express@4.14.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f5763b5a..f871967c 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.1", "cookie-parser": "1.4.3", - "express": "4.13.4", + "express": "4.14.0", "istanbul": "0.4.3", "mocha": "2.5.3", "supertest": "1.1.0" From 16cbfb29860499470d4daa3f2e4b886b62f1fb79 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Jun 2016 18:03:24 -0400 Subject: [PATCH 326/766] Correctly inherit from EventEmitter class in Store base class --- HISTORY.md | 1 + session/store.js | 26 ++++++++++++++++++-------- test/session.js | 8 +++++--- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f48a6b4d..a6834d49 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Correctly inherit from `EventEmitter` class in `Store` base class * Fix issue where `Set-Cookie` `Expires` was not always updated * Methods are no longer enumerable on `req.session` object * deps: cookie@0.3.1 diff --git a/session/store.js b/session/store.js index ca3d4a9d..7dac9453 100644 --- a/session/store.js +++ b/session/store.js @@ -9,25 +9,35 @@ /** * Module dependencies. + * @private */ +var Cookie = require('./cookie') var EventEmitter = require('events').EventEmitter - , Session = require('./session') - , Cookie = require('./cookie'); +var Session = require('./session') +var util = require('util') /** - * Initialize abstract `Store`. - * - * @api private + * Module exports. + * @public + */ + +module.exports = Store + +/** + * Abstract base class for session stores. + * @public */ -var Store = module.exports = function Store(options){}; +function Store () { + EventEmitter.call(this) +} /** - * Inherit from `EventEmitter.prototype`. + * Inherit from EventEmitter. */ -Store.prototype.__proto__ = EventEmitter.prototype; +util.inherits(Store, EventEmitter) /** * Re-generate the given requests's session. diff --git a/test/session.js b/test/session.js index b6b6f01d..727a9ed2 100644 --- a/test/session.js +++ b/test/session.js @@ -11,6 +11,7 @@ var express = require('express') var fs = require('fs') var http = require('http') var https = require('https') +var util = require('util') var min = 60 * 1000; @@ -2289,11 +2290,12 @@ function writePatch() { } } -function SyncStore() { - this.sessions = Object.create(null); +function SyncStore () { + session.Store.call(this) + this.sessions = Object.create(null) } -SyncStore.prototype.__proto__ = session.Store.prototype; +util.inherits(SyncStore, session.Store) SyncStore.prototype.destroy = function destroy(sid, callback) { delete this.sessions[sid]; From 3c1cc028b10cfb3acf96123d6e9f4dab0869c3d8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Jun 2016 22:05:46 -0400 Subject: [PATCH 327/766] build: istanbul@0.4.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f871967c..5eae7025 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.1", "cookie-parser": "1.4.3", "express": "4.14.0", - "istanbul": "0.4.3", + "istanbul": "0.4.4", "mocha": "2.5.3", "supertest": "1.1.0" }, From 9d21d90f3e07f4380b6b187faa21e096ec9db6a2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Jun 2016 22:21:19 -0400 Subject: [PATCH 328/766] tests: add tests for store disconnect and connect --- index.js | 21 +++++++++++++++++---- test/session.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 8bec911d..a00dda0d 100644 --- a/index.js +++ b/index.js @@ -150,16 +150,29 @@ function session(options){ }; var storeImplementsTouch = typeof store.touch === 'function'; - store.on('disconnect', function(){ storeReady = false; }); - store.on('connect', function(){ storeReady = true; }); + + // register event listeners for the store + store.on('disconnect', function ondisconnect() { + storeReady = false + }) + store.on('connect', function onconnect() { + storeReady = true + }) return function session(req, res, next) { // self-awareness - if (req.session) return next(); + if (req.session) { + next() + return + } // Handle connection as if there is no session if // the store has temporarily disconnected etc - if (!storeReady) return debug('store is disconnected'), next(); + if (!storeReady) { + debug('store is disconnected') + next() + return + } // pathname mismatch var originalPath = parseUrl.original(req).pathname; diff --git a/test/session.js b/test/session.js index 727a9ed2..e2258114 100644 --- a/test/session.js +++ b/test/session.js @@ -1467,6 +1467,42 @@ describe('session()', function(){ .expect(200, 'bar,cookie,foo', done); }); + it('should not be set if store is disconnected', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + res.end(typeof req.session) + }) + + store.emit('disconnect') + + request(server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'undefined', done) + }) + + it('should be set when store reconnects', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + res.end(typeof req.session) + }) + + store.emit('disconnect') + + request(server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'undefined', function (err) { + if (err) return done(err) + + store.emit('connect') + + request(server) + .get('/') + .expect(200, 'object', done) + }) + }) + describe('.destroy()', function(){ it('should destroy the previous session', function(done){ var app = express() From d95275bd5345b161585ec7c6de22bcd77b484a65 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Jun 2016 22:50:55 -0400 Subject: [PATCH 329/766] perf: remove argument reassignment --- HISTORY.md | 1 + index.js | 50 ++++++++++++++++++++++++++++++++---------------- session/store.js | 3 +-- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a6834d49..dbe831ea 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -17,6 +17,7 @@ unreleased - Use `random-bytes` for byte source - deps: base64-url@1.2.2 * perf: enable strict mode + * perf: remove argument reassignment 1.13.0 / 2016-01-10 =================== diff --git a/index.js b/index.js index a00dda0d..5794118f 100644 --- a/index.js +++ b/index.js @@ -83,20 +83,35 @@ var defer = typeof setImmediate === 'function' * @public */ -function session(options){ - var options = options || {} - // name - previously "options.key" - , name = options.name || options.key || 'connect.sid' - , store = options.store || new MemoryStore - , trustProxy = options.proxy - , storeReady = true - , rollingSessions = options.rolling || false; - var cookieOptions = options.cookie || {}; - var resaveSession = options.resave; - var saveUninitializedSession = options.saveUninitialized; - var secret = options.secret; - - var generateId = options.genid || generateSessionId; +function session(options) { + var opts = options || {} + + // get the cookie options + var cookieOptions = opts.cookie || {} + + // get the session id generate function + var generateId = opts.genid || generateSessionId + + // get the session cookie name + var name = opts.name || opts.key || 'connect.sid' + + // get the session store + var store = opts.store || new MemoryStore() + + // get the trust proxy setting + var trustProxy = opts.proxy + + // get the resave session option + var resaveSession = opts.resave; + + // get the rolling session option + var rollingSessions = Boolean(opts.rolling) + + // get the save uninitialized session option + var saveUninitializedSession = opts.saveUninitialized + + // get the cookie signing secret + var secret = opts.secret if (typeof generateId !== 'function') { throw new TypeError('genid option must be a function'); @@ -112,12 +127,12 @@ function session(options){ saveUninitializedSession = true; } - if (options.unset && options.unset !== 'destroy' && options.unset !== 'keep') { + if (opts.unset && opts.unset !== 'destroy' && opts.unset !== 'keep') { throw new TypeError('unset option must be "destroy" or "keep"'); } // TODO: switch to "destroy" on next major - var unsetDestroy = options.unset === 'destroy'; + var unsetDestroy = opts.unset === 'destroy' if (Array.isArray(secret) && secret.length === 0) { throw new TypeError('secret option array must contain one or more strings'); @@ -151,7 +166,8 @@ function session(options){ var storeImplementsTouch = typeof store.touch === 'function'; - // register event listeners for the store + // register event listeners for the store to track readiness + var storeReady = true store.on('disconnect', function ondisconnect() { storeReady = false }) diff --git a/session/store.js b/session/store.js index 7dac9453..387469c5 100644 --- a/session/store.js +++ b/session/store.js @@ -70,8 +70,7 @@ Store.prototype.load = function(sid, fn){ if (err) return fn(err); if (!sess) return fn(); var req = { sessionID: sid, sessionStore: self }; - sess = self.createSession(req, sess); - fn(null, sess); + fn(null, self.createSession(req, sess)) }); }; From af2fa7dcb2be7866fadca8500fd4204530b72ea3 Mon Sep 17 00:00:00 2001 From: Gabriel D Date: Wed, 22 Jun 2016 02:28:34 -0500 Subject: [PATCH 330/766] tests: handle errors within tests --- test/session.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/session.js b/test/session.js index e2258114..f9419d48 100644 --- a/test/session.js +++ b/test/session.js @@ -1509,7 +1509,7 @@ describe('session()', function(){ .use(session({ secret: 'keyboard cat' })) .use(function(req, res, next){ req.session.destroy(function(err){ - if (err) throw err; + if (err) return next(err) assert(!req.session, 'req.session after destroy'); res.end(); }); @@ -1529,7 +1529,7 @@ describe('session()', function(){ .use(function(req, res, next){ var id = req.session.id; req.session.regenerate(function(err){ - if (err) throw err; + if (err) return next(err) assert.notEqual(id, req.session.id) res.end(); }); @@ -1936,6 +1936,7 @@ describe('session()', function(){ request(app) .get('/') .expect(200, '1', function (err, res) { + if (err) return done(err) var a = new Date(expires(res)) var b = new Date var delta = a.valueOf() - b.valueOf() @@ -1952,6 +1953,7 @@ describe('session()', function(){ .get('/') .set('Cookie', val) .expect(200, '2', function (err, res) { + if (err) return done(err) var a = new Date(expires(res)) var b = new Date var delta = a.valueOf() - b.valueOf() @@ -1968,6 +1970,7 @@ describe('session()', function(){ .get('/') .set('Cookie', val) .expect(200, '3', function (err, res) { + if (err) return done(err) var a = new Date(expires(res)) var b = new Date var delta = a.valueOf() - b.valueOf() From bf359988222c8919cc4234bb72e1c00985a69042 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 24 Jun 2016 00:16:45 -0400 Subject: [PATCH 331/766] Fix a merge error in MemoryStore to fix JSDoc comments --- session/memory.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/session/memory.js b/session/memory.js index ae2175ba..25252b6c 100644 --- a/session/memory.js +++ b/session/memory.js @@ -116,6 +116,11 @@ MemoryStore.prototype.get = function get(sessionId, callback) { * @public */ +MemoryStore.prototype.set = function set(sessionId, session, callback) { + this.sessions[sessionId] = JSON.stringify(session) + callback && defer(callback) +} + /** * Get number of active sessions. * @@ -130,11 +135,6 @@ MemoryStore.prototype.length = function length(callback) { }) } -MemoryStore.prototype.set = function set(sessionId, session, callback) { - this.sessions[sessionId] = JSON.stringify(session) - callback && defer(callback) -} - /** * Touch the given session object associated with the given session ID. * From 9fd23195578eac5962d52f46781a75a297fbe685 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 1 Jul 2016 23:04:33 -0400 Subject: [PATCH 332/766] 1.14.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index dbe831ea..8ec88855 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.14.0 / 2016-07-01 +=================== * Correctly inherit from `EventEmitter` class in `Store` base class * Fix issue where `Set-Cookie` `Expires` was not always updated diff --git a/package.json b/package.json index 5eae7025..d1852719 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.13.0", + "version": "1.14.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From de4ea0150c27efd48ed8aa4b6c4f1112b9321874 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Aug 2016 15:17:51 -0400 Subject: [PATCH 333/766] build: support Node.js 6.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 388f282d..fc45a8be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ node_js: - "3.3" - "4.4" - "5.11" + - "6.2" sudo: false cache: directories: From 5a6d259a595d5ca0d3ac94a064b8f210f1ef74db Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Aug 2016 15:27:52 -0400 Subject: [PATCH 334/766] deps: uid-safe@~2.1.2 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8ec88855..26a24595 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: uid-safe@~2.1.2 + - deps: base64-url@1.3.2 + 1.14.0 / 2016-07-01 =================== diff --git a/package.json b/package.json index d1852719..f2af341e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", - "uid-safe": "~2.1.1", + "uid-safe": "~2.1.2", "utils-merge": "1.0.0" }, "devDependencies": { From 5d7b01d335f0704e74c25cd4ce20eb0f4c8a7290 Mon Sep 17 00:00:00 2001 From: Jan Hecking Date: Mon, 11 Jul 2016 11:10:25 +0800 Subject: [PATCH 335/766] docs: add aerospike-session-store to list of session stores closes #328 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b88ed824..3bbca19a 100644 --- a/README.md +++ b/README.md @@ -477,6 +477,11 @@ potentially resetting the idle timer. The following modules implement a session store that is compatible with this module. Please make a PR to add additional modules :) +[![โ˜…][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/). + +[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store +[aerospike-session-store-image]: https://img.shields.io/github/stars/aerospike/aerospike-session-store-expressjs.svg?label=%E2%98%85 + [![โ˜…][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. [cassandra-store-url]: https://www.npmjs.com/package/cassandra-store From 4c85a80376f137dfea9456ecc2495c10cd018a4e Mon Sep 17 00:00:00 2001 From: Benjamin Vadant Date: Tue, 19 Jul 2016 22:12:43 +0200 Subject: [PATCH 336/766] docs: add medea-session-store to list of session stores closes #332 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 3bbca19a..af6085b1 100644 --- a/README.md +++ b/README.md @@ -577,6 +577,11 @@ and other multi-core embedded devices). [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 +[![โ˜…][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store. + +[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store +[medea-session-store-image]: https://img.shields.io/github/stars/scriptollc/medea-session-store.svg?label=%E2%98%85 + [![โ˜…][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. [mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store From 4d432ad482814f77ba2a7889c7411183a3ee8f97 Mon Sep 17 00:00:00 2001 From: Ali Lokhandwala Date: Sun, 24 Jul 2016 15:43:24 +0100 Subject: [PATCH 337/766] docs: add connect-db2 to list of session stores closes #333 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index af6085b1..04e590f0 100644 --- a/README.md +++ b/README.md @@ -504,6 +504,11 @@ and other multi-core embedded devices). [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase [connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 +[![โ˜…][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module. + +[connect-db2-url]: https://www.npmjs.com/package/connect-db2 +[connect-db2-image]: https://img.shields.io/github/stars/wallali/connect-db2.svg?label=%E2%98%85 + [![โ˜…][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store. [connect-dynamodb-url]: https://github.com/ca98am79/connect-dynamodb From c3c26ba1a7b92eb5eed127fcd299dc29087be869 Mon Sep 17 00:00:00 2001 From: Guille Paz Date: Tue, 19 Jul 2016 11:22:51 -0300 Subject: [PATCH 338/766] Fix the cookie sameSite option to actually alter the Set-Cookie fixes #331 --- HISTORY.md | 1 + session/cookie.js | 1 + 2 files changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 26a24595..72617c30 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix the cookie `sameSite` option to actually alter the `Set-Cookie` * deps: uid-safe@~2.1.2 - deps: base64-url@1.3.2 diff --git a/session/cookie.js b/session/cookie.js index a4dbd8a8..60ef22af 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -102,6 +102,7 @@ Cookie.prototype = { , httpOnly: this.httpOnly , domain: this.domain , path: this.path + , sameSite: this.sameSite } }, From f224a325ce2247d967aa42f462a0ac767408c931 Mon Sep 17 00:00:00 2001 From: Benjamin Vadant Date: Tue, 16 Aug 2016 11:22:41 +0200 Subject: [PATCH 339/766] docs: fix image link for medea-session-store closes #341 closes #344 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 04e590f0..92566e0f 100644 --- a/README.md +++ b/README.md @@ -585,7 +585,7 @@ and other multi-core embedded devices). [![โ˜…][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store. [medea-session-store-url]: https://www.npmjs.com/package/medea-session-store -[medea-session-store-image]: https://img.shields.io/github/stars/scriptollc/medea-session-store.svg?label=%E2%98%85 +[medea-session-store-image]: https://img.shields.io/github/stars/BenjaminVadant/medea-session-store.svg?label=%E2%98%85 [![โ˜…][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. From cf3d960d021d988ac0b0c221d12beab12db053dc Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 22 Aug 2016 12:02:56 -0400 Subject: [PATCH 340/766] docs: add connect-loki to list of session stores closes #343 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 92566e0f..f052c876 100644 --- a/README.md +++ b/README.md @@ -514,6 +514,11 @@ and other multi-core embedded devices). [connect-dynamodb-url]: https://github.com/ca98am79/connect-dynamodb [connect-dynamodb-image]: https://img.shields.io/github/stars/ca98am79/connect-dynamodb.svg?label=%E2%98%85 +[![โ˜…][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store. + +[connect-loki-url]: https://www.npmjs.com/package/connect-loki +[connect-loki-image]: https://img.shields.io/github/stars/Requarks/connect-loki.svg?label=%E2%98%85 + [![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql From 4c476fa7f01aac55ae8bc68d411ebfad22379eea Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 12:29:15 -0400 Subject: [PATCH 341/766] Fix not always resetting session max age before session save fixes #340 --- HISTORY.md | 1 + index.js | 14 ++++++++++++-- test/session.js | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 72617c30..405e0a13 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix not always resetting session max age before session save * Fix the cookie `sameSite` option to actually alter the `Set-Cookie` * deps: uid-safe@~2.1.2 - deps: base64-url@1.3.2 diff --git a/index.js b/index.js index 5794118f..2241d974 100644 --- a/index.js +++ b/index.js @@ -207,6 +207,7 @@ function session(options) { var originalHash; var originalId; var savedHash; + var touched = false // expose store req.sessionStore = store; @@ -231,8 +232,11 @@ function session(options) { return; } - // touch session - req.session.touch(); + if (!touched) { + // touch session + req.session.touch() + touched = true + } // set cookie setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data); @@ -316,6 +320,12 @@ function session(options) { return _end.call(res, chunk, encoding); } + if (!touched) { + // touch session + req.session.touch() + touched = true + } + if (shouldSave(req)) { req.session.save(function onsave(err) { if (err) { diff --git a/test/session.js b/test/session.js index f9419d48..f553d1c5 100644 --- a/test/session.js +++ b/test/session.js @@ -396,6 +396,42 @@ describe('session()', function(){ done() }) }) + + it('should have saved session with updated cookie expiration', function (done) { + var store = new session.MemoryStore() + var server = createServer({ cookie: { maxAge: min }, store: store }, function (req, res) { + req.session.user = 'bob' + res.end(req.session.id) + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, function (err, res) { + if (err) return done(err) + var id = res.text + store.get(id, function (err, sess) { + if (err) return done(err) + assert.ok(sess, 'session saved to store') + var exp = new Date(sess.cookie.expires) + assert.equal(exp.toUTCString(), expires(res)) + setTimeout(function () { + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, function (err, res) { + if (err) return done(err) + store.get(id, function (err, sess) { + assert.equal(res.text, id) + assert.ok(sess, 'session still in store') + assert.notEqual(new Date(sess.cookie.expires).toUTCString(), exp.toUTCString(), 'session cookie expiration updated') + done() + }) + }) + }, (1000 - (Date.now() % 1000) + 200)) + }) + }) + }) }) describe('when sid not in store', function () { From ec8cde2866ae00aed3796ce4ebcf61527298cdb2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 12:36:29 -0400 Subject: [PATCH 342/766] build: after@0.8.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f2af341e..743db1a9 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "utils-merge": "1.0.0" }, "devDependencies": { - "after": "0.8.1", + "after": "0.8.2", "cookie-parser": "1.4.3", "express": "4.14.0", "istanbul": "0.4.4", From e8ae80d9b760c0af579dfe48d190446dec00b4f5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 12:36:59 -0400 Subject: [PATCH 343/766] build: istanbul@0.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 743db1a9..5ecc5f8c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "after": "0.8.2", "cookie-parser": "1.4.3", "express": "4.14.0", - "istanbul": "0.4.4", + "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" }, From d78676fc22da3e5fc08f026f98b72b648e63ebb5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 12:37:43 -0400 Subject: [PATCH 344/766] build: Node.js@4.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fc45a8be..9d13ceb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.4" + - "4.5" - "5.11" - "6.2" sudo: false From 4c19dfeb41323fe26083bdf802177e1b7503e78f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 12:38:09 -0400 Subject: [PATCH 345/766] build: Node.js@5.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9d13ceb0..a27e3a0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.5" - - "5.11" + - "5.12" - "6.2" sudo: false cache: From 8fca4176d7ce4d552425e433f5b8292cffc0f709 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 12:38:19 -0400 Subject: [PATCH 346/766] build: Node.js@6.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a27e3a0d..ce9f6754 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.5" - "5.12" - - "6.2" + - "6.4" sudo: false cache: directories: From 19b8f725d924035574d71e22bcb0a7d06c09ae80 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Aug 2016 13:11:35 -0400 Subject: [PATCH 347/766] 1.14.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 405e0a13..972d1c96 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.14.1 / 2016-08-24 +=================== * Fix not always resetting session max age before session save * Fix the cookie `sameSite` option to actually alter the `Set-Cookie` diff --git a/package.json b/package.json index 5ecc5f8c..47dfa5e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.14.0", + "version": "1.14.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From b8f29abb2fe2853c880af868726a3512b8404788 Mon Sep 17 00:00:00 2001 From: Gabriel D Date: Tue, 30 Aug 2016 01:06:38 -0400 Subject: [PATCH 348/766] tests: handle errors within tests closes #352 --- test/session.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/session.js b/test/session.js index f553d1c5..9eb3d38e 100644 --- a/test/session.js +++ b/test/session.js @@ -422,6 +422,7 @@ describe('session()', function(){ .expect(200, function (err, res) { if (err) return done(err) store.get(id, function (err, sess) { + if (err) return done(err) assert.equal(res.text, id) assert.ok(sess, 'session still in store') assert.notEqual(new Date(sess.cookie.expires).toUTCString(), exp.toUTCString(), 'session cookie expiration updated') From e99d8a6d3ea256853bb9f4e321842ad9e339d16e Mon Sep 17 00:00:00 2001 From: Gajus Kuizinas Date: Wed, 31 Aug 2016 16:23:30 +0100 Subject: [PATCH 349/766] docs: add express-session-level to list of session stores closes #353 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f052c876..dbb263ca 100644 --- a/README.md +++ b/README.md @@ -582,6 +582,11 @@ and other multi-core embedded devices). [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session [express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 +[![โ˜…][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store. + +[express-session-level-url]: https://www.npmjs.com/package/express-session-level +[express-session-level-image]: https://img.shields.io/github/stars/tgohn/express-session-level.svg?label=%E2%98%85 + [![โ˜…][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store From 81e6d097e840f5d2473eca65fc0926813ec8b2cf Mon Sep 17 00:00:00 2001 From: "Daniel W. Hieber" Date: Sun, 28 Aug 2016 02:03:52 -0500 Subject: [PATCH 350/766] docs: add documentdb-session to list of session stores closes #348 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index dbb263ca..c47171d1 100644 --- a/README.md +++ b/README.md @@ -577,6 +577,11 @@ and other multi-core embedded devices). [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 [connect-sqlite3-image]: https://img.shields.io/github/stars/rawberg/connect-sqlite3.svg?label=%E2%98%85 +[![โ˜…][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service. + +[documentdb-session-url]: https://www.npmjs.com/package/documentdb-session +[documentdb-session-image]: https://img.shields.io/github/stars/dwhieb/documentdb-session.svg?label=%E2%98%85 + [![โ˜…][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session From 8e57b21bef0d53010c4d37f4beee3f0341f3eaa6 Mon Sep 17 00:00:00 2001 From: Matt Savino Date: Wed, 24 Aug 2016 10:35:06 -0700 Subject: [PATCH 351/766] docs: add hazelcast-store to list of session stores closes #346 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c47171d1..d826a8b9 100644 --- a/README.md +++ b/README.md @@ -592,6 +592,11 @@ and other multi-core embedded devices). [express-session-level-url]: https://www.npmjs.com/package/express-session-level [express-session-level-image]: https://img.shields.io/github/stars/tgohn/express-session-level.svg?label=%E2%98%85 +[![โ˜…][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client). + +[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store +[hazelcast-store-image]: https://img.shields.io/github/stars/jackspaniel/hazelcast-store.svg?label=%E2%98%85 + [![โ˜…][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store From 708a70b28729ee3ce5f530f31540b560f2efc713 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 2 Oct 2016 22:09:46 -0400 Subject: [PATCH 352/766] build: Node.js@4.6 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ce9f6754..fa54996f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.5" + - "4.6" - "5.12" - "6.4" sudo: false From 7ede22400b5cb67dc24bcdaedb1415c624c68747 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 2 Oct 2016 22:12:33 -0400 Subject: [PATCH 353/766] build: Node.js@6.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fa54996f..06387449 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.6" - "5.12" - - "6.4" + - "6.7" sudo: false cache: directories: From 12b050286659da76dfe025dd2d2fd05a59e6fa9b Mon Sep 17 00:00:00 2001 From: Alex Movsisyan Date: Tue, 23 Aug 2016 11:21:37 +0400 Subject: [PATCH 354/766] docs: add express-sessions to list of session stores closes #345 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d826a8b9..525efe53 100644 --- a/README.md +++ b/README.md @@ -572,6 +572,10 @@ and other multi-core embedded devices). [express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session [express-mysql-session-image]: https://img.shields.io/github/stars/chill117/express-mysql-session.svg?label=%E2%98%85 +[![โ˜…][express-sessions-image] express-sessions][express-sessions-url]: A session store supporting both MongoDB and Redis. +[express-sessions-url]: https://www.npmjs.com/package/express-sessions +[express-sessions-image]: https://img.shields.io/github/stars/konteck/express-sessions.svg?label=%E2%98%85 + [![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 From fba7be43c569834ce5b111d0c9a0580e893dd624 Mon Sep 17 00:00:00 2001 From: Olli Kankare Date: Wed, 7 Sep 2016 12:23:32 +0300 Subject: [PATCH 355/766] docs: add express-etcd to the list of session stores closes #358 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 525efe53..a71e093c 100644 --- a/README.md +++ b/README.md @@ -596,6 +596,11 @@ and other multi-core embedded devices). [express-session-level-url]: https://www.npmjs.com/package/express-session-level [express-session-level-image]: https://img.shields.io/github/stars/tgohn/express-session-level.svg?label=%E2%98%85 +[![โ˜…][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. + +[express-etcd-url]: https://www.npmjs.com/package/express-etcd +[express-etcd-image]: https://img.shields.io/github/stars/gildean/express-etcd.svg?label=%E2%98%85 + [![โ˜…][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client). [hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store From 30a4d886229b16791a944d97750a6cba0ea476d9 Mon Sep 17 00:00:00 2001 From: Adrian Tanasa Date: Thu, 6 Oct 2016 10:26:32 +0100 Subject: [PATCH 356/766] docs: add connect-datacache to the list of session stores closes #368 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index a71e093c..91ac2c0d 100644 --- a/README.md +++ b/README.md @@ -504,6 +504,11 @@ and other multi-core embedded devices). [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase [connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 +[![โ˜…][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store. + +[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache +[connect-datacache-image]: https://img.shields.io/github/stars/adriantanasa/connect-datacache.svg?label=%E2%98%85 + [![โ˜…][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module. [connect-db2-url]: https://www.npmjs.com/package/connect-db2 From ddffd58e9eaffb6ac59ff29e7f864012691bfd1e Mon Sep 17 00:00:00 2001 From: Bruce Holt Date: Wed, 12 Oct 2016 08:35:16 -0600 Subject: [PATCH 357/766] docs: add connect-ml to the list of session stores closes #370 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 91ac2c0d..073c43ab 100644 --- a/README.md +++ b/README.md @@ -524,6 +524,11 @@ and other multi-core embedded devices). [connect-loki-url]: https://www.npmjs.com/package/connect-loki [connect-loki-image]: https://img.shields.io/github/stars/Requarks/connect-loki.svg?label=%E2%98%85 +[![โ˜…][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store. + +[connect-ml-url]: https://www.npmjs.com/package/connect-ml +[connect-ml-image]: https://img.shields.io/github/stars/bluetorch/connect-ml.svg?label=%E2%98%85 + [![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql From b7c6974be37a8f97811c3158916a3d2aecfaa4b1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Oct 2016 15:15:34 -0400 Subject: [PATCH 358/766] docs: flatten cookie options into option header level closes #356 closes #378 --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 073c43ab..a8938b5d 100644 --- a/README.md +++ b/README.md @@ -48,13 +48,13 @@ Settings object for the session ID cookie. The default value is The following are options that can be set in this object. -###### domain +##### cookie.domain Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain is set, and most clients will consider the cookie to apply to only the current domain. -###### expires +##### cookie.expires Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute. By default, no expiration is set, and most clients will consider this a @@ -67,7 +67,7 @@ defined in the object is what is used. **Note** The `expires` option should not be set directly; instead only use the `maxAge` option. -###### httpOnly +##### cookie.httpOnly Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy, the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` @@ -76,7 +76,7 @@ attribute is set. **Note** be careful when setting this to `true`, as compliant clients will not allow client-side JavaScript to see the cookie in `document.cookie`. -###### maxAge +##### cookie.maxAge Specifies the `number` (in milliseconds) to use when calculating the `Expires` `Set-Cookie` attribute. This is done by taking the current server time and adding @@ -86,12 +86,12 @@ no maximum age is set. **Note** If both `expires` and `maxAge` are set in the options, then the last one defined in the object is what is used. -###### path +##### cookie.path Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. -###### sameSite +##### cookie.sameSite Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute. @@ -106,7 +106,7 @@ https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1.1 **Note** This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it. -###### secure +##### cookie.secure Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy, the `Secure` attribute is set, otherwise it is not. By default, the `Secure` From 2667028d39b3655a45eb1f9579d7f66f26a6937f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Oct 2016 21:21:28 -0400 Subject: [PATCH 359/766] docs: add callback to method signatures that take one closes #379 --- README.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a8938b5d..2062421b 100644 --- a/README.md +++ b/README.md @@ -302,10 +302,11 @@ app.get('/', function(req, res, next) { }) ``` -#### Session.regenerate() +#### Session.regenerate(callback) To regenerate the session simply invoke the method. Once complete, -a new SID and `Session` instance will be initialized at `req.session`. +a new SID and `Session` instance will be initialized at `req.session` +and the `callback` will be invoked. ```js req.session.regenerate(function(err) { @@ -313,9 +314,10 @@ req.session.regenerate(function(err) { }) ``` -#### Session.destroy() +#### Session.destroy(callback) -Destroys the session, removing `req.session`; will be re-generated next request. +Destroys the session and will unset the `req.session` property. +Once complete, the `callback` will be invoked. ```js req.session.destroy(function(err) { @@ -323,9 +325,10 @@ req.session.destroy(function(err) { }) ``` -#### Session.reload() +#### Session.reload(callback) -Reloads the session data. +Reloads the session data from the store and re-populates the +`req.session` object. Once complete, the `callback` will be invoked. ```js req.session.reload(function(err) { @@ -333,7 +336,7 @@ req.session.reload(function(err) { }) ``` -#### Session.save() +#### Session.save(callback) Save the session back to the store, replacing the contents on the store with the contents in memory (though a store may do something else--consult the store's From 1c6ea4457c1dfd9addf24ba86c2a674dc4471571 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Oct 2016 21:22:53 -0400 Subject: [PATCH 360/766] build: Node.js@6.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 06387449..fa13448d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.6" - "5.12" - - "6.7" + - "6.9" sudo: false cache: directories: From 69f07ec527f66feeccf42b55a00fa974c9360d1a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 28 Oct 2016 16:40:48 -0400 Subject: [PATCH 361/766] deps: crc@3.4.1 fixes #380 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 972d1c96..549222ab 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: crc@3.4.1 + - Fix deprecation warning in Node.js 7.x + 1.14.1 / 2016-08-24 =================== diff --git a/package.json b/package.json index 47dfa5e8..b2578bd1 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.3.1", "cookie-signature": "1.0.6", - "crc": "3.4.0", + "crc": "3.4.1", "debug": "~2.2.0", "depd": "~1.1.0", "on-headers": "~1.0.1", From dcc6241d1320b9abcfd4742a2af2dced54e4ce15 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 31 Oct 2016 00:58:54 -0400 Subject: [PATCH 362/766] deps: uid-safe@~2.1.3 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 549222ab..aac80fbd 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,8 @@ unreleased * deps: crc@3.4.1 - Fix deprecation warning in Node.js 7.x + * deps: uid-safe@~2.1.3 + - deps: base64-url@1.3.3 1.14.1 / 2016-08-24 =================== diff --git a/package.json b/package.json index b2578bd1..7bcab08c 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", - "uid-safe": "~2.1.2", + "uid-safe": "~2.1.3", "utils-merge": "1.0.0" }, "devDependencies": { From 087a0a40d689c8b4885d20f60addbb71c6881f65 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 31 Oct 2016 00:59:40 -0400 Subject: [PATCH 363/766] build: support Node.js 7.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fa13448d..237d447a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ node_js: - "4.6" - "5.12" - "6.9" + - "7.0" sudo: false cache: directories: From 1a61416bdaae56fc4a2a3af708f992d4dd2885c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 31 Oct 2016 01:07:18 -0400 Subject: [PATCH 364/766] 1.14.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index aac80fbd..fd15864d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.14.2 / 2016-10-30 +=================== * deps: crc@3.4.1 - Fix deprecation warning in Node.js 7.x diff --git a/package.json b/package.json index 7bcab08c..4adeb4f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.14.1", + "version": "1.14.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From ef30faf8040068c25bef3d9ae13ccbe354d1e812 Mon Sep 17 00:00:00 2001 From: Alice Klipper Date: Tue, 1 Nov 2016 23:31:40 +0300 Subject: [PATCH 365/766] docs: add fortune-session to the list of session stores closes #386 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 2062421b..cc3bc8fa 100644 --- a/README.md +++ b/README.md @@ -614,6 +614,12 @@ and other multi-core embedded devices). [express-etcd-url]: https://www.npmjs.com/package/express-etcd [express-etcd-image]: https://img.shields.io/github/stars/gildean/express-etcd.svg?label=%E2%98%85 +[![โ˜…][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune) +based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB). + +[fortune-session-url]: https://www.npmjs.com/package/fortune-session +[fortune-session-image]: https://img.shields.io/github/stars/aliceklipper/fortune-session.svg?label=%E2%98%85 + [![โ˜…][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client). [hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store From ce2de6b30ff061cbb84fbc0634342f19a8128342 Mon Sep 17 00:00:00 2001 From: Peter Dotchev Date: Sun, 30 Oct 2016 17:29:45 +0200 Subject: [PATCH 366/766] Fix resaving already-saved reloaded session at end of request fixes #383 closes #384 --- HISTORY.md | 5 +++++ index.js | 16 ++++++++++++++++ test/session.js | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index fd15864d..9d4761a3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix resaving already-saved reloaded session at end of request + 1.14.2 / 2016-10-30 =================== diff --git a/index.js b/index.js index 2241d974..90aa52c7 100644 --- a/index.js +++ b/index.js @@ -364,14 +364,30 @@ function session(options) { // wrap session methods function wrapmethods(sess) { + var _reload = sess.reload var _save = sess.save; + function reload(callback) { + debug('reloading %s', this.id) + _reload.call(this, function () { + wrapmethods(req.session) + callback.apply(this, arguments) + }) + } + function save() { debug('saving %s', this.id); savedHash = hash(this); _save.apply(this, arguments); } + Object.defineProperty(sess, 'reload', { + configurable: true, + enumerable: false, + value: reload, + writable: true + }) + Object.defineProperty(sess, 'save', { configurable: true, enumerable: false, diff --git a/test/session.js b/test/session.js index 9eb3d38e..9cfb6ef9 100644 --- a/test/session.js +++ b/test/session.js @@ -1714,6 +1714,42 @@ describe('session()', function(){ }) }) }) + + it('should prevent end-of-request save on reloaded session', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + req.session.reload(function () { + req.session.save(function (err) { + if (err) return res.end(err.message) + res.end('saved') + }) + }) + }) + + var _set = store.set + store.set = function set(sid, sess, callback) { + count++ + _set.call(store, sid, sess, callback) + } + + request(server) + .get('/') + .expect(200, 'saved', function (err, res) { + if (err) return done(err) + assert.equal(count, 1) + count = 0 + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'saved', function (err) { + if (err) return done(err) + assert.equal(count, 1) + done() + }) + }) + }) }) describe('.touch()', function () { From bab6e228187958b40fa91e1e5e23171121866c16 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Nov 2016 22:09:42 -0500 Subject: [PATCH 367/766] deps: debug@2.3.2 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9d4761a3..b99a2fe0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,9 @@ unreleased ========== * Fix resaving already-saved reloaded session at end of request + * deps: debug@2.3.2 + - Fix error when running under React Native + - deps: ms@0.7.2 1.14.2 / 2016-10-30 =================== diff --git a/package.json b/package.json index 4adeb4f4..5b0d8c9e 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.1", - "debug": "~2.2.0", + "debug": "2.3.2", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From a8f367c1e397b0b0d0079d452522cc0662c8963c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Nov 2016 22:10:08 -0500 Subject: [PATCH 368/766] build: Node.js@7.1 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 237d447a..6525236c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.6" - "5.12" - "6.9" - - "7.0" + - "7.1" sudo: false cache: directories: From 588d09900c0ee4796ba78f3d51c690de6b77dd50 Mon Sep 17 00:00:00 2001 From: OlegTsyba Date: Sat, 8 Oct 2016 21:16:10 +0300 Subject: [PATCH 369/766] perf: remove unreachable branch in set-cookie method closes #369 --- HISTORY.md | 1 + index.js | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b99a2fe0..f1a72f57 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,7 @@ unreleased * deps: debug@2.3.2 - Fix error when running under React Native - deps: ms@0.7.2 + * perf: remove unreachable branch in set-cookie method 1.14.2 / 2016-10-30 =================== diff --git a/index.js b/index.js index 90aa52c7..01752a12 100644 --- a/index.js +++ b/index.js @@ -635,9 +635,7 @@ function setcookie(res, name, val, secret, options) { debug('set-cookie %s', data); var prev = res.getHeader('set-cookie') || []; - var header = Array.isArray(prev) ? prev.concat(data) - : Array.isArray(data) ? [prev].concat(data) - : [prev, data]; + var header = Array.isArray(prev) ? prev.concat(data) : [prev, data]; res.setHeader('set-cookie', header) } From f21f95668986b8a99957598b1e3bbb54b720fdbf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Nov 2016 22:23:48 -0500 Subject: [PATCH 370/766] docs: add preamble to install section --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index cc3bc8fa..261600f7 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ ## Installation +This is a [Node.js](https://nodejs.org/en/) module available through the +[npm registry](https://www.npmjs.com/). Installation is done using the +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): + ```bash $ npm install express-session ``` From 583ee482cf8a23e9e22c475902f4de8dbf49d0fb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Nov 2016 23:43:36 -0500 Subject: [PATCH 371/766] deps: debug@2.3.3 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f1a72f57..b09a6ec8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,7 @@ unreleased ========== * Fix resaving already-saved reloaded session at end of request - * deps: debug@2.3.2 + * deps: debug@2.3.3 - Fix error when running under React Native - deps: ms@0.7.2 * perf: remove unreachable branch in set-cookie method diff --git a/package.json b/package.json index 5b0d8c9e..3a088c52 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.1", - "debug": "2.3.2", + "debug": "2.3.3", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 534ae1e6f536960e8f4c1cb10b66256a1b1c500a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 7 Dec 2016 23:54:32 -0500 Subject: [PATCH 372/766] build: Node.js@4.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6525236c..0e5953d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.6" + - "4.7" - "5.12" - "6.9" - "7.1" From 899c27fca1e8b5cc203810e7a55b61b9a0569453 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 7 Dec 2016 23:56:33 -0500 Subject: [PATCH 373/766] build: Node.js@7.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0e5953d3..c285293f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.7" - "5.12" - "6.9" - - "7.1" + - "7.2" sudo: false cache: directories: From 0b4c0eddb22232e881303f6c05c52fc188a32cf7 Mon Sep 17 00:00:00 2001 From: Cong Do Date: Mon, 28 Nov 2016 11:09:59 +0700 Subject: [PATCH 374/766] deps: crc@3.4.3 closes #390 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b09a6ec8..183026fa 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,8 @@ unreleased ========== * Fix resaving already-saved reloaded session at end of request + * deps: crc@3.4.3 + - perf: use `Buffer.from` when available * deps: debug@2.3.3 - Fix error when running under React Native - deps: ms@0.7.2 diff --git a/package.json b/package.json index 3a088c52..b71e0d63 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.3.1", "cookie-signature": "1.0.6", - "crc": "3.4.1", + "crc": "3.4.3", "debug": "2.3.3", "depd": "~1.1.0", "on-headers": "~1.0.1", From e01ce259d2ae50c2aa8dc294ee1d1f1ac7e47e10 Mon Sep 17 00:00:00 2001 From: Gabriel D Date: Sat, 31 Dec 2016 23:17:18 -0500 Subject: [PATCH 375/766] build: Node.js@7.3 closes #408 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c285293f..ecf24c60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.7" - "5.12" - "6.9" - - "7.2" + - "7.3" sudo: false cache: directories: From c935f7636696d85cbc530890574ca899f306590f Mon Sep 17 00:00:00 2001 From: Agostino Marzotta Date: Thu, 29 Dec 2016 16:16:18 +0100 Subject: [PATCH 376/766] docs: add express-oracle-session to the list of session stores closes #405 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 261600f7..70f8f2be 100644 --- a/README.md +++ b/README.md @@ -589,6 +589,12 @@ and other multi-core embedded devices). [express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session [express-mysql-session-image]: https://img.shields.io/github/stars/chill117/express-mysql-session.svg?label=%E2%98%85 +[![โ˜…][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native +[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module. + +[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session +[express-oracle-session-image]: https://img.shields.io/github/stars/slumber86/express-oracle-session.svg?label=%E2%98%85 + [![โ˜…][express-sessions-image] express-sessions][express-sessions-url]: A session store supporting both MongoDB and Redis. [express-sessions-url]: https://www.npmjs.com/package/express-sessions [express-sessions-image]: https://img.shields.io/github/stars/konteck/express-sessions.svg?label=%E2%98%85 From aa6336f4a71dcde9a65eac6d718402081ae3460f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 31 Dec 2016 23:34:09 -0500 Subject: [PATCH 377/766] deps: crc@3.4.4 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 183026fa..7ce29147 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,7 @@ unreleased ========== * Fix resaving already-saved reloaded session at end of request - * deps: crc@3.4.3 + * deps: crc@3.4.4 - perf: use `Buffer.from` when available * deps: debug@2.3.3 - Fix error when running under React Native diff --git a/package.json b/package.json index b71e0d63..eac99644 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.3.1", "cookie-signature": "1.0.6", - "crc": "3.4.3", + "crc": "3.4.4", "debug": "2.3.3", "depd": "~1.1.0", "on-headers": "~1.0.1", From 61290c79fe076cfbb5b7f209b19df84d7867c782 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 31 Dec 2016 23:40:12 -0500 Subject: [PATCH 378/766] deps: debug@2.6.0 --- HISTORY.md | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 7ce29147..3d4a6129 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,7 +4,10 @@ unreleased * Fix resaving already-saved reloaded session at end of request * deps: crc@3.4.4 - perf: use `Buffer.from` when available - * deps: debug@2.3.3 + * deps: debug@2.6.0 + - Allow colors in workers + - Deprecated `DEBUG_FD` environment variable + - Use same color for same namespace - Fix error when running under React Native - deps: ms@0.7.2 * perf: remove unreachable branch in set-cookie method diff --git a/package.json b/package.json index eac99644..276327f6 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.3.3", + "debug": "2.6.0", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 7073cafb36161257b57533cfca7a932fe0669137 Mon Sep 17 00:00:00 2001 From: Gustavo Henke Date: Fri, 16 Dec 2016 09:20:24 -0200 Subject: [PATCH 379/766] Fix detecting modified session when session contains "cookie" property fixes #398 closes #400 --- HISTORY.md | 1 + index.js | 9 ++++++--- test/session.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 3d4a6129..fe154656 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix detecting modified session when session contains "cookie" property * Fix resaving already-saved reloaded session at end of request * deps: crc@3.4.4 - perf: use `Buffer.from` when available diff --git a/index.js b/index.js index 01752a12..68ccf533 100644 --- a/index.js +++ b/index.js @@ -578,10 +578,13 @@ function getcookie(req, name, secrets) { function hash(sess) { return crc(JSON.stringify(sess, function (key, val) { - if (key !== 'cookie') { - return val; + // ignore sess.cookie property + if (this === sess && key === 'cookie') { + return } - })); + + return val + })) } /** diff --git a/test/session.js b/test/session.js index 9cfb6ef9..c00a07bf 100644 --- a/test/session.js +++ b/test/session.js @@ -1044,6 +1044,36 @@ describe('session()', function(){ }); }); + it('should detect a "cookie" property as modified', function (done) { + var count = 0 + var app = express() + app.use(session({ resave: 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.user = req.session.user || {} + req.session.user.name = 'bob' + req.session.user.cookie = 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(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/') + .set('Cookie', cookie(res)) + .expect('x-count', '2') + .expect(200, done) + }) + }) + it('should pass session touch error', function (done) { var cb = after(2, done) var store = new session.MemoryStore() From 17aa1de223862d10a8dec38aaa73dece5d47dbe8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Jan 2017 22:25:12 -0500 Subject: [PATCH 380/766] build: Node.js@7.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ecf24c60..d6aabe0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.7" - "5.12" - "6.9" - - "7.3" + - "7.4" sudo: false cache: directories: From 1896dd12e025076bd7ec929ab15f8e79b00fec5c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 00:11:44 -0500 Subject: [PATCH 381/766] tests: fix tests checking store set not to rely on header update --- test/session.js | 294 ++++++++++++++++++------------------------------ 1 file changed, 108 insertions(+), 186 deletions(-) diff --git a/test/session.js b/test/session.js index c00a07bf..fc9120f8 100644 --- a/test/session.js +++ b/test/session.js @@ -865,66 +865,37 @@ describe('session()', function(){ }); 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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, rolling: true, saveUninitialized: false }) - request(app) + request(server) .get('/') - .expect('x-count', '0') + .expect(shouldNotSetSessionInStore(store)) .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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, rolling: true, saveUninitialized: true }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, rolling: true, saveUninitialized: false }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); @@ -932,144 +903,105 @@ describe('session()', function(){ describe('resave option', function(){ it('should default to true', function(done){ - var count = 0; - var app = express(); - app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); - app.use(function(req, res, next){ - var save = req.session.save; - res.setHeader('x-count', count); - req.session.user = 'bob'; - req.session.save = function(fn){ - res.setHeader('x-count', ++count); - return save.call(this, fn); - }; - res.end(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(200, function(err, res){ if (err) return done(err); - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) - .expect('x-count', '2') + .expect(shouldSetSessionInStore(store)) .expect(200, done); }); }); it('should force save on unmodified session', function(done){ - var count = 0; - var app = express(); - app.use(session({ resave: 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.user = 'bob'; - req.session.save = function(fn){ - res.setHeader('x-count', ++count); - return save.call(this, fn); - }; - res.end(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: true }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(200, function(err, res){ if (err) return done(err); - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) - .expect('x-count', '2') + .expect(shouldSetSessionInStore(store)) .expect(200, done); }); }); it('should prevent save on unmodified session', function(done){ - var count = 0; - var app = express(); - app.use(session({ resave: 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.user = 'bob'; - req.session.save = function(fn){ - res.setHeader('x-count', ++count); - return save.call(this, fn); - }; - res.end(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(200, function(err, res){ if (err) return done(err); - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) - .expect('x-count', '1') + .expect(shouldNotSetSessionInStore(store)) .expect(200, done); }); }); it('should still save modified session', function(done){ - var count = 0; - var app = express(); - app.use(session({ resave: 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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + res.end() + }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(200, function(err, res){ if (err) return done(err); - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) - .expect('x-count', '2') + .expect(shouldSetSessionInStore(store)) .expect(200, done); }); }); it('should detect a "cookie" property as modified', function (done) { - var count = 0 - var app = express() - app.use(session({ resave: false, secret: 'keyboard cat', cookie: { maxAge: min }})) - app.use(function (req, res, next) { - var save = req.session.save - res.setHeader('x-count', count) + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { req.session.user = req.session.user || {} req.session.user.name = 'bob' - req.session.user.cookie = count - req.session.save = function (fn) { - res.setHeader('x-count', ++count) - return save.call(this, fn) - } + req.session.user.cookie = req.session.user.cookie || 0 + req.session.user.cookie++ res.end() }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(200, function (err, res) { if (err) return done(err) - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) - .expect('x-count', '2') + .expect(shouldSetSessionInStore(store)) .expect(200, done) }) }) @@ -1106,87 +1038,49 @@ describe('session()', function(){ describe('saveUninitialized option', function(){ it('should default to true', function(done){ - var count = 0; - var app = express(); - app.use(session({ 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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); it('should force save of uninitialized session', function(done){ - var count = 0; - var app = express(); - app.use(session({ 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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, saveUninitialized: true }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); it('should prevent save of uninitialized session', function(done){ - var count = 0; - var app = express(); - app.use(session({ 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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, saveUninitialized: false }) - request(app) + request(server) .get('/') - .expect('x-count', '0') + .expect(shouldNotSetSessionInStore(store)) .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }); it('should still save modified session', function(done){ - var count = 0; - var app = express(); - app.use(session({ 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(); - }); + var store = new session.MemoryStore() + var server = createServer({ store: store, saveUninitialized: false }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + res.end() + }) - request(app) + request(server) .get('/') - .expect('x-count', '1') + .expect(shouldSetSessionInStore(store)) .expect(shouldSetCookie('connect.sid')) .expect(200, done); }); @@ -2368,6 +2262,20 @@ function shouldNotHaveHeader(header) { } } +function shouldNotSetSessionInStore(store) { + var _set = store.set + var count = 0 + + store.set = function set () { + count++ + return _set.apply(this, arguments) + } + + return function () { + assert.ok(count === 0, 'should not set session in store') + } +} + function shouldNotSetSecureCookie(name) { return function (res) { var header = cookie(res) @@ -2403,6 +2311,20 @@ function shouldSetSecureCookie(name) { } } +function shouldSetSessionInStore(store) { + var _set = store.set + var count = 0 + + store.set = function set () { + count++ + return _set.apply(this, arguments) + } + + return function () { + assert.ok(count === 1, 'should set session in store') + } +} + function sid(res) { var match = /^[^=]+=s%3A([^;\.]+)[\.;]/.exec(cookie(res)) var val = match ? match[1] : undefined From 75b29129840e9b342b954fc5a39cf8a80abdc39c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 00:38:11 -0500 Subject: [PATCH 382/766] tests: change more tests to use createServer() helper --- test/session.js | 293 ++++++++++++++++++++---------------------------- 1 file changed, 119 insertions(+), 174 deletions(-) diff --git a/test/session.js b/test/session.js index fc9120f8..089066f9 100644 --- a/test/session.js +++ b/test/session.js @@ -168,16 +168,13 @@ describe('session()', function(){ }) it('should handle multiple res.end calls', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(function(req, res){ - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello, world!'); - res.end(); - }); - app.set('env', 'test'); + var server = createServer(null, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end('Hello, world!') + res.end() + }) - request(app) + request(server) .get('/') .expect('Content-Type', 'text/plain') .expect(200, 'Hello, world!', done); @@ -257,24 +254,22 @@ describe('session()', function(){ }) it('should update cookie expiration when slow write', function (done) { - var app = express(); - app.use(session({ rolling: true, secret: 'keyboard cat', cookie: { maxAge: min }})); - app.use(function (req, res, next) { - req.session.user = 'bob'; - res.write('hello, '); + var server = createServer({ rolling: true }, function (req, res) { + req.session.user = 'bob' + res.write('hello, ') setTimeout(function () { - res.end('world!'); - }, 200); - }); + res.end('world!') + }, 200) + }) - request(app) + request(server) .get('/') .expect(shouldSetCookie('connect.sid')) .expect(200, function (err, res) { if (err) return done(err); var originalExpires = expires(res); setTimeout(function () { - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) @@ -823,19 +818,17 @@ describe('session()', function(){ describe('rolling option', function(){ it('should default to false', function(done){ - var app = express(); - app.use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})); - app.use(function(req, res, next){ - req.session.user = 'bob'; - res.end(); - }); + var server = createServer(null, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(app) + request(server) .get('/') .expect(shouldSetCookie('connect.sid')) .expect(200, function(err, res){ if (err) return done(err); - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldNotHaveHeader('Set-Cookie')) @@ -844,19 +837,17 @@ describe('session()', function(){ }); it('should force cookie on unmodified session', function(done){ - var app = express(); - app.use(session({ rolling: true, secret: 'keyboard cat', cookie: { maxAge: min }})); - app.use(function(req, res, next){ - req.session.user = 'bob'; - res.end(); - }); + var server = createServer({ rolling: true }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(app) + request(server) .get('/') .expect(shouldSetCookie('connect.sid')) .expect(200, function(err, res){ if (err) return done(err); - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) @@ -1199,23 +1190,21 @@ describe('session()', function(){ it('should default to keep', function(done){ var store = new session.MemoryStore(); - var app = express() - .use(session({ store: store, secret: 'keyboard cat' })) - .use(function(req, res, next){ - req.session.count = req.session.count || 0; - req.session.count++; - if (req.session.count === 2) req.session = null; - res.end(); - }); + var server = createServer({ store: store }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + if (req.session.count === 2) req.session = null + res.end() + }) - request(app) + request(server) .get('/') .expect(200, function(err, res){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); assert.equal(len, 1) - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(200, function(err, res){ @@ -1232,23 +1221,21 @@ describe('session()', function(){ it('should allow destroy on req.session = null', function(done){ var store = new session.MemoryStore(); - var app = express() - .use(session({ store: store, unset: 'destroy', secret: 'keyboard cat' })) - .use(function(req, res, next){ - req.session.count = req.session.count || 0; - req.session.count++; - if (req.session.count === 2) req.session = null; - res.end(); - }); + var server = createServer({ store: store, unset: 'destroy' }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + if (req.session.count === 2) req.session = null + res.end() + }) - request(app) + request(server) .get('/') .expect(200, function(err, res){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); assert.equal(len, 1) - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(200, function(err, res){ @@ -1265,14 +1252,12 @@ describe('session()', function(){ it('should not set cookie if initial session destroyed', function(done){ var store = new session.MemoryStore(); - var app = express() - .use(session({ store: store, unset: 'destroy', secret: 'keyboard cat' })) - .use(function(req, res, next){ - req.session = null; - res.end(); - }); + var server = createServer({ store: store, unset: 'destroy' }, function (req, res) { + req.session = null + res.end() + }) - request(app) + request(server) .get('/') .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, function(err, res){ @@ -1369,22 +1354,19 @@ describe('session()', function(){ it('should only set-cookie when modified', function(done){ var modify = true; + var server = createServer(null, function (req, res) { + if (modify) { + req.session.count = req.session.count || 0 + req.session.count++ + } + res.end(req.session.count.toString()) + }) - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) - .use(function(req, res, next){ - if (modify) { - req.session.count = req.session.count || 0; - req.session.count++; - } - res.end(req.session.count.toString()); - }); - - request(app) + request(server) .get('/') .expect(200, '1', function (err, res) { if (err) return done(err) - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(200, '2', function (err, res) { @@ -1392,7 +1374,7 @@ describe('session()', function(){ var val = cookie(res); modify = false; - request(app) + request(server) .get('/') .set('Cookie', val) .expect(shouldNotHaveHeader('Set-Cookie')) @@ -1400,7 +1382,7 @@ describe('session()', function(){ if (err) return done(err) modify = true; - request(app) + request(server) .get('/') .set('Cookie', val) .expect(shouldSetCookie('connect.sid')) @@ -1411,19 +1393,17 @@ 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(',')); - }); + var server = createServer(null, function (req, res) { + 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) + request(server) .get('/') .expect(200, 'bar,cookie,foo', done); }); @@ -1714,15 +1694,13 @@ describe('session()', function(){ describe('.cookie', function(){ describe('.*', function(){ it('should serialize as parameters', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', proxy: true, cookie: { maxAge: min }})) - .use(function(req, res, next){ - req.session.cookie.httpOnly = false; - req.session.cookie.secure = true; - res.end(); - }); + var server = createServer({ proxy: true }, function (req, res) { + req.session.cookie.httpOnly = false + req.session.cookie.secure = true + res.end() + }) - request(app) + request(server) .get('/') .set('X-Forwarded-Proto', 'https') .expect(200, function(err, res){ @@ -1735,13 +1713,7 @@ describe('session()', function(){ }) it('should default to a browser-session length cookie', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) - .use(function(req, res, next){ - res.end(); - }); - - request(app) + request(createServer({ cookie: { path: '/admin' } })) .get('/admin') .expect(200, function(err, res){ if (err) return done(err); @@ -1752,18 +1724,14 @@ describe('session()', function(){ }) it('should Set-Cookie only once for browser-session cookies', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/admin' }})) - .use(function(req, res, next){ - res.end(); - }); + var server = createServer({ cookie: { path: '/admin' } }) - request(app) + request(server) .get('/admin/foo') .expect(shouldSetCookie('connect.sid')) .expect(200, function (err, res) { if (err) return done(err) - request(app) + request(server) .get('/admin') .set('Cookie', cookie(res)) .expect(shouldNotHaveHeader('Set-Cookie')) @@ -1772,14 +1740,12 @@ describe('session()', function(){ }) it('should override defaults', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/admin', httpOnly: false, secure: true, maxAge: 5000 }})) - .use(function(req, res, next){ - req.session.cookie.secure = false; - res.end(); - }); + var server = createServer({ cookie: { path: '/admin', httpOnly: false, secure: true, maxAge: 5000 } }, function (req, res) { + req.session.cookie.secure = false + res.end() + }) - request(app) + request(server) .get('/admin') .expect(200, function(err, res){ if (err) return done(err); @@ -1793,15 +1759,13 @@ describe('session()', function(){ }) it('should preserve cookies set before writeHead is called', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat' })) - .use(function(req, res, next){ - var cookie = new Cookie(); - res.setHeader('Set-Cookie', cookie.serialize('previous', 'cookieValue')); - res.end(); - }); + var server = createServer(null, function (req, res) { + var cookie = new Cookie() + res.setHeader('Set-Cookie', cookie.serialize('previous', 'cookieValue')) + res.end() + }) - request(app) + request(server) .get('/') .expect(shouldSetCookieToValue('previous', 'cookieValue')) .expect(200, done) @@ -1850,35 +1814,24 @@ describe('session()', function(){ describe('when the pathname does not match cookie.path', function(){ it('should not set-cookie', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) - .use(function(req, res, next){ - if (!req.session) { - return res.end(); - } - req.session.foo = Math.random(); - res.end(); - }); + var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { + if (req.session) req.session.foo = Math.random() + res.end() + }) - request(app) + request(server) .get('/') .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) it('should not set-cookie even for FQDN', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) - .use(function(req, res, next){ - if (!req.session) { - return res.end(); - } - - req.session.foo = Math.random(); - res.end(); - }); + var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { + if (req.session) req.session.foo = Math.random() + res.end() + }) - request(app) + request(server) .get('/') .set('host', 'http://foo/bar') .expect(shouldNotHaveHeader('Set-Cookie')) @@ -1888,28 +1841,24 @@ describe('session()', function(){ describe('when the pathname does match cookie.path', function(){ it('should set-cookie', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) - .use(function(req, res, next){ - req.session.foo = Math.random(); - res.end(); - }); + var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { + req.session.foo = Math.random() + res.end() + }) - request(app) + request(server) .get('/foo/bar/baz') .expect(shouldSetCookie('connect.sid')) .expect(200, done) }) it('should set-cookie even for FQDN', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat', cookie: { path: '/foo/bar' }})) - .use(function(req, res, next){ - req.session.foo = Math.random(); - res.end(); - }); + var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { + req.session.foo = Math.random() + res.end() + }) - request(app) + request(server) .get('/foo/bar/baz') .set('host', 'http://example.com') .expect(shouldSetCookie('connect.sid')) @@ -1983,14 +1932,12 @@ describe('session()', function(){ describe('.expires', function(){ describe('when given a Date', function(){ it('should set absolute', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat' })) - .use(function(req, res, next){ - req.session.cookie.expires = new Date(0); - res.end(); - }); + var server = createServer(null, function (req, res) { + req.session.cookie.expires = new Date(0) + res.end() + }) - request(app) + request(server) .get('/') .end(function(err, res){ if (err) return done(err) @@ -2002,14 +1949,12 @@ describe('session()', function(){ describe('when null', function(){ it('should be a browser-session cookie', function(done){ - var app = express() - .use(session({ secret: 'keyboard cat' })) - .use(function(req, res, next){ - req.session.cookie.expires = null; - res.end(); - }); + var server = createServer(null, function (req, res) { + req.session.cookie.expires = null + res.end() + }) - request(app) + request(server) .get('/') .expect(200, function(err, res){ if (err) return done(err); From 1c9a60606bd755d8194776f846ac1abae3467fd9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 01:06:35 -0500 Subject: [PATCH 383/766] tests: use createSession() helper for less verbosity --- test/session.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/session.js b/test/session.js index 089066f9..188d43d1 100644 --- a/test/session.js +++ b/test/session.js @@ -25,7 +25,7 @@ describe('session()', function(){ it('should do nothing if req.session exists', function(done){ var app = express() .use(function(req, res, next){ req.session = {}; next(); }) - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(createSession()) .use(end); request(app) @@ -43,7 +43,7 @@ describe('session()', function(){ it('should get secret from req.secret', function(done){ var app = express() .use(function(req, res, next){ req.secret = 'keyboard cat'; next(); }) - .use(session({ cookie: { maxAge: min }})) + .use(createSession()) .use(end); app.set('env', 'test'); @@ -658,7 +658,7 @@ describe('session()', function(){ it('should ignore req.secure from express', function(done){ var app = express() - .use(session({ secret: 'keyboard cat', proxy: false, cookie: { secure: true, maxAge: min }})) + .use(createSession({ proxy: false, cookie: { secure: true } })) .use(function(req, res) { res.json(req.secure); }); app.enable('trust proxy'); @@ -686,7 +686,7 @@ describe('session()', function(){ it('should use req.secure from express', function(done){ var app = express() - .use(session({ secret: 'keyboard cat', cookie: { secure: true, maxAge: min }})) + .use(createSession({ cookie: { secure: true } })) .use(function(req, res) { res.json(req.secure); }); app.enable('trust proxy'); @@ -735,7 +735,7 @@ describe('session()', function(){ before(function () { this.app = express() .use(function(req, res, next) { Object.defineProperty(req, 'secure', { value: JSON.parse(req.headers['x-secure']) }); next(); }) - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min, secure: 'auto' }})) + .use(createSession({ cookie: { secure: 'auto' } })) .use(function(req, res) { res.json(req.secure); }); }) @@ -1447,7 +1447,7 @@ describe('session()', function(){ describe('.destroy()', function(){ it('should destroy the previous session', function(done){ var app = express() - .use(session({ secret: 'keyboard cat' })) + .use(createSession()) .use(function(req, res, next){ req.session.destroy(function(err){ if (err) return next(err) @@ -1466,7 +1466,7 @@ describe('session()', function(){ describe('.regenerate()', function(){ it('should destroy/replace the previous session', function(done){ var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: min }})) + .use(createSession()) .use(function(req, res, next){ var id = req.session.id; req.session.regenerate(function(err){ @@ -1869,7 +1869,7 @@ describe('session()', function(){ describe('.maxAge', function(){ var val; var app = express() - .use(session({ secret: 'keyboard cat', cookie: { maxAge: 2000 }})) + .use(createSession({ cookie: { maxAge: 2000 } })) .use(function(req, res, next){ req.session.count = req.session.count || 0; req.session.count++; @@ -2058,7 +2058,7 @@ describe('session()', function(){ var app = express() .use(cookieParser()) .use(function(req, res, next){ req.headers.cookie = 'foo=bar'; next() }) - .use(session({ secret: 'keyboard cat' })) + .use(createSession()) .use(function(req, res, next){ req.session.count = req.session.count || 0 req.session.count++ @@ -2080,7 +2080,7 @@ describe('session()', function(){ var app = express() .use(cookieParser()) .use(function(req, res, next){ req.headers.cookie = 'foo=bar'; next() }) - .use(session({ secret: 'keyboard cat', key: 'sessid' })) + .use(createSession({ key: 'sessid' })) .use(function(req, res, next){ req.session.count = req.session.count || 0 req.session.count++ @@ -2102,7 +2102,7 @@ describe('session()', function(){ var app = express() .use(cookieParser()) .use(function(req, res, next){ req.headers.cookie = 'foo=bar'; next() }) - .use(session({ secret: 'keyboard cat', key: 'sessid' })) + .use(createSession({ key: 'sessid' })) .use(function(req, res, next){ req.session.count = req.session.count || 0 req.session.count++ @@ -2125,7 +2125,7 @@ describe('session()', function(){ var app = express() .use(cookieParser('keyboard cat')) .use(function(req, res, next){ delete req.headers.cookie; next() }) - .use(session()) + .use(createSession()) .use(function(req, res, next){ req.session.count = req.session.count || 0 req.session.count++ From 4f261d0d5f78887954773c226a920517df02e6bc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 17:14:07 -0500 Subject: [PATCH 384/766] tests: change more tests to use should set in store helpers --- test/session.js | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/test/session.js b/test/session.js index 188d43d1..610a427b 100644 --- a/test/session.js +++ b/test/session.js @@ -1586,7 +1586,6 @@ describe('session()', function(){ }) it('should prevent end-of-request save', function (done) { - var count = 0 var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { req.session.hit = true @@ -1596,31 +1595,20 @@ describe('session()', function(){ }) }) - var _set = store.set - store.set = function set(sid, sess, callback) { - count++ - _set.call(store, sid, sess, callback) - } - request(server) .get('/') + .expect(shouldSetSessionInStore(store)) .expect(200, 'saved', function (err, res) { if (err) return done(err) - assert.equal(count, 1) - count = 0 request(server) .get('/') .set('Cookie', cookie(res)) - .expect(200, 'saved', function (err) { - if (err) return done(err) - assert.equal(count, 1) - done() - }) + .expect(shouldSetSessionInStore(store)) + .expect(200, 'saved', done) }) }) it('should prevent end-of-request save on reloaded session', function (done) { - var count = 0 var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { req.session.hit = true @@ -1632,26 +1620,16 @@ describe('session()', function(){ }) }) - var _set = store.set - store.set = function set(sid, sess, callback) { - count++ - _set.call(store, sid, sess, callback) - } - request(server) .get('/') + .expect(shouldSetSessionInStore(store)) .expect(200, 'saved', function (err, res) { if (err) return done(err) - assert.equal(count, 1) - count = 0 request(server) .get('/') .set('Cookie', cookie(res)) - .expect(200, 'saved', function (err) { - if (err) return done(err) - assert.equal(count, 1) - done() - }) + .expect(shouldSetSessionInStore(store)) + .expect(200, 'saved', done) }) }) }) From fe324f2c2dead9d6d68a3ffeac96cef6a109bd5e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 17:54:16 -0500 Subject: [PATCH 385/766] tests: add simple set-cookie parser for accuracy --- test/session.js | 51 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/test/session.js b/test/session.js index 610a427b..49eeb5d5 100644 --- a/test/session.js +++ b/test/session.js @@ -2174,9 +2174,28 @@ function end(req, res) { res.end() } -function expires(res) { - var match = /Expires=([^;]+)/.exec(cookie(res)); - return match ? match[1] : undefined; +function expires (res) { + var header = cookie(res) + return header && parseSetCookie(header).expires +} + +function parseSetCookie (header) { + var match + var pairs = [] + var pattern = /\s*([^=;]+)(?:=([^;]*);?|;|$)/g + + while ((match = pattern.exec(header))) { + pairs.push({ name: match[1], value: match[2] }) + } + + var cookie = pairs.shift() + + for (var i = 0; i < pairs.length; i++) { + match = pairs[i] + cookie[match.name.toLowerCase()] = (match.value || true) + } + + return cookie } function shouldNotHaveHeader(header) { @@ -2202,35 +2221,39 @@ function shouldNotSetSessionInStore(store) { function shouldNotSetSecureCookie(name) { return function (res) { var header = cookie(res) + var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(header.split('=')[0], name, 'should set cookie ' + name) - assert.ok(header.toLowerCase().split(/; */).every(function (k) { return k !== 'secure'; }), 'should not set secure cookie') + assert.equal(data.name, name, 'should set cookie ' + name) + assert.ok(!data.secure, 'should not set secure cookie') } } -function shouldSetCookie(name) { +function shouldSetCookie (name) { return function (res) { var header = cookie(res) + var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(header.split('=')[0], name, 'should set cookie ' + name) + assert.equal(data.name, name, 'should set cookie ' + name) } } -function shouldSetCookieToValue(name, val) { +function shouldSetCookieToValue (name, val) { return function (res) { - var header = cookie(res); + var header = cookie(res) + var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(header.split('=')[0], name, 'should set cookie ' + name) - assert.equal(header.split('=')[1].split(';')[0], val, 'should set cookie ' + name + ' to ' + val) + assert.equal(data.name, name, 'should set cookie ' + name) + assert.equal(data.value, val, 'should set cookie ' + name + ' to ' + val) } } -function shouldSetSecureCookie(name) { +function shouldSetSecureCookie (name) { return function (res) { var header = cookie(res) + var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(header.split('=')[0], name, 'should set cookie ' + name) - assert.ok(header.toLowerCase().split(/; */).some(function (k) { return k === 'secure'; }), 'should set secure cookie') + assert.equal(data.name, name, 'should set cookie ' + name) + assert.ok(data.secure, 'should set secure cookie') } } From 42007efe9559b2f6f80f1ed587a2284b2df1dba1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 18:49:19 -0500 Subject: [PATCH 386/766] tests: add helpers to validate set-cookie attributes --- test/session.js | 108 ++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/test/session.js b/test/session.js index 49eeb5d5..87e48334 100644 --- a/test/session.js +++ b/test/session.js @@ -710,8 +710,7 @@ describe('session()', function(){ request(this.server) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(shouldSetCookie('connect.sid')) - .expect(shouldSetSecureCookie('connect.sid')) + .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) .expect(200, done) }) }) @@ -725,8 +724,7 @@ describe('session()', function(){ request(this.server) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(shouldSetCookie('connect.sid')) - .expect(shouldNotSetSecureCookie('connect.sid')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) .expect(200, done) }) }) @@ -743,8 +741,7 @@ describe('session()', function(){ request(this.app) .get('/') .set('X-Secure', 'true') - .expect(shouldSetCookie('connect.sid')) - .expect(shouldSetSecureCookie('connect.sid')) + .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) .expect(200, 'true', done) }) @@ -752,8 +749,7 @@ describe('session()', function(){ request(this.app) .get('/') .set('X-Secure', 'false') - .expect(shouldSetCookie('connect.sid')) - .expect(shouldNotSetSecureCookie('connect.sid')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) .expect(200, 'false', done) }) }) @@ -1681,24 +1677,16 @@ describe('session()', function(){ request(server) .get('/') .set('X-Forwarded-Proto', 'https') - .expect(200, function(err, res){ - if (err) return done(err); - var val = cookie(res); - assert.equal(val.indexOf('HttpOnly'), -1, 'should not be HttpOnly cookie') - assert.notEqual(val.indexOf('Secure'), -1, 'should be Secure cookie') - done(); - }); + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'HttpOnly')) + .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) + .expect(200, done) }) it('should default to a browser-session length cookie', function(done){ request(createServer({ cookie: { path: '/admin' } })) .get('/admin') - .expect(200, function(err, res){ - if (err) return done(err); - var val = cookie(res); - assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') - done(); - }); + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Expires')) + .expect(200, done) }) it('should Set-Cookie only once for browser-session cookies', function(done){ @@ -1725,15 +1713,11 @@ describe('session()', function(){ request(server) .get('/admin') - .expect(200, function(err, res){ - if (err) return done(err); - var val = cookie(res); - assert.equal(val.indexOf('HttpOnly'), -1, 'should not be HttpOnly cookie') - assert.equal(val.indexOf('Secure'), -1, 'should not be Secure cookie') - assert.notEqual(val.indexOf('Path=/admin'), -1, 'should have cookie path /admin') - assert.notEqual(val.indexOf('Expires'), -1, 'should have cookie Expires') - done(); - }); + .expect(shouldSetCookieWithAttribute('connect.sid', 'Expires')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'HttpOnly')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Path', '/admin')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(200, done) }) it('should preserve cookies set before writeHead is called', function(done){ @@ -1917,11 +1901,8 @@ describe('session()', function(){ request(server) .get('/') - .end(function(err, res){ - if (err) return done(err) - assert.equal(expires(res), 'Thu, 01 Jan 1970 00:00:00 GMT') - done(); - }); + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Expires', 'Thu, 01 Jan 1970 00:00:00 GMT')) + .expect(200, done) }) }) @@ -1934,12 +1915,8 @@ describe('session()', function(){ request(server) .get('/') - .expect(200, function(err, res){ - if (err) return done(err); - var val = cookie(res); - assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') - done(); - }); + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Expires')) + .expect(200, done) }) it('should not reset cookie', function (done) { @@ -1950,18 +1927,14 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Expires')) .expect(200, function (err, res) { if (err) return done(err); - var val = cookie(res); - assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') request(server) .get('/') - .set('Cookie', val) - .expect(200, function (err, res) { - if (err) return done(err); - assert.ok(!cookie(res)); - done(); - }); + .set('Cookie', cookie(res)) + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }); }) @@ -1974,18 +1947,14 @@ describe('session()', function(){ request(server) .get('/') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Expires')) .expect(200, function (err, res) { if (err) return done(err); - var val = cookie(res); - assert.equal(val.indexOf('Expires'), -1, 'should be not have cookie Expires') request(server) .get('/') - .set('Cookie', val) - .expect(200, function (err, res) { - if (err) return done(err); - assert.ok(!cookie(res)); - done(); - }); + .set('Cookie', cookie(res)) + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }); }) }) @@ -2218,42 +2187,53 @@ function shouldNotSetSessionInStore(store) { } } -function shouldNotSetSecureCookie(name) { +function shouldSetCookie (name) { return function (res) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.equal(data.name, name, 'should set cookie ' + name) - assert.ok(!data.secure, 'should not set secure cookie') } } -function shouldSetCookie (name) { +function shouldSetCookieToValue (name, val) { return function (res) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.equal(data.name, name, 'should set cookie ' + name) + assert.equal(data.value, val, 'should set cookie ' + name + ' to ' + val) } } -function shouldSetCookieToValue (name, val) { +function shouldSetCookieWithAttribute (name, attrib) { return function (res) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.equal(data.name, name, 'should set cookie ' + name) - assert.equal(data.value, val, 'should set cookie ' + name + ' to ' + val) + assert.ok((attrib.toLowerCase() in data), 'should set cookie with attribute ' + attrib) + } +} + +function shouldSetCookieWithAttributeAndValue (name, attrib, value) { + return function (res) { + var header = cookie(res) + var data = header && parseSetCookie(header) + assert.ok(header, 'should have a cookie header') + assert.equal(data.name, name, 'should set cookie ' + name) + assert.ok((attrib.toLowerCase() in data), 'should set cookie with attribute ' + attrib) + assert.equal(data[attrib.toLowerCase()], value, 'should set cookie with attribute ' + attrib + ' set to ' + value) } } -function shouldSetSecureCookie (name) { +function shouldSetCookieWithoutAttribute (name, attrib) { return function (res) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.equal(data.name, name, 'should set cookie ' + name) - assert.ok(data.secure, 'should set secure cookie') + assert.ok(!(attrib.toLowerCase() in data), 'should set cookie without attribute ' + attrib) } } From 28d5332c9d799b063046c2ea8054fc5eb799c974 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 21:18:34 -0500 Subject: [PATCH 387/766] tests: improve accuracy of maxAge cookie tests --- test/session.js | 112 +++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/test/session.js b/test/session.js index 87e48334..e0c97d60 100644 --- a/test/session.js +++ b/test/session.js @@ -1828,67 +1828,59 @@ describe('session()', function(){ }) }) - describe('.maxAge', function(){ - var val; - var app = express() - .use(createSession({ cookie: { maxAge: 2000 } })) - .use(function(req, res, next){ - req.session.count = req.session.count || 0; - req.session.count++; - if (req.session.count == 2) req.session.cookie.maxAge = 5000; - if (req.session.count == 3) req.session.cookie.maxAge = 3000000000; - res.end(req.session.count.toString()); - }); + describe('.maxAge', function () { + before(function (done) { + var ctx = this + + ctx.cookie = '' + ctx.server = createServer({ cookie: { maxAge: 2000 } }, function (req, res) { + switch (++req.session.count) { + case 1: + break + case 2: + req.session.cookie.maxAge = 5000 + break + case 3: + req.session.cookie.maxAge = 3000000000 + break + default: + req.session.count = 0 + break + } + res.end(req.session.count.toString()) + }) - it('should set relative in milliseconds', function(done){ - request(app) + request(ctx.server) .get('/') - .expect(200, '1', function (err, res) { - if (err) return done(err) - var a = new Date(expires(res)) - var b = new Date - var delta = a.valueOf() - b.valueOf() - - val = cookie(res); - - assert.ok(delta > 1000 && delta <= 2000) - done(); - }); - }); + .end(function (err, res) { + ctx.cookie = res && cookie(res) + done(err) + }) + }) - it('should modify cookie when changed', function(done){ - request(app) + it('should set cookie expires relative to maxAge', function (done) { + request(this.server) .get('/') - .set('Cookie', val) - .expect(200, '2', function (err, res) { - if (err) return done(err) - var a = new Date(expires(res)) - var b = new Date - var delta = a.valueOf() - b.valueOf() - - val = cookie(res); - - assert.ok(delta > 4000 && delta <= 5000) - done(); - }); - }); + .set('Cookie', this.cookie) + .expect(shouldSetCookieToExpireIn('connect.sid', 2000)) + .expect(200, '1', done) + }) - it('should modify cookie when changed to large value', function(done){ - request(app) + it('should modify cookie expires when changed', function (done) { + request(this.server) .get('/') - .set('Cookie', val) - .expect(200, '3', function (err, res) { - if (err) return done(err) - var a = new Date(expires(res)) - var b = new Date - var delta = a.valueOf() - b.valueOf() - - val = cookie(res); + .set('Cookie', this.cookie) + .expect(shouldSetCookieToExpireIn('connect.sid', 5000)) + .expect(200, '2', done) + }) - assert.ok(delta > 2999999000 && delta <= 3000000000) - done(); - }); - }); + it('should modify cookie expires when changed to large value', function (done) { + request(this.server) + .get('/') + .set('Cookie', this.cookie) + .expect(shouldSetCookieToExpireIn('connect.sid', 3000000000)) + .expect(200, '3', done) + }) }) describe('.expires', function(){ @@ -2196,6 +2188,18 @@ function shouldSetCookie (name) { } } +function shouldSetCookieToExpireIn (name, delta) { + return function (res) { + var header = cookie(res) + var data = header && parseSetCookie(header) + assert.ok(header, 'should have a cookie header') + assert.equal(data.name, name, 'should set cookie ' + name) + assert.ok(('expires' in data), 'should set cookie with attribute Expires') + assert.ok(('date' in res.headers), 'should have a date header') + assert.equal((Date.parse(data.expires) - Date.parse(res.headers.date)), delta, 'should set cookie ' + name + ' to expire in ' + delta + ' ms') + } +} + function shouldSetCookieToValue (name, val) { return function (res) { var header = cookie(res) From dc8481c152b162c119d1faa8e9edf505dc22cbb3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 22 Jan 2017 21:21:14 -0500 Subject: [PATCH 388/766] 1.15.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index fe154656..68807acb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.0 / 2017-01-22 +=================== * Fix detecting modified session when session contains "cookie" property * Fix resaving already-saved reloaded session at end of request diff --git a/package.json b/package.json index 276327f6..badf81cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.14.2", + "version": "1.15.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From eba25212170401cb259ebe3d713c2e377fedefcd Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Fri, 10 Feb 2017 15:50:26 -0500 Subject: [PATCH 389/766] deps: debug@2.6.1 closes #426 closes #427 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 68807acb..0c8229fd 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * deps: debug@2.6.1 + - Fix deprecation messages in WebStorm and other editors + - Undeprecate `DEBUG_FD` set to `1` or `2` + 1.15.0 / 2017-01-22 =================== diff --git a/package.json b/package.json index badf81cb..bab5a2e3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.0", + "debug": "2.6.1", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From f8550538f6e821037b33fc0d59748ddd54781164 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Feb 2017 20:58:00 -0500 Subject: [PATCH 390/766] build: Node.js@7.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d6aabe0b..d0b78b78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.7" - "5.12" - "6.9" - - "7.4" + - "7.5" sudo: false cache: directories: From 8e56128d8ba014ab586521247977b0d4e67340f9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Feb 2017 21:01:08 -0500 Subject: [PATCH 391/766] 1.15.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0c8229fd..023a8213 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.1 / 2017-02-10 +=================== * deps: debug@2.6.1 - Fix deprecation messages in WebStorm and other editors diff --git a/package.json b/package.json index bab5a2e3..3f4d17ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.0", + "version": "1.15.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 599595495a4907f02ee98d601e91c9cf20057e72 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Feb 2017 22:28:47 -0500 Subject: [PATCH 392/766] build: express@4.14.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f4d17ad..bd98956a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.3", - "express": "4.14.0", + "express": "4.14.1", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From c4b2fb95584aeec1527b649b14e8bab64a7ca5f3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Feb 2017 22:29:30 -0500 Subject: [PATCH 393/766] build: Node.js@4.8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d0b78b78..d1f33819 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.7" + - "4.8" - "5.12" - "6.9" - "7.5" From edfe52ddf7891a8da9cd654f85b4d6cded9f50e2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Feb 2017 22:29:38 -0500 Subject: [PATCH 394/766] build: Node.js@6.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d1f33819..5ce3c81d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.9" + - "6.10" - "7.5" sudo: false cache: From 14b5480a4d19649846c903cc6b6b41f7217db29f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Feb 2017 22:30:30 -0500 Subject: [PATCH 395/766] build: Node.js@7.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5ce3c81d..83b36bb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.5" + - "7.7" sudo: false cache: directories: From 27f6489b78467e281716440d125822ce4373a940 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Feb 2017 22:34:51 -0500 Subject: [PATCH 396/766] docs: update install code block style --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70f8f2be..10d2f49d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): -```bash +```sh $ npm install express-session ``` From 304678b8f8e0d8061a05fb5e2c3d38d765c49c95 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Feb 2017 22:36:45 -0500 Subject: [PATCH 397/766] build: test on Node.js 8.x nightly --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 83b36bb4..e62ed128 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,13 @@ node_js: - "5.12" - "6.10" - "7.7" +matrix: + include: + - node_js: "8.0" + env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" + allow_failures: + # Allow the nightly installs to fail + - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" sudo: false cache: directories: From fff51d6ff087d53250b7c6752253dc4ca30664c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Mar 2017 23:00:48 -0500 Subject: [PATCH 398/766] deps: uid-safe@~2.1.4 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 023a8213..ea881415 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: uid-safe@~2.1.4 + - Remove `base64-url` dependency + 1.15.1 / 2017-02-10 =================== diff --git a/package.json b/package.json index bd98956a..c23e31f1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", - "uid-safe": "~2.1.3", + "uid-safe": "~2.1.4", "utils-merge": "1.0.0" }, "devDependencies": { From 2604a6cbac9a77b4e06959e8aebe65b50ccb9491 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 8 Mar 2017 09:26:44 +0000 Subject: [PATCH 399/766] docs: add connect-cloudant-store to the list of session stores closes #436 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 10d2f49d..206ed11a 100644 --- a/README.md +++ b/README.md @@ -506,6 +506,11 @@ and other multi-core embedded devices). [connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables [connect-azuretables-image]: https://img.shields.io/github/stars/mike-goodwin/connect-azuretables.svg?label=%E2%98%85 +[![โ˜…][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store. + +[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store +[connect-cloudant-store-image]: https://img.shields.io/github/stars/adriantanasa/connect-cloudant-store.svg?label=%E2%98%85 + [![โ˜…][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase From 9a014fd9b07ab56f57e1f9759e4e247a65cd21dc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Mar 2017 23:31:14 -0500 Subject: [PATCH 400/766] build: express@4.15.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c23e31f1..91fe07b7 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.3", - "express": "4.14.1", + "express": "4.15.2", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 66e518be96df608eaf73c97d29735688efa61270 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Mar 2017 20:58:03 -0500 Subject: [PATCH 401/766] tests: fix req.secret test --- test/session.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/session.js b/test/session.js index e0c97d60..94812b91 100644 --- a/test/session.js +++ b/test/session.js @@ -43,7 +43,7 @@ describe('session()', function(){ it('should get secret from req.secret', function(done){ var app = express() .use(function(req, res, next){ req.secret = 'keyboard cat'; next(); }) - .use(createSession()) + .use(createSession({ secret: undefined })) .use(end); app.set('env', 'test'); From 4a4c2efa194009e1cdfa9bafb2412e5ab315234f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Mar 2017 21:28:53 -0500 Subject: [PATCH 402/766] tests: remove express from more tests --- test/session.js | 199 +++++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 94 deletions(-) diff --git a/test/session.js b/test/session.js index 94812b91..6711df98 100644 --- a/test/session.js +++ b/test/session.js @@ -23,15 +23,14 @@ describe('session()', function(){ }) it('should do nothing if req.session exists', function(done){ - var app = express() - .use(function(req, res, next){ req.session = {}; next(); }) - .use(createSession()) - .use(end); + function setup (req) { + req.session = {} + } - request(app) - .get('/') - .expect(shouldNotHaveHeader('Set-Cookie')) - .expect(200, done) + request(createServer(setup)) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) }) it('should error without secret', function(done){ @@ -41,13 +40,11 @@ describe('session()', function(){ }) it('should get secret from req.secret', function(done){ - var app = express() - .use(function(req, res, next){ req.secret = 'keyboard cat'; next(); }) - .use(createSession({ secret: undefined })) - .use(end); - app.set('env', 'test'); + function setup (req) { + req.secret = 'keyboard cat' + } - request(app) + request(createServer(setup, { secret: undefined })) .get('/') .expect(200, '', done) }) @@ -643,56 +640,66 @@ describe('session()', function(){ }) describe('when disabled', function(){ - var server before(function () { - server = createServer({ proxy: false, cookie: { secure: true, maxAge: 5 }}) + function setup (req) { + req.secure = req.headers['x-secure'] + ? JSON.parse(req.headers['x-secure']) + : undefined + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { proxy: false, cookie: { secure: true }}, respond) }) it('should not trust X-Forwarded-Proto', function(done){ - request(server) + request(this.server) .get('/') .set('X-Forwarded-Proto', 'https') .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) - it('should ignore req.secure from express', function(done){ - var app = express() - .use(createSession({ proxy: false, cookie: { secure: true } })) - .use(function(req, res) { res.json(req.secure); }); - app.enable('trust proxy'); - - request(app) + it('should ignore req.secure', function (done) { + request(this.server) .get('/') .set('X-Forwarded-Proto', 'https') + .set('X-Secure', 'true') .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, 'true', done) }) }) describe('when unspecified', function(){ - var server before(function () { - server = createServer({ cookie: { secure: true, maxAge: 5 }}) + function setup (req) { + req.secure = req.headers['x-secure'] + ? JSON.parse(req.headers['x-secure']) + : undefined + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { cookie: { secure: true }}, respond) }) it('should not trust X-Forwarded-Proto', function(done){ - request(server) + request(this.server) .get('/') .set('X-Forwarded-Proto', 'https') .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, done) }) - it('should use req.secure from express', function(done){ - var app = express() - .use(createSession({ cookie: { secure: true } })) - .use(function(req, res) { res.json(req.secure); }); - app.enable('trust proxy'); - - request(app) + it('should use req.secure', function (done) { + request(this.server) .get('/') .set('X-Forwarded-Proto', 'https') + .set('X-Secure', 'true') .expect(shouldSetCookie('connect.sid')) .expect(200, 'true', done) }) @@ -731,14 +738,19 @@ describe('session()', function(){ describe('when "proxy" is undefined', function() { before(function () { - this.app = express() - .use(function(req, res, next) { Object.defineProperty(req, 'secure', { value: JSON.parse(req.headers['x-secure']) }); next(); }) - .use(createSession({ cookie: { secure: 'auto' } })) - .use(function(req, res) { res.json(req.secure); }); + function setup (req) { + req.secure = JSON.parse(req.headers['x-secure']) + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { cookie: { secure: 'auto' } }, respond) }) it('should set secure if req.secure = true', function (done) { - request(this.app) + request(this.server) .get('/') .set('X-Secure', 'true') .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) @@ -746,7 +758,7 @@ describe('session()', function(){ }) it('should not set secure if req.secure = false', function (done) { - request(this.app) + request(this.server) .get('/') .set('X-Secure', 'false') .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) @@ -1292,33 +1304,30 @@ describe('session()', function(){ describe('res.end patch', function () { it('should correctly handle res.end/res.write patched prior', function (done) { - var app = express() + function setup (req, res) { + writePatch(res) + } - app.use(writePatch()) - app.use(createSession()) - app.use(function (req, res) { + function respond (req, res) { req.session.hit = true res.write('hello, ') res.end('world') - }) + } - request(app) + request(createServer(setup, null, respond)) .get('/') .expect(200, 'hello, world', done) }) it('should correctly handle res.end/res.write patched after', function (done) { - var app = express() - - app.use(createSession()) - app.use(writePatch()) - app.use(function (req, res) { + function respond (req, res) { + writePatch(res) req.session.hit = true res.write('hello, ') res.end('world') - }) + } - request(app) + request(createServer(null, respond)) .get('/') .expect(200, 'hello, world', done) }) @@ -1442,47 +1451,41 @@ describe('session()', function(){ describe('.destroy()', function(){ it('should destroy the previous session', function(done){ - var app = express() - .use(createSession()) - .use(function(req, res, next){ - req.session.destroy(function(err){ - if (err) return next(err) - assert(!req.session, 'req.session after destroy'); - res.end(); - }); - }); + var server = createServer(null, function (req, res) { + req.session.destroy(function (err) { + if (err) res.statusCode = 500 + res.end(String(req.session)) + }) + }) - request(app) + request(server) .get('/') .expect(shouldNotHaveHeader('Set-Cookie')) - .expect(200, done) + .expect(200, 'undefined', done) }) }) describe('.regenerate()', function(){ it('should destroy/replace the previous session', function(done){ - var app = express() - .use(createSession()) - .use(function(req, res, next){ - var id = req.session.id; - req.session.regenerate(function(err){ - if (err) return next(err) - assert.notEqual(id, req.session.id) - res.end(); - }); - }); + var server = createServer(null, function (req, res) { + var id = req.session.id + req.session.regenerate(function (err) { + if (err) res.statusCode = 500 + res.end(String(req.session.id === id)) + }) + }) - request(app) + request(server) .get('/') .expect(shouldSetCookie('connect.sid')) .expect(200, function (err, res) { if (err) return done(err) var id = sid(res) - request(app) + request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) - .expect(200, function (err, res) { + .expect(200, 'false', function (err, res) { if (err) return done(err) assert.notEqual(sid(res), id) done(); @@ -2089,8 +2092,20 @@ function cookie(res) { return (setCookie && setCookie[0]) || undefined; } -function createServer(opts, fn) { - return http.createServer(createRequestListener(opts, fn)) +function createServer (options, respond) { + var fn = respond + var opts = options + var server = http.createServer() + + // setup, options, respond + if (typeof arguments[0] === 'function') { + opts = arguments[1] + fn = arguments[2] + + server.on('request', arguments[0]) + } + + return server.on('request', createRequestListener(opts, fn)) } function createRequestListener(opts, fn) { @@ -2261,26 +2276,22 @@ function sid(res) { return val } -function writePatch() { +function writePatch (res) { + var _end = res.end + var _write = res.write var ended = false - return function addWritePatch(req, res, next) { - var _end = res.end - var _write = res.write - res.end = function end() { - ended = true - return _end.apply(this, arguments) - } - - res.write = function write() { - if (ended) { - throw new Error('write after end') - } + res.end = function end() { + ended = true + return _end.apply(this, arguments) + } - return _write.apply(this, arguments) + res.write = function write() { + if (ended) { + throw new Error('write after end') } - next() + return _write.apply(this, arguments) } } From 3a7e3d2734ef088c25550453652937a8c3cc37a5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Mar 2017 21:33:53 -0500 Subject: [PATCH 403/766] deps: debug@2.6.2 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index ea881415..7e89a695 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * deps: debug@2.6.2 + - Fix `DEBUG_MAX_ARRAY_LENGTH` * deps: uid-safe@~2.1.4 - Remove `base64-url` dependency diff --git a/package.json b/package.json index 91fe07b7..77c6cb76 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.1", + "debug": "2.6.2", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 5fd74d2601aafe43c7697a1bd2dab0add6d71010 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Mar 2017 23:04:42 -0400 Subject: [PATCH 404/766] build: fix istanbul ignore scope --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 68ccf533..8db4eca3 100644 --- a/index.js +++ b/index.js @@ -148,8 +148,8 @@ function session(options) { // notify user that this store is not // meant for a production environment + /* istanbul ignore next: not tested */ if ('production' == env && store instanceof MemoryStore) { - /* istanbul ignore next: not tested */ console.warn(warning); } From b5a0437373862e2e0303cfca67e2736d2fcbf586 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Mar 2017 23:12:18 -0400 Subject: [PATCH 405/766] deps: debug@2.6.3 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 7e89a695..7a280573 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ unreleased ========== - * deps: debug@2.6.2 + * deps: debug@2.6.3 - Fix `DEBUG_MAX_ARRAY_LENGTH` * deps: uid-safe@~2.1.4 - Remove `base64-url` dependency diff --git a/package.json b/package.json index 77c6cb76..56fdf0c3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.2", + "debug": "2.6.3", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 4b033b32c667dead3e1e25c871c72c66f9d7241b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 26 Mar 2017 19:35:40 -0400 Subject: [PATCH 406/766] docs: fix rendering of express-sessions store in list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 206ed11a..a2b96bcd 100644 --- a/README.md +++ b/README.md @@ -601,6 +601,7 @@ and other multi-core embedded devices). [express-oracle-session-image]: https://img.shields.io/github/stars/slumber86/express-oracle-session.svg?label=%E2%98%85 [![โ˜…][express-sessions-image] express-sessions][express-sessions-url]: A session store supporting both MongoDB and Redis. + [express-sessions-url]: https://www.npmjs.com/package/express-sessions [express-sessions-image]: https://img.shields.io/github/stars/konteck/express-sessions.svg?label=%E2%98%85 From d051890724e0cf10d51cc310f3f07517c9b724a2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 26 Mar 2017 19:52:50 -0400 Subject: [PATCH 407/766] 1.15.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 7a280573..5fc286b3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.2 / 2017-03-26 +=================== * deps: debug@2.6.3 - Fix `DEBUG_MAX_ARRAY_LENGTH` diff --git a/package.json b/package.json index 56fdf0c3..24de3879 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.1", + "version": "1.15.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 4aa57a0c24c8f5bb1a287722d0444374820d8f10 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 May 2017 22:34:25 -0400 Subject: [PATCH 408/766] deps: debug@2.6.6 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 5fc286b3..6994c4ea 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: debug@2.6.6 + - deps: ms@0.7.3 + 1.15.2 / 2017-03-26 =================== diff --git a/package.json b/package.json index 24de3879..74d15f5c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.3", + "debug": "2.6.6", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 32c2b107291e1271f8ae3319ade479b567193453 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 May 2017 22:39:04 -0400 Subject: [PATCH 409/766] build: Node.js@7.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e62ed128..0cd03d33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.7" + - "7.9" matrix: include: - node_js: "8.0" From e01ca868bc3fc7861aab9556942cd89eb0fcb50f Mon Sep 17 00:00:00 2001 From: Jorrit Schippers Date: Mon, 1 May 2017 12:08:28 +0200 Subject: [PATCH 410/766] docs: add connect-memjs to the list of session stores closes #455 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a2b96bcd..3530d7cd 100644 --- a/README.md +++ b/README.md @@ -576,6 +576,12 @@ and other multi-core embedded devices). [connect-memcached-url]: https://www.npmjs.com/package/connect-memcached [connect-memcached-image]: https://img.shields.io/github/stars/balor/connect-memcached.svg?label=%E2%98%85 +[![โ˜…][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using +[memjs](https://www.npmjs.com/package/memjs) as the memcached client. + +[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs +[connect-memjs-image]: https://img.shields.io/github/stars/liamdon/connect-memjs.svg?label=%E2%98%85 + [![โ˜…][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using [Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. From d0df7abdfbdb77c221bc173ae3a480afcc5247a8 Mon Sep 17 00:00:00 2001 From: Gajus Kuizinas Date: Mon, 1 May 2017 21:10:57 +0100 Subject: [PATCH 411/766] docs: add note that req.session.id is alias of req.sessionID closes #456 closes #457 --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3530d7cd..96106cdf 100644 --- a/README.md +++ b/README.md @@ -367,8 +367,10 @@ not necessary to call, as the session middleware does this for you. ### req.session.id -Each session has a unique ID associated with it. This property will -contain the session ID and cannot be modified. +Each session has a unique ID associated with it. This property is an +alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified. +It has been added to make the session ID accessible from the `session` +object. ### req.session.cookie From 762c041e26c27a9e3332325fd000345929782260 Mon Sep 17 00:00:00 2001 From: Theo Gravity Date: Mon, 1 May 2017 21:40:35 -0700 Subject: [PATCH 412/766] docs: add express-session-cache-manager to the list of session stores closes #454 closes #458 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 96106cdf..df8dc5b7 100644 --- a/README.md +++ b/README.md @@ -628,6 +628,13 @@ and other multi-core embedded devices). [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session [express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 +[![โ˜…][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url] +A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports +a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines). + +[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager +[express-session-cache-manager-image]: https://img.shields.io/github/stars/theogravity/express-session-cache-manager.svg?label=%E2%98%85 + [![โ˜…][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store. [express-session-level-url]: https://www.npmjs.com/package/express-session-level From 98b90053bcc21e7ce9a40cd5d3fc27412e2b1a01 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 18 May 2017 01:02:50 -0400 Subject: [PATCH 413/766] deps: debug@2.6.7 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6994c4ea..493f0916 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,8 +1,8 @@ unreleased ========== - * deps: debug@2.6.6 - - deps: ms@0.7.3 + * deps: debug@2.6.7 + - deps: ms@2.0.0 1.15.2 / 2017-03-26 =================== diff --git a/package.json b/package.json index 74d15f5c..fe196bbc 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.6", + "debug": "2.6.7", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 4866502dba022c5134cc819d8d7ace1707a2695d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 18 May 2017 01:03:27 -0400 Subject: [PATCH 414/766] build: express@4.15.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fe196bbc..bc2be3d5 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.3", - "express": "4.15.2", + "express": "4.15.3", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 0595f890bede6bca4040a2f412157c61fe81b1f8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 18 May 2017 01:03:55 -0400 Subject: [PATCH 415/766] build: Node.js@7.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0cd03d33..43adb0db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.9" + - "7.10" matrix: include: - node_js: "8.0" From ff4c5117d4c7f93f375610b76494e47cdd7d1aaa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 18 May 2017 01:14:05 -0400 Subject: [PATCH 416/766] 1.15.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 493f0916..21ca5aca 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.3 / 2017-05-17 +=================== * deps: debug@2.6.7 - deps: ms@2.0.0 diff --git a/package.json b/package.json index bc2be3d5..f8d1eae7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.2", + "version": "1.15.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 3a7fbaa6b3a239e7afd73f76dababf53a0c148ac Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Jun 2017 19:00:35 -0400 Subject: [PATCH 417/766] build: support Node.js 8.x --- .gitignore | 1 + .travis.yml | 10 +++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index df9af16b..84a48637 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coverage node_modules npm-debug.log +package-lock.json diff --git a/.travis.yml b/.travis.yml index 43adb0db..6844810b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,18 +10,14 @@ node_js: - "5.12" - "6.10" - "7.10" -matrix: - include: - - node_js: "8.0" - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" - allow_failures: - # Allow the nightly installs to fail - - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" + - "8.0" sudo: false cache: directories: - node_modules before_install: + # Skip updating shrinkwrap / lock + - "npm config set shrinkwrap false" # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" # Update Node.js modules From 501b31f7a09c9d7f9b4953c4f5a9a3099c5b8937 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Jun 2017 19:04:09 -0400 Subject: [PATCH 418/766] deps: debug@2.6.8 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 21ca5aca..832925cb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@2.6.8 + 1.15.3 / 2017-05-17 =================== diff --git a/package.json b/package.json index f8d1eae7..8f1c9022 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.7", + "debug": "2.6.8", "depd": "~1.1.0", "on-headers": "~1.0.1", "parseurl": "~1.3.1", From 239e1b9b7a59bbb71d2a2a7e90f64d3ca2435145 Mon Sep 17 00:00:00 2001 From: Steven Vachon Date: Tue, 18 Jul 2017 11:05:09 -0400 Subject: [PATCH 419/766] docs: mention redirects in for session.save() use closes #484 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df8dc5b7..9a9be6e1 100644 --- a/README.md +++ b/README.md @@ -351,8 +351,8 @@ session data has been altered (though this behavior can be altered with various options in the middleware constructor). Because of this, typically this method does not need to be called. -There are some cases where it is useful to call this method, for example, long- -lived requests or in WebSockets. +There are some cases where it is useful to call this method, for example, +redirects, long-lived requests or in WebSockets. ```js req.session.save(function(err) { From 5a227d658152f165689f6f3763759a0c9068e987 Mon Sep 17 00:00:00 2001 From: Rafael Pinto Date: Wed, 19 Jul 2017 00:10:58 +0100 Subject: [PATCH 420/766] docs: add dynamodb-store to the list of session stores closes #485 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 9a9be6e1..351cd1ba 100644 --- a/README.md +++ b/README.md @@ -596,6 +596,11 @@ and other multi-core embedded devices). [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 +[![โ˜…][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store. + +[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store +[dynamodb-store-image]: https://img.shields.io/github/stars/rafaelrpinto/dynamodb-store.svg?label=%E2%98%85 + [![โ˜…][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native [MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module. From d367b335cc2146e673b6eff106929979b39fc757 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 18 Jul 2017 23:00:45 -0400 Subject: [PATCH 421/766] build: Node.js@6.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6844810b..da95e861 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.10" + - "6.11" - "7.10" - "8.0" sudo: false From fc9d474e034f1f9545f0e7e1f180d50ea39389e5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 18 Jul 2017 23:00:53 -0400 Subject: [PATCH 422/766] build: Node.js@8.1 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index da95e861..ebf941a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.11" - "7.10" - - "8.0" + - "8.1" sudo: false cache: directories: From 7b26d57bb766b416a81f4a70f3da22d4bbbfb0e1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 18 Jul 2017 23:47:37 -0400 Subject: [PATCH 423/766] 1.15.4 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 832925cb..c4daf96c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.4 / 2017-07-18 +=================== * deps: debug@2.6.8 diff --git a/package.json b/package.json index 8f1c9022..21afdb65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.3", + "version": "1.15.4", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 521e6bd965fb425e1ece42fd68fbff4b524c4636 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 19 Jul 2017 13:49:11 -0400 Subject: [PATCH 424/766] tests: add leak checking for variables and handles --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 21afdb65..dab9bc91 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,8 @@ "node": ">= 0.8.0" }, "scripts": { - "test": "mocha --bail --reporter spec test/", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec test/" + "test": "mocha --check-leaks --bail --no-exit --reporter spec test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --no-exit --reporter dot test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --no-exit --reporter spec test/" } } From fc60bb63cec5f62810f61c16a81e682213cdfad3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 30 Jul 2017 22:34:12 -0400 Subject: [PATCH 425/766] build: Node.js@8.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ebf941a0..47a26ad2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.11" - "7.10" - - "8.1" + - "8.2" sudo: false cache: directories: From 310d288819175424b57a5689a4a8bc4cfb387ae5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 30 Jul 2017 22:38:02 -0400 Subject: [PATCH 426/766] deps: depd@~1.1.1 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index c4daf96c..b2bdf23a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: depd@~1.1.1 + - Remove unnecessary `Buffer` loading + 1.15.4 / 2017-07-18 =================== diff --git a/package.json b/package.json index dab9bc91..ec4c2a25 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.6", "crc": "3.4.4", "debug": "2.6.8", - "depd": "~1.1.0", + "depd": "~1.1.1", "on-headers": "~1.0.1", "parseurl": "~1.3.1", "uid-safe": "~2.1.4", From 2b08370431bef47dd58b8567006c3d94b4ec2c45 Mon Sep 17 00:00:00 2001 From: ralvarezo123 Date: Fri, 21 Jul 2017 18:43:48 -0600 Subject: [PATCH 427/766] docs: improve code readability closes #488 --- README.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 351cd1ba..939b0c0e 100644 --- a/README.md +++ b/README.md @@ -292,15 +292,14 @@ app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) // Access the session as req.session app.get('/', function(req, res, next) { - var sess = req.session - if (sess.views) { - sess.views++ + if (req.session.views) { + req.session.views++ res.setHeader('Content-Type', 'text/html') - res.write('

views: ' + sess.views + '

') - res.write('

expires in: ' + (sess.cookie.maxAge / 1000) + 's

') + res.write('

views: ' + req.session.views + '

') + res.write('

expires in: ' + (req.session.cookie.maxAge / 1000) + 's

') res.end() } else { - sess.views = 1 + req.session.views = 1 res.end('welcome to the session demo. refresh!') } }) @@ -714,17 +713,15 @@ app.use(session({ })) app.use(function (req, res, next) { - var views = req.session.views - - if (!views) { - views = req.session.views = {} + if (!req.session.views) { + req.session.views = {} } // get the url pathname var pathname = parseurl(req).pathname // count the views - views[pathname] = (views[pathname] || 0) + 1 + req.session.views[pathname] = (req.session.views[pathname] || 0) + 1 next() }) From 8518200db49aff3b2e3f079679459aa7d400976c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Aug 2017 21:11:11 -0400 Subject: [PATCH 428/766] tests: move the cookie path tests --- test/session.js | 89 +++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 54 deletions(-) diff --git a/test/session.js b/test/session.js index 6711df98..8e0f986a 100644 --- a/test/session.js +++ b/test/session.js @@ -707,6 +707,41 @@ describe('session()', function(){ }) describe('cookie option', function () { + describe('when "path" set to "/foo/bar"', function () { + before(function () { + this.server = createServer({ cookie: { path: '/foo/bar' } }) + }) + + it('should not set cookie for "/" request', function (done) { + request(this.server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }) + + it('should not set cookie for "http://foo/bar" request', function (done) { + request(this.server) + .get('/') + .set('host', 'http://foo/bar') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }) + + it('should set cookie for "/foo/bar" request', function (done) { + request(this.server) + .get('/foo/bar/baz') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should set cookie for "/foo/bar/baz" request', function (done) { + request(this.server) + .get('/foo/bar/baz') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + }) + describe('when "secure" set to "auto"', function () { describe('when "proxy" is "true"', function () { before(function () { @@ -1777,60 +1812,6 @@ describe('session()', function(){ }) }) - describe('when the pathname does not match cookie.path', function(){ - it('should not set-cookie', function(done){ - var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { - if (req.session) req.session.foo = Math.random() - res.end() - }) - - request(server) - .get('/') - .expect(shouldNotHaveHeader('Set-Cookie')) - .expect(200, done) - }) - - it('should not set-cookie even for FQDN', function(done){ - var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { - if (req.session) req.session.foo = Math.random() - res.end() - }) - - request(server) - .get('/') - .set('host', 'http://foo/bar') - .expect(shouldNotHaveHeader('Set-Cookie')) - .expect(200, done) - }) - }) - - describe('when the pathname does match cookie.path', function(){ - it('should set-cookie', function(done){ - var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { - req.session.foo = Math.random() - res.end() - }) - - request(server) - .get('/foo/bar/baz') - .expect(shouldSetCookie('connect.sid')) - .expect(200, done) - }) - - it('should set-cookie even for FQDN', function(done){ - var server = createServer({ cookie: { path: '/foo/bar' } }, function (req, res) { - req.session.foo = Math.random() - res.end() - }) - - request(server) - .get('/foo/bar/baz') - .set('host', 'http://example.com') - .expect(shouldSetCookie('connect.sid')) - .expect(200, done) - }) - }) - describe('.maxAge', function () { before(function (done) { var ctx = this From 62c4d15c71bf92063d3bed9fc8684914d08ee1aa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Aug 2017 21:48:45 -0400 Subject: [PATCH 429/766] tests: add test for mounted middleware --- test/session.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/session.js b/test/session.js index 8e0f986a..4a7a2263 100644 --- a/test/session.js +++ b/test/session.js @@ -740,6 +740,26 @@ describe('session()', function(){ .expect(shouldSetCookie('connect.sid')) .expect(200, done) }) + + describe('when mounted at "/foo"', function () { + before(function () { + this.server = createServer(mountAt('/foo'), { cookie: { path: '/foo/bar' } }) + }) + + it('should set cookie for "/foo/bar" request', function (done) { + request(this.server) + .get('/foo/bar') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should not set cookie for "/foo/foo/bar" request', function (done) { + request(this.server) + .get('/foo/foo/bar') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }) + }) }) describe('when "secure" set to "auto"', function () { @@ -2136,6 +2156,15 @@ function expires (res) { return header && parseSetCookie(header).expires } +function mountAt (path) { + return function (req, res) { + if (req.url.indexOf(path) === 0) { + req.originalUrl = req.url + req.url = req.url.slice(path.length) + } + } +} + function parseSetCookie (header) { var match var pairs = [] From c22630155f697eed9043c85eded6d3fa7e9212ff Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Aug 2017 22:33:19 -0400 Subject: [PATCH 430/766] Fix TypeError when req.url is an empty string fixes #495 --- HISTORY.md | 1 + index.js | 2 +- test/session.js | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b2bdf23a..79f07def 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix `TypeError` when `req.url` is an empty string * deps: depd@~1.1.1 - Remove unnecessary `Buffer` loading diff --git a/index.js b/index.js index 8db4eca3..175fb234 100644 --- a/index.js +++ b/index.js @@ -191,7 +191,7 @@ function session(options) { } // pathname mismatch - var originalPath = parseUrl.original(req).pathname; + var originalPath = parseUrl.original(req).pathname || '/' if (originalPath.indexOf(cookieOptions.path || '/') !== 0) return next(); // ensure a secret is available or bail diff --git a/test/session.js b/test/session.js index 4a7a2263..241eb5f6 100644 --- a/test/session.js +++ b/test/session.js @@ -164,6 +164,17 @@ describe('session()', function(){ .expect(200, 'session created', cb) }) + it('should handle empty req.url', function (done) { + function setup (req) { + req.url = '' + } + + request(createServer(setup)) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + it('should handle multiple res.end calls', function(done){ var server = createServer(null, function (req, res) { res.setHeader('Content-Type', 'text/plain') From d63a3e9c270271ec899db9e35824a3eb9ab2d0d2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Aug 2017 23:17:40 -0400 Subject: [PATCH 431/766] 1.15.5 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 79f07def..64cb57ba 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.5 / 2017-08-02 +=================== * Fix `TypeError` when `req.url` is an empty string * deps: depd@~1.1.1 diff --git a/package.json b/package.json index ec4c2a25..cd999a00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.4", + "version": "1.15.5", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 0e97d6f02743d76c82d652d4b56cb2bc95618b31 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Aug 2017 23:31:31 -0400 Subject: [PATCH 432/766] docs: fix formatting in history --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 64cb57ba..de3f083e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,7 +3,7 @@ * Fix `TypeError` when `req.url` is an empty string * deps: depd@~1.1.1 - - Remove unnecessary `Buffer` loading + - Remove unnecessary `Buffer` loading 1.15.4 / 2017-07-18 =================== From 11b3e97a4881fc4eacac6cf2236e1e50a2121e17 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Aug 2017 19:09:35 -0400 Subject: [PATCH 433/766] deps: uid-safe@~2.1.5 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index de3f083e..10f83635 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: uid-safe@~2.1.5 + - perf: remove only trailing `=` + 1.15.5 / 2017-08-02 =================== diff --git a/package.json b/package.json index cd999a00..c8253b5d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.1", "on-headers": "~1.0.1", "parseurl": "~1.3.1", - "uid-safe": "~2.1.4", + "uid-safe": "~2.1.5", "utils-merge": "1.0.0" }, "devDependencies": { From 71c9d7c994086b73f92569cf5ef0a2b108096812 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 14 Aug 2017 19:17:54 -0400 Subject: [PATCH 434/766] build: express@4.15.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8253b5d..0983b1b6 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.3", - "express": "4.15.3", + "express": "4.15.4", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 65781dd935126d8df0fd4b104a4c7b8ea82f0a21 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 24 Aug 2017 20:09:36 -0400 Subject: [PATCH 435/766] build: Node.js@8.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 47a26ad2..d343742f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.11" - "7.10" - - "8.2" + - "8.4" sudo: false cache: directories: From 917b03d0db98e0e433f10e3d69875eabb0fa97f0 Mon Sep 17 00:00:00 2001 From: Rocco Musolino Date: Wed, 19 Jul 2017 19:17:26 +0200 Subject: [PATCH 436/766] docs: add memorystore to the list of session stores closes #487 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 939b0c0e..1708a938 100644 --- a/README.md +++ b/README.md @@ -670,6 +670,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [medea-session-store-url]: https://www.npmjs.com/package/medea-session-store [medea-session-store-image]: https://img.shields.io/github/stars/BenjaminVadant/medea-session-store.svg?label=%E2%98%85 +[![โ˜…][memorystore-image] memorystore][memorystore-url] A memory session store made for production. + +[memorystore-url]: https://www.npmjs.com/package/memorystore +[memorystore-image]: https://img.shields.io/github/stars/roccomuso/memorystore.svg?label=%E2%98%85 + [![โ˜…][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. [mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store From 8b4f668dba2221acd1e218fa0bca9a504e256090 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Aug 2017 22:08:20 -0400 Subject: [PATCH 437/766] lint: add editorconfig and eslint to enforce --- .editorconfig | 11 +++++++++++ .eslintignore | 2 ++ .eslintrc | 7 +++++++ .travis.yml | 2 ++ package.json | 2 ++ session/cookie.js | 2 +- test/session.js | 28 ++++++++++++++-------------- 7 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..cdb36c1b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.js,*.json,*.yml}] +indent_size = 2 +indent_style = space diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..62562b74 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +coverage +node_modules diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..8f51db36 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,7 @@ +{ + "rules": { + "eol-last": "error", + "indent": ["error", 2, { "SwitchCase": 1 }], + "no-trailing-spaces": "error" + } +} diff --git a/.travis.yml b/.travis.yml index d343742f..0835c242 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ before_install: - "npm config set shrinkwrap false" # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" + - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint" # Update Node.js modules - "test ! -d node_modules || npm prune" - "test ! -d node_modules || npm rebuild" @@ -27,5 +28,6 @@ script: # Run test script, depending on istanbul install - "test ! -z $(npm -ps ls istanbul) || npm test" - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" + - "test -z $(npm -ps ls eslint) || npm run-script lint" after_script: - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" diff --git a/package.json b/package.json index 0983b1b6..7e8527d8 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.3", + "eslint": "3.19.0", "express": "4.15.4", "istanbul": "0.4.5", "mocha": "2.5.3", @@ -38,6 +39,7 @@ "node": ">= 0.8.0" }, "scripts": { + "lint": "eslint .", "test": "mocha --check-leaks --bail --no-exit --reporter spec test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --no-exit --reporter dot test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --no-exit --reporter spec test/" diff --git a/session/cookie.js b/session/cookie.js index 60ef22af..13142ccc 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -96,7 +96,7 @@ Cookie.prototype = { get data() { return { - originalMaxAge: this.originalMaxAge + originalMaxAge: this.originalMaxAge , expires: this._expires , secure: this.secure , httpOnly: this.httpOnly diff --git a/test/session.js b/test/session.js index 241eb5f6..5f49e352 100644 --- a/test/session.js +++ b/test/session.js @@ -652,17 +652,17 @@ describe('session()', function(){ describe('when disabled', function(){ before(function () { - function setup (req) { - req.secure = req.headers['x-secure'] + function setup (req) { + req.secure = req.headers['x-secure'] ? JSON.parse(req.headers['x-secure']) : undefined - } + } - function respond (req, res) { - res.end(String(req.secure)) - } + function respond (req, res) { + res.end(String(req.secure)) + } - this.server = createServer(setup, { proxy: false, cookie: { secure: true }}, respond) + this.server = createServer(setup, { proxy: false, cookie: { secure: true }}, respond) }) it('should not trust X-Forwarded-Proto', function(done){ @@ -685,17 +685,17 @@ describe('session()', function(){ describe('when unspecified', function(){ before(function () { - function setup (req) { - req.secure = req.headers['x-secure'] + function setup (req) { + req.secure = req.headers['x-secure'] ? JSON.parse(req.headers['x-secure']) : undefined - } + } - function respond (req, res) { - res.end(String(req.secure)) - } + function respond (req, res) { + res.end(String(req.secure)) + } - this.server = createServer(setup, { cookie: { secure: true }}, respond) + this.server = createServer(setup, { cookie: { secure: true }}, respond) }) it('should not trust X-Forwarded-Proto', function(done){ From 68e210d1c5f21bd7469d0792e6cd67a6235b358b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Sep 2017 01:03:44 -0400 Subject: [PATCH 438/766] deps: parseurl@~1.3.2 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 10f83635..ac479a6c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,9 @@ unreleased ========== + * deps: parseurl@~1.3.2 + - perf: reduce overhead for full URLs + - perf: unroll the "fast-path" `RegExp` * deps: uid-safe@~2.1.5 - perf: remove only trailing `=` diff --git a/package.json b/package.json index 7e8527d8..bc33066b 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "debug": "2.6.8", "depd": "~1.1.1", "on-headers": "~1.0.1", - "parseurl": "~1.3.1", + "parseurl": "~1.3.2", "uid-safe": "~2.1.5", "utils-merge": "1.0.0" }, From 44ee0467e3de21b2666d41682543cf384282224a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Sep 2017 01:08:06 -0400 Subject: [PATCH 439/766] docs: remove trailing newline in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1708a938..aa947c61 100644 --- a/README.md +++ b/README.md @@ -632,7 +632,7 @@ and other multi-core embedded devices). [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session [express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 -[![โ˜…][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url] +[![โ˜…][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url] A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines). From f24d228cbc3b86de661c23cd268276309bf370a2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Sep 2017 01:12:33 -0400 Subject: [PATCH 440/766] lint: run eslint against README --- .travis.yml | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0835c242..fb3f15d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ before_install: - "npm config set shrinkwrap false" # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint" + - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-plugin-markdown" # Update Node.js modules - "test ! -d node_modules || npm prune" - "test ! -d node_modules || npm rebuild" diff --git a/package.json b/package.json index bc33066b..81e76f6f 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "after": "0.8.2", "cookie-parser": "1.4.3", "eslint": "3.19.0", + "eslint-plugin-markdown": "1.0.0-beta.6", "express": "4.15.4", "istanbul": "0.4.5", "mocha": "2.5.3", @@ -39,7 +40,7 @@ "node": ">= 0.8.0" }, "scripts": { - "lint": "eslint .", + "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --check-leaks --bail --no-exit --reporter spec test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --no-exit --reporter dot test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --no-exit --reporter spec test/" From d190faac7e428e5e735187b48b940efbb312aa93 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Sep 2017 22:08:48 -0400 Subject: [PATCH 441/766] deps: utils-merge@1.0.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index ac479a6c..c8c432e2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,7 @@ unreleased - perf: unroll the "fast-path" `RegExp` * deps: uid-safe@~2.1.5 - perf: remove only trailing `=` + * deps: utils-merge@1.0.1 1.15.5 / 2017-08-02 =================== diff --git a/package.json b/package.json index 81e76f6f..b23fc5f2 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "on-headers": "~1.0.1", "parseurl": "~1.3.2", "uid-safe": "~2.1.5", - "utils-merge": "1.0.0" + "utils-merge": "1.0.1" }, "devDependencies": { "after": "0.8.2", From 6cf886d080b3fe5b114951fca1711fccf891a715 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Sep 2017 22:10:30 -0400 Subject: [PATCH 442/766] deps: debug@2.6.9 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index c8c432e2..9af687ac 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * deps: debug@2.6.9 * deps: parseurl@~1.3.2 - perf: reduce overhead for full URLs - perf: unroll the "fast-path" `RegExp` diff --git a/package.json b/package.json index b23fc5f2..07a6617c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.8", + "debug": "2.6.9", "depd": "~1.1.1", "on-headers": "~1.0.1", "parseurl": "~1.3.2", From d4344fb0ca1839f0585723942516981415b07c9c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Sep 2017 14:59:57 -0400 Subject: [PATCH 443/766] build: express@4.15.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07a6617c..7132ef8f 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "1.4.3", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "express": "4.15.4", + "express": "4.15.5", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 89fd7156129210f2b0c350afcbdf226665a8328c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Sep 2017 15:02:08 -0400 Subject: [PATCH 444/766] 1.15.6 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9af687ac..a82e8395 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.15.6 / 2017-09-26 +=================== * deps: debug@2.6.9 * deps: parseurl@~1.3.2 diff --git a/package.json b/package.json index 7132ef8f..58b89282 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.5", + "version": "1.15.6", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 1bcf69ee657d8c24d1a7b3064f406f4977434e6c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Dec 2017 18:08:25 -0500 Subject: [PATCH 445/766] build: Node.js@6.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fb3f15d4..518ec0db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.11" + - "6.12" - "7.10" - "8.4" sudo: false From 5bf7287982e4370f8b91f62a4ab989d1b5a3742a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Dec 2017 18:09:02 -0500 Subject: [PATCH 446/766] build: Node.js@8.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 518ec0db..843dce60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.12" - "7.10" - - "8.4" + - "8.9" sudo: false cache: directories: From 2afda1118f514cc954685a80853b059d6374f234 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Dec 2017 18:10:28 -0500 Subject: [PATCH 447/766] build: express@4.16.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 58b89282..c4a2f129 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "1.4.3", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "express": "4.15.5", + "express": "4.16.2", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 5c04910e1a10a7ca4cdeb05f4e4d5d43e9533e0c Mon Sep 17 00:00:00 2001 From: Nfer Zhuang Date: Fri, 8 Dec 2017 20:17:55 -0600 Subject: [PATCH 448/766] lint: simplify ternary secure check closes #528 closes #530 --- index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/index.js b/index.js index 175fb234..3c2a5df9 100644 --- a/index.js +++ b/index.js @@ -609,10 +609,7 @@ function issecure(req, trustProxy) { // no explicit trust; try req.secure from express if (trustProxy !== true) { - var secure = req.secure; - return typeof secure === 'boolean' - ? secure - : false; + return req.secure === true } // read the proto from x-forwarded-proto header From 881f2874931e9ad6084081ecdb6a791a456e4c6b Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 11 Oct 2017 20:56:40 +0530 Subject: [PATCH 449/766] docs: add couchdb-expression to the list of session stores closes #514 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index aa947c61..c526f51f 100644 --- a/README.md +++ b/README.md @@ -595,6 +595,11 @@ and other multi-core embedded devices). [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 +[![โ˜…][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store. + +[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression +[couchdb-expression-image]: https://img.shields.io/github/stars/tkshnwesper/couchdb-expression.svg?label=%E2%98%85 + [![โ˜…][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store. [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store From 36eaf353e86510c402a345b9608a562796a551a2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 19 Dec 2017 18:49:00 -0500 Subject: [PATCH 450/766] deps: crc@3.5.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index a82e8395..dfdb26db 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: crc@3.5.0 + 1.15.6 / 2017-09-26 =================== diff --git a/package.json b/package.json index c4a2f129..fdaae0db 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "cookie": "0.3.1", "cookie-signature": "1.0.6", - "crc": "3.4.4", + "crc": "3.5.0", "debug": "2.6.9", "depd": "~1.1.1", "on-headers": "~1.0.1", From a432c82804fadeb3f6a3137a536ce71d36e496db Mon Sep 17 00:00:00 2001 From: Alexander Jank Date: Mon, 25 Dec 2017 19:20:21 +0100 Subject: [PATCH 451/766] docs: add restsession to the list of session stores closes #536 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c526f51f..2a3102cf 100644 --- a/README.md +++ b/README.md @@ -690,6 +690,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store [nedb-session-store-image]: https://img.shields.io/github/stars/JamesMGreene/nedb-session-store.svg?label=%E2%98%85 +[![โ˜…][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API + +[restsession-url]: https://www.npmjs.com/package/restsession +[restsession-image]: https://img.shields.io/github/stars/jankal/restsession.svg?label=%E2%98%85 + [![โ˜…][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). [sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect From 251d1b4094fb8b773221b2a92b581242b1c8e598 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 18:51:11 -0500 Subject: [PATCH 452/766] docs: remove gratipay badge --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 2a3102cf..22c10da1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] -[![Gratipay][gratipay-image]][gratipay-url] ## Installation @@ -762,5 +761,3 @@ app.get('/bar', function (req, res, next) { [coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master [downloads-image]: https://img.shields.io/npm/dm/express-session.svg [downloads-url]: https://npmjs.org/package/express-session -[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg -[gratipay-url]: https://gratipay.com/dougwilson/ From cf15ee924e5f06d33895e49f6e338abfa4e4df80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20Ar=C4=B1l=C4=B1k?= Date: Wed, 20 Dec 2017 09:20:10 +0300 Subject: [PATCH 453/766] docs: add sessionstore to the list of session stores closes #532 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 22c10da1..deac6026 100644 --- a/README.md +++ b/README.md @@ -709,6 +709,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb [session-rethinkdb-image]: https://img.shields.io/github/stars/llambda/session-rethinkdb.svg?label=%E2%98%85 +[![โ˜…][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases. + +[sessionstore-url]: https://www.npmjs.com/package/sessionstore +[sessionstore-image]: https://img.shields.io/github/stars/adrai/sessionstore.svg?label=%E2%98%85 + ## Example A simple example using `express-session` to store page views for a user. From 70f3c2bd45dfbae7351088bcd64aaed07eb1965d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 18:55:10 -0500 Subject: [PATCH 454/766] build: support Node.js 9.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 843dce60..2c39382e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ node_js: - "6.12" - "7.10" - "8.9" + - "9.3" sudo: false cache: directories: From c720066af13d1719609096f7a24d850de9b39550 Mon Sep 17 00:00:00 2001 From: GochoMugo Date: Sun, 22 Oct 2017 20:30:39 +0300 Subject: [PATCH 455/766] docs: document req.session.cookie.originalMaxAge closes #516 closes #517 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index deac6026..ff64240f 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,11 @@ to its original value. req.session.cookie.maxAge // => 30000 ``` +#### Cookie.originalMaxAge + +The `req.session.cookie.originalMaxAge` property returns the original +`maxAge` (time-to-live), in milliseconds, of the session cookie. + ### req.sessionID To get the ID of the loaded session, access the request property From 2bb2860794a8516cb4f223119588afd8d29fe13d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 7 Jan 2018 22:09:36 -0500 Subject: [PATCH 456/766] lint: only declare one variable per var --- .eslintrc | 3 ++- index.js | 10 +++++----- session/cookie.js | 2 +- session/session.js | 3 ++- session/store.js | 3 ++- test/session.js | 9 +++++---- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.eslintrc b/.eslintrc index 8f51db36..bca8da4b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,7 @@ "rules": { "eol-last": "error", "indent": ["error", 2, { "SwitchCase": 1 }], - "no-trailing-spaces": "error" + "no-trailing-spaces": "error", + "one-var": ["error", { "initialized": "never" }] } } diff --git a/index.js b/index.js index 3c2a5df9..ca4bc635 100644 --- a/index.js +++ b/index.js @@ -17,15 +17,15 @@ var cookie = require('cookie'); var crc = require('crc').crc32; var debug = require('debug')('express-session'); var deprecate = require('depd')('express-session'); +var onHeaders = require('on-headers') var parseUrl = require('parseurl'); +var signature = require('cookie-signature') var uid = require('uid-safe').sync - , onHeaders = require('on-headers') - , signature = require('cookie-signature') +var Cookie = require('./session/cookie') +var MemoryStore = require('./session/memory') var Session = require('./session/session') - , MemoryStore = require('./session/memory') - , Cookie = require('./session/cookie') - , Store = require('./session/store') +var Store = require('./session/store') // environment diff --git a/session/cookie.js b/session/cookie.js index 13142ccc..05183294 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -11,8 +11,8 @@ * Module dependencies. */ +var cookie = require('cookie') var merge = require('utils-merge') - , cookie = require('cookie'); /** * Initialize a new `Cookie` with the given `options`. diff --git a/session/session.js b/session/session.js index 2eacde60..fee7608c 100644 --- a/session/session.js +++ b/session/session.js @@ -87,7 +87,8 @@ defineMethod(Session.prototype, 'save', function save(fn) { defineMethod(Session.prototype, 'reload', function reload(fn) { var req = this.req - , store = this.req.sessionStore; + var store = this.req.sessionStore + store.get(this.id, function(err, sess){ if (err) return fn(err); if (!sess) return fn(new Error('failed to load session')); diff --git a/session/store.js b/session/store.js index 387469c5..00f3ac41 100644 --- a/session/store.js +++ b/session/store.js @@ -85,7 +85,8 @@ Store.prototype.load = function(sid, fn){ Store.prototype.createSession = function(req, sess){ var expires = sess.cookie.expires - , orig = sess.cookie.originalMaxAge; + var orig = sess.cookie.originalMaxAge + sess.cookie = new Cookie(sess.cookie); if ('string' == typeof expires) sess.cookie.expires = new Date(expires); sess.cookie.originalMaxAge = orig; diff --git a/test/session.js b/test/session.js index 5f49e352..44d0a868 100644 --- a/test/session.js +++ b/test/session.js @@ -3,16 +3,17 @@ process.env.NO_DEPRECATION = 'express-session'; var after = require('after') var assert = require('assert') +var cookieParser = require('cookie-parser') var express = require('express') - , request = require('supertest') - , cookieParser = require('cookie-parser') - , session = require('../') - , Cookie = require('../session/cookie') var fs = require('fs') var http = require('http') var https = require('https') +var request = require('supertest') +var session = require('../') var util = require('util') +var Cookie = require('../session/cookie') + var min = 60 * 1000; describe('session()', function(){ From 112efaf885bacdfaaa19a2e8c2338beeec519471 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 7 Jan 2018 22:30:47 -0500 Subject: [PATCH 457/766] Use safe-buffer for improved Buffer API --- HISTORY.md | 1 + index.js | 3 ++- package.json | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index dfdb26db..153bc6e0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Use `safe-buffer` for improved Buffer API * deps: crc@3.5.0 1.15.6 / 2017-09-26 diff --git a/index.js b/index.js index ca4bc635..f3dfcfd0 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,7 @@ * @private */ +var Buffer = require('safe-buffer').Buffer var cookie = require('cookie'); var crc = require('crc').crc32; var debug = require('debug')('express-session'); @@ -281,7 +282,7 @@ function session(options) { if (!isNaN(contentLength) && contentLength > 0) { // measure chunk chunk = !Buffer.isBuffer(chunk) - ? new Buffer(chunk, encoding) + ? Buffer.from(chunk, encoding) : chunk; encoding = undefined; diff --git a/package.json b/package.json index fdaae0db..6c1d8633 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "depd": "~1.1.1", "on-headers": "~1.0.1", "parseurl": "~1.3.2", + "safe-buffer": "5.1.1", "uid-safe": "~2.1.5", "utils-merge": "1.0.1" }, From 7ff103893a3e26ae0e8c478bbab8c4919fd78855 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 25 Jan 2018 19:09:36 -0500 Subject: [PATCH 458/766] deps: depd@~1.1.2 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 153bc6e0..5655351f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,8 @@ unreleased * Use `safe-buffer` for improved Buffer API * deps: crc@3.5.0 + * deps: depd@~1.1.2 + - perf: remove argument reassignment 1.15.6 / 2017-09-26 =================== diff --git a/package.json b/package.json index 6c1d8633..8aa22424 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.6", "crc": "3.5.0", "debug": "2.6.9", - "depd": "~1.1.1", + "depd": "~1.1.2", "on-headers": "~1.0.1", "parseurl": "~1.3.2", "safe-buffer": "5.1.1", From 336ad96e34cca1e38a01fe9ca13f3e4523acfc06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20G=C3=B3mez=20Matarrodona?= Date: Sun, 21 Jan 2018 19:58:32 +0100 Subject: [PATCH 459/766] docs: add session-pouchdb-store to the list of session stores closes #542 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ff64240f..086e8157 100644 --- a/README.md +++ b/README.md @@ -709,6 +709,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-file-store-url]: https://www.npmjs.com/package/session-file-store [session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 +[![โ˜…][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization. + +[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store +[session-pouchdb-store-image]: https://img.shields.io/github/stars/solzimer/session-pouchdb-store.svg?label=%E2%98%85 + [![โ˜…][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb From 7068f9416c8ca7631b34547a23c10c1cd270eb7f Mon Sep 17 00:00:00 2001 From: Matthew Canham Date: Sun, 4 Feb 2018 15:24:05 +1300 Subject: [PATCH 460/766] docs: add @google-cloud/connect-datastore to the list of session stores closes #552 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 086e8157..2c290ce8 100644 --- a/README.md +++ b/README.md @@ -526,6 +526,11 @@ and other multi-core embedded devices). [connect-datacache-url]: https://www.npmjs.com/package/connect-datacache [connect-datacache-image]: https://img.shields.io/github/stars/adriantanasa/connect-datacache.svg?label=%E2%98%85 +[![โ˜…][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store. + +[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore +[@google-cloud/connect-datastore-image]: https://img.shields.io/github/stars/GoogleCloudPlatform/cloud-datastore-session-node.svg?label=%E2%98%85 + [![โ˜…][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module. [connect-db2-url]: https://www.npmjs.com/package/connect-db2 From 4b32125c5c655a612cda5518f9a604ac55b990c8 Mon Sep 17 00:00:00 2001 From: William Grasel Date: Fri, 9 Mar 2018 18:43:31 -0300 Subject: [PATCH 461/766] docs: add express-session-etcd3 to the list of session stores closes #562 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2c290ce8..f8ecf179 100644 --- a/README.md +++ b/README.md @@ -663,6 +663,11 @@ a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-e [express-etcd-url]: https://www.npmjs.com/package/express-etcd [express-etcd-image]: https://img.shields.io/github/stars/gildean/express-etcd.svg?label=%E2%98%85 +[![โ˜…][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store. + +[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3 +[express-session-etcd3-image]: https://img.shields.io/github/stars/willgm/express-session-etcd3.svg?label=%E2%98%85 + [![โ˜…][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune) based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB). From 0c605637ef051ec4d77f0a4fa4fac4cae9483c06 Mon Sep 17 00:00:00 2001 From: Hendry Sadrak Date: Wed, 14 Mar 2018 13:08:10 +0200 Subject: [PATCH 462/766] docs: add firestore-store to the list of session stores closes #566 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f8ecf179..a316a018 100644 --- a/README.md +++ b/README.md @@ -668,6 +668,11 @@ a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-e [express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3 [express-session-etcd3-image]: https://img.shields.io/github/stars/willgm/express-session-etcd3.svg?label=%E2%98%85 +[![โ˜…][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store. + +[firestore-store-url]: https://github.com/hendrysadrak/firestore-store +[firestore-store-image]: https://img.shields.io/github/stars/hendrysadrak/firestore-store.svg?label=%E2%98%85 + [![โ˜…][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune) based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB). From f8d3dec04c679abefd6e5e65196c15e125494d13 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 12:20:26 -0400 Subject: [PATCH 463/766] build: Node.js@6.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2c39382e..f1de0a43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.12" + - "6.13" - "7.10" - "8.9" - "9.3" From ce2b702abc1b2b64731cba8a9519d86a35631ab6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 12:20:52 -0400 Subject: [PATCH 464/766] build: Node.js@8.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f1de0a43..84af9959 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.13" - "7.10" - - "8.9" + - "8.10" - "9.3" sudo: false cache: From 979ab16c44233558849ac3b17599aa819854efe2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 12:21:00 -0400 Subject: [PATCH 465/766] build: Node.js@9.8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 84af9959..cb7fd1d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ node_js: - "6.13" - "7.10" - "8.10" - - "9.3" + - "9.8" sudo: false cache: directories: From 6b6816443feaf93a5b94bd710de50298b5c815d3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 15:05:55 -0400 Subject: [PATCH 466/766] build: express@4.16.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8aa22424..d4a7da50 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "cookie-parser": "1.4.3", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "express": "4.16.2", + "express": "4.16.3", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 082e56effc5dca4834a23a659a99ae71e234748f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 15:25:45 -0400 Subject: [PATCH 467/766] tests: add basic tests for Cookie object --- package.json | 6 ++--- test/cookie.js | 55 +++++++++++++++++++++++++++++++++++++++++++++ test/session.js | 2 -- test/support/env.js | 2 ++ 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 test/cookie.js create mode 100644 test/support/env.js diff --git a/package.json b/package.json index d4a7da50..2407632d 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ }, "scripts": { "lint": "eslint --plugin markdown --ext js,md .", - "test": "mocha --check-leaks --bail --no-exit --reporter spec test/", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --no-exit --reporter dot test/", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --no-exit --reporter spec test/" + "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --check-leaks --no-exit --reporter dot test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --check-leaks --no-exit --reporter spec test/" } } diff --git a/test/cookie.js b/test/cookie.js new file mode 100644 index 00000000..51b248bc --- /dev/null +++ b/test/cookie.js @@ -0,0 +1,55 @@ + +var assert = require('assert') +var Cookie = require('../session/cookie') + +describe('new Cookie()', function () { + it('should create a new cookie object', function () { + assert.equal(typeof new Cookie(), 'object') + }) + + it('should default expires to null', function () { + var cookie = new Cookie() + assert.strictEqual(cookie.expires, null) + }) + + it('should default httpOnly to true', function () { + var cookie = new Cookie() + assert.strictEqual(cookie.httpOnly, true) + }) + + it('should default path to "/"', function () { + var cookie = new Cookie() + assert.strictEqual(cookie.path, '/') + }) + + it('should default maxAge to null', function () { + var cookie = new Cookie() + assert.strictEqual(cookie.maxAge, null) + }) + + describe('with options', function () { + it('should create a new cookie object', function () { + assert.equal(typeof new Cookie({}), 'object') + }) + + it('should set expires', function () { + var expires = new Date() + var cookie = new Cookie({ expires: expires }) + + assert.strictEqual(cookie.expires, expires) + assert.notStrictEqual(cookie.maxAge, null) + }) + + it('should set httpOnly', function () { + var cookie = new Cookie({ httpOnly: false }) + + assert.strictEqual(cookie.httpOnly, false) + }) + + it('should set path', function () { + var cookie = new Cookie({ path: '/foo' }) + + assert.strictEqual(cookie.path, '/foo') + }) + }) +}) diff --git a/test/session.js b/test/session.js index 44d0a868..a6e0e5cc 100644 --- a/test/session.js +++ b/test/session.js @@ -1,6 +1,4 @@ -process.env.NO_DEPRECATION = 'express-session'; - var after = require('after') var assert = require('assert') var cookieParser = require('cookie-parser') diff --git a/test/support/env.js b/test/support/env.js new file mode 100644 index 00000000..fba1bd89 --- /dev/null +++ b/test/support/env.js @@ -0,0 +1,2 @@ + +process.env.NO_DEPRECATION = 'express-session'; From efdde800ef78e1880f14106f2b54d84521d407bc Mon Sep 17 00:00:00 2001 From: Void Date: Wed, 24 Jan 2018 03:45:11 +0400 Subject: [PATCH 468/766] Add type check to new Cookie(options) closes #544 --- session/cookie.js | 10 +++++++++- test/cookie.js | 7 +++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/session/cookie.js b/session/cookie.js index 05183294..edac988f 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -26,7 +26,15 @@ var Cookie = module.exports = function Cookie(options) { this.path = '/'; this.maxAge = null; this.httpOnly = true; - if (options) merge(this, options); + + if (options) { + if (typeof options !== 'object') { + throw new TypeError('argument options must be a object') + } + + merge(this, options) + } + this.originalMaxAge = undefined == this.originalMaxAge ? this.maxAge : this.originalMaxAge; diff --git a/test/cookie.js b/test/cookie.js index 51b248bc..ee1df956 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -32,6 +32,13 @@ describe('new Cookie()', function () { assert.equal(typeof new Cookie({}), 'object') }) + it('should reject non-objects', function () { + assert.throws(function () { new Cookie(42) }, /argument options/) + assert.throws(function () { new Cookie('foo') }, /argument options/) + assert.throws(function () { new Cookie(true) }, /argument options/) + assert.throws(function () { new Cookie(function () {}) }, /argument options/) + }) + it('should set expires', function () { var expires = new Date() var cookie = new Cookie({ expires: expires }) From befa6b5c8869d90362485b62cd5815afc1bc330a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 16:17:13 -0400 Subject: [PATCH 469/766] tests: add additional supertest helper --- test/session.js | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/test/session.js b/test/session.js index a6e0e5cc..2555e4a6 100644 --- a/test/session.js +++ b/test/session.js @@ -474,19 +474,14 @@ describe('session()', function(){ .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - var val = sid(res) - assert.ok(val) store.clear(function (err) { if (err) return done(err) request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) - .expect(200, 'session 2', function (err, res) { - if (err) return done(err) - assert.notEqual(sid(res), val) - done() - }) + .expect(shouldSetCookieToDifferentSessionId(res)) + .expect(200, 'session 2', done) }) }) }) @@ -512,6 +507,7 @@ describe('session()', function(){ .get('/') .set('Cookie', 'sessid=' + val) .expect(shouldSetCookie('sessid')) + .expect(shouldSetCookieToDifferentSessionId(val)) .expect(200, 'session created', done) }) }) @@ -578,18 +574,13 @@ describe('session()', function(){ .expect(shouldSetCookie('connect.sid')) .expect(200, 'session 1', function (err, res) { if (err) return done(err) - var val = sid(res) - assert.ok(val) setTimeout(function () { request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) - .expect(200, 'session 2', function (err, res) { - if (err) return done(err) - assert.notEqual(sid(res), val) - done() - }) + .expect(shouldSetCookieToDifferentSessionId(sid(res))) + .expect(200, 'session 2', done) }, 15) }) }) @@ -1545,16 +1536,12 @@ describe('session()', function(){ .expect(shouldSetCookie('connect.sid')) .expect(200, function (err, res) { if (err) return done(err) - var id = sid(res) request(server) .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) - .expect(200, 'false', function (err, res) { - if (err) return done(err) - assert.notEqual(sid(res), id) - done(); - }); + .expect(shouldSetCookieToDifferentSessionId(sid(res))) + .expect(200, 'false', done) }); }) }) @@ -2223,6 +2210,12 @@ function shouldSetCookie (name) { } } +function shouldSetCookieToDifferentSessionId (id) { + return function (res) { + assert.notEqual(sid(res), id) + } +} + function shouldSetCookieToExpireIn (name, delta) { return function (res) { var header = cookie(res) @@ -2290,10 +2283,12 @@ function shouldSetSessionInStore(store) { } } -function sid(res) { - var match = /^[^=]+=s%3A([^;\.]+)[\.;]/.exec(cookie(res)) - var val = match ? match[1] : undefined - return val +function sid (res) { + var header = cookie(res) + var data = header && parseSetCookie(header) + var value = data && unescape(data.value) + var sid = value && value.substring(2, value.indexOf('.')) + return sid || undefined } function writePatch (res) { From a8f3e459adfa0e798b9d68a3d43eb30ca95d2693 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Mar 2018 20:58:04 -0400 Subject: [PATCH 470/766] Use "Set-Cookie" as cookie header name for compatibility fixes #449 --- HISTORY.md | 1 + index.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 5655351f..996baae3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Use `safe-buffer` for improved Buffer API + * Use `Set-Cookie` as cookie header name for compatibility * deps: crc@3.5.0 * deps: depd@~1.1.2 - perf: remove argument reassignment diff --git a/index.js b/index.js index f3dfcfd0..d547e504 100644 --- a/index.js +++ b/index.js @@ -635,10 +635,10 @@ function setcookie(res, name, val, secret, options) { debug('set-cookie %s', data); - var prev = res.getHeader('set-cookie') || []; + var prev = res.getHeader('Set-Cookie') || [] var header = Array.isArray(prev) ? prev.concat(data) : [prev, data]; - res.setHeader('set-cookie', header) + res.setHeader('Set-Cookie', header) } /** From 73e9c4f1ac5000fedc15708f54971a463473b052 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 29 Mar 2018 11:54:50 -0400 Subject: [PATCH 471/766] build: Node.js@4.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cb7fd1d0..59d34a8a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.8" + - "4.9" - "5.12" - "6.13" - "7.10" From 82a5ffbc15b5590117fc4a4949d68d5a904d541b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 29 Mar 2018 11:55:01 -0400 Subject: [PATCH 472/766] build: Node.js@6.14 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 59d34a8a..95cc19d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.9" - "5.12" - - "6.13" + - "6.14" - "7.10" - "8.10" - "9.8" From efcec428ff641256beea0619459fddde287f5c48 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 29 Mar 2018 11:55:11 -0400 Subject: [PATCH 473/766] build: Node.js@8.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 95cc19d0..94865ec7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.14" - "7.10" - - "8.10" + - "8.11" - "9.8" sudo: false cache: From 4f6198f19081f7c0765d1f4542118fde64cde3cb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 29 Mar 2018 11:55:17 -0400 Subject: [PATCH 474/766] build: Node.js@9.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 94865ec7..21f2fe73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ node_js: - "6.14" - "7.10" - "8.11" - - "9.8" + - "9.10" sudo: false cache: directories: From 71230d637b12d7c197ac899c2189731650cba89d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 1 Apr 2018 14:25:14 -0400 Subject: [PATCH 475/766] lint: catch mixed tabs and spaces --- .eslintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc b/.eslintrc index bca8da4b..6c53531a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,7 @@ "rules": { "eol-last": "error", "indent": ["error", 2, { "SwitchCase": 1 }], + "no-mixed-spaces-and-tabs": "error", "no-trailing-spaces": "error", "one-var": ["error", { "initialized": "never" }] } From 104725ebcb1c8ef9a242ea18577d1f34885974a0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 1 Apr 2018 14:33:45 -0400 Subject: [PATCH 476/766] tests: add missing tests for "name" option --- test/session.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/session.js b/test/session.js index 2555e4a6..560be20b 100644 --- a/test/session.js +++ b/test/session.js @@ -880,6 +880,22 @@ describe('session()', function(){ }) }) + describe('name option', function () { + it('should default to "connect.sid"', function (done) { + request(createServer()) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should set the cookie name', function (done) { + request(createServer({ name: 'session_id' })) + .get('/') + .expect(shouldSetCookie('session_id')) + .expect(200, done) + }) + }) + describe('rolling option', function(){ it('should default to false', function(done){ var server = createServer(null, function (req, res) { From 7af7dfafc8203c5dabfa51c1a89d4a7c80b627b0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 15 Jun 2018 23:40:02 -0400 Subject: [PATCH 477/766] deps: safe-buffer@5.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2407632d..5affdc34 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "depd": "~1.1.2", "on-headers": "~1.0.1", "parseurl": "~1.3.2", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "uid-safe": "~2.1.5", "utils-merge": "1.0.1" }, From b33dad018e462ad386aa6db678bc5da2df3d423f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jun 2018 00:10:02 -0400 Subject: [PATCH 478/766] build: use yaml eslint configuration --- .eslintrc | 9 --------- .eslintrc.yml | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.yml diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 6c53531a..00000000 --- a/.eslintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "rules": { - "eol-last": "error", - "indent": ["error", 2, { "SwitchCase": 1 }], - "no-mixed-spaces-and-tabs": "error", - "no-trailing-spaces": "error", - "one-var": ["error", { "initialized": "never" }] - } -} diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..e48de5ea --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,7 @@ +root: true +rules: + eol-last: error + indent: ["error", 2, { "SwitchCase": 1 }] + no-mixed-spaces-and-tabs: error + no-trailing-spaces: error + one-var: ["error", { "initialized": "never" }] From 513f6b94943c8a8af5d540d4e831e996892ab074 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jun 2018 00:14:10 -0400 Subject: [PATCH 479/766] build: Node.js@9.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 21f2fe73..b0ed83c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ node_js: - "6.14" - "7.10" - "8.11" - - "9.10" + - "9.11" sudo: false cache: directories: From 32e10cf331a8f7f9c277175d383e70e935a3330c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jun 2018 00:19:01 -0400 Subject: [PATCH 480/766] build: support Node.js 10.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b0ed83c6..36ea4cd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ node_js: - "7.10" - "8.11" - "9.11" + - "10.4" sudo: false cache: directories: From ee11428d487439fb68a906b26c5f6f32370a57cf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 21 Sep 2018 10:02:11 -0400 Subject: [PATCH 481/766] build: restructure Travis CI build steps --- .travis.yml | 54 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36ea4cd4..b7d031b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,18 +18,50 @@ cache: directories: - node_modules before_install: - # Skip updating shrinkwrap / lock - - "npm config set shrinkwrap false" + # Configure npm + - | + # Skip updating shrinkwrap / lock + npm config set shrinkwrap false # Setup Node.js version-specific dependencies - - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-plugin-markdown" + - | + # eslint for linting + # - remove on Node.js < 4 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ + grep -E '^eslint(-|$)' | \ + xargs npm rm --save-dev + fi + - | + # istanbul for coverage + # - remove on Node.js < 0.10 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + npm rm --save-dev istanbul + fi # Update Node.js modules - - "test ! -d node_modules || npm prune" - - "test ! -d node_modules || npm rebuild" + - | + # Prune & rebuild node_modules + if [[ -d node_modules ]]; then + npm prune + npm rebuild + fi + script: - # Run test script, depending on istanbul install - - "test ! -z $(npm -ps ls istanbul) || npm test" - - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" - - "test -z $(npm -ps ls eslint) || npm run-script lint" + - | + # Run test script, depending on istanbul install + if [[ -n "$(npm -ps ls istanbul)" ]]; then + npm run-script test-travis + else + npm test + fi + - | + # Run linting, depending on eslint install + if [[ -n "$(npm -ps ls eslint)" ]]; then + npm run-script lint + fi after_script: - - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" + - | + # Upload coverage to coveralls, if exists + if [[ -f ./coverage/lcov.info ]]; then + npm install --save-dev coveralls@2 + coveralls < ./coverage/lcov.info + fi From d1dd3664096d4b0755be30943897daee333a36fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 21 Sep 2018 18:02:21 -0400 Subject: [PATCH 482/766] build: mocha@5.2.0 --- .travis.yml | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b7d031b9..111c4d37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,15 @@ before_install: if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then npm rm --save-dev istanbul fi + - | + # mocha for testing + # - use 2.x for Node.js < 0.10 + # - use 3.x for Node.js < 6 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + npm install --save-dev mocha@2.5.3 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + npm install --save-dev mocha@3.5.3 + fi # Update Node.js modules - | # Prune & rebuild node_modules diff --git a/package.json b/package.json index 5affdc34..efe989af 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "eslint-plugin-markdown": "1.0.0-beta.6", "express": "4.16.3", "istanbul": "0.4.5", - "mocha": "2.5.3", + "mocha": "5.2.0", "supertest": "1.1.0" }, "files": [ From 66cfdf163ca021fd1f985d87180ba355f18c7b0f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 21 Sep 2018 18:40:02 -0400 Subject: [PATCH 483/766] build: supertest@3.3.0 --- .travis.yml | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 111c4d37..f97db6fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,6 +46,15 @@ before_install: elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then npm install --save-dev mocha@3.5.3 fi + - | + # supertest for http calls + # - use 1.1.0 for Node.js < 0.10 + # - use 2.0.0 for Node.js < 4 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + npm install --save-dev supertest@1.1.0 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + npm install --save-dev supertest@2.0.0 + fi # Update Node.js modules - | # Prune & rebuild node_modules diff --git a/package.json b/package.json index efe989af..bb4f41a2 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "express": "4.16.3", "istanbul": "0.4.5", "mocha": "5.2.0", - "supertest": "1.1.0" + "supertest": "3.3.0" }, "files": [ "session/", From 57d8e81f1a486d9a1817f6295e422c85e2e18c34 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 21 Sep 2018 18:47:01 -0400 Subject: [PATCH 484/766] build: Node.js@8.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f97db6fa..26fc35ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.14" - "7.10" - - "8.11" + - "8.12" - "9.11" - "10.4" sudo: false From 45176f870965505f2715f3e534720a3fce4a1fe2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 21 Sep 2018 18:50:21 -0400 Subject: [PATCH 485/766] build: Node.js@10.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 26fc35ee..ee15ba74 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.12" - "9.11" - - "10.4" + - "10.11" sudo: false cache: directories: From 1ab3e637d6599d45546eaf642aa6c21480b62b29 Mon Sep 17 00:00:00 2001 From: Felix Wu Date: Sun, 2 Sep 2018 00:58:00 +0200 Subject: [PATCH 486/766] docs: add connect-session-firebase to the list of session stores closes #609 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index a316a018..3aa26b22 100644 --- a/README.md +++ b/README.md @@ -592,6 +592,11 @@ and other multi-core embedded devices). [connect-memjs-url]: https://www.npmjs.com/package/connect-memjs [connect-memjs-image]: https://img.shields.io/github/stars/liamdon/connect-memjs.svg?label=%E2%98%85 +[![โ˜…][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/) + +[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase +[connect-session-firebase-image]: https://img.shields.io/github/stars/benweier/connect-session-firebase.svg?label=%E2%98%85 + [![โ˜…][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using [Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. From c846e3e906c85b82e7fedaa82c4f05b605954a4c Mon Sep 17 00:00:00 2001 From: Jonathan Price Date: Wed, 29 Aug 2018 16:20:16 -0700 Subject: [PATCH 487/766] docs: dix typo in readme about "req.session.cookie.maxAge" closes #608 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3aa26b22..fbe3be92 100644 --- a/README.md +++ b/README.md @@ -392,8 +392,8 @@ req.session.cookie.maxAge = hour For example when `maxAge` is set to `60000` (one minute), and 30 seconds has elapsed it will return `30000` until the current request has completed, -at which time `req.session.touch()` is called to reset `req.session.maxAge` -to its original value. +at which time `req.session.touch()` is called to reset +`req.session.cookie.maxAge` to its original value. ```js req.session.cookie.maxAge // => 30000 From 785d094705b4e0a1b9f93c50a3ba7c8f5b32efb6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 24 Sep 2018 10:23:33 -0400 Subject: [PATCH 488/766] tests: use strict equality --- test/cookie.js | 4 ++-- test/session.js | 60 ++++++++++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/test/cookie.js b/test/cookie.js index ee1df956..6f6992c3 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -4,7 +4,7 @@ var Cookie = require('../session/cookie') describe('new Cookie()', function () { it('should create a new cookie object', function () { - assert.equal(typeof new Cookie(), 'object') + assert.strictEqual(typeof new Cookie(), 'object') }) it('should default expires to null', function () { @@ -29,7 +29,7 @@ describe('new Cookie()', function () { describe('with options', function () { it('should create a new cookie object', function () { - assert.equal(typeof new Cookie({}), 'object') + assert.strictEqual(typeof new Cookie({}), 'object') }) it('should reject non-objects', function () { diff --git a/test/session.js b/test/session.js index 560be20b..7435b196 100644 --- a/test/session.js +++ b/test/session.js @@ -16,9 +16,9 @@ var min = 60 * 1000; describe('session()', function(){ it('should export constructors', function(){ - assert.equal(typeof session.Session, 'function') - assert.equal(typeof session.Store, 'function') - assert.equal(typeof session.MemoryStore, 'function') + assert.strictEqual(typeof session.Session, 'function') + assert.strictEqual(typeof session.Store, 'function') + assert.strictEqual(typeof session.MemoryStore, 'function') }) it('should do nothing if req.session exists', function(done){ @@ -62,7 +62,7 @@ describe('session()', function(){ if (err) return done(err) store.length(function (err, len) { if (err) return done(err) - assert.equal(len, 1) + assert.strictEqual(len, 1) done() }) }) @@ -149,7 +149,7 @@ describe('session()', function(){ if (err) return done(err) store.all(function (err, sess) { if (err) return done(err) - assert.equal(Object.keys(sess).length, 2) + assert.strictEqual(Object.keys(sess).length, 2) done() }) } @@ -254,7 +254,7 @@ describe('session()', function(){ if (err) return done(err) store.length(function (err, length) { if (err) return done(err) - assert.equal(length, 0) + assert.strictEqual(length, 0) done() }) }) @@ -280,7 +280,7 @@ describe('session()', function(){ .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) - .expect(function (res) { assert.notEqual(originalExpires, expires(res)); }) + .expect(function (res) { assert.notStrictEqual(originalExpires, expires(res)); }) .expect(200, done); }, (1000 - (Date.now() % 1000) + 200)); }); @@ -416,7 +416,7 @@ describe('session()', function(){ if (err) return done(err) assert.ok(sess, 'session saved to store') var exp = new Date(sess.cookie.expires) - assert.equal(exp.toUTCString(), expires(res)) + assert.strictEqual(exp.toUTCString(), expires(res)) setTimeout(function () { request(server) .get('/') @@ -425,9 +425,9 @@ describe('session()', function(){ if (err) return done(err) store.get(id, function (err, sess) { if (err) return done(err) - assert.equal(res.text, id) + assert.strictEqual(res.text, id) assert.ok(sess, 'session still in store') - assert.notEqual(new Date(sess.cookie.expires).toUTCString(), exp.toUTCString(), 'session cookie expiration updated') + assert.notStrictEqual(new Date(sess.cookie.expires).toUTCString(), exp.toUTCString(), 'session cookie expiration updated') done() }) }) @@ -601,7 +601,7 @@ describe('session()', function(){ setTimeout(function () { store.all(function (err, sess) { if (err) return done(err) - assert.equal(Object.keys(sess).length, 0) + assert.strictEqual(Object.keys(sess).length, 0) done() }) }, 10) @@ -1091,7 +1091,7 @@ describe('session()', function(){ server.on('error', function onerror(err) { assert.ok(err) - assert.equal(err.message, 'boom!') + assert.strictEqual(err.message, 'boom!') cb() }) @@ -1169,7 +1169,7 @@ describe('session()', function(){ server.on('error', function onerror(err) { assert.ok(err) - assert.equal(err.message, 'boom!') + assert.strictEqual(err.message, 'boom!') cb() }) @@ -1283,7 +1283,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - assert.equal(len, 1) + assert.strictEqual(len, 1) request(server) .get('/') .set('Cookie', cookie(res)) @@ -1291,7 +1291,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - assert.equal(len, 1) + assert.strictEqual(len, 1) done(); }); }); @@ -1314,7 +1314,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - assert.equal(len, 1) + assert.strictEqual(len, 1) request(server) .get('/') .set('Cookie', cookie(res)) @@ -1322,7 +1322,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - assert.equal(len, 0) + assert.strictEqual(len, 0) done(); }); }); @@ -1344,7 +1344,7 @@ describe('session()', function(){ if (err) return done(err); store.length(function(err, len){ if (err) return done(err); - assert.equal(len, 0) + assert.strictEqual(len, 0) done(); }); }); @@ -1364,7 +1364,7 @@ describe('session()', function(){ server.on('error', function onerror(err) { assert.ok(err) - assert.equal(err.message, 'boom!') + assert.strictEqual(err.message, 'boom!') cb() }) @@ -1726,7 +1726,7 @@ describe('session()', function(){ if (err) return done(err); store.get(id, function (err, sess) { if (err) return done(err) - assert.notEqual(new Date(sess.cookie.expires).getTime(), exp.getTime()) + assert.notStrictEqual(new Date(sess.cookie.expires).getTime(), exp.getTime()) done() }) }) @@ -2222,13 +2222,13 @@ function shouldSetCookie (name) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(data.name, name, 'should set cookie ' + name) + assert.strictEqual(data.name, name, 'should set cookie ' + name) } } function shouldSetCookieToDifferentSessionId (id) { return function (res) { - assert.notEqual(sid(res), id) + assert.notStrictEqual(sid(res), id) } } @@ -2237,10 +2237,10 @@ function shouldSetCookieToExpireIn (name, delta) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(data.name, name, 'should set cookie ' + name) + assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok(('expires' in data), 'should set cookie with attribute Expires') assert.ok(('date' in res.headers), 'should have a date header') - assert.equal((Date.parse(data.expires) - Date.parse(res.headers.date)), delta, 'should set cookie ' + name + ' to expire in ' + delta + ' ms') + assert.strictEqual((Date.parse(data.expires) - Date.parse(res.headers.date)), delta, 'should set cookie ' + name + ' to expire in ' + delta + ' ms') } } @@ -2249,8 +2249,8 @@ function shouldSetCookieToValue (name, val) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(data.name, name, 'should set cookie ' + name) - assert.equal(data.value, val, 'should set cookie ' + name + ' to ' + val) + assert.strictEqual(data.name, name, 'should set cookie ' + name) + assert.strictEqual(data.value, val, 'should set cookie ' + name + ' to ' + val) } } @@ -2259,7 +2259,7 @@ function shouldSetCookieWithAttribute (name, attrib) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(data.name, name, 'should set cookie ' + name) + assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok((attrib.toLowerCase() in data), 'should set cookie with attribute ' + attrib) } } @@ -2269,9 +2269,9 @@ function shouldSetCookieWithAttributeAndValue (name, attrib, value) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(data.name, name, 'should set cookie ' + name) + assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok((attrib.toLowerCase() in data), 'should set cookie with attribute ' + attrib) - assert.equal(data[attrib.toLowerCase()], value, 'should set cookie with attribute ' + attrib + ' set to ' + value) + assert.strictEqual(data[attrib.toLowerCase()], value, 'should set cookie with attribute ' + attrib + ' set to ' + value) } } @@ -2280,7 +2280,7 @@ function shouldSetCookieWithoutAttribute (name, attrib) { var header = cookie(res) var data = header && parseSetCookie(header) assert.ok(header, 'should have a cookie header') - assert.equal(data.name, name, 'should set cookie ' + name) + assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok(!(attrib.toLowerCase() in data), 'should set cookie without attribute ' + attrib) } } From a6402811c135ad59f75c2e0e365234ccfb25c0b5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 24 Sep 2018 14:13:14 -0400 Subject: [PATCH 489/766] tests: add describe level in "resave option" tests --- test/session.js | 174 +++++++++++++++++++++++++----------------------- 1 file changed, 89 insertions(+), 85 deletions(-) diff --git a/test/session.js b/test/session.js index 7435b196..11607df6 100644 --- a/test/session.js +++ b/test/session.js @@ -993,116 +993,120 @@ describe('session()', function(){ }); }); - it('should force save on unmodified session', function(done){ - var store = new session.MemoryStore() - var server = createServer({ store: store, resave: true }, function (req, res) { - req.session.user = 'bob' - res.end() - }) + describe('when true', function () { + it('should force save on unmodified session', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: true }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(server) - .get('/') - .expect(shouldSetSessionInStore(store)) - .expect(200, function(err, res){ - if (err) return done(err); request(server) .get('/') - .set('Cookie', cookie(res)) .expect(shouldSetSessionInStore(store)) - .expect(200, done); - }); - }); - - it('should prevent save on unmodified session', function(done){ - var store = new session.MemoryStore() - var server = createServer({ store: store, resave: false }, function (req, res) { - req.session.user = 'bob' - res.end() + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetSessionInStore(store)) + .expect(200, done) + }) }) + }) + + describe('when false', function () { + it('should prevent save on unmodified session', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.user = 'bob' + res.end() + }) - request(server) - .get('/') - .expect(shouldSetSessionInStore(store)) - .expect(200, function(err, res){ - if (err) return done(err); request(server) .get('/') - .set('Cookie', cookie(res)) - .expect(shouldNotSetSessionInStore(store)) - .expect(200, done); - }); - }); - - it('should still save modified session', function(done){ - var store = new session.MemoryStore() - var server = createServer({ store: store, resave: false }, function (req, res) { - req.session.count = req.session.count || 0 - req.session.count++ - res.end() + .expect(shouldSetSessionInStore(store)) + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldNotSetSessionInStore(store)) + .expect(200, done) + }) }) - request(server) - .get('/') - .expect(shouldSetSessionInStore(store)) - .expect(200, function(err, res){ - if (err) return done(err); + it('should still save modified session', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.count = req.session.count || 0 + req.session.count++ + res.end() + }) + request(server) .get('/') - .set('Cookie', cookie(res)) .expect(shouldSetSessionInStore(store)) - .expect(200, done); - }); - }); - - it('should detect a "cookie" property as modified', function (done) { - var store = new session.MemoryStore() - var server = createServer({ store: store, resave: false }, function (req, res) { - req.session.user = req.session.user || {} - req.session.user.name = 'bob' - req.session.user.cookie = req.session.user.cookie || 0 - req.session.user.cookie++ - res.end() + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetSessionInStore(store)) + .expect(200, done) + }) }) - request(server) - .get('/') - .expect(shouldSetSessionInStore(store)) - .expect(200, function (err, res) { - if (err) return done(err) + it('should detect a "cookie" property as modified', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.user = req.session.user || {} + req.session.user.name = 'bob' + req.session.user.cookie = req.session.user.cookie || 0 + req.session.user.cookie++ + res.end() + }) + request(server) .get('/') - .set('Cookie', cookie(res)) .expect(shouldSetSessionInStore(store)) - .expect(200, done) + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetSessionInStore(store)) + .expect(200, done) + }) }) - }) - it('should pass session touch error', function (done) { - var cb = after(2, done) - var store = new session.MemoryStore() - var server = createServer({ store: store, resave: false }, function (req, res) { - req.session.hit = true - res.end('session saved') - }) + it('should pass session touch error', function (done) { + var cb = after(2, done) + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + req.session.hit = true + res.end('session saved') + }) - store.touch = function touch(sid, sess, callback) { - callback(new Error('boom!')) - } + store.touch = function touch (sid, sess, callback) { + callback(new Error('boom!')) + } - server.on('error', function onerror(err) { - assert.ok(err) - assert.strictEqual(err.message, 'boom!') - cb() - }) + server.on('error', function onerror (err) { + assert.ok(err) + assert.strictEqual(err.message, 'boom!') + cb() + }) - request(server) - .get('/') - .expect(200, 'session saved', function (err, res) { - if (err) return cb(err) request(server) .get('/') - .set('Cookie', cookie(res)) - .end(cb) + .expect(200, 'session saved', function (err, res) { + if (err) return cb(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .end(cb) + }) }) }) }); From bcad89859fffe5e379dfa56d4ef82e19ca187111 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 24 Sep 2018 22:18:56 -0400 Subject: [PATCH 490/766] Fix issue where "resave: false" may not save altered sessions --- HISTORY.md | 2 +- index.js | 13 ++++++++++--- package.json | 1 - test/session.js | 33 ++++++++++++++++++++++++--------- 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 996baae3..b490c4ef 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,9 +1,9 @@ unreleased ========== + * Fix issue where `resave: false` may not save altered sessions * Use `safe-buffer` for improved Buffer API * Use `Set-Cookie` as cookie header name for compatibility - * deps: crc@3.5.0 * deps: depd@~1.1.2 - perf: remove argument reassignment diff --git a/index.js b/index.js index d547e504..42639913 100644 --- a/index.js +++ b/index.js @@ -15,7 +15,7 @@ var Buffer = require('safe-buffer').Buffer var cookie = require('cookie'); -var crc = require('crc').crc32; +var crypto = require('crypto') var debug = require('debug')('express-session'); var deprecate = require('depd')('express-session'); var onHeaders = require('on-headers') @@ -578,14 +578,21 @@ function getcookie(req, name, secrets) { */ function hash(sess) { - return crc(JSON.stringify(sess, function (key, val) { + // serialize + var str = JSON.stringify(sess, function (key, val) { // ignore sess.cookie property if (this === sess && key === 'cookie') { return } return val - })) + }) + + // hash + return crypto + .createHash('sha1') + .update(str, 'utf8') + .digest('hex') } /** diff --git a/package.json b/package.json index bb4f41a2..c20cde2e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "dependencies": { "cookie": "0.3.1", "cookie-signature": "1.0.6", - "crc": "3.5.0", "debug": "2.6.9", "depd": "~1.1.2", "on-headers": "~1.0.1", diff --git a/test/session.js b/test/session.js index 11607df6..6862ccc4 100644 --- a/test/session.js +++ b/test/session.js @@ -1038,22 +1038,37 @@ describe('session()', function(){ it('should still save modified session', function (done) { var store = new session.MemoryStore() - var server = createServer({ store: store, resave: false }, function (req, res) { - req.session.count = req.session.count || 0 - req.session.count++ - res.end() + var server = createServer({ resave: false, store: store }, function (req, res) { + if (req.method === 'PUT') { + req.session.token = req.url.substr(1) + } + res.end('token=' + (req.session.token || '')) }) request(server) - .get('/') + .put('/w6RHhwaA') + .expect(200) .expect(shouldSetSessionInStore(store)) - .expect(200, function (err, res) { + .expect('token=w6RHhwaA') + .end(function (err, res) { if (err) return done(err) + var sess = cookie(res) request(server) .get('/') - .set('Cookie', cookie(res)) - .expect(shouldSetSessionInStore(store)) - .expect(200, done) + .set('Cookie', sess) + .expect(200) + .expect(shouldNotSetSessionInStore(store)) + .expect('token=w6RHhwaA') + .end(function (err) { + if (err) return done(err) + request(server) + .put('/zfQ3rzM3') + .set('Cookie', sess) + .expect(200) + .expect(shouldSetSessionInStore(store)) + .expect('token=zfQ3rzM3') + .end(done) + }) }) }) From 582fa28d431d310b091ae452b90d3796c87f2da1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 17 Oct 2018 23:02:21 -0400 Subject: [PATCH 491/766] build: express@4.16.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c20cde2e..3a22636b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cookie-parser": "1.4.3", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "express": "4.16.3", + "express": "4.16.4", "istanbul": "0.4.5", "mocha": "5.2.0", "supertest": "3.3.0" From 88a45366996a7a8481e1f3a94355104b1f910efa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 17 Oct 2018 23:09:11 -0400 Subject: [PATCH 492/766] build: Node.js@10.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ee15ba74..5a16d310 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.12" - "9.11" - - "10.11" + - "10.12" sudo: false cache: directories: From df72a66a0e2ee18b76821ed99233b4acc7b4e462 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 27 Oct 2018 13:03:28 -0400 Subject: [PATCH 493/766] deps: depd@~2.0.0 --- HISTORY.md | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b490c4ef..c91d901a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,7 +4,9 @@ unreleased * Fix issue where `resave: false` may not save altered sessions * Use `safe-buffer` for improved Buffer API * Use `Set-Cookie` as cookie header name for compatibility - * deps: depd@~1.1.2 + * deps: depd@~2.0.0 + - Replace internal `eval` usage with `Function` constructor + - Use instance methods on `process` to check for listeners - perf: remove argument reassignment 1.15.6 / 2017-09-26 diff --git a/package.json b/package.json index 3a22636b..6c8ac6b9 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "~2.0.0", "on-headers": "~1.0.1", "parseurl": "~1.3.2", "safe-buffer": "5.1.2", From 5fcc3e91591783cfadfe682c3adc1ce5b9d782d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chyl=C3=BD?= Date: Mon, 8 Oct 2018 21:11:03 +0200 Subject: [PATCH 494/766] docs: add tch-nedb-session to the list of session stores closes #617 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index fbe3be92..cd52f9b9 100644 --- a/README.md +++ b/README.md @@ -744,6 +744,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [sessionstore-url]: https://www.npmjs.com/package/sessionstore [sessionstore-image]: https://img.shields.io/github/stars/adrai/sessionstore.svg?label=%E2%98%85 +[![โ˜…][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB. + +[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session +[tch-nedb-session-image]: https://img.shields.io/github/stars/tomaschyly/NeDBSession.svg?label=%E2%98%85 + ## Example A simple example using `express-session` to store page views for a user. From d943e3764aaf037aeb3c5e6abd3657a8977fa36d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Nov 2018 00:12:30 -0500 Subject: [PATCH 495/766] build: Node.js@10.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5a16d310..e84788db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.12" - "9.11" - - "10.12" + - "10.13" sudo: false cache: directories: From 2f971f95ca087e2fe4670aa3c6a35a94108f1cd0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Nov 2018 00:43:11 -0500 Subject: [PATCH 496/766] docs: switch badges to badgen --- README.md | 116 +++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index cd52f9b9..2be21d2c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # express-session -[![NPM Version][npm-image]][npm-url] -[![NPM Downloads][downloads-image]][downloads-url] +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][node-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] @@ -492,262 +492,262 @@ module. Please make a PR to add additional modules :) [![โ˜…][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/). [aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store -[aerospike-session-store-image]: https://img.shields.io/github/stars/aerospike/aerospike-session-store-expressjs.svg?label=%E2%98%85 +[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85 [![โ˜…][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. [cassandra-store-url]: https://www.npmjs.com/package/cassandra-store -[cassandra-store-image]: https://img.shields.io/github/stars/webcc/cassandra-store.svg?label=%E2%98%85 +[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85 [![โ˜…][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2 and other multi-core embedded devices). [cluster-store-url]: https://www.npmjs.com/package/cluster-store -[cluster-store-image]: https://img.shields.io/github/stars/coolaj86/cluster-store.svg?label=%E2%98%85 +[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85 [![โ˜…][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store. [connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables -[connect-azuretables-image]: https://img.shields.io/github/stars/mike-goodwin/connect-azuretables.svg?label=%E2%98%85 +[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85 [![โ˜…][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store. [connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store -[connect-cloudant-store-image]: https://img.shields.io/github/stars/adriantanasa/connect-cloudant-store.svg?label=%E2%98%85 +[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85 [![โ˜…][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase -[connect-couchbase-image]: https://img.shields.io/github/stars/christophermina/connect-couchbase.svg?label=%E2%98%85 +[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85 [![โ˜…][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store. [connect-datacache-url]: https://www.npmjs.com/package/connect-datacache -[connect-datacache-image]: https://img.shields.io/github/stars/adriantanasa/connect-datacache.svg?label=%E2%98%85 +[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85 [![โ˜…][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store. [@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore -[@google-cloud/connect-datastore-image]: https://img.shields.io/github/stars/GoogleCloudPlatform/cloud-datastore-session-node.svg?label=%E2%98%85 +[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85 [![โ˜…][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module. [connect-db2-url]: https://www.npmjs.com/package/connect-db2 -[connect-db2-image]: https://img.shields.io/github/stars/wallali/connect-db2.svg?label=%E2%98%85 +[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85 [![โ˜…][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store. [connect-dynamodb-url]: https://github.com/ca98am79/connect-dynamodb -[connect-dynamodb-image]: https://img.shields.io/github/stars/ca98am79/connect-dynamodb.svg?label=%E2%98%85 +[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85 [![โ˜…][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store. [connect-loki-url]: https://www.npmjs.com/package/connect-loki -[connect-loki-image]: https://img.shields.io/github/stars/Requarks/connect-loki.svg?label=%E2%98%85 +[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85 [![โ˜…][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store. [connect-ml-url]: https://www.npmjs.com/package/connect-ml -[connect-ml-image]: https://img.shields.io/github/stars/bluetorch/connect-ml.svg?label=%E2%98%85 +[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85 [![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. [connect-mssql-url]: https://www.npmjs.com/package/connect-mssql -[connect-mssql-image]: https://img.shields.io/github/stars/patriksimek/connect-mssql.svg?label=%E2%98%85 +[connect-mssql-image]: https://badgen.net/github/stars/patriksimek/connect-mssql?label=%E2%98%85 [![โ˜…][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store. [connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb -[connect-monetdb-image]: https://img.shields.io/github/stars/MonetDB/npm-connect-monetdb.svg?label=%E2%98%85 +[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85 [![โ˜…][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store. [connect-mongo-url]: https://www.npmjs.com/package/connect-mongo -[connect-mongo-image]: https://img.shields.io/github/stars/kcbanner/connect-mongo.svg?label=%E2%98%85 +[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85 [![โ˜…][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB. [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session -[connect-mongodb-session-image]: https://img.shields.io/github/stars/mongodb-js/connect-mongodb-session.svg?label=%E2%98%85 +[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85 [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple -[connect-pg-simple-image]: https://img.shields.io/github/stars/voxpelli/node-connect-pg-simple.svg?label=%E2%98%85 +[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85 [![โ˜…][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store. [connect-redis-url]: https://www.npmjs.com/package/connect-redis -[connect-redis-image]: https://img.shields.io/github/stars/tj/connect-redis.svg?label=%E2%98%85 +[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85 [![โ˜…][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. [connect-memcached-url]: https://www.npmjs.com/package/connect-memcached -[connect-memcached-image]: https://img.shields.io/github/stars/balor/connect-memcached.svg?label=%E2%98%85 +[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85 [![โ˜…][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using [memjs](https://www.npmjs.com/package/memjs) as the memcached client. [connect-memjs-url]: https://www.npmjs.com/package/connect-memjs -[connect-memjs-image]: https://img.shields.io/github/stars/liamdon/connect-memjs.svg?label=%E2%98%85 +[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85 [![โ˜…][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/) [connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase -[connect-session-firebase-image]: https://img.shields.io/github/stars/benweier/connect-session-firebase.svg?label=%E2%98%85 +[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85 [![โ˜…][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using [Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle. [connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex -[connect-session-knex-image]: https://img.shields.io/github/stars/llambda/connect-session-knex.svg?label=%E2%98%85 +[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85 [![โ˜…][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using [Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL. [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize -[connect-session-sequelize-image]: https://img.shields.io/github/stars/mweibel/connect-session-sequelize.svg?label=%E2%98%85 +[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85 [![โ˜…][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store. [couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression -[couchdb-expression-image]: https://img.shields.io/github/stars/tkshnwesper/couchdb-expression.svg?label=%E2%98%85 +[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85 [![โ˜…][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store. [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store -[dynamodb-store-image]: https://img.shields.io/github/stars/rafaelrpinto/dynamodb-store.svg?label=%E2%98%85 +[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85 [![โ˜…][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native [MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module. [express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session -[express-mysql-session-image]: https://img.shields.io/github/stars/chill117/express-mysql-session.svg?label=%E2%98%85 +[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85 [![โ˜…][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native [oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module. [express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session -[express-oracle-session-image]: https://img.shields.io/github/stars/slumber86/express-oracle-session.svg?label=%E2%98%85 +[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85 [![โ˜…][express-sessions-image] express-sessions][express-sessions-url]: A session store supporting both MongoDB and Redis. [express-sessions-url]: https://www.npmjs.com/package/express-sessions -[express-sessions-image]: https://img.shields.io/github/stars/konteck/express-sessions.svg?label=%E2%98%85 +[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85 [![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 -[connect-sqlite3-image]: https://img.shields.io/github/stars/rawberg/connect-sqlite3.svg?label=%E2%98%85 +[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85 [![โ˜…][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service. [documentdb-session-url]: https://www.npmjs.com/package/documentdb-session -[documentdb-session-image]: https://img.shields.io/github/stars/dwhieb/documentdb-session.svg?label=%E2%98%85 +[documentdb-session-image]: https://badgen.net/github/stars/dwhieb/documentdb-session?label=%E2%98%85 [![โ˜…][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. [express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session -[express-nedb-session-image]: https://img.shields.io/github/stars/louischatriot/express-nedb-session.svg?label=%E2%98%85 +[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85 [![โ˜…][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url] A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines). [express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager -[express-session-cache-manager-image]: https://img.shields.io/github/stars/theogravity/express-session-cache-manager.svg?label=%E2%98%85 +[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85 [![โ˜…][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store. [express-session-level-url]: https://www.npmjs.com/package/express-session-level -[express-session-level-image]: https://img.shields.io/github/stars/tgohn/express-session-level.svg?label=%E2%98%85 +[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85 [![โ˜…][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. [express-etcd-url]: https://www.npmjs.com/package/express-etcd -[express-etcd-image]: https://img.shields.io/github/stars/gildean/express-etcd.svg?label=%E2%98%85 +[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85 [![โ˜…][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store. [express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3 -[express-session-etcd3-image]: https://img.shields.io/github/stars/willgm/express-session-etcd3.svg?label=%E2%98%85 +[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85 [![โ˜…][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store. [firestore-store-url]: https://github.com/hendrysadrak/firestore-store -[firestore-store-image]: https://img.shields.io/github/stars/hendrysadrak/firestore-store.svg?label=%E2%98%85 +[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85 [![โ˜…][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune) based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB). [fortune-session-url]: https://www.npmjs.com/package/fortune-session -[fortune-session-image]: https://img.shields.io/github/stars/aliceklipper/fortune-session.svg?label=%E2%98%85 +[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85 [![โ˜…][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client). [hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store -[hazelcast-store-image]: https://img.shields.io/github/stars/jackspaniel/hazelcast-store.svg?label=%E2%98%85 +[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85 [![โ˜…][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store -[level-session-store-image]: https://img.shields.io/github/stars/scriptollc/level-session-store.svg?label=%E2%98%85 +[level-session-store-image]: https://badgen.net/github/stars/scriptollc/level-session-store?label=%E2%98%85 [![โ˜…][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store. [medea-session-store-url]: https://www.npmjs.com/package/medea-session-store -[medea-session-store-image]: https://img.shields.io/github/stars/BenjaminVadant/medea-session-store.svg?label=%E2%98%85 +[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85 [![โ˜…][memorystore-image] memorystore][memorystore-url] A memory session store made for production. [memorystore-url]: https://www.npmjs.com/package/memorystore -[memorystore-image]: https://img.shields.io/github/stars/roccomuso/memorystore.svg?label=%E2%98%85 +[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85 [![โ˜…][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store. [mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store -[mssql-session-store-image]: https://img.shields.io/github/stars/jwathen/mssql-session-store.svg?label=%E2%98%85 +[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85 [![โ˜…][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store. [nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store -[nedb-session-store-image]: https://img.shields.io/github/stars/JamesMGreene/nedb-session-store.svg?label=%E2%98%85 +[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85 [![โ˜…][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API [restsession-url]: https://www.npmjs.com/package/restsession -[restsession-image]: https://img.shields.io/github/stars/jankal/restsession.svg?label=%E2%98%85 +[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85 [![โ˜…][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). [sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect -[sequelstore-connect-image]: https://img.shields.io/github/stars/MattMcFarland/sequelstore-connect.svg?label=%E2%98%85 +[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85 [![โ˜…][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store. [session-file-store-url]: https://www.npmjs.com/package/session-file-store -[session-file-store-image]: https://img.shields.io/github/stars/valery-barysok/session-file-store.svg?label=%E2%98%85 +[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85 [![โ˜…][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization. [session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store -[session-pouchdb-store-image]: https://img.shields.io/github/stars/solzimer/session-pouchdb-store.svg?label=%E2%98%85 +[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85 [![โ˜…][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb -[session-rethinkdb-image]: https://img.shields.io/github/stars/llambda/session-rethinkdb.svg?label=%E2%98%85 +[session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85 [![โ˜…][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases. [sessionstore-url]: https://www.npmjs.com/package/sessionstore -[sessionstore-image]: https://img.shields.io/github/stars/adrai/sessionstore.svg?label=%E2%98%85 +[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85 [![โ˜…][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB. [tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session -[tch-nedb-session-image]: https://img.shields.io/github/stars/tomaschyly/NeDBSession.svg?label=%E2%98%85 +[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85 ## Example @@ -793,11 +793,11 @@ app.get('/bar', function (req, res, next) { [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/express-session.svg +[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master +[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master +[node-url]: https://nodejs.org/en/download +[npm-downloads-image]: https://badgen.net/npm/dm/express-session [npm-url]: https://npmjs.org/package/express-session -[travis-image]: https://img.shields.io/travis/expressjs/session/master.svg +[npm-version-image]: https://badgen.net/npm/v/express-session +[travis-image]: https://badgen.net/travis/expressjs/session/master [travis-url]: https://travis-ci.org/expressjs/session -[coveralls-image]: https://img.shields.io/coveralls/expressjs/session/master.svg -[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master -[downloads-image]: https://img.shields.io/npm/dm/express-session.svg -[downloads-url]: https://npmjs.org/package/express-session From 868c5fb9adc37dd6b2db4520c6c1c60c5875207d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Nov 2018 13:09:27 -0500 Subject: [PATCH 497/766] tests: add maxAge to new Cookie tests --- test/cookie.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/cookie.js b/test/cookie.js index 6f6992c3..dc083e85 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -12,6 +12,11 @@ describe('new Cookie()', function () { assert.strictEqual(cookie.expires, null) }) + it('should default maxAge to null', function () { + var cookie = new Cookie() + assert.strictEqual(cookie.maxAge, null) + }) + it('should default httpOnly to true', function () { var cookie = new Cookie() assert.strictEqual(cookie.httpOnly, true) @@ -53,6 +58,15 @@ describe('new Cookie()', function () { assert.strictEqual(cookie.httpOnly, false) }) + it('should set maxAge', function () { + var maxAge = 60000 + var cookie = new Cookie({ maxAge: maxAge }) + + assert.ok(cookie.expires.getTime() - Date.now() - 1000 <= maxAge) + assert.ok(cookie.expires.getTime() - Date.now() + 1000 >= maxAge) + assert.strictEqual(cookie.maxAge, maxAge) + }) + it('should set path', function () { var cookie = new Cookie({ path: '/foo' }) From 19b4f4ed410b3d045c634a37a218efd843ad4e09 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Nov 2018 13:14:30 -0500 Subject: [PATCH 498/766] tests: reorganize new Cookie options tests --- test/cookie.js | 55 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/test/cookie.js b/test/cookie.js index dc083e85..cac5ef6f 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -44,33 +44,54 @@ describe('new Cookie()', function () { assert.throws(function () { new Cookie(function () {}) }, /argument options/) }) - it('should set expires', function () { - var expires = new Date() - var cookie = new Cookie({ expires: expires }) + describe('expires', function () { + it('should set expires', function () { + var expires = new Date(Date.now() + 60000) + var cookie = new Cookie({ expires: expires }) - assert.strictEqual(cookie.expires, expires) - assert.notStrictEqual(cookie.maxAge, null) + assert.strictEqual(cookie.expires, expires) + }) + + it('should set maxAge', function () { + var expires = new Date(Date.now() + 60000) + var cookie = new Cookie({ expires: expires }) + + assert.ok(expires.getTime() - Date.now() - 1000 <= cookie.maxAge) + assert.ok(expires.getTime() - Date.now() + 1000 >= cookie.maxAge) + }) }) - it('should set httpOnly', function () { - var cookie = new Cookie({ httpOnly: false }) + describe('httpOnly', function () { + it('should set httpOnly', function () { + var cookie = new Cookie({ httpOnly: false }) - assert.strictEqual(cookie.httpOnly, false) + assert.strictEqual(cookie.httpOnly, false) + }) }) - it('should set maxAge', function () { - var maxAge = 60000 - var cookie = new Cookie({ maxAge: maxAge }) + describe('maxAge', function () { + it('should set expires', function () { + var maxAge = 60000 + var cookie = new Cookie({ maxAge: maxAge }) + + assert.ok(cookie.expires.getTime() - Date.now() - 1000 <= maxAge) + assert.ok(cookie.expires.getTime() - Date.now() + 1000 >= maxAge) + }) + + it('should set maxAge', function () { + var maxAge = 60000 + var cookie = new Cookie({ maxAge: maxAge }) - assert.ok(cookie.expires.getTime() - Date.now() - 1000 <= maxAge) - assert.ok(cookie.expires.getTime() - Date.now() + 1000 >= maxAge) - assert.strictEqual(cookie.maxAge, maxAge) + assert.strictEqual(cookie.maxAge, maxAge) + }) }) - it('should set path', function () { - var cookie = new Cookie({ path: '/foo' }) + describe('path', function () { + it('should set path', function () { + var cookie = new Cookie({ path: '/foo' }) - assert.strictEqual(cookie.path, '/foo') + assert.strictEqual(cookie.path, '/foo') + }) }) }) }) From 2cf079688afcce6824da8345935bc20fdb96c5ae Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 5 Nov 2018 13:27:09 -0500 Subject: [PATCH 499/766] tests: add tests for Date as maxAge --- test/cookie.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/cookie.js b/test/cookie.js index cac5ef6f..80409876 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -84,6 +84,15 @@ describe('new Cookie()', function () { assert.strictEqual(cookie.maxAge, maxAge) }) + + it('should accept Date object', function () { + var maxAge = new Date(Date.now() + 60000) + var cookie = new Cookie({ maxAge: maxAge }) + + assert.strictEqual(cookie.expires.getTime(), maxAge.getTime()) + assert.ok(maxAge.getTime() - Date.now() - 1000 <= cookie.maxAge) + assert.ok(maxAge.getTime() - Date.now() + 1000 >= cookie.maxAge) + }) }) describe('path', function () { From 784d7434da9a34a44c7d93959e4b18bf8285d9f1 Mon Sep 17 00:00:00 2001 From: Paul Berg Date: Sat, 31 Mar 2018 20:15:52 +0100 Subject: [PATCH 500/766] Catch invalid cookie.maxAge value earlier closes #432 closes #574 --- HISTORY.md | 1 + session/cookie.js | 4 ++++ test/cookie.js | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index c91d901a..6a775a6c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Catch invalid `cookie.maxAge` value earlier * Fix issue where `resave: false` may not save altered sessions * Use `safe-buffer` for improved Buffer API * Use `Set-Cookie` as cookie header name for compatibility diff --git a/session/cookie.js b/session/cookie.js index edac988f..bf8ee33b 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -77,6 +77,10 @@ Cookie.prototype = { */ set maxAge(ms) { + if (ms && typeof ms !== 'number' && !(ms instanceof Date)) { + throw new TypeError('maxAge must be a number or Date') + } + this.expires = 'number' == typeof ms ? new Date(Date.now() + ms) : ms; diff --git a/test/cookie.js b/test/cookie.js index 80409876..4cca87bb 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -93,6 +93,12 @@ describe('new Cookie()', function () { assert.ok(maxAge.getTime() - Date.now() - 1000 <= cookie.maxAge) assert.ok(maxAge.getTime() - Date.now() + 1000 >= cookie.maxAge) }) + + it('should reject invalid types', function() { + assert.throws(function() { new Cookie({ maxAge: '42' }) }, /maxAge/) + assert.throws(function() { new Cookie({ maxAge: true }) }, /maxAge/) + assert.throws(function() { new Cookie({ maxAge: function () {} }) }, /maxAge/) + }) }) describe('path', function () { From ad717fe9aeaf9af016ab72cdaf25b490ebde8591 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 20 Nov 2018 15:05:13 -0500 Subject: [PATCH 501/766] Remove utils-merge dependency --- HISTORY.md | 1 + package.json | 3 +-- session/cookie.js | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6a775a6c..1e5a3a40 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,7 @@ unreleased * Catch invalid `cookie.maxAge` value earlier * Fix issue where `resave: false` may not save altered sessions + * Remove `utils-merge` dependency * Use `safe-buffer` for improved Buffer API * Use `Set-Cookie` as cookie header name for compatibility * deps: depd@~2.0.0 diff --git a/package.json b/package.json index 6c8ac6b9..03d016eb 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,7 @@ "on-headers": "~1.0.1", "parseurl": "~1.3.2", "safe-buffer": "5.1.2", - "uid-safe": "~2.1.5", - "utils-merge": "1.0.1" + "uid-safe": "~2.1.5" }, "devDependencies": { "after": "0.8.2", diff --git a/session/cookie.js b/session/cookie.js index bf8ee33b..ae7e7d7a 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -12,7 +12,6 @@ */ var cookie = require('cookie') -var merge = require('utils-merge') /** * Initialize a new `Cookie` with the given `options`. @@ -32,7 +31,9 @@ var Cookie = module.exports = function Cookie(options) { throw new TypeError('argument options must be a object') } - merge(this, options) + for (var key in options) { + this[key] = options[key] + } } this.originalMaxAge = undefined == this.originalMaxAge From 15fe12144527ed3ca60781f7993e446e74b5c3e6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 20 Nov 2018 15:33:24 -0500 Subject: [PATCH 502/766] Deprecate setting cookie.maxAge to a Date object --- HISTORY.md | 1 + session/cookie.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 1e5a3a40..d9ca7e60 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Catch invalid `cookie.maxAge` value earlier + * Deprecate setting `cookie.maxAge` to a `Date` object * Fix issue where `resave: false` may not save altered sessions * Remove `utils-merge` dependency * Use `safe-buffer` for improved Buffer API diff --git a/session/cookie.js b/session/cookie.js index ae7e7d7a..1dd9bf95 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -12,6 +12,7 @@ */ var cookie = require('cookie') +var deprecate = require('depd')('express-session') /** * Initialize a new `Cookie` with the given `options`. @@ -82,6 +83,10 @@ Cookie.prototype = { throw new TypeError('maxAge must be a number or Date') } + if (ms instanceof Date) { + deprecate('maxAge as Date; pass number of milliseconds instead') + } + this.expires = 'number' == typeof ms ? new Date(Date.now() + ms) : ms; From a856618f4d7d3f88f1620608acda46485a939f9e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 21 Nov 2018 00:30:28 -0500 Subject: [PATCH 503/766] build: eslint-plugin-markdown@1.0.0-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03d016eb..eed1ff33 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.3", "eslint": "3.19.0", - "eslint-plugin-markdown": "1.0.0-beta.6", + "eslint-plugin-markdown": "1.0.0-rc.1", "express": "4.16.4", "istanbul": "0.4.5", "mocha": "5.2.0", From 0f5913ceb5812f6f24738a776d3502797388e0b7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 21 Nov 2018 00:37:22 -0500 Subject: [PATCH 504/766] build: Node.js@8.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e84788db..361d170e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.14" - "7.10" - - "8.12" + - "8.13" - "9.11" - "10.13" sudo: false From 6a3cf0ec90261faeec48854ceb91be6aced00a4f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 21 Nov 2018 00:56:21 -0500 Subject: [PATCH 505/766] build: support Node.js 11.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 361d170e..0cd58dbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ node_js: - "8.13" - "9.11" - "10.13" + - "11.2" sudo: false cache: directories: From 5508375d95796b402b6c32d710911a86a559ea10 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 22 Jan 2019 23:41:20 -0500 Subject: [PATCH 506/766] build: Node.js@6.16 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0cd58dbe..22cb8b69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.9" - "5.12" - - "6.14" + - "6.16" - "7.10" - "8.13" - "9.11" From 80bf8b28c2f86c560a7840a251635f95ff35f668 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Jan 2019 01:27:10 -0500 Subject: [PATCH 507/766] build: Node.js@8.15 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 22cb8b69..5b2ebd48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.16" - "7.10" - - "8.13" + - "8.15" - "9.11" - "10.13" - "11.2" From dd21b1401eb570514495e8d64ce1c5c371d405da Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Jan 2019 01:32:33 -0500 Subject: [PATCH 508/766] build: Node.js@10.15 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5b2ebd48..7950bb88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.15" - "9.11" - - "10.13" + - "10.15" - "11.2" sudo: false cache: From 73cbcb01162abdb2b4de43bd6390f8c9b6ebf78e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Jan 2019 01:39:03 -0500 Subject: [PATCH 509/766] build: Node.js@11.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7950bb88..33ce5cfd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.15" - "9.11" - "10.15" - - "11.2" + - "11.7" sudo: false cache: directories: From 787721123331bdf122e895762676043aee2386fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 1 Feb 2019 12:09:28 -0500 Subject: [PATCH 510/766] build: supertest@3.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eed1ff33..f8e53c81 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.16.4", "istanbul": "0.4.5", "mocha": "5.2.0", - "supertest": "3.3.0" + "supertest": "3.4.2" }, "files": [ "session/", From a7b66fb94d09fd9f701c836c7af05b0dc711dfb7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 14 Feb 2019 12:50:13 -0500 Subject: [PATCH 511/766] build: Node.js@11.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 33ce5cfd..2a828984 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.15" - "9.11" - "10.15" - - "11.7" + - "11.9" sudo: false cache: directories: From 85c0ff56b71a691d422353b7e46d8dd9c4fd6a68 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 14 Feb 2019 12:54:10 -0500 Subject: [PATCH 512/766] build: fix istanbul/eslint detection in Travis CI --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a828984..0eba9a47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -67,14 +67,14 @@ before_install: script: - | # Run test script, depending on istanbul install - if [[ -n "$(npm -ps ls istanbul)" ]]; then + if npm -ps ls istanbul | grep -q istanbul; then npm run-script test-travis else npm test fi - | # Run linting, depending on eslint install - if [[ -n "$(npm -ps ls eslint)" ]]; then + if npm -ps ls eslint | grep -q eslint; then npm run-script lint fi after_script: From 6e3ff5dffe4ce26c239cb7b5da1d1c797306bdca Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 14 Feb 2019 13:31:54 -0500 Subject: [PATCH 513/766] build: make Travis CI version compare readable --- .travis.yml | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0eba9a47..7f60f4e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,12 @@ cache: directories: - node_modules before_install: + - | + function v () { + tr '.' '\n' <<< "${1}" \ + | awk '{ printf "%03d", $0 }' \ + | sed 's/^0*//' + } # Configure npm - | # Skip updating shrinkwrap / lock @@ -26,34 +32,34 @@ before_install: # Setup Node.js version-specific dependencies - | # eslint for linting - # - remove on Node.js < 4 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '4.0')" ]]; then + # - remove on Node.js < 4 node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ grep -E '^eslint(-|$)' | \ xargs npm rm --save-dev fi - | # istanbul for coverage - # - remove on Node.js < 0.10 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '0.10')" ]]; then + # - remove on Node.js < 0.10 npm rm --save-dev istanbul fi - | # mocha for testing - # - use 2.x for Node.js < 0.10 - # - use 3.x for Node.js < 6 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '0.10')" ]]; then + # - use 2.x for Node.js < 0.10 npm install --save-dev mocha@2.5.3 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + elif [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '6.0')" ]]; then + # - use 3.x for Node.js < 6 npm install --save-dev mocha@3.5.3 fi - | # supertest for http calls - # - use 1.1.0 for Node.js < 0.10 - # - use 2.0.0 for Node.js < 4 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '0.10')" ]]; then + # - use 1.1.0 for Node.js < 0.10 npm install --save-dev supertest@1.1.0 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + elif [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '4.0')" ]]; then + # - use 2.0.0 for Node.js < 4 npm install --save-dev supertest@2.0.0 fi # Update Node.js modules From fee8e68b1d77bf7cf3cba1b588a5cfdd8ccc7656 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 15 Feb 2019 11:49:53 -0500 Subject: [PATCH 514/766] build: eslint-plugin-markdown@1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8e53c81..d473f546 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.3", "eslint": "3.19.0", - "eslint-plugin-markdown": "1.0.0-rc.1", + "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", "istanbul": "0.4.5", "mocha": "5.2.0", From 99288b44c2a1f5057cdd44eb8fb116c41361407c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 15 Feb 2019 11:50:30 -0500 Subject: [PATCH 515/766] build: cookie-parser@1.4.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d473f546..158f6310 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "after": "0.8.2", - "cookie-parser": "1.4.3", + "cookie-parser": "1.4.4", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", From 3602d293b51cf81bf02742b764e32426a0384a56 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Feb 2019 20:03:39 -0500 Subject: [PATCH 516/766] build: Node.js@11.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7f60f4e3..aa29ae70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.15" - "9.11" - "10.15" - - "11.9" + - "11.10" sudo: false cache: directories: From eda02b213370399e0ec21fd141399252075f7ff9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Feb 2019 20:18:02 -0500 Subject: [PATCH 517/766] deps: on-headers@~1.0.2 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d9ca7e60..b21a4b41 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -11,6 +11,8 @@ unreleased - Replace internal `eval` usage with `Function` constructor - Use instance methods on `process` to check for listeners - perf: remove argument reassignment + * deps: on-headers@~1.0.2 + - Fix `res.writeHead` patch missing return value 1.15.6 / 2017-09-26 =================== diff --git a/package.json b/package.json index 158f6310..fc58c2bf 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", - "on-headers": "~1.0.1", + "on-headers": "~1.0.2", "parseurl": "~1.3.2", "safe-buffer": "5.1.2", "uid-safe": "~2.1.5" From 4cbb93f6138c3c6219144637ca648b8580945755 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 28 Feb 2019 22:09:18 -0500 Subject: [PATCH 518/766] build: simplify & speed up logic in Travis CI build steps --- .travis.yml | 69 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index aa29ae70..4a1fd41d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,32 @@ cache: - node_modules before_install: - | + # Setup utility functions + function node_version_lt () { + [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v "${1}")" ]] + } + function npm_module_installed () { + npm -lsp ls | grep -Fq "$(pwd)/node_modules/${1}:${1}@" + } + function npm_remove_module_re () { + node -e ' + fs = require("fs"); + p = JSON.parse(fs.readFileSync("package.json", "utf8")); + r = RegExp(process.argv[1]); + for (k in p.devDependencies) { + if (r.test(k)) delete p.devDependencies[k]; + } + fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); + ' "$@" + } + function npm_use_module () { + node -e ' + fs = require("fs"); + p = JSON.parse(fs.readFileSync("package.json", "utf8")); + p.devDependencies[process.argv[1]] = process.argv[2]; + fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); + ' "$@" + } function v () { tr '.' '\n' <<< "${1}" \ | awk '{ printf "%03d", $0 }' \ @@ -31,36 +57,22 @@ before_install: npm config set shrinkwrap false # Setup Node.js version-specific dependencies - | - # eslint for linting - if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '4.0')" ]]; then - # - remove on Node.js < 4 - node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ - grep -E '^eslint(-|$)' | \ - xargs npm rm --save-dev + # Configure eslint for linting + if node_version_lt '4.0'; then npm_remove_module_re '^eslint(-|$)' fi - | - # istanbul for coverage - if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '0.10')" ]]; then - # - remove on Node.js < 0.10 - npm rm --save-dev istanbul + # Configure istanbul for coverage + if node_version_lt '0.10'; then npm_remove_module_re '^istanbul$' fi - | - # mocha for testing - if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '0.10')" ]]; then - # - use 2.x for Node.js < 0.10 - npm install --save-dev mocha@2.5.3 - elif [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '6.0')" ]]; then - # - use 3.x for Node.js < 6 - npm install --save-dev mocha@3.5.3 + # Configure mocha for testing + if node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' + elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' fi - | - # supertest for http calls - if [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '0.10')" ]]; then - # - use 1.1.0 for Node.js < 0.10 - npm install --save-dev supertest@1.1.0 - elif [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v '4.0')" ]]; then - # - use 2.0.0 for Node.js < 4 - npm install --save-dev supertest@2.0.0 + # Configure supertest for http calls + if node_version_lt '0.10'; then npm_use_module 'supertest' '1.1.0' + elif node_version_lt '4.0' ; then npm_use_module 'supertest' '2.0.0' fi # Update Node.js modules - | @@ -73,15 +85,12 @@ before_install: script: - | # Run test script, depending on istanbul install - if npm -ps ls istanbul | grep -q istanbul; then - npm run-script test-travis - else - npm test + if npm_module_installed 'istanbul'; then npm run-script test-travis + else npm test fi - | # Run linting, depending on eslint install - if npm -ps ls eslint | grep -q eslint; then - npm run-script lint + if npm_module_installed 'eslint'; then npm run-script lint fi after_script: - | From 2f0759cfcb7b6f828754c6cd3983fee06cfe8028 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 28 Feb 2019 22:14:40 -0500 Subject: [PATCH 519/766] build: mocha@6.0.2 --- .travis.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4a1fd41d..09447479 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,6 +68,7 @@ before_install: # Configure mocha for testing if node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' + elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' fi - | # Configure supertest for http calls diff --git a/package.json b/package.json index fc58c2bf..5473f28b 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", "istanbul": "0.4.5", - "mocha": "5.2.0", + "mocha": "6.0.2", "supertest": "3.4.2" }, "files": [ From 3e0d5489f53763899a91395b26b57f1e8f54a8d3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 2 Mar 2019 13:09:20 -0500 Subject: [PATCH 520/766] tests: move some code into support/ --- test/session.js | 82 ++++++-------------------------------- test/support/sync-store.js | 27 +++++++++++++ test/support/utils.js | 42 +++++++++++++++++++ 3 files changed, 81 insertions(+), 70 deletions(-) create mode 100644 test/support/sync-store.js create mode 100644 test/support/utils.js diff --git a/test/session.js b/test/session.js index 6862ccc4..383a3024 100644 --- a/test/session.js +++ b/test/session.js @@ -8,7 +8,8 @@ var http = require('http') var https = require('https') var request = require('supertest') var session = require('../') -var util = require('util') +var SyncStore = require('./support/sync-store') +var utils = require('./support/utils') var Cookie = require('../session/cookie') @@ -1396,7 +1397,7 @@ describe('session()', function(){ describe('res.end patch', function () { it('should correctly handle res.end/res.write patched prior', function (done) { function setup (req, res) { - writePatch(res) + utils.writePatch(res) } function respond (req, res) { @@ -1412,7 +1413,7 @@ describe('session()', function(){ it('should correctly handle res.end/res.write patched after', function (done) { function respond (req, res) { - writePatch(res) + utils.writePatch(res) req.session.hit = true res.write('hello, ') res.end('world') @@ -2185,7 +2186,7 @@ function end(req, res) { function expires (res) { var header = cookie(res) - return header && parseSetCookie(header).expires + return header && utils.parseSetCookie(header).expires } function mountAt (path) { @@ -2197,25 +2198,6 @@ function mountAt (path) { } } -function parseSetCookie (header) { - var match - var pairs = [] - var pattern = /\s*([^=;]+)(?:=([^;]*);?|;|$)/g - - while ((match = pattern.exec(header))) { - pairs.push({ name: match[1], value: match[2] }) - } - - var cookie = pairs.shift() - - for (var i = 0; i < pairs.length; i++) { - match = pairs[i] - cookie[match.name.toLowerCase()] = (match.value || true) - } - - return cookie -} - function shouldNotHaveHeader(header) { return function (res) { assert.ok(!(header.toLowerCase() in res.headers), 'should not have ' + header + ' header') @@ -2239,7 +2221,7 @@ function shouldNotSetSessionInStore(store) { function shouldSetCookie (name) { return function (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.strictEqual(data.name, name, 'should set cookie ' + name) } @@ -2254,7 +2236,7 @@ function shouldSetCookieToDifferentSessionId (id) { function shouldSetCookieToExpireIn (name, delta) { return function (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok(('expires' in data), 'should set cookie with attribute Expires') @@ -2266,7 +2248,7 @@ function shouldSetCookieToExpireIn (name, delta) { function shouldSetCookieToValue (name, val) { return function (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.strictEqual(data.value, val, 'should set cookie ' + name + ' to ' + val) @@ -2276,7 +2258,7 @@ function shouldSetCookieToValue (name, val) { function shouldSetCookieWithAttribute (name, attrib) { return function (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok((attrib.toLowerCase() in data), 'should set cookie with attribute ' + attrib) @@ -2286,7 +2268,7 @@ function shouldSetCookieWithAttribute (name, attrib) { function shouldSetCookieWithAttributeAndValue (name, attrib, value) { return function (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok((attrib.toLowerCase() in data), 'should set cookie with attribute ' + attrib) @@ -2297,7 +2279,7 @@ function shouldSetCookieWithAttributeAndValue (name, attrib, value) { function shouldSetCookieWithoutAttribute (name, attrib) { return function (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) assert.ok(header, 'should have a cookie header') assert.strictEqual(data.name, name, 'should set cookie ' + name) assert.ok(!(attrib.toLowerCase() in data), 'should set cookie without attribute ' + attrib) @@ -2320,48 +2302,8 @@ function shouldSetSessionInStore(store) { function sid (res) { var header = cookie(res) - var data = header && parseSetCookie(header) + var data = header && utils.parseSetCookie(header) var value = data && unescape(data.value) var sid = value && value.substring(2, value.indexOf('.')) return sid || undefined } - -function writePatch (res) { - var _end = res.end - var _write = res.write - var ended = false - - res.end = function end() { - ended = true - return _end.apply(this, arguments) - } - - res.write = function write() { - if (ended) { - throw new Error('write after end') - } - - return _write.apply(this, arguments) - } -} - -function SyncStore () { - session.Store.call(this) - this.sessions = Object.create(null) -} - -util.inherits(SyncStore, session.Store) - -SyncStore.prototype.destroy = function destroy(sid, callback) { - delete this.sessions[sid]; - callback(); -}; - -SyncStore.prototype.get = function get(sid, callback) { - callback(null, JSON.parse(this.sessions[sid])); -}; - -SyncStore.prototype.set = function set(sid, sess, callback) { - this.sessions[sid] = JSON.stringify(sess); - callback(); -}; diff --git a/test/support/sync-store.js b/test/support/sync-store.js new file mode 100644 index 00000000..b45dc9a8 --- /dev/null +++ b/test/support/sync-store.js @@ -0,0 +1,27 @@ +'use strict' + +var session = require('../../') +var util = require('util') + +module.exports = SyncStore + +function SyncStore () { + session.Store.call(this) + this.sessions = Object.create(null) +} + +util.inherits(SyncStore, session.Store) + +SyncStore.prototype.destroy = function destroy (sid, callback) { + delete this.sessions[sid] + callback() +} + +SyncStore.prototype.get = function get (sid, callback) { + callback(null, JSON.parse(this.sessions[sid])) +} + +SyncStore.prototype.set = function set (sid, sess, callback) { + this.sessions[sid] = JSON.stringify(sess) + callback() +} diff --git a/test/support/utils.js b/test/support/utils.js new file mode 100644 index 00000000..0f13ba6a --- /dev/null +++ b/test/support/utils.js @@ -0,0 +1,42 @@ +'use strict' + +module.exports.parseSetCookie = parseSetCookie +module.exports.writePatch = writePatch + +function parseSetCookie (header) { + var match + var pairs = [] + var pattern = /\s*([^=;]+)(?:=([^;]*);?|;|$)/g + + while ((match = pattern.exec(header))) { + pairs.push({ name: match[1], value: match[2] }) + } + + var cookie = pairs.shift() + + for (var i = 0; i < pairs.length; i++) { + match = pairs[i] + cookie[match.name.toLowerCase()] = (match.value || true) + } + + return cookie +} + +function writePatch (res) { + var _end = res.end + var _write = res.write + var ended = false + + res.end = function end () { + ended = true + return _end.apply(this, arguments) + } + + res.write = function write () { + if (ended) { + throw new Error('write after end') + } + + return _write.apply(this, arguments) + } +} From ed8a50f725b2b4a5837b868cae524c424cb4d49b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 5 Mar 2019 23:09:17 -0500 Subject: [PATCH 521/766] build: supertest@4.0.2 --- .travis.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 09447479..eef1707b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,6 +74,7 @@ before_install: # Configure supertest for http calls if node_version_lt '0.10'; then npm_use_module 'supertest' '1.1.0' elif node_version_lt '4.0' ; then npm_use_module 'supertest' '2.0.0' + elif node_version_lt '6.0' ; then npm_use_module 'supertest' '3.4.2' fi # Update Node.js modules - | diff --git a/package.json b/package.json index 5473f28b..e8f866c5 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.16.4", "istanbul": "0.4.5", "mocha": "6.0.2", - "supertest": "3.4.2" + "supertest": "4.0.2" }, "files": [ "session/", From cc5c83abf710c6e9e4d0bb887777b44faefd2251 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 6 Mar 2019 22:08:17 -0500 Subject: [PATCH 522/766] lint: ensure strict equality checks --- .eslintrc.yml | 1 + index.js | 4 ++-- session/cookie.js | 8 ++++---- session/store.js | 12 +++++++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index e48de5ea..0740b11f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,6 +1,7 @@ root: true rules: eol-last: error + eqeqeq: ["error", "always", { "null": "ignore" }] indent: ["error", 2, { "SwitchCase": 1 }] no-mixed-spaces-and-tabs: error no-trailing-spaces: error diff --git a/index.js b/index.js index 42639913..1cd02f6e 100644 --- a/index.js +++ b/index.js @@ -150,7 +150,7 @@ function session(options) { // notify user that this store is not // meant for a production environment /* istanbul ignore next: not tested */ - if ('production' == env && store instanceof MemoryStore) { + if (env === 'production' && store instanceof MemoryStore) { console.warn(warning); } @@ -443,7 +443,7 @@ function session(options) { return false; } - return cookieId != req.sessionID + return cookieId !== req.sessionID ? saveUninitializedSession || isModified(req.session) : rollingSessions || req.session.cookie.expires != null && isModified(req.session); } diff --git a/session/cookie.js b/session/cookie.js index 1dd9bf95..3197d272 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -37,9 +37,9 @@ var Cookie = module.exports = function Cookie(options) { } } - this.originalMaxAge = undefined == this.originalMaxAge - ? this.maxAge - : this.originalMaxAge; + if (this.originalMaxAge === undefined || this.originalMaxAge === null) { + this.originalMaxAge = this.maxAge + } }; /*! @@ -87,7 +87,7 @@ Cookie.prototype = { deprecate('maxAge as Date; pass number of milliseconds instead') } - this.expires = 'number' == typeof ms + this.expires = typeof ms === 'number' ? new Date(Date.now() + ms) : ms; }, diff --git a/session/store.js b/session/store.js index 00f3ac41..baefbf8d 100644 --- a/session/store.js +++ b/session/store.js @@ -85,11 +85,17 @@ Store.prototype.load = function(sid, fn){ Store.prototype.createSession = function(req, sess){ var expires = sess.cookie.expires - var orig = sess.cookie.originalMaxAge + var originalMaxAge = sess.cookie.originalMaxAge sess.cookie = new Cookie(sess.cookie); - if ('string' == typeof expires) sess.cookie.expires = new Date(expires); - sess.cookie.originalMaxAge = orig; + + if (typeof expires === 'string') { + // convert expires to a Date object, + // keeping originalMaxAge intact + sess.cookie.expires = new Date(expires) + sess.cookie.originalMaxAge = originalMaxAge + } + req.session = new Session(req, sess); return req.session; }; From 03aa560b17e0e038050d379b8d0b040ee5255011 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 6 Mar 2019 22:14:43 -0500 Subject: [PATCH 523/766] build: Node.js@6.17 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eef1707b..99eddf67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.9" - "5.12" - - "6.16" + - "6.17" - "7.10" - "8.15" - "9.11" From a7cf57f56bd60878e0067d8c507415e356e36e94 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 6 Mar 2019 22:18:11 -0500 Subject: [PATCH 524/766] build: Node.js@11.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 99eddf67..bcebedef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.15" - "9.11" - "10.15" - - "11.10" + - "11.11" sudo: false cache: directories: From e926b8846d9cfbf092a626dcc866b8055d99cf73 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Apr 2019 18:09:22 -0400 Subject: [PATCH 525/766] build: mocha@6.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8f866c5..0117e2e2 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", "istanbul": "0.4.5", - "mocha": "6.0.2", + "mocha": "6.1.2", "supertest": "4.0.2" }, "files": [ From dc5262a2c83759d54325ab62c2cd657d7d8eb8ec Mon Sep 17 00:00:00 2001 From: ich Date: Sun, 10 Mar 2019 17:01:35 +1000 Subject: [PATCH 526/766] docs: add connect-arango to the list of session stores closes #642 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2be21d2c..5f96d794 100644 --- a/README.md +++ b/README.md @@ -506,6 +506,11 @@ and other multi-core embedded devices). [cluster-store-url]: https://www.npmjs.com/package/cluster-store [cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85 +[![โ˜…][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store. + +[connect-arango-url]: https://www.npmjs.com/package/connect-arango +[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85 + [![โ˜…][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store. [connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables From 6e514a4cc9cb5a683af6f0b75439e5546f7b3dcd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Apr 2019 23:57:02 -0400 Subject: [PATCH 527/766] build: Node.js@11.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bcebedef..c2fd08f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.15" - "9.11" - "10.15" - - "11.11" + - "11.13" sudo: false cache: directories: From 9495367f7cfd750a48cf99b74370d18c1f8930e9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 11 Apr 2019 00:00:37 -0400 Subject: [PATCH 528/766] docs: update badge for level-session-store store --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f96d794..48c1ab1e 100644 --- a/README.md +++ b/README.md @@ -697,7 +697,7 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [![โ˜…][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store. [level-session-store-url]: https://www.npmjs.com/package/level-session-store -[level-session-store-image]: https://badgen.net/github/stars/scriptollc/level-session-store?label=%E2%98%85 +[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85 [![โ˜…][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store. From e77cbfa93fb083209c4973c2bc6113b86bc32dc2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 11 Apr 2019 00:04:56 -0400 Subject: [PATCH 529/766] build: add version script for npm version releases --- package.json | 3 +- scripts/version-history.js | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 scripts/version-history.js diff --git a/package.json b/package.json index 0117e2e2..5d243086 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --check-leaks --no-exit --reporter dot test/", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --check-leaks --no-exit --reporter spec test/" + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --check-leaks --no-exit --reporter spec test/", + "version": "node scripts/version-history.js && git add HISTORY.md" } } diff --git a/scripts/version-history.js b/scripts/version-history.js new file mode 100644 index 00000000..b8a2b0e8 --- /dev/null +++ b/scripts/version-history.js @@ -0,0 +1,63 @@ +'use strict' + +var fs = require('fs') +var path = require('path') + +var HISTORY_FILE_PATH = path.join(__dirname, '..', 'HISTORY.md') +var MD_HEADER_REGEXP = /^====*$/ +var VERSION = process.env.npm_package_version +var VERSION_PLACEHOLDER_REGEXP = /^(?:unreleased|(\d+\.)+x)$/ + +var historyFileLines = fs.readFileSync(HISTORY_FILE_PATH, 'utf-8').split('\n') + +if (!MD_HEADER_REGEXP.test(historyFileLines[1])) { + console.error('Missing header in HISTORY.md') + process.exit(1) +} + +if (!VERSION_PLACEHOLDER_REGEXP.test(historyFileLines[0])) { + console.error('Missing placegolder version in HISTORY.md') + process.exit(1) +} + +if (historyFileLines[0].indexOf('x') !== -1) { + var versionCheckRegExp = new RegExp('^' + historyFileLines[0].replace('x', '.+') + '$') + + if (!versionCheckRegExp.test(VERSION)) { + console.error('Version %s does not match placeholder %s', VERSION, historyFileLines[0]) + process.exit(1) + } +} + +historyFileLines[0] = VERSION + ' / ' + getLocaleDate() +historyFileLines[1] = repeat('=', historyFileLines[0].length) + +fs.writeFileSync(HISTORY_FILE_PATH, historyFileLines.join('\n')) + +function getLocaleDate () { + var now = new Date() + + return zeroPad(now.getFullYear(), 4) + '-' + + zeroPad(now.getMonth() + 1, 2) + '-' + + zeroPad(now.getDate(), 2) +} + +function repeat (str, length) { + var out = '' + + for (var i = 0; i < length; i++) { + out += str + } + + return out +} + +function zeroPad (number, length) { + var num = number.toString() + + while (num.length < length) { + num = '0' + num + } + + return num +} From b1f0984086c8ed15162aa6ce22562ff829bf5ba7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 11 Apr 2019 00:09:18 -0400 Subject: [PATCH 530/766] 1.16.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b21a4b41..aca5825e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.16.0 / 2019-04-10 +=================== * Catch invalid `cookie.maxAge` value earlier * Deprecate setting `cookie.maxAge` to a `Date` object diff --git a/package.json b/package.json index 5d243086..c0787d66 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.15.6", + "version": "1.16.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 1e3fc39a3fc3810772dfa00a7535a710042c42aa Mon Sep 17 00:00:00 2001 From: eol95 Date: Thu, 11 Apr 2019 16:35:27 +0500 Subject: [PATCH 531/766] Fix error passing "data" option to Cookie constructor fixes #648 closes #649 --- HISTORY.md | 5 +++++ session/cookie.js | 4 +++- test/cookie.js | 9 +++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index aca5825e..9eee06f9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix error passing `data` option to `Cookie` constructor + 1.16.0 / 2019-04-10 =================== diff --git a/session/cookie.js b/session/cookie.js index 3197d272..a8b4e570 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -33,7 +33,9 @@ var Cookie = module.exports = function Cookie(options) { } for (var key in options) { - this[key] = options[key] + if (key !== 'data') { + this[key] = options[key] + } } } diff --git a/test/cookie.js b/test/cookie.js index 4cca87bb..b280dff1 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -44,6 +44,15 @@ describe('new Cookie()', function () { assert.throws(function () { new Cookie(function () {}) }, /argument options/) }) + it('should ignore "data" option', function () { + var cookie = new Cookie({ data: { foo: 'bar' }, path: '/foo' }) + + assert.strictEqual(typeof cookie, 'object') + assert.strictEqual(typeof cookie.data, 'object') + assert.strictEqual(cookie.data.path, '/foo') + assert.notStrictEqual(cookie.data.foo, 'bar') + }) + describe('expires', function () { it('should set expires', function () { var expires = new Date(Date.now() + 60000) From 85682a2a56c5bdbed8d7e7cd2cc5e1343c951af6 Mon Sep 17 00:00:00 2001 From: geekjob-ru <47718537+geekjob-ru@users.noreply.github.com> Date: Thu, 21 Feb 2019 22:34:20 +0300 Subject: [PATCH 532/766] Fix uncaught error from bad session data closes #634 --- HISTORY.md | 1 + index.js | 51 ++++++++++++++++++++++++++--------------------- session/memory.js | 18 +++++++++-------- test/session.js | 25 +++++++++++++++++++++++ 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9eee06f9..e58674b8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Fix error passing `data` option to `Cookie` constructor + * Fix uncaught error from bad session data 1.16.0 / 2019-04-10 =================== diff --git a/index.js b/index.js index 1cd02f6e..24221b48 100644 --- a/index.js +++ b/index.js @@ -363,6 +363,19 @@ function session(options) { wrapmethods(req.session); } + // inflate the session + function inflate (req, sess) { + store.createSession(req, sess) + originalId = req.sessionID + originalHash = hash(sess) + + if (!resaveSession) { + savedHash = originalHash + } + + wrapmethods(req.session) + } + // wrap session methods function wrapmethods(sess) { var _reload = sess.reload @@ -460,34 +473,26 @@ function session(options) { debug('fetching %s', req.sessionID); store.get(req.sessionID, function(err, sess){ // error handling - if (err) { + if (err && err.code !== 'ENOENT') { debug('error %j', err); + next(err) + return + } - if (err.code !== 'ENOENT') { - next(err); - return; - } - - generate(); - // no session - } else if (!sess) { - debug('no session found'); - generate(); - // populate req.session - } else { - debug('session found'); - store.createSession(req, sess); - originalId = req.sessionID; - originalHash = hash(sess); - - if (!resaveSession) { - savedHash = originalHash + try { + if (err || !sess) { + debug('no session found') + generate() + } else { + debug('session found') + inflate(req, sess) } - - wrapmethods(req.session); + } catch (e) { + next(e) + return } - next(); + next() }); }; }; diff --git a/session/memory.js b/session/memory.js index 25252b6c..11ed686c 100644 --- a/session/memory.js +++ b/session/memory.js @@ -171,14 +171,16 @@ function getSession(sessionId) { // parse sess = JSON.parse(sess) - var expires = typeof sess.cookie.expires === 'string' - ? new Date(sess.cookie.expires) - : sess.cookie.expires - - // destroy expired session - if (expires && expires <= Date.now()) { - delete this.sessions[sessionId] - return + if (sess.cookie) { + var expires = typeof sess.cookie.expires === 'string' + ? new Date(sess.cookie.expires) + : sess.cookie.expires + + // destroy expired session + if (expires && expires <= Date.now()) { + delete this.sessions[sessionId] + return + } } return sess diff --git a/test/session.js b/test/session.js index 383a3024..437baf0e 100644 --- a/test/session.js +++ b/test/session.js @@ -610,6 +610,31 @@ describe('session()', function(){ }) }) + describe('when session without cookie property in store', function () { + it('should pass error from inflate', function (done) { + var count = 0 + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.num = req.session.num || ++count + res.end('session ' + req.session.num) + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'session 1', function (err, res) { + if (err) return done(err) + store.set(sid(res), { foo: 'bar' }, function (err) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(500, /Cannot read property/, done) + }) + }) + }) + }) + describe('proxy option', function(){ describe('when enabled', function(){ var server From 421bb3f320b2bbbb6f5ff386666ecd574a53fec6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 11 Apr 2019 12:14:05 -0400 Subject: [PATCH 533/766] 1.16.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e58674b8..b842fbe3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.16.1 / 2019-04-11 +=================== * Fix error passing `data` option to `Cookie` constructor * Fix uncaught error from bad session data diff --git a/package.json b/package.json index c0787d66..6e1ef2b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.16.0", + "version": "1.16.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 5d2e4ec6a9241f634e629e0ff4cf5765236ed24d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 21 Apr 2019 18:04:22 -0400 Subject: [PATCH 534/766] build: mocha@6.1.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6e1ef2b9..8cc2d597 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", "istanbul": "0.4.5", - "mocha": "6.1.2", + "mocha": "6.1.4", "supertest": "4.0.2" }, "files": [ From 072f0b11834186791a303d0cb7392d9fc53f7e3d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 21 Apr 2019 18:09:19 -0400 Subject: [PATCH 535/766] deps: parseurl@~1.3.3 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b842fbe3..a5cd3507 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: parseurl@~1.3.3 + 1.16.1 / 2019-04-11 =================== diff --git a/package.json b/package.json index 8cc2d597..60b3df93 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", - "parseurl": "~1.3.2", + "parseurl": "~1.3.3", "safe-buffer": "5.1.2", "uid-safe": "~2.1.5" }, From cc3d51bd87566b4d7dd85fe46537957c9b618608 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Apr 2019 11:47:51 -0400 Subject: [PATCH 536/766] lint: add linter for session store readme list --- README.md | 92 ++++++++++++++++++++--------------------- package.json | 2 +- scripts/lint-readme.js | 93 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 scripts/lint-readme.js diff --git a/README.md b/README.md index 48c1ab1e..7b39aafb 100644 --- a/README.md +++ b/README.md @@ -543,7 +543,7 @@ and other multi-core embedded devices). [![โ˜…][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store. -[connect-dynamodb-url]: https://github.com/ca98am79/connect-dynamodb +[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb [connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85 [![โ˜…][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store. @@ -551,16 +551,22 @@ and other multi-core embedded devices). [connect-loki-url]: https://www.npmjs.com/package/connect-loki [connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85 +[![โ˜…][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. + +[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached +[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85 + +[![โ˜…][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using +[memjs](https://www.npmjs.com/package/memjs) as the memcached client. + +[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs +[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85 + [![โ˜…][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store. [connect-ml-url]: https://www.npmjs.com/package/connect-ml [connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85 -[![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. - -[connect-mssql-url]: https://www.npmjs.com/package/connect-mssql -[connect-mssql-image]: https://badgen.net/github/stars/patriksimek/connect-mssql?label=%E2%98%85 - [![โ˜…][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store. [connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb @@ -576,6 +582,11 @@ and other multi-core embedded devices). [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session [connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85 +[![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. + +[connect-mssql-url]: https://www.npmjs.com/package/connect-mssql +[connect-mssql-image]: https://badgen.net/github/stars/patriksimek/connect-mssql?label=%E2%98%85 + [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple @@ -586,17 +597,6 @@ and other multi-core embedded devices). [connect-redis-url]: https://www.npmjs.com/package/connect-redis [connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85 -[![โ˜…][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. - -[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached -[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85 - -[![โ˜…][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using -[memjs](https://www.npmjs.com/package/memjs) as the memcached client. - -[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs -[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85 - [![โ˜…][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/) [connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase @@ -614,48 +614,48 @@ and other multi-core embedded devices). [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85 +[![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. + +[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 +[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85 + [![โ˜…][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store. [couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression [couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85 +[![โ˜…][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service. + +[documentdb-session-url]: https://www.npmjs.com/package/documentdb-session +[documentdb-session-image]: https://badgen.net/github/stars/dwhieb/documentdb-session?label=%E2%98%85 + [![โ˜…][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store. [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store [dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85 +[![โ˜…][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. + +[express-etcd-url]: https://www.npmjs.com/package/express-etcd +[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85 + [![โ˜…][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native [MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module. [express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session [express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85 +[![โ˜…][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. + +[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session +[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85 + [![โ˜…][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native [oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module. [express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session [express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85 -[![โ˜…][express-sessions-image] express-sessions][express-sessions-url]: A session store supporting both MongoDB and Redis. - -[express-sessions-url]: https://www.npmjs.com/package/express-sessions -[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85 - -[![โ˜…][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store. - -[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 -[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85 - -[![โ˜…][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service. - -[documentdb-session-url]: https://www.npmjs.com/package/documentdb-session -[documentdb-session-image]: https://badgen.net/github/stars/dwhieb/documentdb-session?label=%E2%98%85 - -[![โ˜…][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store. - -[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session -[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85 - [![โ˜…][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url] A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines). @@ -663,24 +663,24 @@ a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-e [express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager [express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85 +[![โ˜…][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store. + +[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3 +[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85 + [![โ˜…][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store. [express-session-level-url]: https://www.npmjs.com/package/express-session-level [express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85 -[![โ˜…][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. - -[express-etcd-url]: https://www.npmjs.com/package/express-etcd -[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85 - -[![โ˜…][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store. +[![โ˜…][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis. -[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3 -[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85 +[express-sessions-url]: https://www.npmjs.com/package/express-sessions +[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85 [![โ˜…][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store. -[firestore-store-url]: https://github.com/hendrysadrak/firestore-store +[firestore-store-url]: https://www.npmjs.com/package/firestore-store [firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85 [![โ˜…][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune) diff --git a/package.json b/package.json index 60b3df93..c6543b84 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "node": ">= 0.8.0" }, "scripts": { - "lint": "eslint --plugin markdown --ext js,md .", + "lint": "eslint --plugin markdown --ext js,md . && node ./scripts/lint-readme.js", "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --check-leaks --no-exit --reporter dot test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --check-leaks --no-exit --reporter spec test/", diff --git a/scripts/lint-readme.js b/scripts/lint-readme.js new file mode 100644 index 00000000..a93129e2 --- /dev/null +++ b/scripts/lint-readme.js @@ -0,0 +1,93 @@ +var assert = require('assert') +var fs = require('fs') +var path = require('path') + +var BADGE_STAR_LINK_REGEXP = /^https:\/\/badgen.net\/github\/stars\/[^/]+\/[^/]+?label=%E2%98%85$/ +var MARKDOWN_LINK_REGEXP = /^\[([^ \]]+)\]: ([^ ]+)$/ +var MARKDOWN_SECTION_REGEXP = /^#+ (.+)$/ +var NEWLINE_REGEXP = /\r?\n/ +var README_PATH = path.join(__dirname, '..', 'README.md') +var README_CONTENTS = fs.readFileSync(README_PATH, 'utf-8') +var STORE_HEADER_REGEXP = /^\[!\[โ˜…\]\[([^ \]]+)\] ([^ \]]+)\]\[([^ \]]+)\](?: .+)?$/ + +var header = null +var lintedStores = false +var section = null +var state = 0 + +README_CONTENTS.split(NEWLINE_REGEXP).forEach(function (line, lineidx) { + section = (MARKDOWN_SECTION_REGEXP.exec(line) || [])[1] || section + + if (section === 'Compatible Session Stores') { + lintedStores = true + + switch (state) { + case 0: // premble + if (line[0] !== '[') break + state = 1 + case 1: // header + var prev = header + + if (!(header = STORE_HEADER_REGEXP.exec(line))) { + expect(lineidx, 'session store header', line) + } else if (prev && prev[2].replace(/^[^/]+\//, '').localeCompare(header[2].replace(/^[^/]+\//, '')) > 0) { + expect(lineidx, (header[2] + ' to be alphabetically after ' + prev[2]), line) + state = 2 + } else { + state = 2 + } + + break + case 2: // blank line + if (line && MARKDOWN_LINK_REGEXP.test(line)) { + expect(lineidx, 'blank line or wrapped description', line) + } else if (line === '') { + state = 3 + } + break + case 3: // url link + var urlLink = MARKDOWN_LINK_REGEXP.exec(line) + + if (!urlLink) { + expect(lineidx, 'link reference', line) + } else if (urlLink[1] !== header[3]) { + expect(lineidx, ('link name of ' + header[3]), line) + } else if (urlLink[2] !== ('https://www.npmjs.com/package/' + header[2])) { + expect(lineidx, ('link url of https://www.npmjs.com/package/' + header[2]), line) + } else { + state = 4 + } + + break + case 4: // image link + var imageLink = MARKDOWN_LINK_REGEXP.exec(line) + + if (!imageLink) { + expect(lineidx, 'link reference', line) + } else if (imageLink[1] !== header[1]) { + expect(lineidx, ('link name of ' + header[1]), line) + } else if (!BADGE_STAR_LINK_REGEXP.test(imageLink[2])) { + expect(lineidx, ('link url to github stars badge'), line) + } else { + state = 5 + } + + break + case 5: // blank line + if (line !== '') { + expect(lineidx, 'blank line after links', line) + } else { + state = 1 + } + break + } + } +}) + +assert.ok(lintedStores, 'Compatible Session Stores section linted') + +function expect (lineidx, message, line) { + console.log('Expected %s on line %d', message, (lineidx + 1)) + console.log(' Got: %s', line) + process.exitCode = 1 +} From 1588ef6c0903469c48355f7a3a867591b7864357 Mon Sep 17 00:00:00 2001 From: Huseyin BABAL Date: Tue, 23 Apr 2019 12:59:55 +0300 Subject: [PATCH 537/766] docs: add connect-hazelcast to the list of session stores closes #654 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 7b39aafb..f89453ae 100644 --- a/README.md +++ b/README.md @@ -546,6 +546,11 @@ and other multi-core embedded devices). [connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb [connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85 +[![โ˜…][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express. + +[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast +[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85 + [![โ˜…][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store. [connect-loki-url]: https://www.npmjs.com/package/connect-loki From 3d5fa06375ea649e37b63dd0202c85e112db4f98 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Apr 2019 14:29:49 -0400 Subject: [PATCH 538/766] build: use nyc for coverage testing --- .eslintignore | 1 + .gitignore | 1 + .travis.yml | 14 ++++++++------ package.json | 6 +++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.eslintignore b/.eslintignore index 62562b74..76b1021d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ +.nyc_output coverage node_modules diff --git a/.gitignore b/.gitignore index 84a48637..207febba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.nyc_output coverage node_modules npm-debug.log diff --git a/.travis.yml b/.travis.yml index c2fd08f1..531f9a6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,16 +60,18 @@ before_install: # Configure eslint for linting if node_version_lt '4.0'; then npm_remove_module_re '^eslint(-|$)' fi - - | - # Configure istanbul for coverage - if node_version_lt '0.10'; then npm_remove_module_re '^istanbul$' - fi - | # Configure mocha for testing if node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' fi + - | + # Configure nyc for coverage + if node_version_lt '0.10'; then npm_remove_module_re '^nyc$' + elif node_version_lt '4.0' ; then npm_use_module 'nyc' '10.3.2' + elif node_version_lt '6.0' ; then npm_use_module 'nyc' '11.9.0' + fi - | # Configure supertest for http calls if node_version_lt '0.10'; then npm_use_module 'supertest' '1.1.0' @@ -97,7 +99,7 @@ script: after_script: - | # Upload coverage to coveralls, if exists - if [[ -f ./coverage/lcov.info ]]; then + if [[ -d .nyc_output ]]; then npm install --save-dev coveralls@2 - coveralls < ./coverage/lcov.info + nyc report --reporter=text-lcov | coveralls fi diff --git a/package.json b/package.json index c6543b84..a40271ee 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", - "istanbul": "0.4.5", "mocha": "6.1.4", + "nyc": "14.0.0", "supertest": "4.0.2" }, "files": [ @@ -41,8 +41,8 @@ "scripts": { "lint": "eslint --plugin markdown --ext js,md . && node ./scripts/lint-readme.js", "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --check-leaks --no-exit --reporter dot test/", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --check-leaks --no-exit --reporter spec test/", + "test-cov": "nyc npm test", + "test-travis": "nyc npm test -- --no-exit", "version": "node scripts/version-history.js && git add HISTORY.md" } } From 268c929fb598a21dc5e4806c310d14039bcacf73 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Apr 2019 14:58:58 -0400 Subject: [PATCH 539/766] build: Node.js@8.16 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 531f9a6a..13c8fdb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.17" - "7.10" - - "8.15" + - "8.16" - "9.11" - "10.15" - "11.13" From 327695e3d1dd4d7a5d3857f2afbb5852b7710213 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Apr 2019 14:59:24 -0400 Subject: [PATCH 540/766] build: Node.js@11.14 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 13c8fdb2..5cc7b7fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.16" - "9.11" - "10.15" - - "11.13" + - "11.14" sudo: false cache: directories: From e0feb046108642d190facf18e59e05ab80213419 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 May 2019 18:30:53 -0400 Subject: [PATCH 541/766] build: support Node.js 12.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 5cc7b7fb..e483a9a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ node_js: - "9.11" - "10.15" - "11.14" + - "12.2" sudo: false cache: directories: From 8d6430e7df82a7b9bd29ca100bbfacc0ed530b67 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 13 May 2019 18:38:08 -0400 Subject: [PATCH 542/766] build: nyc@14.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a40271ee..b03fe961 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.0", "express": "4.16.4", "mocha": "6.1.4", - "nyc": "14.0.0", + "nyc": "14.1.1", "supertest": "4.0.2" }, "files": [ From 969e4c19d8439f2c6a73a9793a8bb08a84c246a3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 4 Jun 2019 19:03:22 -0400 Subject: [PATCH 543/766] build: express@4.17.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b03fe961..19488f15 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "cookie-parser": "1.4.4", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0", - "express": "4.16.4", + "express": "4.17.1", "mocha": "6.1.4", "nyc": "14.1.1", "supertest": "4.0.2" From ad90250d77685890b422990cb274544a3655815f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 4 Jun 2019 19:09:58 -0400 Subject: [PATCH 544/766] build: Node.js@10.16 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e483a9a0..069b7d5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.16" - "9.11" - - "10.15" + - "10.16" - "11.14" - "12.2" sudo: false From 1c75fa049e363449cb52b4aacfed83b95e375356 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 5 Jun 2019 00:01:28 -0400 Subject: [PATCH 545/766] build: Node.js@11.15 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 069b7d5b..485800b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.16" - "9.11" - "10.16" - - "11.14" + - "11.15" - "12.2" sudo: false cache: From fb498ace8946307decc5da5f564cc09ba8227fef Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 5 Jun 2019 00:05:58 -0400 Subject: [PATCH 546/766] build: Node.js@12.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 485800b5..8c857819 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.16" - "11.15" - - "12.2" + - "12.4" sudo: false cache: directories: From bff097ef16ef02bebe0862ac1508c98e2da012e3 Mon Sep 17 00:00:00 2001 From: Ravi van Rooijen Date: Sat, 4 May 2019 02:14:12 +0200 Subject: [PATCH 547/766] docs: add connect-typeorm to the list of session stores closes #658 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f89453ae..97c9bd2f 100644 --- a/README.md +++ b/README.md @@ -624,6 +624,11 @@ and other multi-core embedded devices). [connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3 [connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85 +[![โ˜…][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store. + +[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm +[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85 + [![โ˜…][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store. [couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression From 97fe63cd024e9227f05923d1f65d3c48f6bffdad Mon Sep 17 00:00:00 2001 From: "F. Hinkelmann" Date: Thu, 30 May 2019 04:47:49 -0400 Subject: [PATCH 548/766] docs: add @google-cloud/connect-firestore to the list of session stores closes #665 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 97c9bd2f..60163a70 100644 --- a/README.md +++ b/README.md @@ -546,6 +546,11 @@ and other multi-core embedded devices). [connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb [connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85 +[![โ˜…][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store. + +[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore +[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85 + [![โ˜…][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express. [connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast From 479940afd22a0b939eaee3997f883408d2e41bec Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 12 Jun 2019 00:07:59 -0400 Subject: [PATCH 549/766] tests: add cookie.originalMaxAge tests --- test/session.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/session.js b/test/session.js index 437baf0e..fe503c0a 100644 --- a/test/session.js +++ b/test/session.js @@ -1850,6 +1850,37 @@ describe('session()', function(){ }) }) + describe('.originalMaxAge', function () { + before(function () { + this.server = createServer({ cookie: { maxAge: 2000 } }, function (req, res) { + req.session.hits = (req.session.hits || 0) + 1 + res.end(JSON.stringify(req.session.cookie.originalMaxAge)) + }) + }) + + it('should equal original maxAge', function (done) { + request(this.server) + .get('/') + .expect(200, '2000', done) + }) + + it('should equal original maxAge for all requests', function (done) { + var server = this.server + + request(server) + .get('/') + .expect(200, '2000', function (err, res) { + if (err) return done(err) + setTimeout(function () { + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, '2000', done) + }, 100) + }) + }) + }) + describe('.secure', function(){ var app From 30e23f1343d3912bc3e3715792ee8ddca694e9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janusz=20Bia=C5=82obrzewski?= Date: Thu, 30 May 2019 09:58:08 +0200 Subject: [PATCH 550/766] Fix restoring cookie.originalMaxAge when store returns Date fixes #664 --- HISTORY.md | 1 + session/store.js | 7 ++--- test/session.js | 33 ++++++++++++++++++----- test/support/smart-store.js | 54 +++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 test/support/smart-store.js diff --git a/HISTORY.md b/HISTORY.md index a5cd3507..3d1533ee 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix restoring `cookie.originalMaxAge` when store returns `Date` * deps: parseurl@~1.3.3 1.16.1 / 2019-04-11 diff --git a/session/store.js b/session/store.js index baefbf8d..3793877e 100644 --- a/session/store.js +++ b/session/store.js @@ -90,12 +90,13 @@ Store.prototype.createSession = function(req, sess){ sess.cookie = new Cookie(sess.cookie); if (typeof expires === 'string') { - // convert expires to a Date object, - // keeping originalMaxAge intact + // convert expires to a Date object sess.cookie.expires = new Date(expires) - sess.cookie.originalMaxAge = originalMaxAge } + // keep originalMaxAge intact + sess.cookie.originalMaxAge = originalMaxAge + req.session = new Session(req, sess); return req.session; }; diff --git a/test/session.js b/test/session.js index fe503c0a..1e3b7124 100644 --- a/test/session.js +++ b/test/session.js @@ -8,6 +8,7 @@ var http = require('http') var https = require('https') var request = require('supertest') var session = require('../') +var SmartStore = require('./support/smart-store') var SyncStore = require('./support/sync-store') var utils = require('./support/utils') @@ -1851,21 +1852,39 @@ describe('session()', function(){ }) describe('.originalMaxAge', function () { - before(function () { - this.server = createServer({ cookie: { maxAge: 2000 } }, function (req, res) { - req.session.hits = (req.session.hits || 0) + 1 + it('should equal original maxAge', function (done) { + var server = createServer({ cookie: { maxAge: 2000 } }, function (req, res) { res.end(JSON.stringify(req.session.cookie.originalMaxAge)) }) - }) - it('should equal original maxAge', function (done) { - request(this.server) + request(server) .get('/') .expect(200, '2000', done) }) it('should equal original maxAge for all requests', function (done) { - var server = this.server + var server = createServer({ cookie: { maxAge: 2000 } }, function (req, res) { + res.end(JSON.stringify(req.session.cookie.originalMaxAge)) + }) + + request(server) + .get('/') + .expect(200, '2000', function (err, res) { + if (err) return done(err) + setTimeout(function () { + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, '2000', done) + }, 100) + }) + }) + + it('should equal original maxAge for all requests', function (done) { + var store = new SmartStore() + var server = createServer({ cookie: { maxAge: 2000 }, store: store }, function (req, res) { + res.end(JSON.stringify(req.session.cookie.originalMaxAge)) + }) request(server) .get('/') diff --git a/test/support/smart-store.js b/test/support/smart-store.js new file mode 100644 index 00000000..8b224fdd --- /dev/null +++ b/test/support/smart-store.js @@ -0,0 +1,54 @@ +'use strict' + +var session = require('../../') +var util = require('util') + +/* istanbul ignore next */ +var defer = typeof setImmediate === 'function' + ? setImmediate + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } + +module.exports = SmartStore + +function SmartStore () { + session.Store.call(this) + this.sessions = Object.create(null) +} + +util.inherits(SmartStore, session.Store) + +SmartStore.prototype.destroy = function destroy (sid, callback) { + delete this.sessions[sid] + defer(callback, null) +} + +SmartStore.prototype.get = function get (sid, callback) { + var sess = this.sessions[sid] + + if (!sess) { + return + } + + // parse + sess = JSON.parse(sess) + + if (sess.cookie) { + // expand expires into Date object + sess.cookie.expires = typeof sess.cookie.expires === 'string' + ? new Date(sess.cookie.expires) + : sess.cookie.expires + + // destroy expired session + if (sess.cookie.expires && sess.cookie.expires <= Date.now()) { + delete this.sessions[sid] + sess = null + } + } + + defer(callback, null, sess) +} + +SmartStore.prototype.set = function set (sid, sess, callback) { + this.sessions[sid] = JSON.stringify(sess) + defer(callback, null) +} From 2d54f0dca1506883bebc634fcb7135c2f02c47cd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 12 Jun 2019 01:01:41 -0400 Subject: [PATCH 551/766] 1.16.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 3d1533ee..f12dc39f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.16.2 / 2019-06-12 +=================== * Fix restoring `cookie.originalMaxAge` when store returns `Date` * deps: parseurl@~1.3.3 diff --git a/package.json b/package.json index 19488f15..fffbd49f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.16.1", + "version": "1.16.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 6db8e04b92e18107c59f6eaf4e162bdaabd64f6a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Aug 2019 20:03:10 -0400 Subject: [PATCH 552/766] build: mocha@6.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fffbd49f..6e2af8b8 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0", "express": "4.17.1", - "mocha": "6.1.4", + "mocha": "6.2.0", "nyc": "14.1.1", "supertest": "4.0.2" }, From 2719bef016b4ab5e8013402a5c0c2b13b188c6a2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Aug 2019 20:09:09 -0400 Subject: [PATCH 553/766] build: Node.js@12.8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8c857819..afa837b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.16" - "11.15" - - "12.4" + - "12.8" sudo: false cache: directories: From f75ed7eb6ce16426162d53ae8b588a999d589758 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Aug 2019 20:13:09 -0400 Subject: [PATCH 554/766] build: fix readme lint out of order message --- scripts/lint-readme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/lint-readme.js b/scripts/lint-readme.js index a93129e2..f4c50d76 100644 --- a/scripts/lint-readme.js +++ b/scripts/lint-readme.js @@ -31,7 +31,7 @@ README_CONTENTS.split(NEWLINE_REGEXP).forEach(function (line, lineidx) { if (!(header = STORE_HEADER_REGEXP.exec(line))) { expect(lineidx, 'session store header', line) } else if (prev && prev[2].replace(/^[^/]+\//, '').localeCompare(header[2].replace(/^[^/]+\//, '')) > 0) { - expect(lineidx, (header[2] + ' to be alphabetically after ' + prev[2]), line) + expect(lineidx, (header[2] + ' to be alphabetically before ' + prev[2]), line) state = 2 } else { state = 2 From 8de786571771d465a607f1b421b27dbbf566bbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Rig=C3=A9t?= Date: Wed, 26 Jun 2019 23:13:01 +0200 Subject: [PATCH 555/766] docs: add express-session-rsdb to the list of session stores closes #670 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 60163a70..959287c9 100644 --- a/README.md +++ b/README.md @@ -688,6 +688,11 @@ a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-e [express-session-level-url]: https://www.npmjs.com/package/express-session-level [express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85 +[![โ˜…][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerfull, flat file database. + +[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb +[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85 + [![โ˜…][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis. [express-sessions-url]: https://www.npmjs.com/package/express-sessions From 1684c548b2dcb54c8c38474eae729c7edc54866c Mon Sep 17 00:00:00 2001 From: Scott MacLellan Date: Tue, 16 Jul 2019 10:15:53 -0400 Subject: [PATCH 556/766] deps: cookie@0.4.0 closes #674 --- HISTORY.md | 6 ++++++ README.md | 6 ++++-- package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f12dc39f..1bcd0a17 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: cookie@0.4.0 + - Add `SameSite=None` support + 1.16.2 / 2019-06-12 =================== diff --git a/README.md b/README.md index 959287c9..19047d58 100644 --- a/README.md +++ b/README.md @@ -101,10 +101,11 @@ Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cook - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. - `false` will not set the `SameSite` attribute. - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. + - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie. - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. -More information about the different enforcement levels can be found in the specification -https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1.1 +More information about the different enforcement levels can be found in +[the specification][rfc-6265bis-03-4.1.2.7]. **Note** This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it. @@ -818,6 +819,7 @@ app.get('/bar', function (req, res, next) { [MIT](LICENSE) +[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master [coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master [node-url]: https://nodejs.org/en/download diff --git a/package.json b/package.json index 6e2af8b8..1fad0d98 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", From 10607bdb780204b91a8cf90e4ce27726619b8285 Mon Sep 17 00:00:00 2001 From: Justin Nahin Date: Wed, 10 Jul 2019 03:56:45 -0700 Subject: [PATCH 557/766] deps: safe-buffer@5.2.0 closes #672 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1bcd0a17..559e362c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,7 @@ unreleased * deps: cookie@0.4.0 - Add `SameSite=None` support + * deps: safe-buffer@5.2.0 1.16.2 / 2019-06-12 =================== diff --git a/package.json b/package.json index 1fad0d98..a8f34e4e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "depd": "~2.0.0", "on-headers": "~1.0.2", "parseurl": "~1.3.3", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.0", "uid-safe": "~2.1.5" }, "devDependencies": { From 8731d7bdd9c4f0e455bd594cd16c075d993e4401 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 7 Oct 2019 22:41:19 -0400 Subject: [PATCH 558/766] build: Node.js@12.11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index afa837b3..6eec393b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.16" - "11.15" - - "12.8" + - "12.11" sudo: false cache: directories: From 9c065098eb51a2a540c2f3d744a84b0941b70a56 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 7 Oct 2019 22:43:57 -0400 Subject: [PATCH 559/766] build: mocha@6.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8f34e4e..6d173184 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0", "express": "4.17.1", - "mocha": "6.2.0", + "mocha": "6.2.1", "nyc": "14.1.1", "supertest": "4.0.2" }, From 9a5e31349e4274487d7f75ebe53fa78b3462894b Mon Sep 17 00:00:00 2001 From: fhellwig Date: Tue, 17 Sep 2019 09:36:58 -0400 Subject: [PATCH 560/766] docs: add lowdb-session-store to the list of session stores closes #690 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 19047d58..c9eb012b 100644 --- a/README.md +++ b/README.md @@ -720,6 +720,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [level-session-store-url]: https://www.npmjs.com/package/level-session-store [level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85 +[![โ˜…][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store. + +[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store +[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85 + [![โ˜…][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store. [medea-session-store-url]: https://www.npmjs.com/package/medea-session-store From c32ad191da9abba58e539fe1ce164536c6d65f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Borntr=C3=A4ger?= Date: Tue, 6 Aug 2019 13:07:17 +0200 Subject: [PATCH 561/766] docs: expand description of the rolling option closes #677 --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c9eb012b..a1ed3fa1 100644 --- a/README.md +++ b/README.md @@ -228,15 +228,24 @@ likely need `resave: true`. ##### rolling -Force a session identifier cookie to be set on every response. The expiration +Force the session identifier cookie to be set on every response. The expiration is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration countdown. The default value is `false`. +With this enabled, the session identifier cookie will expire in +[`maxAge`](#cookiemaxage) since the last response was sent instead of in +[`maxAge`](#cookiemaxage) since the session was last modified by the server. + +This is typically used in conjuction with short, non-session-length +[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data +with reduced potentional of it occurring during on going server interactions. + **Note** When this option is set to `true` but the `saveUninitialized` option is set to `false`, the cookie will not be set on a response with an uninitialized -session. +session. This option only modifies the behavior when an existing session was +loaded for the request. ##### saveUninitialized From 4d253405aca773e3e994c0259a3bc658c22430e0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 8 Oct 2019 17:56:31 -0400 Subject: [PATCH 562/766] build: fix coverage reporting --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6eec393b..08d2fea7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -89,8 +89,8 @@ before_install: script: - | - # Run test script, depending on istanbul install - if npm_module_installed 'istanbul'; then npm run-script test-travis + # Run test script, depending on nyc install + if npm_module_installed 'nyc'; then npm run-script test-travis else npm test fi - | From b22384b712fea118f1c3eb5b0d79312ebd25e97c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 10 Oct 2019 22:59:50 -0400 Subject: [PATCH 563/766] 1.17.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 559e362c..ccc03991 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.17.0 / 2019-10-10 +=================== * deps: cookie@0.4.0 - Add `SameSite=None` support diff --git a/package.json b/package.json index 6d173184..82ca06f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.16.2", + "version": "1.17.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 9e1943303b6f7cb2bf83b2d215036bfb12d48065 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 29 Oct 2019 20:03:58 -0400 Subject: [PATCH 564/766] build: eslint-plugin-markdown@1.0.1 --- .travis.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 08d2fea7..d092ada1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,7 +59,7 @@ before_install: # Setup Node.js version-specific dependencies - | # Configure eslint for linting - if node_version_lt '4.0'; then npm_remove_module_re '^eslint(-|$)' + if node_version_lt '6.0'; then npm_remove_module_re '^eslint(-|$)' fi - | # Configure mocha for testing diff --git a/package.json b/package.json index 82ca06f3..a652e78f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.4", "eslint": "3.19.0", - "eslint-plugin-markdown": "1.0.0", + "eslint-plugin-markdown": "1.0.1", "express": "4.17.1", "mocha": "6.2.1", "nyc": "14.1.1", From 3281442df86f6f26f5d2cf9d6038f2d845784585 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 29 Oct 2019 20:08:00 -0400 Subject: [PATCH 565/766] build: mocha@6.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a652e78f..e41e71b1 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.1", "express": "4.17.1", - "mocha": "6.2.1", + "mocha": "6.2.2", "nyc": "14.1.1", "supertest": "4.0.2" }, From 77a3d192ba8303be57e0b5652ceb9516da92f772 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 30 Oct 2019 00:21:06 -0400 Subject: [PATCH 566/766] build: Node.js@10.17 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d092ada1..078ab9a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.16" - "9.11" - - "10.16" + - "10.17" - "11.15" - "12.11" sudo: false From 7d071562ee5db3e00a484b302af40873dbb8e22a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 30 Oct 2019 00:24:55 -0400 Subject: [PATCH 567/766] build: Node.js@12.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 078ab9a5..5b763e29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.17" - "11.15" - - "12.11" + - "12.13" sudo: false cache: directories: From e18fb51d2d403bf3b5bd4e498f621dee4a52db41 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 8 Jan 2020 22:10:48 -0500 Subject: [PATCH 568/766] build: nyc@15.0.0 --- .travis.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5b763e29..c1c97986 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,6 +72,7 @@ before_install: if node_version_lt '0.10'; then npm_remove_module_re '^nyc$' elif node_version_lt '4.0' ; then npm_use_module 'nyc' '10.3.2' elif node_version_lt '6.0' ; then npm_use_module 'nyc' '11.9.0' + elif node_version_lt '8.0' ; then npm_use_module 'nyc' '14.1.1' fi - | # Configure supertest for http calls diff --git a/package.json b/package.json index e41e71b1..e650cdeb 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.1", "express": "4.17.1", "mocha": "6.2.2", - "nyc": "14.1.1", + "nyc": "15.0.0", "supertest": "4.0.2" }, "files": [ From 4ea1ba33bc29b159f03deece1c6489af28f6e901 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Jan 2020 22:34:45 -0500 Subject: [PATCH 569/766] build: mocha@7.0.1 --- .travis.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c1c97986..947febeb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,6 +66,7 @@ before_install: if node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' + elif node_version_lt '8.0' ; then npm_use_module 'mocha' '6.2.2' fi - | # Configure nyc for coverage diff --git a/package.json b/package.json index e650cdeb..44c692e9 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.1", "express": "4.17.1", - "mocha": "6.2.2", + "mocha": "7.0.1", "nyc": "15.0.0", "supertest": "4.0.2" }, From adb11406b7d292b38085879185878164ec201b58 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Jan 2020 22:39:55 -0500 Subject: [PATCH 570/766] build: Node.js@8.17 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 947febeb..d60cfc1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.17" - "7.10" - - "8.16" + - "8.17" - "9.11" - "10.17" - "11.15" From c7849bcc3b4827f7749d722c05fd2157b739ec39 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 28 Jan 2020 22:43:44 -0500 Subject: [PATCH 571/766] build: Node.js@10.18 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d60cfc1e..6f5f0169 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.17" + - "10.18" - "11.15" - "12.13" sudo: false From dfee1fad24d7d837bd99fec181babc35d6b14ae7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 29 Jan 2020 00:03:57 -0500 Subject: [PATCH 572/766] build: Node.js@12.14 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6f5f0169..69074cc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.18" - "11.15" - - "12.13" + - "12.14" sudo: false cache: directories: From 40a64089f00330d8f3b2f3ca9c157df5b68f235b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 29 Jan 2020 00:09:26 -0500 Subject: [PATCH 573/766] build: remove deprecated Travis CI directive --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 69074cc7..fff4bc40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,6 @@ node_js: - "10.18" - "11.15" - "12.14" -sudo: false cache: directories: - node_modules From 0461302973bce4aba82c44f5a15ab388584161a4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 2 Feb 2020 21:49:02 -0500 Subject: [PATCH 574/766] build: support Node.js 13.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fff4bc40..5ec6c661 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ node_js: - "10.18" - "11.15" - "12.14" + - "13.7" cache: directories: - node_modules From 99d21d16c2b344a58b318a2190b2f68899e58c58 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Feb 2020 19:20:24 -0500 Subject: [PATCH 575/766] build: mocha@7.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 44c692e9..6ca5d7da 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.1", "express": "4.17.1", - "mocha": "7.0.1", + "mocha": "7.1.0", "nyc": "15.0.0", "supertest": "4.0.2" }, From e3c04a2691595768b8925107458a158eafcdc2f1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Feb 2020 19:24:44 -0500 Subject: [PATCH 576/766] build: Node.js@13.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5ec6c661..b5855359 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ node_js: - "10.18" - "11.15" - "12.14" - - "13.7" + - "13.9" cache: directories: - node_modules From a3c9dd39b96df5fd668403352a586b1b93e2d3ab Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 2 Mar 2020 20:04:24 -0500 Subject: [PATCH 577/766] build: eslint-plugin-markdown@1.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ca5d7da..c33d5f82 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.4", "eslint": "3.19.0", - "eslint-plugin-markdown": "1.0.1", + "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", "mocha": "7.1.0", "nyc": "15.0.0", From f927fc13e7fda51082990cb1e26c27d0022a1b12 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 2 Mar 2020 20:09:50 -0500 Subject: [PATCH 578/766] build: Node.js@10.19 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b5855359..70e4577f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.18" + - "10.19" - "11.15" - "12.14" - "13.9" From a2b27958a498340dcf0f87f69735aadf9f7a9adc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 5 Mar 2020 21:40:57 -0500 Subject: [PATCH 579/766] build: Node.js@12.16 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 70e4577f..427ff29f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.19" - "11.15" - - "12.14" + - "12.16" - "13.9" cache: directories: From 95946e320b32c6756b532128d737c97ab21d3e6c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Apr 2020 19:34:36 -0400 Subject: [PATCH 580/766] build: nyc@15.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c33d5f82..8bf91ddc 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", "mocha": "7.1.0", - "nyc": "15.0.0", + "nyc": "15.0.1", "supertest": "4.0.2" }, "files": [ From 82cc88217c49f0549f84414b90c192f30a2ba109 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Apr 2020 19:38:49 -0400 Subject: [PATCH 581/766] build: mocha@7.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8bf91ddc..8369f6b6 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "7.1.0", + "mocha": "7.1.1", "nyc": "15.0.1", "supertest": "4.0.2" }, From 06e557911e22b748050db5b4cc9eb3e8b53b3979 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Apr 2020 19:43:04 -0400 Subject: [PATCH 582/766] build: cookie-parser@1.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8369f6b6..b8f44d24 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "after": "0.8.2", - "cookie-parser": "1.4.4", + "cookie-parser": "1.4.5", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", From bcf1f071235ad4ddb22a24179c3d5151bb41c901 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 6 Apr 2020 23:01:31 -0400 Subject: [PATCH 583/766] build: Node.js@13.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 427ff29f..23e0c446 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ node_js: - "10.19" - "11.15" - "12.16" - - "13.9" + - "13.12" cache: directories: - node_modules From 909d9e0a238795aa927fe45ded86669fd446f1fe Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Apr 2020 20:24:14 -0400 Subject: [PATCH 584/766] docs: add debugging section closes #707 --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index a1ed3fa1..fe5076d8 100644 --- a/README.md +++ b/README.md @@ -829,6 +829,24 @@ app.get('/bar', function (req, res, next) { }) ``` +## Debugging + +This module uses the [debug](https://www.npmjs.com/package/debug) module +internally to log information about session operations. + +To see all the internal logs, set the `DEBUG` environment variable to +`express-session` when launching your app (`npm start`, in this example): + +```sh +$ DEBUG=express-session npm start +``` + +On Windows, use the corresponding command; + +```sh +> set DEBUG=express-session & npm start +``` + ## License [MIT](LICENSE) From ac3f0a256ba376f3e760c83cfde87adf3706cd2e Mon Sep 17 00:00:00 2001 From: Zirak Date: Sun, 17 Nov 2019 22:36:19 +0000 Subject: [PATCH 585/766] Fix internal method wrapping error on failed reloads closes #715 --- HISTORY.md | 5 +++++ index.js | 15 +++++++++++---- test/session.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ccc03991..99d0636a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix internal method wrapping error on failed reloads + 1.17.0 / 2019-10-10 =================== diff --git a/index.js b/index.js index 24221b48..9615346c 100644 --- a/index.js +++ b/index.js @@ -376,6 +376,16 @@ function session(options) { wrapmethods(req.session) } + function rewrapmethods (sess, callback) { + return function () { + if (req.session !== sess) { + wrapmethods(req.session) + } + + callback.apply(this, arguments) + } + } + // wrap session methods function wrapmethods(sess) { var _reload = sess.reload @@ -383,10 +393,7 @@ function session(options) { function reload(callback) { debug('reloading %s', this.id) - _reload.call(this, function () { - wrapmethods(req.session) - callback.apply(this, arguments) - }) + _reload.call(this, rewrapmethods(this, callback)) } function save() { diff --git a/test/session.js b/test/session.js index 1e3b7124..c0f1716d 100644 --- a/test/session.js +++ b/test/session.js @@ -1677,6 +1677,49 @@ describe('session()', function(){ .expect(500, 'failed to load session', done) }) }) + + it('should not override an overriden `reload` in case of errors', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, resave: false }, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + store.clear(function (err) { + if (err) return done(err) + + // reload way too many times on top of each other, + // attempting to overflow the call stack + var iters = 20 + reload() + function reload () { + if (!--iters) { + res.end('ok') + return + } + + try { + req.session.reload(reload) + } catch (e) { + res.statusCode = 500 + res.end(e.message) + } + } + }) + }) + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + request(server) + .get('/foo') + .set('Cookie', cookie(res)) + .expect(200, 'ok', done) + }) + }) }) describe('.save()', function () { From 5d5b51ff220f0e0d2adca06b3fbffc3310e56975 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Apr 2020 20:48:21 -0400 Subject: [PATCH 586/766] tests: resolve originalMaxAge flaky tests fixes #719 --- test/session.js | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/test/session.js b/test/session.js index c0f1716d..929d7c74 100644 --- a/test/session.js +++ b/test/session.js @@ -1902,7 +1902,13 @@ describe('session()', function(){ request(server) .get('/') - .expect(200, '2000', done) + .expect(200) + .expect(function (res) { + // account for 1ms latency + assert.ok(res.text === '2000' || res.text === '1999', + 'expected 2000, got ' + res.text) + }) + .end(done) }) it('should equal original maxAge for all requests', function (done) { @@ -1912,13 +1918,25 @@ describe('session()', function(){ request(server) .get('/') - .expect(200, '2000', function (err, res) { + .expect(200) + .expect(function (res) { + // account for 1ms latency + assert.ok(res.text === '2000' || res.text === '1999', + 'expected 2000, got ' + res.text) + }) + .end(function (err, res) { if (err) return done(err) setTimeout(function () { request(server) .get('/') .set('Cookie', cookie(res)) - .expect(200, '2000', done) + .expect(200) + .expect(function (res) { + // account for 1ms latency + assert.ok(res.text === '2000' || res.text === '1999', + 'expected 2000, got ' + res.text) + }) + .end(done) }, 100) }) }) @@ -1931,13 +1949,25 @@ describe('session()', function(){ request(server) .get('/') - .expect(200, '2000', function (err, res) { + .expect(200) + .expect(function (res) { + // account for 1ms latency + assert.ok(res.text === '2000' || res.text === '1999', + 'expected 2000, got ' + res.text) + }) + .end(function (err, res) { if (err) return done(err) setTimeout(function () { request(server) .get('/') .set('Cookie', cookie(res)) - .expect(200, '2000', done) + .expect(200) + .expect(function (res) { + // account for 1ms latency + assert.ok(res.text === '2000' || res.text === '1999', + 'expected 2000, got ' + res.text) + }) + .end(done) }, 100) }) }) From 4b40b2fb54cde1774e7810c42ca01fe5c971bcbf Mon Sep 17 00:00:00 2001 From: Gaby Baghdadi Date: Mon, 11 Nov 2019 15:31:14 -0500 Subject: [PATCH 587/766] tests: fix flaky cookie.maxAge test closes #713 --- test/cookie.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cookie.js b/test/cookie.js index b280dff1..36f0f5f5 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -91,7 +91,9 @@ describe('new Cookie()', function () { var maxAge = 60000 var cookie = new Cookie({ maxAge: maxAge }) - assert.strictEqual(cookie.maxAge, maxAge) + assert.strictEqual(typeof cookie.maxAge, 'number') + assert.ok(cookie.maxAge - 1000 <= maxAge) + assert.ok(cookie.maxAge + 1000 >= maxAge) }) it('should accept Date object', function () { From 80ae6a54107efd936c55bc4696fe8770cedbfd31 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 16 Apr 2020 22:43:02 -0400 Subject: [PATCH 588/766] 1.71.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 99d0636a..c5a97fd2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.17.1 / 2020-04-16 +=================== * Fix internal method wrapping error on failed reloads diff --git a/package.json b/package.json index b8f44d24..ba2adb65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.17.0", + "version": "1.17.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 975924658fd94dd10a373272a5dc465622dc0e0b Mon Sep 17 00:00:00 2001 From: Glenn Hinks Date: Tue, 14 Apr 2020 15:35:04 -0400 Subject: [PATCH 589/766] tests: remove duplicate test closes #741 --- test/cookie.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/cookie.js b/test/cookie.js index 36f0f5f5..65ae1fc3 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -12,11 +12,6 @@ describe('new Cookie()', function () { assert.strictEqual(cookie.expires, null) }) - it('should default maxAge to null', function () { - var cookie = new Cookie() - assert.strictEqual(cookie.maxAge, null) - }) - it('should default httpOnly to true', function () { var cookie = new Cookie() assert.strictEqual(cookie.httpOnly, true) From 3b08fc7a78fe7742d5a29c5a4ad999169adaf3cb Mon Sep 17 00:00:00 2001 From: Glenn Hinks Date: Tue, 14 Apr 2020 18:01:22 -0400 Subject: [PATCH 590/766] tests: fix test validation of session ID closes #742 --- test/session.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/session.js b/test/session.js index 929d7c74..f0b60fdf 100644 --- a/test/session.js +++ b/test/session.js @@ -482,7 +482,7 @@ describe('session()', function(){ .get('/') .set('Cookie', cookie(res)) .expect(shouldSetCookie('connect.sid')) - .expect(shouldSetCookieToDifferentSessionId(res)) + .expect(shouldSetCookieToDifferentSessionId(sid(res))) .expect(200, 'session 2', done) }) }) From c3e784e1a736fb41fab3da682f63582c709d6da8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 26 Apr 2020 18:09:58 -0400 Subject: [PATCH 591/766] build: Node.js@10.20 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 23e0c446..347cf792 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.19" + - "10.20" - "11.15" - "12.16" - "13.12" From fa4e23405bc2dcabfac12a8436dcab1f3a830801 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 26 Apr 2020 18:11:34 -0400 Subject: [PATCH 592/766] build: Node.js@13.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 347cf792..6c647735 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ node_js: - "10.20" - "11.15" - "12.16" - - "13.12" + - "13.13" cache: directories: - node_modules From fbf7059e565064ce1efc63a3b7b8995a9024ae2d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 1 May 2020 20:03:52 -0400 Subject: [PATCH 593/766] build: mocha@7.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ba2adb65..209c6e46 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "7.1.1", + "mocha": "7.1.2", "nyc": "15.0.1", "supertest": "4.0.2" }, From 4186dff8cdfa0a77005195697a0137f91082b073 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 May 2020 19:44:45 -0400 Subject: [PATCH 594/766] deps: safe-buffer@5.2.1 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index c5a97fd2..60592140 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: safe-buffer@5.2.1 + 1.17.1 / 2020-04-16 =================== diff --git a/package.json b/package.json index 209c6e46..d5eb6be2 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "depd": "~2.0.0", "on-headers": "~1.0.2", "parseurl": "~1.3.3", - "safe-buffer": "5.2.0", + "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" }, "devDependencies": { From c5ec988ae982dfc00061fdb1571b2a88ada3aba5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 18 May 2020 19:49:08 -0400 Subject: [PATCH 595/766] build: Node.js@13.14 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6c647735..ba846eac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ node_js: - "10.20" - "11.15" - "12.16" - - "13.13" + - "13.14" cache: directories: - node_modules From 40a6337a7e69346694091f66d55928c913299c56 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Jun 2020 21:33:32 -0400 Subject: [PATCH 596/766] build: mocha@7.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5eb6be2..9ef314d2 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "7.1.2", + "mocha": "7.2.0", "nyc": "15.0.1", "supertest": "4.0.2" }, From fa6ced353fb3eecb9305eefeec9ef02d1dd07f7f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Jun 2020 21:36:35 -0400 Subject: [PATCH 597/766] build: Node.js@10.21 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ba846eac..9ff2e6e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.20" + - "10.21" - "11.15" - "12.16" - "13.14" From 34a4db1c279aad87ca1b12e19574f9e307831a6c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Jun 2020 21:40:20 -0400 Subject: [PATCH 598/766] build: Node.js@12.18 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9ff2e6e9..db00f6ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.21" - "11.15" - - "12.16" + - "12.18" - "13.14" cache: directories: From 357b98b4f9460173181a5e3dac84db126115b749 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Jun 2020 21:54:22 -0400 Subject: [PATCH 599/766] build: support Node.js 14.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index db00f6ed..f62c5a5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ node_js: - "11.15" - "12.18" - "13.14" + - "14.4" cache: directories: - node_modules From 67ccd90bedf155e249652df49714913297bfbc92 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Jun 2020 22:01:55 -0400 Subject: [PATCH 600/766] build: nyc@15.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ef314d2..4c34510c 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", "mocha": "7.2.0", - "nyc": "15.0.1", + "nyc": "15.1.0", "supertest": "4.0.2" }, "files": [ From 75896a5525f7245278510b670c2e08a14ec10fc0 Mon Sep 17 00:00:00 2001 From: Glenn Hinks Date: Tue, 19 May 2020 08:10:26 -0400 Subject: [PATCH 601/766] docs: expand secret documentation with key advice fixes #734 fixes #750 closes #752 --- README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe5076d8..14cad1e8 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,22 @@ it to be saved. *This has been fixed in PassportJS 0.3.0* This is the secret used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while -all the elements will be considered when verifying the signature in requests. +all the elements will be considered when verifying the signature in requests. The +secret itself should be not easily parsed by a human and would best be a random set +of characters. A best practice may include: + + - The use of environment variables to store the secret, ensuring the secret itself + does not exist in your repository. + - Periodic updates of the secret, while ensuring the previous secret is in the + array. + +Using a secret that cannot be guessed will reduce the ability to hijack a session to +only guessing the session ID (as determined by the `genid` option). + +Changing the secret value will invalidate all existing sessions. In order to rotate +the secret without invalidating sessions, provide an array of secrets, with the new +secret as first element of the array, and including previous secrets as the later +elements. ##### store From 28d2691eaa6ff1796805eef3f9cf66ef6f6428cf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 10 Jun 2020 21:18:03 -0400 Subject: [PATCH 602/766] deps: cookie@0.4.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 60592140..355c8021 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * deps: cookie@0.4.1 * deps: safe-buffer@5.2.1 1.17.1 / 2020-04-16 diff --git a/package.json b/package.json index 4c34510c..adadb821 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.4.0", + "cookie": "0.4.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", From 0f26a224ef03e7b251b5f92098258b47c02bc579 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Jun 2020 19:03:56 -0400 Subject: [PATCH 603/766] build: mocha@8.0.1 --- .travis.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f62c5a5a..d7722207 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,6 +68,7 @@ before_install: elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' elif node_version_lt '8.0' ; then npm_use_module 'mocha' '6.2.2' + elif node_version_lt '10.0'; then npm_use_module 'mocha' '7.2.0' fi - | # Configure nyc for coverage diff --git a/package.json b/package.json index adadb821..e5c7e480 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "7.2.0", + "mocha": "8.0.1", "nyc": "15.1.0", "supertest": "4.0.2" }, From e485e11496f78b75f04ca58cde0d124f80f2b9e2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 6 Jul 2020 21:03:04 -0400 Subject: [PATCH 604/766] build: Node.js@14.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7722207..8fabbdf3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ node_js: - "11.15" - "12.18" - "13.14" - - "14.4" + - "14.5" cache: directories: - node_modules From 7d7f4f72dd28586d978009b0fde946c51202fb27 Mon Sep 17 00:00:00 2001 From: Glenn Hinks Date: Sun, 3 May 2020 09:15:33 -0400 Subject: [PATCH 605/766] tests: add res.writeHead set-cookie test closes #746 --- test/session.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/session.js b/test/session.js index f0b60fdf..1455f0a6 100644 --- a/test/session.js +++ b/test/session.js @@ -1892,6 +1892,21 @@ describe('session()', function(){ .expect(shouldSetCookieToValue('previous', 'cookieValue')) .expect(200, done) }) + + it('should preserve cookies set in writeHead', function (done) { + var server = createServer(null, function (req, res) { + var cookie = new Cookie() + res.writeHead(200, { + 'Set-Cookie': cookie.serialize('previous', 'cookieValue') + }) + res.end() + }) + + request(server) + .get('/') + .expect(shouldSetCookieToValue('previous', 'cookieValue')) + .expect(200, done) + }) }) describe('.originalMaxAge', function () { From 09d41b9b82fb56e8d86c410d38c52139cd932eec Mon Sep 17 00:00:00 2001 From: Glenn Hinks Date: Fri, 3 Jul 2020 11:48:48 -0400 Subject: [PATCH 606/766] docs: remove deprecated store modules from readme closes #765 --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index 14cad1e8..66c84da7 100644 --- a/README.md +++ b/README.md @@ -617,11 +617,6 @@ and other multi-core embedded devices). [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session [connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85 -[![โ˜…][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store. - -[connect-mssql-url]: https://www.npmjs.com/package/connect-mssql -[connect-mssql-image]: https://badgen.net/github/stars/patriksimek/connect-mssql?label=%E2%98%85 - [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple @@ -664,11 +659,6 @@ and other multi-core embedded devices). [couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression [couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85 -[![โ˜…][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service. - -[documentdb-session-url]: https://www.npmjs.com/package/documentdb-session -[documentdb-session-image]: https://badgen.net/github/stars/dwhieb/documentdb-session?label=%E2%98%85 - [![โ˜…][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store. [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store From 6a128cc5941365d0416d92760328a8e11549eb5d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Jul 2020 21:43:18 -0400 Subject: [PATCH 607/766] Fix res.end patch to always commit headers fixes #766 closes #767 --- HISTORY.md | 1 + index.js | 4 ++++ test/session.js | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 355c8021..4fa89ab4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix `res.end` patch to always commit headers * deps: cookie@0.4.1 * deps: safe-buffer@5.2.1 diff --git a/index.js b/index.js index 9615346c..d7efeab9 100644 --- a/index.js +++ b/index.js @@ -272,6 +272,10 @@ function session(options) { return ret; } + if (!res._header) { + res._implicitHeader() + } + if (chunk == null) { ret = true; return ret; diff --git a/test/session.js b/test/session.js index 1455f0a6..8d796f91 100644 --- a/test/session.js +++ b/test/session.js @@ -1449,6 +1449,42 @@ describe('session()', function(){ .get('/') .expect(200, 'hello, world', done) }) + + it('should error when res.end is called twice', function (done) { + var error1 = null + var error2 = null + var server = http.createServer(function (req, res) { + res.end() + + try { + res.setHeader('Content-Length', '3') + res.end('foo') + } catch (e) { + error1 = e + } + }) + + function respond (req, res) { + res.end() + + try { + res.setHeader('Content-Length', '3') + res.end('foo') + } catch (e) { + error2 = e + } + } + + request(server) + .get('/') + .end(function (err, res) { + if (err) return done(err) + request(createServer(null, respond)) + .get('/') + .expect(function () { assert.strictEqual((error1 && error1.message), (error2 && error2.message)) }) + .expect(res.statusCode, res.text, done) + }) + }) }) describe('req.session', function(){ From c678436a0d2b62113ef5433acf45fe72d36e80ce Mon Sep 17 00:00:00 2001 From: Krispin Leydon Date: Sat, 20 Jun 2020 09:44:56 -0700 Subject: [PATCH 608/766] docs: add @quixo3/prisma-session-store-url to the list of session stores closes #760 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 66c84da7..3b2bcbf4 100644 --- a/README.md +++ b/README.md @@ -759,6 +759,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store [nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85 +[![โ˜…][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io). + +[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store +[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85 + [![โ˜…][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API [restsession-url]: https://www.npmjs.com/package/restsession From 4715f3b4ed75f7a3926137f6754cde42b9fb66b7 Mon Sep 17 00:00:00 2001 From: shree Date: Sat, 11 Jul 2020 18:03:24 +0530 Subject: [PATCH 609/766] docs: fix typo in readme closes #768 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b2bcbf4..94ec2743 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ With this enabled, the session identifier cookie will expire in This is typically used in conjuction with short, non-session-length [`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data -with reduced potentional of it occurring during on going server interactions. +with reduced potential of it occurring during on going server interactions. **Note** When this option is set to `true` but the `saveUninitialized` option is set to `false`, the cookie will not be set on a response with an uninitialized From 9face93ed0cdd4494a6513542ac12e15ad0a9848 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 27 Jul 2020 22:41:07 -0400 Subject: [PATCH 610/766] build: Node.js@10.22 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8fabbdf3..4621c083 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.21" + - "10.22" - "11.15" - "12.18" - "13.14" From c37c46b0773ef3c415dc0aa8efc3f0f904d0772a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 5 Aug 2020 16:44:49 -0400 Subject: [PATCH 611/766] build: mocha@8.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5c7e480..e3f988f7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "8.0.1", + "mocha": "8.1.1", "nyc": "15.1.0", "supertest": "4.0.2" }, From 7d9ec2b7d531c943b65751ea60ca04b7080bf75e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 5 Aug 2020 16:49:27 -0400 Subject: [PATCH 612/766] build: Node.js@14.7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4621c083..d0615e91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ node_js: - "11.15" - "12.18" - "13.14" - - "14.5" + - "14.7" cache: directories: - node_modules From a8641429502fcc076c4b2dcbd6b2320891c1650c Mon Sep 17 00:00:00 2001 From: Jason Luboff Date: Tue, 18 Aug 2020 15:02:47 -0700 Subject: [PATCH 613/766] docs: add connect-mssql-v2 to the list of session stores closes #775 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 94ec2743..38b75c7c 100644 --- a/README.md +++ b/README.md @@ -617,6 +617,11 @@ and other multi-core embedded devices). [connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session [connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85 +[![โ˜…][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql). + +[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2 +[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85 + [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple From d9702ed2496fabcc5417f3103aaccd381b2084ac Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 31 Aug 2020 20:41:56 -0400 Subject: [PATCH 614/766] build: mocha@8.1.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e3f988f7..cfbcb255 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "8.1.1", + "mocha": "8.1.3", "nyc": "15.1.0", "supertest": "4.0.2" }, From c5cd79056384e661d131a0a4174f1448819b09ea Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 3 Sep 2020 20:43:27 -0400 Subject: [PATCH 615/766] tests: add helper for delay store set --- test/session.js | 103 ++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 70 deletions(-) diff --git a/test/session.js b/test/session.js index 8d796f91..021b3251 100644 --- a/test/session.js +++ b/test/session.js @@ -290,34 +290,21 @@ describe('session()', function(){ describe('when response ended', function () { it('should have saved session', function (done) { - var saved = false var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { req.session.hit = true res.end('session saved') }) - var _set = store.set - store.set = function set(sid, sess, callback) { - setTimeout(function () { - _set.call(store, sid, sess, function (err) { - saved = true - callback(err) - }) - }, 200) - } - request(server) - .get('/') - .expect(200, 'session saved', function (err) { - if (err) return done(err) - assert.ok(saved) - done() - }) + .get('/') + .expect(200) + .expect(shouldSetSessionInStore(store, 200)) + .expect('session saved') + .end(done) }) it('should have saved session even with empty response', function (done) { - var saved = false var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { req.session.hit = true @@ -325,27 +312,14 @@ describe('session()', function(){ res.end() }) - var _set = store.set - store.set = function set(sid, sess, callback) { - setTimeout(function () { - _set.call(store, sid, sess, function (err) { - saved = true - callback(err) - }) - }, 200) - } - request(server) - .get('/') - .expect(200, '', function (err) { - if (err) return done(err) - assert.ok(saved) - done() - }) + .get('/') + .expect(200) + .expect(shouldSetSessionInStore(store, 200)) + .end(done) }) it('should have saved session even with multi-write', function (done) { - var saved = false var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { req.session.hit = true @@ -354,27 +328,15 @@ describe('session()', function(){ res.end('world') }) - var _set = store.set - store.set = function set(sid, sess, callback) { - setTimeout(function () { - _set.call(store, sid, sess, function (err) { - saved = true - callback(err) - }) - }, 200) - } - request(server) - .get('/') - .expect(200, 'hello, world', function (err) { - if (err) return done(err) - assert.ok(saved) - done() - }) + .get('/') + .expect(200) + .expect(shouldSetSessionInStore(store, 200)) + .expect('hello, world') + .end(done) }) it('should have saved session even with non-chunked response', function (done) { - var saved = false var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { req.session.hit = true @@ -382,23 +344,12 @@ describe('session()', function(){ res.end('session saved') }) - var _set = store.set - store.set = function set(sid, sess, callback) { - setTimeout(function () { - _set.call(store, sid, sess, function (err) { - saved = true - callback(err) - }) - }, 200) - } - request(server) - .get('/') - .expect(200, 'session saved', function (err) { - if (err) return done(err) - assert.ok(saved) - done() - }) + .get('/') + .expect(200) + .expect(shouldSetSessionInStore(store, 200)) + .expect('session saved') + .end(done) }) it('should have saved session with updated cookie expiration', function (done) { @@ -2485,13 +2436,25 @@ function shouldSetCookieWithoutAttribute (name, attrib) { } } -function shouldSetSessionInStore(store) { +function shouldSetSessionInStore (store, delay) { var _set = store.set var count = 0 store.set = function set () { count++ - return _set.apply(this, arguments) + + if (!delay) { + return _set.apply(this, arguments) + } + + var args = new Array(arguments.length + 1) + + args[0] = this + for (var i = 1; i < args.length; i++) { + args[i] = arguments[i - 1] + } + + setTimeout(_set.bind.apply(_set, args), delay) } return function () { From 284a71a166b514dbb5b15afd0a99a66b1937b9d1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2020 21:33:40 -0400 Subject: [PATCH 616/766] build: Node.js@12.19 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d0615e91..5c6f7149 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.22" - "11.15" - - "12.18" + - "12.19" - "13.14" - "14.7" cache: From 69ac483771e10cfb651f28379a07ca2e6f3ab613 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Oct 2020 21:39:44 -0400 Subject: [PATCH 617/766] build: Node.js@14.13 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5c6f7149..fe7c7c82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ node_js: - "11.15" - "12.19" - "13.14" - - "14.7" + - "14.13" cache: directories: - node_modules From 2637221c383805c49dd57287fb58df4b63bc7dbe Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 10 Nov 2020 00:31:28 -0500 Subject: [PATCH 618/766] build: supertest@6.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cfbcb255..f395b686 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.1", "mocha": "8.1.3", "nyc": "15.1.0", - "supertest": "4.0.2" + "supertest": "6.0.1" }, "files": [ "session/", From 0d7f3d83a6309c1473199b6af768c1aa679c869f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 13 Nov 2020 21:30:32 -0500 Subject: [PATCH 619/766] build: mocha@8.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f395b686..99eaffd6 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "8.1.3", + "mocha": "8.2.1", "nyc": "15.1.0", "supertest": "6.0.1" }, From 1cfd994507daa6c32ad4edd836db7368c6a98af0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Nov 2020 00:31:44 -0500 Subject: [PATCH 620/766] build: support Node.js 15.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fe7c7c82..9c413128 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ node_js: - "12.19" - "13.14" - "14.13" + - "15.2" cache: directories: - node_modules From 8914d60a0ef37ef81ffc8ddc361fc8f7d8290c7f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 29 Nov 2020 18:30:13 -0500 Subject: [PATCH 621/766] build: Node.js@12.20 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9c413128..9404890b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.22" - "11.15" - - "12.19" + - "12.20" - "13.14" - "14.13" - "15.2" From 7452225b1a8b6768adca916ebdb141d1aac0a502 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 15 Dec 2020 16:30:21 -0500 Subject: [PATCH 622/766] build: Node.js@15.4 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9404890b..d8ecf916 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ node_js: - "12.20" - "13.14" - "14.13" - - "15.2" + - "15.4" cache: directories: - node_modules From 1813cd4d8035dd31670789dfd014d52752476eef Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Dec 2020 00:18:50 -0500 Subject: [PATCH 623/766] build: Node.js@14.15 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d8ecf916..c99c0b5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ node_js: - "11.15" - "12.20" - "13.14" - - "14.13" + - "14.15" - "15.4" cache: directories: From a26b4d351eecae43c1ba6bbe9d3451db1adbaf6c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Dec 2020 00:22:53 -0500 Subject: [PATCH 624/766] build: Node.js@10.23 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c99c0b5e..772af3c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.22" + - "10.23" - "11.15" - "12.20" - "13.14" From 54e4193d7b0a11a61fdfcfdb24f2f2839a45923e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jan 2021 19:42:02 -0500 Subject: [PATCH 625/766] build: supertest@6.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 99eaffd6..cefc5c07 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.1", "mocha": "8.2.1", "nyc": "15.1.0", - "supertest": "6.0.1" + "supertest": "6.1.1" }, "files": [ "session/", From acca90868c4c00ba31e2d763dd98d8fbbaaa175b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jan 2021 19:49:16 -0500 Subject: [PATCH 626/766] build: Node.js@15.6 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 772af3c3..3e8c9128 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ node_js: - "12.20" - "13.14" - "14.15" - - "15.4" + - "15.6" cache: directories: - node_modules From 7a6c4793602b9b048bd3c2d543bd4de1ea93df29 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 26 Feb 2021 21:39:33 -0500 Subject: [PATCH 627/766] build: Node.js@12.21 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3e8c9128..68cc93d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.23" - "11.15" - - "12.20" + - "12.21" - "13.14" - "14.15" - "15.6" From 3acbb8149de59581a1d78fbf17e6540f13cea4f1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 26 Feb 2021 21:44:49 -0500 Subject: [PATCH 628/766] build: Node.js@10.24 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 68cc93d2..6f010cd2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.17" - "9.11" - - "10.23" + - "10.24" - "11.15" - "12.21" - "13.14" From c1df7c54e89f84342acd03386e998ef54b766477 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 28 Feb 2021 19:43:04 -0500 Subject: [PATCH 629/766] build: Node.js@14.16 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6f010cd2..c9fc0622 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ node_js: - "11.15" - "12.21" - "13.14" - - "14.15" + - "14.16" - "15.6" cache: directories: From 6e4052d5b26f7e6809c84acc130b891b8370d0e0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 Mar 2021 20:31:00 -0500 Subject: [PATCH 630/766] build: Node.js@15.10 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c9fc0622..e78c4851 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ node_js: - "12.21" - "13.14" - "14.16" - - "15.6" + - "15.10" cache: directories: - node_modules From 373514d6607ce73fc3d0e33a1469c23a55757cff Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 8 Mar 2021 19:30:10 -0500 Subject: [PATCH 631/766] build: mocha@8.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cefc5c07..f02d0e73 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "8.2.1", + "mocha": "8.3.1", "nyc": "15.1.0", "supertest": "6.1.1" }, From e007c854f5de4e8455557eef14dae76706090dec Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 19 Mar 2021 21:30:10 -0400 Subject: [PATCH 632/766] build: Node.js@15.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e78c4851..51f530d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ node_js: - "12.21" - "13.14" - "14.16" - - "15.10" + - "15.12" cache: directories: - node_modules From f44f0e42df64e76dd6d5b943e23ab279c10358fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 12 May 2021 23:41:22 -0400 Subject: [PATCH 633/766] build: support Node.js 16.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 51f530d0..11828a14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ node_js: - "13.14" - "14.16" - "15.12" + - "16.1" cache: directories: - node_modules From 657e3c086caf9a2f2167933e8205466bf74c4660 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 12 May 2021 23:48:38 -0400 Subject: [PATCH 634/766] build: mocha@8.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f02d0e73..e58b1cec 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", - "mocha": "8.3.1", + "mocha": "8.4.0", "nyc": "15.1.0", "supertest": "6.1.1" }, From 579154ae6b7234fe385167a6534276420848b4ad Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 13 May 2021 21:31:51 -0400 Subject: [PATCH 635/766] build: Node.js@12.22 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 11828a14..2e7e2e23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.24" - "11.15" - - "12.21" + - "12.22" - "13.14" - "14.16" - "15.12" From 5cf60e2be83fcab4ae30d4447eb815ddab31ef47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 20 Nov 2020 15:34:49 +0100 Subject: [PATCH 636/766] docs: add better-sqlite3-session-store to the list of session stores closes #795 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 38b75c7c..bd9ac856 100644 --- a/README.md +++ b/README.md @@ -519,6 +519,11 @@ module. Please make a PR to add additional modules :) [aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store [aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85 +[![โ˜…][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3). + +[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store +[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85 + [![โ˜…][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store. [cassandra-store-url]: https://www.npmjs.com/package/cassandra-store From a811b59da52031cc9594e8467cc79205711690f0 Mon Sep 17 00:00:00 2001 From: Yuli Date: Sat, 1 May 2021 21:53:01 +0300 Subject: [PATCH 637/766] docs: add @databunker/session-store to the list of session stores closes #826 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index bd9ac856..bcccdbd8 100644 --- a/README.md +++ b/README.md @@ -799,6 +799,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb [session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85 +[![โ˜…][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store. + +[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store +[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85 + [![โ˜…][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases. [sessionstore-url]: https://www.npmjs.com/package/sessionstore From 034fd4e0bef8085431180258f329fe1168fb9e01 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 17 May 2021 16:33:52 -0400 Subject: [PATCH 638/766] build: supertest@6.1.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e58b1cec..f216c9fb 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.1", "mocha": "8.4.0", "nyc": "15.1.0", - "supertest": "6.1.1" + "supertest": "6.1.3" }, "files": [ "session/", From b23ec4fa4553845138cbda823bb4e7bbd3d7242f Mon Sep 17 00:00:00 2001 From: john-redd Date: Wed, 26 Aug 2020 09:45:16 -0600 Subject: [PATCH 639/766] docs: note about samesite attribute and secure requirements closes #778 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index bcccdbd8..77531505 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,10 @@ More information about the different enforcement levels can be found in **Note** This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it. +**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01) +that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been +set to `'none'`. Some web browsers or other clients may be adopting this specification. + ##### cookie.secure Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy, From 7ff50af0d88e011e9830c14222df79d0b9e4ddc6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 17 May 2021 15:45:22 -0400 Subject: [PATCH 640/766] build: use GitHub Actions instead of Travis CI --- .github/workflows/ci.yml | 180 +++++++++++++++++++++++++++++++++++++++ .travis.yml | 112 ------------------------ README.md | 6 +- package.json | 2 +- 4 files changed, 184 insertions(+), 116 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..2cba7fab --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,180 @@ +name: ci + +on: +- pull_request +- push + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + name: + - Node.js 0.8 + - Node.js 0.10 + - Node.js 0.12 + - io.js 1.x + - io.js 2.x + - io.js 3.x + - Node.js 4.x + - Node.js 5.x + - Node.js 6.x + - Node.js 7.x + - Node.js 8.x + - Node.js 9.x + - Node.js 10.x + - Node.js 11.x + - Node.js 12.x + - Node.js 13.x + - Node.js 14.x + - Node.js 15.x + - Node.js 16.x + + include: + - name: Node.js 0.8 + node-version: "0.8" + npm-i: mocha@2.5.3 supertest@1.1.0 + npm-rm: nyc + + - name: Node.js 0.10 + node-version: "0.10" + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + + - name: Node.js 0.12 + node-version: "0.12" + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + + - name: io.js 1.x + node-version: "1.8" + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + + - name: io.js 2.x + node-version: "2.5" + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + + - name: io.js 3.x + node-version: "3.3" + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + + - name: Node.js 4.x + node-version: "4.9" + npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2 + + - name: Node.js 5.x + node-version: "5.12" + npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2 + + - name: Node.js 6.x + node-version: "6.17" + npm-i: mocha@6.2.2 nyc@14.1.1 + + - name: Node.js 7.x + node-version: "7.10" + npm-i: mocha@6.2.2 nyc@14.1.1 + + - name: Node.js 8.x + node-version: "8.17" + npm-i: mocha@7.2.0 + + - name: Node.js 9.x + node-version: "9.11" + npm-i: mocha@7.2.0 + + - name: Node.js 10.x + node-version: "10.24" + + - name: Node.js 11.x + node-version: "11.15" + + - name: Node.js 12.x + node-version: "12.22" + + - name: Node.js 13.x + node-version: "13.14" + + - name: Node.js 14.x + node-version: "14.17" + + - name: Node.js 15.x + node-version: "15.14" + + - name: Node.js 16.x + node-version: "16.1" + + steps: + - uses: actions/checkout@v2 + + - name: Install Node.js ${{ matrix.node-version }} + shell: bash -eo pipefail -l {0} + run: | + nvm install --default ${{ matrix.node-version }} + if [[ "${{ matrix.node-version }}" == 0.* ]]; then + npm config set strict-ssl false + fi + dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" + + - name: Configure npm + run: npm config set shrinkwrap false + + - name: Remove npm module(s) ${{ matrix.npm-rm }} + run: npm rm --silent --save-dev ${{ matrix.npm-rm }} + if: matrix.npm-rm != '' + + - name: Install npm module(s) ${{ matrix.npm-i }} + run: npm install --save-dev ${{ matrix.npm-i }} + if: matrix.npm-i != '' + + - name: Setup Node.js version-specific dependencies + shell: bash + run: | + # eslint for linting + # - remove on Node.js < 6 + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 6 ]]; then + node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ + grep -E '^eslint(-|$)' | \ + sort -r | \ + xargs -n1 npm rm --silent --save-dev + fi + + - name: Install Node.js dependencies + run: npm install + + - name: List environment + id: list_env + shell: bash + run: | + echo "node@$(node -v)" + echo "npm@$(npm -v)" + npm -s ls ||: + (npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print "::set-output name=" $2 "::" $3 }' + + - name: Run tests + shell: bash + run: | + if npm -ps ls nyc | grep -q nyc; then + npm run test-ci + else + npm test + fi + + - name: Lint code + if: steps.list_env.outputs.eslint != '' + run: npm run lint + + - name: Collect code coverage + uses: coverallsapp/github-action@master + if: steps.list_env.outputs.nyc != '' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: run-${{ matrix.test_number }} + parallel: true + + coverage: + needs: test + runs-on: ubuntu-latest + steps: + - name: Upload code coverage + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2e7e2e23..00000000 --- a/.travis.yml +++ /dev/null @@ -1,112 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" - - "0.12" - - "1.8" - - "2.5" - - "3.3" - - "4.9" - - "5.12" - - "6.17" - - "7.10" - - "8.17" - - "9.11" - - "10.24" - - "11.15" - - "12.22" - - "13.14" - - "14.16" - - "15.12" - - "16.1" -cache: - directories: - - node_modules -before_install: - - | - # Setup utility functions - function node_version_lt () { - [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v "${1}")" ]] - } - function npm_module_installed () { - npm -lsp ls | grep -Fq "$(pwd)/node_modules/${1}:${1}@" - } - function npm_remove_module_re () { - node -e ' - fs = require("fs"); - p = JSON.parse(fs.readFileSync("package.json", "utf8")); - r = RegExp(process.argv[1]); - for (k in p.devDependencies) { - if (r.test(k)) delete p.devDependencies[k]; - } - fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); - ' "$@" - } - function npm_use_module () { - node -e ' - fs = require("fs"); - p = JSON.parse(fs.readFileSync("package.json", "utf8")); - p.devDependencies[process.argv[1]] = process.argv[2]; - fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); - ' "$@" - } - function v () { - tr '.' '\n' <<< "${1}" \ - | awk '{ printf "%03d", $0 }' \ - | sed 's/^0*//' - } - # Configure npm - - | - # Skip updating shrinkwrap / lock - npm config set shrinkwrap false - # Setup Node.js version-specific dependencies - - | - # Configure eslint for linting - if node_version_lt '6.0'; then npm_remove_module_re '^eslint(-|$)' - fi - - | - # Configure mocha for testing - if node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' - elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' - elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' - elif node_version_lt '8.0' ; then npm_use_module 'mocha' '6.2.2' - elif node_version_lt '10.0'; then npm_use_module 'mocha' '7.2.0' - fi - - | - # Configure nyc for coverage - if node_version_lt '0.10'; then npm_remove_module_re '^nyc$' - elif node_version_lt '4.0' ; then npm_use_module 'nyc' '10.3.2' - elif node_version_lt '6.0' ; then npm_use_module 'nyc' '11.9.0' - elif node_version_lt '8.0' ; then npm_use_module 'nyc' '14.1.1' - fi - - | - # Configure supertest for http calls - if node_version_lt '0.10'; then npm_use_module 'supertest' '1.1.0' - elif node_version_lt '4.0' ; then npm_use_module 'supertest' '2.0.0' - elif node_version_lt '6.0' ; then npm_use_module 'supertest' '3.4.2' - fi - # Update Node.js modules - - | - # Prune & rebuild node_modules - if [[ -d node_modules ]]; then - npm prune - npm rebuild - fi - -script: - - | - # Run test script, depending on nyc install - if npm_module_installed 'nyc'; then npm run-script test-travis - else npm test - fi - - | - # Run linting, depending on eslint install - if npm_module_installed 'eslint'; then npm run-script lint - fi -after_script: - - | - # Upload coverage to coveralls, if exists - if [[ -d .nyc_output ]]; then - npm install --save-dev coveralls@2 - nyc report --reporter=text-lcov | coveralls - fi diff --git a/README.md b/README.md index 77531505..01477c39 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][node-url] -[![Build Status][travis-image]][travis-url] +[![Build Status][ci-image]][ci-url] [![Test Coverage][coveralls-image]][coveralls-url] ## Installation @@ -881,11 +881,11 @@ On Windows, use the corresponding command; [MIT](LICENSE) [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 +[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci +[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master [coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master [node-url]: https://nodejs.org/en/download [npm-downloads-image]: https://badgen.net/npm/dm/express-session [npm-url]: https://npmjs.org/package/express-session [npm-version-image]: https://badgen.net/npm/v/express-session -[travis-image]: https://badgen.net/travis/expressjs/session/master -[travis-url]: https://travis-ci.org/expressjs/session diff --git a/package.json b/package.json index f216c9fb..634b4f99 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "scripts": { "lint": "eslint --plugin markdown --ext js,md . && node ./scripts/lint-readme.js", "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", + "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc npm test", - "test-travis": "nyc npm test -- --no-exit", "version": "node scripts/version-history.js && git add HISTORY.md" } } From 9a1cc15efbc637a9d4503eb8f8f51a25461a51e3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 19 May 2021 08:10:33 -0400 Subject: [PATCH 641/766] build: eslint@7.26.0 --- .eslintrc.yml | 2 +- .github/workflows/ci.yml | 4 ++-- package.json | 2 +- test/session.js | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 0740b11f..fe10d7ea 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -2,7 +2,7 @@ root: true rules: eol-last: error eqeqeq: ["error", "always", { "null": "ignore" }] - indent: ["error", 2, { "SwitchCase": 1 }] + indent: ["error", 2, { "MemberExpression": "off", "SwitchCase": 1 }] no-mixed-spaces-and-tabs: error no-trailing-spaces: error one-var: ["error", { "initialized": "never" }] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cba7fab..b52cfc9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,8 +128,8 @@ jobs: shell: bash run: | # eslint for linting - # - remove on Node.js < 6 - if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 6 ]]; then + # - remove on Node.js < 10 + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ grep -E '^eslint(-|$)' | \ sort -r | \ diff --git a/package.json b/package.json index 634b4f99..5185b37d 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.5", - "eslint": "3.19.0", + "eslint": "7.26.0", "eslint-plugin-markdown": "1.0.2", "express": "4.17.1", "mocha": "8.4.0", diff --git a/test/session.js b/test/session.js index 021b3251..7ce3c194 100644 --- a/test/session.js +++ b/test/session.js @@ -622,8 +622,8 @@ describe('session()', function(){ before(function () { function setup (req) { req.secure = req.headers['x-secure'] - ? JSON.parse(req.headers['x-secure']) - : undefined + ? JSON.parse(req.headers['x-secure']) + : undefined } function respond (req, res) { @@ -655,8 +655,8 @@ describe('session()', function(){ before(function () { function setup (req) { req.secure = req.headers['x-secure'] - ? JSON.parse(req.headers['x-secure']) - : undefined + ? JSON.parse(req.headers['x-secure']) + : undefined } function respond (req, res) { From 45cbbf4108ed9e05470d638ec0f6cb7be8b5f12a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 19 May 2021 08:13:08 -0400 Subject: [PATCH 642/766] bulid: eslint-plugin-markdown@2.1.0 --- .eslintrc.yml | 7 +++++++ package.json | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index fe10d7ea..b6b9f62f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,4 +1,11 @@ root: true +extends: + - plugin:markdown/recommended +plugins: + - markdown +overrides: + - files: '**/*.md' + processor: 'markdown/markdown' rules: eol-last: error eqeqeq: ["error", "always", { "null": "ignore" }] diff --git a/package.json b/package.json index 5185b37d..c9e38fa9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.5", "eslint": "7.26.0", - "eslint-plugin-markdown": "1.0.2", + "eslint-plugin-markdown": "2.1.0", "express": "4.17.1", "mocha": "8.4.0", "nyc": "15.1.0", @@ -39,7 +39,7 @@ "node": ">= 0.8.0" }, "scripts": { - "lint": "eslint --plugin markdown --ext js,md . && node ./scripts/lint-readme.js", + "lint": "eslint . && node ./scripts/lint-readme.js", "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc npm test", From 4baea4a3750cfd933aba32d91dabfd494174ec86 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 19 May 2021 08:52:55 -0400 Subject: [PATCH 643/766] build: Node.js@16.2 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b52cfc9e..3c1182bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,7 +99,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.1" + node-version: "16.2" steps: - uses: actions/checkout@v2 From 0048bcac451ad867299d404aca94c79cc8bc751d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 19 May 2021 13:33:52 -0400 Subject: [PATCH 644/766] 1.17.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 4fa89ab4..774607dc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.17.2 / 2021-05-19 +=================== * Fix `res.end` patch to always commit headers * deps: cookie@0.4.1 diff --git a/package.json b/package.json index c9e38fa9..d085f292 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.17.1", + "version": "1.17.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From bccab373df5626a9e1635afcf3661d1e89b4ccae Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 12 Nov 2021 21:09:00 -0500 Subject: [PATCH 645/766] build: update CI for npm TLS upgrade --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c1182bd..fc4de3e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,10 @@ jobs: shell: bash -eo pipefail -l {0} run: | nvm install --default ${{ matrix.node-version }} - if [[ "${{ matrix.node-version }}" == 0.* ]]; then + if [[ "${{ matrix.node-version }}" == 0.* && "$(cut -d. -f2 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then + nvm install --alias=npm 0.10 + nvm use ${{ matrix.node-version }} + sed -i '1s;^.*$;'"$(printf '#!%q' "$(nvm which npm)")"';' "$(readlink -f "$(which npm)")" npm config set strict-ssl false fi dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" From ae3269e9733792bee584e58f03d907ad2a522352 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 12 Nov 2021 21:15:13 -0500 Subject: [PATCH 646/766] build: eslint-plugin-markdown@2.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d085f292..e66b200f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.5", "eslint": "7.26.0", - "eslint-plugin-markdown": "2.1.0", + "eslint-plugin-markdown": "2.2.1", "express": "4.17.1", "mocha": "8.4.0", "nyc": "15.1.0", From d6c5c19b9f2270e04a64732987bd27a41d2b8ff1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 12 Nov 2021 21:19:50 -0500 Subject: [PATCH 647/766] build: eslint@7.32.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e66b200f..c590dfc2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.5", - "eslint": "7.26.0", + "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.1", "mocha": "8.4.0", From 81a15883317f052b48c17ab9638dc2cdcdceb0fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 1 Dec 2021 23:41:13 -0500 Subject: [PATCH 648/766] build: mocha@9.1.3 --- .github/workflows/ci.yml | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc4de3e9..6340057c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,9 +82,11 @@ jobs: - name: Node.js 10.x node-version: "10.24" + npm-i: mocha@8.4.0 - name: Node.js 11.x node-version: "11.15" + npm-i: mocha@8.4.0 - name: Node.js 12.x node-version: "12.22" diff --git a/package.json b/package.json index c590dfc2..be6ccc7b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.1", - "mocha": "8.4.0", + "mocha": "9.1.3", "nyc": "15.1.0", "supertest": "6.1.3" }, From 0a1534abce1bf4f115aa8c6171fc0db327ab89fa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 1 Dec 2021 23:43:27 -0500 Subject: [PATCH 649/766] build: cookie-parser@1.4.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be6ccc7b..3f1bd5f9 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "after": "0.8.2", - "cookie-parser": "1.4.5", + "cookie-parser": "1.4.6", "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.1", From 2f6cc21a23a1393c0740c6f6bda3261fcabee077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 6 Sep 2021 13:32:29 +0200 Subject: [PATCH 650/766] build: Node.js@16.9 closes #844 --- .github/workflows/ci.yml | 2 +- test/session.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6340057c..d06912fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.2" + node-version: "16.9" steps: - uses: actions/checkout@v2 diff --git a/test/session.js b/test/session.js index 7ce3c194..425ed2bc 100644 --- a/test/session.js +++ b/test/session.js @@ -581,7 +581,7 @@ describe('session()', function(){ request(server) .get('/') .set('Cookie', cookie(res)) - .expect(500, /Cannot read property/, done) + .expect(500, /Cannot read prop/, done) }) }) }) From 9ab975338843d84a6c3fe8e52939f3a186f32df9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Dec 2021 21:57:34 -0500 Subject: [PATCH 651/766] build: supertest@6.1.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f1bd5f9..03078057 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.1", "mocha": "9.1.3", "nyc": "15.1.0", - "supertest": "6.1.3" + "supertest": "6.1.6" }, "files": [ "session/", From 6782719ebecc8a6fe2cd5d24b79501bc8cce9474 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Dec 2021 21:58:27 -0500 Subject: [PATCH 652/766] build: express@4.17.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03078057..f83da9c0 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "cookie-parser": "1.4.6", "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", - "express": "4.17.1", + "express": "4.17.2", "mocha": "9.1.3", "nyc": "15.1.0", "supertest": "6.1.6" From b40e624ae8824f1d44500b0ea774ce97dfaf91b6 Mon Sep 17 00:00:00 2001 From: Max Andersson Date: Wed, 20 Oct 2021 11:18:06 +0100 Subject: [PATCH 653/766] docs: add connect-neo4j to the list of session stores closes #851 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 01477c39..2d1963b7 100644 --- a/README.md +++ b/README.md @@ -631,6 +631,11 @@ and other multi-core embedded devices). [connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2 [connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85 +[![โ˜…][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store. + +[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j +[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85 + [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple From 72ee3081a3577923dbfc739d2574d1938e15a07e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Dec 2021 22:15:35 -0500 Subject: [PATCH 654/766] build: Node.js@16.13 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d06912fe..462696b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.9" + node-version: "16.13" steps: - uses: actions/checkout@v2 From e2d3dfa5551a3506f0209fd482b0616d58d20784 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Dec 2021 22:16:01 -0500 Subject: [PATCH 655/766] build: support Node.js 17.x --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 462696b1..d3cf49ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ jobs: - Node.js 14.x - Node.js 15.x - Node.js 16.x + - Node.js 17.x include: - name: Node.js 0.8 @@ -103,6 +104,9 @@ jobs: - name: Node.js 16.x node-version: "16.13" + - name: Node.js 17.x + node-version: "17.3" + steps: - uses: actions/checkout@v2 From 66634e9f77132a444dfda7e279a399054e3b28df Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Dec 2021 22:19:48 -0500 Subject: [PATCH 656/766] build: Node.js@14.18 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3cf49ed..1f69a643 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: node-version: "13.14" - name: Node.js 14.x - node-version: "14.17" + node-version: "14.18" - name: Node.js 15.x node-version: "15.14" From c2eefb8572e8bf74789946886ec1dacebaeea368 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 Feb 2022 21:11:28 -0500 Subject: [PATCH 657/766] build: use mocha@2.5.3 for Node.js < 4 --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f69a643..d1cc3499 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,23 +39,23 @@ jobs: - name: Node.js 0.10 node-version: "0.10" - npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-i: mocha@2.5.3 nyc@10.3.2 supertest@2.0.0 - name: Node.js 0.12 node-version: "0.12" - npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-i: mocha@2.5.3 nyc@10.3.2 supertest@2.0.0 - name: io.js 1.x node-version: "1.8" - npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-i: mocha@2.5.3 nyc@10.3.2 supertest@2.0.0 - name: io.js 2.x node-version: "2.5" - npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-i: mocha@2.5.3 nyc@10.3.2 supertest@2.0.0 - name: io.js 3.x node-version: "3.3" - npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-i: mocha@2.5.3 nyc@10.3.2 supertest@2.0.0 - name: Node.js 4.x node-version: "4.9" From 3b91d4b2c733942713be2f6280be43e91ef36bc5 Mon Sep 17 00:00:00 2001 From: Travis Horn Date: Sun, 6 Feb 2022 14:08:07 -0600 Subject: [PATCH 658/766] docs: add connect-lowdb to the list of session stores closes #873 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2d1963b7..e2513c84 100644 --- a/README.md +++ b/README.md @@ -595,6 +595,11 @@ and other multi-core embedded devices). [connect-loki-url]: https://www.npmjs.com/package/connect-loki [connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85 +[![โ˜…][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store. + +[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb +[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85 + [![โ˜…][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. [connect-memcached-url]: https://www.npmjs.com/package/connect-memcached From 99b93afd52b3de4234a79ee956d0e36ff6ca674b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 19 Feb 2022 20:03:00 -0500 Subject: [PATCH 659/766] build: Node.js@17.5 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1cc3499..1136d442 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.13" - name: Node.js 17.x - node-version: "17.3" + node-version: "17.5" steps: - uses: actions/checkout@v2 From 00dd7075f2d60f8c9f87e5a739a0739ba362e9c7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 19 Feb 2022 20:06:00 -0500 Subject: [PATCH 660/766] build: Node.js@16.14 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1136d442..7ed18da5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.13" + node-version: "16.14" - name: Node.js 17.x node-version: "17.5" From 3b2406d00558dc6eaf42733579ec3f6af040f6cb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 19 Feb 2022 20:09:37 -0500 Subject: [PATCH 661/766] build: Node.js@14.19 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ed18da5..4018263c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: node-version: "13.14" - name: Node.js 14.x - node-version: "14.18" + node-version: "14.19" - name: Node.js 15.x node-version: "15.14" From 8108059514c7e4ae420f2d4e86c6987518a4a2ff Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 22 Feb 2022 00:12:46 -0500 Subject: [PATCH 662/766] build: mocha@9.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f83da9c0..f27aa2e2 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.2", - "mocha": "9.1.3", + "mocha": "9.2.1", "nyc": "15.1.0", "supertest": "6.1.6" }, From ca8e298823a8ebbc50de496c8f3bbc5909f78f16 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 22 Feb 2022 00:17:35 -0500 Subject: [PATCH 663/766] build: express@4.17.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f27aa2e2..4744c9f7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "cookie-parser": "1.4.6", "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", - "express": "4.17.2", + "express": "4.17.3", "mocha": "9.2.1", "nyc": "15.1.0", "supertest": "6.1.6" From 62d5df60f4d380a080d9a90b41ddb56b71446f35 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 3 Mar 2022 22:54:12 -0500 Subject: [PATCH 664/766] build: supertest@6.2.2 --- .github/workflows/ci.yml | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4018263c..1817a822 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,11 +67,11 @@ jobs: - name: Node.js 6.x node-version: "6.17" - npm-i: mocha@6.2.2 nyc@14.1.1 + npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6 - name: Node.js 7.x node-version: "7.10" - npm-i: mocha@6.2.2 nyc@14.1.1 + npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6 - name: Node.js 8.x node-version: "8.17" diff --git a/package.json b/package.json index 4744c9f7..5ae5f69a 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.3", "mocha": "9.2.1", "nyc": "15.1.0", - "supertest": "6.1.6" + "supertest": "6.2.2" }, "files": [ "session/", From 1c2a1d74f5e91948150af53eb406a89a218e0b09 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 3 Mar 2022 22:58:15 -0500 Subject: [PATCH 665/766] deps: cookie@0.4.2 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 774607dc..21cd8015 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: cookie@0.4.2 + 1.17.2 / 2021-05-19 =================== diff --git a/package.json b/package.json index 5ae5f69a..ec8e8446 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.4.1", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", From 796cd0259a7c2122c80900332bc61f9eedc1fba7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Mar 2022 18:55:23 -0400 Subject: [PATCH 666/766] build: Node.js@17.8 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1817a822..40e77f42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.14" - name: Node.js 17.x - node-version: "17.5" + node-version: "17.8" steps: - uses: actions/checkout@v2 From 9ea6d4a9e5614db8e667e7d8212b1f0e744f32d3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Mar 2022 18:58:05 -0400 Subject: [PATCH 667/766] build: mocha@9.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec8e8446..965e7185 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.3", - "mocha": "9.2.1", + "mocha": "9.2.2", "nyc": "15.1.0", "supertest": "6.2.2" }, From 5df613c481bc7c5979aeaeac691b64ef0a5c4948 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 Mar 2022 14:10:03 -0400 Subject: [PATCH 668/766] docs: document default cookie.sameSite closes #783 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e2513c84..0e2015d3 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ is the root path of the domain. ##### cookie.sameSite Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute. +By default, this is `false`. - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. - `false` will not set the `SameSite` attribute. From 070492992bd7a12b004b749d9215b344273b72ea Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 4 Apr 2022 19:43:16 -0400 Subject: [PATCH 669/766] docs: add user login example --- README.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e2015d3..45e68a98 100644 --- a/README.md +++ b/README.md @@ -829,7 +829,9 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session [tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85 -## Example +## Examples + +### View counter A simple example using `express-session` to store page views for a user. @@ -867,6 +869,87 @@ app.get('/foo', function (req, res, next) { app.get('/bar', function (req, res, next) { res.send('you viewed this page ' + req.session.views['/bar'] + ' times') }) + +app.listen(3000) +``` + +### User login + +A simple example using `express-session` to keep a user log in session. + +```js +var escapeHtml = require('escape-html') +var express = require('express') +var session = require('express-session') + +var app = express() + +app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true +})) + +// middleware to test if authenticated +function isAuthenticated (req, res, next) { + if (req.session.user) next() + else next('route') +} + +app.get('/', isAuthenticated, function (req, res) { + // this is only called when there is an authentication user due to isAuthenticated + res.send('hello, ' + escapeHtml(req.session.user) + '!' + + ' Logout') +}) + +app.get('/', function (req, res) { + res.send('
' + + 'Username:
' + + 'Password:
' + + '
') +}) + +app.post('/login', express.urlencoded({ extended: false }), function (req, res) { + // login logic to validate req.body.user and req.body.pass + // would be implemented here. for this example any combo works + + // regenerate the session, which is good practice to help + // guard against forms of session fixation + req.session.regenerate(function (err) { + if (err) next(err) + + // store user information in session, typically a user id + req.session.user = req.body.user + + // save the session before redirection to ensure page + // load does not happen before session is saved + req.session.save(function (err) { + if (err) return next(err) + res.redirect('/') + }) + }) +}) + +app.get('/logout', function (req, res, next) { + // logout logic + + // clear the user from the session object and save. + // this will ensure that re-using the old session id + // does not have a logged in user + req.session.user = null + req.session.save(function (err) { + if (err) next(err) + + // regenerate the session, which is good practice to help + // guard against forms of session fixation + req.session.regenerate(function (err) { + if (err) next(err) + res.redirect('/') + }) + }) +}) + +app.listen(3000) ``` ## Debugging From 78d1acd95ad07112c7bf4a5806730fb3f95ec792 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 Apr 2022 22:09:48 -0400 Subject: [PATCH 670/766] build: Node.js@17.9 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40e77f42..ae4cd745 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.14" - name: Node.js 17.x - node-version: "17.8" + node-version: "17.9" steps: - uses: actions/checkout@v2 From 18a10117962202ccc245a21590b0eef3a1e69fee Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 21 Apr 2022 21:54:27 -0400 Subject: [PATCH 671/766] build: support Node.js 18.x --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae4cd745..7847ca4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: - Node.js 15.x - Node.js 16.x - Node.js 17.x + - Node.js 18.x include: - name: Node.js 0.8 @@ -107,6 +108,9 @@ jobs: - name: Node.js 17.x node-version: "17.9" + - name: Node.js 18.x + node-version: "18.0" + steps: - uses: actions/checkout@v2 From 86ed9f3f6f3fed192ab85ea2c0db875c4942e3f0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 8 May 2022 20:41:49 -0400 Subject: [PATCH 672/766] build: supertest@6.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 965e7185..8cf683d6 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.3", "mocha": "9.2.2", "nyc": "15.1.0", - "supertest": "6.2.2" + "supertest": "6.2.3" }, "files": [ "session/", From 08f5dca7339517f59ca500b03b1da1deec996f66 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 8 May 2022 20:49:11 -0400 Subject: [PATCH 673/766] build: Node.js@16.15 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7847ca4a..bc591048 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,7 +103,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.14" + node-version: "16.15" - name: Node.js 17.x node-version: "17.9" From a1aebf29c8040a622631a60ad67f69a7815c0ceb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 8 May 2022 20:55:19 -0400 Subject: [PATCH 674/766] build: mocha@10.0.0 --- .github/workflows/ci.yml | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc591048..7e662fb3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,9 +92,11 @@ jobs: - name: Node.js 12.x node-version: "12.22" + npm-i: mocha@9.2.2 - name: Node.js 13.x node-version: "13.14" + npm-i: mocha@9.2.2 - name: Node.js 14.x node-version: "14.19" diff --git a/package.json b/package.json index 8cf683d6..9723dfe5 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.3", - "mocha": "9.2.2", + "mocha": "10.0.0", "nyc": "15.1.0", "supertest": "6.2.3" }, From a06b0beda7e9686c19c2f3dd3d72114c80e8457d Mon Sep 17 00:00:00 2001 From: Noah Liechti <38284563+noahliechti@users.noreply.github.com> Date: Fri, 14 Jan 2022 16:34:57 +0100 Subject: [PATCH 675/766] build: remove unnecessary entry from package files closes #869 --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 9723dfe5..15fec342 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "files": [ "session/", "HISTORY.md", - "LICENSE", "index.js" ], "engines": { From 99d6cdea3e04e6fb48c155c1e0ad507fde5d8702 Mon Sep 17 00:00:00 2001 From: Jeremy Neander Date: Mon, 18 Oct 2021 11:50:34 -0500 Subject: [PATCH 676/766] Fix resaving already-saved new session at end of request closes #849 --- HISTORY.md | 1 + index.js | 2 +- test/session.js | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 21cd8015..64fee3c7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix resaving already-saved new session at end of request * deps: cookie@0.4.2 1.17.2 / 2021-05-19 diff --git a/index.js b/index.js index d7efeab9..40a442ba 100644 --- a/index.js +++ b/index.js @@ -444,7 +444,7 @@ function session(options) { return false; } - return !saveUninitializedSession && cookieId !== req.sessionID + return !saveUninitializedSession && !savedHash && cookieId !== req.sessionID ? isModified(req.session) : !isSaved(req.session) } diff --git a/test/session.js b/test/session.js index 425ed2bc..7416b261 100644 --- a/test/session.js +++ b/test/session.js @@ -1775,6 +1775,31 @@ describe('session()', function(){ .expect(200, 'saved', done) }) }) + + describe('when saveUninitialized is false', function () { + it('should prevent end-of-request save', function (done) { + var store = new session.MemoryStore() + var server = createServer({ saveUninitialized: false, store: store }, function (req, res) { + req.session.hit = true + req.session.save(function (err) { + if (err) return res.end(err.message) + res.end('saved') + }) + }) + + request(server) + .get('/') + .expect(shouldSetSessionInStore(store)) + .expect(200, 'saved', function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetSessionInStore(store)) + .expect(200, 'saved', done) + }) + }) + }) }) describe('.touch()', function () { From 1010fadc2f071ddf2add94235d72224cf65159c6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 11 May 2022 14:51:00 -0400 Subject: [PATCH 677/766] 1.17.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 64fee3c7..9fdd147f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.17.3 / 2022-05-11 +=================== * Fix resaving already-saved new session at end of request * deps: cookie@0.4.2 diff --git a/package.json b/package.json index 15fec342..711e9866 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.17.2", + "version": "1.17.3", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From d06b73c3aaa08fda13e9834303d9556501f225b1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Sep 2022 20:40:44 -0400 Subject: [PATCH 678/766] build: downgrade nyc on Node.js 8/9 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e662fb3..807849bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,11 +76,11 @@ jobs: - name: Node.js 8.x node-version: "8.17" - npm-i: mocha@7.2.0 + npm-i: mocha@7.2.0 nyc@14.1.1 - name: Node.js 9.x node-version: "9.11" - npm-i: mocha@7.2.0 + npm-i: mocha@7.2.0 nyc@14.1.1 - name: Node.js 10.x node-version: "10.24" From 1e992fd5794f15e9640d6d6e37b714ecb04f033b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Sep 2022 20:47:06 -0400 Subject: [PATCH 679/766] build: Node.js@18.9 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 807849bc..b5af9c03 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,7 @@ jobs: node-version: "17.9" - name: Node.js 18.x - node-version: "18.0" + node-version: "18.9" steps: - uses: actions/checkout@v2 From 4b38b12c4c156018392311d05db4a8fc6f31fb36 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Dec 2022 20:38:38 -0500 Subject: [PATCH 680/766] build: mocha@10.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 711e9866..a2d2d119 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.3", - "mocha": "10.0.0", + "mocha": "10.2.0", "nyc": "15.1.0", "supertest": "6.2.3" }, From 4fafd15e5443f9d24d8dd12e59f5a5841c5a1de1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Dec 2022 20:42:08 -0500 Subject: [PATCH 681/766] build: Node.js@16.19 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5af9c03..98a8d85f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.15" + node-version: "16.19" - name: Node.js 17.x node-version: "17.9" From a8968b80c6a19741d67458cf402aadfbf3fba7d7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Dec 2022 20:43:49 -0500 Subject: [PATCH 682/766] build: Node.js@14.21 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98a8d85f..4095d9b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,7 +99,7 @@ jobs: npm-i: mocha@9.2.2 - name: Node.js 14.x - node-version: "14.19" + node-version: "14.21" - name: Node.js 15.x node-version: "15.14" From 474572597eac48ae2abd12b2df8741a13e6c2260 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 12 Dec 2022 20:45:17 -0500 Subject: [PATCH 683/766] build: Node.js@18.12 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4095d9b3..dcb37bed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,7 @@ jobs: node-version: "17.9" - name: Node.js 18.x - node-version: "18.9" + node-version: "18.12" steps: - uses: actions/checkout@v2 From a77973ba460aadd72afa8960ad01f463d23436ac Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jan 2023 22:53:53 -0500 Subject: [PATCH 684/766] build: support Node.js 19.x --- .github/workflows/ci.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcb37bed..33cd7fea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: - Node.js 16.x - Node.js 17.x - Node.js 18.x + - Node.js 19.x include: - name: Node.js 0.8 @@ -113,6 +114,9 @@ jobs: - name: Node.js 18.x node-version: "18.12" + - name: Node.js 19.x + node-version: "19.4" + steps: - uses: actions/checkout@v2 @@ -129,7 +133,12 @@ jobs: dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" - name: Configure npm - run: npm config set shrinkwrap false + run: | + if [[ "$(npm config get package-lock)" == "true" ]]; then + npm config set package-lock false + else + npm config set shrinkwrap false + fi - name: Remove npm module(s) ${{ matrix.npm-rm }} run: npm rm --silent --save-dev ${{ matrix.npm-rm }} From a1f7b0f6fa6c91ad9b0737f776ce273b7d8b64e8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jan 2023 22:58:49 -0500 Subject: [PATCH 685/766] build: supertest@6.3.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a2d2d119..dbcf990b 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.3", "mocha": "10.2.0", "nyc": "15.1.0", - "supertest": "6.2.3" + "supertest": "6.3.3" }, "files": [ "session/", From d21a69faa8415c759f4464cb3890066351434e7c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Jan 2023 23:02:12 -0500 Subject: [PATCH 686/766] build: eslint@8.31.0 --- .github/workflows/ci.yml | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33cd7fea..7519f5cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,8 +152,8 @@ jobs: shell: bash run: | # eslint for linting - # - remove on Node.js < 10 - if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then + # - remove on Node.js < 12 + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 12 ]]; then node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ grep -E '^eslint(-|$)' | \ sort -r | \ diff --git a/package.json b/package.json index dbcf990b..ef7ad2dd 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.6", - "eslint": "7.32.0", - "eslint-plugin-markdown": "2.2.1", + "eslint": "8.31.0", + "eslint-plugin-markdown": "3.0.0", "express": "4.17.3", "mocha": "10.2.0", "nyc": "15.1.0", From b57e1868b9ed38edc4703fbfef3261c364f57ea3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 3 May 2023 18:44:55 -0400 Subject: [PATCH 687/766] build: Node.js@18.16 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7519f5cf..c96b39e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,7 +112,7 @@ jobs: node-version: "17.9" - name: Node.js 18.x - node-version: "18.12" + node-version: "18.16" - name: Node.js 19.x node-version: "19.4" From 249ea7259abf25b4d396652b338359408e6db4b2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 3 May 2023 18:47:26 -0400 Subject: [PATCH 688/766] build: Node.js@19.9 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c96b39e1..7b8c7cf6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,7 +115,7 @@ jobs: node-version: "18.16" - name: Node.js 19.x - node-version: "19.4" + node-version: "19.9" steps: - uses: actions/checkout@v2 From bd69beef941a982013a21704fa8eb7214db13765 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 3 May 2023 18:49:08 -0400 Subject: [PATCH 689/766] build: support Node.js 20.x --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b8c7cf6..02605500 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,7 @@ jobs: - Node.js 17.x - Node.js 18.x - Node.js 19.x + - Node.js 20.x include: - name: Node.js 0.8 @@ -117,6 +118,9 @@ jobs: - name: Node.js 19.x node-version: "19.9" + - name: Node.js 20.x + node-version: "20.1" + steps: - uses: actions/checkout@v2 From 710ae0620eae293d765882fc7056f0511218e525 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Jun 2023 22:49:45 -0400 Subject: [PATCH 690/766] build: eslint@8.42.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef7ad2dd..ee0252f0 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.6", - "eslint": "8.31.0", + "eslint": "8.42.0", "eslint-plugin-markdown": "3.0.0", "express": "4.17.3", "mocha": "10.2.0", From d8a8fe23e78e65b81e6e1ab4bcaa13061fa4a89f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 8 Jun 2023 23:02:49 -0400 Subject: [PATCH 691/766] Support any type in "secret" that crypto.createHmac supports --- HISTORY.md | 6 ++++++ README.md | 13 +++++++------ package.json | 2 +- test/session.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9fdd147f..30facb56 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * Support any type in `secret` that `crypto.createHmac` supports + * deps: cookie-signature@1.0.7 + 1.17.3 / 2022-05-11 =================== diff --git a/README.md b/README.md index 45e68a98..b5dbcba5 100644 --- a/README.md +++ b/README.md @@ -274,12 +274,13 @@ it to be saved. *This has been fixed in PassportJS 0.3.0* **Required option** -This is the secret used to sign the session ID cookie. This can be either a string -for a single secret, or an array of multiple secrets. If an array of secrets is -provided, only the first element will be used to sign the session ID cookie, while -all the elements will be considered when verifying the signature in requests. The -secret itself should be not easily parsed by a human and would best be a random set -of characters. A best practice may include: +This is the secret used to sign the session ID cookie. The secret can be any type +of value that is supported by Node.js `crypto.createHmac` (like a string or a +`Buffer`). This can be either a single secret, or an array of multiple secrets. If +an array of secrets is provided, only the first element will be used to sign the +session ID cookie, while all the elements will be considered when verifying the +signature in requests. The secret itself should be not easily parsed by a human and +would best be a random set of characters. A best practice may include: - The use of environment variables to store the secret, ensuring the secret itself does not exist in your repository. diff --git a/package.json b/package.json index ee0252f0..b58aea28 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "license": "MIT", "dependencies": { "cookie": "0.4.2", - "cookie-signature": "1.0.6", + "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", diff --git a/test/session.js b/test/session.js index 7416b261..09893902 100644 --- a/test/session.js +++ b/test/session.js @@ -2,6 +2,7 @@ var after = require('after') var assert = require('assert') var cookieParser = require('cookie-parser') +var crypto = require('crypto') var express = require('express') var fs = require('fs') var http = require('http') @@ -1197,6 +1198,50 @@ describe('session()', function(){ assert.throws(createServer.bind(null, { secret: [] }), /secret option array/); }) + it('should sign and unsign with a string', function (done) { + var server = createServer({ secret: 'awesome cat' }, function (req, res) { + if (!req.session.user) { + req.session.user = 'bob' + res.end('set') + } else { + res.end('get:' + JSON.stringify(req.session.user)) + } + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'set', function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'get:"bob"', done) + }) + }) + + it('should sign and unsign with a Buffer', function (done) { + var server = createServer({ secret: crypto.randomBytes(32) }, function (req, res) { + if (!req.session.user) { + req.session.user = 'bob' + res.end('set') + } else { + res.end('get:' + JSON.stringify(req.session.user)) + } + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'set', function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'get:"bob"', done) + }) + }) + describe('when an array', function () { it('should sign cookies', function (done) { var server = createServer({ secret: ['keyboard cat', 'nyan cat'] }, function (req, res) { From b3530542ec675d6a9d913837f1a4853b550a3cff Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Aug 2023 20:43:37 -0400 Subject: [PATCH 692/766] build: Node.js@20.5 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02605500..9c841b72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,7 +119,7 @@ jobs: node-version: "19.9" - name: Node.js 20.x - node-version: "20.1" + node-version: "20.5" steps: - uses: actions/checkout@v2 From 7adb9fec0ac0875a6cce73b6b4eade9b11b65d53 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Aug 2023 20:46:22 -0400 Subject: [PATCH 693/766] build: Node.js@18.17 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c841b72..dd6b1f25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,7 +113,7 @@ jobs: node-version: "17.9" - name: Node.js 18.x - node-version: "18.16" + node-version: "18.17" - name: Node.js 19.x node-version: "19.9" From addaa54541a285c6e725b05d5e81fc6542111dce Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Aug 2023 20:47:14 -0400 Subject: [PATCH 694/766] build: Node.js@16.20 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd6b1f25..502a3280 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,7 +107,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.19" + node-version: "16.20" - name: Node.js 17.x node-version: "17.9" From 49e5eb67b72dd8e5618f9f9317828d696520d960 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 Sep 2023 19:54:52 -0400 Subject: [PATCH 695/766] build: eslint@8.49.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b58aea28..0aa03a97 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.6", - "eslint": "8.42.0", + "eslint": "8.49.0", "eslint-plugin-markdown": "3.0.0", "express": "4.17.3", "mocha": "10.2.0", From 25cedf86553bf89c7ea81c8a12cc479d9bd8defd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 Sep 2023 19:57:08 -0400 Subject: [PATCH 696/766] build: eslint-plugin-markdown@3.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0aa03a97..597df1a9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "after": "0.8.2", "cookie-parser": "1.4.6", "eslint": "8.49.0", - "eslint-plugin-markdown": "3.0.0", + "eslint-plugin-markdown": "3.0.1", "express": "4.17.3", "mocha": "10.2.0", "nyc": "15.1.0", From 54a8ee59e533639fbede38f00884e6ef0580e516 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Nov 2023 23:10:58 -0500 Subject: [PATCH 697/766] build: support Node.js 21.x --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 502a3280..ba089e20 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,7 @@ jobs: - Node.js 18.x - Node.js 19.x - Node.js 20.x + - Node.js 21.x include: - name: Node.js 0.8 @@ -121,6 +122,9 @@ jobs: - name: Node.js 20.x node-version: "20.5" + - name: Node.js 21.x + node-version: "21.1" + steps: - uses: actions/checkout@v2 From e942982391130adeea57d5555ebfc0b83f6bee1e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Nov 2023 23:12:06 -0500 Subject: [PATCH 698/766] build: Node.js@20.9 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba089e20..65a945cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: node-version: "19.9" - name: Node.js 20.x - node-version: "20.5" + node-version: "20.9" - name: Node.js 21.x node-version: "21.1" From fc24b2640abd9ebec295ff3b426c09691ef51e7a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Nov 2023 23:14:32 -0500 Subject: [PATCH 699/766] build: Node.js@18.18 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65a945cb..4c51044d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,7 +114,7 @@ jobs: node-version: "17.9" - name: Node.js 18.x - node-version: "18.17" + node-version: "18.18" - name: Node.js 19.x node-version: "19.9" From 4bfc5baa0dc368352faf41e340fea812dee90fbd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Dec 2023 20:33:10 -0500 Subject: [PATCH 700/766] build: use $GITHUB_OUTPUT for environment list --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c51044d..b0c097c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -178,7 +178,7 @@ jobs: echo "node@$(node -v)" echo "npm@$(npm -v)" npm -s ls ||: - (npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print "::set-output name=" $2 "::" $3 }' + (npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print $2 "=" $3 }' >> "$GITHUB_OUTPUT" - name: Run tests shell: bash From c1611ad8b3f9c7564d130040c2b188293727e155 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Dec 2023 20:34:20 -0500 Subject: [PATCH 701/766] build: actions/checkout@v3 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0c097c9..7c3ee7df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,7 +126,7 @@ jobs: node-version: "21.1" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install Node.js ${{ matrix.node-version }} shell: bash -eo pipefail -l {0} From 825e6c00c13d472be8b08f202209668ad3a1769d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 10 Dec 2023 20:38:10 -0500 Subject: [PATCH 702/766] build: fix code coverage aggregate upload --- .github/workflows/ci.yml | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c3ee7df..2d4bfc2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -185,6 +185,7 @@ jobs: run: | if npm -ps ls nyc | grep -q nyc; then npm run test-ci + cp coverage/lcov.info "coverage/${{ matrix.name }}.lcov" else npm test fi @@ -194,19 +195,43 @@ jobs: run: npm run lint - name: Collect code coverage - uses: coverallsapp/github-action@master + if: steps.list_env.outputs.nyc != '' + run: | + if [[ -d ./coverage ]]; then + mv ./coverage "./${{ matrix.name }}" + mkdir ./coverage + mv "./${{ matrix.name }}" "./coverage/${{ matrix.name }}" + fi + + - name: Upload code coverage + uses: actions/upload-artifact@v3 if: steps.list_env.outputs.nyc != '' with: - github-token: ${{ secrets.GITHUB_TOKEN }} - flag-name: run-${{ matrix.test_number }} - parallel: true + name: coverage + path: ./coverage + retention-days: 1 coverage: needs: test runs-on: ubuntu-latest steps: - - name: Upload code coverage + - uses: actions/checkout@v3 + + - name: Install lcov + shell: bash + run: sudo apt-get -y install lcov + + - name: Collect coverage reports + uses: actions/download-artifact@v3 + with: + name: coverage + path: ./coverage + + - name: Merge coverage reports + shell: bash + run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./coverage/lcov.info + + - name: Upload coverage report uses: coverallsapp/github-action@master with: - github-token: ${{ secrets.github_token }} - parallel-finished: true + github-token: ${{ secrets.GITHUB_TOKEN }} From 6b7c9a0d29aa0dee84ffdffb5da2d88f53906832 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 3 Jan 2024 19:44:48 -0500 Subject: [PATCH 703/766] build: Node.js@21.5 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d4bfc2c..e770d94a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: node-version: "20.9" - name: Node.js 21.x - node-version: "21.1" + node-version: "21.5" steps: - uses: actions/checkout@v3 From 8e9f7a4a701b77a8baff1ea3f7b568dc70bf6ecf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 3 Jan 2024 19:45:09 -0500 Subject: [PATCH 704/766] build: Node.js@20.10 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e770d94a..cde69396 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: node-version: "19.9" - name: Node.js 20.x - node-version: "20.9" + node-version: "20.10" - name: Node.js 21.x node-version: "21.5" From 7dec651403d4ce7b072c2992914a0a28b93922a0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 3 Jan 2024 19:46:01 -0500 Subject: [PATCH 705/766] build: Node.js@18.19 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cde69396..d4d66ca1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,7 +114,7 @@ jobs: node-version: "17.9" - name: Node.js 18.x - node-version: "18.18" + node-version: "18.19" - name: Node.js 19.x node-version: "19.9" From a46e8578183efffe8fdc122375b53bd2c9ee51b1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 27 Jan 2024 21:40:27 -0500 Subject: [PATCH 706/766] supertest@6.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 597df1a9..2b12839e 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "express": "4.17.3", "mocha": "10.2.0", "nyc": "15.1.0", - "supertest": "6.3.3" + "supertest": "6.3.4" }, "files": [ "session/", From 2a7a50bcbc2d5844c030d4d684108f09f60b460c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 27 Jan 2024 21:42:33 -0500 Subject: [PATCH 707/766] eslint@8.56.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b12839e..2f5190c8 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "after": "0.8.2", "cookie-parser": "1.4.6", - "eslint": "8.49.0", + "eslint": "8.56.0", "eslint-plugin-markdown": "3.0.1", "express": "4.17.3", "mocha": "10.2.0", From e5f19cedac9edcc754dda7807f99e834614763d6 Mon Sep 17 00:00:00 2001 From: Lukas Elmer Date: Mon, 14 Nov 2022 17:45:37 +0100 Subject: [PATCH 708/766] docs: add note on length of secret closes #919 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b5dbcba5..6ce6ae4a 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,9 @@ the secret without invalidating sessions, provide an array of secrets, with the secret as first element of the array, and including previous secrets as the later elements. +**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should +contain at least 32 bytes of entropy. + ##### store The session store instance, defaults to a new `MemoryStore` instance. From a1f884fb8f8937d7b1628bbe5349ee6aa375742f Mon Sep 17 00:00:00 2001 From: Kam Lasater Date: Wed, 30 Nov 2022 15:08:10 -0500 Subject: [PATCH 709/766] docs: add @cyclic.sh/session-store to the list of session stores closes #922 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 6ce6ae4a..39d14796 100644 --- a/README.md +++ b/README.md @@ -818,6 +818,11 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb [session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85 +[![โ˜…][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps. + +[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store +[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85 + [![โ˜…][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store. [@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store From 9d377c5a58295cdb77e6b85dc4c0a5ab63c78ddf Mon Sep 17 00:00:00 2001 From: Jordan Day Date: Mon, 27 Feb 2023 13:35:06 -0600 Subject: [PATCH 710/766] docs: add dynamodb-store-v3 to the list of session stores closes #930 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 39d14796..21303c32 100644 --- a/README.md +++ b/README.md @@ -693,6 +693,11 @@ and other multi-core embedded devices). [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store [dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85 +[![โ˜…][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3). + +[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3 +[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85 + [![โ˜…][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. [express-etcd-url]: https://www.npmjs.com/package/express-etcd From 71c3f741080703520f16bccf8ed455f193cb69bb Mon Sep 17 00:00:00 2001 From: Ajesh DS Date: Mon, 24 Jul 2023 04:32:30 +0530 Subject: [PATCH 711/766] docs: add connect-cosmosdb to the list of session stores closes #950 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 21303c32..ab2de080 100644 --- a/README.md +++ b/README.md @@ -560,6 +560,11 @@ and other multi-core embedded devices). [connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store [connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85 +[![โ˜…][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store. + +[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb +[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85 + [![โ˜…][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase From 3ee08c466c37f2eb81d18ce13f0d3653416f79df Mon Sep 17 00:00:00 2001 From: Marc Udoff Date: Mon, 1 May 2023 11:36:09 -0400 Subject: [PATCH 712/766] Add "priority" to cookie options closes #884 closes #939 --- HISTORY.md | 5 +++++ README.md | 15 +++++++++++++++ package.json | 2 +- session/cookie.js | 3 ++- test/cookie.js | 8 ++++++++ test/session.js | 22 +++++++++++++++------- 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 30facb56..29e5657a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,12 @@ unreleased ========== + * Add `priority` to `cookie` options * Support any type in `secret` that `crypto.createHmac` supports + * deps: cookie@0.5.0 + - Fix `expires` option to reject invalid dates + - perf: improve default decode speed + - perf: remove slow string split in parse * deps: cookie-signature@1.0.7 1.17.3 / 2022-05-11 diff --git a/README.md b/README.md index ab2de080..5096ac0f 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,20 @@ defined in the object is what is used. Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. +##### cookie.priority + +Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. + + - `'low'` will set the `Priority` attribute to `Low`. + - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set. + - `'high'` will set the `Priority` attribute to `High`. + +More information about the different priority levels can be found in +[the specification][rfc-west-cookie-priority-00-4.1]. + +**Note** This is an attribute that has not yet been fully standardized, and may change in the future. +This also means many clients may ignore this attribute until they understand it. + ##### cookie.sameSite Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute. @@ -994,6 +1008,7 @@ On Windows, use the corresponding command; [MIT](LICENSE) [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 +[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 [ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci [ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master diff --git a/package.json b/package.json index 2f5190c8..f3d663b4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.4.2", + "cookie": "0.5.0", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", diff --git a/session/cookie.js b/session/cookie.js index a8b4e570..ff24d08b 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -116,7 +116,8 @@ Cookie.prototype = { get data() { return { - originalMaxAge: this.originalMaxAge + originalMaxAge: this.originalMaxAge, + priority: this.priority , expires: this._expires , secure: this.secure , httpOnly: this.httpOnly diff --git a/test/cookie.js b/test/cookie.js index 65ae1fc3..0869db9e 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -114,5 +114,13 @@ describe('new Cookie()', function () { assert.strictEqual(cookie.path, '/foo') }) }) + + describe('priority', function () { + it('should set priority', function () { + var cookie = new Cookie({ priority: 'high' }) + + assert.strictEqual(cookie.priority, 'high') + }) + }) }) }) diff --git a/test/session.js b/test/session.js index 09893902..755017d1 100644 --- a/test/session.js +++ b/test/session.js @@ -1923,18 +1923,26 @@ describe('session()', function(){ }) it('should override defaults', function(done){ - var server = createServer({ cookie: { path: '/admin', httpOnly: false, secure: true, maxAge: 5000 } }, function (req, res) { + var opts = { + httpOnly: false, + maxAge: 5000, + path: '/admin', + priority: 'high', + secure: true + } + var server = createServer({ cookie: opts }, function (req, res) { req.session.cookie.secure = false res.end() }) request(server) - .get('/admin') - .expect(shouldSetCookieWithAttribute('connect.sid', 'Expires')) - .expect(shouldSetCookieWithoutAttribute('connect.sid', 'HttpOnly')) - .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Path', '/admin')) - .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) - .expect(200, done) + .get('/admin') + .expect(shouldSetCookieWithAttribute('connect.sid', 'Expires')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'HttpOnly')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Path', '/admin')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Priority', 'High')) + .expect(200, done) }) it('should preserve cookies set before writeHead is called', function(done){ From f9f2318615bd12ad47342fd8cd88a1e0b52686f1 Mon Sep 17 00:00:00 2001 From: Alexandre ZANNI <16578570+noraj@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:22:16 +0200 Subject: [PATCH 713/766] docs: remove session-rethinkdb to the list of session stores closes #960 --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 5096ac0f..2ee2385e 100644 --- a/README.md +++ b/README.md @@ -837,11 +837,6 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store [session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85 -[![โ˜…][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. - -[session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb -[session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85 - [![โ˜…][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps. [@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store From d9354ef09ffb1b750b7cd3eb0ddd3f0cdfd4bfab Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 28 Jan 2024 14:44:24 -0500 Subject: [PATCH 714/766] Fix handling errors from setting cookie --- HISTORY.md | 1 + index.js | 6 +++++- test/session.js | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 29e5657a..c0f46aa2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Add `priority` to `cookie` options + * Fix handling errors from setting cookie * Support any type in `secret` that `crypto.createHmac` supports * deps: cookie@0.5.0 - Fix `expires` option to reject invalid dates diff --git a/index.js b/index.js index 40a442ba..981262cc 100644 --- a/index.js +++ b/index.js @@ -240,7 +240,11 @@ function session(options) { } // set cookie - setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data); + try { + setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data) + } catch (err) { + defer(next, err) + } }); // proxy end() to commit the session diff --git a/test/session.js b/test/session.js index 755017d1..e1b6419b 100644 --- a/test/session.js +++ b/test/session.js @@ -1945,6 +1945,23 @@ describe('session()', function(){ .expect(200, done) }) + it('should forward errors setting cookie', function (done) { + var cb = after(2, done) + var server = createServer({ cookie: { expires: new Date(NaN) } }, function (req, res) { + res.end() + }) + + server.on('error', function onerror (err) { + assert.ok(err) + assert.strictEqual(err.message, 'option expires is invalid') + cb() + }) + + request(server) + .get('/admin') + .expect(200, cb) + }) + it('should preserve cookies set before writeHead is called', function(done){ var server = createServer(null, function (req, res) { var cookie = new Cookie() From 88e0f2eff2a9b2456d70c1d5edac3c45b1552581 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 28 Jan 2024 14:46:52 -0500 Subject: [PATCH 715/766] build: actions/checkout@v4 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4d66ca1..a27948bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,7 +126,7 @@ jobs: node-version: "21.5" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Node.js ${{ matrix.node-version }} shell: bash -eo pipefail -l {0} @@ -215,7 +215,7 @@ jobs: needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install lcov shell: bash From 6153b3f52ddad6d975c40b851694602a5be3d35b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 28 Jan 2024 14:57:28 -0500 Subject: [PATCH 716/766] build: Node.js@21.6 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a27948bd..66f1f09c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: node-version: "20.10" - name: Node.js 21.x - node-version: "21.5" + node-version: "21.6" steps: - uses: actions/checkout@v4 From 50e1429314e3b08b3680a3805a849e68414afc4b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 28 Jan 2024 14:57:37 -0500 Subject: [PATCH 717/766] build: Node.js@20.11 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66f1f09c..38dc4da7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: node-version: "19.9" - name: Node.js 20.x - node-version: "20.10" + node-version: "20.11" - name: Node.js 21.x node-version: "21.6" From 408229ea3373097732875315d6f63c45e39fd3b6 Mon Sep 17 00:00:00 2001 From: Alex Op Date: Tue, 26 Dec 2023 11:09:58 +0100 Subject: [PATCH 718/766] Add "partitioned" to cookie options fixes #961 closes #966 --- HISTORY.md | 3 ++- README.md | 13 +++++++++++++ package.json | 2 +- session/cookie.js | 1 + test/cookie.js | 8 ++++++++ test/session.js | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c0f46aa2..ef77098b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,10 +1,11 @@ unreleased ========== + * Add `partitioned` to `cookie` options * Add `priority` to `cookie` options * Fix handling errors from setting cookie * Support any type in `secret` that `crypto.createHmac` supports - * deps: cookie@0.5.0 + * deps: cookie@0.6.0 - Fix `expires` option to reject invalid dates - perf: improve default decode speed - perf: remove slow string split in parse diff --git a/README.md b/README.md index 2ee2385e..e8d6db55 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,18 @@ no maximum age is set. **Note** If both `expires` and `maxAge` are set in the options, then the last one defined in the object is what is used. +##### cookie.partitioned + +Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies) +attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. +By default, the `Partitioned` attribute is not set. + +**Note** This is an attribute that has not yet been fully standardized, and may +change in the future. This also means many clients may ignore this attribute until +they understand it. + +More information about can be found in [the proposal](https://github.com/privacycg/CHIPS). + ##### cookie.path Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which @@ -1003,6 +1015,7 @@ On Windows, use the corresponding command; [MIT](LICENSE) [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 +[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ [rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 [ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci [ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci diff --git a/package.json b/package.json index f3d663b4..52cd1d00 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", diff --git a/session/cookie.js b/session/cookie.js index ff24d08b..8bb5907b 100644 --- a/session/cookie.js +++ b/session/cookie.js @@ -117,6 +117,7 @@ Cookie.prototype = { get data() { return { originalMaxAge: this.originalMaxAge, + partitioned: this.partitioned, priority: this.priority , expires: this._expires , secure: this.secure diff --git a/test/cookie.js b/test/cookie.js index 0869db9e..ea676e35 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -107,6 +107,14 @@ describe('new Cookie()', function () { }) }) + describe('partitioned', function () { + it('should set partitioned', function () { + var cookie = new Cookie({ partitioned: true }) + + assert.strictEqual(cookie.partitioned, true) + }) + }) + describe('path', function () { it('should set path', function () { var cookie = new Cookie({ path: '/foo' }) diff --git a/test/session.js b/test/session.js index e1b6419b..7bf3e51f 100644 --- a/test/session.js +++ b/test/session.js @@ -2233,6 +2233,41 @@ describe('session()', function(){ }) }) }) + + describe('.partitioned', function () { + describe('by default', function () { + it('should not set partitioned attribute', function (done) { + var server = createServer() + + request(server) + .get('/') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Partitioned')) + .expect(200, done) + }) + }) + + describe('when "false"', function () { + it('should not set partitioned attribute', function (done) { + var server = createServer({ cookie: { partitioned: false } }) + + request(server) + .get('/') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Partitioned')) + .expect(200, done) + }) + }) + + describe('when "true"', function () { + it('should set partitioned attribute', function (done) { + var server = createServer({ cookie: { partitioned: true } }) + + request(server) + .get('/') + .expect(shouldSetCookieWithAttribute('connect.sid', 'Partitioned')) + .expect(200, done) + }) + }) + }) }) }) From 991b7ee815d32cb7e17ce51904d007596e8ec862 Mon Sep 17 00:00:00 2001 From: Kenneth Tan Xin You Date: Wed, 18 Aug 2021 16:27:40 +0800 Subject: [PATCH 719/766] Add debug log for pathname mismatch closes #840 --- HISTORY.md | 1 + index.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index ef77098b..ea175bdb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Add debug log for pathname mismatch * Add `partitioned` to `cookie` options * Add `priority` to `cookie` options * Fix handling errors from setting cookie diff --git a/index.js b/index.js index 981262cc..d41b2378 100644 --- a/index.js +++ b/index.js @@ -193,7 +193,11 @@ function session(options) { // pathname mismatch var originalPath = parseUrl.original(req).pathname || '/' - if (originalPath.indexOf(cookieOptions.path || '/') !== 0) return next(); + if (originalPath.indexOf(cookieOptions.path || '/') !== 0) { + debug('pathname mismatch') + next() + return + } // ensure a secret is available or bail if (!secret && !req.secret) { From 855f21ab9325b6be1b857c582b7ba810595d3bf5 Mon Sep 17 00:00:00 2001 From: noiissyboy Date: Wed, 18 May 2022 10:49:07 +0530 Subject: [PATCH 720/766] docs: add connect-ottoman to the list of session stores closes #895 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index e8d6db55..65a37e63 100644 --- a/README.md +++ b/README.md @@ -677,6 +677,11 @@ and other multi-core embedded devices). [connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j [connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85 +[![โ˜…][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store. + +[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman +[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85 + [![โ˜…][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple From 24d4972764d2c962f806c38357f257cf97081009 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 28 Jan 2024 16:20:57 -0500 Subject: [PATCH 721/766] 1.18.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ea175bdb..a9903c03 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +1.18.0 / 2024-01-28 +=================== * Add debug log for pathname mismatch * Add `partitioned` to `cookie` options diff --git a/package.json b/package.json index 52cd1d00..597a6994 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.17.3", + "version": "1.18.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 8f0a1c4a35d80293eb51633e90916bdbdaa09ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8D=C3=B1igo=20Marqu=C3=ADnez=20Prado?= <25435858+inigomarquinez@users.noreply.github.com> Date: Tue, 14 May 2024 18:19:12 +0200 Subject: [PATCH 722/766] ci: add support for OSSF scorecard reporting (#984) PR-URL: https://github.com/expressjs/session/pull/984 --- .github/workflows/scorecard.yml | 73 +++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/workflows/scorecard.yml diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 00000000..0e064f47 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,73 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security + +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '16 21 * * 1' + push: + branches: [ "master" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + # Uncomment the permissions below if installing in a private repository. + # contents: read + # actions: read + + steps: + - name: "Checkout code" + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@2f93e4319b2f04a2efc38fa7f78bd681bc3f7b2f # v2.23.2 + with: + sarif_file: results.sarif From 341b179ec67c85c751ba0f5cfee8e514a139f630 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 8 Oct 2024 18:50:29 +0100 Subject: [PATCH 723/766] dep: cookie@0.7.2 (#997) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ulises Gascรณn --- HISTORY.md | 15 +++++++++++++++ package.json | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index a9903c03..256606b7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,18 @@ +unreleased +========== + + + * deps: cookie@0.7.2 + - Fix object assignment of `hasOwnProperty` + * deps: cookie@0.7.1 + - Allow leading dot for domain + - Although not permitted in the spec, some users expect this to work and user agents ignore the leading dot according to spec + - Add fast path for `serialize` without options, use `obj.hasOwnProperty` when parsing + * deps: cookie@0.7.0 + - perf: parse cookies ~10% faster + - fix: narrow the validation of cookies to match RFC6265 + - fix: add `main` to `package.json` for rspack + 1.18.0 / 2024-01-28 =================== diff --git a/package.json b/package.json index 597a6994..910f8b6a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "repository": "expressjs/session", "license": "MIT", "dependencies": { - "cookie": "0.6.0", + "cookie": "0.7.2", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", From bbeca94e69b93d437c4ca300b111bd59169de925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Tue, 8 Oct 2024 21:52:45 +0200 Subject: [PATCH 724/766] 1.18.1 PR-URL: https://github.com/expressjs/session/pull/998 --- HISTORY.md | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 256606b7..57c68d3a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,6 @@ -unreleased +1.18.1 / 2024-10-08 ========== - * deps: cookie@0.7.2 - Fix object assignment of `hasOwnProperty` * deps: cookie@0.7.1 diff --git a/package.json b/package.json index 910f8b6a..e3322438 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.18.0", + "version": "1.18.1", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 460e18c8f3b0cc21a437e984f0ea04b9c0138193 Mon Sep 17 00:00:00 2001 From: BaileyFirman Date: Thu, 21 Nov 2024 16:29:59 +1300 Subject: [PATCH 725/766] Refresh server.crt with existing key extending expiry to Nov 21 03:28:10 2024 GMT --- test/fixtures/server.crt | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/test/fixtures/server.crt b/test/fixtures/server.crt index c019198a..3f68e2f2 100644 --- a/test/fixtures/server.crt +++ b/test/fixtures/server.crt @@ -1,14 +1,15 @@ -----BEGIN CERTIFICATE----- -MIICMzCCAZwCCQCJTms0qcIZgDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJV -UzEQMA4GA1UECBMHSW5kaWFuYTEdMBsGA1UEChMUbm9kZS1leHByZXNzLXNlc3Np -b24xHjAcBgNVBAMTFWV4cHJlc3Mtc2Vzc2lvbi5sb2NhbDAeFw0xNDExMjMwNTQ3 -MzlaFw0yNDExMjAwNTQ3MzlaMF4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdJbmRp -YW5hMR0wGwYDVQQKExRub2RlLWV4cHJlc3Mtc2Vzc2lvbjEeMBwGA1UEAxMVZXhw -cmVzcy1zZXNzaW9uLmxvY2FsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY -G398zqN6Yv/FAx77eoLLje4VNCYDXUciWBzceaZ5u/rtP/XshTQWDKFfUbb/kmni -DazsCasSoNsUCrcqQPJF1jF3F9XjsZxcggDab8MAbAMhnhJax2l3yPJsWnB/8mrY -cdsdQNPXJxQW9MMZgUxz73gIY5/rEeayU9owgcnVcQIDAQABMA0GCSqGSIb3DQEB -BQUAA4GBADi0XXsZlQAKxOyD4qvdJNWJXlfqhr1q53dZmfF7nikDaMDiMspczTS/ -pxNbq2UaMc7g+6qmXPaPQoN3laQQtMdyVfSh6EIJHbzXXzdcCT4fDBYX7iwvh0Gg -DUpjmxmCzFCaob9+hZzwbJi5MFQ4Qq12LW1aYHMs8wgLboHml1WL +MIICWzCCAcSgAwIBAgIJAIlOazSpwhmAMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdJbmRpYW5hMR0wGwYDVQQKExRub2RlLWV4cHJlc3Mt +c2Vzc2lvbjEeMBwGA1UEAxMVZXhwcmVzcy1zZXNzaW9uLmxvY2FsMB4XDTI0MTEy +MTAzMjgxMFoXDTM0MTExOTAzMjgxMFowXjELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0luZGlhbmExHTAbBgNVBAoTFG5vZGUtZXhwcmVzcy1zZXNzaW9uMR4wHAYDVQQD +ExVleHByZXNzLXNlc3Npb24ubG9jYWwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBANgbf3zOo3pi/8UDHvt6gsuN7hU0JgNdRyJYHNx5pnm7+u0/9eyFNBYMoV9R +tv+SaeINrOwJqxKg2xQKtypA8kXWMXcX1eOxnFyCANpvwwBsAyGeElrHaXfI8mxa +cH/yathx2x1A09cnFBb0wxmBTHPveAhjn+sR5rJT2jCBydVxAgMBAAGjITAfMB0G +A1UdDgQWBBTqXycJwRboThk0uB3Cd3+oSLz1fjANBgkqhkiG9w0BAQsFAAOBgQCT +/E1rZGxemZZ5F8qX9SoTsc04ELEwT3PwA0cgU5fGmWmajPfjw339y53EQAb/H/sM +hugSreKMLVSAHRhMNGXb+dR0MzJiR4GbKRvYyHul4zjWen9uQrDHdgsqD4RnUcq8 +7HB+i49oFLN59qoI9MOoOKBfAKGKlXd+IL9+jyR/jA== -----END CERTIFICATE----- From c9d0572701a1bd2714b82ce03cf225e60a3f41a9 Mon Sep 17 00:00:00 2001 From: ctcpip Date: Wed, 22 Jan 2025 09:10:19 -0600 Subject: [PATCH 726/766] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F=20use=202048=20bi?= =?UTF-8?q?t=20key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cd test/fixtures openssl genpkey -algorithm RSA -out new_server.key -pkeyopt rsa_keygen_bits:2048 openssl x509 -in server.crt -signkey new_server.key -days 3650 -out new_server.crt openssl x509 -in new_server.crt -text -noout mv new_server.crt server.crt mv new_server.key server.key --- test/fixtures/server.crt | 28 ++++++++++++++++---------- test/fixtures/server.key | 43 ++++++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/test/fixtures/server.crt b/test/fixtures/server.crt index 3f68e2f2..3bee94f1 100644 --- a/test/fixtures/server.crt +++ b/test/fixtures/server.crt @@ -1,15 +1,21 @@ -----BEGIN CERTIFICATE----- -MIICWzCCAcSgAwIBAgIJAIlOazSpwhmAMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV +MIIDYDCCAkigAwIBAgIJAIlOazSpwhmAMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV BAYTAlVTMRAwDgYDVQQIEwdJbmRpYW5hMR0wGwYDVQQKExRub2RlLWV4cHJlc3Mt -c2Vzc2lvbjEeMBwGA1UEAxMVZXhwcmVzcy1zZXNzaW9uLmxvY2FsMB4XDTI0MTEy -MTAzMjgxMFoXDTM0MTExOTAzMjgxMFowXjELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +c2Vzc2lvbjEeMBwGA1UEAxMVZXhwcmVzcy1zZXNzaW9uLmxvY2FsMB4XDTI1MDEy +MjE1MTMyMFoXDTM1MDEyMDE1MTMyMFowXjELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0luZGlhbmExHTAbBgNVBAoTFG5vZGUtZXhwcmVzcy1zZXNzaW9uMR4wHAYDVQQD -ExVleHByZXNzLXNlc3Npb24ubG9jYWwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBANgbf3zOo3pi/8UDHvt6gsuN7hU0JgNdRyJYHNx5pnm7+u0/9eyFNBYMoV9R -tv+SaeINrOwJqxKg2xQKtypA8kXWMXcX1eOxnFyCANpvwwBsAyGeElrHaXfI8mxa -cH/yathx2x1A09cnFBb0wxmBTHPveAhjn+sR5rJT2jCBydVxAgMBAAGjITAfMB0G -A1UdDgQWBBTqXycJwRboThk0uB3Cd3+oSLz1fjANBgkqhkiG9w0BAQsFAAOBgQCT -/E1rZGxemZZ5F8qX9SoTsc04ELEwT3PwA0cgU5fGmWmajPfjw339y53EQAb/H/sM -hugSreKMLVSAHRhMNGXb+dR0MzJiR4GbKRvYyHul4zjWen9uQrDHdgsqD4RnUcq8 -7HB+i49oFLN59qoI9MOoOKBfAKGKlXd+IL9+jyR/jA== +ExVleHByZXNzLXNlc3Npb24ubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCy4w/9Wa85PGpdkzuZeU2qel+jlQd5L8b0RoKwlQ5k8NS/zIRd2fiF +8XIQMi5m7sGaYT3xUUItuksQF3XnOGQddppLCnfshjqUeSrMAoSZPnqHsZYsbRhS +3HiJFLWvBRDndVpmvdyg7BZicqEFmVBYNqsbsGH0Nrx6Xcb3iEZL8Z1mg3y+5f7c +0s0buXJmX9usc8g7CRiLfuqArAJM8NUSyBonsIlzQvudmNiyqb5UZIYqK8YvCpkZ +3QcHpzVCZ1uYIKa8MY878PhaiVqwDWGEtXO9xi3rtHXkvm5Y3wwbXYFDoOvA1YvM +/CtLXNCpHU23WhiIErBb3dvGxZZroCTtAgMBAAGjITAfMB0GA1UdDgQWBBSJqiKJ +f66iraVLqI3oZsgVeFA14jANBgkqhkiG9w0BAQsFAAOCAQEAP2VZidUCQptk4BiU +Fi390fR5wrgnqhBRmoE+iL5ok05ToLsg2DyvCefPyZgNp//NIRp6QUIHmPVXWHXx +fVDPLUC1CuOXy+o6TDWWjbtFW/PG5uPA6uhW4XpaBR5EGlptOBrGIRKIqneUwsMk +5fpDo7pbU4GSMToDDnhJxijrHIQFTs+PJLAGjCBQn/FRcDR1AJlxW/AyO0bIBSLE +fnZP+feQG6koDK8rgyT4t4z+hynAuf7y1ToFckNfTkdLdbXG5ceGu21qJCY/8uje +Nf01ik1p8gL5dZcW3qucTP5p45t3bnUDOjPFmrs87Ooeix9UjZG2hwW258FN86r6 +3PDrTw== -----END CERTIFICATE----- diff --git a/test/fixtures/server.key b/test/fixtures/server.key index dabf2b83..51b6a7b1 100644 --- a/test/fixtures/server.key +++ b/test/fixtures/server.key @@ -1,15 +1,28 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDYG398zqN6Yv/FAx77eoLLje4VNCYDXUciWBzceaZ5u/rtP/Xs -hTQWDKFfUbb/kmniDazsCasSoNsUCrcqQPJF1jF3F9XjsZxcggDab8MAbAMhnhJa -x2l3yPJsWnB/8mrYcdsdQNPXJxQW9MMZgUxz73gIY5/rEeayU9owgcnVcQIDAQAB -AoGBALB8HGw/kPA1Ay3Qc6/qCADWYvW8BcM/nQUmMkO3sUW/R5gTYPIMglHzdKIU -aL9kwcXTZ0HIT4ZCCUffzF/cdD0lqCZjwGl0aM4xUZcPbaM/KmZOUcP92ymsN+rF -uuJXks6hxrmJ5hh5D6FXdlQjTCdG3u9w0+KD4n1BkBkEaqflAkEA9q4TBt1bLOvV -bbwz7bunI6bwS5eD7sVn1qUqrm6hcirhF1xCv75pO/uqAyccbguxjp8y2LNuN+cO -IgSwr+Jq1wJBAOBFuKSMAcg2WmJ4IAT7143yhoHKMgA8Nl4sfLFwFl2/hw+fdEBe -gndRfKHT4IV/YLcnS7d/H6mEMSAusWx5QPcCQQDTYaF+TWrW2JRAf3jEK/xyiZf6 -PrDYh6KOhWRIqxZ/fYz69p1gL6t/sg0ivH4ZMr4JKBRrK360OrOapQg+/7drAkB6 -3pfPRok/aE/SfN+F+3fX49Q/TUhhipt6ssLJ74/BYsobDBADqAOwXSt7+XmbifKx -xUydRn9RPwQvDoXT2QZ3AkAdnwR9PMEHAsaibrPyzBztKjPL2rWBRk1QAmcdrTpt -XL99XfmkERWtiBA/Lz2K332qYOa/zo5c/SADx9fm7+HP ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCy4w/9Wa85PGpd +kzuZeU2qel+jlQd5L8b0RoKwlQ5k8NS/zIRd2fiF8XIQMi5m7sGaYT3xUUItuksQ +F3XnOGQddppLCnfshjqUeSrMAoSZPnqHsZYsbRhS3HiJFLWvBRDndVpmvdyg7BZi +cqEFmVBYNqsbsGH0Nrx6Xcb3iEZL8Z1mg3y+5f7c0s0buXJmX9usc8g7CRiLfuqA +rAJM8NUSyBonsIlzQvudmNiyqb5UZIYqK8YvCpkZ3QcHpzVCZ1uYIKa8MY878Pha +iVqwDWGEtXO9xi3rtHXkvm5Y3wwbXYFDoOvA1YvM/CtLXNCpHU23WhiIErBb3dvG +xZZroCTtAgMBAAECggEAA8BHqE4eYsKdz18EP6xfwMymn0FDghrKnvowiN/jSKIV +L/1rpCUrNTHSLL1EpFNq22AhIqOL0fYnV0vKpOHVlZmUVDEAwUSyS0U8LMF7wtPg +0WIbrkxOV4R4gZVd1vDyAQyArAlcrEIvGPri3gFwQh1JWsAI2cxhCObZAn1IzhRW +sMecAmtNzzYWeXentSfkfWr0niKDbSAAuYzgVIEWbIfE+kgqBckrWnyM9IgSdy1g +0b3NRRD/gvykszX7j9fzXGj8RAcCTbN1miaFcHRg3moa1Pu50KjokINsr5xxYqTk +ltPYU35gMYzNPvu5clvj067j6ikCFMiE4XOXf58qwQKBgQDpQJ2l6b1LrvGAV4Q6 +qieTYPTnGhnm/rSn7jK+AUIF+UmK3mtASuc14keelXeiI42MzvO1P6LLwkFIzVx0 +2X/BrTDZUvU5P5nsgBkoyiC71bkbCzoiSxIQtRurenmkD7EqM+4zBYMvCvrPFmOr +twuWk+4XLA+nl5Vl+FUgjehCQQKBgQDEVShtn68Pkq22GXR5kzgFu+GaXuVPJKu8 +z45K4mbG+WrnwuMmnIRbMfN9oGF5JXWAe5AtFqlQEcUQLElllRkdUe76WX15M2Jm +UeqFFARWjToNs7NXmxjsQZFOe0TyfAsdaX++lUhEpeCcv2MnEoNQS9n8yTwhuJM4 +8Zr9KUWfrQKBgQCFkNK1ZxtWc18nNvYpAbaX1jVnALNEayXX47Z6xw2fjhhmxOZ1 +cm7jlCeez8gpuGId94PmjgIS27G2lqIS51kY9qu6Rp7VoW3q14+Qo+4KoV/V9J/d +c09s8checUumfrXcjNAht05fadIlM5Tvh2nDWAJGkpyEQ3DxazqT4a7WAQKBgFok +Zz191Zim1c8H/Oxc5ZnsW3bPHyWpRpiYC1LihCHTHnxuhHCT6EketBb37gj7Y+mr +0dSB1RcIMZxtWP2k6TUHC1wyfmOJbiJgdfbH6/35NbBY03zjnxvKNvb7rfpPbaMB +bz+Htvid2HTfgpzL6TKSwPFJS6yH3ECG3YxiyK65AoGAHIYaLIP53pszdd1ruCO6 +0rI6/He6hKwG8SmtbXKCKYSAeNwZJkUI+B0xD8ZTq5h3geJD7CEoVPPsv9xauliG +fspe/KyTX5DqTBx9xNVYj9C2MSozQNs8ObCsUOMKzRaJtHl64US1VzweWA7Whkwf +1r8MiT2ty4eCk7V3qW1W88A= +-----END PRIVATE KEY----- From d5baeeca833a6370936a844654f0d7147dc234aa Mon Sep 17 00:00:00 2001 From: Wes Todd Date: Wed, 22 Jan 2025 17:06:47 -0600 Subject: [PATCH 727/766] feat: gencert script to regenerate the test ssl certs --- package.json | 3 ++- test/support/gencert.sh | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100755 test/support/gencert.sh diff --git a/package.json b/package.json index e3322438..87b31098 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc npm test", - "version": "node scripts/version-history.js && git add HISTORY.md" + "version": "node scripts/version-history.js && git add HISTORY.md", + "gencert": "./test/support/gencert.sh" } } diff --git a/test/support/gencert.sh b/test/support/gencert.sh new file mode 100755 index 00000000..114bf70f --- /dev/null +++ b/test/support/gencert.sh @@ -0,0 +1,12 @@ +#! /bin/sh +set -ex + +openssl genpkey -algorithm RSA -out new_server.key -pkeyopt rsa_keygen_bits:2048 + +openssl x509 -in ./test/fixtures/server.crt -signkey new_server.key -days 3650 -out new_server.crt + +openssl x509 -in new_server.crt -text -noout + +mv new_server.crt ./test/fixtures/server.crt + +mv new_server.key ./test/fixtures/server.key From 67d61ee1799a8070dff4a5b759189be2023c7a62 Mon Sep 17 00:00:00 2001 From: ctcpip Date: Thu, 23 Jan 2025 11:01:24 -0600 Subject: [PATCH 728/766] =?UTF-8?q?=E2=9C=85=20always=20generate=20fresh?= =?UTF-8?q?=20cert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ package.json | 5 ++--- test/fixtures/.gitkeep | 0 test/fixtures/server.crt | 21 --------------------- test/fixtures/server.key | 28 ---------------------------- test/support/gencert.sh | 11 ++--------- 6 files changed, 6 insertions(+), 61 deletions(-) create mode 100644 test/fixtures/.gitkeep delete mode 100644 test/fixtures/server.crt delete mode 100644 test/fixtures/server.key diff --git a/.gitignore b/.gitignore index 207febba..1b6fef23 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ coverage node_modules npm-debug.log package-lock.json +/test/fixtures/server.crt +/test/fixtures/server.key diff --git a/package.json b/package.json index 87b31098..79cb1b4c 100644 --- a/package.json +++ b/package.json @@ -39,10 +39,9 @@ }, "scripts": { "lint": "eslint . && node ./scripts/lint-readme.js", - "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", + "test": "./test/support/gencert.sh && mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc npm test", - "version": "node scripts/version-history.js && git add HISTORY.md", - "gencert": "./test/support/gencert.sh" + "version": "node scripts/version-history.js && git add HISTORY.md" } } diff --git a/test/fixtures/.gitkeep b/test/fixtures/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/server.crt b/test/fixtures/server.crt deleted file mode 100644 index 3bee94f1..00000000 --- a/test/fixtures/server.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDYDCCAkigAwIBAgIJAIlOazSpwhmAMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV -BAYTAlVTMRAwDgYDVQQIEwdJbmRpYW5hMR0wGwYDVQQKExRub2RlLWV4cHJlc3Mt -c2Vzc2lvbjEeMBwGA1UEAxMVZXhwcmVzcy1zZXNzaW9uLmxvY2FsMB4XDTI1MDEy -MjE1MTMyMFoXDTM1MDEyMDE1MTMyMFowXjELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0luZGlhbmExHTAbBgNVBAoTFG5vZGUtZXhwcmVzcy1zZXNzaW9uMR4wHAYDVQQD -ExVleHByZXNzLXNlc3Npb24ubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCy4w/9Wa85PGpdkzuZeU2qel+jlQd5L8b0RoKwlQ5k8NS/zIRd2fiF -8XIQMi5m7sGaYT3xUUItuksQF3XnOGQddppLCnfshjqUeSrMAoSZPnqHsZYsbRhS -3HiJFLWvBRDndVpmvdyg7BZicqEFmVBYNqsbsGH0Nrx6Xcb3iEZL8Z1mg3y+5f7c -0s0buXJmX9usc8g7CRiLfuqArAJM8NUSyBonsIlzQvudmNiyqb5UZIYqK8YvCpkZ -3QcHpzVCZ1uYIKa8MY878PhaiVqwDWGEtXO9xi3rtHXkvm5Y3wwbXYFDoOvA1YvM -/CtLXNCpHU23WhiIErBb3dvGxZZroCTtAgMBAAGjITAfMB0GA1UdDgQWBBSJqiKJ -f66iraVLqI3oZsgVeFA14jANBgkqhkiG9w0BAQsFAAOCAQEAP2VZidUCQptk4BiU -Fi390fR5wrgnqhBRmoE+iL5ok05ToLsg2DyvCefPyZgNp//NIRp6QUIHmPVXWHXx -fVDPLUC1CuOXy+o6TDWWjbtFW/PG5uPA6uhW4XpaBR5EGlptOBrGIRKIqneUwsMk -5fpDo7pbU4GSMToDDnhJxijrHIQFTs+PJLAGjCBQn/FRcDR1AJlxW/AyO0bIBSLE -fnZP+feQG6koDK8rgyT4t4z+hynAuf7y1ToFckNfTkdLdbXG5ceGu21qJCY/8uje -Nf01ik1p8gL5dZcW3qucTP5p45t3bnUDOjPFmrs87Ooeix9UjZG2hwW258FN86r6 -3PDrTw== ------END CERTIFICATE----- diff --git a/test/fixtures/server.key b/test/fixtures/server.key deleted file mode 100644 index 51b6a7b1..00000000 --- a/test/fixtures/server.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCy4w/9Wa85PGpd -kzuZeU2qel+jlQd5L8b0RoKwlQ5k8NS/zIRd2fiF8XIQMi5m7sGaYT3xUUItuksQ -F3XnOGQddppLCnfshjqUeSrMAoSZPnqHsZYsbRhS3HiJFLWvBRDndVpmvdyg7BZi -cqEFmVBYNqsbsGH0Nrx6Xcb3iEZL8Z1mg3y+5f7c0s0buXJmX9usc8g7CRiLfuqA -rAJM8NUSyBonsIlzQvudmNiyqb5UZIYqK8YvCpkZ3QcHpzVCZ1uYIKa8MY878Pha -iVqwDWGEtXO9xi3rtHXkvm5Y3wwbXYFDoOvA1YvM/CtLXNCpHU23WhiIErBb3dvG -xZZroCTtAgMBAAECggEAA8BHqE4eYsKdz18EP6xfwMymn0FDghrKnvowiN/jSKIV -L/1rpCUrNTHSLL1EpFNq22AhIqOL0fYnV0vKpOHVlZmUVDEAwUSyS0U8LMF7wtPg -0WIbrkxOV4R4gZVd1vDyAQyArAlcrEIvGPri3gFwQh1JWsAI2cxhCObZAn1IzhRW -sMecAmtNzzYWeXentSfkfWr0niKDbSAAuYzgVIEWbIfE+kgqBckrWnyM9IgSdy1g -0b3NRRD/gvykszX7j9fzXGj8RAcCTbN1miaFcHRg3moa1Pu50KjokINsr5xxYqTk -ltPYU35gMYzNPvu5clvj067j6ikCFMiE4XOXf58qwQKBgQDpQJ2l6b1LrvGAV4Q6 -qieTYPTnGhnm/rSn7jK+AUIF+UmK3mtASuc14keelXeiI42MzvO1P6LLwkFIzVx0 -2X/BrTDZUvU5P5nsgBkoyiC71bkbCzoiSxIQtRurenmkD7EqM+4zBYMvCvrPFmOr -twuWk+4XLA+nl5Vl+FUgjehCQQKBgQDEVShtn68Pkq22GXR5kzgFu+GaXuVPJKu8 -z45K4mbG+WrnwuMmnIRbMfN9oGF5JXWAe5AtFqlQEcUQLElllRkdUe76WX15M2Jm -UeqFFARWjToNs7NXmxjsQZFOe0TyfAsdaX++lUhEpeCcv2MnEoNQS9n8yTwhuJM4 -8Zr9KUWfrQKBgQCFkNK1ZxtWc18nNvYpAbaX1jVnALNEayXX47Z6xw2fjhhmxOZ1 -cm7jlCeez8gpuGId94PmjgIS27G2lqIS51kY9qu6Rp7VoW3q14+Qo+4KoV/V9J/d -c09s8checUumfrXcjNAht05fadIlM5Tvh2nDWAJGkpyEQ3DxazqT4a7WAQKBgFok -Zz191Zim1c8H/Oxc5ZnsW3bPHyWpRpiYC1LihCHTHnxuhHCT6EketBb37gj7Y+mr -0dSB1RcIMZxtWP2k6TUHC1wyfmOJbiJgdfbH6/35NbBY03zjnxvKNvb7rfpPbaMB -bz+Htvid2HTfgpzL6TKSwPFJS6yH3ECG3YxiyK65AoGAHIYaLIP53pszdd1ruCO6 -0rI6/He6hKwG8SmtbXKCKYSAeNwZJkUI+B0xD8ZTq5h3geJD7CEoVPPsv9xauliG -fspe/KyTX5DqTBx9xNVYj9C2MSozQNs8ObCsUOMKzRaJtHl64US1VzweWA7Whkwf -1r8MiT2ty4eCk7V3qW1W88A= ------END PRIVATE KEY----- diff --git a/test/support/gencert.sh b/test/support/gencert.sh index 114bf70f..cfdda070 100755 --- a/test/support/gencert.sh +++ b/test/support/gencert.sh @@ -1,12 +1,5 @@ #! /bin/sh set -ex -openssl genpkey -algorithm RSA -out new_server.key -pkeyopt rsa_keygen_bits:2048 - -openssl x509 -in ./test/fixtures/server.crt -signkey new_server.key -days 3650 -out new_server.crt - -openssl x509 -in new_server.crt -text -noout - -mv new_server.crt ./test/fixtures/server.crt - -mv new_server.key ./test/fixtures/server.key +openssl req -x509 -nodes -newkey rsa:2048 -keyout ./test/fixtures/server.key -out ./test/fixtures/server.crt -days 3650 \ +-subj "/C=US/ST=Illinois/L=Chicago/O=node-express-session/CN=express-session.local" From 4930de729107448e4b34b5bd39f138f71f1561f6 Mon Sep 17 00:00:00 2001 From: ctcpip Date: Thu, 23 Jan 2025 11:04:34 -0600 Subject: [PATCH 729/766] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20bump=20actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38dc4da7..ff3bce76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -185,7 +185,7 @@ jobs: run: | if npm -ps ls nyc | grep -q nyc; then npm run test-ci - cp coverage/lcov.info "coverage/${{ matrix.name }}.lcov" + cp coverage/lcov.info "coverage/${{ matrix.node-version }}.lcov" else npm test fi @@ -198,17 +198,17 @@ jobs: if: steps.list_env.outputs.nyc != '' run: | if [[ -d ./coverage ]]; then - mv ./coverage "./${{ matrix.name }}" + mv ./coverage "./${{ matrix.node-version }}" mkdir ./coverage - mv "./${{ matrix.name }}" "./coverage/${{ matrix.name }}" + mv "./${{ matrix.node-version }}" "./coverage/${{ matrix.node-version }}" fi - name: Upload code coverage - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: steps.list_env.outputs.nyc != '' with: - name: coverage - path: ./coverage + name: coverage-${{ matrix.node-version }} + path: "./coverage/${{ matrix.node-version }}" retention-days: 1 coverage: @@ -222,9 +222,8 @@ jobs: run: sudo apt-get -y install lcov - name: Collect coverage reports - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: coverage path: ./coverage - name: Merge coverage reports From b99e6c6fba30996069c9122e9e041a26f13d1d5e Mon Sep 17 00:00:00 2001 From: Carlos Serrano Date: Thu, 17 Apr 2025 16:18:22 +0200 Subject: [PATCH 730/766] chore: upgrade scorecard workflow pinned action versions (#1008) --- .github/workflows/scorecard.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 0e064f47..d23de00e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,12 +33,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -60,7 +60,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: SARIF file path: results.sarif @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@2f93e4319b2f04a2efc38fa7f78bd681bc3f7b2f # v2.23.2 + uses: github/codeql-action/upload-sarif@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 with: - sarif_file: results.sarif + sarif_file: results.sarif \ No newline at end of file From 6edf5eeab25c1b89ecd2676ce119d600c741b5f6 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 26 Apr 2025 22:09:29 -0500 Subject: [PATCH 731/766] ci: add CodeQL (SAST) (#1005) --- .github/workflows/codeql.yml | 66 ++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..9d1b3041 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,66 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: ["master"] + pull_request: + # The branches below must be a subset of the branches above + branches: ["master"] + schedule: + - cron: "0 0 * * 1" + +permissions: + contents: read + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + with: + languages: javascript + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + # - name: Autobuild + # uses: github/codeql-action/autobuild@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + + # โ„น๏ธ Command-line programs to run using the OS shell. + # ๐Ÿ“š See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + with: + category: "/language:javascript" \ No newline at end of file From 122714cbdab4aee732d9e43a90865c73ec9819af Mon Sep 17 00:00:00 2001 From: StepSecurity Bot Date: Sat, 17 May 2025 10:33:44 -0700 Subject: [PATCH 732/766] [StepSecurity] Apply security best practices (#1047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [StepSecurity] Apply security best practices Signed-off-by: StepSecurity Bot * Update dependabot.yml * ping supertest versions in CI Signed-off-by: Sebastian Beltran --------- Signed-off-by: StepSecurity Bot Signed-off-by: Sebastian Beltran Co-authored-by: Ulises Gascรณn Co-authored-by: Sebastian Beltran --- .github/dependabot.yml | 11 +++++++++++ .github/workflows/ci.yml | 31 +++++++++++++++++++------------ 2 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..69f2040f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + + - package-ecosystem: npm + directory: / + schedule: + interval: monthly diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff3bce76..746b29e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,9 @@ on: - pull_request - push +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest @@ -79,33 +82,34 @@ jobs: - name: Node.js 8.x node-version: "8.17" - npm-i: mocha@7.2.0 nyc@14.1.1 + npm-i: mocha@7.2.0 nyc@14.1.1 supertest@6.1.6 - name: Node.js 9.x node-version: "9.11" - npm-i: mocha@7.2.0 nyc@14.1.1 + npm-i: mocha@7.2.0 nyc@14.1.1 supertest@6.1.6 - name: Node.js 10.x node-version: "10.24" - npm-i: mocha@8.4.0 + npm-i: mocha@8.4.0 supertest@6.1.6 - name: Node.js 11.x node-version: "11.15" - npm-i: mocha@8.4.0 + npm-i: mocha@8.4.0 supertest@6.1.6 - name: Node.js 12.x node-version: "12.22" - npm-i: mocha@9.2.2 + npm-i: mocha@9.2.2 supertest@6.1.6 - name: Node.js 13.x node-version: "13.14" - npm-i: mocha@9.2.2 + npm-i: mocha@9.2.2 supertest@6.1.6 - name: Node.js 14.x node-version: "14.21" - name: Node.js 15.x - node-version: "15.14" + node-version: "15.14" + npm-i: supertest@6.1.6 - name: Node.js 16.x node-version: "16.20" @@ -126,7 +130,7 @@ jobs: node-version: "21.6" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Node.js ${{ matrix.node-version }} shell: bash -eo pipefail -l {0} @@ -204,7 +208,7 @@ jobs: fi - name: Upload code coverage - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 if: steps.list_env.outputs.nyc != '' with: name: coverage-${{ matrix.node-version }} @@ -212,17 +216,20 @@ jobs: retention-days: 1 coverage: + permissions: + checks: write # for coverallsapp/github-action to create new checks + contents: read # for actions/checkout to fetch code needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install lcov shell: bash run: sudo apt-get -y install lcov - name: Collect coverage reports - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: path: ./coverage @@ -231,6 +238,6 @@ jobs: run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./coverage/lcov.info - name: Upload coverage report - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@09b709cf6a16e30b0808ba050c7a6e8a5ef13f8d # master with: github-token: ${{ secrets.GITHUB_TOKEN }} From 168271c665519d7d9164f97873bd0eee88d9e6fb Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 17 May 2025 13:02:43 -0500 Subject: [PATCH 733/766] fix(dependabot): do not update major versions Signed-off-by: Sebastian Beltran --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 69f2040f..492d67d0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,6 @@ updates: directory: / schedule: interval: monthly + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] From 92dd3008e334eaa8466a431ae3c032b827b5816d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 May 2025 11:19:32 +0200 Subject: [PATCH 734/766] build(deps-dev): bump mocha from 10.2.0 to 10.8.2 (#1061) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ulises Gascรณn --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 57c68d3a..cc879c63 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unpublished +========== + * deps: mocha@10.8.2 + + 1.18.1 / 2024-10-08 ========== diff --git a/package.json b/package.json index 79cb1b4c..b4978a27 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "eslint": "8.56.0", "eslint-plugin-markdown": "3.0.1", "express": "4.17.3", - "mocha": "10.2.0", + "mocha": "10.8.2", "nyc": "15.1.0", "supertest": "6.3.4" }, From 7e2c6964263b66d7fbdbd75d1c603413880fef64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 19:32:09 -0500 Subject: [PATCH 735/766] build(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.1 (#1048) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.0 to 2.4.1. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/62b2cac7ed8198b15735ed49ab1e5cf35480ba46...f49aabe0b5af0936a0987cfb85d86b75731b0186) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index d23de00e..3d4b1114 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -38,7 +38,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif From 2633e88780e5655db44d11f917629942cb92628d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 19:32:43 -0500 Subject: [PATCH 736/766] build(deps): bump github/codeql-action from 3.24.7 to 3.28.18 (#1050) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.7 to 3.28.18. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3.24.7...ff0a06e83cb2de871e5a09832bc6a81e7276941f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 3.28.18 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9d1b3041..894e99aa 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3d4b1114..5ad5ef6a 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: sarif_file: results.sarif \ No newline at end of file From 2caff6ae8976763841abbc8ed7b560cc5ebdf6cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 19:33:21 -0500 Subject: [PATCH 737/766] build(deps): bump actions/checkout from 4.1.1 to 4.2.2 (#1049) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.1...11bd71901bbe5b1630ceea73d27597364c9af683) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 894e99aa..1a41f87b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From ec1957b9bd169c582a00d83f5966f4c5fed9017d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 19:33:55 -0500 Subject: [PATCH 738/766] build(deps): bump actions/upload-artifact from 4.5.0 to 4.6.2 (#1052) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.5.0 to 4.6.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.5.0...ea165f8d65b6e75b540449e92b4886f43607fa02) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 4.6.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 5ad5ef6a..d53e5871 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -60,7 +60,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: SARIF file path: results.sarif From a698c81f2ab950188cdbd7f30bb3a89fd68e2046 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 19:34:41 -0500 Subject: [PATCH 739/766] build(deps): bump coverallsapp/github-action from 1.2.5 to 2.3.6 (#1051) Bumps [coverallsapp/github-action](https://github.com/coverallsapp/github-action) from 1.2.5 to 2.3.6. - [Release notes](https://github.com/coverallsapp/github-action/releases) - [Upgrade guide](https://github.com/coverallsapp/github-action/blob/main/UPGRADE.md) - [Commits](https://github.com/coverallsapp/github-action/compare/09b709cf6a16e30b0808ba050c7a6e8a5ef13f8d...648a8eb78e6d50909eff900e4ec85cab4524a45b) --- updated-dependencies: - dependency-name: coverallsapp/github-action dependency-version: 2.3.6 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 746b29e1..210657e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -238,6 +238,6 @@ jobs: run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./coverage/lcov.info - name: Upload coverage report - uses: coverallsapp/github-action@09b709cf6a16e30b0808ba050c7a6e8a5ef13f8d # master + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # master with: github-token: ${{ secrets.GITHUB_TOKEN }} From b9fcad8a8bc8f1ac84809d81c569ffbcc6f9ef99 Mon Sep 17 00:00:00 2001 From: Noritaka Kobayashi Date: Sat, 12 Jul 2025 02:21:20 +0900 Subject: [PATCH 740/766] chore: fix typos (#1066) --- HISTORY.md | 2 +- README.md | 4 ++-- scripts/version-history.js | 2 +- test/session.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index cc879c63..1dcedcc5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -171,7 +171,7 @@ unpublished - Improve error message when `expires` is not a `Date` - perf: enable strict mode - perf: use for loop in parse - - perf: use string concatination for serialization + - perf: use string concatenation for serialization * deps: parseurl@~1.3.1 - perf: enable strict mode * deps: uid-safe@~2.1.1 diff --git a/README.md b/README.md index 65a37e63..b880e6b4 100644 --- a/README.md +++ b/README.md @@ -269,7 +269,7 @@ With this enabled, the session identifier cookie will expire in [`maxAge`](#cookiemaxage) since the last response was sent instead of in [`maxAge`](#cookiemaxage) since the session was last modified by the server. -This is typically used in conjuction with short, non-session-length +This is typically used in conjunction with short, non-session-length [`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data with reduced potential of it occurring during on going server interactions. @@ -773,7 +773,7 @@ a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-e [express-session-level-url]: https://www.npmjs.com/package/express-session-level [express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85 -[![โ˜…][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerfull, flat file database. +[![โ˜…][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database. [express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb [express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85 diff --git a/scripts/version-history.js b/scripts/version-history.js index b8a2b0e8..c58268ad 100644 --- a/scripts/version-history.js +++ b/scripts/version-history.js @@ -16,7 +16,7 @@ if (!MD_HEADER_REGEXP.test(historyFileLines[1])) { } if (!VERSION_PLACEHOLDER_REGEXP.test(historyFileLines[0])) { - console.error('Missing placegolder version in HISTORY.md') + console.error('Missing placeholder version in HISTORY.md') process.exit(1) } diff --git a/test/session.js b/test/session.js index 7bf3e51f..a7d79b70 100644 --- a/test/session.js +++ b/test/session.js @@ -1710,7 +1710,7 @@ describe('session()', function(){ }) }) - it('should not override an overriden `reload` in case of errors', function (done) { + it('should not override an overridden `reload` in case of errors', function (done) { var store = new session.MemoryStore() var server = createServer({ store: store, resave: false }, function (req, res) { if (req.url === '/') { From 58087831a68787fb3c1ef8b821efb965225dc725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Thu, 17 Jul 2025 19:25:18 +0200 Subject: [PATCH 741/766] deps: on-headers@1.1.0 (#1069) --- HISTORY.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 1dcedcc5..401ffbd5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,8 @@ unpublished ========== * deps: mocha@10.8.2 - + * deps: on-headers@~1.1.0 + - Fix [CVE-2025-7339](https://www.cve.org/CVERecord?id=CVE-2025-7339) ([GHSA-76c9-3jph-rj3q](https://github.com/expressjs/on-headers/security/advisories/GHSA-76c9-3jph-rj3q)) 1.18.1 / 2024-10-08 ========== diff --git a/package.json b/package.json index b4978a27..f03896af 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", - "on-headers": "~1.0.2", + "on-headers": "~1.1.0", "parseurl": "~1.3.3", "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" From d10709f319d1ff4069e1e552fc7f3ca27989e981 Mon Sep 17 00:00:00 2001 From: Chris de Almeida Date: Thu, 17 Jul 2025 12:51:20 -0500 Subject: [PATCH 742/766] =?UTF-8?q?=F0=9F=94=96=20v1.18.2=20(#1070)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 401ffbd5..9aacf124 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,4 @@ -unpublished +1.18.2 / 2025-07-17 ========== * deps: mocha@10.8.2 * deps: on-headers@~1.1.0 diff --git a/package.json b/package.json index f03896af..7039d1d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.18.1", + "version": "1.18.2", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 1aa756d20a1af2b922e9897ca0010fa466ce17e7 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Wed, 23 Jul 2025 07:42:19 -0500 Subject: [PATCH 743/766] chore: add funding to package.json (#1071) --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 7039d1d4..3bc6ac59 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,10 @@ "Joe Wagner " ], "repository": "expressjs/session", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + }, "license": "MIT", "dependencies": { "cookie": "0.7.2", From 488102d3d79ee394c90e0b051bf0dbe137956400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Nov 2025 09:29:37 +0100 Subject: [PATCH 744/766] build(deps): bump actions/download-artifact from 4.3.0 to 6.0.0 (#1086) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 210657e2..167e2e38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -229,7 +229,7 @@ jobs: run: sudo apt-get -y install lcov - name: Collect coverage reports - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: path: ./coverage From b6f79be32f4afd88b92eda9a3448b7136cecac1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Nov 2025 09:30:20 +0100 Subject: [PATCH 745/766] build(deps): bump github/codeql-action from 3.28.18 to 4.31.2 (#1085) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1a41f87b..bdff87f4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index d53e5871..a6a29448 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: sarif_file: results.sarif \ No newline at end of file From c83c8e28d586c3f86f9844356590b2e704843f57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:15:55 +0100 Subject: [PATCH 746/766] build(deps): bump coverallsapp/github-action from 2.3.6 to 2.3.7 (#1091) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 167e2e38..f7078328 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -238,6 +238,6 @@ jobs: run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./coverage/lcov.info - name: Upload coverage report - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # master + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # master with: github-token: ${{ secrets.GITHUB_TOKEN }} From a095a9a17c862746af8c2d8671825e4743d38169 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:16:45 +0100 Subject: [PATCH 747/766] build(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 (#1090) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7078328..30a606f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -208,7 +208,7 @@ jobs: fi - name: Upload code coverage - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 if: steps.list_env.outputs.nyc != '' with: name: coverage-${{ matrix.node-version }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a6a29448..a6efdc9e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -60,7 +60,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: SARIF file path: results.sarif From 0e7a438512fa584c617d681cf7fca8fb5c42da5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:17:30 +0100 Subject: [PATCH 748/766] build(deps): bump github/codeql-action from 4.31.2 to 4.31.6 (#1089) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index bdff87f4..31ffb64a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a6efdc9e..51230d44 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/upload-sarif@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 with: sarif_file: results.sarif \ No newline at end of file From 1307f30a62d10cf33f7abd59b8ecf3aae428ff3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:18:56 +0100 Subject: [PATCH 749/766] build(deps): bump actions/checkout from 4.2.2 to 6.0.0 (#1088) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30a606f2..13336155 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,7 +130,7 @@ jobs: node-version: "21.6" steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - name: Install Node.js ${{ matrix.node-version }} shell: bash -eo pipefail -l {0} @@ -222,7 +222,7 @@ jobs: needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - name: Install lcov shell: bash diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 31ffb64a..8534ee51 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 51230d44..30f54d2b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,7 +33,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false From 2cd6561f64cb9e0b847237885802351606d4029d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:04:48 -0500 Subject: [PATCH 750/766] build(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.3 (#1082) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.1 to 2.4.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/f49aabe0b5af0936a0987cfb85d86b75731b0186...4eaacf0543bb3f2c246792bd56e8cdeffafb205a) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 30f54d2b..169262af 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -38,7 +38,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif From 00b8a5ff111bba1a0ca9bb3d84947446c198a9a3 Mon Sep 17 00:00:00 2001 From: Ayoub Mabrouk <77799760+Ayoub-Mabrouk@users.noreply.github.com> Date: Thu, 18 Dec 2025 02:53:00 +0100 Subject: [PATCH 751/766] refactor: remove unused `sess` parameter from `generateSessionId` function (#1001) The `sess` parameter was not used in `generateSessionId`, so it was removed to improve code clarity and reduce potential confusion. Co-authored-by: Sebastian Beltran --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index d41b2378..85a0330c 100644 --- a/index.js +++ b/index.js @@ -523,7 +523,7 @@ function session(options) { * @private */ -function generateSessionId(sess) { +function generateSessionId() { return uid(24); } From 6d69f090d6239394e008cf39a2be2d5f60bdde97 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 18 Dec 2025 06:45:22 -0500 Subject: [PATCH 752/766] chore: remove history.md from being packaged on publish (#1097) --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 3bc6ac59..6d04c9c1 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ }, "files": [ "session/", - "HISTORY.md", "index.js" ], "engines": { From 264b6a0360a1d4b34955c27948bf1b1cfad74d66 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 18 Dec 2025 06:46:00 -0500 Subject: [PATCH 753/766] deps: use tilde notation for dependencies (#1096) --- HISTORY.md | 6 ++++++ package.json | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9aacf124..e12d0a00 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +# Unreleased changes + +### ๐Ÿš€ Improvements + +* deps: use tilde notation for dependencies + 1.18.2 / 2025-07-17 ========== * deps: mocha@10.8.2 diff --git a/package.json b/package.json index 6d04c9c1..42d244b9 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,13 @@ }, "license": "MIT", "dependencies": { - "cookie": "0.7.2", - "cookie-signature": "1.0.7", - "debug": "2.6.9", + "cookie": "~0.7.2", + "cookie-signature": "~1.0.7", + "debug": "~2.6.9", "depd": "~2.0.0", "on-headers": "~1.1.0", "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", + "safe-buffer": "~5.2.1", "uid-safe": "~2.1.5" }, "devDependencies": { From 73e0193afbee24bca8744e4fc8a67b92810301e8 Mon Sep 17 00:00:00 2001 From: Zacchaeus Bolaji Date: Sat, 17 Jan 2026 23:20:37 +0100 Subject: [PATCH 754/766] Add sameSite 'auto' support to match secure 'auto' pattern (#1087) * feat: add sameSite 'auto' support for automatic cross-site cookie configuration * test: enhance session tests for secure and SameSite cookie attributes * test: update session tests for SameSite cookie handling and logging * docs: add history entry * refactor: cache issecure result to avoid duplicate calls * Apply suggestion from @bjohansebas --------- Co-authored-by: Sebastian Beltran --- HISTORY.md | 4 ++ README.md | 9 +++ index.js | 8 ++- package.json | 2 +- test/session.js | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e12d0a00..60cf6db4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,10 @@ ### ๐Ÿš€ Improvements +* Add sameSite 'auto' support for automatic SameSite attribute configuration + + Added `sameSite: 'auto'` option for cookie configuration that automatically sets `SameSite=None` for HTTPS and `SameSite=Lax` for HTTP connections, simplifying cookie handling across different environments. + * deps: use tilde notation for dependencies 1.18.2 / 2025-07-17 diff --git a/README.md b/README.md index b880e6b4..4f19ce59 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ By default, this is `false`. - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie. - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. + - `'auto'` will set the `SameSite` attribute to `None` for secure connections and `Lax` for non-secure connections. More information about the different enforcement levels can be found in [the specification][rfc-6265bis-03-4.1.2.7]. @@ -141,6 +142,14 @@ the future. This also means many clients may ignore this attribute until they un that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been set to `'none'`. Some web browsers or other clients may be adopting this specification. +The `cookie.sameSite` option can also be set to the special value `'auto'` to have +this setting automatically match the determined security of the connection. When the connection +is secure (HTTPS), the `SameSite` attribute will be set to `None` to enable cross-site usage. +When the connection is not secure (HTTP), the `SameSite` attribute will be set to `Lax` for +better security while maintaining functionality. This is useful when the Express `"trust proxy"` +setting is properly setup to simplify development vs production configuration, particularly +for SAML authentication scenarios. + ##### cookie.secure Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy, diff --git a/index.js b/index.js index 85a0330c..1ee99eb5 100644 --- a/index.js +++ b/index.js @@ -160,8 +160,14 @@ function session(options) { req.session = new Session(req); req.session.cookie = new Cookie(cookieOptions); + var isSecure = issecure(req, trustProxy); + if (cookieOptions.secure === 'auto') { - req.session.cookie.secure = issecure(req, trustProxy); + req.session.cookie.secure = isSecure; + } + + if (cookieOptions.sameSite === 'auto') { + req.session.cookie.sameSite = isSecure ? 'none' : 'lax'; } }; diff --git a/package.json b/package.json index 42d244b9..0f7d92e7 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "scripts": { "lint": "eslint . && node ./scripts/lint-readme.js", - "test": "./test/support/gencert.sh && mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/", + "test": "./test/support/gencert.sh && mocha --require test/support/env --check-leaks --no-exit --reporter spec test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc npm test", "version": "node scripts/version-history.js && git add HISTORY.md" diff --git a/test/session.js b/test/session.js index a7d79b70..31f4707b 100644 --- a/test/session.js +++ b/test/session.js @@ -801,6 +801,173 @@ describe('session()', function(){ }) }) }) + + describe('when "sameSite" set to "auto"', function () { + describe('basic functionality', function () { + before(function () { + function setup (req) { + req.secure = JSON.parse(req.headers['x-secure']) + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { cookie: { sameSite: 'auto' } }, respond) + }) + + it('should set SameSite=None for secure connections', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'true') + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'None')) + .expect(200, 'true', done) + }) + + it('should set SameSite=Lax for insecure connections', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'false') + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'Lax')) + .expect(200, 'false', done) + }) + }) + + describe('with proxy settings', function () { + describe('when "proxy" is "true"', function () { + before(function () { + this.server = createServer({ proxy: true, cookie: { sameSite: 'auto' }}) + }) + + it('should set SameSite=None when X-Forwarded-Proto is https', function (done) { + request(this.server) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'None')) + .expect(200, done) + }) + + it('should set SameSite=Lax when X-Forwarded-Proto is http', function (done) { + request(this.server) + .get('/') + .set('X-Forwarded-Proto', 'http') + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'Lax')) + .expect(200, done) + }) + }) + + describe('when "proxy" is "false"', function () { + before(function () { + this.server = createServer({ proxy: false, cookie: { sameSite: 'auto' }}) + }) + + it('should set SameSite=Lax when X-Forwarded-Proto is https', function (done) { + request(this.server) + .get('/') + .set('X-Forwarded-Proto', 'https') + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'Lax')) + .expect(200, done) + }) + }) + }) + + describe('combined with secure auto', function() { + describe('when "secure" is "auto"', function () { + before(function () { + function setup (req) { + req.secure = JSON.parse(req.headers['x-secure']) + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { cookie: { secure: 'auto', sameSite: 'auto' } }, respond) + }) + + it('should set both Secure and SameSite=None when secure', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'true') + .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'None')) + .expect(200, 'true', done) + }) + + it('should set neither Secure nor SameSite=None when insecure', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'false') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'Lax')) + .expect(200, 'false', done) + }) + }) + + describe('when "secure" is "false"', function () { + before(function () { + function setup (req) { + req.secure = JSON.parse(req.headers['x-secure']) + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { cookie: { secure: false, sameSite: 'auto' } }, respond) + }) + + it('should set SameSite=None without Secure when secure', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'true') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'None')) + .expect(200, 'true', done) + }) + + it('should set SameSite=Lax without Secure when insecure', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'false') + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'Lax')) + .expect(200, 'false', done) + }) + }) + + describe('when "secure" is "true"', function () { + before(function () { + function setup (req) { + req.secure = JSON.parse(req.headers['x-secure']) + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + this.server = createServer(setup, { cookie: { secure: true, sameSite: 'auto' } }, respond) + }) + + it('should set both Secure and SameSite=None when secure', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'true') + .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) + .expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'None')) + .expect(200, 'true', done) + }) + + it('should not set cookie when insecure', function (done) { + request(this.server) + .get('/') + .set('X-Secure', 'false') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'false', done) + }) + }) + }) + }) }) describe('genid option', function(){ From 2673736548304359d3d3fb8f8d3019b4ea5b61a7 Mon Sep 17 00:00:00 2001 From: Lincon Date: Mon, 19 Jan 2026 11:44:13 -0300 Subject: [PATCH 755/766] feat: add support to dynamic cookie options (#1027) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sebastian Beltran Co-authored-by: Ulises Gascรณn --- HISTORY.md | 21 ++++++++++++++++++++ README.md | 20 +++++++++++++++++++ index.js | 7 ++++--- test/session.js | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 60cf6db4..e28c5427 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,27 @@ ### ๐Ÿš€ Improvements +* Add dynamic cookie options support + + Cookie options can now be dynamic, allowing for more flexible and context-aware configuration based on each request. This feature enables programmatic modification of cookie attributes like `secure`, `httpOnly`, `sameSite`, `maxAge`, `domain`, and `path` based on session or request conditions. + + ```js + var app = express() + app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true, + cookie: function (req) { + var match = req.url.match(/^\/([^/]+)/); + return { + path: match ? '/' + match[1] : '/', + httpOnly: true, + secure: req.secure || false, + maxAge: 60000 + } + } + })) + ``` * Add sameSite 'auto' support for automatic SameSite attribute configuration Added `sameSite: 'auto'` option for cookie configuration that automatically sets `SameSite=None` for HTTPS and `SameSite=Lax` for HTTP connections, simplifying cookie handling across different environments. diff --git a/README.md b/README.md index 4f19ce59..292b2024 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,26 @@ For a list of stores, see [compatible session stores](#compatible-session-stores Settings object for the session ID cookie. The default value is `{ path: '/', httpOnly: true, secure: false, maxAge: null }`. +In addition to providing a static object, you can also pass a callback function to dynamically generate the cookie options for each request. The callback receives the `req` object as its argument and should return an object containing the cookie settings. + +```js +var app = express() +app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true, + cookie: function(req) { + var match = req.url.match(/^\/([^/]+)/); + return { + path: match ? '/' + match[1] : '/', + httpOnly: true, + secure: req.secure || false, + maxAge: 60000 + } + } +})) +``` + The following are options that can be set in this object. ##### cookie.domain diff --git a/index.js b/index.js index 1ee99eb5..1a509318 100644 --- a/index.js +++ b/index.js @@ -70,7 +70,7 @@ var defer = typeof setImmediate === 'function' * Setup session store with the given `options`. * * @param {Object} [options] - * @param {Object} [options.cookie] Options for cookie + * @param {Object|Function} [options.cookie] Options for cookie * @param {Function} [options.genid] * @param {String} [options.name=connect.sid] Session ID cookie name * @param {Boolean} [options.proxy] @@ -158,7 +158,7 @@ function session(options) { store.generate = function(req){ req.sessionID = generateId(req); req.session = new Session(req); - req.session.cookie = new Cookie(cookieOptions); + req.session.cookie = new Cookie(typeof cookieOptions === 'function' ? cookieOptions(req) : cookieOptions); var isSecure = issecure(req, trustProxy); @@ -199,7 +199,8 @@ function session(options) { // pathname mismatch var originalPath = parseUrl.original(req).pathname || '/' - if (originalPath.indexOf(cookieOptions.path || '/') !== 0) { + var resolvedCookieOptions = typeof cookieOptions === 'function' ? cookieOptions(req) : cookieOptions + if (originalPath.indexOf(resolvedCookieOptions.path || '/') !== 0) { debug('pathname mismatch') next() return diff --git a/test/session.js b/test/session.js index 31f4707b..46fed763 100644 --- a/test/session.js +++ b/test/session.js @@ -802,6 +802,58 @@ describe('session()', function(){ }) }) + describe('when "cookie" is a function', function () { + it('should call custom function and apply cookie options', function (done) { + var cookieCallbackCalled = false; + var cookieCallback = function () { + cookieCallbackCalled = true; + return { path: '/test', httpOnly: true, secure: false }; + }; + var server = createServer({ cookie: cookieCallback }); + request(server) + .get('/test') + .expect( + shouldSetCookieWithAttributeAndValue('connect.sid', 'Path', '/test') + ) + .expect(shouldSetCookieWithAttribute('connect.sid', 'HttpOnly')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(200, function (err) { + if (err) return done(err); + assert.strictEqual( + cookieCallbackCalled, + true, + 'should have called cookie callback' + ); + done(); + }); + }); + + it('should provide req argument', function (done) { + var _path = '/test'; + var cookieCallbackCalled = false; + var cookieCallback = function (req) { + cookieCallbackCalled = true; + return { path: req.url, httpOnly: true, secure: false }; + }; + var server = createServer({ cookie: cookieCallback }); + request(server) + .get(_path) + .expect( + shouldSetCookieWithAttributeAndValue('connect.sid', 'Path', _path) + ) + .expect(shouldSetCookieWithAttribute('connect.sid', 'HttpOnly')) + .expect(shouldSetCookieWithoutAttribute('connect.sid', 'Secure')) + .expect(200, function (err) { + if (err) return done(err); + assert.strictEqual( + cookieCallbackCalled, + true, + 'should have called cookie callback' + ); + done(); + }); + }); + }); describe('when "sameSite" set to "auto"', function () { describe('basic functionality', function () { before(function () { From c10b2a383841766899f6dcf53c8aff8c7fd3d2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Thu, 22 Jan 2026 15:44:27 +0100 Subject: [PATCH 756/766] 1.19.0 (#1107) --- HISTORY.md | 36 ++++++------------------------------ package.json | 2 +- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e28c5427..fae1a0f1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,33 +1,9 @@ -# Unreleased changes - -### ๐Ÿš€ Improvements - -* Add dynamic cookie options support - - Cookie options can now be dynamic, allowing for more flexible and context-aware configuration based on each request. This feature enables programmatic modification of cookie attributes like `secure`, `httpOnly`, `sameSite`, `maxAge`, `domain`, and `path` based on session or request conditions. - - ```js - var app = express() - app.use(session({ - secret: 'keyboard cat', - resave: false, - saveUninitialized: true, - cookie: function (req) { - var match = req.url.match(/^\/([^/]+)/); - return { - path: match ? '/' + match[1] : '/', - httpOnly: true, - secure: req.secure || false, - maxAge: 60000 - } - } - })) - ``` -* Add sameSite 'auto' support for automatic SameSite attribute configuration - - Added `sameSite: 'auto'` option for cookie configuration that automatically sets `SameSite=None` for HTTPS and `SameSite=Lax` for HTTP connections, simplifying cookie handling across different environments. - -* deps: use tilde notation for dependencies +1.19.0 / 2026-01-22 +========== + + * Add dynamic cookie options support + * Add sameSite 'auto' support for automatic SameSite attribute configuration + * deps: use tilde notation for dependencies 1.18.2 / 2025-07-17 ========== diff --git a/package.json b/package.json index 0f7d92e7..36387796 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-session", - "version": "1.18.2", + "version": "1.19.0", "description": "Simple session middleware for Express", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "contributors": [ From 31bb90351eceb003e4fb40d01c6c0ca1c1ba2f6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:42:03 +0100 Subject: [PATCH 757/766] build(deps): bump github/codeql-action from 4.31.6 to 4.32.4 (#1111) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.6 to 4.32.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/fe4161a26a8629af62121b670040955b330f9af2...89a39a4e59826350b863aa6b6252a07ad50cf83e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.32.4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8534ee51..e4fbd605 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 169262af..a1566ba6 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 with: sarif_file: results.sarif \ No newline at end of file From 1d90a1a61921ae600fc127b3bc0ce6de03890cc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:42:39 +0100 Subject: [PATCH 758/766] build(deps): bump actions/upload-artifact from 5.0.0 to 7.0.0 (#1112) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5.0.0 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/330a01c490aca151604b8cf639adc76d48f6c5d4...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13336155..152d687d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -208,7 +208,7 @@ jobs: fi - name: Upload code coverage - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: steps.list_env.outputs.nyc != '' with: name: coverage-${{ matrix.node-version }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a1566ba6..e6ba6369 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -60,7 +60,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: SARIF file path: results.sarif From 625c136fe52189ed3cc6e7ad4eb45b1cf11540b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:43:16 +0100 Subject: [PATCH 759/766] build(deps): bump actions/download-artifact from 6.0.0 to 8.0.0 (#1113) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6.0.0 to 8.0.0. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/018cc2cf5baa6db3ef3c5f8a56943fffe632ef53...70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 152d687d..9dee4344 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -229,7 +229,7 @@ jobs: run: sudo apt-get -y install lcov - name: Collect coverage reports - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: path: ./coverage From 663359c771f6b13b9b3bd60ee7d56062d98c63bd Mon Sep 17 00:00:00 2001 From: Ignacio Mangas Date: Mon, 16 Mar 2026 12:23:53 +0100 Subject: [PATCH 760/766] chore: fix node to v25 (#1110) --- .github/workflows/ci.yml | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9dee4344..29b55239 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,10 @@ jobs: - Node.js 19.x - Node.js 20.x - Node.js 21.x + - Node.js 22.x + - Node.js 23.x + - Node.js 24.x + - Node.js 25.x include: - name: Node.js 0.8 @@ -124,10 +128,22 @@ jobs: node-version: "19.9" - name: Node.js 20.x - node-version: "20.11" + node-version: "20" - name: Node.js 21.x - node-version: "21.6" + node-version: "21" + + - name: Node.js 22.x + node-version: "22" + + - name: Node.js 23.x + node-version: "23" + + - name: Node.js 24.x + node-version: "24" + + - name: Node.js 25.x + node-version: "25" steps: - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 @@ -139,7 +155,12 @@ jobs: if [[ "${{ matrix.node-version }}" == 0.* && "$(cut -d. -f2 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then nvm install --alias=npm 0.10 nvm use ${{ matrix.node-version }} - sed -i '1s;^.*$;'"$(printf '#!%q' "$(nvm which npm)")"';' "$(readlink -f "$(which npm)")" + if [[ "$(npm -v)" == 1.1.* ]]; then + nvm exec npm npm install -g npm@1.1 + ln -fs "$(which npm)" "$(dirname "$(nvm which npm)")/npm" + else + sed -i '1s;^.*$;'"$(printf '#!%q' "$(nvm which npm)")"';' "$(readlink -f "$(which npm)")" + fi npm config set strict-ssl false fi dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" From 2c9512fb790e4bf80b3b62305eb8078028607785 Mon Sep 17 00:00:00 2001 From: krzysdz <12915102+krzysdz@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:11:21 +0000 Subject: [PATCH 761/766] Remove nonexistent projects and update link in readme (#1122) - sequelize has a new website and a slightly broken redirect to the new one - cyclic has shut down - dynamodb-store-v3 package does not exist https://github.com/sequelize/website/issues/839 https://github.com/cyclic-software/www/blob/31e26692f2f04e29917fe011b9bfd7a03fbd7e81/content/posts/cyclic-is-shutting-down.md https://web.archive.org/web/20240501064115/https://www.cyclic.sh/posts/cyclic-is-shutting-down/ --- README.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 292b2024..0a7edb04 100644 --- a/README.md +++ b/README.md @@ -733,7 +733,7 @@ and other multi-core embedded devices). [connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85 [![โ˜…][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using -[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL. +[Sequelize.js](https://sequelize.org/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL. [connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize [connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85 @@ -758,11 +758,6 @@ and other multi-core embedded devices). [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store [dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85 -[![โ˜…][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3). - -[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3 -[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85 - [![โ˜…][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. [express-etcd-url]: https://www.npmjs.com/package/express-etcd @@ -868,7 +863,7 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [restsession-url]: https://www.npmjs.com/package/restsession [restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85 -[![โ˜…][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/). +[![โ˜…][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](https://sequelize.org/). [sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect [sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85 @@ -883,11 +878,6 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store [session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85 -[![โ˜…][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps. - -[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store -[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85 - [![โ˜…][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store. [@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store From e6509b12dea0c2911352725af99874d574c8d66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Mon, 6 Jul 2026 04:07:01 +0200 Subject: [PATCH 762/766] fix: use RFC 6265 path matching for cookie path option (#1114) * test: add specific RFC 6265 5.1.4 compliance tests * feat: add specific RFC 6265 5.1.4 handler * docs: note RFC 6265 5.1.4 compliance in cookie.path documentation * feat: enhance cookie handling for RFC 6265 compliance with path matching and auto secure/sameSite options * feat: enforce RFC 6265 section 5.1.4 path matching for session cookie path --------- Co-authored-by: Sebastian Beltran --- HISTORY.md | 6 ++ README.md | 7 +++ index.js | 48 ++++++++++++++-- test/session.js | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index fae1a0f1..251d5fa7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * Enforce RFC 6265 section 5.1.4 path matching for the session cookie path + * Fix `secure: 'auto'` and `sameSite: 'auto'` not being resolved when `cookie` is a function + 1.19.0 / 2026-01-22 ========== diff --git a/README.md b/README.md index 0a7edb04..162ea14d 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,12 @@ More information about can be found in [the proposal](https://github.com/privacy Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. +Since 1.19.1, path matching follows [RFC 6265 section 5.1.4][rfc-6265-5.1.4]. This means +the session middleware will only activate when the request path is an exact match or falls +under a segment boundary of the cookie path. For example, a cookie path of `/admin` will +match `/admin` and `/admin/users` but will **not** match `/administrator`. Prior versions +used a simple prefix check that did not enforce segment boundaries. + ##### cookie.priority Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. @@ -1038,6 +1044,7 @@ On Windows, use the corresponding command; [MIT](LICENSE) +[rfc-6265-5.1.4]: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 [rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ [rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 diff --git a/index.js b/index.js index 1a509318..41f9447f 100644 --- a/index.js +++ b/index.js @@ -158,15 +158,16 @@ function session(options) { store.generate = function(req){ req.sessionID = generateId(req); req.session = new Session(req); - req.session.cookie = new Cookie(typeof cookieOptions === 'function' ? cookieOptions(req) : cookieOptions); + var resolvedCookieOptions = typeof cookieOptions === 'function' ? cookieOptions(req) : cookieOptions; + req.session.cookie = new Cookie(resolvedCookieOptions); var isSecure = issecure(req, trustProxy); - if (cookieOptions.secure === 'auto') { + if (resolvedCookieOptions.secure === 'auto') { req.session.cookie.secure = isSecure; } - if (cookieOptions.sameSite === 'auto') { + if (resolvedCookieOptions.sameSite === 'auto') { req.session.cookie.sameSite = isSecure ? 'none' : 'lax'; } }; @@ -200,12 +201,15 @@ function session(options) { // pathname mismatch var originalPath = parseUrl.original(req).pathname || '/' var resolvedCookieOptions = typeof cookieOptions === 'function' ? cookieOptions(req) : cookieOptions - if (originalPath.indexOf(resolvedCookieOptions.path || '/') !== 0) { + var cfgPath = resolvedCookieOptions.path || '/' + + if (!rfcPathMatch(originalPath, cfgPath)) { debug('pathname mismatch') next() return } + // ensure a secret is available or bail if (!secret && !req.secret) { next(new Error('secret option required for sessions')); @@ -523,6 +527,42 @@ function session(options) { }; }; +/** + * Check if the cookiePath matches the requestPath following the + * rules in RFC 6265 section 5.1.4. + * + * @param {String} requestPath + * @param {String} cookiePath + * @return {Boolean} + * @private + */ + +function rfcPathMatch(requestPath, cookiePath) { + // Normalize inputs (Node 0.8-safe) + requestPath = (typeof requestPath === 'string' && requestPath.length) ? requestPath : '/'; + cookiePath = (typeof cookiePath === 'string' && cookiePath.length) ? cookiePath : '/'; + + // Root cookie matches everything + if (cookiePath === '/') return true; + + // Exact match + if (requestPath === cookiePath) return true; + + // Prefix match + if (requestPath.indexOf(cookiePath) === 0) { + // If cookiePath ends with '/', any longer requestPath is OK + if (cookiePath.charAt(cookiePath.length - 1) === '/') return true; + + // Otherwise the next char after the prefix must be '/' + var nextChar = requestPath.length > cookiePath.length + ? requestPath.charAt(cookiePath.length) + : ''; + return nextChar === '/'; + } + + return false; +} + /** * Generate a session ID for a new session. * diff --git a/test/session.js b/test/session.js index 46fed763..330c4137 100644 --- a/test/session.js +++ b/test/session.js @@ -853,6 +853,40 @@ describe('session()', function(){ done(); }); }); + + it('should not set cookie when request-path does not match returned path', function (done) { + var cookieCallback = function () { + return { path: '/admin', httpOnly: true, secure: false }; + }; + var server = createServer({ cookie: cookieCallback }); + request(server) + .get('/administrator') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done); + }); + + it('should resolve "secure" and "sameSite" set to "auto"', function (done) { + function setup (req) { + req.secure = JSON.parse(req.headers['x-secure']) + } + + function respond (req, res) { + res.end(String(req.secure)) + } + + var cookieCallback = function () { + return { path: '/', secure: 'auto', sameSite: 'auto' }; + }; + var server = createServer(setup, { cookie: cookieCallback }, respond); + request(server) + .get('/') + .set('X-Secure', 'true') + .expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) + .expect( + shouldSetCookieWithAttributeAndValue('connect.sid', 'SameSite', 'None') + ) + .expect(200, 'true', done); + }); }); describe('when "sameSite" set to "auto"', function () { describe('basic functionality', function () { @@ -2620,6 +2654,115 @@ describe('session()', function(){ }) }) +describe('path matching (RFC 6265)', function () { + describe('when "path" is "/" (root path)', function () { + before(function () { + this.server = createServer({ cookie: { path: '/' } }) + }) + + it('should set cookie when request-path is "/" (root path)', function (done) { + // RFC 6265 5.1.4: "The cookie-path and the request-path are identical." + request(this.server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should set cookie when request-path is any path ("/foo")', function (done) { + // RFC 6265 5.1.4: "The cookie-path is a prefix of the request-path, and the last + // character of the cookie-path is %x2F ("/")." + request(this.server) + .get('/foo') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should set cookie when request-path has multiple segments ("/foo/bar/baz")', function (done) { + // RFC 6265 5.1.4: "The cookie-path is a prefix of the request-path, and the last + // character of the cookie-path is %x2F ("/")." + request(this.server) + .get('/foo/bar/baz') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + }) + + describe('when "path" is "/admin"', function () { + before(function () { + this.server = createServer({ cookie: { path: '/admin' } }) + }) + + it('should set cookie when request-path and cookie-path are identical ("/admin")', function (done) { + // RFC 6265 5.1.4: "The cookie-path and the request-path are identical." + request(this.server) + .get('/admin') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should set cookie when cookie-path is prefix and last char is "/" ("/admin/")', function (done) { + // RFC 6265 5.1.4: "The cookie-path is a prefix of the request-path, and the last + // character of the cookie-path is %x2F ("/")." + request(this.server) + .get('/admin/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should set cookie when cookie-path is prefix and next char is "/" ("/admin/users")', function (done) { + // RFC 6265 5.1.4: "The cookie-path is a prefix of the request-path, and the first + // character of the request-path that is not included in the cookie-path is a %x2F ("/") character." + request(this.server) + .get('/admin/users') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should NOT set cookie when cookie-path is not a prefix ("/administrator")', function (done) { + // RFC 6265 5.1.4: None of the path-match conditions are met + request(this.server) + .get('/administrator') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }) + }) + + describe('when "path" is "/admin/" (trailing slash)', function () { + before(function () { + this.server = createServer({ cookie: { path: '/admin/' } }) + }) + + it('should set cookie when cookie-path is prefix and last char is "/" ("/admin/x")', function (done) { + // RFC 6265 5.1.4: "The cookie-path is a prefix of the request-path, and the last + // character of the cookie-path is %x2F ("/")." + request(this.server) + .get('/admin/x') + .expect(shouldSetCookie('connect.sid')) + .expect(200, done) + }) + + it('should NOT set cookie when request-path is not prefixed by cookie-path ("/admin")', function (done) { + // RFC 6265 5.1.4: cookie-path "/admin/" is not a prefix of request-path "/admin" + request(this.server) + .get('/admin') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }) + + it('should NOT set cookie when cookie-path is not a prefix ("/administrator")', function (done) { + // RFC 6265 5.1.4: None of the path-match conditions are met: + // 1. The paths are not identical + // 2. "/admin/" is not a prefix of "/administrator" + // 3. The prefix condition with next character "/" is not applicable + request(this.server) + .get('/administrator') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, done) + }) + }) +}) + + function cookie(res) { var setCookie = res.headers['set-cookie']; return (setCookie && setCookie[0]) || undefined; From 953bfe2ea1878fe79b5494335c0f1c5e332224c2 Mon Sep 17 00:00:00 2001 From: Raashish Aggarwal <94279692+raashish1601@users.noreply.github.com> Date: Mon, 6 Jul 2026 07:54:05 +0530 Subject: [PATCH 763/766] fix: detect secure socket when connection is missing (#1124) * fix: detect secure socket when connection is missing * fix: improve secure socket detection logic in session handling --------- Co-authored-by: Sebastian Beltran --- index.js | 3 ++- test/session.js | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 41f9447f..eb15ea64 100644 --- a/index.js +++ b/index.js @@ -677,7 +677,8 @@ function hash(sess) { function issecure(req, trustProxy) { // socket is https server - if (req.connection && req.connection.encrypted) { + var socket = req.socket || req.connection; + if (socket && socket.encrypted) { return true; } diff --git a/test/session.js b/test/session.js index 330c4137..abf846f5 100644 --- a/test/session.js +++ b/test/session.js @@ -800,6 +800,31 @@ describe('session()', function(){ .expect(200, 'false', done) }) }) + + describe('when request socket is encrypted', function () { + it('should set secure over TLS', function (done) { + var cert = fs.readFileSync(__dirname + '/fixtures/server.crt', 'ascii') + var server = https.createServer({ + key: fs.readFileSync(__dirname + '/fixtures/server.key', 'ascii'), + cert: cert + }) + + server.on('request', createRequestListener({ secret: 'keyboard cat', cookie: { secure: 'auto' } })) + + var agent = new https.Agent({ ca: cert }) + var createConnection = agent.createConnection + + agent.createConnection = function (options) { + options.servername = 'express-session.local' + return createConnection.call(this, options) + } + + var req = request(server).get('/') + req.agent(agent) + req.expect(shouldSetCookieWithAttribute('connect.sid', 'Secure')) + req.expect(200, done) + }) + }) }) describe('when "cookie" is a function', function () { @@ -888,6 +913,8 @@ describe('session()', function(){ .expect(200, 'true', done); }); }); + + describe('when "sameSite" set to "auto"', function () { describe('basic functionality', function () { before(function () { From 2deb78e42a8dff6c6d8ffcf3f196dfc4ed0f02da Mon Sep 17 00:00:00 2001 From: Ayoub Mabrouk <77799760+Ayoub-Mabrouk@users.noreply.github.com> Date: Mon, 6 Jul 2026 03:30:48 +0100 Subject: [PATCH 764/766] refactor: replace deprecated substr() with slice() (#1099) Replace all instances of String.prototype.substr() with String.prototype.slice() to use the standard, non-deprecated method. This maintains compatibility with Node.js >= 0.8.0 while following modern JavaScript best practices. All replacements maintain identical functionality as slice() and substr() behave the same for these use cases. Co-authored-by: bjohansebas <103585995+bjohansebas@users.noreply.github.com> --- index.js | 6 +++--- test/session.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index eb15ea64..3e23e901 100644 --- a/index.js +++ b/index.js @@ -593,7 +593,7 @@ function getcookie(req, name, secrets) { raw = cookies[name]; if (raw) { - if (raw.substr(0, 2) === 's:') { + if (raw.slice(0, 2) === 's:') { val = unsigncookie(raw.slice(2), secrets); if (val === false) { @@ -620,7 +620,7 @@ function getcookie(req, name, secrets) { raw = req.cookies[name]; if (raw) { - if (raw.substr(0, 2) === 's:') { + if (raw.slice(0, 2) === 's:') { val = unsigncookie(raw.slice(2), secrets); if (val) { @@ -696,7 +696,7 @@ function issecure(req, trustProxy) { var header = req.headers['x-forwarded-proto'] || ''; var index = header.indexOf(','); var proto = index !== -1 - ? header.substr(0, index).toLowerCase().trim() + ? header.slice(0, index).toLowerCase().trim() : header.toLowerCase().trim() return proto === 'https'; diff --git a/test/session.js b/test/session.js index abf846f5..405e3ddf 100644 --- a/test/session.js +++ b/test/session.js @@ -1299,7 +1299,7 @@ describe('session()', function(){ var store = new session.MemoryStore() var server = createServer({ resave: false, store: store }, function (req, res) { if (req.method === 'PUT') { - req.session.token = req.url.substr(1) + req.session.token = req.url.slice(1) } res.end('token=' + (req.session.token || '')) }) From 2799984fd07d4963fbc128f5f0d9d9f2f48829fe Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 7 Jul 2026 11:15:48 -0500 Subject: [PATCH 765/766] chore: add groups for GitHub Actions and npm dependencies in dependabot (#1133) --- .github/dependabot.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 492d67d0..7d2c7033 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,6 +4,10 @@ updates: directory: / schedule: interval: monthly + groups: + github-actions: + patterns: + - "*" - package-ecosystem: npm directory: / @@ -12,3 +16,7 @@ updates: ignore: - dependency-name: "*" update-types: ["version-update:semver-major"] + groups: + npm-dependencies: + patterns: + - "*" From d209c1f4cd645e514cd7320afd15acf7e7b5fcb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 12:23:53 -0500 Subject: [PATCH 766/766] build(deps): bump the github-actions group with 6 updates (#1140) Bumps the github-actions group with 6 updates: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `6.0.0` | `7.0.0` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `8.0.0` | `8.0.1` | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.32.4` | `4.36.3` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.32.4` | `4.36.3` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.32.4` | `4.36.3` | Updates `actions/checkout` from 6.0.0 to 7.0.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/1af3b93b6815bc44a9784bd300feb67ff0d1eeb3...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) Updates `actions/upload-artifact` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) Updates `actions/download-artifact` from 8.0.0 to 8.0.1 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) Updates `github/codeql-action/init` from 4.32.4 to 4.36.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/89a39a4e59826350b863aa6b6252a07ad50cf83e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a) Updates `github/codeql-action/analyze` from 4.32.4 to 4.36.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/89a39a4e59826350b863aa6b6252a07ad50cf83e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a) Updates `github/codeql-action/upload-sarif` from 4.32.4 to 4.36.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/89a39a4e59826350b863aa6b6252a07ad50cf83e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/init dependency-version: 4.36.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: github/codeql-action/analyze dependency-version: 4.36.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.36.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/codeql.yml | 6 +++--- .github/workflows/scorecard.yml | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29b55239..004c35ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -146,7 +146,7 @@ jobs: node-version: "25" steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Install Node.js ${{ matrix.node-version }} shell: bash -eo pipefail -l {0} @@ -229,7 +229,7 @@ jobs: fi - name: Upload code coverage - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: steps.list_env.outputs.nyc != '' with: name: coverage-${{ matrix.node-version }} @@ -243,14 +243,14 @@ jobs: needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Install lcov shell: bash run: sudo apt-get -y install lcov - name: Collect coverage reports - uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ./coverage diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e4fbd605..139ec706 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,11 +34,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e6ba6369..2bb15b23 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,7 +33,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -60,7 +60,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: SARIF file path: results.sarif @@ -68,6 +68,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 with: sarif_file: results.sarif \ No newline at end of file