@fastify/cookie 6.0.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.
@@ -0,0 +1,191 @@
1
+ import fastify, { FastifyInstance, FastifyPluginCallback, FastifyReply, setCookieWrapper } from 'fastify';
2
+ import { Server } from 'http';
3
+ import { expectType } from 'tsd';
4
+ import * as fastifyCookieStar from '..';
5
+ import fastifyCookieDefault, {
6
+ CookieSerializeOptions,
7
+ fastifyCookie as fastifyCookieNamed
8
+ } from '..';
9
+ import cookie, { FastifyCookieOptions } from '../plugin';
10
+
11
+ import fastifyCookieCjsImport = require('..');
12
+ const fastifyCookieCjs = require('..');
13
+
14
+ const app: FastifyInstance = fastify();
15
+ app.register(fastifyCookieNamed);
16
+ app.register(fastifyCookieDefault);
17
+ app.register(fastifyCookieCjs);
18
+ app.register(fastifyCookieCjsImport.default);
19
+ app.register(fastifyCookieCjsImport.fastifyCookie);
20
+ app.register(fastifyCookieStar.default);
21
+ app.register(fastifyCookieStar.fastifyCookie);
22
+
23
+ expectType<FastifyPluginCallback<FastifyCookieOptions, Server>>(fastifyCookieNamed);
24
+ expectType<FastifyPluginCallback<FastifyCookieOptions, Server>>(fastifyCookieDefault);
25
+ expectType<FastifyPluginCallback<FastifyCookieOptions, Server>>(fastifyCookieCjsImport.default);
26
+ expectType<FastifyPluginCallback<FastifyCookieOptions, Server>>(fastifyCookieCjsImport.fastifyCookie);
27
+ expectType<FastifyPluginCallback<FastifyCookieOptions, Server>>(fastifyCookieStar.default);
28
+ expectType<FastifyPluginCallback<FastifyCookieOptions, Server>>(
29
+ fastifyCookieStar.fastifyCookie
30
+ );
31
+ expectType<any>(fastifyCookieCjs);
32
+
33
+ const server = fastify();
34
+
35
+ server.register(cookie);
36
+
37
+ server.after((_err) => {
38
+ expectType<{ [key: string]: string }>(
39
+ // See https://github.com/fastify/fastify-cookie#manual-cookie-parsing
40
+ server.parseCookie('sessionId=aYb4uTIhdBXC')
41
+ );
42
+
43
+ server.get('/', (request, reply) => {
44
+ const test = request.cookies.test;
45
+
46
+ expectType<setCookieWrapper>(reply.cookie);
47
+ expectType<setCookieWrapper>(reply.setCookie);
48
+
49
+ expectType<FastifyReply>(
50
+ reply
51
+ .setCookie('test', test, { domain: 'example.com', path: '/' })
52
+ .clearCookie('foo')
53
+ .send({ hello: 'world' })
54
+ );
55
+ });
56
+ });
57
+
58
+ const serverWithHttp2 = fastify({ http2: true });
59
+
60
+ serverWithHttp2.register(cookie);
61
+
62
+ serverWithHttp2.after(() => {
63
+ serverWithHttp2.get('/', (request, reply) => {
64
+ const test = request.cookies.test;
65
+ reply
66
+ .setCookie('test', test, { domain: 'example.com', path: '/' })
67
+ .clearCookie('foo')
68
+ .send({ hello: 'world' });
69
+ });
70
+ });
71
+
72
+ const testSamesiteOptionsApp = fastify();
73
+
74
+ testSamesiteOptionsApp.register(cookie);
75
+ testSamesiteOptionsApp.after(() => {
76
+ server.get('/test-samesite-option-true', (request, reply) => {
77
+ const test = request.cookies.test;
78
+ reply.setCookie('test', test, { sameSite: true }).send({ hello: 'world' });
79
+ });
80
+ server.get('/test-samesite-option-false', (request, reply) => {
81
+ const test = request.cookies.test;
82
+ reply.setCookie('test', test, { sameSite: false }).send({ hello: 'world' });
83
+ });
84
+ server.get('/test-samesite-option-lax', (request, reply) => {
85
+ const test = request.cookies.test;
86
+ reply.setCookie('test', test, { sameSite: 'lax' }).send({ hello: 'world' });
87
+ });
88
+ server.get('/test-samesite-option-strict', (request, reply) => {
89
+ const test = request.cookies.test;
90
+ reply
91
+ .setCookie('test', test, { sameSite: 'strict' })
92
+ .send({ hello: 'world' });
93
+ });
94
+ server.get('/test-samesite-option-none', (request, reply) => {
95
+ const test = request.cookies.test;
96
+ reply
97
+ .setCookie('test', test, { sameSite: 'none' })
98
+ .send({ hello: 'world' });
99
+ });
100
+ });
101
+
102
+ const appWithImplicitHttpSigned = fastify();
103
+
104
+ appWithImplicitHttpSigned.register(cookie, {
105
+ secret: 'testsecret',
106
+ });
107
+ appWithImplicitHttpSigned.after(() => {
108
+ server.get('/', (request, reply) => {
109
+ appWithImplicitHttpSigned.unsignCookie(request.cookies.test);
110
+ appWithImplicitHttpSigned.unsignCookie('test');
111
+
112
+ reply.unsignCookie(request.cookies.test);
113
+ reply.unsignCookie('test');
114
+
115
+ request.unsignCookie(request.cookies.anotherTest);
116
+ request.unsignCookie('anotherTest');
117
+
118
+ reply.send({ hello: 'world' });
119
+ });
120
+ });
121
+
122
+ const appWithRotationSecret = fastify();
123
+
124
+ appWithRotationSecret.register(cookie, {
125
+ secret: ['testsecret'],
126
+ });
127
+ appWithRotationSecret.after(() => {
128
+ server.get('/', (request, reply) => {
129
+ reply.unsignCookie(request.cookies.test);
130
+ const { valid, renew, value } = reply.unsignCookie('test');
131
+
132
+ expectType<boolean>(valid);
133
+ expectType<boolean>(renew);
134
+ expectType<string | null>(value);
135
+
136
+ reply.send({ hello: 'world' });
137
+ });
138
+ });
139
+
140
+ const appWithParseOptions = fastify();
141
+
142
+ const parseOptions: fastifyCookieStar.CookieSerializeOptions = {
143
+ domain: 'example.com',
144
+ encode: (value: string) => value,
145
+ expires: new Date(),
146
+ httpOnly: true,
147
+ maxAge: 3600,
148
+ path: '/',
149
+ sameSite: 'lax',
150
+ secure: true,
151
+ signed: true,
152
+ };
153
+ expectType<fastifyCookieStar.CookieSerializeOptions>(parseOptions);
154
+
155
+ appWithParseOptions.register(cookie, {
156
+ secret: 'testsecret',
157
+ parseOptions,
158
+ });
159
+ appWithParseOptions.after(() => {
160
+ server.get('/', (request, reply) => {
161
+ const { valid, renew, value } = reply.unsignCookie(request.cookies.test);
162
+
163
+ expectType<boolean>(valid);
164
+ expectType<boolean>(renew);
165
+ expectType<string | null>(value);
166
+ });
167
+ });
168
+
169
+ const appWithCustomSigner = fastify()
170
+
171
+ appWithCustomSigner.register(cookie, {
172
+ secret: {
173
+ sign: (x) => x + '.signed',
174
+ unsign: (x) => {
175
+ if (x.endsWith('.signed')) { return { renew: false, valid: true, value: x.slice(0, -7) } }
176
+ return { renew: false, valid: false, value: null }
177
+ }
178
+ }
179
+ })
180
+ appWithCustomSigner.after(() => {
181
+ server.get('/', (request, reply) => {
182
+ reply.unsignCookie(request.cookies.test)
183
+ const { valid, renew, value } = reply.unsignCookie('test')
184
+
185
+ expectType<boolean>(valid)
186
+ expectType<boolean>(renew)
187
+ expectType<string | null>(value)
188
+
189
+ reply.send({ hello: 'world' })
190
+ })
191
+ })
@@ -0,0 +1,79 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('tap')
4
+ const sinon = require('sinon')
5
+ const cookieSignature = require('cookie-signature')
6
+ const signerFactory = require('../signer')
7
+
8
+ test('default', (t) => {
9
+ t.plan(2)
10
+
11
+ const secret = 'my-secret'
12
+ const signer = signerFactory(secret)
13
+
14
+ t.test('signer.sign', (t) => {
15
+ t.plan(1)
16
+
17
+ const input = 'some-value'
18
+ const result = signer.sign(input)
19
+
20
+ t.equal(result, cookieSignature.sign(input, secret))
21
+ })
22
+
23
+ t.test('signer.unsign', (t) => {
24
+ t.plan(3)
25
+
26
+ const input = cookieSignature.sign('some-value', secret)
27
+ const result = signer.unsign(input)
28
+
29
+ t.equal(result.valid, true)
30
+ t.equal(result.renew, false)
31
+ t.equal(result.value, 'some-value')
32
+ })
33
+ })
34
+
35
+ test('key rotation', (t) => {
36
+ t.plan(3)
37
+ const secret1 = 'my-secret-1'
38
+ const secret2 = 'my-secret-2'
39
+ const secret3 = 'my-secret-3'
40
+ const signer = signerFactory([secret1, secret2, secret3])
41
+ const unsignSpy = sinon.spy(cookieSignature, 'unsign')
42
+
43
+ t.beforeEach(() => {
44
+ unsignSpy.resetHistory()
45
+ })
46
+
47
+ t.test('signer.sign always signs using first key', (t) => {
48
+ t.plan(1)
49
+
50
+ const input = 'some-value'
51
+ const result = signer.sign(input)
52
+
53
+ t.equal(result, cookieSignature.sign(input, secret1))
54
+ })
55
+
56
+ t.test('signer.unsign tries to decode using all keys till it finds', (t) => {
57
+ t.plan(4)
58
+
59
+ const input = cookieSignature.sign('some-value', secret2)
60
+ const result = signer.unsign(input)
61
+
62
+ t.equal(result.valid, true)
63
+ t.equal(result.renew, true)
64
+ t.equal(result.value, 'some-value')
65
+ t.equal(unsignSpy.callCount, 2) // should have returned early when the right key was found
66
+ })
67
+
68
+ t.test('signer.unsign failure response', (t) => {
69
+ t.plan(4)
70
+
71
+ const input = cookieSignature.sign('some-value', 'invalid-secret')
72
+ const result = signer.unsign(input)
73
+
74
+ t.equal(result.valid, false)
75
+ t.equal(result.renew, false)
76
+ t.equal(result.value, null)
77
+ t.equal(unsignSpy.callCount, 3) // should have tried all 3
78
+ })
79
+ })