import { makeRateLimiter } from '../../../src/sources/rateLimit.js'; export { makeRateLimiter } from '../../../src/sources/rateLimit.js'; /** * Opt-in per-IP rate limiter for the cost-bearing API proxies (OpenAI / Google). * DEFAULT IS UNLIMITED: when the env var is unset, `0`, or non-numeric, this * returns `null` and the caller skips the check entirely — a runtime no-op that * preserves the original behavior. Only a positive integer N enables a fixed * 60s window of N requests/IP (built lazily once, then reused so its per-IP * window state persists across requests). The global backstop is set to a * generous multiple of the per-IP cap so a single host can't starve the rest. * * @param {string|undefined} envValue - Raw env value (requests/min/IP). * @returns {((key:string)=>boolean)|null} An `allow(key)` fn, or null when unlimited. */ export function makeOptInRateLimiter(envValue) { const max = Number(envValue); if (!Number.isFinite(max) || max <= 0) return null; // unset/0/garbage -> unlimited return makeRateLimiter({ windowMs: 60_000, max: Math.floor(max), globalMax: Math.floor(max) * 20, }); } /** * Client key for rate limiting. Uses the real socket peer address only — we do * NOT trust X-Forwarded-For (client-controlled; a rotating value would mint fresh * quota and grow the limiter map). This is a localhost dev proxy, so the socket * address is the real client. */ export function clientKey(req) { return String(req.socket?.remoteAddress || 'local'); }