diff --git a/web/src/pages/EmailVerification.tsx b/web/src/pages/EmailVerification.tsx index d5a2baa2..17e34ff6 100644 --- a/web/src/pages/EmailVerification.tsx +++ b/web/src/pages/EmailVerification.tsx @@ -10,7 +10,6 @@ export default function EmailVerification() { const [searchParams] = useSearchParams(); const location = useLocation(); const navigate = useNavigate(); - const [verifying, setVerifying] = useState(false); const [verified, setVerified] = useState(false); const [error, setError] = useState(''); const [resending, setResending] = useState(false); @@ -19,7 +18,6 @@ export default function EmailVerification() { // Get email from navigation state (after sign up) const email = location.state?.email; - const token = searchParams.get('token'); const type = searchParams.get('type'); useEffect(() => { @@ -32,29 +30,8 @@ export default function EmailVerification() { setVerified(true); } }); - } else if (token) { - verifyEmail(token); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [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); - } - }; + }, [type]); const handleResendEmail = async () => { if (!email) return; @@ -80,7 +57,7 @@ export default function EmailVerification() { }; // Show "check your email" screen after sign up - if (email && !token && !type) { + if (email && !type) { return (
@@ -162,18 +139,11 @@ export default function EmailVerification() { {t('emailVerify.title')} - {verifying ? t('emailVerify.verifyingEmail') : t('emailVerify.verificationStatus')} + {t('emailVerify.verificationStatus')} - {verifying && ( -
- -

{t('emailVerify.pleaseWait')}

-
- )} - - {!verifying && verified && ( + {verified && (

{t('emailVerify.success')}

@@ -189,7 +159,7 @@ export default function EmailVerification() {
)} - {!verifying && !verified && error && ( + {!verified && error && (

{t('emailVerify.failed')}

@@ -205,7 +175,7 @@ export default function EmailVerification() {
)} - {!verifying && !verified && !error && !token && !type && ( + {!verified && !error && !type && (

{t('emailVerify.noToken')}

diff --git a/web/supabase/functions/email-verification/index.ts b/web/supabase/functions/email-verification/index.ts deleted file mode 100644 index e2bd0b7c..00000000 --- a/web/supabase/functions/email-verification/index.ts +++ /dev/null @@ -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, - }); - } -});