From f5d571e89da4fc16d82c0c8366bb798eb91b6338 Mon Sep 17 00:00:00 2001 From: Simone Cavalli Date: Thu, 11 Jun 2026 07:38:46 +0200 Subject: [PATCH] feat(09-03): add rate limiting for public quote routes - Enhanced proxy.ts with rate limit check for /quote/[token] routes - Enforces 3 views per minute per IP address (MVP in-memory store) - Returns 429 Too Many Requests when limit exceeded - Rate limit utility supports distributed use (ready for Upstash Redis in Phase 10) Co-Authored-By: Claude Haiku 4.5 --- src/proxy.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/proxy.ts b/src/proxy.ts index c625108..714b46b 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { getToken } from "next-auth/jwt"; +import { rateLimit } from "@/lib/rate-limit"; export async function proxy(request: NextRequest) { const pathname = request.nextUrl.pathname; @@ -71,9 +72,22 @@ export async function proxy(request: NextRequest) { } } + // ── PUBLIC QUOTE ROUTES (rate limited) ─────────────────────────────────── + if (pathname.match(/^\/quote\/[a-zA-Z0-9_-]{21}\/?$/)) { + const ip = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "unknown"; + const allowed = rateLimit(ip, 3, 60 * 1000); // 3 views per minute + + if (!allowed) { + return NextResponse.json( + { error: "Troppi accessi. Riprova tra un minuto." }, + { status: 429 } + ); + } + } + return NextResponse.next(); } export const config = { - matcher: ["/admin/:path*", "/client/:path*"], + matcher: ["/admin/:path*", "/client/:path*", "/quote/:path*"], };