From 0d8cf3bead9bf1f8c0e7d6c605903788b24a284d Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 18:47:17 -0600 Subject: [PATCH 1/4] fix(gigs): cap page query values --- src/app/api/gigs/route.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/api/gigs/route.ts b/src/app/api/gigs/route.ts index 952f81a0..3261a389 100644 --- a/src/app/api/gigs/route.ts +++ b/src/app/api/gigs/route.ts @@ -7,6 +7,8 @@ import { sanitizeTitle, sanitizeContent, stripProtoPollution } from "@/lib/sanit import { getUserDid, onGigPosted } from "@/lib/reputation-hooks"; import { logActivity } from "@/lib/activity"; +const MAX_GIG_PAGE = 100_000; + // GET /api/gigs - List gigs (public) export async function GET(request: NextRequest) { try { @@ -24,7 +26,7 @@ export async function GET(request: NextRequest) { account_type: searchParams.get("account_type") || undefined, listing_type: searchParams.get("listing_type") || undefined, sort: searchParams.get("sort") || "newest", - page: Number(searchParams.get("page")) || 1, + page: Math.min(Number(searchParams.get("page")) || 1, MAX_GIG_PAGE), limit: Number(searchParams.get("limit")) || 20, }); From 9d5aa4a924a0372ae814322212e65f60778bb342 Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 18:47:18 -0600 Subject: [PATCH 2/4] fix(gigs): cap page query values --- src/app/api/gigs/route.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/app/api/gigs/route.test.ts b/src/app/api/gigs/route.test.ts index 5006710d..931fd94c 100644 --- a/src/app/api/gigs/route.test.ts +++ b/src/app/api/gigs/route.test.ts @@ -113,6 +113,21 @@ describe("GET /api/gigs", () => { expect(json.pagination.total).toBe(1); }); + it("caps huge page values before building the Supabase range", async () => { + const chain = chainResult({ data: null, error: null }); + chain.select = vi.fn().mockReturnValue(chain); + chain.range = vi.fn().mockResolvedValue({ data: [], error: null, count: 0 }); + + mockFrom.mockReturnValue(chain); + + const res = await GET(makeGetRequest({ page: "999999999" })); + const json = await res.json(); + + expect(res.status).toBe(200); + expect(chain.range).toHaveBeenCalledWith(1999980, 1999999); + expect(json.pagination.page).toBe(100000); + }); + it("filters by listing_type when provided", async () => { const chain = chainResult({ data: null, error: null }); chain.select = vi.fn().mockReturnValue(chain); From 5df2d4127ce22a3eec54a74a959f3013b2a3cef0 Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 18:50:52 -0600 Subject: [PATCH 3/4] fix(gigs): cap page and limit values --- src/app/api/gigs/route.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/api/gigs/route.ts b/src/app/api/gigs/route.ts index 3261a389..5d7172d0 100644 --- a/src/app/api/gigs/route.ts +++ b/src/app/api/gigs/route.ts @@ -8,6 +8,7 @@ import { getUserDid, onGigPosted } from "@/lib/reputation-hooks"; import { logActivity } from "@/lib/activity"; const MAX_GIG_PAGE = 100_000; +const MAX_GIG_LIMIT = 50; // GET /api/gigs - List gigs (public) export async function GET(request: NextRequest) { @@ -27,7 +28,7 @@ export async function GET(request: NextRequest) { listing_type: searchParams.get("listing_type") || undefined, sort: searchParams.get("sort") || "newest", page: Math.min(Number(searchParams.get("page")) || 1, MAX_GIG_PAGE), - limit: Number(searchParams.get("limit")) || 20, + limit: Math.min(Number(searchParams.get("limit")) || 20, MAX_GIG_LIMIT), }); if (!filters.success) { @@ -130,8 +131,7 @@ export async function GET(request: NextRequest) { // Apply pagination — ensure non-negative offset (#69) const offset = Math.max(0, (page - 1) * limit); - const clampedLimit = Math.max(1, Math.min(50, limit)); - query = query.range(offset, offset + clampedLimit - 1); + query = query.range(offset, offset + limit - 1); const { data: gigs, error, count } = await query; From b665796a2034b9d4c2cecdf6d63d6d9a41d67fca Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 18:50:54 -0600 Subject: [PATCH 4/4] fix(gigs): cap page and limit values --- src/app/api/gigs/route.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/app/api/gigs/route.test.ts b/src/app/api/gigs/route.test.ts index 931fd94c..ca705ff7 100644 --- a/src/app/api/gigs/route.test.ts +++ b/src/app/api/gigs/route.test.ts @@ -128,6 +128,22 @@ describe("GET /api/gigs", () => { expect(json.pagination.page).toBe(100000); }); + it("caps huge limit values before building range and pagination metadata", async () => { + const chain = chainResult({ data: null, error: null }); + chain.select = vi.fn().mockReturnValue(chain); + chain.range = vi.fn().mockResolvedValue({ data: [], error: null, count: 125 }); + + mockFrom.mockReturnValue(chain); + + const res = await GET(makeGetRequest({ limit: "999999999" })); + const json = await res.json(); + + expect(res.status).toBe(200); + expect(chain.range).toHaveBeenCalledWith(0, 49); + expect(json.pagination.limit).toBe(50); + expect(json.pagination.totalPages).toBe(3); + }); + it("filters by listing_type when provided", async () => { const chain = chainResult({ data: null, error: null }); chain.select = vi.fn().mockReturnValue(chain);