diff --git a/src/components/auth/PasswordVerificationDialog.tsx b/src/components/auth/PasswordVerificationDialog.tsx index 0ef10437..d59fe4c0 100644 --- a/src/components/auth/PasswordVerificationDialog.tsx +++ b/src/components/auth/PasswordVerificationDialog.tsx @@ -48,9 +48,16 @@ export function PasswordVerificationDialog({ const result = await reverifyPasswordAuth(email, password); if (result.success) { - toast.success("Password Verified!", { - description: "Your password authentication has been activated.", - }); + if (result.needsEmailConfirmation) { + toast.success("Password Verified!", { + description: "Check your email for a confirmation link to complete activation.", + duration: 8000, + }); + } else { + toast.success("Password Verified!", { + description: "Your password authentication has been activated.", + }); + } onOpenChange(false); onSuccess(); } else { diff --git a/src/components/settings/SecurityTab.tsx b/src/components/settings/SecurityTab.tsx index 9d95784d..58d39899 100644 --- a/src/components/settings/SecurityTab.tsx +++ b/src/components/settings/SecurityTab.tsx @@ -192,8 +192,12 @@ export function SecurityTab() { }; const handleVerificationSuccess = async () => { - await loadIdentities(); - sonnerToast.success("Password authentication activated successfully!"); + // Don't reload identities immediately - user needs to confirm email first + toast({ + title: "Email Confirmation Required", + description: "Check your email and click the confirmation link to activate password authentication.", + duration: 0, // Persistent + }); }; // Get connected accounts with identity data diff --git a/src/lib/identityService.ts b/src/lib/identityService.ts index 957bcb13..72349c3f 100644 --- a/src/lib/identityService.ts +++ b/src/lib/identityService.ts @@ -290,33 +290,54 @@ export async function hasOrphanedPassword(): Promise { } /** - * Re-verify password authentication by attempting sign-in - * This forces Supabase to create the email identity if it's missing + * Re-verify password authentication by signing in and triggering email confirmation + * This creates the missing email identity through Supabase's confirmation flow */ export async function reverifyPasswordAuth( email: string, password: string ): Promise { try { - const { error } = await supabase.auth.signInWithPassword({ + // Step 1: Verify credentials by signing in + console.log('[IdentityService] Verifying password credentials'); + const { data: authData, error: signInError } = await supabase.auth.signInWithPassword({ email, password }); - if (error) throw error; - - // Check if email identity was created - const emailCreated = await waitForEmailProvider(3); - - if (!emailCreated) { + if (signInError) { return { success: false, - error: 'Sign-in successful but identity verification failed. Please contact support.' + error: 'Invalid email or password' }; } - return { success: true }; + // Step 2: Trigger email confirmation to create identity + console.log('[IdentityService] Credentials verified, triggering email confirmation'); + const { error: updateError } = await supabase.auth.updateUser({ + email: email // Re-confirming email triggers identity creation + }); + + if (updateError) throw updateError; + + // Step 3: Sign out so user can confirm email + console.log('[IdentityService] Signing out to complete email confirmation'); + await supabase.auth.signOut(); + + // Step 4: Log the verification + if (authData.user) { + await logIdentityChange(authData.user.id, 'password_verified', { + method: 'orphaned_password_recovery' + }); + } + + return { + success: true, + needsEmailConfirmation: true, + email + }; } catch (error: any) { + console.error('[IdentityService] Failed to verify password:', error); return { success: false, error: error.message || 'Failed to verify password authentication'