@fastify/cookie 9.0.0 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/cookie",
3
- "version": "9.0.0",
3
+ "version": "9.0.2",
4
4
  "description": "Plugin for fastify to add support for cookies",
5
5
  "main": "plugin.js",
6
6
  "types": "types/plugin.d.ts",
package/plugin.js CHANGED
@@ -6,6 +6,7 @@ const cookie = require('cookie')
6
6
  const { Signer, sign, unsign } = require('./signer')
7
7
 
8
8
  const kReplySetCookies = Symbol('fastify.reply.setCookies')
9
+ const kReplySetCookiesHookRan = Symbol('fastify.reply.setCookiesHookRan')
9
10
 
10
11
  function fastifyCookieSetCookie (reply, name, value, options) {
11
12
  const opts = Object.assign({}, options)
@@ -29,6 +30,10 @@ function fastifyCookieSetCookie (reply, name, value, options) {
29
30
 
30
31
  reply[kReplySetCookies].set(`${name};${opts.domain};${opts.path || '/'}`, { name, value, opts })
31
32
 
33
+ if (reply[kReplySetCookiesHookRan]) {
34
+ setCookies(reply)
35
+ }
36
+
32
37
  return reply
33
38
  }
34
39
 
@@ -63,33 +68,43 @@ function onReqHandlerWrapper (fastify, hook) {
63
68
  }
64
69
  }
65
70
 
