From 341ec70ebda4a83c17b607407804e013c742a4ea Mon Sep 17 00:00:00 2001 From: vipul674 Date: Sun, 31 May 2026 14:57:58 +0530 Subject: [PATCH 1/4] fix: add input validation and rate limiting to /api/compare endpoint --- lib/validations.ts | 18 ++++++++++++++++++ middleware.ts | 1 + 2 files changed, 19 insertions(+) diff --git a/lib/validations.ts b/lib/validations.ts index faa64cb7..bc33eff9 100644 --- a/lib/validations.ts +++ b/lib/validations.ts @@ -322,6 +322,24 @@ export const githubParamsSchema = z.object({ refresh: z.string().optional().transform(toRefreshFlag), }); +export const compareParamsSchema = z.object({ + user1: z + .string({ error: 'Missing "user1" parameter' }) + .trim() + .min(1, { message: 'user1 is required' }) + .max(39, { message: 'GitHub username cannot exceed 39 characters' }) + .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user1' }), + user2: z + .string({ error: 'Missing "user2" parameter' }) + .trim() + .min(1, { message: 'user2 is required' }) + .max(39, { message: 'GitHub username cannot exceed 39 characters' }) + .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user2' }), +}).refine((data) => data.user1.toLowerCase() !== data.user2.toLowerCase(), { + message: 'Cannot compare a user with themselves', + path: ['user2'], +}); + export const ogParamsSchema = z .object({ user: z.string().trim().optional().transform(toEmptyStringAsUndefined), diff --git a/middleware.ts b/middleware.ts index bbb09744..981916e4 100644 --- a/middleware.ts +++ b/middleware.ts @@ -62,5 +62,6 @@ export const config = { '/api/stats/:path*', '/api/og/:path*', '/api/notify/:path*', + '/api/compare/:path*', ], }; From c178060dfc9d6e3f768fe3549104be625e528e90 Mon Sep 17 00:00:00 2001 From: vipul674 Date: Sun, 31 May 2026 15:07:09 +0530 Subject: [PATCH 2/4] style: fix prettier formatting in validations.ts --- lib/validations.ts | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/validations.ts b/lib/validations.ts index bc33eff9..5ebdd415 100644 --- a/lib/validations.ts +++ b/lib/validations.ts @@ -322,23 +322,25 @@ export const githubParamsSchema = z.object({ refresh: z.string().optional().transform(toRefreshFlag), }); -export const compareParamsSchema = z.object({ - user1: z - .string({ error: 'Missing "user1" parameter' }) - .trim() - .min(1, { message: 'user1 is required' }) - .max(39, { message: 'GitHub username cannot exceed 39 characters' }) - .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user1' }), - user2: z - .string({ error: 'Missing "user2" parameter' }) - .trim() - .min(1, { message: 'user2 is required' }) - .max(39, { message: 'GitHub username cannot exceed 39 characters' }) - .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user2' }), -}).refine((data) => data.user1.toLowerCase() !== data.user2.toLowerCase(), { - message: 'Cannot compare a user with themselves', - path: ['user2'], -}); +export const compareParamsSchema = z + .object({ + user1: z + .string({ error: 'Missing "user1" parameter' }) + .trim() + .min(1, { message: 'user1 is required' }) + .max(39, { message: 'GitHub username cannot exceed 39 characters' }) + .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user1' }), + user2: z + .string({ error: 'Missing "user2" parameter' }) + .trim() + .min(1, { message: 'user2 is required' }) + .max(39, { message: 'GitHub username cannot exceed 39 characters' }) + .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user2' }), + }) + .refine((data) => data.user1.toLowerCase() !== data.user2.toLowerCase(), { + message: 'Cannot compare a user with themselves', + path: ['user2'], + }); export const ogParamsSchema = z .object({ From 88ed0e538595b0c0bc44f3b5695072372eade5b7 Mon Sep 17 00:00:00 2001 From: vipul674 Date: Mon, 1 Jun 2026 07:54:29 +0530 Subject: [PATCH 3/4] fix: remove duplicate compareParamsSchema after upstream merge --- lib/validations.ts | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/lib/validations.ts b/lib/validations.ts index 5ebdd415..7c7ee082 100644 --- a/lib/validations.ts +++ b/lib/validations.ts @@ -473,26 +473,6 @@ export const wrappedParamsSchema = z.object({ height: dimensionParam('height', 80, 800), }); -export const compareParamsSchema = z - .object({ - user1: z - .string({ error: 'Missing user1 parameter' }) - .trim() - .min(1, { message: 'user1 is required' }) - .max(39, { message: 'GitHub username cannot exceed 39 characters' }) - .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user1' }), - user2: z - .string({ error: 'Missing user2 parameter' }) - .trim() - .min(1, { message: 'user2 is required' }) - .max(39, { message: 'GitHub username cannot exceed 39 characters' }) - .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user2' }), - }) - .refine((data) => data.user1.toLowerCase() !== data.user2.toLowerCase(), { - message: 'Cannot compare a user with themselves.', - path: ['user2'], - }); - export const notifyPostSchema = z.object({ username: z .string({ error: 'Username is required.' }) From b0cc9cee6960054682062150f87ffec4a26974aa Mon Sep 17 00:00:00 2001 From: vipul674 Date: Mon, 1 Jun 2026 07:58:10 +0530 Subject: [PATCH 4/4] fix: align compareParamsSchema refine message with test expectation --- lib/validations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/validations.ts b/lib/validations.ts index 7c7ee082..13e00e5f 100644 --- a/lib/validations.ts +++ b/lib/validations.ts @@ -338,7 +338,7 @@ export const compareParamsSchema = z .regex(GITHUB_USERNAME_REGEX, { message: 'Invalid GitHub username for user2' }), }) .refine((data) => data.user1.toLowerCase() !== data.user2.toLowerCase(), { - message: 'Cannot compare a user with themselves', + message: 'Cannot compare a user with themselves.', path: ['user2'], });