Merge pull request #27 from pezkuwichain/fix/remove-dead-email-verification

fix(security): remove the dead email-verification function
This commit is contained in:
SatoshiQaziMuhammed
2026-07-31 20:26:51 -07:00
committed by GitHub
2 changed files with 6 additions and 136 deletions
+6 -36
View File
@@ -10,7 +10,6 @@ export default function EmailVerification() {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const [verifying, setVerifying] = useState(false);
const [verified, setVerified] = useState(false); const [verified, setVerified] = useState(false);
const [error, setError] = useState(''); const [error, setError] = useState('');
const [resending, setResending] = useState(false); const [resending, setResending] = useState(false);
@@ -19,7 +18,6 @@ export default function EmailVerification() {
// Get email from navigation state (after sign up) // Get email from navigation state (after sign up)
const email = location.state?.email; const email = location.state?.email;
const token = searchParams.get('token');
const type = searchParams.get('type'); const type = searchParams.get('type');
useEffect(() => { useEffect(() => {
@@ -32,29 +30,8 @@ export default function EmailVerification() {
setVerified(true); setVerified(true);
} }
}); });
} else if (token) {
verifyEmail(token);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps }, [type]);
}, [token, type]);
const verifyEmail = async (verifyToken: string) => {
setVerifying(true);
try {
const { error } = await supabase.functions.invoke('email-verification', {
body: { action: 'verify', token: verifyToken }
});
if (error) throw error;
setVerified(true);
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : t('emailVerify.failedToVerify');
setError(errorMessage);
} finally {
setVerifying(false);
}
};
const handleResendEmail = async () => { const handleResendEmail = async () => {
if (!email) return; if (!email) return;
@@ -80,7 +57,7 @@ export default function EmailVerification() {
}; };
// Show "check your email" screen after sign up // Show "check your email" screen after sign up
if (email && !token && !type) { if (email && !type) {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-gray-900 via-black to-gray-900 flex items-center justify-center p-4"> <div className="min-h-screen bg-gradient-to-br from-gray-900 via-black to-gray-900 flex items-center justify-center p-4">
<Card className="w-full max-w-md relative bg-gray-900/90 backdrop-blur-xl border-gray-800"> <Card className="w-full max-w-md relative bg-gray-900/90 backdrop-blur-xl border-gray-800">
@@ -162,18 +139,11 @@ export default function EmailVerification() {
<CardHeader> <CardHeader>
<CardTitle className="text-white">{t('emailVerify.title')}</CardTitle> <CardTitle className="text-white">{t('emailVerify.title')}</CardTitle>
<CardDescription className="text-gray-400"> <CardDescription className="text-gray-400">
{verifying ? t('emailVerify.verifyingEmail') : t('emailVerify.verificationStatus')} {t('emailVerify.verificationStatus')}
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent className="text-center space-y-4"> <CardContent className="text-center space-y-4">
{verifying && ( {verified && (
<div className="flex flex-col items-center space-y-4">
<Loader2 className="h-12 w-12 animate-spin text-green-500" />
<p className="text-gray-300">{t('emailVerify.pleaseWait')}</p>
</div>
)}
{!verifying && verified && (
<div className="flex flex-col items-center space-y-4"> <div className="flex flex-col items-center space-y-4">
<CheckCircle className="h-12 w-12 text-green-500" /> <CheckCircle className="h-12 w-12 text-green-500" />
<h3 className="text-lg font-semibold text-white">{t('emailVerify.success')}</h3> <h3 className="text-lg font-semibold text-white">{t('emailVerify.success')}</h3>
@@ -189,7 +159,7 @@ export default function EmailVerification() {
</div> </div>
)} )}
{!verifying && !verified && error && ( {!verified && error && (
<div className="flex flex-col items-center space-y-4"> <div className="flex flex-col items-center space-y-4">
<XCircle className="h-12 w-12 text-red-500" /> <XCircle className="h-12 w-12 text-red-500" />
<h3 className="text-lg font-semibold text-white">{t('emailVerify.failed')}</h3> <h3 className="text-lg font-semibold text-white">{t('emailVerify.failed')}</h3>
@@ -205,7 +175,7 @@ export default function EmailVerification() {
</div> </div>
)} )}
{!verifying && !verified && !error && !token && !type && ( {!verified && !error && !type && (
<div className="flex flex-col items-center space-y-4"> <div className="flex flex-col items-center space-y-4">
<Mail className="h-12 w-12 text-gray-500" /> <Mail className="h-12 w-12 text-gray-500" />
<h3 className="text-lg font-semibold text-white">{t('emailVerify.noToken')}</h3> <h3 className="text-lg font-semibold text-white">{t('emailVerify.noToken')}</h3>
@@ -1,100 +0,0 @@
export const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"authorization, x-client-info, apikey, content-type",
};
Deno.serve(async (req) => {
if (req.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders });
}
try {
const { action, token, email } = await req.json();
if (action === "send") {
// Generate verification token
const verificationToken = crypto.randomUUID();
// Store token in database (expires in 24 hours)
const { createClient } =
await import("https://esm.sh/@supabase/supabase-js@2");
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
const supabaseKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
const supabase = createClient(supabaseUrl, supabaseKey);
const { data: user } = await supabase.auth.admin.getUserByEmail(email);
if (!user?.user) {
throw new Error("User not found");
}
await supabase.from("email_verification_tokens").insert({
user_id: user.user.id,
token: verificationToken,
email: email,
expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
});
// In production, send email via email service
// For now, return the token
return new Response(
JSON.stringify({
success: true,
message: "Verification email sent",
token: verificationToken, // Remove in production
}),
{ headers: { ...corsHeaders, "Content-Type": "application/json" } },
);
}
if (action === "verify") {
const { createClient } =
await import("https://esm.sh/@supabase/supabase-js@2");
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
const supabaseKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
const supabase = createClient(supabaseUrl, supabaseKey);
// Check token validity
const { data: tokenData } = await supabase
.from("email_verification_tokens")
.select("*")
.eq("token", token)
.single();
if (!tokenData || new Date(tokenData.expires_at) < new Date()) {
throw new Error("Invalid or expired token");
}
// Update user profile
await supabase
.from("profiles")
.update({
email_verified: true,
email_verified_at: new Date().toISOString(),
})
.eq("id", tokenData.user_id);
// Delete used token
await supabase
.from("email_verification_tokens")
.delete()
.eq("token", token);
return new Response(
JSON.stringify({
success: true,
message: "Email verified successfully",
}),
{ headers: { ...corsHeaders, "Content-Type": "application/json" } },
);
}
throw new Error("Invalid action");
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
headers: { ...corsHeaders, "Content-Type": "application/json" },
status: 400,
});
}
});