diff --git a/src/app/api/chat/conversations/[id]/participants/route.js b/src/app/api/chat/conversations/[id]/participants/route.js index 5c439a96..0292fcdf 100644 --- a/src/app/api/chat/conversations/[id]/participants/route.js +++ b/src/app/api/chat/conversations/[id]/participants/route.js @@ -123,7 +123,8 @@ export async function GET(request, { params } = {}) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } - const { id: conversationId } = await resolveRouteParams(params); + const { id: rawConversationId } = await resolveRouteParams(params); + const conversationId = typeof rawConversationId === 'string' ? rawConversationId.trim() : ''; if (!conversationId) { return NextResponse.json({ error: 'Missing conversation ID' }, { status: 400 }); } diff --git a/src/app/api/chat/conversations/[id]/participants/route.test.js b/src/app/api/chat/conversations/[id]/participants/route.test.js index bcc31e41..338be74f 100644 --- a/src/app/api/chat/conversations/[id]/participants/route.test.js +++ b/src/app/api/chat/conversations/[id]/participants/route.test.js @@ -129,4 +129,25 @@ describe('GET /api/chat/conversations/[id]/participants', () => { expect(body).toEqual({ error: 'Missing conversation ID' }); expect(mocks.authGetUser).toHaveBeenCalled(); }); + + it('rejects whitespace-only conversation IDs before participant lookup', async () => { + mocks.serviceFrom.mockImplementation((table) => { + if (table === 'users') return createUsersQuery(); + if (table === 'conversation_participants') throw new Error('Participant lookup should not run'); + throw new Error(`Unexpected table: ${table}`); + }); + + const { GET } = await import('./route.js'); + const response = await GET( + new Request('https://qrypt.chat/api/chat/conversations/%20%20/participants', { + headers: { cookie: 'session=header.payload.signature' } + }), + { params: Promise.resolve({ id: ' ' }) } + ); + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body).toEqual({ error: 'Missing conversation ID' }); + expect(mocks.authGetUser).toHaveBeenCalled(); + }); });