Refactor identity management

This commit is contained in:
gpt-engineer-app[bot]
2025-10-14 17:38:18 +00:00
parent 5c075c363e
commit a255442616
5 changed files with 21 additions and 456 deletions

View File

@@ -16,8 +16,7 @@ import {
checkDisconnectSafety,
disconnectIdentity,
connectIdentity,
hasOrphanedPassword,
triggerOrphanedPasswordConfirmation
addPasswordToAccount
} from '@/lib/identityService';
import type { UserIdentity, OAuthProvider } from '@/types/identity';
import { toast as sonnerToast } from '@/components/ui/sonner';
@@ -33,26 +32,12 @@ export function SecurityTab() {
const [disconnectingProvider, setDisconnectingProvider] = useState<OAuthProvider | null>(null);
const [hasPassword, setHasPassword] = useState(false);
const [addingPassword, setAddingPassword] = useState(false);
const [showOrphanedPasswordOption, setShowOrphanedPasswordOption] = useState(false);
// Load user identities on mount
useEffect(() => {
loadIdentities();
}, []);
useEffect(() => {
const checkOrphanedPassword = async () => {
if (!hasPassword) {
const isOrphaned = await hasOrphanedPassword();
setShowOrphanedPasswordOption(isOrphaned);
}
};
if (!loadingIdentities) {
checkOrphanedPassword();
}
}, [hasPassword, loadingIdentities]);
const loadIdentities = async () => {
try {
setLoadingIdentities(true);
@@ -140,50 +125,11 @@ export function SecurityTab() {
const handleAddPassword = async () => {
setAddingPassword(true);
const { data: { user } } = await supabase.auth.getUser();
if (!user?.email) {
toast({
title: "No Email Found",
description: "Your account doesn't have an email address associated with it.",
variant: "destructive"
});
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: "Failed to Send Email",
description: error.message,
variant: "destructive"
});
} else {
sonnerToast.success("Password Reset Email Sent!", {
description: "Check your email for a password reset link. Click it to set your password on ThrillWiki.",
duration: 15000,
});
}
setAddingPassword(false);
};
const handleSendConfirmationEmail = async () => {
setAddingPassword(true);
const result = await triggerOrphanedPasswordConfirmation('security_settings');
const result = await addPasswordToAccount();
if (result.success) {
sonnerToast.success("Reset Email Sent!", {
description: "Check your email for a password reset link from Supabase to activate your password authentication. You'll also receive a notification email from ThrillWiki.",
sonnerToast.success("Password Setup Email Sent!", {
description: `Check ${result.email} for a password reset link. Click it to set your password.`,
duration: 15000,
});
} else {
@@ -247,39 +193,16 @@ export function SecurityTab() {
Change Password
</Button>
) : (
<>
<Button onClick={handleAddPassword} disabled={addingPassword}>
{addingPassword ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Sending Email...
</>
) : (
'Add Password'
)}
</Button>
{showOrphanedPasswordOption && (
<Button
variant="outline"
onClick={handleSendConfirmationEmail}
disabled={addingPassword}
className="w-full"
>
{addingPassword ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Sending Email...
</>
) : (
<>
<Key className="w-4 h-4 mr-2" />
Send Confirmation Email
</>
)}
</Button>
<Button onClick={handleAddPassword} disabled={addingPassword}>
{addingPassword ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Sending Email...
</>
) : (
'Add Password'
)}
</>
</Button>
)}
</CardContent>
</Card>