From f10135649e7baaf8bbf43846e2bfb6e9bc732e0b Mon Sep 17 00:00:00 2001 From: azizur100389 Date: Mon, 4 May 2026 23:03:05 +0100 Subject: [PATCH] fix(server): rate-limit /api/analyze and /api/embed endpoints (#1328) (#1339) --- gitnexus/src/server/api.ts | 4 ++-- gitnexus/test/unit/rate-limit.test.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gitnexus/src/server/api.ts b/gitnexus/src/server/api.ts index d0c9c5577..376ab5876 100644 --- a/gitnexus/src/server/api.ts +++ b/gitnexus/src/server/api.ts @@ -1348,7 +1348,7 @@ export const createServer = async (port: number, host: string = '127.0.0.1') => // ── Analyze API ────────────────────────────────────────────────────── // POST /api/analyze — start a new analysis job - app.post('/api/analyze', async (req, res) => { + app.post('/api/analyze', createRouteLimiter({ limit: 10 }), async (req, res) => { try { const { url: repoUrl, path: repoLocalPath, force, embeddings, dropEmbeddings } = req.body; @@ -1615,7 +1615,7 @@ export const createServer = async (port: number, host: string = '127.0.0.1') => const embedJobManager = new JobManager(); // POST /api/embed — trigger server-side embedding generation - app.post('/api/embed', async (req, res) => { + app.post('/api/embed', createRouteLimiter({ limit: 20 }), async (req, res) => { try { const entry = await resolveRepo(requestedRepo(req)); if (!entry) { diff --git a/gitnexus/test/unit/rate-limit.test.ts b/gitnexus/test/unit/rate-limit.test.ts index 099cc5feb..0087cfc87 100644 --- a/gitnexus/test/unit/rate-limit.test.ts +++ b/gitnexus/test/unit/rate-limit.test.ts @@ -230,6 +230,14 @@ describe('production routes — rate-limit middleware wiring', () => { expect(apiSource).toMatch(/app\.delete\('\/api\/repo',\s*createRouteLimiter\(/); }); + it('POST /api/analyze is wired with createRouteLimiter', () => { + expect(apiSource).toMatch(/app\.post\('\/api\/analyze',\s*createRouteLimiter\(/); + }); + + it('POST /api/embed is wired with createRouteLimiter', () => { + expect(apiSource).toMatch(/app\.post\('\/api\/embed',\s*createRouteLimiter\(/); + }); + it('SPA fallback is wired with createRouteLimiter', () => { expect(apiSource).toMatch(/app\.get\(SPA_FALLBACK_REGEX,\s*createRouteLimiter\(/); });