diff --git a/src/components/auth/PasswordSetupDialog.tsx b/src/components/auth/PasswordSetupDialog.tsx index f4022608..c4e36a27 100644 --- a/src/components/auth/PasswordSetupDialog.tsx +++ b/src/components/auth/PasswordSetupDialog.tsx @@ -18,7 +18,7 @@ import type { OAuthProvider } from '@/types/identity'; interface PasswordSetupDialogProps { open: boolean; onOpenChange: (open: boolean) => void; - onSuccess: (email?: string) => void; + onSuccess: (email?: string, needsConfirmation?: boolean) => void; provider?: OAuthProvider; mode?: 'standalone' | 'disconnect'; } @@ -61,8 +61,8 @@ export function PasswordSetupDialog({ setConfirmPassword(''); if (result.needsRelogin && result.email) { - // Pass email to parent for redirect handling - onSuccess(result.email); + // Pass email and confirmation flag to parent for redirect handling + onSuccess(result.email, result.needsEmailConfirmation); } else { onSuccess(); } diff --git a/src/components/settings/SecurityTab.tsx b/src/components/settings/SecurityTab.tsx index 82c70d85..ed3bb682 100644 --- a/src/components/settings/SecurityTab.tsx +++ b/src/components/settings/SecurityTab.tsx @@ -122,14 +122,22 @@ export function SecurityTab() { } }; - const handlePasswordSetupSuccess = async (email?: string) => { + const handlePasswordSetupSuccess = (email?: string, needsConfirmation?: boolean) => { if (email) { - // Password was set, user was logged out, needs to sign in with email/password - toast({ - title: 'Password Set Successfully', - description: 'Please sign in with your email and password to complete setup.', - duration: 6000, - }); + // Password was set, user was logged out, needs to confirm email + if (needsConfirmation) { + toast({ + title: 'Check Your Email', + description: 'A confirmation link has been sent to your email. Click it to activate password authentication, then sign in.', + duration: 10000, + }); + } else { + toast({ + title: 'Password Set Successfully', + description: 'Please sign in with your email and password to complete setup.', + duration: 6000, + }); + } // Redirect to auth page with email pre-filled navigate(`/auth?email=${encodeURIComponent(email)}&message=complete-password-setup`); @@ -137,16 +145,15 @@ export function SecurityTab() { // Normal password change flow (user already had email identity) setAddingPassword(true); - try { - await loadIdentities(); + loadIdentities().then(() => { toast({ title: 'Password Updated', description: 'Your password has been successfully updated.', }); setPasswordSetupProvider(null); - } finally { + }).finally(() => { setAddingPassword(false); - } + }); } }; @@ -185,7 +192,7 @@ export function SecurityTab() { !open && setPasswordSetupProvider(null)} - onSuccess={handlePasswordSetupSuccess} + onSuccess={(email, needsConfirmation) => handlePasswordSetupSuccess(email, needsConfirmation)} provider={passwordSetupProvider} mode={addPasswordMode} /> diff --git a/src/lib/identityService.ts b/src/lib/identityService.ts index e8fb31c0..957bcb13 100644 --- a/src/lib/identityService.ts +++ b/src/lib/identityService.ts @@ -213,9 +213,13 @@ export async function addPasswordToAccount( }; } - // Step 1: Update password - console.log('[IdentityService] Setting password for user'); - const { error: updateError } = await supabase.auth.updateUser({ password }); + // Step 1: Update password AND trigger email confirmation + // Re-confirming the email will trigger Supabase to create the email identity + console.log('[IdentityService] Setting password and triggering email confirmation'); + const { error: updateError } = await supabase.auth.updateUser({ + password, + email: userEmail // Re-confirm email to create email identity provider + }); if (updateError) throw updateError; // Step 2: Get user profile for email personalization @@ -248,17 +252,18 @@ export async function addPasswordToAccount( // Step 4: Log the password addition await logIdentityChange(user!.id, 'password_added', { - method: 'oauth_with_relogin_required' + method: 'oauth_with_email_confirmation_required' }); - // Step 5: Sign the user out so they can sign back in with email/password - console.log('[IdentityService] Signing user out to force re-login'); + // Step 5: Sign the user out so they can confirm email + console.log('[IdentityService] Signing user out to complete email confirmation'); await supabase.auth.signOut(); - // Return success with relogin flag + // Return success with relogin and email confirmation flags return { success: true, needsRelogin: true, + needsEmailConfirmation: true, email: userEmail }; diff --git a/src/pages/Auth.tsx b/src/pages/Auth.tsx index 8acb7df2..1a7d40ca 100644 --- a/src/pages/Auth.tsx +++ b/src/pages/Auth.tsx @@ -390,7 +390,7 @@ export default function Auth() { - Your password has been set. Please sign in with your email and password to complete the setup. + Password setup in progress. Check your email for a confirmation link. After confirming your email, sign in below with your email and password. )} diff --git a/src/types/identity.ts b/src/types/identity.ts index 712e316d..36980b96 100644 --- a/src/types/identity.ts +++ b/src/types/identity.ts @@ -31,5 +31,6 @@ export interface IdentityOperationResult { success: boolean; error?: string; needsRelogin?: boolean; + needsEmailConfirmation?: boolean; email?: string; } diff --git a/supabase/functions/send-password-added-email/index.ts b/supabase/functions/send-password-added-email/index.ts index 17479774..8e70206d 100644 --- a/supabase/functions/send-password-added-email/index.ts +++ b/supabase/functions/send-password-added-email/index.ts @@ -76,12 +76,22 @@ serve(async (req) => {

🔐 Complete Your Setup

-

To activate your password authentication, please sign in with your new credentials:

+

Important: To complete your password setup, you need to confirm your email address.

- - Sign In Now +
    +
  1. Check your inbox for a confirmation email from ThrillWiki
  2. +
  3. Click the confirmation link in that email
  4. +
  5. Return to the sign-in page and log in with your email and password
  6. +
+ +
+ Go to Sign In Page +

+ Note: You must confirm your email before you can sign in with your password. +

+
⚠️ Security Notice
If you didn't add a password to your account, please contact our support team immediately at support@thrillwiki.com