Files
web/apps/scandic-web/app/[lang]/(live)/(protected)/logout/route.ts
Joakim Jäderberg daf765f3d5 Merged in feature/wrap-logging (pull request #2511)
Feature/wrap logging

* feat: change all logging to go through our own logger function so that we can control log levels

* move packages/trpc to using our own logger

* merge


Approved-by: Linus Flood
2025-07-03 12:37:04 +00:00

118 lines
3.5 KiB
TypeScript

import { type NextRequest, NextResponse } from "next/server"
import { AuthError } from "next-auth"
import { Lang } from "@scandic-hotels/common/constants/language"
import { logger } from "@scandic-hotels/common/logger"
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: Promise<{ 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"
logger.debug(
`[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 {
logger.debug(
`[login] missing returnUrl, using fallback: ${redirectToFallback}`
)
redirectTo = redirectToFallback
}
} else {
redirectTo = redirectToSearchParamValue || redirectToFallback
// Make relative URL to absolute URL
if (redirectTo.startsWith("/")) {
logger.debug(`[logout] make redirectTo absolute, from ${redirectTo}`)
redirectTo = new URL(redirectTo, publicURL).href
logger.debug(`[logout] make redirectTo absolute, to ${redirectTo}`)
}
try {
// Initiate the seamless logout flow
let redirectUrlValue
const params = await context.params
switch (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)
logger.debug(
`[logout] creating redirect to seamless logout: ${redirectUrl}`
)
redirectTo = redirectUrl.toString()
} catch (e) {
logger.error(
"Unable to create URL for seamless logout, proceeding without it.",
e
)
}
}
try {
redirectTo = `${env.CURITY_ISSUER_USER}/authn/authenticate/logout?redirect_uri=${encodeURIComponent(redirectTo)}`
logger.debug(`[logout] final redirectUrl: ${redirectTo}`)
/**
* 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) {
logger.debug(`[logout] redirecting to: ${redirectUrlObj.redirect}`)
return NextResponse.redirect(redirectUrlObj.redirect)
} else {
logger.error(`[logout] missing redirectUrlObj reponse from signOut()`)
}
} catch (error) {
if (error instanceof AuthError) {
logger.error("signOutAuthError", { signOutAuthError: error })
} else {
logger.error("signOutError", { signOutError: error })
}
}
return internalServerError()
}