( bucketName: string, request: NextRequest, config: TokenBucketConfig = DEFAULT_PUBLIC_IP_ROUTE_LIMIT )
| 60 | * `X-Forwarded-For: unknown` spoofing. |
| 61 | */ |
| 62 | export async function enforceIpRateLimit( |
| 63 | bucketName: string, |
| 64 | request: NextRequest, |
| 65 | config: TokenBucketConfig = DEFAULT_PUBLIC_IP_ROUTE_LIMIT |
| 66 | ): Promise<NextResponse | null> { |
| 67 | const ip = getClientIp(request) |
| 68 | const key = `route:${bucketName}:ip:${ip}` |
| 69 | const { allowed, resetAt } = await rateLimiter.checkRateLimitDirect(key, config) |
| 70 | if (allowed) return null |
| 71 | logger.warn('IP rate limit exceeded', { bucket: bucketName, ip }) |
| 72 | return buildRateLimitResponse(resetAt) |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * Apply a per-user limit when a userId is present, else fall back to per-IP. |
no test coverage detected