mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 09:51:13 -05:00
Refactor: Implement email confirmation for password auth
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
<PasswordSetupDialog
|
||||
open={!!passwordSetupProvider}
|
||||
onOpenChange={(open) => !open && setPasswordSetupProvider(null)}
|
||||
onSuccess={handlePasswordSetupSuccess}
|
||||
onSuccess={(email, needsConfirmation) => handlePasswordSetupSuccess(email, needsConfirmation)}
|
||||
provider={passwordSetupProvider}
|
||||
mode={addPasswordMode}
|
||||
/>
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ export default function Auth() {
|
||||
<Alert className="mb-4">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertDescription>
|
||||
Your password has been set. Please sign in with your email and password to complete the setup.
|
||||
<strong>Password setup in progress.</strong> Check your email for a confirmation link. After confirming your email, sign in below with your email and password.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
@@ -31,5 +31,6 @@ export interface IdentityOperationResult {
|
||||
success: boolean;
|
||||
error?: string;
|
||||
needsRelogin?: boolean;
|
||||
needsEmailConfirmation?: boolean;
|
||||
email?: string;
|
||||
}
|
||||
|
||||
@@ -76,12 +76,22 @@ serve(async (req) => {
|
||||
</ul>
|
||||
|
||||
<h3>🔐 Complete Your Setup</h3>
|
||||
<p>To activate your password authentication, please sign in with your new credentials:</p>
|
||||
<p><strong>Important:</strong> To complete your password setup, you need to confirm your email address.</p>
|
||||
|
||||
<a href="${siteUrl}/auth?email=${encodeURIComponent(email)}" class="button">
|
||||
Sign In Now
|
||||
<ol style="padding-left: 20px; margin: 15px 0; line-height: 1.8;">
|
||||
<li style="margin-bottom: 8px;">Check your inbox for a <strong>confirmation email</strong> from ThrillWiki</li>
|
||||
<li style="margin-bottom: 8px;">Click the confirmation link in that email</li>
|
||||
<li style="margin-bottom: 8px;">Return to the sign-in page and log in with your email and password</li>
|
||||
</ol>
|
||||
|
||||
<a href="${siteUrl}/auth?email=${encodeURIComponent(email)}&message=complete-password-setup" class="button">
|
||||
Go to Sign In Page
|
||||
</a>
|
||||
|
||||
<p style="margin-top: 15px; font-size: 14px; color: #666;">
|
||||
<strong>Note:</strong> You must confirm your email before you can sign in with your password.
|
||||
</p>
|
||||
|
||||
<div class="security-notice">
|
||||
<strong>⚠️ Security Notice</strong><br>
|
||||
If you didn't add a password to your account, please contact our support team immediately at <strong>support@thrillwiki.com</strong>
|
||||
|
||||
Reference in New Issue
Block a user