mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-12 19:57:37 +00:00
feat(audit-log): add configurable retention, export, Auditor role, and enhanced filtering (#258)
- Configurable retention: audit_retention_days setting (1-365 days, default 90) replaces hardcoded 90-day retention, exposed in Settings > Data Retention - Export: one-click CSV/JSON export of filtered audit data via new GET /api/audit-log/export endpoint (capped at 10,000 entries) - Auditor role: read-only role with system:audit permission for viewing and exporting audit logs without admin privileges (Admiral tier) - Enhanced filtering: full-text search across summaries/paths/usernames, date range picker, and expandable row details showing request path, IP address, node ID, and entry ID
This commit is contained in:
@@ -62,7 +62,7 @@ export interface WebhookExecution {
|
||||
|
||||
export type AuthProvider = 'local' | 'ldap' | 'oidc_google' | 'oidc_github' | 'oidc_okta';
|
||||
|
||||
export type UserRole = 'admin' | 'viewer' | 'deployer' | 'node-admin';
|
||||
export type UserRole = 'admin' | 'viewer' | 'deployer' | 'node-admin' | 'auditor';
|
||||
export type ResourceType = 'stack' | 'node';
|
||||
|
||||
export interface User {
|
||||
@@ -1109,6 +1109,7 @@ export class DatabaseService {
|
||||
method?: string;
|
||||
from?: number;
|
||||
to?: number;
|
||||
search?: string;
|
||||
} = {}): { entries: AuditLogEntry[]; total: number } {
|
||||
const page = filters.page ?? 1;
|
||||
const limit = filters.limit ?? 50;
|
||||
@@ -1133,6 +1134,11 @@ export class DatabaseService {
|
||||
conditions.push('timestamp <= ?');
|
||||
params.push(filters.to);
|
||||
}
|
||||
if (filters.search) {
|
||||
conditions.push('(summary LIKE ? OR path LIKE ? OR username LIKE ?)');
|
||||
const term = `%${filters.search}%`;
|
||||
params.push(term, term, term);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
||||
|
||||
|
||||
@@ -304,7 +304,8 @@ export class MonitorService {
|
||||
db.cleanupOldMetrics(isNaN(retentionHours) ? 24 : retentionHours);
|
||||
const retentionDays = parseInt(settings['log_retention_days'] || '30', 10);
|
||||
db.cleanupOldNotifications(isNaN(retentionDays) ? 30 : retentionDays);
|
||||
db.cleanupOldAuditLogs(90);
|
||||
const auditRetentionDays = parseInt(settings['audit_retention_days'] || '90', 10);
|
||||
db.cleanupOldAuditLogs(isNaN(auditRetentionDays) ? 90 : auditRetentionDays);
|
||||
} catch (e) {
|
||||
console.error('MonitorService: failed to cleanup old data', e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user