From e76bb6aff5c8ee05aa4873fd368bd8de84626d72 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Mon, 11 May 2026 09:46:58 -0400 Subject: [PATCH] fix: reject expired retained share creation --- api/server/routes/__tests__/share.spec.js | 11 +++-------- api/server/routes/share.js | 4 ++++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/api/server/routes/__tests__/share.spec.js b/api/server/routes/__tests__/share.spec.js index 7ddd8eeb43..71763bb4de 100644 --- a/api/server/routes/__tests__/share.spec.js +++ b/api/server/routes/__tests__/share.spec.js @@ -105,7 +105,7 @@ describe('share routes retention', () => { ); }); - it('keeps new shares on the parent expiration when the retained conversation expired', async () => { + it('rejects new shares when the retained conversation expired', async () => { mongoose.models.Conversation.findOne.mockReturnValue(lean(expiredRetainedConvo)); createSharedLink.mockResolvedValue({ shareId: 'share-123' }); @@ -113,14 +113,9 @@ describe('share routes retention', () => { .post('/api/share/convo-123') .send({ targetMessageId: 'msg-123' }); - expect(response.status).toBe(200); + expect(response.status).toBe(404); expect(createTempChatExpirationDate).not.toHaveBeenCalled(); - expect(createSharedLink).toHaveBeenCalledWith( - 'user-123', - 'convo-123', - 'msg-123', - expiredRetainedConvo.expiredAt, - ); + expect(createSharedLink).not.toHaveBeenCalled(); }); it('expires updated shares for retained non-temporary conversations', async () => { diff --git a/api/server/routes/share.js b/api/server/routes/share.js index e8370f3e0f..a2be8d8fe1 100644 --- a/api/server/routes/share.js +++ b/api/server/routes/share.js @@ -141,6 +141,10 @@ router.post('/:conversationId', requireJwtAuth, async (req, res) => { try { const { targetMessageId } = req.body; const expiredAt = await getSharedLinkExpiration(req, req.params.conversationId); + if (expiredAt != null && !isActiveExpirationDate(expiredAt)) { + return res.status(404).end(); + } + const created = await createSharedLink( req.user.id, req.params.conversationId,