diff --git a/History.md b/History.md index 6d133be..3106d57 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ 0.6.x ===== + * Add `secure` constructor option for secure connection checking * Change constructor to signature `new Cookies(req, res, [options])` - Replace `new Cookies(req, res, key)` with `new Cookies(req, res, {'keys': keys})` * Change prototype construction for proper "constructor" property diff --git a/README.md b/README.md index bd2e22b..39149dd 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ This creates a cookie jar corresponding to the current _request_ and _response_, A [Keygrip](https://www.npmjs.com/package/keygrip) object or an array of keys can optionally be passed as _options.keys_ to enable cryptographic signing based on SHA1 HMAC, using rotated credentials. +A Boolean can optionally be passed as _options.secure_ to explicitally specify if the connection is secure, rather than this module exaiming _request_. + Note that since this only saves parameters without any other processing, it is very lightweight. Cookies are only parsed on demand when they are accessed. ### express.createServer( Cookies.express( keys ) ) diff --git a/lib/cookies.js b/lib/cookies.js index ec97e7a..15a64e7 100644 --- a/lib/cookies.js +++ b/lib/cookies.js @@ -16,6 +16,7 @@ var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; function Cookies(request, response, options) { if (!(this instanceof Cookies)) return new Cookies(request, response, options) + this.secure = undefined this.request = request this.response = response @@ -30,6 +31,7 @@ function Cookies(request, response, options) { this.keys = options } else { this.keys = options.keys + this.secure = options.secure } } } @@ -67,7 +69,7 @@ Cookies.prototype.set = function(name, value, opts) { var res = this.response , req = this.request , headers = res.getHeader("Set-Cookie") || [] - , secure = req.protocol === 'https' || req.connection.encrypted + , secure = this.secure !== undefined ? !!this.secure : req.protocol === 'https' || req.connection.encrypted , cookie = new Cookie(name, value, opts) , signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys diff --git a/test/http.js b/test/http.js index 4f4ed1a..38fcd44 100644 --- a/test/http.js +++ b/test/http.js @@ -82,4 +82,46 @@ describe('HTTP', function () { .set('Cookie', header.join(';')) .expect(200, done) }) + + describe('with "secure" option', function () { + it('should check connection when undefined; unencrypted', function (done) { + request(createServer( "http", { "keys": keys } )) + .get('/') + .expect(500, 'Cannot send secure cookie over unencrypted connection', done) + }) + + it('should check connection when undefined; encrypted', function (done) { + request(createServer( "https", { "keys": keys } )) + .get('/') + .expect(200, done) + }) + + it('should not check connection when defined; true', function (done) { + request(createServer( "http", { "keys": keys, "secure": true } )) + .get('/') + .expect(200, done) + }) + + it('should not check connection when defined; false', function (done) { + request(createServer( "https", { "keys": keys, "secure": false } )) + .get('/') + .expect(500, 'Cannot send secure cookie over unencrypted connection', done) + }) + }) }) + +function createServer(proto, opts) { + return http.createServer(function (req, res) { + var cookies = new Cookies( req, res, opts ) + req.protocol = proto + + try { + cookies.set( "foo", "bar", { "secure": true } ) + } catch (e) { + res.statusCode = 500 + res.write(e.message) + } + + res.end() + }) +}