From f746dc2e66743a2dda821c6b3d0bd241f5ed80d5 Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 17:38:38 -0600 Subject: [PATCH 1/4] fix(queries): clamp invalid page values --- src/lib/queries/agents.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lib/queries/agents.ts b/src/lib/queries/agents.ts index 3faf33a5..69576b25 100644 --- a/src/lib/queries/agents.ts +++ b/src/lib/queries/agents.ts @@ -1,5 +1,7 @@ import { SupabaseClient } from "@supabase/supabase-js"; +const MAX_PAGE = 100_000; + export interface AgentsQueryParams { q?: string; sort?: string; @@ -8,6 +10,13 @@ export interface AgentsQueryParams { tags?: string[]; } +function parsePage(value?: string) { + const parsed = parseInt(value || "1", 10); + return Number.isFinite(parsed) + ? Math.min(Math.max(parsed, 1), MAX_PAGE) + : 1; +} + export function buildAgentsQuery( supabase: SupabaseClient, params: AgentsQueryParams @@ -49,7 +58,7 @@ export function buildAgentsQuery( query = query.order("created_at", { ascending: false }); } - const pageNum = parseInt(page || "1"); + const pageNum = parsePage(page); const limit = 20; const offset = (pageNum - 1) * limit; query = query.range(offset, offset + limit - 1); From c2b500870609010d68ea67f4bf794708adf62dc8 Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 17:38:40 -0600 Subject: [PATCH 2/4] test(queries): cover invalid page ranges --- src/lib/queries/agents.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/lib/queries/agents.test.ts b/src/lib/queries/agents.test.ts index cae14f6e..2665deb1 100644 --- a/src/lib/queries/agents.test.ts +++ b/src/lib/queries/agents.test.ts @@ -101,4 +101,22 @@ describe("buildAgentsQuery", () => { expect(mock.chain.range).toHaveBeenCalledWith(40, 59); }); + + it("clamps negative page values to page 1", () => { + buildAgentsQuery(mock.client, { page: "-1" }); + + expect(mock.chain.range).toHaveBeenCalledWith(0, 19); + }); + + it("falls back to page 1 for non-numeric values", () => { + buildAgentsQuery(mock.client, { page: "abc" }); + + expect(mock.chain.range).toHaveBeenCalledWith(0, 19); + }); + + it("caps very large page values before calculating the range", () => { + buildAgentsQuery(mock.client, { page: "999999999" }); + + expect(mock.chain.range).toHaveBeenCalledWith(1999980, 1999999); + }); }); From cbba87f94d8fb55a1094eff302292c16e850e8c3 Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 17:38:41 -0600 Subject: [PATCH 3/4] fix(queries): clamp invalid page values --- src/lib/queries/candidates.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lib/queries/candidates.ts b/src/lib/queries/candidates.ts index 9615c033..767db245 100644 --- a/src/lib/queries/candidates.ts +++ b/src/lib/queries/candidates.ts @@ -1,5 +1,7 @@ import { SupabaseClient } from "@supabase/supabase-js"; +const MAX_PAGE = 100_000; + export interface CandidatesQueryParams { q?: string; sort?: string; @@ -8,6 +10,13 @@ export interface CandidatesQueryParams { tags?: string[]; } +function parsePage(value?: string) { + const parsed = parseInt(value || "1", 10); + return Number.isFinite(parsed) + ? Math.min(Math.max(parsed, 1), MAX_PAGE) + : 1; +} + export function buildCandidatesQuery( supabase: SupabaseClient, params: CandidatesQueryParams @@ -49,7 +58,7 @@ export function buildCandidatesQuery( query = query.order("created_at", { ascending: false }); } - const pageNum = parseInt(page || "1"); + const pageNum = parsePage(page); const limit = 20; const offset = (pageNum - 1) * limit; query = query.range(offset, offset + limit - 1); From ab78847f8e398c231e082cb7c1b29c12a2be328a Mon Sep 17 00:00:00 2001 From: Jorel97 <83238249+Jorel97@users.noreply.github.com> Date: Fri, 29 May 2026 17:38:43 -0600 Subject: [PATCH 4/4] test(queries): cover invalid page ranges --- src/lib/queries/candidates.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/lib/queries/candidates.test.ts b/src/lib/queries/candidates.test.ts index 201ebaf8..1e9b3afa 100644 --- a/src/lib/queries/candidates.test.ts +++ b/src/lib/queries/candidates.test.ts @@ -73,4 +73,22 @@ describe("buildCandidatesQuery", () => { expect(mock.chain.range).toHaveBeenCalledWith(20, 39); }); + + it("clamps negative page values to page 1", () => { + buildCandidatesQuery(mock.client, { page: "-1" }); + + expect(mock.chain.range).toHaveBeenCalledWith(0, 19); + }); + + it("falls back to page 1 for non-numeric values", () => { + buildCandidatesQuery(mock.client, { page: "abc" }); + + expect(mock.chain.range).toHaveBeenCalledWith(0, 19); + }); + + it("caps very large page values before calculating the range", () => { + buildCandidatesQuery(mock.client, { page: "999999999" }); + + expect(mock.chain.range).toHaveBeenCalledWith(1999980, 1999999); + }); });