@fastify/cookie 8.0.0 → 8.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 +2 -1
- package/package.json +2 -2
- package/plugin.js +39 -11
- package/signer.js +1 -1
- package/test/cookie.test.js +143 -0
- package/types/plugin.d.ts +3 -0
- package/types/plugin.test-d.ts +14 -3
package/README.md
CHANGED
|
@@ -33,7 +33,8 @@ const fastify = require('fastify')()
|
|
|
33
33
|
|
|
34
34
|
fastify.register(require('@fastify/cookie'), {
|
|
35
35
|
secret: "my-secret", // for cookies signature
|
|
36
|
-
|
|
36
|
+
hook: 'onRequest', // set to false to disable cookie autoparsing or set autoparsing on any of the following hooks: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. default: 'onRequest'
|
|
37
|
+
parseOptions: {} // options for parsing cookies
|
|
37
38
|
})
|
|
38
39
|
|
|
39
40
|
fastify.get('/', (req, reply) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/cookie",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.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
|
|
@@ -50,19 +50,44 @@ function fastifyCookieClearCookie (reply, name, options) {
|
|
|
50
50
|
return fastifyCookieSetCookie(reply, name, '', opts)
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function onReqHandlerWrapper (fastify) {
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
function onReqHandlerWrapper (fastify, hook) {
|
|
54
|
+
return hook === 'preParsing'
|
|
55
|
+
? function fastifyCookieHandler (fastifyReq, fastifyRes, payload, done) {
|
|
56
|
+
fastifyReq.cookies = {} // New container per request. Issue #53
|
|
57
|
+
const cookieHeader = fastifyReq.raw.headers.cookie
|
|
58
|
+
if (cookieHeader) {
|
|
59
|
+
fastifyReq.cookies = fastify.parseCookie(cookieHeader)
|
|
60
|
+
}
|
|
61
|
+
done()
|
|
59
62
|
}
|
|
60
|
-
done
|
|
63
|
+
: function fastifyCookieHandler (fastifyReq, fastifyRes, done) {
|
|
64
|
+
fastifyReq.cookies = {} // New container per request. Issue #53
|
|
65
|
+
const cookieHeader = fastifyReq.raw.headers.cookie
|
|
66
|
+
if (cookieHeader) {
|
|
67
|
+
fastifyReq.cookies = fastify.parseCookie(cookieHeader)
|
|
68
|
+
}
|
|
69
|
+
done()
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getHook (hook = 'onRequest') {
|
|
74
|
+
const hooks = {
|
|
75
|
+
onRequest: 'onRequest',
|
|
76
|
+
preParsing: 'preParsing',
|
|
77
|
+
preValidation: 'preValidation',
|
|
78
|
+
preHandler: 'preHandler',
|
|
79
|
+
[false]: false
|
|
61
80
|
}
|
|
81
|
+
|
|
82
|
+
return hooks[hook]
|
|
62
83
|
}
|
|
63
84
|
|
|
64
85
|
function plugin (fastify, options, next) {
|
|
65
86
|
const secret = options.secret
|
|
87
|
+
const hook = getHook(options.hook)
|
|
88
|
+
if (hook === undefined) {
|
|
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
|
+
}
|
|
66
91
|
const enableRotation = Array.isArray(secret)
|
|
67
92
|
const algorithm = options.algorithm || 'sha256'
|
|
68
93
|
const signer = typeof secret === 'string' || enableRotation ? new Signer(secret, algorithm) : secret
|
|
@@ -86,7 +111,9 @@ function plugin (fastify, options, next) {
|
|
|
86
111
|
fastify.decorateReply('setCookie', setCookie)
|
|
87
112
|
fastify.decorateReply('clearCookie', clearCookie)
|
|
88
113
|
|
|
89
|
-
|
|
114
|
+
if (hook) {
|
|
115
|
+
fastify.addHook(hook, onReqHandlerWrapper(fastify, hook))
|
|
116
|
+
}
|
|
90
117
|
|
|
91
118
|
next()
|
|
92
119
|
|
|
@@ -108,8 +135,9 @@ function plugin (fastify, options, next) {
|
|
|
108
135
|
return fastifyCookieSetCookie(this, name, value, opts, signer)
|
|
109
136
|
}
|
|
110
137
|
|
|
111
|
-
function clearCookie (name,
|
|
112
|
-
|
|
138
|
+
function clearCookie (name, cookieOptions) {
|
|
139
|
+
const opts = Object.assign({}, options.parseOptions, cookieOptions)
|
|
140
|
+
return fastifyCookieClearCookie(this, name, opts)
|
|
113
141
|
}
|
|
114
142
|
}
|
|
115
143
|
|
package/signer.js
CHANGED
|
@@ -34,7 +34,7 @@ function validateSecrets (secrets) {
|
|
|
34
34
|
function validateAlgorithm (algorithm) {
|
|
35
35
|
// validate that the algorithm is supported by the node runtime
|
|
36
36
|
try {
|
|
37
|
-
crypto.createHmac(algorithm,
|
|
37
|
+
crypto.createHmac(algorithm, crypto.randomBytes(16))
|
|
38
38
|
} catch (e) {
|
|
39
39
|
throw new TypeError(`Algorithm ${algorithm} not supported.`)
|
|
40
40
|
}
|
package/test/cookie.test.js
CHANGED
|
@@ -847,3 +847,146 @@ test('should not decorate fastify, request and reply if no secret was provided',
|
|
|
847
847
|
message: 'req.unsignCookie is not a function'
|
|
848
848
|
})
|
|
849
849
|
})
|
|
850
|
+
|
|
851
|
+
test('dont add auto cookie parsing to onRequest-hook if hook-option is set to false', (t) => {
|
|
852
|
+
t.plan(6)
|
|
853
|
+
const fastify = Fastify()
|
|
854
|
+
fastify.register(plugin, { hook: false })
|
|
855
|
+
|
|
856
|
+
for (const hook of ['preValidation', 'preHandler', 'preParsing']) {
|
|
857
|
+
fastify.addHook(hook, async (req) => {
|
|
858
|
+
t.equal(req.cookies, null)
|
|
859
|
+
})
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
fastify.get('/disable', (req, reply) => {
|
|
863
|
+
t.equal(req.cookies, null)
|
|
864
|
+
reply.send()
|
|
865
|
+
})
|
|
866
|
+
|
|
867
|
+
fastify.inject({
|
|
868
|
+
method: 'GET',
|
|
869
|
+
url: '/disable',
|
|
870
|
+
headers: {
|
|
871
|
+
cookie: 'bar=bar'
|
|
872
|
+
}
|
|
873
|
+
}, (err, res) => {
|
|
874
|
+
t.error(err)
|
|
875
|
+
t.equal(res.statusCode, 200)
|
|
876
|
+
})
|
|
877
|
+
})
|
|
878
|
+
|
|
879
|
+
test('result in an error if hook-option is set to an invalid value', (t) => {
|
|
880
|
+
t.plan(1)
|
|
881
|
+
const fastify = Fastify()
|
|
882
|
+
|
|
883
|
+
t.rejects(
|
|
884
|
+
() => fastify.register(plugin, { hook: true }),
|
|
885
|
+
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'")
|
|
886
|
+
)
|
|
887
|
+
})
|
|
888
|
+
|
|
889
|
+
test('correct working plugin if hook-option to preParsing', (t) => {
|
|
890
|
+
t.plan(5)
|
|
891
|
+
const fastify = Fastify()
|
|
892
|
+
fastify.register(plugin, { hook: 'preParsing' })
|
|
893
|
+
|
|
894
|
+
fastify.addHook('onRequest', async (req) => {
|
|
895
|
+
t.equal(req.cookies, null)
|
|
896
|
+
})
|
|
897
|
+
|
|
898
|
+
fastify.addHook('preValidation', async (req) => {
|
|
899
|
+
t.equal(req.cookies.bar, 'bar')
|
|
900
|
+
})
|
|
901
|
+
|
|
902
|
+
fastify.get('/preparsing', (req, reply) => {
|
|
903
|
+
t.equal(req.cookies.bar, 'bar')
|
|
904
|
+
reply.send()
|
|
905
|
+
})
|
|
906
|
+
|
|
907
|
+
fastify.inject({
|
|
908
|
+
method: 'GET',
|
|
909
|
+
url: '/preparsing',
|
|
910
|
+
headers: {
|
|
911
|
+
cookie: 'bar=bar'
|
|
912
|
+
}
|
|
913
|
+
}, (err, res) => {
|
|
914
|
+
t.error(err)
|
|
915
|
+
t.equal(res.statusCode, 200)
|
|
916
|
+
})
|
|
917
|
+
})
|
|
918
|
+
|
|
919
|
+
test('if cookies are not set, then the handler creates an empty req.cookies object', (t) => {
|
|
920
|
+
t.plan(5)
|
|
921
|
+
const fastify = Fastify()
|
|
922
|
+
fastify.register(plugin, { hook: 'preParsing' })
|
|
923
|
+
|
|
924
|
+
fastify.addHook('onRequest', async (req) => {
|
|
925
|
+
t.equal(req.cookies, null)
|
|
926
|
+
})
|
|
927
|
+
|
|
928
|
+
fastify.addHook('preValidation', async (req) => {
|
|
929
|
+
t.ok(req.cookies)
|
|
930
|
+
})
|
|
931
|
+
|
|
932
|
+
fastify.get('/preparsing', (req, reply) => {
|
|
933
|
+
t.ok(req.cookies)
|
|
934
|
+
reply.send()
|
|
935
|
+
})
|
|
936
|
+
|
|
937
|
+
fastify.inject({
|
|
938
|
+
method: 'GET',
|
|
939
|
+
url: '/preparsing'
|
|
940
|
+
}, (err, res) => {
|
|
941
|
+
t.error(err)
|
|
942
|
+
t.equal(res.statusCode, 200)
|
|
943
|
+
})
|
|
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/types/plugin.d.ts
CHANGED
|
@@ -125,8 +125,11 @@ declare namespace fastifyCookie {
|
|
|
125
125
|
signed?: boolean;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
type HookType = 'onRequest' | 'preParsing' | 'preValidation' | 'preHandler' | 'preSerialization';
|
|
129
|
+
|
|
128
130
|
export interface FastifyCookieOptions {
|
|
129
131
|
secret?: string | string[] | Signer;
|
|
132
|
+
hook?: HookType | false;
|
|
130
133
|
parseOptions?: fastifyCookie.CookieSerializeOptions;
|
|
131
134
|
}
|
|
132
135
|
|
package/types/plugin.test-d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import cookie from '..';
|
|
2
|
-
import { expectType } from 'tsd';
|
|
2
|
+
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,
|
|
6
|
+
import fastify, { FastifyInstance, FastifyReply, setCookieWrapper } from 'fastify';
|
|
7
7
|
|
|
8
8
|
const fastifyCookieCjs = require('..');
|
|
9
9
|
|
|
@@ -213,4 +213,15 @@ new fastifyCookieStar.Signer('secretString')
|
|
|
213
213
|
new fastifyCookieStar.Signer(['secretStringInArray'])
|
|
214
214
|
const signer = new fastifyCookieStar.Signer(['secretStringInArray'], 'sha256')
|
|
215
215
|
signer.sign('Lorem Ipsum')
|
|
216
|
-
signer.unsign('Lorem Ipsum')
|
|
216
|
+
signer.unsign('Lorem Ipsum')
|
|
217
|
+
|
|
218
|
+
const appWithHook: FastifyInstance = fastify();
|
|
219
|
+
|
|
220
|
+
appWithHook.register(cookie, { hook: false });
|
|
221
|
+
appWithHook.register(cookie, { hook: 'onRequest' });
|
|
222
|
+
appWithHook.register(cookie, { hook: 'preHandler' });
|
|
223
|
+
appWithHook.register(cookie, { hook: 'preParsing' });
|
|
224
|
+
appWithHook.register(cookie, { hook: 'preSerialization' });
|
|
225
|
+
appWithHook.register(cookie, { hook: 'preValidation' });
|
|
226
|
+
expectError(appWithHook.register(cookie, { hook: true }));
|
|
227
|
+
expectError(appWithHook.register(cookie, { hook: 'false' }));
|