import {FastifyReply, FastifyRequest} from "fastify"; import {RouteGenericInterface} from "fastify/types/route"; import {randomBytes} from "crypto"; export interface XSRFRoute extends RouteGenericInterface { Querystring: { [key in typeof XSRFParameter]: string | string[] | undefined } } export const XSRFCookie = "__Host-XSRF-Cookie"; export const XSRFParameter = "state" as const; export async function generateXSRFCookie(res: FastifyReply): Promise { const newState = randomBytes(30).toString("base64url") res.setCookie(XSRFCookie, newState, { path: "/", sameSite: "strict", httpOnly: true, signed: true, secure: true, }) return newState } export function checkAndClearXSRFCookie(req: FastifyRequest, res: FastifyReply): boolean { const queryState = req.query[XSRFParameter] ?? null const cookieState = req.cookies[XSRFCookie] ?? null res.clearCookie(XSRFCookie) return cookieState !== null && queryState !== null && cookieState === queryState }