66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
import { useQuery } from "@tanstack/react-query"
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@/components/ui/table"
|
|
import { securityService } from "@/services"
|
|
import type { RateLimitViolation } from "@/types/security.types"
|
|
|
|
export default function RateLimitsPage() {
|
|
const { data: violations, isLoading } = useQuery({
|
|
queryKey: ['admin', 'security', 'rate-limits'],
|
|
queryFn: () => securityService.getRateLimitViolations(7),
|
|
})
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h2 className="text-3xl font-bold">Rate Limit Violations</h2>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Recent Violations (Last 7 Days)</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{isLoading ? (
|
|
<div className="text-center py-8">Loading violations...</div>
|
|
) : (
|
|
<>
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>User</TableHead>
|
|
<TableHead>IP Address</TableHead>
|
|
<TableHead>Requests</TableHead>
|
|
<TableHead>Period</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{violations?.map((violation: RateLimitViolation) => (
|
|
<TableRow key={violation.id}>
|
|
<TableCell>{violation.userId || 'N/A'}</TableCell>
|
|
<TableCell className="font-mono text-sm">{violation.ipAddress}</TableCell>
|
|
<TableCell>{violation.requests}</TableCell>
|
|
<TableCell>{violation.period}</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
{violations?.length === 0 && (
|
|
<div className="text-center py-8 text-muted-foreground">
|
|
No rate limit violations found
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|
|
|