20 lines
1.0 KiB
TypeScript
20 lines
1.0 KiB
TypeScript
import { NextRequest } from "next/server";
|
|
export function clientIp(req: NextRequest): string {
|
|
const xff = req.headers.get("x-forwarded-for");
|
|
if (xff) return xff.split(",")[0]?.trim() || "unknown";
|
|
return (req as any).ip ?? req.headers.get("x-real-ip") ?? "unknown";
|
|
}
|
|
const buckets = new Map<string, number[]>();
|
|
export function isRateLimited(key: string, maxHits: number, windowMs: number): boolean {
|
|
const now = Date.now();
|
|
const arr = (buckets.get(key) ?? []).filter((t) => now - t < windowMs);
|
|
if (arr.length >= maxHits) { buckets.set(key, arr); return true; }
|
|
arr.push(now); buckets.set(key, arr); return false;
|
|
}
|
|
export function timeTrapOk(startedAt?: string | null, minSeconds = 4): boolean {
|
|
const started = Number(startedAt ?? 0); if (!started) return false;
|
|
return Date.now() - started >= minSeconds * 1000;
|
|
}
|
|
export function isHoneyFilled(value?: string | null): boolean { return !!value && value.trim().length > 0; }
|
|
export function sanitize(input: string): string { return input.replace(/<[^>]*>?/gm, "").trim(); }
|