From e264e4d2e26e8f98d6673910eabf617bffbd7de1 Mon Sep 17 00:00:00 2001 From: Hrishikesh Vaipurkar Date: Fri, 19 Jul 2024 13:15:56 +0200 Subject: [PATCH] feat: SW-162 Updated redirect to rewrite reducing unnecessary redirects for user --- .../(live)/(protected)/mfa-login/route.ts | 68 ------------------- app/[lang]/(live)/(public)/login/route.ts | 4 +- constants/routes/handleAuth.js | 16 +---- middlewares/authRequired.ts | 32 ++++----- next.config.js | 7 +- 5 files changed, 19 insertions(+), 108 deletions(-) delete mode 100644 app/[lang]/(live)/(protected)/mfa-login/route.ts diff --git a/app/[lang]/(live)/(protected)/mfa-login/route.ts b/app/[lang]/(live)/(protected)/mfa-login/route.ts deleted file mode 100644 index bec0a3eb5..000000000 --- a/app/[lang]/(live)/(protected)/mfa-login/route.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { 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 { signIn } from "@/auth" - -export async function GET( - request: NextRequest, - context: { params: { lang: Lang } } -) { - let redirectHeaders: Headers | undefined = undefined - let redirectTo: string - - redirectTo = - request.cookies.get("redirectTo")?.value || // Cookie gets set by authRequired middleware - request.nextUrl.searchParams.get("redirectTo") || - "/" - - // Make relative URL to absolute URL - if (redirectTo.startsWith("/")) { - if (!env.PUBLIC_URL) { - throw internalServerError("No value for env.PUBLIC_URL") - } - redirectTo = new URL(redirectTo, env.PUBLIC_URL).href - } - - // 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 { - /** - * Passing `redirect: false` to `signIn` will return the URL instead of - * automatically redirecting to it inside of `signIn`. - * https://github.com/nextauthjs/next-auth/blob/3c035ec/packages/next-auth/src/lib/actions.ts#L76 - */ - const redirectUrl = await signIn( - "curity-mfa", - { - redirectTo, - redirect: false, - }, - { - ui_locales: context.params.lang, - } - ) - - if (redirectUrl) { - return NextResponse.redirect(redirectUrl, { - headers: redirectHeaders, - }) - } - } catch (error) { - if (error instanceof AuthError) { - console.error({ signInAuthError: error }) - } else { - console.error({ signInError: error }) - } - } - - return internalServerError() -} diff --git a/app/[lang]/(live)/(public)/login/route.ts b/app/[lang]/(live)/(public)/login/route.ts index 5cbc22d9b..9f1a682e7 100644 --- a/app/[lang]/(live)/(public)/login/route.ts +++ b/app/[lang]/(live)/(public)/login/route.ts @@ -15,6 +15,7 @@ export async function GET( let redirectTo: string const returnUrl = request.headers.get("x-returnurl") + const isMFA = request.headers.get("mfa-login") if (returnUrl) { // Seamless login request from Current web @@ -85,8 +86,9 @@ export async function GET( console.log({ login_env: process.env }) console.log({ login_redirectTo: redirectTo }) + const signInProvider = isMFA ? "curity-mfa" : "curity" const redirectUrl = await signIn( - "curity", + signInProvider, { redirectTo, redirect: false, diff --git a/constants/routes/handleAuth.js b/constants/routes/handleAuth.js index dda9924f7..042ffba6d 100644 --- a/constants/routes/handleAuth.js +++ b/constants/routes/handleAuth.js @@ -22,18 +22,4 @@ export const logout = { sv: "/sv/logga-ut", } -/** @type {import('@/types/routes').LangRoute} */ -export const mfaLogin = { - da: "/da/mfa-log-pa", - de: "/de/mfa-anmeldung", - en: "/en/mfa-login", - fi: "/fi/mfa-kirjaudu-sisaan", - no: "/no/mfa-logg-inn", - sv: "/sv/mfa-logga-in", -} - -export const handleAuth = [ - ...Object.values(login), - ...Object.values(logout), - ...Object.values(mfaLogin), -] +export const handleAuth = [...Object.values(login), ...Object.values(logout)] diff --git a/middlewares/authRequired.ts b/middlewares/authRequired.ts index 56f80708b..52bb06c04 100644 --- a/middlewares/authRequired.ts +++ b/middlewares/authRequired.ts @@ -3,7 +3,7 @@ import { cookies } from "next/headers" import { NextResponse } from "next/server" import { authRequired, mfaRequired } from "@/constants/routes/authRequired" -import { login, mfaLogin } from "@/constants/routes/handleAuth" +import { login } from "@/constants/routes/handleAuth" import { env } from "@/env/server" import { internalServerError } from "@/server/errors/next" @@ -77,25 +77,21 @@ export const middleware = auth(async (request) => { return true } } + const isMFAPath = mfaRequired.includes(nextUrl.pathname) + const mfaInvalid = isMFAPath ? await isMFAInvalid() : false + + if (isLoggedIn && mfaInvalid) { + const headers = new Headers(request.headers) + headers.set("mfa-login", "true") + headers.set("x-returnurl", request.nextUrl.href) + return NextResponse.rewrite(new URL(`/${lang}/login`, request.nextUrl), { + request: { + headers, + }, + }) + } if (isLoggedIn && !hasError) { - const isMFAPath = mfaRequired.includes(nextUrl.pathname) - const mfaInvalid = isMFAPath ? await isMFAInvalid() : false - if (mfaInvalid) { - const mfaLoginUrl = mfaLogin[lang] - const nextUrlClone = nextUrl.clone() - nextUrlClone.host = publicUrl.host - nextUrlClone.hostname = publicUrl.hostname - const headers = new Headers() - headers.append( - "set-cookie", - `redirectTo=${encodeURIComponent(nextUrlClone.href)}; Path=/; HttpOnly; SameSite=Lax` - ) - return NextResponse.redirect(new URL(mfaLoginUrl, nextUrlClone), { - headers, - }) - } - const headers = new Headers(request.headers) headers.set("x-continue", "1") return NextResponse.next({ diff --git a/next.config.js b/next.config.js index e5011a6c3..60e5a38d9 100644 --- a/next.config.js +++ b/next.config.js @@ -1,7 +1,7 @@ import createJiti from "jiti" import { fileURLToPath } from "url" -import { login, logout, mfaLogin } from "./constants/routes/handleAuth.js" +import { login, logout } from "./constants/routes/handleAuth.js" import { hotelReservation } from "./constants/routes/hotelReservation.js" import { myPages } from "./constants/routes/myPages.js" @@ -80,11 +80,6 @@ const nextConfig = { { source: logout.fi, destination: "/fi/logout" }, { source: logout.no, destination: "/no/logout" }, { source: logout.sv, destination: "/sv/logout" }, - { source: mfaLogin.da, destination: "/da/mfa-login" }, - { source: mfaLogin.de, destination: "/de/mfa-login" }, - { source: mfaLogin.fi, destination: "/fi/mfa-login" }, - { source: mfaLogin.no, destination: "/no/mfa-login" }, - { source: mfaLogin.sv, destination: "/sv/mfa-login" }, { source: `${myPages.en}/:path*`, destination: `/en/my-pages/:path*`,