refactor(api): sensible default cookie config (#55227)

This commit is contained in:
Oliver Eyton-Williams
2024-06-27 08:44:47 +00:00
committed by GitHub
parent 22e74e6406
commit 512547e76c
6 changed files with 65 additions and 20 deletions
+1 -5
View File
@@ -3,7 +3,7 @@ import fp from 'fastify-plugin';
import jwt from 'jsonwebtoken';
import { type user } from '@prisma/client';
import { COOKIE_DOMAIN, JWT_SECRET } from '../utils/env';
import { JWT_SECRET } from '../utils/env';
import { type Token, isExpired } from '../utils/tokens';
import { getRedirectParams } from '../utils/redirection';
@@ -27,12 +27,8 @@ const codeFlowAuth: FastifyPluginCallback = (fastify, _options, done) => {
fastify.decorateReply('setAccessTokenCookie', function (accessToken: Token) {
const signedToken = jwt.sign({ accessToken }, JWT_SECRET);
void this.setCookie('jwt_access_token', signedToken, {
path: '/',
httpOnly: false,
secure: false,
sameSite: 'lax',
domain: COOKIE_DOMAIN,
signed: true,
maxAge: accessToken.ttl
});
});
+32
View File
@@ -4,6 +4,12 @@ import fastifyCookie from '@fastify/cookie';
import { COOKIE_SECRET } from '../utils/env';
import cookies from './cookies';
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
jest.mock('../utils/env', () => ({
...jest.requireActual('../utils/env'),
COOKIE_DOMAIN: 'www.example.com'
}));
describe('cookies', () => {
let fastify: FastifyInstance;
@@ -67,4 +73,30 @@ describe('cookies', () => {
unsigned: { value: null, renew: false, valid: false }
});
});
it('should have reasonable defaults', async () => {
fastify.get('/test', async (req, reply) => {
void reply.setCookie('test', 'value');
return { ok: true };
});
const res = await fastify.inject({
method: 'GET',
url: '/test'
});
// No max-age, so we default to a session cookie.
expect(res.cookies[0]).toStrictEqual({
name: 'test',
// defaults:
domain: 'www.example.com',
httpOnly: true,
path: '/',
sameSite: 'Lax',
secure: true,
// sign by default:
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
value: expect.stringMatching(/s:value\.\w*/)
});
});
});
+11 -1
View File
@@ -2,7 +2,7 @@ import fastifyCookie from '@fastify/cookie';
import { FastifyPluginCallback } from 'fastify';
import fp from 'fastify-plugin';
import { COOKIE_SECRET } from '../utils/env';
import { COOKIE_DOMAIN, COOKIE_SECRET } from '../utils/env';
/**
* Signs a cookie value by prefixing it with "s:" and using the COOKIE_SECRET.
@@ -41,6 +41,16 @@ const cookies: FastifyPluginCallback = (fastify, _options, done) => {
secret: {
sign,
unsign
},
parseOptions: {
domain: COOKIE_DOMAIN,
httpOnly: true,
// Path is necessary to ensure that only one cookie is set and it is valid
// for all routes.
path: '/',
sameSite: 'lax',
secure: true,
signed: true
}
});