mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 13:11:16 -05:00
Implement Phase 2 audit logging
Add audit logging for admin settings changes, rate limit config updates, anomaly detection config changes (skipped due to no UI), and version cleanup settings updates. Implement logging via central logAdminAction helper and integrate into AdminSettings, VersionCleanupSettings, and RateLimitAlerts mutations (create, update, delete).
This commit is contained in:
@@ -68,7 +68,15 @@ export function VersionCleanupSettings() {
|
|||||||
|
|
||||||
const handleSaveRetention = async () => {
|
const handleSaveRetention = async () => {
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
|
const oldRetentionDays = retentionDays;
|
||||||
try {
|
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
|
const { error } = await supabase
|
||||||
.from('admin_settings')
|
.from('admin_settings')
|
||||||
.update({ setting_value: retentionDays.toString() })
|
.update({ setting_value: retentionDays.toString() })
|
||||||
@@ -76,6 +84,14 @@ export function VersionCleanupSettings() {
|
|||||||
|
|
||||||
if (error) throw error;
|
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({
|
toast({
|
||||||
title: 'Settings Saved',
|
title: 'Settings Saved',
|
||||||
description: 'Retention period updated successfully'
|
description: 'Retention period updated successfully'
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ export function useAdminSettings() {
|
|||||||
|
|
||||||
const updateSettingMutation = useMutation({
|
const updateSettingMutation = useMutation({
|
||||||
mutationFn: async ({ key, value }: { key: string; value: unknown }) => {
|
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
|
const { error } = await supabase
|
||||||
.from('admin_settings')
|
.from('admin_settings')
|
||||||
.update({
|
.update({
|
||||||
@@ -59,10 +63,19 @@ export function useAdminSettings() {
|
|||||||
.eq('setting_key', key);
|
.eq('setting_key', key);
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
return { key, value };
|
return { key, value, oldValue };
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async (data) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['admin-settings'] });
|
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({
|
toast({
|
||||||
title: "Setting Updated",
|
title: "Setting Updated",
|
||||||
description: "The setting has been saved successfully.",
|
description: "The setting has been saved successfully.",
|
||||||
|
|||||||
@@ -80,6 +80,13 @@ export function useUpdateAlertConfig() {
|
|||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async ({ id, updates }: { id: string; updates: Partial<AlertConfig> }) => {
|
mutationFn: async ({ id, updates }: { id: string; updates: Partial<AlertConfig> }) => {
|
||||||
|
// 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
|
const { data, error } = await supabase
|
||||||
.from('rate_limit_alert_config')
|
.from('rate_limit_alert_config')
|
||||||
.update(updates)
|
.update(updates)
|
||||||
@@ -88,10 +95,23 @@ export function useUpdateAlertConfig() {
|
|||||||
.single();
|
.single();
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
return data;
|
return { data, oldConfig };
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async ({ data, oldConfig }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['rateLimitAlertConfigs'] });
|
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');
|
toast.success('Alert configuration updated');
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@@ -114,8 +134,20 @@ export function useCreateAlertConfig() {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async (data) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['rateLimitAlertConfigs'] });
|
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');
|
toast.success('Alert configuration created');
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@@ -129,15 +161,36 @@ export function useDeleteAlertConfig() {
|
|||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (id: string) => {
|
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
|
const { error } = await supabase
|
||||||
.from('rate_limit_alert_config')
|
.from('rate_limit_alert_config')
|
||||||
.delete()
|
.delete()
|
||||||
.eq('id', id);
|
.eq('id', id);
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
return config;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async (config) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['rateLimitAlertConfigs'] });
|
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');
|
toast.success('Alert configuration deleted');
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user