import { NextApiRequest, NextApiResponse } from 'next'; import { serialize } from "cookie"; export const cookieFunctions: any = { saveCookie: saveCookie, deleteCookie: deleteCookie, } type CookieOptions = { path: string; httpOnly: boolean; secure: boolean; sameSite: boolean | "strict" | "lax" | "none" | undefined; maxAge: number; }; //cookie age of 14 days const cookieMaxAge = 60 * 60 * 24 * 14; const cookieOptions: CookieOptions = { path: "/", httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "strict", maxAge: cookieMaxAge, }; //create a function to save a cookie using the req and res objects async function saveCookie (req: NextApiRequest, res: NextApiResponse, session_token: string) { if ("headersSent" in res && res.headersSent === true) { throw new Error( "Cannot save cookie because headers were already sent." ) } if (session_token.length > 4096) { throw new Error( `Session token: Cookie length is too big ${session_token.length}, browsers will refuse it.` ) } const cookieValue = serialize(process.env.SESSION_COOKIE_NAME, session_token, { ...cookieOptions, }); addToCookies(cookieValue, res); } async function deleteCookie (res: NextApiResponse) { const cookieValue = serialize(process.env.SESSION_COOKIE_NAME, "", { ...cookieOptions, maxAge: 0, }) addToCookies(cookieValue, res); } function addToCookies (cookieValue: string, res: NextApiResponse) { //check if there are headers in the res object from the client var _a; if ("headers" in res) { res.setHeader("set-cookie", cookieValue); return; } let existingSetCookie = (_a = res.getHeader("set-cookie")) != null ? _a : []; if (typeof existingSetCookie === "string") { existingSetCookie = [existingSetCookie]; } else if (!Array.isArray(existingSetCookie)) { throw new Error("Invalid existingSetCookie type"); } res.setHeader("set-cookie", [...existingSetCookie, cookieValue]); }