From 2361ba696d8faedcbe52c5ae6c690848f554492f Mon Sep 17 00:00:00 2001 From: Michael Zetterberg Date: Thu, 22 Aug 2024 07:25:08 +0200 Subject: [PATCH] fix: improve auth handling and logging --- app/[lang]/(live)/(public)/login/route.ts | 52 ++++++++++++++++------- middlewares/authRequired.ts | 2 +- middlewares/currentWebLogin.ts | 1 + middlewares/currentWebLoginEmail.ts | 2 +- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/app/[lang]/(live)/(public)/login/route.ts b/app/[lang]/(live)/(public)/login/route.ts index ba8292d89..91668330e 100644 --- a/app/[lang]/(live)/(public)/login/route.ts +++ b/app/[lang]/(live)/(public)/login/route.ts @@ -15,28 +15,46 @@ export async function GET( let redirectTo: string const returnUrl = request.headers.get("x-returnurl") - const isMFA = request.headers.get("x-mfa-login") - - // This is to support seamless login when using magic link login - const isMagicLinkUpdateLogin = !!request.headers.get("x-magic-link") + const isSeamless = request.headers.get("x-login-source") === "seamless" + const isMFA = request.headers.get("x-login-source") === "mfa" + const isSeamlessMagicLink = + request.headers.get("x-login-source") === "seamless-magiclink" if (!env.PUBLIC_URL) { throw internalServerError("No value for env.PUBLIC_URL") } - if (returnUrl) { - // Seamless login request from Current web - redirectTo = returnUrl + console.log( + `[login] source: ${request.headers.get("x-login-source") || "normal"}` + ) + + const redirectToCookieValue = request.cookies.get("redirectTo")?.value // Cookie gets set by authRequired middleware + const redirectToSearchParamValue = + request.nextUrl.searchParams.get("redirectTo") + const redirectToFallback = "/" + console.log(`[login] redirectTo cookie value: ${redirectToCookieValue}`) + console.log( + `[login] redirectTo search param value: ${redirectToSearchParamValue}` + ) + + if (isSeamless) { + if (returnUrl) { + redirectTo = returnUrl + } else { + console.log( + `[login] missing returnUrl, using fallback: ${redirectToFallback}` + ) + redirectTo = redirectToFallback + } } else { - // Normal login request from New web redirectTo = - request.cookies.get("redirectTo")?.value || // Cookie gets set by authRequired middleware - request.nextUrl.searchParams.get("redirectTo") || - "/" + redirectToCookieValue || redirectToSearchParamValue || redirectToFallback // Make relative URL to absolute URL if (redirectTo.startsWith("/")) { + console.log(`[login] make redirectTo absolute, from ${redirectTo}`) redirectTo = new URL(redirectTo, env.PUBLIC_URL).href + console.log(`[login] make redirectTo absolute, to ${redirectTo}`) } // Clean up cookie from authRequired middleware @@ -70,7 +88,11 @@ export async function GET( break } const redirectUrl = new URL(redirectUrlValue) + console.log(`[login] creating redirect to seamless login: ${redirectUrl}`) redirectUrl.searchParams.set("returnurl", redirectTo) + console.log( + `[login] returnurl for seamless login: ${redirectUrl.searchParams.get("returnurl")}` + ) redirectTo = redirectUrl.toString() /** Set cookie with redirect Url to appropriately redirect user when using magic link login */ @@ -94,10 +116,8 @@ export async function GET( * automatically redirecting to it inside of `signIn`. * https://github.com/nextauthjs/next-auth/blob/3c035ec/packages/next-auth/src/lib/actions.ts#L76 */ - console.log({ login_NEXTAUTH_URL: process.env.NEXTAUTH_URL }) + console.log(`[login] final redirectUrl: ${redirectTo}`) console.log({ login_env: process.env }) - - console.log({ login_redirectTo: redirectTo }) const params = { ui_locales: context.params.lang, scope: ["openid", "profile"].join(" "), @@ -117,6 +137,7 @@ export async function GET( // This is new param set for differentiate between the Magic link login of New web and current web version: "2", } + if (isMFA) { // Append profile_update scope for MFA params.scope = params.scope + " profile_udpate" @@ -126,9 +147,10 @@ export async function GET( */ params.acr_values = "urn:se:curity:authentication:otp-authenticator:OTP-Authenticator_web" - } else if (isMagicLinkUpdateLogin) { + } else if (isSeamlessMagicLink) { params.acr_values = "abc" } + const redirectUrl = await signIn( "curity", { diff --git a/middlewares/authRequired.ts b/middlewares/authRequired.ts index 222f408fe..896bbfd3a 100644 --- a/middlewares/authRequired.ts +++ b/middlewares/authRequired.ts @@ -67,8 +67,8 @@ export const middleware = auth(async (request) => { if (isLoggedIn && isMFAPath && isMFAInvalid()) { const headers = new Headers(request.headers) - headers.set("x-mfa-login", "true") headers.set("x-returnurl", nextUrlClone.href) + headers.set("x-login-source", "mfa") return NextResponse.rewrite(new URL(`/${lang}/login`, request.nextUrl), { request: { headers, diff --git a/middlewares/currentWebLogin.ts b/middlewares/currentWebLogin.ts index 49c664be3..14fb89e67 100644 --- a/middlewares/currentWebLogin.ts +++ b/middlewares/currentWebLogin.ts @@ -19,6 +19,7 @@ export const middleware: NextMiddleware = (request) => { const headers = new Headers(request.headers) headers.set("x-returnurl", returnUrl) + headers.set("x-login-source", "seamless") return NextResponse.rewrite(new URL(`/${lang}/login`, request.nextUrl), { request: { diff --git a/middlewares/currentWebLoginEmail.ts b/middlewares/currentWebLoginEmail.ts index 9e27016ed..3f53417df 100644 --- a/middlewares/currentWebLoginEmail.ts +++ b/middlewares/currentWebLoginEmail.ts @@ -19,7 +19,7 @@ export const middleware: NextMiddleware = (request) => { const headers = new Headers(request.headers) headers.set("x-returnurl", returnUrl) - headers.set("x-magic-link", "1") + headers.set("x-login-source", "seamless-magiclink") return NextResponse.rewrite(new URL(`/${lang}/login`, request.nextUrl), { request: {