From f0a5eec43c3b325d17cb54c3b7734ec54dd9089b Mon Sep 17 00:00:00 2001 From: aiirvizionz Date: Thu, 30 Jul 2026 09:39:33 -0600 Subject: [PATCH] fix(files): validate upload metadata values --- src/app/api/files/upload-url/route.js | 4 +++ src/app/api/files/upload-url/route.test.js | 40 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/app/api/files/upload-url/route.js b/src/app/api/files/upload-url/route.js index 4fa6835..5ac057b 100644 --- a/src/app/api/files/upload-url/route.js +++ b/src/app/api/files/upload-url/route.js @@ -59,6 +59,10 @@ export async function POST(request, { params } = {}) { console.error('UPLOAD-URL: No encrypted metadata found'); return NextResponse.json({ error: 'Invalid encrypted metadata' }, { status: 400 }); } + if (Object.values(encryptedMetadata).some((value) => typeof value !== 'string' || !value.trim())) { + console.error('UPLOAD-URL: Invalid encrypted metadata values'); + return NextResponse.json({ error: 'Invalid encrypted metadata' }, { status: 400 }); + } // Get the internal user ID from the users table using auth_user_id const { data: internalUser, error: userError } = await supabase diff --git a/src/app/api/files/upload-url/route.test.js b/src/app/api/files/upload-url/route.test.js index 3b5f39b..f160965 100644 --- a/src/app/api/files/upload-url/route.test.js +++ b/src/app/api/files/upload-url/route.test.js @@ -69,4 +69,44 @@ describe('POST /api/files/upload-url validation', () => { expect(body.error).toBe('Invalid encrypted metadata'); expect(mocks.from).not.toHaveBeenCalled(); }); + + it('rejects non-string encrypted metadata values before database work', async () => { + const { POST } = await import('./route.js'); + const request = { + json: vi.fn().mockResolvedValue({ + conversationId: 'conversation-1', + messageId: 'message-1', + encryptedMetadata: { + 'user-1': { ciphertext: 'abc' } + } + }) + }; + + const response = await POST(request); + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body.error).toBe('Invalid encrypted metadata'); + expect(mocks.from).not.toHaveBeenCalled(); + }); + + it('rejects blank encrypted metadata values before database work', async () => { + const { POST } = await import('./route.js'); + const request = { + json: vi.fn().mockResolvedValue({ + conversationId: 'conversation-1', + messageId: 'message-1', + encryptedMetadata: { + 'user-1': ' ' + } + }) + }; + + const response = await POST(request); + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body.error).toBe('Invalid encrypted metadata'); + expect(mocks.from).not.toHaveBeenCalled(); + }); });