Files
Epicnabbo-Catalogus-Updated…/src/instrumentation.ts
T
openhands 4479753160 feat(security): mirror anti-DDoS blocks to Cloudflare edge via API
- gate creates a zone IP Access Rule (block) for proxied offenders that hit the block threshold, deduped until the tiered block expires
- cloudflare-api lib: verified endpoints, create/delete/verify/list helpers, Redis-backed tracking + 30s TTL sweep (instrumentation worker + admin render)
- runtime toggle cloudflareAutoBlock in antiddos config; boot default CLOUDFLARE_AUTO_BLOCK_ENABLED
- admin panel: Cloudflare edge-blocks card with verify + remove-rule actions; unban also lifts the edge block
- credentials live in env only (CLOUDFLARE_API_TOKEN / CLOUDFLARE_ZONE_ID)
2026-09-22 23:27:15 +02:00

43 lines
1.1 KiB
TypeScript

import type { Instrumentation } from "next";
export const onRequestError: Instrumentation.onRequestError = async (
error,
request,
context,
) => {
if (process.env.NEXT_RUNTIME !== "nodejs") return;
const { logServerError } = await import("@/lib/server-log");
logServerError("next.request_failed", error, {
path: request.path.split("?", 1)[0] ?? request.path,
method: request.method,
routePath: context.routePath,
routeType: context.routeType,
renderSource: context.renderSource,
digest:
typeof error === "object" && error !== null && "digest" in error
? String(error.digest)
: null,
});
};
export async function register() {
if (
process.env.NEXT_RUNTIME !== "nodejs" ||
process.env.NEXT_PHASE === "phase-production-build"
)
return;
const { drainFurnitureImports } = await import(
"@/lib/services/furni-job-worker"
);
const timer = setInterval(() => {
void drainFurnitureImports();
}, 30000);
timer.unref();
const { sweepExpiredCloudflareBlocks } = await import("@/lib/cloudflare-api");
const cloudflareSweep = setInterval(() => {
void sweepExpiredCloudflareBlocks();
}, 30000);
cloudflareSweep.unref();
}