import { type NextRequest, NextResponse } from "next/server" import { AuthError } from "next-auth" import { Lang } from "@/constants/languages" import { env } from "@/env/server" import { internalServerError } from "@/server/errors/next" import { getPublicURL } from "@/server/utils" import { signOut } from "@/auth" export async function GET( request: NextRequest, context: { params: { lang: Lang } } ) { const publicURL = getPublicURL(request) let redirectTo: string = "" const returnUrl = request.headers.get("x-returnurl") const isSeamless = request.headers.get("x-logout-source") === "seamless" console.log( `[logout] source: ${request.headers.get("x-logout-source") || "normal"}` ) const redirectToSearchParamValue = request.nextUrl.searchParams.get("redirectTo") const redirectToFallback = "/" if (isSeamless) { if (returnUrl) { redirectTo = returnUrl } else { console.log( `[login] missing returnUrl, using fallback: ${redirectToFallback}` ) redirectTo = redirectToFallback } } else { redirectTo = redirectToSearchParamValue || redirectToFallback // Make relative URL to absolute URL if (redirectTo.startsWith("/")) { console.log(`[logout] make redirectTo absolute, from ${redirectTo}`) redirectTo = new URL(redirectTo, publicURL).href console.log(`[logout] make redirectTo absolute, to ${redirectTo}`) } try { // Initiate the seamless logout flow let redirectUrlValue switch (context.params.lang) { case Lang.da: redirectUrlValue = env.SEAMLESS_LOGOUT_DA break case Lang.de: redirectUrlValue = env.SEAMLESS_LOGOUT_DE break case Lang.en: redirectUrlValue = env.SEAMLESS_LOGOUT_EN break case Lang.fi: redirectUrlValue = env.SEAMLESS_LOGOUT_FI break case Lang.no: redirectUrlValue = env.SEAMLESS_LOGOUT_NO break case Lang.sv: redirectUrlValue = env.SEAMLESS_LOGOUT_SV break } const redirectUrl = new URL(redirectUrlValue) console.log( `[logout] creating redirect to seamless logout: ${redirectUrl}` ) redirectTo = redirectUrl.toString() } catch (e) { console.error( "Unable to create URL for seamless logout, proceeding without it." ) console.error(e) } } try { redirectTo = `${env.CURITY_ISSUER_USER}/authn/authenticate/logout?redirect_uri=${encodeURIComponent(redirectTo)}` console.log(`[logout] final redirectUrl: ${redirectTo}`) console.log({ logout_env: process.env }) /** * Passing `redirect: false` to `signOut` will return a result object * instead of automatically redirecting inside of `signOut`. * https://github.com/nextauthjs/next-auth/blob/3c035ec/packages/next-auth/src/lib/actions.ts#L104 */ const redirectUrlObj = await signOut({ redirectTo, redirect: false, }) if (redirectUrlObj) { console.log(`[logout] redirecting to: ${redirectUrlObj.redirect}`) return NextResponse.redirect(redirectUrlObj.redirect) } else { console.error(`[logout] missing redirectUrlObj reponse from signOut()`) } } catch (error) { if (error instanceof AuthError) { console.log({ signOutAuthError: error }) } else { console.log({ signOutError: error }) } } return internalServerError() }