diff --git a/app/api/auth/logout/route.ts b/app/api/auth/logout/route.ts index 02543b3c..fdcd8c44 100644 --- a/app/api/auth/logout/route.ts +++ b/app/api/auth/logout/route.ts @@ -1,9 +1,11 @@ -// app/app/api/auth/logout/route.ts +// app/api/auth/logout/route.ts import { NextRequest, NextResponse } from "next/server"; import { clearAuthCookies } from "@/lib/auth-cookies"; +export const runtime = "nodejs"; + export async function POST(_req: NextRequest) { - let res = NextResponse.json({ ok: true }); - res = clearAuthCookies(res); + const res = NextResponse.json({ ok: true }); + clearAuthCookies(res); return res; } diff --git a/lib/auth-cookies.ts b/lib/auth-cookies.ts index 57f09e91..da4f6fb3 100644 --- a/lib/auth-cookies.ts +++ b/lib/auth-cookies.ts @@ -14,6 +14,9 @@ export type PublicUser = { 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. @@ -23,11 +26,11 @@ export function setAuthCookies( tokens: TokenBundle, _user?: PublicUser ): void { - const maxAge = typeof tokens.expires === "number" ? tokens.expires : 60 * 60 * 12; // 12h default + const maxAge = + typeof tokens.expires === "number" ? tokens.expires : 60 * 60 * 12; // 12h default - // Access token if (tokens.access_token) { - res.cookies.set("ma_access", tokens.access_token, { + res.cookies.set(ACCESS_COOKIE, tokens.access_token, { httpOnly: true, sameSite: "lax", secure: true, @@ -36,13 +39,12 @@ export function setAuthCookies( }); } - // Refresh token (if present) if (tokens.refresh_token) { - // Give it a longer lifetime (fallback 30 days) if Directus didn’t specify one + // 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("ma_refresh", tokens.refresh_token, { + res.cookies.set(REFRESH_COOKIE, tokens.refresh_token, { httpOnly: true, sameSite: "lax", secure: true, @@ -51,3 +53,16 @@ export function setAuthCookies( }); } } + +/** 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); +}