Rate-Limit-Liste: bereits freigegebene IPs ausblenden
Die Liste basiert auf unveränderlichen SecurityEvents – ein Reset
leerte nur den In-Memory-Limiter, aber die historischen Events
blieben weitere 15 Min in der Anzeige stehen ("Freigeben klappt nicht").
Fix: für jede candidate-IP wird der letzte AuditLog-Eintrag
(resourceType=RateLimit) im 15-Min-Fenster geprüft. Liegt er nach dem
letzten Hit der IP, fliegt die IP aus der Liste – aber sobald wieder
ein RATE_LIMIT_HIT nach dem Reset kommt, taucht die IP wieder auf.
Live-verifiziert: trigger → 1 Eintrag; reset → 0 Einträge;
erneuter trigger → 1 Eintrag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,37 @@ export async function getActiveRateLimits(req: AuthRequest, res: Response): Prom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bereits manuell freigegebene IPs aus der Anzeige rauswerfen: wenn der
|
||||||
|
// letzte Reset (= Audit-Log-Eintrag) NACH dem letzten Hit liegt, ist die
|
||||||
|
// IP nicht mehr gesperrt. SecurityEvents sind unveränderlich, also brauchen
|
||||||
|
// wir diesen Reset-Marker, sonst bleibt eine bereits freigegebene IP
|
||||||
|
// weiterhin im Bildschirm hängen, bis das 15-Min-Fenster abgelaufen ist.
|
||||||
|
const candidateIps = Array.from(byIp.keys());
|
||||||
|
if (candidateIps.length > 0) {
|
||||||
|
const recentResets = await prisma.auditLog.findMany({
|
||||||
|
where: {
|
||||||
|
resourceType: 'RateLimit',
|
||||||
|
resourceId: { in: candidateIps },
|
||||||
|
createdAt: { gte: since },
|
||||||
|
},
|
||||||
|
select: { resourceId: true, createdAt: true },
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
});
|
||||||
|
const resetMap = new Map<string, Date>();
|
||||||
|
for (const r of recentResets) {
|
||||||
|
if (r.resourceId && !resetMap.has(r.resourceId)) {
|
||||||
|
resetMap.set(r.resourceId, r.createdAt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const ip of candidateIps) {
|
||||||
|
const reset = resetMap.get(ip);
|
||||||
|
const entry = byIp.get(ip)!;
|
||||||
|
if (reset && reset >= entry.lastHit) {
|
||||||
|
byIp.delete(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const list = Array.from(byIp.values()).sort(
|
const list = Array.from(byIp.values()).sort(
|
||||||
(a, b) => b.lastHit.getTime() - a.lastHit.getTime(),
|
(a, b) => b.lastHit.getTime() - a.lastHit.getTime(),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user