From 22642df40cbb6663b4f6dc50faba239932865231 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Wed, 5 Aug 2026 11:24:44 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20fix:=20Exclude=20Mongo=20ID=20Fr?= =?UTF-8?q?om=20Conversation=20Updates=20(#14631)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Exclude Mongo ID from conversation updates * fix: Limit conversation sync to conversation ID * fix: Preserve explicit conversation metadata --- .../routes/__tests__/messages-get.spec.js | 19 +++++++++++++++++-- api/server/routes/messages.js | 10 +++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/api/server/routes/__tests__/messages-get.spec.js b/api/server/routes/__tests__/messages-get.spec.js index fd75898942..fc9971bb95 100644 --- a/api/server/routes/__tests__/messages-get.spec.js +++ b/api/server/routes/__tests__/messages-get.spec.js @@ -110,13 +110,20 @@ describe('message route conversation ownership filters', () => { }); }); - it('should save POST messages with the validated URL conversationId', async () => { + it('should pass only mutable conversation fields to saveConvo', async () => { const urlConversationId = '11111111-1111-4111-8111-111111111111'; const bodyConversationId = '22222222-2222-4222-8222-222222222222'; const savedMessage = { + _id: 'message-object-id', + __v: 0, messageId: 'message-1', conversationId: urlConversationId, text: 'hello', + endpoint: 'openAI', + model: 'gpt-5', + iconURL: 'https://example.com/icon.png', + isTemporary: false, + files: [{ file_id: 'file-1' }], user: authenticatedUserId, }; @@ -127,6 +134,9 @@ describe('message route conversation ownership filters', () => { messageId: savedMessage.messageId, conversationId: bodyConversationId, text: savedMessage.text, + endpoint: savedMessage.endpoint, + model: savedMessage.model, + iconURL: savedMessage.iconURL, }); expect(response.status).toBe(201); @@ -143,7 +153,12 @@ describe('message route conversation ownership filters', () => { expect(saveMessage.mock.calls[0][1].conversationId).not.toBe(bodyConversationId); expect(saveConvo).toHaveBeenCalledWith( expect.objectContaining({ userId: authenticatedUserId }), - savedMessage, + { + conversationId: urlConversationId, + endpoint: savedMessage.endpoint, + model: savedMessage.model, + iconURL: savedMessage.iconURL, + }, { context: 'POST /api/messages/:conversationId' }, ); }); diff --git a/api/server/routes/messages.js b/api/server/routes/messages.js index 1c4a8ddc74..0425b40eaa 100644 --- a/api/server/routes/messages.js +++ b/api/server/routes/messages.js @@ -324,7 +324,15 @@ router.post('/:conversationId', validateMessageReq, async (req, res) => { if (!savedMessage) { return res.status(400).json({ error: 'Message not saved' }); } - await db.saveConvo(reqCtx, savedMessage, { context: 'POST /api/messages/:conversationId' }); + const conversationUpdate = { + conversationId: savedMessage.conversationId, + ...(message.endpoint !== undefined && { endpoint: savedMessage.endpoint }), + ...(message.model !== undefined && { model: savedMessage.model }), + ...(message.iconURL !== undefined && { iconURL: savedMessage.iconURL }), + }; + await db.saveConvo(reqCtx, conversationUpdate, { + context: 'POST /api/messages/:conversationId', + }); res.status(201).json(savedMessage); } catch (error) { logger.error('Error saving message:', error);