"use client"; import { useCallback, useEffect, useId, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; interface SecurityConfig { thresholds: { failedLoginsPerMinute: number; failedLoginsPerHour: number; rateLimitViolationsPerMinute: number; cspViolationsPerMinute: number; adminActionsPerHour: number; massDataAccessThreshold: number; suspiciousIPThreshold: number; }; alerting: { enabled: boolean; channels: string[]; suppressDuplicateMinutes: number; escalationTimeoutMinutes: number; }; retention: { alertRetentionDays: number; metricsRetentionDays: number; }; } interface SecurityConfigModalProps { onClose: () => void; onSave: () => void; } export function SecurityConfigModal({ onClose, onSave, }: SecurityConfigModalProps) { const [config, setConfig] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); // Generate unique IDs for form elements const failedLoginsPerMinuteId = useId(); const failedLoginsPerHourId = useId(); const rateLimitViolationsPerMinuteId = useId(); const cspViolationsPerMinuteId = useId(); const adminActionsPerHourId = useId(); const suspiciousIPThresholdId = useId(); const alertingEnabledId = useId(); const suppressDuplicateMinutesId = useId(); const escalationTimeoutMinutesId = useId(); const alertRetentionDaysId = useId(); const metricsRetentionDaysId = useId(); const loadConfig = useCallback(async () => { try { const response = await fetch("/api/admin/security-monitoring"); if (!response.ok) throw new Error("Failed to load config"); const data = await response.json(); setConfig(data.config); } catch (error) { console.error("Error loading config:", error); } finally { setLoading(false); } }, []); useEffect(() => { loadConfig(); }, [loadConfig]); const saveConfig = async () => { if (!config) return; setSaving(true); try { const response = await fetch("/api/admin/security-monitoring", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(config), }); if (!response.ok) throw new Error("Failed to save config"); onSave(); } catch (error) { console.error("Error saving config:", error); } finally { setSaving(false); } }; const updateThreshold = ( key: keyof SecurityConfig["thresholds"], value: number ) => { if (!config) return; setConfig({ ...config, thresholds: { ...config.thresholds, [key]: value, }, }); }; const updateAlerting = ( key: keyof SecurityConfig["alerting"], value: unknown ) => { if (!config) return; setConfig({ ...config, alerting: { ...config.alerting, [key]: value, }, }); }; const updateRetention = ( key: keyof SecurityConfig["retention"], value: number ) => { if (!config) return; setConfig({ ...config, retention: { ...config.retention, [key]: value, }, }); }; const toggleAlertChannel = (channel: string) => { if (!config) return; const channels = config.alerting.channels.includes(channel) ? config.alerting.channels.filter((c) => c !== channel) : [...config.alerting.channels, channel]; updateAlerting("channels", channels); }; if (loading) { return (
); } if (!config) { return ( Error Failed to load security configuration ); } return ( Security Monitoring Configuration Configure security monitoring thresholds, alerting, and data retention Thresholds Alerting Data Retention Detection Thresholds Configure when security alerts should be triggered
updateThreshold( "failedLoginsPerMinute", Number.parseInt(e.target.value) ) } />
updateThreshold( "failedLoginsPerHour", Number.parseInt(e.target.value) ) } />
updateThreshold( "rateLimitViolationsPerMinute", Number.parseInt(e.target.value) ) } />
updateThreshold( "cspViolationsPerMinute", Number.parseInt(e.target.value) ) } />
updateThreshold( "adminActionsPerHour", Number.parseInt(e.target.value) ) } />
updateThreshold( "suspiciousIPThreshold", Number.parseInt(e.target.value) ) } />
Alert Configuration Configure how and when alerts are sent
updateAlerting("enabled", checked) } />
{["EMAIL", "WEBHOOK", "SLACK", "DISCORD", "PAGERDUTY"].map( (channel) => ( toggleAlertChannel(channel)} > {channel} ) )}
updateAlerting( "suppressDuplicateMinutes", Number.parseInt(e.target.value) ) } />
updateAlerting( "escalationTimeoutMinutes", Number.parseInt(e.target.value) ) } />
Data Retention Configure how long security data is stored
updateRetention( "alertRetentionDays", Number.parseInt(e.target.value) ) } />
updateRetention( "metricsRetentionDays", Number.parseInt(e.target.value) ) } />

• Alert data includes security alerts and acknowledgments

• Metrics data includes aggregated security statistics

• Audit logs are retained separately according to audit policy

); }