Enable RLS on rate limits table

This commit is contained in:
gpt-engineer-app[bot]
2025-10-14 19:24:54 +00:00
parent fd17234b67
commit 0a325d7c37
11 changed files with 821 additions and 252 deletions

View File

@@ -4,7 +4,7 @@ import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import { Badge } from '@/components/ui/badge';
import { useToast } from '@/hooks/use-toast';
import { handleError, handleSuccess } from '@/lib/errorHandler';
import { useAuth } from '@/hooks/useAuth';
import { Shield, Key, Smartphone, Globe, Loader2, Monitor, Tablet, Trash2 } from 'lucide-react';
import { format } from 'date-fns';
@@ -20,7 +20,6 @@ import {
addPasswordToAccount
} from '@/lib/identityService';
import type { UserIdentity, OAuthProvider } from '@/types/identity';
import { toast as sonnerToast } from '@/components/ui/sonner';
import { supabase } from '@/integrations/supabase/client';
interface AuthSession {
@@ -36,7 +35,6 @@ interface AuthSession {
export function SecurityTab() {
const { user } = useAuth();
const { toast } = useToast();
const navigate = useNavigate();
const [passwordDialogOpen, setPasswordDialogOpen] = useState(false);
const [identities, setIdentities] = useState<UserIdentity[]>([]);
@@ -64,11 +62,7 @@ export function SecurityTab() {
setHasPassword(hasEmailProvider);
} catch (error) {
console.error('Failed to load identities:', error);
toast({
title: 'Error',
description: 'Failed to load connected accounts',
variant: 'destructive',
});
handleError(error, { action: 'Load connected accounts' });
} finally {
setLoadingIdentities(false);
}
@@ -79,32 +73,15 @@ export function SecurityTab() {
const result = await connectIdentity(provider, '/settings?tab=security');
if (!result.success) {
// Handle rate limiting
if (result.error?.includes('rate limit')) {
toast({
title: 'Too Many Attempts',
description: 'Please wait a few minutes before trying again.',
variant: 'destructive'
});
} else {
toast({
title: 'Connection Failed',
description: result.error,
variant: 'destructive'
});
}
handleError(
new Error(result.error || 'Connection failed'),
{ action: `Connect ${provider} account` }
);
} else {
toast({
title: 'Redirecting...',
description: `Connecting your ${provider} account...`
});
handleSuccess('Redirecting...', `Connecting your ${provider} account...`);
}
} catch (error: any) {
toast({
title: 'Connection Error',
description: error.message || 'Failed to connect account',
variant: 'destructive'
});
} catch (error) {
handleError(error, { action: `Connect ${provider} account` });
}
};
@@ -116,20 +93,18 @@ export function SecurityTab() {
if (safetyCheck.reason === 'no_password_backup') {
// Trigger password reset flow first
await handleAddPassword();
toast({
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
});
handleSuccess(
"Password Required First",
"Check your email for a password reset link. Once you've set a password, you can disconnect your social login."
);
return;
}
if (safetyCheck.reason === 'last_identity') {
toast({
title: "Cannot Disconnect",
description: "You cannot disconnect your only login method. Please add another authentication method first.",
variant: "destructive"
});
handleError(
new Error("You cannot disconnect your only login method"),
{ action: "Disconnect social login" }
);
return;
}
}
@@ -141,16 +116,12 @@ export function SecurityTab() {
if (result.success) {
await loadIdentities(); // Refresh identities list
toast({
title: "Disconnected",
description: `Your ${provider} account has been successfully disconnected.`
});
handleSuccess("Disconnected", `Your ${provider} account has been successfully disconnected.`);
} else {
toast({
title: "Disconnect Failed",
description: result.error,
variant: "destructive"
});
handleError(
new Error(result.error || 'Disconnect failed'),
{ action: `Disconnect ${provider} account` }
);
}
};
@@ -160,16 +131,15 @@ export function SecurityTab() {
const result = await addPasswordToAccount();
if (result.success) {
sonnerToast.success("Password Setup Email Sent!", {
description: `Check ${result.email} for a password reset link. Click it to set your password.`,
duration: 15000,
});
handleSuccess(
"Password Setup Email Sent!",
`Check ${result.email} for a password reset link. Click it to set your password.`
);
} else {
toast({
title: "Failed to Send Email",
description: result.error,
variant: "destructive"
});
handleError(
new Error(result.error || 'Failed to send email'),
{ action: 'Send password setup email' }
);
}
setAddingPassword(false);
@@ -182,11 +152,7 @@ export function SecurityTab() {
if (error) {
console.error('Error fetching sessions:', error);
toast({
title: 'Error',
description: 'Failed to load sessions',
variant: 'destructive'
});
handleError(error, { action: 'Load sessions' });
} else {
setSessions(data || []);
}
@@ -197,16 +163,9 @@ export function SecurityTab() {
const { error } = await supabase.rpc('revoke_my_session', { session_id: sessionId });
if (error) {
toast({
title: 'Error',
description: 'Failed to revoke session',
variant: 'destructive'
});
handleError(error, { action: 'Revoke session' });
} else {
toast({
title: 'Success',
description: 'Session revoked successfully'
});
handleSuccess('Success', 'Session revoked successfully');
fetchSessions();
}
};
@@ -254,10 +213,7 @@ export function SecurityTab() {
open={passwordDialogOpen}
onOpenChange={setPasswordDialogOpen}
onSuccess={() => {
toast({
title: 'Password updated',
description: 'Your password has been successfully changed.'
});
handleSuccess('Password updated', 'Your password has been successfully changed.');
}}
/>