diff --git a/index.js b/index.js index a381db7..f3741f7 100644 --- a/index.js +++ b/index.js @@ -67,6 +67,29 @@ function fastifyCookieClearCookie (reply, name, options) { return fastifyCookieSetCookie(reply, name, '', opts) } +function fastifyCookieGetCookie (reply, name) { + parseCookies(reply.server, reply.request, reply) + + for (const c of reply[kReplySetCookies].values()) { + if (c.name === name) { + return Object.assign({ value: c.value }, c.opts) + } + } + + return undefined +} + +function fastifyCookieGetCookies (reply) { + parseCookies(reply.server, reply.request, reply) + + const result = {} + for (const c of reply[kReplySetCookies].values()) { + result[c.name] = Object.assign({ value: c.value }, c.opts) + } + + return result +} + function parseCookies (fastify, request, reply) { if (reply[kReplySetCookies]) return @@ -168,6 +191,8 @@ async function plugin (fastify, options) { fastify.decorateReply('cookie', setCookie) fastify.decorateReply('setCookie', setCookie) fastify.decorateReply('clearCookie', clearCookie) + fastify.decorateReply('getCookie', getCookie) + fastify.decorateReply('getCookies', getCookies) if (hook) { fastify.addHook(hook, onReqHandlerWrapper(fastify, hook)) @@ -200,6 +225,14 @@ async function plugin (fastify, options) { const opts = Object.assign({}, options.parseOptions, cookieOptions) return fastifyCookieClearCookie(this, name, opts) } + + function getCookie (name) { + return fastifyCookieGetCookie(this, name) + } + + function getCookies () { + return fastifyCookieGetCookies(this) + } } function getHook (hook = 'onRequest') { diff --git a/test/cookie.test.js b/test/cookie.test.js index 50aba33..1a4fb0b 100644 --- a/test/cookie.test.js +++ b/test/cookie.test.js @@ -1333,3 +1333,34 @@ test('do not crash if the onRequest hook is not run', async (t) => { t.assert.strictEqual(res.statusCode, 200) t.assert.deepStrictEqual(JSON.parse(res.body), { hello: 'world' }) }) + +test('reply.getCookie and reply.getCookies return cookies set on reply', async (t) => { + t.plan(7) + + const fastify = Fastify() + fastify.register(plugin) + + fastify.get('/test', (req, reply) => { + t.assert.strictEqual(reply.getCookie('foo'), undefined) + t.assert.deepStrictEqual(reply.getCookies(), {}) + + reply.setCookie('foo', 'bar', { path: '/test', httpOnly: true }) + reply.setCookie('baz', 'qux', { secure: true }) + + const foo = reply.getCookie('foo') + t.assert.deepStrictEqual(foo, { value: 'bar', sameSite: 'lax', path: '/test', httpOnly: true }) + + const cookies = reply.getCookies() + t.assert.deepStrictEqual(cookies.foo, { value: 'bar', sameSite: 'lax', path: '/test', httpOnly: true }) + t.assert.deepStrictEqual(cookies.baz, { value: 'qux', sameSite: 'lax', secure: true }) + + reply.send('done') + }) + + const res = await fastify.inject({ + method: 'GET', + url: '/test' + }) + t.assert.strictEqual(res.statusCode, 200) + t.assert.strictEqual(res.body, 'done') +}) diff --git a/types/index.d.ts b/types/index.d.ts index 6a10987..14d2226 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -86,6 +86,17 @@ declare module 'fastify' { options?: fastifyCookie.CookieSerializeOptions ): this; + /** + * Get response cookie + * @param name Cookie name + */ + getCookie(name: string): ({ value: string } & fastifyCookie.CookieSerializeOptions) | undefined; + + /** + * Get all response cookies + */ + getCookies(): { [key: string]: { value: string } & fastifyCookie.CookieSerializeOptions }; + /** * Unsigns the specified cookie using the secret provided. * @param value Cookie value diff --git a/types/index.tst.ts b/types/index.tst.ts index aad6adb..e70f0f9 100644 --- a/types/index.tst.ts +++ b/types/index.tst.ts @@ -69,6 +69,13 @@ server.after((_err) => { .clearCookie('foo') .send({ hello: 'world' }) ).type.toBe() + + expect(reply.getCookie('test')).type.toBe< + ({ value: string } & fastifyCookieStar.CookieSerializeOptions) | undefined + >() + expect(reply.getCookies()).type.toBe<{ + [key: string]: { value: string } & fastifyCookieStar.CookieSerializeOptions; + }>() }) expect(server.signCookie).type.toBe<(value: string) => string>()