mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:31:13 -05:00
Refactor: Simplify Add Password flow
This commit is contained in:
@@ -11,7 +11,6 @@ import { TOTPSetup } from '@/components/auth/TOTPSetup';
|
||||
import { GoogleIcon } from '@/components/icons/GoogleIcon';
|
||||
import { DiscordIcon } from '@/components/icons/DiscordIcon';
|
||||
import { PasswordUpdateDialog } from './PasswordUpdateDialog';
|
||||
import { PasswordSetupDialog } from '@/components/auth/PasswordSetupDialog';
|
||||
import {
|
||||
getUserIdentities,
|
||||
checkDisconnectSafety,
|
||||
@@ -22,6 +21,8 @@ import {
|
||||
} from '@/lib/identityService';
|
||||
import type { UserIdentity, OAuthProvider } from '@/types/identity';
|
||||
import { toast as sonnerToast } from '@/components/ui/sonner';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
|
||||
export function SecurityTab() {
|
||||
const { user } = useAuth();
|
||||
const { toast } = useToast();
|
||||
@@ -30,9 +31,7 @@ export function SecurityTab() {
|
||||
const [identities, setIdentities] = useState<UserIdentity[]>([]);
|
||||
const [loadingIdentities, setLoadingIdentities] = useState(true);
|
||||
const [disconnectingProvider, setDisconnectingProvider] = useState<OAuthProvider | null>(null);
|
||||
const [passwordSetupProvider, setPasswordSetupProvider] = useState<OAuthProvider | null>(null);
|
||||
const [hasPassword, setHasPassword] = useState(false);
|
||||
const [addPasswordMode, setAddPasswordMode] = useState<'standalone' | 'disconnect'>('standalone');
|
||||
const [addingPassword, setAddingPassword] = useState(false);
|
||||
const [showOrphanedPasswordOption, setShowOrphanedPasswordOption] = useState(false);
|
||||
|
||||
@@ -98,13 +97,12 @@ export function SecurityTab() {
|
||||
|
||||
if (!safetyCheck.canDisconnect) {
|
||||
if (safetyCheck.reason === 'no_password_backup') {
|
||||
// Show password setup dialog
|
||||
setAddPasswordMode('disconnect');
|
||||
setPasswordSetupProvider(provider);
|
||||
// Trigger password reset flow first
|
||||
await handleAddPassword();
|
||||
toast({
|
||||
title: "Password Required",
|
||||
description: "Set a password before disconnecting your last social login to maintain account access.",
|
||||
variant: "default"
|
||||
title: "Password Required First",
|
||||
description: "Check your email for a password reset link. Once you've set a password, you can disconnect your social login.",
|
||||
duration: 10000
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -139,42 +137,43 @@ export function SecurityTab() {
|
||||
}
|
||||
};
|
||||
|
||||
const handlePasswordSetupSuccess = (email?: string, needsConfirmation?: boolean) => {
|
||||
if (email && needsConfirmation) {
|
||||
// Password setup initiated via reset flow
|
||||
const handleAddPassword = async () => {
|
||||
setAddingPassword(true);
|
||||
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
|
||||
if (!user?.email) {
|
||||
toast({
|
||||
title: 'Check Your Email',
|
||||
description: "Click the password reset link from Supabase to complete setup. You'll receive two emails: one with the reset link, and one with instructions from ThrillWiki.",
|
||||
duration: 15000,
|
||||
title: "No Email Found",
|
||||
description: "Your account doesn't have an email address associated with it.",
|
||||
variant: "destructive"
|
||||
});
|
||||
|
||||
// Stay on settings page - user will complete setup via email link
|
||||
} else if (email) {
|
||||
// Fallback: direct password set (shouldn't happen with new flow)
|
||||
setAddingPassword(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger password reset email directly (no modal needed!)
|
||||
const { error } = await supabase.auth.resetPasswordForEmail(
|
||||
user.email,
|
||||
{
|
||||
redirectTo: `${window.location.origin}/auth/callback?action=password-setup-direct`
|
||||
}
|
||||
);
|
||||
|
||||
if (error) {
|
||||
toast({
|
||||
title: 'Password Set Successfully',
|
||||
description: 'You can now sign in with your email and password.',
|
||||
duration: 6000,
|
||||
title: "Failed to Send Email",
|
||||
description: error.message,
|
||||
variant: "destructive"
|
||||
});
|
||||
} else {
|
||||
// Normal password change flow (user already had email identity)
|
||||
setAddingPassword(true);
|
||||
|
||||
loadIdentities().then(() => {
|
||||
toast({
|
||||
title: 'Password Updated',
|
||||
description: 'Your password has been successfully updated.',
|
||||
});
|
||||
setPasswordSetupProvider(null);
|
||||
}).finally(() => {
|
||||
setAddingPassword(false);
|
||||
sonnerToast.success("Password Reset Email Sent!", {
|
||||
description: "Check your email for a password reset link from Supabase. Click the link to set your password. You'll also receive a notification email from ThrillWiki.",
|
||||
duration: 15000,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddPassword = () => {
|
||||
setAddPasswordMode('standalone');
|
||||
setPasswordSetupProvider('google' as OAuthProvider);
|
||||
|
||||
setAddingPassword(false);
|
||||
};
|
||||
|
||||
const handleSendConfirmationEmail = async () => {
|
||||
@@ -224,16 +223,6 @@ export function SecurityTab() {
|
||||
}}
|
||||
/>
|
||||
|
||||
{passwordSetupProvider && (
|
||||
<PasswordSetupDialog
|
||||
open={!!passwordSetupProvider}
|
||||
onOpenChange={(open) => !open && setPasswordSetupProvider(null)}
|
||||
onSuccess={(email, needsConfirmation) => handlePasswordSetupSuccess(email, needsConfirmation)}
|
||||
provider={passwordSetupProvider}
|
||||
mode={addPasswordMode}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="space-y-8">
|
||||
{/* Password Section - Conditional based on auth method */}
|
||||
<div className="space-y-4">
|
||||
@@ -263,7 +252,7 @@ export function SecurityTab() {
|
||||
{addingPassword ? (
|
||||
<>
|
||||
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
||||
Adding Password...
|
||||
Sending Email...
|
||||
</>
|
||||
) : (
|
||||
'Add Password'
|
||||
|
||||
@@ -36,6 +36,25 @@ export default function AuthCallback() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const action = urlParams.get('action');
|
||||
|
||||
if (action === 'password-setup-direct') {
|
||||
console.log('[AuthCallback] Processing password-setup-direct action (direct reset flow)');
|
||||
|
||||
// User set password via Supabase's hosted page
|
||||
// Email identity is already created automatically
|
||||
|
||||
toast({
|
||||
title: "Password Set Successfully!",
|
||||
description: "Your email identity has been created. You can now sign in with your email and password.",
|
||||
});
|
||||
|
||||
// Redirect to auth page for sign-in
|
||||
setTimeout(() => {
|
||||
navigate('/auth');
|
||||
}, 1500);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === 'password-setup') {
|
||||
console.log('[AuthCallback] Processing password-setup action');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user