mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 12:11:21 -05:00
Fix password state sync for OAuth users
This commit is contained in:
@@ -28,6 +28,7 @@ export function SecurityTab() {
|
|||||||
const [passwordSetupProvider, setPasswordSetupProvider] = useState<OAuthProvider | null>(null);
|
const [passwordSetupProvider, setPasswordSetupProvider] = useState<OAuthProvider | null>(null);
|
||||||
const [hasPassword, setHasPassword] = useState(false);
|
const [hasPassword, setHasPassword] = useState(false);
|
||||||
const [addPasswordMode, setAddPasswordMode] = useState<'standalone' | 'disconnect'>('standalone');
|
const [addPasswordMode, setAddPasswordMode] = useState<'standalone' | 'disconnect'>('standalone');
|
||||||
|
const [addingPassword, setAddingPassword] = useState(false);
|
||||||
|
|
||||||
// Load user identities on mount
|
// Load user identities on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -120,7 +121,10 @@ export function SecurityTab() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePasswordSetupSuccess = async () => {
|
const handlePasswordSetupSuccess = async () => {
|
||||||
// Refresh identities to show email provider
|
setAddingPassword(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Refresh identities - should now include email provider after waiting in addPasswordToAccount
|
||||||
await loadIdentities();
|
await loadIdentities();
|
||||||
|
|
||||||
if (addPasswordMode === 'disconnect' && passwordSetupProvider) {
|
if (addPasswordMode === 'disconnect' && passwordSetupProvider) {
|
||||||
@@ -137,6 +141,9 @@ export function SecurityTab() {
|
|||||||
});
|
});
|
||||||
setPasswordSetupProvider(null);
|
setPasswordSetupProvider(null);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
setAddingPassword(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddPassword = () => {
|
const handleAddPassword = () => {
|
||||||
@@ -204,8 +211,15 @@ export function SecurityTab() {
|
|||||||
Change Password
|
Change Password
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button onClick={handleAddPassword}>
|
<Button onClick={handleAddPassword} disabled={addingPassword}>
|
||||||
Add Password
|
{addingPassword ? (
|
||||||
|
<>
|
||||||
|
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
||||||
|
Adding Password...
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
'Add Password'
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -160,6 +160,29 @@ export async function connectIdentity(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for email provider to be created after password addition
|
||||||
|
* Supabase takes time to create the email identity, so we poll with retries
|
||||||
|
*/
|
||||||
|
async function waitForEmailProvider(maxRetries = 4): Promise<boolean> {
|
||||||
|
const delays = [500, 1000, 1500, 2000]; // Exponential backoff
|
||||||
|
|
||||||
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
|
const identities = await getUserIdentities();
|
||||||
|
const hasEmail = identities.some(id => id.provider === 'email');
|
||||||
|
|
||||||
|
if (hasEmail) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < maxRetries - 1) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delays[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add password authentication to an OAuth-only account
|
* Add password authentication to an OAuth-only account
|
||||||
*/
|
*/
|
||||||
@@ -180,6 +203,19 @@ export async function addPasswordToAccount(
|
|||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
const emailCreated = await waitForEmailProvider();
|
||||||
|
|
||||||
|
if (!emailCreated) {
|
||||||
|
console.warn('[IdentityService] Email provider not found after password addition');
|
||||||
|
}
|
||||||
|
|
||||||
// Log audit event
|
// Log audit event
|
||||||
const { data: { user } } = await supabase.auth.getUser();
|
const { data: { user } } = await supabase.auth.getUser();
|
||||||
if (user) {
|
if (user) {
|
||||||
|
|||||||
Reference in New Issue
Block a user