import { getCookieDomain } from "@/lib/getDomain"; import { env } from "@/lib/env"; import { NextResponse } from "next/server"; const BASE_URL = env.APP_URL; export async function GET(req: Request) { const url = new URL(req.url); const code = url.searchParams.get("code"); const isHttps = url.protocol === "https:"; if (!code) { return NextResponse.redirect(`${BASE_URL}/login?error=missing_code`); } const redirectUri = `${BASE_URL}/api/auth/callback`; const tokenRes = await fetch( `${env.KEYCLOAK_BASE_URL}/realms/${env.KEYCLOAK_REALM}/protocol/openid-connect/token`, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ client_id: env.KEYCLOAK_CLIENT_ID, client_secret: env.KEYCLOAK_CLIENT_SECRET, grant_type: "authorization_code", code, redirect_uri: redirectUri, }), } ); const text = await tokenRes.text(); let data: { access_token?: string; expires_in?: number }; try { data = JSON.parse(text) as typeof data; } catch { return NextResponse.redirect(`${BASE_URL}/login?error=token_parse`); } if (!tokenRes.ok || !data.access_token) { console.error("token exchange failed", tokenRes.status, text); return NextResponse.redirect(`${BASE_URL}/login?error=token_exchange`); } const res = NextResponse.redirect(`${BASE_URL}/admin/create-news`); // Secure cookies are ignored on http:// (e.g. localhost) — browser drops them. res.cookies.set("access_token", data.access_token, { httpOnly: true, secure: isHttps, sameSite: "lax", path: "/", maxAge: data.expires_in, ...(BASE_URL ? { BASE_URL } : {}), }); return res; }