diff --git a/app/api/auth/refresh/route.ts b/app/api/auth/refresh/route.ts new file mode 100644 index 0000000..a7b678a --- /dev/null +++ b/app/api/auth/refresh/route.ts @@ -0,0 +1,56 @@ +import { NextResponse } from "next/server"; + +export async function GET(req: Request) { + const cookie = req.headers.get("cookie"); + + const refreshToken = cookie + ?.split("; ") + .find((c) => c.startsWith("refresh_token=")) + ?.split("=")[1]; + + if (!refreshToken) { + return NextResponse.json({ message: "No refresh token" }, { status: 401 }); + } + + try { + // Call your auth server (Keycloak or NestJS) + const res = await fetch("http://api.example.com/auth/refresh", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ refresh_token: refreshToken }), + }); + + if (!res.ok) { + throw new Error("Refresh failed"); + } + + const data = await res.json(); + + const response = NextResponse.json({ success: true }); + + // 🍪 Set new access token + response.cookies.set("access_token", data.access_token, { + httpOnly: true, + secure: true, + sameSite: "lax", + path: "/", + domain: ".example.com", + maxAge: data.expires_in, + }); + + response.cookies.set("refresh_token", data.refresh_token, { + httpOnly: true, + secure: true, + sameSite: "lax", + path: "/", + domain: ".example.com", + maxAge: data.expires_in, + }); + + return response; + } catch { + return NextResponse.json({ message: "Refresh failed" }, { status: 401 }); + } +} \ No newline at end of file