Skip to content

Commit

Permalink
Added the ability to configure cookie options within a route (#260)
Browse files Browse the repository at this point in the history
* Added the ability to configure cookie options within a route

* Fixed usage of regenerate, preserve old cookieOpts

Co-authored-by: Gürgün Dayıoğlu <hey@gurgun.day>
Signed-off-by: Oleg Gheorghita <ogheo@users.noreply.github.com>

* Updated override global options test with regenerate

* Moved overriding global options using regenerate fn to a separate test

---------

Signed-off-by: Oleg Gheorghita <ogheo@users.noreply.github.com>
Co-authored-by: Gürgün Dayıoğlu <hey@gurgun.day>
  • Loading branch information
ogheo and gurgunday authored Jul 25, 2024
1 parent efb8e4e commit 2a0ffbe
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 0 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ Allows to destroy the session in the store. If you do not pass a callback, a Pro

Updates the `expires` property of the session's cookie.

#### Session#options(opts)

Updates default options for setCookie inside a route.

```js
fastify.post('/', (request, reply) => {
request.session.set('data', request.body)
// .options takes any parameter that you can pass to setCookie
request.session.options({ maxAge: 60 * 60 }); // 3600 seconds => maxAge is always passed in seconds
reply.send('hello world')
})
```

#### Session#regenerate([ignoreFields, ]callback)

Regenerates the session by generating a new `sessionId` and persist it to the store. If you do not pass a callback, a Promise will be returned.
Expand Down
7 changes: 7 additions & 0 deletions lib/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ module.exports = class Session {
this[persistedHash] = this[hash]()
}

options (opts) {
if (Object.keys(opts).length) {
Object.assign(this[cookieOptsKey], opts)
this.cookie = new Cookie(this[cookieOptsKey], this[requestKey])
}
}

touch () {
if (this.cookie.originalMaxAge) {
this.cookie.expires = new Date(Date.now() + this.cookie.originalMaxAge)
Expand Down
188 changes: 188 additions & 0 deletions test/session.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1083,3 +1083,191 @@ test('should save session if existing, modified, rolling false, and cookie.expir
})
t.equal(response3.statusCode, 200)
})

test('Custom options', async t => {
t.plan(6)

const fastify = Fastify()
fastify.register(fastifyCookie)
fastify.register(fastifySession, {
...DEFAULT_OPTIONS,
cookie: {
secure: false,
path: '/'
}
})

fastify.post('/', (request, reply) => {
request.session.set('data', request.body)
request.session.options({ maxAge: 1000 * 60 * 60 })
reply.send('hello world')
})

t.teardown(fastify.close.bind(fastify))

fastify.get('/', (request, reply) => {
const data = request.session.get('data')
if (!data) {
reply.code(404).send()
return
}
reply.send(data)
})

fastify.inject({
method: 'POST',
url: '/',
payload: {
some: 'data'
}
}, (error, response) => {
t.error(error)
t.equal(response.statusCode, 200)
t.ok(response.headers['set-cookie'])
const { expires } = response.cookies[0]
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())

fastify.inject({
method: 'GET',
url: '/',
headers: {
cookie: response.headers['set-cookie']
}
}, (error, response) => {
t.error(error)
t.same(JSON.parse(response.payload), { some: 'data' })
})
})
})

test('Override global options', t => {
t.plan(11)

const fastify = Fastify()
fastify.register(fastifyCookie)
fastify.register(fastifySession, {
...DEFAULT_OPTIONS,
cookie: {
secure: false,
maxAge: 42,
path: '/'
}
})

fastify.post('/', (request, reply) => {
request.session.set('data', request.body)
request.session.options({ maxAge: 1000 * 60 * 60 })

reply.send('hello world')
})

t.teardown(fastify.close.bind(fastify))

fastify.get('/', (request, reply) => {
const data = request.session.get('data')

if (!data) {
reply.code(404).send()
return
}
reply.send(data)
})

fastify.inject({
method: 'POST',
url: '/',
payload: {
some: 'data'
}
}, (error, response) => {
t.error(error)
t.equal(response.statusCode, 200)
t.ok(response.headers['set-cookie'])
const { expires, path } = response.cookies[0]
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
t.equal(path, '/')

fastify.inject({
method: 'GET',
url: '/',
headers: {
cookie: response.headers['set-cookie']
}
}, (error, response) => {
t.error(error)
t.equal(response.statusCode, 200)
t.same(JSON.parse(response.payload), { some: 'data' })
t.ok(response.headers['set-cookie'])
const { expires, path } = response.cookies[0]
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
t.equal(path, '/')
})
})
})

test('Override global options with regenerate', t => {
t.plan(11)

const fastify = Fastify()
fastify.register(fastifyCookie)
fastify.register(fastifySession, {
...DEFAULT_OPTIONS,
cookie: {
secure: false,
maxAge: 42,
path: '/'
}
})

fastify.post('/', (request, reply) => {
request.session.set('data', request.body)
request.session.options({ maxAge: 1000 * 60 * 60 }) // maxAge updated to 1 hour

reply.send('hello world')
})

t.teardown(fastify.close.bind(fastify))

fastify.get('/', async (request, reply) => {
const data = request.session.get('data')
await request.session.regenerate()

if (!data) {
reply.code(404).send()
return
}

reply.send(data)
})

fastify.inject({
method: 'POST',
url: '/',
payload: {
some: 'data'
}
}, (error, response) => {
t.error(error)
t.equal(response.statusCode, 200)
t.ok(response.headers['set-cookie'])
const { expires, path } = response.cookies[0]
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
t.equal(path, '/')

fastify.inject({
method: 'GET',
url: '/',
headers: {
cookie: response.headers['set-cookie']
}
}, (error, response) => {
t.error(error)
t.equal(response.statusCode, 200)
t.same(JSON.parse(response.payload), { some: 'data' })
t.ok(response.headers['set-cookie'])
const { expires, path } = response.cookies[0]
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
t.equal(path, '/')
})
})
})

0 comments on commit 2a0ffbe

Please sign in to comment.