Merge pull request #1691 from oxen-io/fix/ses-2804-message-reappearing-account-restored

Making sure restored accounts do not display deleted messages
This commit is contained in:
ThomasSession 2024-10-14 10:59:48 +11:00 committed by GitHub
commit ed1bddd10b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 6 deletions

View File

@ -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( override fun conversationInConfig(
publicKey: String?, publicKey: String?,
groupPublicKey: String?, groupPublicKey: String?,

View File

@ -5,10 +5,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import network.loki.messenger.libsession_util.ConfigBase
import nl.komponents.kovenant.Promise import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.task import nl.komponents.kovenant.task
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.Message 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.CallMessage
import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage
import org.session.libsession.messaging.messages.control.ConfigurationMessage import org.session.libsession.messaging.messages.control.ConfigurationMessage
@ -96,6 +98,26 @@ class BatchMessageReceiveJob(
executeAsync(dispatcherName).get() 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<Unit, Exception> { fun executeAsync(dispatcherName: String): Promise<Unit, Exception> {
return task { return task {
val threadMap = mutableMapOf<Long, MutableList<ParsedMessage>>() val threadMap = mutableMapOf<Long, MutableList<ParsedMessage>>()
@ -112,6 +134,9 @@ class BatchMessageReceiveJob(
val (message, proto) = MessageReceiver.parse(data, openGroupMessageServerID, openGroupPublicKey = serverPublicKey, currentClosedGroups = currentClosedGroups) val (message, proto) = MessageReceiver.parse(data, openGroupMessageServerID, openGroupPublicKey = serverPublicKey, currentClosedGroups = currentClosedGroups)
message.serverHash = serverHash message.serverHash = serverHash
val parsedParams = ParsedMessage(messageParameters, message, proto) val parsedParams = ParsedMessage(messageParameters, message, proto)
if(isHidden(message)) return@forEach
val threadID = Message.getThreadId(message, openGroupID, storage, shouldCreateThread(parsedParams)) ?: NO_THREAD_MAPPING val threadID = Message.getThreadId(message, openGroupID, storage, shouldCreateThread(parsedParams)) ?: NO_THREAD_MAPPING
if (!threadMap.containsKey(threadID)) { if (!threadMap.containsKey(threadID)) {
threadMap[threadID] = mutableListOf(parsedParams) threadMap[threadID] = mutableListOf(parsedParams)

View File

@ -33,12 +33,13 @@ abstract class Message {
companion object { companion object {
fun getThreadId(message: Message, openGroupID: String?, storage: StorageProtocol, shouldCreateThread: Boolean): Long? { fun getThreadId(message: Message, openGroupID: String?, storage: StorageProtocol, shouldCreateThread: Boolean): Long? {
val senderOrSync = when (message) { return storage.getThreadIdFor(message.senderOrSync, message.groupPublicKey, openGroupID, createThread = shouldCreateThread)
is VisibleMessage -> message.syncTarget ?: message.sender!!
is ExpirationTimerUpdate -> message.syncTarget ?: message.sender!!
else -> message.sender!!
} }
return storage.getThreadIdFor(senderOrSync, message.groupPublicKey, openGroupID, createThread = shouldCreateThread)
val Message.senderOrSync get() = when(this) {
is VisibleMessage -> syncTarget ?: sender!!
is ExpirationTimerUpdate -> syncTarget ?: sender!!
else -> sender!!
} }
} }

View File

@ -16,6 +16,8 @@ interface ConfigFactoryProtocol {
fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean
fun canPerformChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean fun canPerformChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean
fun getConfigTimestamp(forConfigObject: ConfigBase, publicKey: String): Long
} }
interface ConfigFactoryUpdateListener { interface ConfigFactoryUpdateListener {