Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesPull RequestsActionsSecurityInsightsSettings
✨ AI
More
Blame · Line-by-line history

route-params.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

route-params.tsBlame37 lines · 1 contributor
fc623bfccantynz-alt1/**
2 * URL parameter validation for route handlers.
3 *
4 * Handlers were passing raw path segments straight into database predicates.
5 * `parseInt("abc", 10)` yields NaN, and a NaN or malformed-UUID comparison
6 * makes Postgres raise, which surfaces as a 500. So /:owner/:repo/issues/abc
7 * crashed while /:owner/:repo/issues/99999999 correctly 404'd — a hand-typed
8 * or stale URL returned a server error instead of "not found".
9 *
10 * Found by the authz-matrix gate, which probes every repo-scoped route with a
11 * placeholder id: eight routes answered 5xx (issues, pulls, milestones,
12 * agents and claude sessions).
13 */
14
15/**
16 * A positive integer path segment (issue/PR numbers), or null when the
17 * segment is not one. Rejects NaN, zero, negatives, floats, and numeric
18 * strings with trailing junk ("12abc") that parseInt would happily truncate.
19 */
20export function parseIdNumber(raw: string | undefined): number | null {
21 if (!raw || !/^\d+$/.test(raw)) return null;
22 const n = Number(raw);
23 if (!Number.isSafeInteger(n) || n <= 0) return null;
24 return n;
25}
26
27/**
28 * A UUID path segment, or null. Postgres raises `invalid input syntax for
29 * type uuid` on anything else, which the global error handler turns into a
30 * 500 — so this must be checked before the value reaches a query.
31 */
32export function parseIdUuid(raw: string | undefined): string | null {
33 if (!raw) return null;
34 return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(raw)
35 ? raw
36 : null;
37}