mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 12:31:26 -05:00
feat: Allow OAuth users to add passwords
This commit is contained in:
@@ -26,6 +26,8 @@ export function SecurityTab() {
|
||||
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');
|
||||
|
||||
// Load user identities on mount
|
||||
useEffect(() => {
|
||||
@@ -33,10 +35,24 @@ export function SecurityTab() {
|
||||
}, []);
|
||||
|
||||
const loadIdentities = async () => {
|
||||
setLoadingIdentities(true);
|
||||
const fetchedIdentities = await getUserIdentities();
|
||||
setIdentities(fetchedIdentities);
|
||||
setLoadingIdentities(false);
|
||||
try {
|
||||
setLoadingIdentities(true);
|
||||
const fetchedIdentities = await getUserIdentities();
|
||||
setIdentities(fetchedIdentities);
|
||||
|
||||
// Check if user has email/password auth
|
||||
const hasEmailProvider = fetchedIdentities.some(i => i.provider === 'email');
|
||||
setHasPassword(hasEmailProvider);
|
||||
} catch (error) {
|
||||
console.error('Failed to load identities:', error);
|
||||
toast({
|
||||
title: 'Error',
|
||||
description: 'Failed to load connected accounts',
|
||||
variant: 'destructive',
|
||||
});
|
||||
} finally {
|
||||
setLoadingIdentities(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSocialLogin = async (provider: OAuthProvider) => {
|
||||
@@ -63,6 +79,7 @@ export function SecurityTab() {
|
||||
if (!safetyCheck.canDisconnect) {
|
||||
if (safetyCheck.reason === 'no_password_backup') {
|
||||
// Show password setup dialog
|
||||
setAddPasswordMode('disconnect');
|
||||
setPasswordSetupProvider(provider);
|
||||
toast({
|
||||
title: "Password Required",
|
||||
@@ -103,21 +120,30 @@ export function SecurityTab() {
|
||||
};
|
||||
|
||||
const handlePasswordSetupSuccess = async () => {
|
||||
toast({
|
||||
title: "Password Set",
|
||||
description: "You can now disconnect your social login."
|
||||
});
|
||||
|
||||
// Refresh identities to show email provider
|
||||
await loadIdentities();
|
||||
|
||||
// Proceed with disconnect
|
||||
if (passwordSetupProvider) {
|
||||
if (addPasswordMode === 'disconnect' && passwordSetupProvider) {
|
||||
toast({
|
||||
title: "Password Set",
|
||||
description: "You can now disconnect your social login."
|
||||
});
|
||||
await handleUnlinkSocial(passwordSetupProvider);
|
||||
setPasswordSetupProvider(null);
|
||||
} else {
|
||||
toast({
|
||||
title: 'Password Added',
|
||||
description: 'You can now sign in using your email and password.',
|
||||
});
|
||||
setPasswordSetupProvider(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddPassword = () => {
|
||||
setAddPasswordMode('standalone');
|
||||
setPasswordSetupProvider('google' as OAuthProvider);
|
||||
};
|
||||
|
||||
// Get connected accounts with identity data
|
||||
const connectedAccounts = [
|
||||
{
|
||||
@@ -150,27 +176,38 @@ export function SecurityTab() {
|
||||
onOpenChange={(open) => !open && setPasswordSetupProvider(null)}
|
||||
onSuccess={handlePasswordSetupSuccess}
|
||||
provider={passwordSetupProvider}
|
||||
mode={addPasswordMode}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="space-y-8">
|
||||
{/* Change Password */}
|
||||
{/* Password Section - Conditional based on auth method */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Key className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Change Password</h3>
|
||||
<h3 className="text-lg font-medium">{hasPassword ? 'Change Password' : 'Add Password'}</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardDescription>
|
||||
Update your password to keep your account secure. {user?.identities?.some(i => i.provider === 'totp') && 'Two-factor authentication will be required.'}
|
||||
{hasPassword ? (
|
||||
<>Update your password to keep your account secure. {user?.identities?.some(i => i.provider === 'totp') && 'Two-factor authentication will be required.'}</>
|
||||
) : (
|
||||
'Add password authentication to your account for increased security and backup access.'
|
||||
)}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Button onClick={() => setPasswordDialogOpen(true)}>
|
||||
Change Password
|
||||
</Button>
|
||||
{hasPassword ? (
|
||||
<Button onClick={() => setPasswordDialogOpen(true)}>
|
||||
Change Password
|
||||
</Button>
|
||||
) : (
|
||||
<Button onClick={handleAddPassword}>
|
||||
Add Password
|
||||
</Button>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user