🧹 fix: Exclude Mongo ID From Conversation Updates (#14631)

* fix: Exclude Mongo ID from conversation updates

* fix: Limit conversation sync to conversation ID

* fix: Preserve explicit conversation metadata
This commit is contained in:
Danny Avila 2026-08-05 11:24:44 -04:00 committed by GitHub
parent ccf4301093
commit 22642df40c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 3 deletions

View file

@ -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' },
);
});

View file

@ -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);