From 793a543f33282f68fdd4a8eed8d4bde288809546 Mon Sep 17 00:00:00 2001 From: ArnavJoshi6391 Date: Sat, 30 May 2026 23:23:43 +0530 Subject: [PATCH] fix(api): validate GitHub usernames in github endpoint --- app/api/github/route.test.ts | 31 ++++++++++++++++++++++++++++++- lib/validations.ts | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/api/github/route.test.ts b/app/api/github/route.test.ts index 8857cc09..fc63c211 100644 --- a/app/api/github/route.test.ts +++ b/app/api/github/route.test.ts @@ -30,8 +30,37 @@ describe('GET /api/github', () => { it('calls getFullDashboardData with { bypassCache: false } when refresh is omitted', async () => { await GET(makeRequest({ username: 'octocat' })); + expect(getFullDashboardData).toHaveBeenCalledWith('octocat', { + bypassCache: false, + }); + }); + it('returns 400 when username contains invalid characters', async () => { + const response = await GET(makeRequest({ username: '@@@@@' })); + const body = await response.json(); - expect(getFullDashboardData).toHaveBeenCalledWith('octocat', { bypassCache: false }); + expect(response.status).toBe(400); + expect(body.error).toContain('Invalid parameters'); + }); + + it('returns 400 when username contains only whitespace', async () => { + const response = await GET(makeRequest({ username: ' ' })); + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body.error).toContain('Invalid parameters'); + }); + + it('returns 400 when username exceeds GitHub maximum length', async () => { + const response = await GET( + makeRequest({ + username: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + }) + ); + + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body.error).toContain('Invalid parameters'); }); // Test 1 — missing username → 400 diff --git a/lib/validations.ts b/lib/validations.ts index b95788a4..0eff810e 100644 --- a/lib/validations.ts +++ b/lib/validations.ts @@ -245,6 +245,7 @@ export const streakParamsSchema = z.object({ export const githubParamsSchema = z.object({ username: z .string({ error: 'Missing "username" parameter' }) + .trim() .min(1, { message: 'Username is required' }) .max(39, { message: 'GitHub username cannot exceed 39 characters' }) .regex(GITHUB_USERNAME_REGEX, {