Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ The default value is `undefined`.
if there is a direct TLS/SSL connection.
- `undefined` Uses the "trust proxy" setting from express

##### autoSecure

Setting this option will turn the cookie into a secure cookie if the request is secure.
It decides whether a request is secure based on the proxy setting. This setting overrides
the "secure" cookie option.

The default value is `false`.

##### resave

Forces the session to be saved back to the session store, even if the session
Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function session(options){
, store = options.store || new MemoryStore
, cookie = options.cookie || {}
, trustProxy = options.proxy
, autoSecure = options.autoSecure || false
, storeReady = true
, rollingSessions = options.rolling || false;
var resaveSession = options.resave;
Expand Down Expand Up @@ -140,6 +141,9 @@ function session(options){
req.sessionID = generateId(req);
req.session = new Session(req);
req.session.cookie = new Cookie(cookie);
if (autoSecure) {
req.session.cookie.secure = issecure(req, trustProxy);
}
};

var storeImplementsTouch = typeof store.touch === 'function';
Expand Down
121 changes: 121 additions & 0 deletions test/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,45 @@ describe('session()', function(){
.expect(shouldNotHaveHeader('Set-Cookie'))
.expect(200, done)
})
describe('auto-set secure cookie', function() {
before(function () {
server = createServer({ proxy: true, autoSecure: true, cookie: { maxAge: 5 }})
})
it('should set secure cookie when X-Forwarded-Proto is https', function(done){
request(server)
.get('/')
.set('X-Forwarded-Proto', 'https')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.notEqual(val.indexOf('Secure'), -1, 'should be Secure cookie')
done();
})
})

it('should trust X-Forwarded-Proto when comma-separated list', function(done){
request(server)
.get('/')
.set('X-Forwarded-Proto', 'https,http')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.notEqual(val.indexOf('Secure'), -1, 'should be Secure cookie')
done();
})
})

it('should work when no header', function(done){
request(server)
.get('/')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.equal(val.indexOf('Secure'), -1, 'should not be Secure cookie')
done();
})
})
})
})

describe('when disabled', function(){
Expand Down Expand Up @@ -607,6 +646,45 @@ describe('session()', function(){
.expect(shouldNotHaveHeader('Set-Cookie'))
.expect(200, 'true', done)
})
describe('never auto-set secure cookie', function() {
before(function () {
server = createServer({ proxy: false, autoSecure: true, cookie: { maxAge: 5 }})
})
it('should set secure cookie when X-Forwarded-Proto is https', function(done){
request(server)
.get('/')
.set('X-Forwarded-Proto', 'https')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.equal(val.indexOf('Secure'), -1, 'should not be a Secure cookie')
done();
})
})

it('should trust X-Forwarded-Proto when comma-separated list', function(done){
request(server)
.get('/')
.set('X-Forwarded-Proto', 'https,http')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.equal(val.indexOf('Secure'), -1, 'should not be Secure cookie')
done();
})
})

it('should work when no header', function(done){
request(server)
.get('/')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.equal(val.indexOf('Secure'), -1, 'should not be Secure cookie')
done();
})
})
})
})

describe('when unspecified', function(){
Expand Down Expand Up @@ -635,6 +713,49 @@ describe('session()', function(){
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', done)
})
describe('auto-set secure cookie', function() {
var app;
before(function () {
app = express()
.use(session({ secret: 'keyboard cat', autoSecure: true, cookie: { maxAge: min }}))
.use(function(req, res) { res.json(req.secure); });
app.enable('trust proxy');
})
it('should set secure cookie when X-Forwarded-Proto is https', function(done){
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.notEqual(val.indexOf('Secure'), -1, 'should be Secure cookie')
done();
})
})

it('should trust X-Forwarded-Proto when comma-separated list', function(done){
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https,http')
.expect(shouldSetCookie('connect.sid'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.notEqual(val.indexOf('Secure'), -1, 'should be Secure cookie')
done();
})
})

it('should work when no header', function(done){
request(app)
.get('/')
.expect(shouldNotHaveHeader('Set-Cookie'))
.expect(200, 'true', function(err, res) {
var val = cookie(res);
assert.equal(val.indexOf('Secure'), -1, 'should not be Secure cookie')
done();
})
})
})
})
})

Expand Down