Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: add ability to create Partitioned Cookies #226

Merged
merged 7 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ The options object is used to generate the `Set-Cookie` header of the session co
* `expires` - The expiration `date` used for the `Expires` attribute. If both `expires` and `maxAge` are set, then `maxAge` is used.
* `sameSite`- The `boolean` or `string` of the `SameSite` attribute. Using `Secure` mode with `auto` attribute will change the behavior of the `SameSite` attribute in `http` mode. The `SameSite` attribute will automatically be set to `Lax` with an `http` request. See this [link](https://www.chromium.org/updates/same-site).
* `domain` - The `Domain` attribute.
* `partitioned`- The `boolean` value of the `Partitioned` attribute. Using the Partitioned attribute as part of Cookies Having Independent Partitioned State (CHIPS) to allow cross-site access with a separate cookie used per site.Defaults to false.
nicob-29 marked this conversation as resolved.
Show resolved Hide resolved
nicob-29 marked this conversation as resolved.
Show resolved Hide resolved

##### store
A session store. Needs the following methods:
Expand Down
4 changes: 3 additions & 1 deletion lib/cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = class Cookie {
this.sameSite = cookie.sameSite || null
this.domain = cookie.domain || null
this.httpOnly = cookie.httpOnly !== undefined ? cookie.httpOnly : true
this.partitioned = cookie.partitioned
this._expires = null

if (originalMaxAge) {
Expand Down Expand Up @@ -61,7 +62,8 @@ module.exports = class Cookie {
secure: this.secure,
path: this.path,
httpOnly: this.httpOnly,
domain: this.domain
domain: this.domain,
partitioned: this.partitioned
}
}
}
32 changes: 30 additions & 2 deletions test/cookie.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,32 @@ test('should set session secure cookie secureAuto x-forwarded-proto header', asy
t.match(response.headers['set-cookie'], /sessionId=[\w-]{32}.[\w-%]{43,57}; Path=\/; HttpOnly; Secure/)
})

test('should set session partitioned cookie secure http encrypted', async (t) => {
t.plan(2)
const fastify = Fastify()
fastify.addHook('onRequest', async (request, reply) => {
request.raw.socket.encrypted = true
})
fastify.register(fastifyCookie)
fastify.register(fastifySession, {
secret: DEFAULT_SECRET,
cookie: { secure: 'true', partitioned: true }
})
fastify.get('/', (request, reply) => {
request.session.test = {}
reply.send(200)
})
await fastify.listen({ port: 0 })
t.teardown(() => { fastify.close() })

const response = await fastify.inject({
url: '/'
})

t.equal(response.statusCode, 200)
t.match(response.headers['set-cookie'], /sessionId=[\w-]{32}.[\w-%]{43,57}; Path=\/; HttpOnly; Secure; Partitioned/)
})

test('should use maxAge instead of expires in session if both are set in options.cookie', async (t) => {
t.plan(3)
const expires = new Date(34214461000) // 1971-02-01T00:01:01.000Z
Expand Down Expand Up @@ -510,7 +536,7 @@ test('Cookie', t => {
const cookie = new Cookie({})

t.test('properties', t => {
t.plan(9)
t.plan(10)

t.equal('expires' in cookie, true)
t.equal('originalMaxAge' in cookie, true)
Expand All @@ -521,10 +547,11 @@ test('Cookie', t => {
t.equal('domain' in cookie, true)
t.equal('_expires' in cookie, true)
t.equal('maxAge' in cookie, true)
t.equal('partitioned' in cookie, true)
})

t.test('toJSON', t => {
t.plan(9)
t.plan(10)

const json = cookie.toJSON()

Expand All @@ -535,6 +562,7 @@ test('Cookie', t => {
t.equal('path' in json, true)
t.equal('httpOnly' in json, true)
t.equal('domain' in json, true)
t.equal('partitioned' in json, true)

t.equal('_expires' in json, false)
t.equal('maxAge' in json, false)
Expand Down