From 060643fed8e5b19114a8d044180d89d4f412ea75 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Mon, 22 Dec 2025 12:50:28 +0530 Subject: [PATCH] feat: add email verification page and allow public access via middleware. --- src/app/verify-email/page.tsx | 136 ++++++++++++++++++++++++++++++++++ src/middleware.ts | 2 +- 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/app/verify-email/page.tsx diff --git a/src/app/verify-email/page.tsx b/src/app/verify-email/page.tsx new file mode 100644 index 0000000..8285f63 --- /dev/null +++ b/src/app/verify-email/page.tsx @@ -0,0 +1,136 @@ +'use client'; + +import { Suspense, useEffect, useState } from 'react'; +import { useSearchParams } from 'next/navigation'; +import Link from 'next/link'; +import { authService, AuthService } from '@/services/auth.service'; + +function VerifyEmailContent() { + const searchParams = useSearchParams(); + const token = searchParams.get('token'); + + const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading'); + const [message, setMessage] = useState(''); + + useEffect(() => { + const verifyEmail = async () => { + if (!token) { + setStatus('error'); + setMessage('Invalid verification link. No token provided.'); + return; + } + + try { + const response = await authService.verifyEmail({ token }); + setStatus('success'); + setMessage(response.data?.message || 'Your email has been verified successfully!'); + } catch (error) { + setStatus('error'); + const errorMsg = AuthService.getErrorMessage(error); + setMessage(errorMsg || 'Email verification failed. The link may have expired or is invalid.'); + } + }; + + verifyEmail(); + }, [token]); + + return ( +
+ {status === 'loading' && ( +
+
+ + + + +
+

Verifying Your Email

+

Please wait while we verify your email address...

+
+ )} + + {status === 'success' && ( +
+
+ + + +
+

Email Verified!

+

{message}

+ + Continue to Login + +
+ )} + + {status === 'error' && ( +
+
+ + + +
+

Verification Failed

+

{message}

+
+ + Go to Login + + + Sign Up Again + +
+
+ )} +
+ ); +} + +function LoadingFallback() { + return ( +
+
+
+ + + + +
+

Loading...

+

Please wait...

+
+
+ ); +} + +export default function VerifyEmailPage() { + return ( +
+
+ {/* Logo */} +
+ RE-QuestN +
+ + {/* Content Card */} + }> + + +
+
+ ); +} diff --git a/src/middleware.ts b/src/middleware.ts index ee594db..4275cde 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -2,7 +2,7 @@ import { auth } from "@/auth"; import { NextResponse } from "next/server"; // Public routes that don't require authentication -const publicRoutes = ["/login", "/signup", "/forgot-password", "/reset-password"]; +const publicRoutes = ["/login", "/signup", "/forgot-password", "/reset-password", "/verify-email"]; export default auth((req) => { const { nextUrl } = req;