Skip to content

Commit

Permalink
feat: Add error handling for authentication and email verification flow
Browse files Browse the repository at this point in the history
  • Loading branch information
kunaldevxxx committed Dec 19, 2024
1 parent 869f5d0 commit 3ea051d
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 4 deletions.
34 changes: 30 additions & 4 deletions src/app/api/auth/[auth0]/route.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
import { handleAuth, handleLogin } from '@auth0/nextjs-auth0';

import { NextRequest, NextResponse } from "next/server";
// export Auth0's default handleAuth with custom action for
// sign-up to render the sign-up screen by default
export const GET = handleAuth({
signup: handleLogin({
authorizationParams: {
screen_hint: 'signup',
redirect_uri: 'http://localhost:3000/verification',
screen_hint: 'signup'
},
}),

login: handleLogin({
authorizationParams: {
scope: 'openid profile email offline_access',
},
}),
})
// https://github.com/SuhravHussen/UmmahrChintah/blob/bb79e4f97c782ce2572f28afa72c17dad9469ed8/client/app/api/auth/%5Bauth0%5D/route.ts
onError: async (req: NextRequest) => {
// Extract error details from the URL
const url = new URL(req.url);
const errorType = url.searchParams.get("error");
const errorDescription = url.searchParams.get("error_description") || "";

// Handle email verification error
if (
errorType === "access_denied" &&
errorDescription?.includes("verify your email")
) {
return NextResponse.redirect(
new URL(`/error/verify-email`, process.env.NEXT_PUBLIC_URL || req.url)
);
}

// For other errors, redirect to a general error page
return NextResponse.redirect(
new URL(
`/auth/error?message=${encodeURIComponent(errorDescription)}`,
process.env.NEXT_PUBLIC_URL || req.url
)
);
},
});

28 changes: 28 additions & 0 deletions src/app/auth/error/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use client'

import { useSearchParams } from 'next/navigation'
import Link from 'next/link'

export default function AuthError() {
const searchParams = useSearchParams()
const errorMessage = searchParams?.get('message') || 'An unknown error occurred'

return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
<div className="text-center">
<h1 className="text-red-600 text-4xl font-bold mb-4">Authentication Error</h1>
<div className="bg-red-50 border border-red-200 rounded-md p-4 mb-4">
<p className="text-red-700">{decodeURIComponent(errorMessage)}</p>
</div>
<Link
href="/api/auth/login"
className="inline-block bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-md transition-colors"
>
Return to Sign In
</Link>
</div>
</div>
</div>
)
}
81 changes: 81 additions & 0 deletions src/app/error/verify-email/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use client";

import { Mail, ArrowRight } from "lucide-react";

export default function Page() {
return (
<div className="min-h-[75vh] flex items-center justify-center p-4">
<div className="w-full max-w-md bg-white rounded-lg shadow-lg p-6">
<div className="text-center space-y-6">
{/* Icon */}
<div className="mx-auto w-16 h-16 rounded-full flex items-center justify-center bg-gray-100">
<Mail className="w-8 h-8" />
</div>

{/* Title and Description */}
<div className="space-y-2">
<h2 className="text-2xl font-bold tracking-tight">
Verify your email
</h2>
<p className="text-sm text-gray-600">
We ve sent you a verification link. Please check your inbox to
continue.
</p>
</div>

{/* Steps */}
<div className="space-y-4 py-4">
{[
"Open your email inbox",
"Click the verification link we sent you",
"Return here to continue",
].map((text, index) => (
<div key={index} className="flex items-center space-x-3 text-left">
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center">
<span className="font-semibold">{index + 1}</span>
</div>
<p className="text-sm text-gray-600">{text}</p>
</div>
))}
</div>

{/* Divider */}
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-gray-200"></div>
</div>
<div className="relative flex justify-center text-sm">
<span className="px-2 bg-white text-gray-500">Already verified?</span>
</div>
</div>

{/* Actions */}
<div className="space-y-3">
<button
className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition-colors flex items-center justify-center group"
onClick={() => {
window.location.href = "/api/auth/logout?returnTo=api/auth/login";
}}
>
Continue to Login
<ArrowRight className="ml-2 h-4 w-4 group-hover:translate-x-1 transition-transform" />
</button>

<button
className="w-full border border-gray-300 text-gray-700 py-2 px-4 rounded-md hover:bg-gray-50 transition-colors"
onClick={() => (window.location.href = "/")}
>
Return to Home
</button>
</div>

{/* Help text */}
<p className="text-xs text-gray-500">
Didnt receive the email? Check your spam folder or try logging in
again to resend the verification email.
</p>
</div>
</div>
</div>
);
}

0 comments on commit 3ea051d

Please sign in to comment.