@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 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
- parseOptions: {} // options for parsing cookies
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.0.0",
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.22.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 function fastifyCookieOnReqHandler (fastifyReq, fastifyRes, done) {
55
- fastifyReq.cookies = {} // New container per request. Issue #53
56
- const cookieHeader = fastifyReq.raw.headers.cookie
57
- if (cookieHeader) {
58
- fastifyReq.cookies = fastify.parseCookie(cookieHeader)
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
- fastify.addHook('onRequest', onReqHandlerWrapper(fastify))
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, options) {
112
- return fastifyCookieClearCookie(this, name, options)
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, 'dummyHmac')
37
+ crypto.createHmac(algorithm, crypto.randomBytes(16))
38
38
  } catch (e) {
39
39
  throw new TypeError(`Algorithm ${algorithm} not supported.`)
40
40
  }
@@ -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
 
@@ -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, FastifyReply, setCookieWrapper } from 'fastify';
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' }));