@fastify/cookie 7.1.0 → 7.2.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 +45 -1
- package/package.json +1 -1
- package/plugin.d.ts +11 -1
- package/plugin.js +14 -0
- package/test/cookie.test.js +20 -0
package/README.md
CHANGED
|
@@ -201,7 +201,7 @@ the provided signer's (or the default signer if no custom implementation is prov
|
|
|
201
201
|
fastify.register(require('@fastify/cookie'), { secret: 'my-secret' })
|
|
202
202
|
|
|
203
203
|
fastify.get('/', (req, rep) => {
|
|
204
|
-
if (fastify.
|
|
204
|
+
if (fastify.unsignCookie(req.cookie.foo).valid === false) {
|
|
205
205
|
rep.send('cookie is invalid')
|
|
206
206
|
return
|
|
207
207
|
}
|
|
@@ -210,6 +210,50 @@ fastify.get('/', (req, rep) => {
|
|
|
210
210
|
})
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
+
### Other cases of manual signing
|
|
214
|
+
|
|
215
|
+
Sometimes the service under test should only accept requests with signed cookies, but it does not generate them itself.
|
|
216
|
+
|
|
217
|
+
**Example:**
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
|
|
221
|
+
test('Request requires signed cookie', async () => {
|
|
222
|
+
const response = await app.inject({
|
|
223
|
+
method: 'GET',
|
|
224
|
+
url: '/',
|
|
225
|
+
headers: {
|
|
226
|
+
cookies : {
|
|
227
|
+
'sid': app.signCookie(sidValue)
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
expect(response.statusCode).toBe(200);
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Manual signing/unsigning with low level utilities
|
|
237
|
+
|
|
238
|
+
with signerFactory
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
const { signerFactory } = require('@fastify/cookie');
|
|
242
|
+
|
|
243
|
+
const signer = signerFactory('secret');
|
|
244
|
+
const signedValue = signer.sign('test');
|
|
245
|
+
const {valid, renew, value } = signer.unsign(signedValue);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
with sign/unsign utilities
|
|
249
|
+
|
|
250
|
+
```js
|
|
251
|
+
const { sign, unsign } = require('@fastify/cookie');
|
|
252
|
+
|
|
253
|
+
const signedValue = sign('test', 'secret');
|
|
254
|
+
const unsignedvalue = unsign(signedValue, 'secret');
|
|
255
|
+
```
|
|
256
|
+
|
|
213
257
|
|
|
214
258
|
## License
|
|
215
259
|
|
package/package.json
CHANGED
package/plugin.d.ts
CHANGED
|
@@ -21,6 +21,12 @@ declare module 'fastify' {
|
|
|
21
21
|
parseCookie(cookieHeader: string): {
|
|
22
22
|
[key: string]: string;
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Manual cookie signing method
|
|
26
|
+
* @docs https://github.com/fastify/fastify-cookie#manual-cookie-parsing
|
|
27
|
+
* @param value cookie value
|
|
28
|
+
*/
|
|
29
|
+
signCookie(value: string): string;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
interface FastifyRequest {
|
|
@@ -106,6 +112,10 @@ interface Signer {
|
|
|
106
112
|
};
|
|
107
113
|
}
|
|
108
114
|
|
|
115
|
+
declare const signerFactory: Signer;
|
|
116
|
+
declare const sign: (value: string, secret: string) => string;
|
|
117
|
+
declare const unsign: (input: string, secret: string) => string | false;
|
|
118
|
+
|
|
109
119
|
export interface FastifyCookieOptions {
|
|
110
120
|
secret?: string | string[] | Signer;
|
|
111
121
|
parseOptions?: CookieSerializeOptions;
|
|
@@ -114,4 +124,4 @@ export interface FastifyCookieOptions {
|
|
|
114
124
|
declare const fastifyCookie: FastifyPluginCallback<NonNullable<FastifyCookieOptions>>;
|
|
115
125
|
|
|
116
126
|
export default fastifyCookie;
|
|
117
|
-
export { fastifyCookie };
|
|
127
|
+
export { fastifyCookie, signerFactory, sign, unsign };
|
package/plugin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { sign, unsign } = require('cookie-signature')
|
|
3
4
|
const fp = require('fastify-plugin')
|
|
4
5
|
const cookie = require('cookie')
|
|
5
6
|
|
|
@@ -58,6 +59,7 @@ function plugin (fastify, options, next) {
|
|
|
58
59
|
const signer = typeof secret === 'string' || enableRotation ? signerFactory(secret) : secret
|
|
59
60
|
|
|
60
61
|
fastify.decorate('parseCookie', parseCookie)
|
|
62
|
+
fastify.decorate('signCookie', signCookie)
|
|
61
63
|
fastify.decorate('unsignCookie', unsignCookie)
|
|
62
64
|
|
|
63
65
|
fastify.decorateRequest('cookies', null)
|
|
@@ -76,6 +78,10 @@ function plugin (fastify, options, next) {
|
|
|
76
78
|
return cookie.parse(cookieHeader, options.parseOptions)
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
function signCookie (value) {
|
|
82
|
+
return signer.sign(value)
|
|
83
|
+
}
|
|
84
|
+
|
|
79
85
|
function unsignCookie (value) {
|
|
80
86
|
return signer.unsign(value)
|
|
81
87
|
}
|
|
@@ -108,3 +114,11 @@ const fastifyCookie = fp(plugin, {
|
|
|
108
114
|
fastifyCookie.fastifyCookie = fastifyCookie
|
|
109
115
|
fastifyCookie.default = fastifyCookie
|
|
110
116
|
module.exports = fastifyCookie
|
|
117
|
+
|
|
118
|
+
fastifyCookie.fastifyCookie.signerFactory = signerFactory
|
|
119
|
+
fastifyCookie.fastifyCookie.sign = sign
|
|
120
|
+
fastifyCookie.fastifyCookie.unsign = unsign
|
|
121
|
+
|
|
122
|
+
module.exports.signerFactory = signerFactory
|
|
123
|
+
module.exports.sign = sign
|
|
124
|
+
module.exports.unsign = unsign
|
package/test/cookie.test.js
CHANGED
|
@@ -756,3 +756,23 @@ test('cookies set with plugin options parseOptions field', (t) => {
|
|
|
756
756
|
}
|
|
757
757
|
)
|
|
758
758
|
})
|
|
759
|
+
|
|
760
|
+
test('create signed cookie manually using signCookie decorator', async (t) => {
|
|
761
|
+
const fastify = Fastify()
|
|
762
|
+
|
|
763
|
+
await fastify.register(plugin, { secret: 'secret' })
|
|
764
|
+
|
|
765
|
+
fastify.get('/test1', (req, reply) => {
|
|
766
|
+
reply.send({
|
|
767
|
+
unsigned: req.unsignCookie(req.cookies.foo)
|
|
768
|
+
})
|
|
769
|
+
})
|
|
770
|
+
|
|
771
|
+
const res = await fastify.inject({
|
|
772
|
+
method: 'GET',
|
|
773
|
+
url: '/test1',
|
|
774
|
+
headers: { cookie: `foo=${fastify.signCookie('bar')}` }
|
|
775
|
+
})
|
|
776
|
+
t.equal(res.statusCode, 200)
|
|
777
|
+
t.same(JSON.parse(res.body), { unsigned: { value: 'bar', renew: false, valid: true } })
|
|
778
|
+
})
|