27 lines
811 B
TypeScript
27 lines
811 B
TypeScript
const WINDOW_MS = 60_000;
|
|
const LIMIT = 10;
|
|
const buckets = new Map<string, number[]>();
|
|
|
|
export function resetRateLimit(): void {
|
|
buckets.clear();
|
|
}
|
|
|
|
/** True when the caller is still inside 10 requests per minute. */
|
|
export function allowRequest(ip: string, now = Date.now()): boolean {
|
|
const fresh = (buckets.get(ip) ?? []).filter((t) => now - t < WINDOW_MS);
|
|
if (fresh.length >= LIMIT) {
|
|
buckets.set(ip, fresh);
|
|
return false;
|
|
}
|
|
fresh.push(now);
|
|
buckets.set(ip, fresh);
|
|
return true;
|
|
}
|
|
|
|
/** Last hop. Apache appends the real client after any address the browser sent. */
|
|
export function clientIp(header: string | null): string {
|
|
if (!header) return "direct";
|
|
const parts = header.split(",").map((part) => part.trim()).filter(Boolean);
|
|
return parts[parts.length - 1] || "direct";
|
|
}
|