diff --git a/src/app/api/auth/key-backup/route.js b/src/app/api/auth/key-backup/route.js index e6e7754..4a3ae3b 100644 --- a/src/app/api/auth/key-backup/route.js +++ b/src/app/api/auth/key-backup/route.js @@ -147,7 +147,14 @@ export async function PUT(request) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } - const { encrypted_keys } = await request.json(); + let body; + try { + body = await request.json(); + } catch { + return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 }); + } + + const { encrypted_keys } = body; if (!encrypted_keys || typeof encrypted_keys !== 'string') { return NextResponse.json({ error: 'Missing or invalid encrypted_keys' }, { status: 400 }); diff --git a/src/app/api/auth/key-backup/route.test.js b/src/app/api/auth/key-backup/route.test.js index 4bed3cb..df97b91 100644 --- a/src/app/api/auth/key-backup/route.test.js +++ b/src/app/api/auth/key-backup/route.test.js @@ -108,4 +108,17 @@ describe('key backup cookie authentication', () => { expect(response.status).toBe(200); expect(mocks.authGetUser).toHaveBeenCalledWith('cookie-token'); }); + + it('returns 400 for malformed JSON instead of a generic 500', async () => { + const { PUT } = await import('./route.js'); + const response = await PUT({ + headers: new Headers({ authorization: 'Bearer access-token' }), + json: vi.fn().mockRejectedValue(new SyntaxError('Unexpected token')) + }); + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body.error).toBe('Invalid JSON body'); + expect(mocks.serviceFrom).not.toHaveBeenCalled(); + }); });