66
- function fastifyCookieOnSendHandler (fastifyReq, fastifyRes, payload, done) {
67
- if (fastifyRes[kReplySetCookies].size) {
68
- let setCookie = fastifyRes.getHeader('Set-Cookie')
69
-
70
- /* istanbul ignore else */
71
- if (setCookie === undefined) {
72
- if (fastifyRes[kReplySetCookies].size === 1) {
73
- for (const c of fastifyRes[kReplySetCookies].values()) {
74
- fastifyRes.header('Set-Cookie', cookie.serialize(c.name, c.value, c.opts))
75
- }
71
+ function setCookies (reply) {
72
+ let setCookie = reply.getHeader('Set-Cookie')
73
+ const setCookieIsUndefined = setCookie === undefined
76
74
 
77
- return done()
75
+ /* istanbul ignore else */
76
+ if (setCookieIsUndefined) {
77
+ if (reply[kReplySetCookies].size === 1) {
78
+ for (const c of reply[kReplySetCookies].values()) {
79
+ reply.header('Set-Cookie', cookie.serialize(c.name, c.value, c.opts))
78
80
  }
79
81
 
80
- setCookie = []
81
- } else if (typeof setCookie === 'string') {
82
- setCookie = [setCookie]
83
- }
82
+ reply[kReplySetCookies].clear()
84
83
 
85
- for (const c of fastifyRes[kReplySetCookies].values()) {
86
- setCookie.push(cookie.serialize(c.name, c.value, c.opts))
84
+ return
87
85
  }
88
86
 
89
- fastifyRes.removeHeader('Set-Cookie')
90
- fastifyRes.header('Set-Cookie', setCookie)
87
+ setCookie = []
88
+ } else if (typeof setCookie === 'string') {
89
+ setCookie = [setCookie]
90
+ }
91
+
92
+ for (const c of reply[kReplySetCookies].values()) {
93
+ setCookie.push(cookie.serialize(c.name, c.value, c.opts))
91
94
  }
92
95
 
96
+ if (!setCookieIsUndefined) reply.removeHeader('Set-Cookie')
97
+ reply.header('Set-Cookie', setCookie)
98
+ reply[kReplySetCookies].clear()
99
+ }
100
+
101
+ function fastifyCookieOnSendHandler (fastifyReq, fastifyRes, payload, done) {
102
+ if (fastifyRes[kReplySetCookies].size) {
103
+ setCookies(fastifyRes)
104
+ }
105
+
106
+ fastifyRes[kReplySetCookiesHookRan] = true
107
+
93
108
  done()
94
109
  }
95
110
 
@@ -130,6 +145,7 @@ function plugin (fastify, options, next) {
130
145
 
131
146
  fastify.decorateRequest('cookies', null)
132
147
  fastify.decorateReply(kReplySetCookies, null)
148
+ fastify.decorateReply(kReplySetCookiesHookRan, false)
133
149
 
134
150
  fastify.decorateReply('cookie', setCookie)
135
151
  fastify.decorateReply('setCookie', setCookie)
package/signer.js CHANGED
@@ -24,7 +24,8 @@ function Signer (secrets, algorithm = 'sha256') {
24
24
  }
25
25
 
26
26
  function validateSecrets (secrets) {
27
- for (const secret of secrets) {
27
+ for (let i = 0; i < secrets.length; ++i) {
28
+ const secret = secrets[i]
28
29
  if (typeof secret !== 'string' && Buffer.isBuffer(secret) === false) {
29
30
  throw new TypeError('Secret key must be a string or Buffer.')
30
31
  }
@@ -59,7 +60,8 @@ function _unsign (signedValue, secrets, algorithm) {
59
60
  const value = signedValue.slice(0, signedValue.lastIndexOf('.'))
60
61
  const actual = Buffer.from(signedValue.slice(signedValue.lastIndexOf('.') + 1))
61
62
 
62
- for (const secret of secrets) {
63
+ for (let i = 0; i < secrets.length; ++i) {
64
+ const secret = secrets[i]
63
65
  const expected = Buffer.from(crypto
64
66
  .createHmac(algorithm, secret)
65
67
  .update(value)
@@ -1156,3 +1156,73 @@ test('should update a cookie value when setCookie is called multiple times (non-
1156
1156
  t.ok(new Date(cookies[1].expires) < new Date())
1157
1157
  })
1158
1158
  })
1159
+
1160
+ test('cookies get set correctly if set inside onSend', (t) => {
1161
+ t.plan(7)
1162
+ const fastify = Fastify()
1163
+ fastify.register(plugin)
1164
+
1165
+ fastify.addHook('onSend', async (req, reply, payload) => {
1166
+ reply.setCookie('foo', 'foo', { path: '/' })
1167
+ return payload
1168
+ })
1169
+
1170
+ fastify.get('/test1', (req, reply) => {
1171
+ reply
1172
+ .send({ hello: 'world' })
1173
+ })
1174
+
1175
+ fastify.inject({
1176
+ method: 'GET',
1177
+ url: '/test1'
1178
+ }, (err, res) => {
1179
+ t.error(err)
1180
+ t.equal(res.statusCode, 200)
1181
+ t.same(JSON.parse(res.body), { hello: 'world' })
1182
+
1183
+ const cookies = res.cookies
1184
+ t.equal(cookies.length, 1)
1185
+ t.equal(cookies[0].name, 'foo')
1186
+ t.equal(cookies[0].value, 'foo')
1187
+ t.equal(cookies[0].path, '/')
1188
+ })
1189
+ })
1190
+
1191
+ test('cookies get set correctly if set inside multiple onSends', (t) => {
1192
+ t.plan(10)
1193
+ const fastify = Fastify()
1194
+ fastify.register(plugin)
1195
+
1196
+ fastify.addHook('onSend', async (req, reply, payload) => {
1197
+ reply.setCookie('foo', 'foo', { path: '/' })
1198
+ })
1199
+
1200
+ fastify.addHook('onSend', async (req, reply, payload) => {
1201
+ reply.setCookie('foo', 'foos', { path: '/' })
1202
+ return payload
1203
+ })
1204
+
1205
+ fastify.get('/test1', (req, reply) => {
1206
+ reply
1207
+ .send({ hello: 'world' })
1208
+ })
1209
+
1210
+ fastify.inject({
1211
+ method: 'GET',
1212
+ url: '/test1'
1213
+ }, (err, res) => {
1214
+ t.error(err)
1215
+ t.equal(res.statusCode, 200)
1216
+ t.same(JSON.parse(res.body), { hello: 'world' })
1217
+
1218
+ const cookies = res.cookies
1219
+ t.equal(cookies.length, 2)
1220
+ t.equal(cookies[0].name, 'foo')
1221
+ t.equal(cookies[0].value, 'foo')
1222
+ t.equal(cookies[0].path, '/')
1223
+
1224
+ t.equal(cookies[1].name, 'foo')
1225
+ t.equal(cookies[1].value, 'foos')
1226
+ t.equal(cookies[1].path, '/')
1227
+ })
1228
+ })