diff --git a/HISTORY.md b/HISTORY.md index 052d791..9fd5dce 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Add `partitioned` option for CHIPS support * Add `priority` option for Priority cookie support * Fix accidental cookie name/value truncation when given invalid chars * Fix `maxAge` option to reject invalid values diff --git a/README.md b/README.md index 7d1353d..d01496e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ If the _options_ object is provided, it will be used to generate the outbound co * `domain`: a string indicating the domain of the cookie (no default). * `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). [Read more about this option below](#secure-cookies). * `httpOnly`: a boolean indicating whether the cookie is only to be sent over HTTP(S), and not made available to client JavaScript (`true` by default). +* `partitioned`: a boolean indicating whether to partition the cookie in Chrome for the [CHIPS Update](https://developers.google.com/privacy-sandbox/3pcd/chips) (`false` by default). If this is true, Cookies from embedded sites will be partitioned and only readable from the same top level site from which it was created. * `priority`: a string indicating the cookie priority. This can be set to `'low'`, `'medium'`, or `'high'`. * `sameSite`: a boolean or string indicating whether the cookie is a "same site" cookie (`false` by default). This can be set to `'strict'`, `'lax'`, `'none'`, or `true` (which maps to `'strict'`). * `signed`: a boolean indicating whether the cookie is to be signed (`false` by default). If this is true, another cookie of the same name with the `.sig` suffix appended will also be sent, with a 27-byte url-safe base64 SHA1 value representing the hash of _cookie-name_=_cookie-value_ against the first [Keygrip](https://www.npmjs.com/package/keygrip) key. This signature key is used to detect tampering the next time a cookie is received. diff --git a/index.js b/index.js index 23c30bc..fb2fb81 100644 --- a/index.js +++ b/index.js @@ -189,6 +189,7 @@ Cookie.prototype.path = "/"; Cookie.prototype.expires = undefined; Cookie.prototype.domain = undefined; Cookie.prototype.httpOnly = true; +Cookie.prototype.partitioned = false Cookie.prototype.priority = undefined Cookie.prototype.sameSite = false; Cookie.prototype.secure = false; @@ -210,6 +211,7 @@ Cookie.prototype.toHeader = function() { if (this.sameSite ) header += "; samesite=" + (this.sameSite === true ? 'strict' : this.sameSite.toLowerCase()) if (this.secure ) header += "; secure" if (this.httpOnly ) header += "; httponly" + if (this.partitioned) header += '; partitioned' return header }; diff --git a/test/cookie.js b/test/cookie.js index b0daea9..375ad4e 100644 --- a/test/cookie.js +++ b/test/cookie.js @@ -81,6 +81,32 @@ describe('new Cookie(name, value, [options])', function () { }) }) + describe('partitioned', function () { + it('should set the .partitioned property', function () { + var cookie = new cookies.Cookie('foo', 'bar', { partitioned: true }) + assert.strictEqual(cookie.partitioned, true) + }) + + it('should default to false', function () { + var cookie = new cookies.Cookie('foo', 'bar') + assert.strictEqual(cookie.partitioned, false) + }) + + describe('when set to false', function () { + it('should not set partitioned attribute in header', function () { + var cookie = new cookies.Cookie('foo', 'bar', { partitioned: false }) + assert.strictEqual(cookie.toHeader(), 'foo=bar; path=/; httponly') + }) + }) + + describe('when set to true', function () { + it('should set partitioned attribute in header', function () { + var cookie = new cookies.Cookie('foo', 'bar', { partitioned: true }) + assert.strictEqual(cookie.toHeader(), 'foo=bar; path=/; httponly; partitioned') + }) + }) + }) + describe('priority', function () { it('should set the .priority property', function () { var cookie = new cookies.Cookie('foo', 'bar', { priority: 'low' }) diff --git a/test/test.js b/test/test.js index 818d2d6..e6a5901 100644 --- a/test/test.js +++ b/test/test.js @@ -339,6 +339,32 @@ describe('new Cookies(req, res, [options])', function () { }) }) + describe('"partitioned" option', function () { + it('should not be set by default', function (done) { + request(createServer(setCookieHandler('foo', 'bar'))) + .get('/') + .expect(200) + .expect(shouldSetCookieWithoutAttribute('foo', 'partitioned')) + .end(done) + }) + + it('should set to true', function (done) { + request(createServer(setCookieHandler('foo', 'bar', { partitioned: true }))) + .get('/') + .expect(200) + .expect(shouldSetCookieWithAttribute('foo', 'partitioned')) + .end(done) + }) + + it('should set to false', function (done) { + request(createServer(setCookieHandler('foo', 'bar', { partitioned: false }))) + .get('/') + .expect(200) + .expect(shouldSetCookieWithoutAttribute('foo', 'partitioned')) + .end(done) + }) + }) + describe('"path" option', function () { it('should default to "/"', function (done) { request(createServer(setCookieHandler('foo', 'bar')))