super-fit-web-app / src / utils / cookies.ts
cookies.ts
Raw
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]);
}