diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.swift b/SignalServiceKit/src/Messages/Interactions/TSMessage.swift index bb6d5aa466..cdb586dc49 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.swift +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.swift @@ -219,7 +219,22 @@ public extension TSMessage { if messageToDelete is TSOutgoingMessage, authorAddress.isLocalAddress { messageToDelete.markMessageAsRemotelyDeleted(transaction: transaction) return .success - } else if let incomingMessageToDelete = messageToDelete as? TSIncomingMessage { + } else if var incomingMessageToDelete = messageToDelete as? TSIncomingMessage { + if incomingMessageToDelete.editState == .pastRevision { + // The remote delete targeted an old revision, fetch + // swap out the target message for the latest (or return an error) + // This avoids cases where older edits could be deleted and + // leave newer revisions + if let latestEdit = EditMessageFinder.findMessage( + fromEdit: incomingMessageToDelete, + transaction: transaction) as? TSIncomingMessage { + incomingMessageToDelete = latestEdit + } else { + Logger.info("Ignoring delete for missing edit target.") + return .invalidDelete + } + } + guard let messageToDeleteServerTimestamp = incomingMessageToDelete.serverTimestamp?.uint64Value else { // Older messages might be missing this, but since we only allow deleting for a small // window after you send a message we should generally never hit this path. diff --git a/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift b/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift index d6fa9f3ddc..12d21b4990 100644 --- a/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift +++ b/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift @@ -140,12 +140,25 @@ public class ReactionManager: NSObject { return .invalidReaction } - if let message = InteractionFinder.findMessage( + if var message = InteractionFinder.findMessage( withTimestamp: reaction.timestamp, threadId: thread.uniqueId, author: SignalServiceAddress(messageAuthor), transaction: transaction ) { + if message.editState == .pastRevision { + // Reaction targeted an old edit revision, fetch the latest + // version to ensure the reaction shows up properly. + if let latestEdit = EditMessageFinder.findMessage( + fromEdit: message, + transaction: transaction) { + message = latestEdit + } else { + Logger.info("Ignoring reaction for missing edit target.") + return .invalidReaction + } + } + guard !message.wasRemotelyDeleted else { Logger.info("Ignoring reaction for a message that was remotely deleted") return .invalidReaction