// Session bridge: exchanges credentials with the Rust backend and stores the // bearer token in an httpOnly cookie so client JavaScript can never read it. import { NextResponse, type NextRequest } from "next/server"; import { apiOrigin, TOKEN_COOKIE } from "@/lib/api/http"; const SESSION_MAX_AGE_SECONDS = 7 * 24 * 60 * 60; export async function POST(request: NextRequest) { const body = await request.json(); const upstream = await fetch(`${apiOrigin()}/api/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); if (!upstream.ok) { return NextResponse.json({ error: "invalid credentials" }, { status: 401 }); } const { token } = (await upstream.json()) as { token: string }; const response = new NextResponse(null, { status: 204 }); response.cookies.set({ name: TOKEN_COOKIE, value: token, httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", path: "/", maxAge: SESSION_MAX_AGE_SECONDS, }); return response; } export async function DELETE(request: NextRequest) { const token = request.cookies.get(TOKEN_COOKIE)?.value; if (token) { await fetch(`${apiOrigin()}/api/auth/logout`, { method: "POST", headers: { Authorization: `Bearer ${token}` }, }); } const response = new NextResponse(null, { status: 204 }); response.cookies.delete(TOKEN_COOKIE); return response; }