Monitoring UX: Log leeren + PageSize wählbar
- Backend: DELETE /api/monitoring/events (settings:update). Optional ?olderThanDays=N – nur Events älter als N Tage löschen. Hinterlässt selbst einen Audit-Eintrag "Log geleert: X Einträge" mit User-E-Mail + IP, damit der Vorgang nachvollziehbar bleibt. - Frontend: "Log leeren"-Button öffnet Bestätigungs-Modal mit optionalem "älter als X Tage"-Filter. Roter Bestätigungs-Button. - Frontend: PageSize-Selector (10/25/50/100/200) neben dem Header. Wechsel setzt automatisch zurück auf Seite 1. Live-verifiziert: Clear löscht 10 Events, schreibt 1 Audit-Event, PageSize=5 wird in pagination respektiert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -148,6 +148,51 @@ export async function testAlert(_req: AuthRequest, res: Response): Promise<void>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /api/monitoring/events
|
||||
* Löscht alle SecurityEvents (oder optional nur älter als ?olderThanDays).
|
||||
* Alert-versendete CRITICAL-Events werden vorher noch geloggt, damit der
|
||||
* Audit-Trail erhalten bleibt.
|
||||
*/
|
||||
export async function clearEvents(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const olderThanDays = req.query.olderThanDays
|
||||
? parseInt(req.query.olderThanDays as string)
|
||||
: undefined;
|
||||
|
||||
const where: any = {};
|
||||
if (olderThanDays && olderThanDays > 0) {
|
||||
const cutoff = new Date(Date.now() - olderThanDays * 24 * 60 * 60 * 1000);
|
||||
where.createdAt = { lt: cutoff };
|
||||
}
|
||||
|
||||
const result = await prisma.securityEvent.deleteMany({ where });
|
||||
|
||||
// Audit-Spur: Wer hat geleert
|
||||
const user = (req as any).user;
|
||||
await prisma.securityEvent.create({
|
||||
data: {
|
||||
type: 'PERMISSION_CHANGED',
|
||||
severity: 'INFO',
|
||||
message: `Security-Log geleert: ${result.count} Einträge gelöscht${olderThanDays ? ` (älter als ${olderThanDays} Tage)` : ''}`,
|
||||
userId: user?.userId || null,
|
||||
userEmail: user?.email || null,
|
||||
ipAddress: req.ip || 'unknown',
|
||||
endpoint: 'DELETE /api/monitoring/events',
|
||||
},
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: `${result.count} Events gelöscht`,
|
||||
data: { deletedCount: result.count },
|
||||
} as any);
|
||||
} catch (error) {
|
||||
console.error('clearEvents error:', error);
|
||||
res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' } as ApiResponse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/monitoring/run-digest (manueller Trigger für den Hourly-Digest)
|
||||
*/
|
||||
|
||||
@@ -11,5 +11,6 @@ router.get('/settings', requirePermission('settings:read'), monitoringController
|
||||
router.put('/settings', requirePermission('settings:update'), monitoringController.updateMonitoringSettings);
|
||||
router.post('/test-alert', requirePermission('settings:update'), monitoringController.testAlert);
|
||||
router.post('/run-digest', requirePermission('settings:update'), monitoringController.runDigestNow);
|
||||
router.delete('/events', requirePermission('settings:update'), monitoringController.clearEvents);
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user