diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 64e9d3cf1..d8e3e9a2e 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -39,7 +39,7 @@ import { isUsFromCache } from '../session/utils/User'; import { changeToDisappearingMessageType, checkForExpireUpdateInContentMessage, - checkHasOutdatedClient, + checkHasOutdatedDisappearingMessageClient, setExpirationStartTimestamp, } from '../util/expiringMessages'; @@ -449,6 +449,14 @@ export async function innerHandleSwarmContentMessage( // We need to make sure that we trigger the outdated client banner ui on the correct model for the conversation and not the author (for closed groups) let conversationModelForUIUpdate = senderConversationModel; + // For a private synced message, we need to make sure we have the conversation with the syncTarget + if (isPrivateConversationMessage && content.dataMessage?.syncTarget) { + conversationModelForUIUpdate = await getConversationController().getOrCreateAndWait( + content.dataMessage.syncTarget, + ConversationTypeEnum.PRIVATE + ); + } + /** * For a closed group message, this holds the closed group's conversation. * For a private conversation message, this is just the conversation with that user @@ -479,7 +487,7 @@ export async function innerHandleSwarmContentMessage( // TODO legacy messages support will be removed in a future release if (expireUpdate.isDisappearingMessagesV2Released) { - await checkHasOutdatedClient( + await checkHasOutdatedDisappearingMessageClient( conversationModelForUIUpdate, senderConversationModel, expireUpdate diff --git a/ts/util/expiringMessages.ts b/ts/util/expiringMessages.ts index 4b04f5da5..af5b35deb 100644 --- a/ts/util/expiringMessages.ts +++ b/ts/util/expiringMessages.ts @@ -44,6 +44,7 @@ export type DisappearingMessageUpdate = { isLegacyConversationSettingMessage?: boolean; isLegacyDataMessage?: boolean; isDisappearingMessagesV2Released?: boolean; + shouldDisappearButIsntMessage?: boolean; }; export async function destroyMessagesAndUpdateRedux( @@ -365,7 +366,34 @@ function checkIsLegacyDisappearingContentMessage(contentMessage: SignalService.C ); } -function checkIsLegacyDisappearingDataMessage(dataMessage: SignalService.DataMessage): boolean { +/** + * Checks if a message is meant to disappear but doesn't have the correct expiration values set + * + * NOTE Examples: legacy disappearing message conversation settings, synced messages from legacy devices + */ +function checkDisappearButIsntMessage( + content: SignalService.Content, + convo: ConversationModel, + expirationMode: DisappearingMessageConversationType, + expirationTimer: number +): boolean { + window.log.debug( + `WIP: expirationMode ${expirationMode} expirationTimer ${expirationTimer} content ${JSON.stringify( + content + )} convo ${JSON.stringify(convo)}` + ); + return ( + content.dataMessage?.flags !== SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE && + expirationMode === 'off' && + expirationTimer === 0 && + convo.get('expirationType') !== 'off' && + convo.get('expireTimer') !== 0 + ); +} + +export function checkIsLegacyDisappearingDataMessage( + dataMessage: SignalService.DataMessage +): boolean { return ( ProtobufUtils.hasDefinedProperty(dataMessage, 'expireTimer') && dataMessage.expireTimer > -1 ); @@ -406,6 +434,13 @@ export async function checkForExpireUpdateInContentMessage( ? Number(content.lastDisappearingMessageChangeTimestamp) : undefined; + const shouldDisappearButIsntMessage = checkDisappearButIsntMessage( + content, + convoToUpdate, + expirationMode, + expirationTimer + ); + const expireUpdate: DisappearingMessageUpdate = { expirationType: changeToDisappearingMessageType(convoToUpdate, expirationTimer, expirationMode), expirationTimer, @@ -413,6 +448,7 @@ export async function checkForExpireUpdateInContentMessage( isLegacyConversationSettingMessage, isLegacyDataMessage, isDisappearingMessagesV2Released, + shouldDisappearButIsntMessage, }; // NOTE some platforms do not include the diappearing message values in the Data Message for sent messages so we have to trust the conversation settings until v2 is released @@ -442,15 +478,6 @@ export async function checkForExpireUpdateInContentMessage( } } - // TODO should review this - // NOTE this is only required for legacy disappearing message conversation settings I think? - const shouldDisappearButIsntMessage = - dataMessage.flags !== SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE && - expirationMode === 'off' && - expirationTimer === 0 && - convoToUpdate.get('expirationType') !== 'off' && - convoToUpdate.get('expireTimer') !== 0; - // NOTE If it is a legacy message and disappearing messages v2 is released then we ignore it and use the local client's conversation settings and show the outdated client banner if ( isDisappearingMessagesV2Released && @@ -525,13 +552,16 @@ export function updateMessageModelToExpire( return messageModel; } -export async function checkHasOutdatedClient( +export async function checkHasOutdatedDisappearingMessageClient( convoToUpdate: ConversationModel, sender: ConversationModel, expireUpdate: DisappearingMessageUpdate ) { const isOutdated = - expireUpdate.isLegacyDataMessage || expireUpdate.isLegacyConversationSettingMessage; + expireUpdate.isLegacyDataMessage || + expireUpdate.isLegacyConversationSettingMessage || + expireUpdate.shouldDisappearButIsntMessage; + const outdatedSender = sender.get('nickname') || sender.get('displayNameInProfile') || sender.get('id');