Files
tvone/app/api/auth/callback/route.ts
T

59 lines
1.8 KiB
TypeScript
Raw Normal View History

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