From 3bfa150348a90572088cb3276a7ceb19ac1c4e73 Mon Sep 17 00:00:00 2001 From: automated-signal <37887102+automated-signal@users.noreply.github.com> Date: Wed, 1 Apr 2026 11:47:31 -0500 Subject: [PATCH] Fix sending receipts to terminated groups Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com> --- ts/jobs/helpers/sendPollTerminate.preload.ts | 4 +++- ts/jobs/helpers/sendPollVote.preload.ts | 4 +++- ts/jobs/helpers/sendProfileKey.preload.ts | 2 +- ts/jobs/helpers/sendReceipts.preload.ts | 7 ++++++- .../sendSenderKeyDistribution.preload.ts | 2 +- .../shouldSendToConversation.preload.ts | 8 ++++++-- ts/messages/handleDataMessage.preload.ts | 18 +++++++++--------- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/ts/jobs/helpers/sendPollTerminate.preload.ts b/ts/jobs/helpers/sendPollTerminate.preload.ts index 58d05785f7..ed29792f40 100644 --- a/ts/jobs/helpers/sendPollTerminate.preload.ts +++ b/ts/jobs/helpers/sendPollTerminate.preload.ts @@ -190,7 +190,9 @@ export async function sendPollTerminate( `${logId}: expected GroupV2 conversation when not direct` ); - const shouldSend = shouldSendToConversation(conversation, jobLog); + const shouldSend = shouldSendToConversation(conversation, { + log: jobLog, + }); if (!shouldSend) { return; } diff --git a/ts/jobs/helpers/sendPollVote.preload.ts b/ts/jobs/helpers/sendPollVote.preload.ts index fa8a033583..9f941fb492 100644 --- a/ts/jobs/helpers/sendPollVote.preload.ts +++ b/ts/jobs/helpers/sendPollVote.preload.ts @@ -242,7 +242,9 @@ export async function sendPollVote( urgent: true, }); } else { - const shouldSend = shouldSendToConversation(conversation, jobLog); + const shouldSend = shouldSendToConversation(conversation, { + log: jobLog, + }); if (!shouldSend) { setMessagePollVoteFailed(pollMessage, currentPendingVote); await window.MessageCache.saveMessage(pollMessage.attributes); diff --git a/ts/jobs/helpers/sendProfileKey.preload.ts b/ts/jobs/helpers/sendProfileKey.preload.ts index e1f549fc5f..777fd684e7 100644 --- a/ts/jobs/helpers/sendProfileKey.preload.ts +++ b/ts/jobs/helpers/sendProfileKey.preload.ts @@ -107,7 +107,7 @@ export async function sendProfileKey( // Note: flags and the profileKey itself are all that matter in the proto. - if (!shouldSendToConversation(conversation, log)) { + if (!shouldSendToConversation(conversation, { log })) { return; } diff --git a/ts/jobs/helpers/sendReceipts.preload.ts b/ts/jobs/helpers/sendReceipts.preload.ts index 5bf8c68859..a8b9501003 100644 --- a/ts/jobs/helpers/sendReceipts.preload.ts +++ b/ts/jobs/helpers/sendReceipts.preload.ts @@ -14,7 +14,12 @@ export async function sendReceipts( { log }: ConversationQueueJobBundle, data: ReceiptsJobData ): Promise { - if (!shouldSendToConversation(conversation, log)) { + if ( + !shouldSendToConversation(conversation, { + log, + shouldSendToTerminatedGroups: true, + }) + ) { return; } await sendReceiptsTask({ diff --git a/ts/jobs/helpers/sendSenderKeyDistribution.preload.ts b/ts/jobs/helpers/sendSenderKeyDistribution.preload.ts index cdb24b4716..31ee5d93e6 100644 --- a/ts/jobs/helpers/sendSenderKeyDistribution.preload.ts +++ b/ts/jobs/helpers/sendSenderKeyDistribution.preload.ts @@ -54,7 +54,7 @@ export async function sendSenderKeyDistribution( return; } - if (!shouldSendToConversation(conversation, log)) { + if (!shouldSendToConversation(conversation, { log })) { return; } diff --git a/ts/jobs/helpers/shouldSendToConversation.preload.ts b/ts/jobs/helpers/shouldSendToConversation.preload.ts index 956a750e9a..20c54ff85e 100644 --- a/ts/jobs/helpers/shouldSendToConversation.preload.ts +++ b/ts/jobs/helpers/shouldSendToConversation.preload.ts @@ -16,8 +16,12 @@ type ConversationForDirectSendType = Pick< export function shouldSendToConversation( conversation: ConversationModel, - log: LoggerType + options: { + log: LoggerType; + shouldSendToTerminatedGroups?: boolean; + } ): boolean { + const { log, shouldSendToTerminatedGroups = false } = options; const recipients = getRecipients(conversation.attributes); const untrustedServiceIds = getUntrustedConversationServiceIds(recipients); @@ -42,7 +46,7 @@ export function shouldSendToConversation( return false; } - if (conversation.get('terminated')) { + if (!shouldSendToTerminatedGroups && conversation.get('terminated')) { log.info( `conversation ${conversation.idForLogging()} is terminated; refusing to send` ); diff --git a/ts/messages/handleDataMessage.preload.ts b/ts/messages/handleDataMessage.preload.ts index 02869f5ed2..4fc9ec94ec 100644 --- a/ts/messages/handleDataMessage.preload.ts +++ b/ts/messages/handleDataMessage.preload.ts @@ -365,15 +365,6 @@ export async function handleDataMessage( } } - // Drop incoming messages to terminated groups - if (conversation.get('terminated')) { - log.warn( - `Received message for terminated group ${conversation.idForLogging()}. Dropping.` - ); - confirm(); - return; - } - const messageId = message.get('id') || generateMessageId(message.get('received_at')).id; @@ -406,6 +397,15 @@ export async function handleDataMessage( ); } + // Drop incoming messages to terminated groups + if (conversation.get('terminated')) { + log.warn( + `Received message for terminated group ${conversation.idForLogging()}. Dropping.` + ); + confirm(); + return; + } + const { storyContext } = initialMessage; let storyContextLogId = 'no storyContext'; if (storyContext) {