Fix: Implement automatic background identity creation

This commit is contained in:
gpt-engineer-app[bot]
2025-10-14 15:12:44 +00:00
parent 41757096c8
commit 92943f2692
2 changed files with 51 additions and 52 deletions

View File

@@ -225,14 +225,7 @@ export function SecurityTab() {
{hasPassword ? ( {hasPassword ? (
<>Update your password to keep your account secure.</> <>Update your password to keep your account secure.</>
) : ( ) : (
<> <>Add password authentication to your account for increased security and backup access.</>
Add password authentication to your account for increased security and backup access.
{identities.length > 0 && (
<span className="block mt-2 text-amber-600 dark:text-amber-400">
If you've previously set a password but don't see it here, click "Add Password" to re-verify your authentication.
</span>
)}
</>
)} )}
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>

View File

@@ -189,7 +189,7 @@ async function waitForEmailProvider(maxRetries = 6): Promise<boolean> {
/** /**
* Add password authentication to an OAuth-only account * Add password authentication to an OAuth-only account
* Also handles re-creating email identity for orphaned passwords * Automatically creates email identity by signing in immediately after setting password
*/ */
export async function addPasswordToAccount( export async function addPasswordToAccount(
password: string password: string
@@ -203,64 +203,70 @@ export async function addPasswordToAccount(
}; };
} }
// Update user with password (works for both new and existing passwords) const { data: { user } } = await supabase.auth.getUser();
const { error } = await supabase.auth.updateUser({ password }); if (!user?.email) {
return {
if (error) throw error; success: false,
error: 'No email address found on your account'
// Force session refresh to sync identity state };
const { error: refreshError } = await supabase.auth.refreshSession();
if (refreshError) {
console.warn('[IdentityService] Session refresh failed:', refreshError);
} }
// Wait for email provider to be created // Step 1: Update password
const emailCreated = await waitForEmailProvider(); console.log('[IdentityService] Setting password for user');
const { error: updateError } = await supabase.auth.updateUser({ password });
if (updateError) throw updateError;
if (!emailCreated) { // Step 2: IMMEDIATELY attempt sign-in to force identity creation
// Password was set but identity verification failed // This is the ONLY reliable way to create the email identity
// Try one more aggressive approach: sign in with the new password console.log('[IdentityService] Attempting sign-in to create email identity');
console.log('[IdentityService] Attempting sign-in to trigger identity creation'); const { error: signInError } = await supabase.auth.signInWithPassword({
email: user.email,
password: password
});
if (signInError) {
// Sign-in failed, but password was set
console.error('[IdentityService] Sign-in failed:', signInError);
const { data: { user } } = await supabase.auth.getUser(); // Check if it's just an email confirmation issue
if (user?.email) { if (signInError.message?.includes('Email not confirmed')) {
// Attempt to sign in (this might create the identity) // Password is set, identity might be created, just needs confirmation
const { error: signInError } = await supabase.auth.signInWithPassword({ console.log('[IdentityService] Email confirmation required, checking identity');
email: user.email, const emailCreated = await waitForEmailProvider(3);
password: password if (emailCreated) {
}); await logIdentityChange(user.id, 'password_added', {
method: 'oauth_fallback_unconfirmed'
if (!signInError) { });
// Sign-in successful, check identities again return { success: true };
const retriedEmailCreated = await waitForEmailProvider(2); // Quick retry
if (retriedEmailCreated) {
console.log('[IdentityService] Email provider created after sign-in');
// Log audit event
await logIdentityChange(user.id, 'password_added', {
method: 'oauth_fallback_with_signin_retry'
});
return { success: true };
}
} }
} }
return { return {
success: false, success: false,
error: 'Password was set but email provider verification failed. Please refresh the page and try signing in with your email and password.' error: `Password was set but authentication failed: ${signInError.message}. Please try signing out and signing back in with your email and password.`
}; };
} }
// Log audit event // Step 3: Verify identity was created
const { data: { user } } = await supabase.auth.getUser(); console.log('[IdentityService] Sign-in successful, verifying identity creation');
if (user) { const emailCreated = await waitForEmailProvider(4);
await logIdentityChange(user.id, 'password_added', {
method: 'oauth_fallback' if (!emailCreated) {
}); console.error('[IdentityService] Identity not found after successful sign-in');
return {
success: false,
error: 'Password authentication was successful but identity verification failed. Please refresh the page.'
};
} }
// Step 4: Log success
console.log('[IdentityService] Email identity successfully created');
await logIdentityChange(user.id, 'password_added', {
method: 'oauth_fallback_signin'
});
return { success: true }; return { success: true };
} catch (error: any) { } catch (error: any) {
console.error('[IdentityService] Failed to add password:', error); console.error('[IdentityService] Failed to add password:', error);
return { return {