mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-10-24 12:13:31 +08:00
refactor(api): sensible default cookie config (#55227)
This commit is contained in:
@@ -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
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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*/)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user