Skip to content

Commit 2a0ffbe

Browse files
ogheogurgunday
andauthored
Added the ability to configure cookie options within a route (#260)
* 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>
1 parent efb8e4e commit 2a0ffbe

File tree

3 files changed

+208
-0
lines changed

3 files changed

+208
-0
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ Allows to destroy the session in the store. If you do not pass a callback, a Pro
119119

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

122+
#### Session#options(opts)
123+
124+
Updates default options for setCookie inside a route.
125+
126+
```js
127+
fastify.post('/', (request, reply) => {
128+
request.session.set('data', request.body)
129+
// .options takes any parameter that you can pass to setCookie
130+
request.session.options({ maxAge: 60 * 60 }); // 3600 seconds => maxAge is always passed in seconds
131+
reply.send('hello world')
132+
})
133+
```
134+
122135
#### Session#regenerate([ignoreFields, ]callback)
123136

124137
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.

lib/session.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ module.exports = class Session {
5656
this[persistedHash] = this[hash]()
5757
}
5858

59+
options (opts) {
60+
if (Object.keys(opts).length) {
61+
Object.assign(this[cookieOptsKey], opts)
62+
this.cookie = new Cookie(this[cookieOptsKey], this[requestKey])
63+
}
64+
}
65+
5966
touch () {
6067
if (this.cookie.originalMaxAge) {
6168
this.cookie.expires = new Date(Date.now() + this.cookie.originalMaxAge)

test/session.test.js

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,3 +1083,191 @@ test('should save session if existing, modified, rolling false, and cookie.expir
10831083
})
10841084
t.equal(response3.statusCode, 200)
10851085
})
1086+
1087+
test('Custom options', async t => {
1088+
t.plan(6)
1089+
1090+
const fastify = Fastify()
1091+
fastify.register(fastifyCookie)
1092+
fastify.register(fastifySession, {
1093+
...DEFAULT_OPTIONS,
1094+
cookie: {
1095+
secure: false,
1096+
path: '/'
1097+
}
1098+
})
1099+
1100+
fastify.post('/', (request, reply) => {
1101+
request.session.set('data', request.body)
1102+
request.session.options({ maxAge: 1000 * 60 * 60 })
1103+
reply.send('hello world')
1104+
})
1105+
1106+
t.teardown(fastify.close.bind(fastify))
1107+
1108+
fastify.get('/', (request, reply) => {
1109+
const data = request.session.get('data')
1110+
if (!data) {
1111+
reply.code(404).send()
1112+
return
1113+
}
1114+
reply.send(data)
1115+
})
1116+
1117+
fastify.inject({
1118+
method: 'POST',
1119+
url: '/',
1120+
payload: {
1121+
some: 'data'
1122+
}
1123+
}, (error, response) => {
1124+
t.error(error)
1125+
t.equal(response.statusCode, 200)
1126+
t.ok(response.headers['set-cookie'])
1127+
const { expires } = response.cookies[0]
1128+
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
1129+
1130+
fastify.inject({
1131+
method: 'GET',
1132+
url: '/',
1133+
headers: {
1134+
cookie: response.headers['set-cookie']
1135+
}
1136+
}, (error, response) => {
1137+
t.error(error)
1138+
t.same(JSON.parse(response.payload), { some: 'data' })
1139+
})
1140+
})
1141+
})
1142+
1143+
test('Override global options', t => {
1144+
t.plan(11)
1145+
1146+
const fastify = Fastify()
1147+
fastify.register(fastifyCookie)
1148+
fastify.register(fastifySession, {
1149+
...DEFAULT_OPTIONS,
1150+
cookie: {
1151+
secure: false,
1152+
maxAge: 42,
1153+
path: '/'
1154+
}
1155+
})
1156+
1157+
fastify.post('/', (request, reply) => {
1158+
request.session.set('data', request.body)
1159+
request.session.options({ maxAge: 1000 * 60 * 60 })
1160+
1161+
reply.send('hello world')
1162+
})
1163+
1164+
t.teardown(fastify.close.bind(fastify))
1165+
1166+
fastify.get('/', (request, reply) => {
1167+
const data = request.session.get('data')
1168+
1169+
if (!data) {
1170+
reply.code(404).send()
1171+
return
1172+
}
1173+
reply.send(data)
1174+
})
1175+
1176+
fastify.inject({
1177+
method: 'POST',
1178+
url: '/',
1179+
payload: {
1180+
some: 'data'
1181+
}
1182+
}, (error, response) => {
1183+
t.error(error)
1184+
t.equal(response.statusCode, 200)
1185+
t.ok(response.headers['set-cookie'])
1186+
const { expires, path } = response.cookies[0]
1187+
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
1188+
t.equal(path, '/')
1189+
1190+
fastify.inject({
1191+
method: 'GET',
1192+
url: '/',
1193+
headers: {
1194+
cookie: response.headers['set-cookie']
1195+
}
1196+
}, (error, response) => {
1197+
t.error(error)
1198+
t.equal(response.statusCode, 200)
1199+
t.same(JSON.parse(response.payload), { some: 'data' })
1200+
t.ok(response.headers['set-cookie'])
1201+
const { expires, path } = response.cookies[0]
1202+
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
1203+
t.equal(path, '/')
1204+
})
1205+
})
1206+
})
1207+
1208+
test('Override global options with regenerate', t => {
1209+
t.plan(11)
1210+
1211+
const fastify = Fastify()
1212+
fastify.register(fastifyCookie)
1213+
fastify.register(fastifySession, {
1214+
...DEFAULT_OPTIONS,
1215+
cookie: {
1216+
secure: false,
1217+
maxAge: 42,
1218+
path: '/'
1219+
}
1220+
})
1221+
1222+
fastify.post('/', (request, reply) => {
1223+
request.session.set('data', request.body)
1224+
request.session.options({ maxAge: 1000 * 60 * 60 }) // maxAge updated to 1 hour
1225+
1226+
reply.send('hello world')
1227+
})
1228+
1229+
t.teardown(fastify.close.bind(fastify))
1230+
1231+
fastify.get('/', async (request, reply) => {
1232+
const data = request.session.get('data')
1233+
await request.session.regenerate()
1234+
1235+
if (!data) {
1236+
reply.code(404).send()
1237+
return
1238+
}
1239+
1240+
reply.send(data)
1241+
})
1242+
1243+
fastify.inject({
1244+
method: 'POST',
1245+
url: '/',
1246+
payload: {
1247+
some: 'data'
1248+
}
1249+
}, (error, response) => {
1250+
t.error(error)
1251+
t.equal(response.statusCode, 200)
1252+
t.ok(response.headers['set-cookie'])
1253+
const { expires, path } = response.cookies[0]
1254+
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
1255+
t.equal(path, '/')
1256+
1257+
fastify.inject({
1258+
method: 'GET',
1259+
url: '/',
1260+
headers: {
1261+
cookie: response.headers['set-cookie']
1262+
}
1263+
}, (error, response) => {
1264+
t.error(error)
1265+
t.equal(response.statusCode, 200)
1266+
t.same(JSON.parse(response.payload), { some: 'data' })
1267+
t.ok(response.headers['set-cookie'])
1268+
const { expires, path } = response.cookies[0]
1269+
t.equal(expires.toUTCString(), new Date(Date.now() + 1000 * 60 * 60).toUTCString())
1270+
t.equal(path, '/')
1271+
})
1272+
})
1273+
})

0 commit comments

Comments
 (0)