// app/lib/auth-cookies.ts import { NextResponse } from "next/server"; export type TokenBundle = { access_token: string; refresh_token?: string; /** Directus returns seconds-until-expiration */ expires?: number; }; export type PublicUser = { id: string; email: string; username: string; }; export const ACCESS_COOKIE = "ma_access"; export const REFRESH_COOKIE = "ma_refresh"; /** * Mutates `res` in-place to set auth cookies. * Keeps tokens HttpOnly; sets SameSite=Lax; Secure for HTTPS. */ export function setAuthCookies( res: NextResponse, tokens: TokenBundle, _user?: PublicUser ): void { const maxAge = typeof tokens.expires === "number" ? tokens.expires : 60 * 60 * 12; // 12h default if (tokens.access_token) { res.cookies.set(ACCESS_COOKIE, tokens.access_token, { httpOnly: true, sameSite: "lax", secure: true, path: "/", maxAge, }); } if (tokens.refresh_token) { // If Directus doesn’t give a separate TTL, just make it longer than access (fallback 30d) const refreshMaxAge = typeof tokens.expires === "number" ? tokens.expires * 4 : 60 * 60 * 24 * 30; res.cookies.set(REFRESH_COOKIE, tokens.refresh_token, { httpOnly: true, sameSite: "lax", secure: true, path: "/", maxAge: refreshMaxAge, }); } } /** Mutates `res` in-place to clear both auth cookies. */ export function clearAuthCookies(res: NextResponse): void { const opts = { httpOnly: true, sameSite: "lax" as const, secure: true, path: "/", maxAge: 0, // expire immediately }; res.cookies.set(ACCESS_COOKIE, "", opts); res.cookies.set(REFRESH_COOKIE, "", opts); }