feat: SW-162 MFA for Profile implemented

This commit is contained in:
Hrishikesh Vaipurkar
2024-07-16 14:38:57 +02:00
parent 0c0fc1d08b
commit dde2b828cb
7 changed files with 177 additions and 12 deletions

View File

@@ -1,7 +1,9 @@
import { decode } from "@auth/core/jwt"
import { cookies } from "next/headers"
import { NextResponse } from "next/server"
import { authRequired } from "@/constants/routes/authRequired"
import { login } from "@/constants/routes/handleAuth"
import { authRequired, mfaRequired } from "@/constants/routes/authRequired"
import { login, mfaLogin } from "@/constants/routes/handleAuth"
import { env } from "@/env/server"
import { internalServerError } from "@/server/errors/next"
@@ -44,14 +46,6 @@ export const middleware = auth(async (request) => {
const isLoggedIn = !!request.auth
const hasError = request.auth?.error
if (isLoggedIn && !hasError) {
const headers = new Headers(request.headers)
headers.set("x-continue", "1")
return NextResponse.next({
headers,
})
}
if (!env.PUBLIC_URL) {
throw internalServerError("Missing value for env.PUBLIC_URL")
}
@@ -61,6 +55,54 @@ export const middleware = auth(async (request) => {
nextUrlClone.host = publicUrl.host
nextUrlClone.hostname = publicUrl.hostname
const isMFAValid = async function () {
const cookieStore = cookies()
const mfaCookieValue = cookieStore.get("_SecureMFA-token")?.value
if (mfaCookieValue) {
try {
const mfaToken = await decode({
token: mfaCookieValue,
secret: env.NEXTAUTH_SECRET,
salt: "_SecureMFA-token",
})
if (mfaToken?.exp) {
return true
}
} catch (e) {
console.log("JWT decode failed", e)
cookieStore.set("_SecureMFA-token", "", { maxAge: 0 })
return false
}
} else {
return false
}
}
if (isLoggedIn && !hasError) {
const isMFAPath = mfaRequired.includes(nextUrl.pathname)
const mfaValid = isMFAPath ? await isMFAValid() : true
if (!mfaValid) {
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({
headers,
})
}
const headers = new Headers()
headers.append(
"set-cookie",