mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 15:11:13 -05:00
Fix: Improve password verification and sync
This commit is contained in:
@@ -5,7 +5,7 @@ import { Separator } from '@/components/ui/separator';
|
|||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { Shield, Key, Smartphone, Globe, Loader2 } from 'lucide-react';
|
import { Shield, Key, Smartphone, Globe, Loader2, RefreshCw } from 'lucide-react';
|
||||||
import { TOTPSetup } from '@/components/auth/TOTPSetup';
|
import { TOTPSetup } from '@/components/auth/TOTPSetup';
|
||||||
import { GoogleIcon } from '@/components/icons/GoogleIcon';
|
import { GoogleIcon } from '@/components/icons/GoogleIcon';
|
||||||
import { DiscordIcon } from '@/components/icons/DiscordIcon';
|
import { DiscordIcon } from '@/components/icons/DiscordIcon';
|
||||||
@@ -127,6 +127,17 @@ export function SecurityTab() {
|
|||||||
// Refresh identities - should now include email provider after waiting in addPasswordToAccount
|
// Refresh identities - should now include email provider after waiting in addPasswordToAccount
|
||||||
await loadIdentities();
|
await loadIdentities();
|
||||||
|
|
||||||
|
// Check if password was actually verified
|
||||||
|
if (!hasPassword && addPasswordMode === 'standalone') {
|
||||||
|
// Password addition failed verification
|
||||||
|
toast({
|
||||||
|
title: 'Verification Failed',
|
||||||
|
description: 'Password was set but identity verification failed. Please refresh the page and check your Security settings.',
|
||||||
|
variant: 'destructive'
|
||||||
|
});
|
||||||
|
return; // Don't close dialog or clear provider
|
||||||
|
}
|
||||||
|
|
||||||
if (addPasswordMode === 'disconnect' && passwordSetupProvider) {
|
if (addPasswordMode === 'disconnect' && passwordSetupProvider) {
|
||||||
toast({
|
toast({
|
||||||
title: "Password Set",
|
title: "Password Set",
|
||||||
@@ -146,6 +157,19 @@ export function SecurityTab() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRefreshIdentities = async () => {
|
||||||
|
setLoadingIdentities(true);
|
||||||
|
await loadIdentities();
|
||||||
|
setLoadingIdentities(false);
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: 'Identities Refreshed',
|
||||||
|
description: hasPassword
|
||||||
|
? 'Your password authentication is now active.'
|
||||||
|
: 'Identity status updated.',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleAddPassword = () => {
|
const handleAddPassword = () => {
|
||||||
setAddPasswordMode('standalone');
|
setAddPasswordMode('standalone');
|
||||||
setPasswordSetupProvider('google' as OAuthProvider);
|
setPasswordSetupProvider('google' as OAuthProvider);
|
||||||
@@ -206,6 +230,7 @@ export function SecurityTab() {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
{hasPassword ? (
|
{hasPassword ? (
|
||||||
<Button onClick={() => setPasswordDialogOpen(true)}>
|
<Button onClick={() => setPasswordDialogOpen(true)}>
|
||||||
Change Password
|
Change Password
|
||||||
@@ -222,6 +247,16 @@ export function SecurityTab() {
|
|||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={handleRefreshIdentities}
|
||||||
|
disabled={loadingIdentities}
|
||||||
|
title="Refresh identity status"
|
||||||
|
>
|
||||||
|
<RefreshCw className={`h-4 w-4 ${loadingIdentities ? 'animate-spin' : ''}`} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -164,22 +164,26 @@ export async function connectIdentity(
|
|||||||
* Wait for email provider to be created after password addition
|
* Wait for email provider to be created after password addition
|
||||||
* Supabase takes time to create the email identity, so we poll with retries
|
* Supabase takes time to create the email identity, so we poll with retries
|
||||||
*/
|
*/
|
||||||
async function waitForEmailProvider(maxRetries = 4): Promise<boolean> {
|
async function waitForEmailProvider(maxRetries = 6): Promise<boolean> {
|
||||||
const delays = [500, 1000, 1500, 2000]; // Exponential backoff
|
const delays = [500, 1000, 1500, 2000, 2500, 3000]; // ~10.5s total
|
||||||
|
|
||||||
for (let i = 0; i < maxRetries; i++) {
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
const identities = await getUserIdentities();
|
const identities = await getUserIdentities();
|
||||||
const hasEmail = identities.some(id => id.provider === 'email');
|
const hasEmail = identities.some(id => id.provider === 'email');
|
||||||
|
|
||||||
if (hasEmail) {
|
if (hasEmail) {
|
||||||
|
console.log(`[IdentityService] Email provider found after ${i + 1} attempts`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`[IdentityService] Email provider not found, attempt ${i + 1}/${maxRetries}`);
|
||||||
|
|
||||||
if (i < maxRetries - 1) {
|
if (i < maxRetries - 1) {
|
||||||
await new Promise(resolve => setTimeout(resolve, delays[i]));
|
await new Promise(resolve => setTimeout(resolve, delays[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.error('[IdentityService] Email provider not found after max retries');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +217,10 @@ export async function addPasswordToAccount(
|
|||||||
const emailCreated = await waitForEmailProvider();
|
const emailCreated = await waitForEmailProvider();
|
||||||
|
|
||||||
if (!emailCreated) {
|
if (!emailCreated) {
|
||||||
console.warn('[IdentityService] Email provider not found after password addition');
|
return {
|
||||||
|
success: false,
|
||||||
|
error: 'Password was set but email provider verification failed. Please refresh the page and try signing in with your email and password.'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log audit event
|
// Log audit event
|
||||||
|
|||||||
Reference in New Issue
Block a user