diff --git a/.env.test b/.env.test index 8d70bab9d..801c4336b 100644 --- a/.env.test +++ b/.env.test @@ -12,6 +12,7 @@ CURITY_CLIENT_SECRET_SERVICE="test" CURITY_CLIENT_ID_USER="test" CURITY_CLIENT_SECRET_USER="test" CURITY_ISSUER_USER="test" +CURITY_ISSUER_SERVICE="test" CYPRESS_API_BASEURL="test" CYPRESS_CURITY_USERNAME="test" CYPRESS_CURITY_PASSWORD="test" @@ -35,3 +36,4 @@ SEAMLESS_LOGOUT_FI="test" SEAMLESS_LOGOUT_NO="test" SEAMLESS_LOGOUT_SV="test" WEBVIEW_ENCRYPTION_KEY="test" +BOOKING_ENCRYPTION_KEY="test" diff --git a/app/[lang]/(live)/(protected)/layout.tsx b/app/[lang]/(live)/(protected)/layout.tsx index 024071af3..19ad58daf 100644 --- a/app/[lang]/(live)/(protected)/layout.tsx +++ b/app/[lang]/(live)/(protected)/layout.tsx @@ -20,13 +20,17 @@ export default async function ProtectedLayout({ h.get("x-url") ?? h.get("x-pathname") ?? overview[getLang()] ) + const redirectURL = `/${getLang()}/login?redirectTo=${redirectTo}` + if (!session) { - redirect(`/${getLang()}/login?redirectTo=${redirectTo}`) + console.log(`[layout:protected] no session, redirecting to: ${redirectURL}`) + redirect(redirectURL) } const user = await serverClient().user.get() if (!user || "error" in user) { - redirect(`/${getLang()}/login?redirectTo=${redirectTo}`) + console.log(`[layout:protected] no user, redirecting to: ${redirectURL}`) + redirect(redirectURL) } return children diff --git a/app/[lang]/(live)/(protected)/logout/route.ts b/app/[lang]/(live)/(protected)/logout/route.ts index 38b98361a..2bb2f0a52 100644 --- a/app/[lang]/(live)/(protected)/logout/route.ts +++ b/app/[lang]/(live)/(protected)/logout/route.ts @@ -1,5 +1,3 @@ -import { createActionURL } from "@auth/core" -import { headers as nextHeaders } from "next/headers" import { NextRequest, NextResponse } from "next/server" import { AuthError } from "next-auth" @@ -16,11 +14,35 @@ export async function GET( let redirectTo: string = "" const returnUrl = request.headers.get("x-returnurl") + const isSeamless = request.headers.get("x-logout-source") === "seamless" - if (returnUrl) { - // Seamless logout request from Current web - redirectTo = returnUrl + 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, env.PUBLIC_URL).href + console.log(`[logout] make redirectTo absolute, to ${redirectTo}`) + } + try { // Initiate the seamless logout flow let redirectUrlValue @@ -45,6 +67,9 @@ export async function GET( break } const redirectUrl = new URL(redirectUrlValue) + console.log( + `[logout] creating redirect to seamless logout: ${redirectUrl}` + ) redirectTo = redirectUrl.toString() } catch (e) { console.error( @@ -55,37 +80,25 @@ export async function GET( } 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 */ - console.log({ logout_NEXTAUTH_URL: process.env.NEXTAUTH_URL }) - console.log({ logout_env: process.env }) - - 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 }) - - // Redirect to Curity logout - const curityLogoutUrl = `${env.CURITY_ISSUER_USER}/authn/authenticate/logout?redirect_uri=${encodeURIComponent(redirectTo)}` - - console.log({ logout_redirectTo: curityLogoutUrl }) - const redirectUrlObj = await signOut({ - redirectTo: curityLogoutUrl, + 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) { diff --git a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx index b35861357..012c40de2 100644 --- a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx @@ -34,7 +34,6 @@ export default async function MyPages({
{formatMessage({ id: "No content published" })}
)} -