@fastify/cookie 9.3.1 → 9.4.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 +8 -0
- package/package.json +3 -3
- package/plugin.js +1 -8
- package/test/cookie.test.js +1 -1
- package/types/plugin.d.ts +13 -8
- package/types/plugin.test-d.ts +24 -12
package/README.md
CHANGED
|
@@ -96,8 +96,16 @@ fastify.get('/', (req, reply) => {
|
|
|
96
96
|
- An `Array` can be passed if key rotation is desired. Read more about it in [Rotating signing secret](#rotating-secret).
|
|
97
97
|
- More sophisticated cookie signing mechanisms can be implemented by supplying an `Object`. Read more about it in [Custom cookie signer](#custom-cookie-signer).
|
|
98
98
|
|
|
99
|
+
- `hook`: the [Fastify Hook](https://fastify.dev/docs/latest/Reference/Lifecycle/#lifecycle) to register the parsing of cookie into. Default: `onRequest`.
|
|
100
|
+
|
|
101
|
+
- `algorithm`: the [algorithm](https://nodejs.org/api/crypto.html#cryptogethashes) to use to sign the cookies. Default: `sha256`.
|
|
102
|
+
|
|
99
103
|
- `parseOptions`: An `Object` to modify the serialization of set cookies.
|
|
100
104
|
|
|
105
|
+
### :warning: Security Considerations :warning:
|
|
106
|
+
|
|
107
|
+
It is recommended to use `sha256` or stronger hashing algorithm as well as a `secret` that is at least 20 bytes long.
|
|
108
|
+
|
|
101
109
|
#### parseOptions
|
|
102
110
|
|
|
103
111
|
##### domain
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/cookie",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0",
|
|
4
4
|
"description": "Plugin for fastify to add support for cookies",
|
|
5
5
|
"main": "plugin.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"@types/node": "^20.1.0",
|
|
45
45
|
"benchmark": "^2.1.4",
|
|
46
46
|
"fastify": "^4.0.0",
|
|
47
|
-
"sinon": "^
|
|
47
|
+
"sinon": "^18.0.0",
|
|
48
48
|
"snazzy": "^9.0.0",
|
|
49
49
|
"standard": "^17.0.0",
|
|
50
50
|
"tap": "^16.0.0",
|
|
51
|
-
"tsd": "^0.
|
|
51
|
+
"tsd": "^0.31.0"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"fastify-plugin": "^4.0.0",
|
package/plugin.js
CHANGED
|
@@ -22,7 +22,7 @@ function fastifyCookieSetCookie (reply, name, value, options) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
if (opts.secure === 'auto') {
|
|
25
|
-
if (
|
|
25
|
+
if (reply.request.protocol === 'https') {
|
|
26
26
|
opts.secure = true
|
|
27
27
|
} else {
|
|
28
28
|
opts.sameSite = 'lax'
|
|
@@ -187,13 +187,6 @@ function getHook (hook = 'onRequest') {
|
|
|
187
187
|
return hooks[hook]
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
function isConnectionSecure (request) {
|
|
191
|
-
return (
|
|
192
|
-
request.raw.socket?.encrypted === true ||
|
|
193
|
-
request.headers['x-forwarded-proto'] === 'https'
|
|
194
|
-
)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
190
|
const fastifyCookie = fp(plugin, {
|
|
198
191
|
fastify: '4.x',
|
|
199
192
|
name: '@fastify/cookie'
|
package/test/cookie.test.js
CHANGED
|
@@ -854,7 +854,7 @@ test('create signed cookie manually using signCookie decorator', async (t) => {
|
|
|
854
854
|
})
|
|
855
855
|
|
|
856
856
|
test('handle secure:auto of cookieOptions', async (t) => {
|
|
857
|
-
const fastify = Fastify()
|
|
857
|
+
const fastify = Fastify({ trustProxy: true })
|
|
858
858
|
|
|
859
859
|
await fastify.register(plugin)
|
|
860
860
|
|
package/types/plugin.d.ts
CHANGED
|
@@ -115,25 +115,26 @@ declare namespace fastifyCookie {
|
|
|
115
115
|
domain?: string;
|
|
116
116
|
/** Specifies a function that will be used to encode a cookie's value. Since value of a cookie has a limited character set (and must be a simple string), this function can be used to encode a value into a string suited for a cookie's value. */
|
|
117
117
|
encode?(val: string): string;
|
|
118
|
-
/** The expiration `date` used for the `Expires` attribute.
|
|
118
|
+
/** The expiration `date` used for the `Expires` attribute. */
|
|
119
119
|
expires?: Date;
|
|
120
|
-
/**
|
|
120
|
+
/** Add the `HttpOnly` attribute. Defaults to `false`. */
|
|
121
121
|
httpOnly?: boolean;
|
|
122
|
-
/** A `number` in seconds that specifies the `
|
|
122
|
+
/** A `number` in seconds that specifies the `Max-Age` attribute. */
|
|
123
123
|
maxAge?: number;
|
|
124
124
|
/** A `boolean` indicating whether the cookie is tied to the top-level site where it's initially set and cannot be accessed from elsewhere. */
|
|
125
125
|
partitioned?: boolean;
|
|
126
|
-
/** The `Path` attribute.
|
|
126
|
+
/** The `Path` attribute. */
|
|
127
127
|
path?: string;
|
|
128
128
|
/** A `boolean` or one of the `SameSite` string attributes. E.g.: `lax`, `none` or `strict`. */
|
|
129
129
|
sameSite?: 'lax' | 'none' | 'strict' | boolean;
|
|
130
130
|
/** One of the `Priority` string attributes (`low`, `medium` or `high`) specifying a retention priority for HTTP cookies that will be respected by user agents during cookie eviction. */
|
|
131
131
|
priority?: 'low' | 'medium' | 'high';
|
|
132
|
-
/**
|
|
132
|
+
/** Add the `Secure` attribute. Defaults to `false`. */
|
|
133
133
|
secure?: boolean;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
export interface CookieSerializeOptions extends Omit<SerializeOptions, 'secure'> {
|
|
137
|
+
/** Add the `Secure` attribute. Value can be set to `"auto"`; in this case the `Secure` attribute will only be added for HTTPS requests. Defaults to `false`. */
|
|
137
138
|
secure?: boolean | 'auto';
|
|
138
139
|
signed?: boolean;
|
|
139
140
|
}
|
|
@@ -154,10 +155,14 @@ declare namespace fastifyCookie {
|
|
|
154
155
|
export type Unsign = (input: string, secret: string | Buffer, algorithm?: string) => UnsignResult;
|
|
155
156
|
export type SignerFactory = (secrets: string | string[] | Buffer | Buffer[], algorithm?: string) => SignerBase;
|
|
156
157
|
|
|
157
|
-
export
|
|
158
|
-
valid:
|
|
158
|
+
export type UnsignResult = {
|
|
159
|
+
valid: true;
|
|
159
160
|
renew: boolean;
|
|
160
|
-
value: string
|
|
161
|
+
value: string;
|
|
162
|
+
} | {
|
|
163
|
+
valid: false;
|
|
164
|
+
renew: false;
|
|
165
|
+
value: null;
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
export const signerFactory: SignerFactory;
|
package/types/plugin.test-d.ts
CHANGED
|
@@ -150,11 +150,15 @@ appWithRotationSecret.register(cookie, {
|
|
|
150
150
|
appWithRotationSecret.after(() => {
|
|
151
151
|
server.get('/', (request, reply) => {
|
|
152
152
|
reply.unsignCookie(request.cookies.test!);
|
|
153
|
-
const
|
|
153
|
+
const unsigned = reply.unsignCookie('test');
|
|
154
154
|
|
|
155
|
-
expectType<boolean>(valid);
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
expectType<boolean>(unsigned.valid);
|
|
156
|
+
if (unsigned.valid) {
|
|
157
|
+
expectType<string>(unsigned.value);
|
|
158
|
+
} else {
|
|
159
|
+
expectType<null>(unsigned.value);
|
|
160
|
+
}
|
|
161
|
+
expectType<boolean>(unsigned.renew);
|
|
158
162
|
|
|
159
163
|
reply.send({ hello: 'world' });
|
|
160
164
|
});
|
|
@@ -182,11 +186,15 @@ appWithParseOptions.register(cookie, {
|
|
|
182
186
|
});
|
|
183
187
|
appWithParseOptions.after(() => {
|
|
184
188
|
server.get('/', (request, reply) => {
|
|
185
|
-
const
|
|
189
|
+
const unsigned = reply.unsignCookie(request.cookies.test!);
|
|
186
190
|
|
|
187
|
-
expectType<boolean>(valid);
|
|
188
|
-
|
|
189
|
-
|
|
191
|
+
expectType<boolean>(unsigned.valid);
|
|
192
|
+
if (unsigned.valid) {
|
|
193
|
+
expectType<string>(unsigned.value);
|
|
194
|
+
} else {
|
|
195
|
+
expectType<null>(unsigned.value);
|
|
196
|
+
}
|
|
197
|
+
expectType<boolean>(unsigned.renew);
|
|
190
198
|
});
|
|
191
199
|
});
|
|
192
200
|
|
|
@@ -204,11 +212,15 @@ appWithCustomSigner.register(cookie, {
|
|
|
204
212
|
appWithCustomSigner.after(() => {
|
|
205
213
|
server.get('/', (request, reply) => {
|
|
206
214
|
reply.unsignCookie(request.cookies.test!)
|
|
207
|
-
const
|
|
215
|
+
const unsigned = reply.unsignCookie('test')
|
|
208
216
|
|
|
209
|
-
expectType<boolean>(valid)
|
|
210
|
-
|
|
211
|
-
|
|
217
|
+
expectType<boolean>(unsigned.valid);
|
|
218
|
+
if (unsigned.valid) {
|
|
219
|
+
expectType<string>(unsigned.value);
|
|
220
|
+
} else {
|
|
221
|
+
expectType<null>(unsigned.value);
|
|
222
|
+
}
|
|
223
|
+
expectType<boolean>(unsigned.renew);
|
|
212
224
|
|
|
213
225
|
reply.send({ hello: 'world' })
|
|
214
226
|
})
|