From 7b90ada4de86716aad38a1b0b6c187cc4c3c62ca Mon Sep 17 00:00:00 2001 From: Jake Prime Date: Tue, 19 Mar 2019 15:52:31 +0000 Subject: [PATCH 1/5] Send `max-age` header as well as `expires` if it is set Older versions of IE will ignore the `max-age` and use the `expires` value. Any browser which supports `max-age` will use it in preference of `expires` if both are present. --- index.js | 1 + test/test.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 9c468ae..e0d574b 100644 --- a/index.js +++ b/index.js @@ -164,6 +164,7 @@ Cookie.prototype.toHeader = function() { if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge); + if (this.maxAge ) header += "; max-age=" + this.maxAge if (this.path ) header += "; path=" + this.path if (this.expires ) header += "; expires=" + this.expires.toUTCString() if (this.domain ) header += "; domain=" + this.domain diff --git a/test/test.js b/test/test.js index 91dfb42..2dabdb7 100644 --- a/test/test.js +++ b/test/test.js @@ -297,7 +297,7 @@ describe('new Cookies(req, res, [options])', function () { .end(done) }) - it('should not set the "maxAge" attribute', function (done) { + it('should set the "maxAge" attribute', function (done) { request(createServer(function (req, res, cookies) { cookies.set('foo', 'bar', { maxAge: 86400000 }) res.end() @@ -305,7 +305,7 @@ describe('new Cookies(req, res, [options])', function () { .get('/') .expect(200) .expect(shouldSetCookieWithAttribute('foo', 'expires')) - .expect(shouldSetCookieWithoutAttribute('foo', 'maxAge')) + .expect(shouldSetCookieWithAttribute('foo', 'max-age')) .end(done) }) }) From aba7338f9e46ba6f775408190e5c05d59909f5ee Mon Sep 17 00:00:00 2001 From: Jake Prime Date: Tue, 19 Mar 2019 17:26:24 +0000 Subject: [PATCH 2/5] `max-age` should be specified in seconds --- README.md | 2 +- index.js | 2 +- test/test.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f7c12f8..35f19cc 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ If the _value_ is omitted, an outbound header with an expired date is used to de If the _options_ object is provided, it will be used to generate the outbound cookie header as follows: -* `maxAge`: a number representing the milliseconds from `Date.now()` for expiry +* `maxAge`: a number representing the seconds from `Date.now()` for expiry * `expires`: a `Date` object indicating the cookie's expiration date (expires at the end of session by default). * `path`: a string indicating the path of the cookie (`/` by default). * `domain`: a string indicating the domain of the cookie (no default). diff --git a/index.js b/index.js index e0d574b..e03f4ef 100644 --- a/index.js +++ b/index.js @@ -162,7 +162,7 @@ Cookie.prototype.toString = function() { Cookie.prototype.toHeader = function() { var header = this.toString() - if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge); + if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge * 1000); if (this.maxAge ) header += "; max-age=" + this.maxAge if (this.path ) header += "; path=" + this.path diff --git a/test/test.js b/test/test.js index 2dabdb7..80cd0ef 100644 --- a/test/test.js +++ b/test/test.js @@ -281,7 +281,7 @@ describe('new Cookies(req, res, [options])', function () { describe('"maxAge" option', function () { it('should set the "expires" attribute', function (done) { - var maxAge = 86400000 + var maxAge = 86400 request(createServer(function (req, res, cookies) { cookies.set('foo', 'bar', { maxAge: maxAge }) res.end() @@ -291,7 +291,7 @@ describe('new Cookies(req, res, [options])', function () { .expect(shouldSetCookieWithAttribute('foo', 'expires')) .expect(function (res) { var cookie = getCookieForName(res, 'foo') - var expected = new Date(Date.parse(res.headers.date) + maxAge).toUTCString() + var expected = new Date(Date.parse(res.headers.date) + maxAge * 1000).toUTCString() assert.strictEqual(cookie.expires, expected) }) .end(done) @@ -299,7 +299,7 @@ describe('new Cookies(req, res, [options])', function () { it('should set the "maxAge" attribute', function (done) { request(createServer(function (req, res, cookies) { - cookies.set('foo', 'bar', { maxAge: 86400000 }) + cookies.set('foo', 'bar', { maxAge: 86400 }) res.end() })) .get('/') From 53297ab9e11a9a843e85bb65574cd2362af6398a Mon Sep 17 00:00:00 2001 From: Jake Prime Date: Wed, 20 Mar 2019 08:16:44 +0000 Subject: [PATCH 3/5] Revert "`max-age` should be specified in seconds" This reverts commit aba7338f9e46ba6f775408190e5c05d59909f5ee. --- README.md | 2 +- index.js | 2 +- test/test.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 35f19cc..f7c12f8 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ If the _value_ is omitted, an outbound header with an expired date is used to de If the _options_ object is provided, it will be used to generate the outbound cookie header as follows: -* `maxAge`: a number representing the seconds from `Date.now()` for expiry +* `maxAge`: a number representing the milliseconds from `Date.now()` for expiry * `expires`: a `Date` object indicating the cookie's expiration date (expires at the end of session by default). * `path`: a string indicating the path of the cookie (`/` by default). * `domain`: a string indicating the domain of the cookie (no default). diff --git a/index.js b/index.js index e03f4ef..e0d574b 100644 --- a/index.js +++ b/index.js @@ -162,7 +162,7 @@ Cookie.prototype.toString = function() { Cookie.prototype.toHeader = function() { var header = this.toString() - if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge * 1000); + if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge); if (this.maxAge ) header += "; max-age=" + this.maxAge if (this.path ) header += "; path=" + this.path diff --git a/test/test.js b/test/test.js index 80cd0ef..2dabdb7 100644 --- a/test/test.js +++ b/test/test.js @@ -281,7 +281,7 @@ describe('new Cookies(req, res, [options])', function () { describe('"maxAge" option', function () { it('should set the "expires" attribute', function (done) { - var maxAge = 86400 + var maxAge = 86400000 request(createServer(function (req, res, cookies) { cookies.set('foo', 'bar', { maxAge: maxAge }) res.end() @@ -291,7 +291,7 @@ describe('new Cookies(req, res, [options])', function () { .expect(shouldSetCookieWithAttribute('foo', 'expires')) .expect(function (res) { var cookie = getCookieForName(res, 'foo') - var expected = new Date(Date.parse(res.headers.date) + maxAge * 1000).toUTCString() + var expected = new Date(Date.parse(res.headers.date) + maxAge).toUTCString() assert.strictEqual(cookie.expires, expected) }) .end(done) @@ -299,7 +299,7 @@ describe('new Cookies(req, res, [options])', function () { it('should set the "maxAge" attribute', function (done) { request(createServer(function (req, res, cookies) { - cookies.set('foo', 'bar', { maxAge: 86400 }) + cookies.set('foo', 'bar', { maxAge: 86400000 }) res.end() })) .get('/') From 186a0aeb2e438c708519970a9cfc5ff6ff694b42 Mon Sep 17 00:00:00 2001 From: Jake Prime Date: Wed, 20 Mar 2019 08:48:54 +0000 Subject: [PATCH 4/5] Convert `max-age` to seconds before setting as header We still accept it as milliseconds though, to prevent a breaking change --- index.js | 2 +- test/test.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index e0d574b..f98ff8a 100644 --- a/index.js +++ b/index.js @@ -164,7 +164,7 @@ Cookie.prototype.toHeader = function() { if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge); - if (this.maxAge ) header += "; max-age=" + this.maxAge + if (this.maxAge ) header += "; max-age=" + Math.round(this.maxAge / 1000) if (this.path ) header += "; path=" + this.path if (this.expires ) header += "; expires=" + this.expires.toUTCString() if (this.domain ) header += "; domain=" + this.domain diff --git a/test/test.js b/test/test.js index 2dabdb7..be82f55 100644 --- a/test/test.js +++ b/test/test.js @@ -308,6 +308,17 @@ describe('new Cookies(req, res, [options])', function () { .expect(shouldSetCookieWithAttribute('foo', 'max-age')) .end(done) }) + + it('should convert the "maxAge" attribute to seconds', function (done) { + request(createServer(function (req, res, cookies) { + cookies.set('foo', 'bar', { maxAge: 86400001 }) + res.end() + })) + .get('/') + .expect(200) + .expect(shouldSetCookieWithAttributeAndValue('foo', 'max-age', '86400')) + .end(done) + }) }) describe('"overwrite" option', function () { From 647f41a111777296eb62abc7cdce977ee4fd0bb5 Mon Sep 17 00:00:00 2001 From: Jake Prime Date: Wed, 20 Mar 2019 09:00:51 +0000 Subject: [PATCH 5/5] Update documentation on `max-age` option --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7c12f8..6c5256c 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ If the _value_ is omitted, an outbound header with an expired date is used to de If the _options_ object is provided, it will be used to generate the outbound cookie header as follows: -* `maxAge`: a number representing the milliseconds from `Date.now()` for expiry +* `maxAge`: a number representing the milliseconds from `Date.now()` for expiry. If this and `expires` are both set this will take precedence. This value will be converted to seconds before being added to the Set-Cookie header * `expires`: a `Date` object indicating the cookie's expiration date (expires at the end of session by default). * `path`: a string indicating the path of the cookie (`/` by default). * `domain`: a string indicating the domain of the cookie (no default).