diff --git a/src/app/api/files/upload-complete/route.js b/src/app/api/files/upload-complete/route.js index 40ccfb6..7dc940b 100644 --- a/src/app/api/files/upload-complete/route.js +++ b/src/app/api/files/upload-complete/route.js @@ -65,6 +65,10 @@ export async function POST(request, { params } = {}) { console.error('UPLOAD-COMPLETE: Invalid encrypted metadata'); return NextResponse.json({ error: 'Invalid encrypted metadata' }, { status: 400 }); } + if (Object.keys(encryptedMetadata).length === 0) { + console.error('UPLOAD-COMPLETE: No encrypted metadata found'); + 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-complete/route.test.js b/src/app/api/files/upload-complete/route.test.js index 07fe2ba..e545f12 100644 --- a/src/app/api/files/upload-complete/route.test.js +++ b/src/app/api/files/upload-complete/route.test.js @@ -108,4 +108,27 @@ describe('POST /api/files/upload-complete validation', () => { expect(mocks.from).not.toHaveBeenCalled(); expect(mocks.broadcastToRoom).not.toHaveBeenCalled(); }); + + it('rejects empty encrypted metadata before database work', async () => { + const { POST } = await import('./route.js'); + const request = { + json: vi.fn().mockResolvedValue({ + storagePath: 'auth-user-id/conversation-1/file-1', + fileId: 'file-1', + metadata: { + messageId: 'message-1', + conversationId: 'conversation-1', + encryptedMetadata: {} + } + }) + }; + + 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(); + expect(mocks.broadcastToRoom).not.toHaveBeenCalled(); + }); });