diff --git a/src/components/admin/VersionCleanupSettings.tsx b/src/components/admin/VersionCleanupSettings.tsx index e7ee70a5..5ef4dd30 100644 --- a/src/components/admin/VersionCleanupSettings.tsx +++ b/src/components/admin/VersionCleanupSettings.tsx @@ -68,7 +68,15 @@ export function VersionCleanupSettings() { const handleSaveRetention = async () => { setIsSaving(true); + const oldRetentionDays = retentionDays; try { + // Get current value for audit log + const { data: currentSetting } = await supabase + .from('admin_settings') + .select('setting_value') + .eq('setting_key', 'version_retention_days') + .single(); + const { error } = await supabase .from('admin_settings') .update({ setting_value: retentionDays.toString() }) @@ -76,6 +84,14 @@ export function VersionCleanupSettings() { if (error) throw error; + // Log to audit trail + const { logAdminAction } = await import('@/lib/adminActionAuditHelpers'); + await logAdminAction('version_cleanup_config_changed', { + setting_key: 'version_retention_days', + old_value: currentSetting?.setting_value, + new_value: retentionDays, + }); + toast({ title: 'Settings Saved', description: 'Retention period updated successfully' diff --git a/src/hooks/useAdminSettings.ts b/src/hooks/useAdminSettings.ts index f77a8f67..c5842217 100644 --- a/src/hooks/useAdminSettings.ts +++ b/src/hooks/useAdminSettings.ts @@ -49,6 +49,10 @@ export function useAdminSettings() { const updateSettingMutation = useMutation({ mutationFn: async ({ key, value }: { key: string; value: unknown }) => { + // Get old value for audit log + const oldSetting = settings?.find(s => s.setting_key === key); + const oldValue = oldSetting?.setting_value; + const { error } = await supabase .from('admin_settings') .update({ @@ -59,10 +63,19 @@ export function useAdminSettings() { .eq('setting_key', key); if (error) throw error; - return { key, value }; + return { key, value, oldValue }; }, - onSuccess: () => { + onSuccess: async (data) => { queryClient.invalidateQueries({ queryKey: ['admin-settings'] }); + + // Log to audit trail + const { logAdminAction } = await import('@/lib/adminActionAuditHelpers'); + await logAdminAction('admin_setting_updated', { + setting_key: data.key, + old_value: data.oldValue, + new_value: data.value, + }); + toast({ title: "Setting Updated", description: "The setting has been saved successfully.", diff --git a/src/hooks/useRateLimitAlerts.ts b/src/hooks/useRateLimitAlerts.ts index afdc29cd..68a4673d 100644 --- a/src/hooks/useRateLimitAlerts.ts +++ b/src/hooks/useRateLimitAlerts.ts @@ -80,6 +80,13 @@ export function useUpdateAlertConfig() { return useMutation({ mutationFn: async ({ id, updates }: { id: string; updates: Partial }) => { + // Fetch old config for audit log + const { data: oldConfig } = await supabase + .from('rate_limit_alert_config') + .select('*') + .eq('id', id) + .single(); + const { data, error } = await supabase .from('rate_limit_alert_config') .update(updates) @@ -88,10 +95,23 @@ export function useUpdateAlertConfig() { .single(); if (error) throw error; - return data; + return { data, oldConfig }; }, - onSuccess: () => { + onSuccess: async ({ data, oldConfig }) => { queryClient.invalidateQueries({ queryKey: ['rateLimitAlertConfigs'] }); + + // Log to audit trail + const { logAdminAction } = await import('@/lib/adminActionAuditHelpers'); + await logAdminAction('rate_limit_config_updated', { + config_id: data.id, + metric_type: data.metric_type, + old_threshold: oldConfig?.threshold_value, + new_threshold: data.threshold_value, + old_enabled: oldConfig?.enabled, + new_enabled: data.enabled, + function_name: data.function_name, + }); + toast.success('Alert configuration updated'); }, onError: (error) => { @@ -114,8 +134,20 @@ export function useCreateAlertConfig() { if (error) throw error; return data; }, - onSuccess: () => { + onSuccess: async (data) => { queryClient.invalidateQueries({ queryKey: ['rateLimitAlertConfigs'] }); + + // Log to audit trail + const { logAdminAction } = await import('@/lib/adminActionAuditHelpers'); + await logAdminAction('rate_limit_config_created', { + config_id: data.id, + metric_type: data.metric_type, + threshold_value: data.threshold_value, + time_window_ms: data.time_window_ms, + function_name: data.function_name, + enabled: data.enabled, + }); + toast.success('Alert configuration created'); }, onError: (error) => { @@ -129,15 +161,36 @@ export function useDeleteAlertConfig() { return useMutation({ mutationFn: async (id: string) => { + // Fetch config details before deletion for audit log + const { data: config } = await supabase + .from('rate_limit_alert_config') + .select('*') + .eq('id', id) + .single(); + const { error } = await supabase .from('rate_limit_alert_config') .delete() .eq('id', id); if (error) throw error; + return config; }, - onSuccess: () => { + onSuccess: async (config) => { queryClient.invalidateQueries({ queryKey: ['rateLimitAlertConfigs'] }); + + // Log to audit trail + if (config) { + const { logAdminAction } = await import('@/lib/adminActionAuditHelpers'); + await logAdminAction('rate_limit_config_deleted', { + config_id: config.id, + metric_type: config.metric_type, + threshold_value: config.threshold_value, + time_window_ms: config.time_window_ms, + function_name: config.function_name, + }); + } + toast.success('Alert configuration deleted'); }, onError: (error) => {