import { createActionURL } from "@auth/core" import { headers as nextHeaders } from "next/headers" import { NextRequest, NextResponse } from "next/server" import { AuthError } from "next-auth" import { Lang } from "@/constants/languages" import { env } from "@/env/server" import { serverClient } from "@/lib/trpc/server" import { badRequest } from "@/server/errors/next" import { signOut } from "@/auth" export async function GET( request: NextRequest, context: { params: { lang: Lang } } ) { let redirectHeaders: Headers | undefined = undefined let redirectTo: string const returnUrl = request.headers.get("x-returnurl") if (returnUrl) { // Seamless logout request from Current web redirectTo = returnUrl } else { // Normal logout request from New web redirectTo = request.cookies.get("redirectTo")?.value || // Cookie gets set by authRequired middleware request.headers.get("x-redirect-to") || request.nextUrl.searchParams.get("redirectTo") || request.headers.get("Referer") || "/" console.log(redirectTo) // If above fails, always redirect to startpage if (!redirectTo) { const proto = request.headers.get("x-forwarded-proto") ?? "http" const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? env.URL redirectTo = `${proto}://${host}/` console.log({ logout_fallback: redirectTo }) } // Clean up cookie from authRequired middleware redirectHeaders = new Headers() redirectHeaders.append( "set-cookie", "redirectTo=; Expires=Thu, 01 Jan 1970 00:00:00 UTC; Path=/; HttpOnly; SameSite=Lax" ) } try { // Initiate the seamless logout flow const invalidateResponse = await serverClient().user.invalidateSessions() 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 } console.log(redirectUrlValue) const redirectUrl = new URL(redirectUrlValue) redirectUrl.searchParams.set("returnurl", redirectTo) redirectTo = redirectUrl.toString() console.log(redirectUrl, redirectTo) } catch (e) { console.error( "Unable to create URL for seamless logout, proceeding without it." ) console.error(e) } try { console.log({ logout_AUTH_URL: process.env.AUTH_URL }) console.log({ logout_NEXTAUTH_URL: process.env.NEXTAUTH_URL }) 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 headers = new Headers(nextHeaders()) const signOutURL = createActionURL( "signout", // @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default headers.get("x-forwarded-proto"), headers, process.env ) console.log({ logout_signOutURL: signOutURL }) const redirectUrlObj = await signOut({ redirectTo, redirect: false, }) console.log(redirectUrlObj) if (redirectUrlObj) { return NextResponse.redirect(redirectUrlObj.redirect, { headers: redirectHeaders, }) } } catch (error) { if (error instanceof AuthError) { console.log({ signOutAuthError: error }) } else { console.log({ signOutError: error }) } } return badRequest() }