/home/techb158/balavpn.abdallabala.com/src
NameSizeModeActions
app/-0755rm
components/-0755rm
domain/-0755rm
integrations/-0755rm
lib/-0755rm
services/-0755rm
middleware.js18680644editdlrm
Edit: /home/techb158/balavpn.abdallabala.com/src/middleware.js (1868B)
import { NextResponse } from "next/server"; const WINDOW_MS = 60_000; const MAX_PER_WINDOW = 100; const hits = new Map(); function getClientIp(request) { return request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || request.headers.get("x-real-ip") || "127.0.0.1"; } function checkRateLimitLocal(key, max = MAX_PER_WINDOW, windowMs = WINDOW_MS) { const now = Date.now(); if (!hits.has(key)) hits.set(key, []); const timestamps = hits.get(key).filter(t => now - t < windowMs); timestamps.push(now); hits.set(key, timestamps); return { allowed: timestamps.length <= max, remaining: Math.max(0, max - timestamps.length), reset: Math.ceil(now / 1000) + Math.ceil(windowMs / 1000) }; } export function middleware(request) { const { pathname } = request.nextUrl; if (!pathname.startsWith("/api/")) return NextResponse.next(); const ip = getClientIp(request); const useRedis = process.env.REDIS_URL && process.env.COSMIC_REDIS_ENABLED !== 'false'; if (!useRedis) { const result = checkRateLimitLocal(`rl:${ip}`); if (!result.allowed) { return new NextResponse(JSON.stringify({ error: "Too many requests. Try again shortly." }), { status: 429, headers: { "Content-Type": "application/json", "X-RateLimit-Limit": String(MAX_PER_WINDOW), "X-RateLimit-Remaining": "0", "X-RateLimit-Reset": String(result.reset), "Cache-Control": "no-store" } }); } const response = NextResponse.next(); response.headers.set("X-RateLimit-Limit", String(MAX_PER_WINDOW)); response.headers.set("X-RateLimit-Remaining", String(result.remaining)); response.headers.set("X-RateLimit-Reset", String(result.reset)); return response; } return NextResponse.next(); } export const config = { matcher: "/api/:path*" };