Merge pull request #1223 from bglglzd/fix/public-api-prompts-pagination

Add validation and caps for public /api/prompts pagination
This commit is contained in:
Fatih Kadir Akın
2026-07-17 22:32:52 +03:00
committed by GitHub
2 changed files with 54 additions and 2 deletions
+30
View File
@@ -87,6 +87,36 @@ describe("GET /api/prompts", () => {
expect(data.perPage).toBe(24);
});
it("should fall back to defaults when pagination parameters are malformed", async () => {
vi.mocked(db.prompt.findMany).mockResolvedValue([]);
vi.mocked(db.prompt.count).mockResolvedValue(0);
const request = new Request(
"http://localhost:3000/api/prompts?page=not-a-number&perPage=bad-value"
);
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.page).toBe(1);
expect(data.perPage).toBe(24);
});
it("should clamp pagination parameters to configured maximums", async () => {
vi.mocked(db.prompt.findMany).mockResolvedValue([]);
vi.mocked(db.prompt.count).mockResolvedValue(0);
const request = new Request(
"http://localhost:3000/api/prompts?page=20000&perPage=999"
);
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.page).toBe(10000);
expect(data.perPage).toBe(100);
});
it("should filter by type", async () => {
vi.mocked(db.prompt.findMany).mockResolvedValue([]);
vi.mocked(db.prompt.count).mockResolvedValue(0);
+24 -2
View File
@@ -306,11 +306,33 @@ export async function POST(request: Request) {
}
// List prompts (for API access)
const MAX_API_PER_PAGE = 100;
const DEFAULT_API_PER_PAGE = 24;
const MAX_API_PAGE = 10000;
const DEFAULT_API_PAGE = 1;
const paginationQuerySchema = z.object({
page: z.coerce
.number()
.int()
.min(1)
.transform((value) => Math.min(value, MAX_API_PAGE))
.catch(DEFAULT_API_PAGE),
perPage: z.coerce
.number()
.int()
.min(1)
.transform((value) => Math.min(value, MAX_API_PER_PAGE))
.catch(DEFAULT_API_PER_PAGE),
});
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get("page") || "1");
const perPage = parseInt(searchParams.get("perPage") || "24");
const { page, perPage } = paginationQuerySchema.parse({
page: searchParams.get("page"),
perPage: searchParams.get("perPage"),
});
const type = searchParams.get("type");
const categoryId = searchParams.get("category");
const tag = searchParams.get("tag");