From bf6157997af9edffa6a6112620190febd046b9d4 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Mon, 14 Oct 2024 10:42:10 +1100 Subject: [PATCH] Making sure restored accounts do not display deleted messages When getting messages we check if the contact was marked as hidden and compare the timestamps of both the message and the config object to check whether to re-show the thread or not. --- .../securesms/dependencies/ConfigFactory.kt | 12 +++++++++ .../messaging/jobs/BatchMessageReceiveJob.kt | 25 +++++++++++++++++++ .../libsession/messaging/messages/Message.kt | 13 +++++----- .../utilities/ConfigFactoryProtocol.kt | 2 ++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt index 505a7939a8..12b7960595 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -196,6 +196,18 @@ class ConfigFactory( } } + override fun getConfigTimestamp(forConfigObject: ConfigBase, publicKey: String): Long { + val variant = when (forConfigObject) { + is UserProfile -> SharedConfigMessage.Kind.USER_PROFILE.name + is Contacts -> SharedConfigMessage.Kind.CONTACTS.name + is ConversationVolatileConfig -> SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name + is UserGroupsConfig -> SharedConfigMessage.Kind.GROUPS.name + else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") + } + + return configDatabase.retrieveConfigLastUpdateTimestamp(variant, publicKey) + } + override fun conversationInConfig( publicKey: String?, groupPublicKey: String?, diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt index 7747f7bdbb..64416f116d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt @@ -5,10 +5,12 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking +import network.loki.messenger.libsession_util.ConfigBase import nl.komponents.kovenant.Promise import nl.komponents.kovenant.task import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.Message +import org.session.libsession.messaging.messages.Message.Companion.senderOrSync import org.session.libsession.messaging.messages.control.CallMessage import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage import org.session.libsession.messaging.messages.control.ConfigurationMessage @@ -96,6 +98,26 @@ class BatchMessageReceiveJob( executeAsync(dispatcherName).get() } + private fun isHidden(message: Message): Boolean{ + // if the contact is marked as hidden for 1on1 messages + // and the message's sentTimestamp is earlier than the sentTimestamp of the last config + val config = MessagingModuleConfiguration.shared.configFactory + val publicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() + if(config.contacts == null || message.sentTimestamp == null || publicKey == null) return false + val contactConfigTimestamp = config.getConfigTimestamp(config.contacts!!, publicKey) + if(message.groupPublicKey == null && // not a group + message.openGroupServerMessageID == null && // not a community + // not marked as hidden + config.contacts?.get(message.senderOrSync)?.priority == ConfigBase.PRIORITY_HIDDEN && + // the message's sentTimestamp is earlier than the sentTimestamp of the last config + message.sentTimestamp!! < contactConfigTimestamp + ) { + return true + } + + return false + } + fun executeAsync(dispatcherName: String): Promise { return task { val threadMap = mutableMapOf>() @@ -112,6 +134,9 @@ class BatchMessageReceiveJob( val (message, proto) = MessageReceiver.parse(data, openGroupMessageServerID, openGroupPublicKey = serverPublicKey, currentClosedGroups = currentClosedGroups) message.serverHash = serverHash val parsedParams = ParsedMessage(messageParameters, message, proto) + + if(isHidden(message)) return@forEach + val threadID = Message.getThreadId(message, openGroupID, storage, shouldCreateThread(parsedParams)) ?: NO_THREAD_MAPPING if (!threadMap.containsKey(threadID)) { threadMap[threadID] = mutableListOf(parsedParams) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt index 5a7ecaedaf..36dcd013d2 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt @@ -33,12 +33,13 @@ abstract class Message { companion object { fun getThreadId(message: Message, openGroupID: String?, storage: StorageProtocol, shouldCreateThread: Boolean): Long? { - val senderOrSync = when (message) { - is VisibleMessage -> message.syncTarget ?: message.sender!! - is ExpirationTimerUpdate -> message.syncTarget ?: message.sender!! - else -> message.sender!! - } - return storage.getThreadIdFor(senderOrSync, message.groupPublicKey, openGroupID, createThread = shouldCreateThread) + return storage.getThreadIdFor(message.senderOrSync, message.groupPublicKey, openGroupID, createThread = shouldCreateThread) + } + + val Message.senderOrSync get() = when(this) { + is VisibleMessage -> syncTarget ?: sender!! + is ExpirationTimerUpdate -> syncTarget ?: sender!! + else -> sender!! } } diff --git a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt index 8add1da849..519ce3f035 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt @@ -16,6 +16,8 @@ interface ConfigFactoryProtocol { fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean fun canPerformChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean + + fun getConfigTimestamp(forConfigObject: ConfigBase, publicKey: String): Long } interface ConfigFactoryUpdateListener {