@fastify/cookie 8.1.0 → 8.3.0
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/README.md +2 -2
- package/package.json +2 -2
- package/plugin.js +6 -5
- package/signer.js +2 -2
- package/test/cookie.test.js +48 -0
- package/test/signer.test.js +10 -6
- package/types/plugin.d.ts +6 -6
- package/types/plugin.test-d.ts +3 -2
package/README.md
CHANGED
|
@@ -72,8 +72,8 @@ app.register(cookie, {
|
|
|
72
72
|
|
|
73
73
|
## Options
|
|
74
74
|
|
|
75
|
-
- `secret` (`String` | `Array` | `Object`):
|
|
76
|
-
- A `String` can be passed to use as secret to sign the cookie using [`cookie-signature`](http://npm.im/cookie-signature).
|
|
75
|
+
- `secret` (`String` | `Array` | `Buffer` | `Object`):
|
|
76
|
+
- A `String` or `Buffer` can be passed to use as secret to sign the cookie using [`cookie-signature`](http://npm.im/cookie-signature).
|
|
77
77
|
- An `Array` can be passed if key rotation is desired. Read more about it in [Rotating signing secret](#rotating-secret).
|
|
78
78
|
- More sophisticated cookie signing mechanisms can be implemented by supplying an `Object`. Read more about it in [Custom cookie signer](#custom-cookie-signer).
|
|
79
79
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/cookie",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"description": "Plugin for fastify to add support for cookies",
|
|
5
5
|
"main": "plugin.js",
|
|
6
6
|
"types": "types/plugin.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"snazzy": "^9.0.0",
|
|
48
48
|
"standard": "^17.0.0",
|
|
49
49
|
"tap": "^16.0.0",
|
|
50
|
-
"tsd": "^0.
|
|
50
|
+
"tsd": "^0.24.1"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"cookie": "^0.5.0",
|
package/plugin.js
CHANGED
|
@@ -42,7 +42,7 @@ function fastifyCookieSetCookie (reply, name, value, options, signer) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function fastifyCookieClearCookie (reply, name, options) {
|
|
45
|
-
const opts = Object.assign({ path: '/' }, options
|
|
45
|
+
const opts = Object.assign({ path: '/' }, options, {
|
|
46
46
|
expires: new Date(1),
|
|
47
47
|
signed: undefined,
|
|
48
48
|
maxAge: undefined
|
|
@@ -88,9 +88,9 @@ function plugin (fastify, options, next) {
|
|
|
88
88
|
if (hook === undefined) {
|
|
89
89
|
return next(new Error('@fastify/cookie: Invalid value provided for the hook-option. You can set the hook-option only to false, \'onRequest\' , \'preParsing\' , \'preValidation\' or \'preHandler\''))
|
|
90
90
|
}
|
|
91
|
-
const
|
|
91
|
+
const isSigner = !secret || (typeof secret.sign === 'function' && typeof secret.unsign === 'function')
|
|
92
92
|
const algorithm = options.algorithm || 'sha256'
|
|
93
|
-
const signer =
|
|
93
|
+
const signer = isSigner ? secret : new Signer(secret, algorithm)
|
|
94
94
|
|
|
95
95
|
fastify.decorate('parseCookie', parseCookie)
|
|
96
96
|
|
|
@@ -135,8 +135,9 @@ function plugin (fastify, options, next) {
|
|
|
135
135
|
return fastifyCookieSetCookie(this, name, value, opts, signer)
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
function clearCookie (name,
|
|
139
|
-
|
|
138
|
+
function clearCookie (name, cookieOptions) {
|
|
139
|
+
const opts = Object.assign({}, options.parseOptions, cookieOptions)
|
|
140
|
+
return fastifyCookieClearCookie(this, name, opts)
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
|
package/signer.js
CHANGED
|
@@ -25,8 +25,8 @@ function Signer (secrets, algorithm = 'sha256') {
|
|
|
25
25
|
|
|
26
26
|
function validateSecrets (secrets) {
|
|
27
27
|
for (const secret of secrets) {
|
|
28
|
-
if (typeof secret !== 'string') {
|
|
29
|
-
throw new TypeError('Secret key must be a string.')
|
|
28
|
+
if (typeof secret !== 'string' && Buffer.isBuffer(secret) === false) {
|
|
29
|
+
throw new TypeError('Secret key must be a string or Buffer.')
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
package/test/cookie.test.js
CHANGED
|
@@ -942,3 +942,51 @@ test('if cookies are not set, then the handler creates an empty req.cookies obje
|
|
|
942
942
|
t.equal(res.statusCode, 200)
|
|
943
943
|
})
|
|
944
944
|
})
|
|
945
|
+
|
|
946
|
+
test('clearCookie should include parseOptions', (t) => {
|
|
947
|
+
t.plan(14)
|
|
948
|
+
const fastify = Fastify()
|
|
949
|
+
fastify.register(plugin, {
|
|
950
|
+
parseOptions: {
|
|
951
|
+
path: '/test',
|
|
952
|
+
domain: 'example.com'
|
|
953
|
+
}
|
|
954
|
+
})
|
|
955
|
+
|
|
956
|
+
const cookieOptions = {
|
|
957
|
+
path: '/test',
|
|
958
|
+
maxAge: 36000
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
fastify.get('/test1', (req, reply) => {
|
|
962
|
+
reply
|
|
963
|
+
.setCookie('foo', 'foo', cookieOptions)
|
|
964
|
+
.clearCookie('foo', cookieOptions)
|
|
965
|
+
.send({ hello: 'world' })
|
|
966
|
+
})
|
|
967
|
+
|
|
968
|
+
fastify.inject({
|
|
969
|
+
method: 'GET',
|
|
970
|
+
url: '/test1'
|
|
971
|
+
}, (err, res) => {
|
|
972
|
+
t.error(err)
|
|
973
|
+
t.equal(res.statusCode, 200)
|
|
974
|
+
t.same(JSON.parse(res.body), { hello: 'world' })
|
|
975
|
+
|
|
976
|
+
const cookies = res.cookies
|
|
977
|
+
|
|
978
|
+
t.equal(cookies.length, 2)
|
|
979
|
+
t.equal(cookies[0].name, 'foo')
|
|
980
|
+
t.equal(cookies[0].value, 'foo')
|
|
981
|
+
t.equal(cookies[0].maxAge, 36000)
|
|
982
|
+
t.equal(cookies[0].path, '/test')
|
|
983
|
+
t.equal(cookies[0].domain, 'example.com')
|
|
984
|
+
|
|
985
|
+
t.equal(cookies[1].name, 'foo')
|
|
986
|
+
t.equal(cookies[1].value, '')
|
|
987
|
+
t.equal(cookies[1].path, '/test')
|
|
988
|
+
t.equal(cookies[1].domain, 'example.com')
|
|
989
|
+
|
|
990
|
+
t.ok(new Date(cookies[1].expires) < new Date())
|
|
991
|
+
})
|
|
992
|
+
})
|
package/test/signer.test.js
CHANGED
|
@@ -28,13 +28,15 @@ test('default', t => {
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
t.test('sign', (t) => {
|
|
31
|
-
t.plan(
|
|
31
|
+
t.plan(5)
|
|
32
32
|
|
|
33
33
|
const input = 'some-value'
|
|
34
34
|
const result = signer.sign(input)
|
|
35
35
|
|
|
36
36
|
t.equal(result, sign(input, secret))
|
|
37
37
|
t.equal(result, sign(input, [secret]))
|
|
38
|
+
t.equal(result, sign(input, Buffer.from(secret)))
|
|
39
|
+
t.equal(result, sign(input, [Buffer.from(secret)]))
|
|
38
40
|
|
|
39
41
|
t.throws(() => sign(undefined), 'Cookie value must be provided as a string.')
|
|
40
42
|
})
|
|
@@ -61,7 +63,7 @@ test('default', t => {
|
|
|
61
63
|
t.equal(result.renew, false)
|
|
62
64
|
t.equal(result.value, 'some-value')
|
|
63
65
|
t.same(result, unsign(input, [secret]))
|
|
64
|
-
t.throws(() => unsign(undefined), 'Secret key must be a string.')
|
|
66
|
+
t.throws(() => unsign(undefined), 'Secret key must be a string or Buffer.')
|
|
65
67
|
t.throws(() => unsign(undefined, secret), 'Signed cookie string must be provided.')
|
|
66
68
|
})
|
|
67
69
|
})
|
|
@@ -117,12 +119,14 @@ test('key rotation', (t) => {
|
|
|
117
119
|
test('Signer', t => {
|
|
118
120
|
t.plan(2)
|
|
119
121
|
|
|
120
|
-
t.test('Signer needs a string as secret', (t) => {
|
|
121
|
-
t.plan(
|
|
122
|
-
t.throws(() => Signer(1), 'Secret key must be a string.')
|
|
123
|
-
t.throws(() => Signer(undefined), 'Secret key must be a string.')
|
|
122
|
+
t.test('Signer needs a string or Buffer as secret', (t) => {
|
|
123
|
+
t.plan(6)
|
|
124
|
+
t.throws(() => Signer(1), 'Secret key must be a string or Buffer.')
|
|
125
|
+
t.throws(() => Signer(undefined), 'Secret key must be a string or Buffer.')
|
|
124
126
|
t.doesNotThrow(() => Signer('secret'))
|
|
125
127
|
t.doesNotThrow(() => Signer(['secret']))
|
|
128
|
+
t.doesNotThrow(() => Signer(Buffer.from('deadbeef76543210', 'hex')))
|
|
129
|
+
t.doesNotThrow(() => Signer([Buffer.from('deadbeef76543210', 'hex')]))
|
|
126
130
|
})
|
|
127
131
|
|
|
128
132
|
t.test('Signer handles algorithm properly', (t) => {
|
package/types/plugin.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ declare namespace fastifyCookie {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export class Signer implements SignerBase {
|
|
103
|
-
constructor (secrets: string | Array<string>, algorithm?: string)
|
|
103
|
+
constructor (secrets: string | Array<string> | Buffer | Array<Buffer>, algorithm?: string)
|
|
104
104
|
sign: (value: string) => string;
|
|
105
105
|
unsign: (input: string) => UnsignResult;
|
|
106
106
|
}
|
|
@@ -128,14 +128,14 @@ declare namespace fastifyCookie {
|
|
|
128
128
|
type HookType = 'onRequest' | 'preParsing' | 'preValidation' | 'preHandler' | 'preSerialization';
|
|
129
129
|
|
|
130
130
|
export interface FastifyCookieOptions {
|
|
131
|
-
secret?: string | string[] | Signer;
|
|
131
|
+
secret?: string | string[] | Buffer | Buffer[] | Signer;
|
|
132
132
|
hook?: HookType | false;
|
|
133
133
|
parseOptions?: fastifyCookie.CookieSerializeOptions;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
export type Sign = (value: string, secret: string, algorithm?: string) => string;
|
|
137
|
-
export type Unsign = (input: string, secret: string, algorithm?: string) => UnsignResult;
|
|
138
|
-
export type SignerFactory = (secrets: string |
|
|
136
|
+
export type Sign = (value: string, secret: string | Buffer, algorithm?: string) => string;
|
|
137
|
+
export type Unsign = (input: string, secret: string | Buffer, algorithm?: string) => UnsignResult;
|
|
138
|
+
export type SignerFactory = (secrets: string | string[] | Buffer | Buffer[], algorithm?: string) => SignerBase;
|
|
139
139
|
|
|
140
140
|
export interface UnsignResult {
|
|
141
141
|
valid: boolean;
|
|
@@ -157,7 +157,7 @@ declare namespace fastifyCookie {
|
|
|
157
157
|
export const fastifyCookie: FastifyCookie;
|
|
158
158
|
|
|
159
159
|
export interface FastifyCookieOptions {
|
|
160
|
-
secret?: string | string[] | SignerBase;
|
|
160
|
+
secret?: string | string[] | Buffer | Buffer[] | SignerBase;
|
|
161
161
|
algorithm?: string;
|
|
162
162
|
parseOptions?: CookieSerializeOptions;
|
|
163
163
|
}
|
package/types/plugin.test-d.ts
CHANGED
|
@@ -3,8 +3,7 @@ import { expectError, expectType } from 'tsd';
|
|
|
3
3
|
import * as fastifyCookieStar from '..';
|
|
4
4
|
import fastifyCookieCjsImport = require('..');
|
|
5
5
|
import fastifyCookieDefault, { fastifyCookie as fastifyCookieNamed } from '..';
|
|
6
|
-
import fastify, { FastifyInstance,
|
|
7
|
-
import { Server } from 'http';
|
|
6
|
+
import fastify, { FastifyInstance, FastifyReply, setCookieWrapper } from 'fastify';
|
|
8
7
|
|
|
9
8
|
const fastifyCookieCjs = require('..');
|
|
10
9
|
|
|
@@ -212,6 +211,8 @@ appWithCustomSigner.after(() => {
|
|
|
212
211
|
|
|
213
212
|
new fastifyCookieStar.Signer('secretString')
|
|
214
213
|
new fastifyCookieStar.Signer(['secretStringInArray'])
|
|
214
|
+
new fastifyCookieStar.Signer(Buffer.from('secretString'))
|
|
215
|
+
new fastifyCookieStar.Signer([Buffer.from('secretStringInArray')])
|
|
215
216
|
const signer = new fastifyCookieStar.Signer(['secretStringInArray'], 'sha256')
|
|
216
217
|
signer.sign('Lorem Ipsum')
|
|
217
218
|
signer.unsign('Lorem Ipsum')
|