mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 11:05:25 +00:00
Updated the code to ignore messages invalidated by the config
This commit is contained in:
parent
f63ad7e034
commit
4a2289646e
@ -419,6 +419,10 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
notifyUpdates(forConfigObject)
|
notifyUpdates(forConfigObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean {
|
||||||
|
return configFactory.conversationInConfig(publicKey, groupPublicKey, openGroupId, visibleOnly)
|
||||||
|
}
|
||||||
|
|
||||||
override fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean {
|
override fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean {
|
||||||
return configFactory.canPerformChange(variant, publicKey, changeTimestampMs)
|
return configFactory.canPerformChange(variant, publicKey, changeTimestampMs)
|
||||||
}
|
}
|
||||||
@ -1217,6 +1221,11 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
recipientDb.setRecipientHash(recipient, recipientHash)
|
recipientDb.setRecipientHash(recipient, recipientHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getThreadArchived(threadId: Long): Boolean {
|
||||||
|
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
||||||
|
return threadDB.getThreadArchived(threadId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getLastUpdated(threadID: Long): Long {
|
override fun getLastUpdated(threadID: Long): Long {
|
||||||
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
||||||
return threadDB.getLastUpdated(threadID)
|
return threadDB.getLastUpdated(threadID)
|
||||||
|
@ -658,6 +658,24 @@ public class ThreadDatabase extends Database {
|
|||||||
return getOrCreateThreadIdFor(recipient, DistributionTypes.DEFAULT);
|
return getOrCreateThreadIdFor(recipient, DistributionTypes.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getThreadArchived(long threadId) {
|
||||||
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
|
Cursor cursor = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
cursor = db.query(TABLE_NAME, null, ID + " = ?", new String[] {threadId+""}, null, null, null);
|
||||||
|
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
return (cursor.getInt(cursor.getColumnIndexOrThrow(ARCHIVED)) == 1);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cursor != null)
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void setThreadArchived(long threadId) {
|
public void setThreadArchived(long threadId) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(ARCHIVED, 1);
|
contentValues.put(ARCHIVED, 1);
|
||||||
|
@ -13,6 +13,8 @@ import org.session.libsession.utilities.TextSecurePreferences
|
|||||||
import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage
|
import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
import org.thoughtcrime.securesms.database.ConfigDatabase
|
import org.thoughtcrime.securesms.database.ConfigDatabase
|
||||||
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupManager
|
||||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||||
|
|
||||||
class ConfigFactory(
|
class ConfigFactory(
|
||||||
@ -189,6 +191,45 @@ class ConfigFactory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun conversationInConfig(
|
||||||
|
publicKey: String?,
|
||||||
|
groupPublicKey: String?,
|
||||||
|
openGroupId: String?,
|
||||||
|
visibleOnly: Boolean
|
||||||
|
): Boolean {
|
||||||
|
if (!ConfigBase.isNewConfigEnabled(isConfigForcedOn, SnodeAPI.nowWithOffset)) return true
|
||||||
|
|
||||||
|
val (_, userPublicKey) = maybeGetUserInfo() ?: return true
|
||||||
|
|
||||||
|
if (openGroupId != null) {
|
||||||
|
val userGroups = userGroups ?: return false
|
||||||
|
val threadId = GroupManager.getOpenGroupThreadID(openGroupId, context)
|
||||||
|
val openGroup = get(context).lokiThreadDatabase().getOpenGroupChat(threadId) ?: return false
|
||||||
|
|
||||||
|
// Not handling the `hidden` behaviour for communities so just indicate the existence
|
||||||
|
return (userGroups.getCommunityInfo(openGroup.server, openGroup.room) != null)
|
||||||
|
}
|
||||||
|
else if (groupPublicKey != null) {
|
||||||
|
val userGroups = userGroups ?: return false
|
||||||
|
|
||||||
|
// Not handling the `hidden` behaviour for legacy groups so just indicate the existence
|
||||||
|
return (userGroups.getLegacyGroupInfo(groupPublicKey) != null)
|
||||||
|
}
|
||||||
|
else if (publicKey == userPublicKey) {
|
||||||
|
val user = user ?: return false
|
||||||
|
|
||||||
|
return (!visibleOnly || user.getNtsPriority() != ConfigBase.PRIORITY_HIDDEN)
|
||||||
|
}
|
||||||
|
else if (publicKey != null) {
|
||||||
|
val contacts = contacts ?: return false
|
||||||
|
val targetContact = contacts.get(publicKey) ?: return false
|
||||||
|
|
||||||
|
return (!visibleOnly || targetContact.priority != ConfigBase.PRIORITY_HIDDEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
override fun canPerformChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean {
|
override fun canPerformChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean {
|
||||||
if (!ConfigBase.isNewConfigEnabled(isConfigForcedOn, SnodeAPI.nowWithOffset)) return true
|
if (!ConfigBase.isNewConfigEnabled(isConfigForcedOn, SnodeAPI.nowWithOffset)) return true
|
||||||
|
|
||||||
|
@ -166,6 +166,7 @@ interface StorageProtocol {
|
|||||||
fun getThreadId(address: Address): Long?
|
fun getThreadId(address: Address): Long?
|
||||||
fun getThreadId(recipient: Recipient): Long?
|
fun getThreadId(recipient: Recipient): Long?
|
||||||
fun getThreadIdForMms(mmsId: Long): Long
|
fun getThreadIdForMms(mmsId: Long): Long
|
||||||
|
fun getThreadArchived(threadId: Long): Boolean
|
||||||
fun getLastUpdated(threadID: Long): Long
|
fun getLastUpdated(threadID: Long): Long
|
||||||
fun trimThread(threadID: Long, threadLimit: Int)
|
fun trimThread(threadID: Long, threadLimit: Int)
|
||||||
fun trimThreadBefore(threadID: Long, timestamp: Long)
|
fun trimThreadBefore(threadID: Long, timestamp: Long)
|
||||||
@ -224,5 +225,6 @@ interface StorageProtocol {
|
|||||||
|
|
||||||
// Shared configs
|
// Shared configs
|
||||||
fun notifyConfigUpdates(forConfigObject: ConfigBase)
|
fun notifyConfigUpdates(forConfigObject: ConfigBase)
|
||||||
|
fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean
|
||||||
fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean
|
fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean
|
||||||
}
|
}
|
||||||
|
@ -92,15 +92,6 @@ class BatchMessageReceiveJob(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getThreadId(message: Message, 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun execute(dispatcherName: String) {
|
override suspend fun execute(dispatcherName: String) {
|
||||||
executeAsync(dispatcherName).get()
|
executeAsync(dispatcherName).get()
|
||||||
}
|
}
|
||||||
@ -120,7 +111,7 @@ class BatchMessageReceiveJob(
|
|||||||
val (message, proto) = MessageReceiver.parse(data, openGroupMessageServerID, openGroupPublicKey = serverPublicKey)
|
val (message, proto) = MessageReceiver.parse(data, openGroupMessageServerID, openGroupPublicKey = serverPublicKey)
|
||||||
message.serverHash = serverHash
|
message.serverHash = serverHash
|
||||||
val parsedParams = ParsedMessage(messageParameters, message, proto)
|
val parsedParams = ParsedMessage(messageParameters, message, proto)
|
||||||
val threadID = getThreadId(message, 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)
|
||||||
} else {
|
} else {
|
||||||
@ -179,7 +170,7 @@ class BatchMessageReceiveJob(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val messageId = MessageReceiver.handleVisibleMessage(
|
val messageId = MessageReceiver.handleVisibleMessage(
|
||||||
message, proto, openGroupID,
|
message, proto, openGroupID, threadId,
|
||||||
runThreadUpdate = false,
|
runThreadUpdate = false,
|
||||||
runProfileUpdate = true
|
runProfileUpdate = true
|
||||||
)
|
)
|
||||||
@ -209,7 +200,7 @@ class BatchMessageReceiveJob(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> MessageReceiver.handle(message, proto, openGroupID)
|
else -> MessageReceiver.handle(message, proto, threadId, openGroupID)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Couldn't process message (id: $id)", e)
|
Log.e(TAG, "Couldn't process message (id: $id)", e)
|
||||||
|
@ -3,6 +3,7 @@ package org.session.libsession.messaging.jobs
|
|||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.deferred
|
import nl.komponents.kovenant.deferred
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
|
import org.session.libsession.messaging.messages.Message
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
||||||
import org.session.libsession.messaging.sending_receiving.handle
|
import org.session.libsession.messaging.sending_receiving.handle
|
||||||
import org.session.libsession.messaging.utilities.Data
|
import org.session.libsession.messaging.utilities.Data
|
||||||
@ -37,8 +38,9 @@ class MessageReceiveJob(val data: ByteArray, val serverHash: String? = null, val
|
|||||||
MessagingModuleConfiguration.shared.storage.getOpenGroupPublicKey(it.split(".").dropLast(1).joinToString("."))
|
MessagingModuleConfiguration.shared.storage.getOpenGroupPublicKey(it.split(".").dropLast(1).joinToString("."))
|
||||||
}
|
}
|
||||||
val (message, proto) = MessageReceiver.parse(this.data, this.openGroupMessageServerID, openGroupPublicKey = serverPublicKey)
|
val (message, proto) = MessageReceiver.parse(this.data, this.openGroupMessageServerID, openGroupPublicKey = serverPublicKey)
|
||||||
|
val threadId = Message.getThreadId(message, this.openGroupID, MessagingModuleConfiguration.shared.storage, false)
|
||||||
message.serverHash = serverHash
|
message.serverHash = serverHash
|
||||||
MessageReceiver.handle(message, proto, this.openGroupID)
|
MessageReceiver.handle(message, proto, threadId ?: -1, this.openGroupID)
|
||||||
this.handleSuccess(dispatcherName)
|
this.handleSuccess(dispatcherName)
|
||||||
deferred.resolve(Unit)
|
deferred.resolve(Unit)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package org.session.libsession.messaging.messages
|
package org.session.libsession.messaging.messages
|
||||||
|
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
|
import org.session.libsession.database.StorageProtocol
|
||||||
|
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
||||||
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.utilities.GroupUtil
|
import org.session.libsession.utilities.GroupUtil
|
||||||
import org.session.libsignal.protos.SignalServiceProtos
|
import org.session.libsignal.protos.SignalServiceProtos
|
||||||
|
|
||||||
@ -19,6 +22,17 @@ abstract class Message {
|
|||||||
open val ttl: Long = 14 * 24 * 60 * 60 * 1000
|
open val ttl: Long = 14 * 24 * 60 * 60 * 1000
|
||||||
open val isSelfSendValid: Boolean = false
|
open val isSelfSendValid: Boolean = false
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun isValid(): Boolean {
|
open fun isValid(): Boolean {
|
||||||
val sentTimestamp = sentTimestamp
|
val sentTimestamp = sentTimestamp
|
||||||
if (sentTimestamp != null && sentTimestamp <= 0) { return false }
|
if (sentTimestamp != null && sentTimestamp <= 0) { return false }
|
||||||
|
@ -60,22 +60,22 @@ internal fun MessageReceiver.isBlocked(publicKey: String): Boolean {
|
|||||||
return recipient.isBlocked
|
return recipient.isBlocked
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?) {
|
fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content, threadId: Long, openGroupID: String?) {
|
||||||
when (message) {
|
when (message) {
|
||||||
is ReadReceipt -> handleReadReceipt(message)
|
is ReadReceipt -> handleReadReceipt(message)
|
||||||
is TypingIndicator -> handleTypingIndicator(message)
|
is TypingIndicator -> handleTypingIndicator(message)
|
||||||
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
|
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
|
||||||
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message)
|
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message)
|
||||||
is DataExtractionNotification -> handleDataExtractionNotification(message)
|
is DataExtractionNotification -> handleDataExtractionNotification(message, threadId)
|
||||||
is ConfigurationMessage -> handleConfigurationMessage(message)
|
is ConfigurationMessage -> handleConfigurationMessage(message)
|
||||||
is UnsendRequest -> handleUnsendRequest(message)
|
is UnsendRequest -> handleUnsendRequest(message)
|
||||||
is MessageRequestResponse -> handleMessageRequestResponse(message)
|
is MessageRequestResponse -> handleMessageRequestResponse(message, threadId)
|
||||||
is VisibleMessage -> handleVisibleMessage(
|
is VisibleMessage -> handleVisibleMessage(
|
||||||
message, proto, openGroupID,
|
message, proto, openGroupID, threadId,
|
||||||
runThreadUpdate = true,
|
runThreadUpdate = true,
|
||||||
runProfileUpdate = true
|
runProfileUpdate = true
|
||||||
)
|
)
|
||||||
is CallMessage -> handleCallMessage(message)
|
is CallMessage -> handleCallMessage(message, threadId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,33 @@ private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) {
|
|||||||
SSKEnvironment.shared.readReceiptManager.processReadReceipts(context, message.sender!!, message.timestamps!!, message.receivedTimestamp!!)
|
SSKEnvironment.shared.readReceiptManager.processReadReceipts(context, message.sender!!, message.timestamps!!, message.receivedTimestamp!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleCallMessage(message: CallMessage) {
|
private fun MessageReceiver.handleCallMessage(message: CallMessage, threadId: Long) {
|
||||||
|
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
||||||
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
|
val recipient = storage.getRecipientForThread(threadId)
|
||||||
|
val dbThreadIsVisible = (
|
||||||
|
threadId > 0 &&
|
||||||
|
recipient != null &&
|
||||||
|
!recipient.isContactRecipient &&
|
||||||
|
!storage.getThreadArchived(threadId)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!dbThreadIsVisible &&
|
||||||
|
!storage.conversationInConfig(
|
||||||
|
recipient?.address?.serialize(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
) &&
|
||||||
|
!storage.canPerformConfigChange(
|
||||||
|
SharedConfigMessage.Kind.CONTACTS.name,
|
||||||
|
userPublicKey,
|
||||||
|
message.sentTimestamp!!
|
||||||
|
)
|
||||||
|
) { return }
|
||||||
|
|
||||||
// TODO: refactor this out to persistence, just to help debug the flow and send/receive in synchronous testing
|
// TODO: refactor this out to persistence, just to help debug the flow and send/receive in synchronous testing
|
||||||
WebRtcUtils.SIGNAL_QUEUE.trySend(message)
|
WebRtcUtils.SIGNAL_QUEUE.trySend(message)
|
||||||
}
|
}
|
||||||
@ -126,11 +152,37 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
|
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification, threadId: Long) {
|
||||||
// We don't handle data extraction messages for groups (they shouldn't be sent, but just in case we filter them here too)
|
// We don't handle data extraction messages for groups (they shouldn't be sent, but just in case we filter them here too)
|
||||||
if (message.groupPublicKey != null) return
|
if (message.groupPublicKey != null) return
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
val senderPublicKey = message.sender!!
|
val senderPublicKey = message.sender!!
|
||||||
|
|
||||||
|
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
||||||
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
|
val recipient = storage.getRecipientForThread(threadId)
|
||||||
|
val dbThreadIsVisible = (
|
||||||
|
threadId > 0 &&
|
||||||
|
recipient != null &&
|
||||||
|
!recipient.isContactRecipient &&
|
||||||
|
!storage.getThreadArchived(threadId)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!dbThreadIsVisible &&
|
||||||
|
!storage.conversationInConfig(
|
||||||
|
recipient?.address?.serialize(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
) &&
|
||||||
|
!storage.canPerformConfigChange(
|
||||||
|
if (recipient?.address?.serialize() == userPublicKey) SharedConfigMessage.Kind.USER_PROFILE.name else SharedConfigMessage.Kind.CONTACTS.name,
|
||||||
|
userPublicKey,
|
||||||
|
message.sentTimestamp!!
|
||||||
|
)
|
||||||
|
) { return }
|
||||||
|
|
||||||
val notification: DataExtractionNotificationInfoMessage = when(message.kind) {
|
val notification: DataExtractionNotificationInfoMessage = when(message.kind) {
|
||||||
is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT)
|
is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT)
|
||||||
is DataExtractionNotification.Kind.MediaSaved -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED)
|
is DataExtractionNotification.Kind.MediaSaved -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED)
|
||||||
@ -215,7 +267,33 @@ fun MessageReceiver.handleUnsendRequest(message: UnsendRequest): Long? {
|
|||||||
return deletedMessageId
|
return deletedMessageId
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleMessageRequestResponse(message: MessageRequestResponse) {
|
fun handleMessageRequestResponse(message: MessageRequestResponse, threadId: Long) {
|
||||||
|
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
||||||
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
|
val recipient = storage.getRecipientForThread(threadId)
|
||||||
|
val dbThreadIsVisible = (
|
||||||
|
threadId > 0 &&
|
||||||
|
recipient != null &&
|
||||||
|
!recipient.isContactRecipient &&
|
||||||
|
!storage.getThreadArchived(threadId)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!dbThreadIsVisible &&
|
||||||
|
!storage.conversationInConfig(
|
||||||
|
recipient?.address?.serialize(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
) &&
|
||||||
|
!storage.canPerformConfigChange(
|
||||||
|
SharedConfigMessage.Kind.CONTACTS.name,
|
||||||
|
userPublicKey,
|
||||||
|
message.sentTimestamp!!
|
||||||
|
)
|
||||||
|
) { return }
|
||||||
|
|
||||||
MessagingModuleConfiguration.shared.storage.insertMessageRequestResponse(message)
|
MessagingModuleConfiguration.shared.storage.insertMessageRequestResponse(message)
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
@ -224,20 +302,45 @@ fun MessageReceiver.handleVisibleMessage(
|
|||||||
message: VisibleMessage,
|
message: VisibleMessage,
|
||||||
proto: SignalServiceProtos.Content,
|
proto: SignalServiceProtos.Content,
|
||||||
openGroupID: String?,
|
openGroupID: String?,
|
||||||
|
threadId: Long,
|
||||||
runThreadUpdate: Boolean,
|
runThreadUpdate: Boolean,
|
||||||
runProfileUpdate: Boolean
|
runProfileUpdate: Boolean
|
||||||
): Long? {
|
): Long? {
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
val context = MessagingModuleConfiguration.shared.context
|
val context = MessagingModuleConfiguration.shared.context
|
||||||
val userPublicKey = storage.getUserPublicKey()
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
val messageSender: String? = message.sender
|
val messageSender: String? = message.sender
|
||||||
|
|
||||||
|
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
||||||
|
val threadRecipient = storage.getRecipientForThread(threadId)
|
||||||
|
val dbThreadIsVisible = (
|
||||||
|
threadId > 0 &&
|
||||||
|
threadRecipient != null &&
|
||||||
|
!threadRecipient.isContactRecipient &&
|
||||||
|
!storage.getThreadArchived(threadId)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!dbThreadIsVisible &&
|
||||||
|
!storage.conversationInConfig(
|
||||||
|
if (message.groupPublicKey == null) threadRecipient?.address?.serialize() else null,
|
||||||
|
message.groupPublicKey,
|
||||||
|
openGroupID,
|
||||||
|
true
|
||||||
|
) &&
|
||||||
|
!storage.canPerformConfigChange(
|
||||||
|
if (threadRecipient?.address?.serialize() == userPublicKey) SharedConfigMessage.Kind.USER_PROFILE.name else SharedConfigMessage.Kind.CONTACTS.name,
|
||||||
|
userPublicKey,
|
||||||
|
message.sentTimestamp!!
|
||||||
|
)
|
||||||
|
) { return null }
|
||||||
|
|
||||||
// Get or create thread
|
// Get or create thread
|
||||||
// FIXME: In case this is an open group this actually * doesn't * create the thread if it doesn't yet
|
// FIXME: In case this is an open group this actually * doesn't * create the thread if it doesn't yet
|
||||||
// exist. This is intentional, but it's very non-obvious.
|
// exist. This is intentional, but it's very non-obvious.
|
||||||
val threadID = storage.getThreadIdFor(message.syncTarget ?: messageSender!!, message.groupPublicKey, openGroupID, createThread = true)
|
val threadID = storage.getThreadIdFor(message.syncTarget ?: messageSender!!, message.groupPublicKey, openGroupID, createThread = true)
|
||||||
// Thread doesn't exist; should only be reached in a case where we are processing open group messages for a no longer existent thread
|
// Thread doesn't exist; should only be reached in a case where we are processing open group messages for a no longer existent thread
|
||||||
?: throw MessageReceiver.Error.NoThread
|
?: throw MessageReceiver.Error.NoThread
|
||||||
val threadRecipient = storage.getRecipientForThread(threadID)
|
|
||||||
val userBlindedKey = openGroupID?.let {
|
val userBlindedKey = openGroupID?.let {
|
||||||
val openGroup = storage.getOpenGroup(threadID) ?: return@let null
|
val openGroup = storage.getOpenGroup(threadID) ?: return@let null
|
||||||
val blindedKey = SodiumUtilities.blindedKeyPair(openGroup.publicKey, MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!) ?: return@let null
|
val blindedKey = SodiumUtilities.blindedKeyPair(openGroup.publicKey, MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!) ?: return@let null
|
||||||
|
@ -12,6 +12,7 @@ import org.session.libsession.messaging.jobs.MessageReceiveJob
|
|||||||
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||||
import org.session.libsession.messaging.jobs.OpenGroupDeleteJob
|
import org.session.libsession.messaging.jobs.OpenGroupDeleteJob
|
||||||
import org.session.libsession.messaging.jobs.TrimThreadJob
|
import org.session.libsession.messaging.jobs.TrimThreadJob
|
||||||
|
import org.session.libsession.messaging.messages.Message
|
||||||
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.messaging.open_groups.Endpoint
|
import org.session.libsession.messaging.open_groups.Endpoint
|
||||||
@ -261,7 +262,8 @@ class OpenGroupPoller(private val server: String, private val executorService: S
|
|||||||
}
|
}
|
||||||
mappingCache[it.recipient] = mapping
|
mappingCache[it.recipient] = mapping
|
||||||
}
|
}
|
||||||
MessageReceiver.handle(message, proto, null)
|
val threadId = Message.getThreadId(message, null, MessagingModuleConfiguration.shared.storage, false)
|
||||||
|
MessageReceiver.handle(message, proto, threadId ?: -1, null)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("Loki", "Couldn't handle direct message", e)
|
Log.e("Loki", "Couldn't handle direct message", e)
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ interface ConfigFactoryProtocol {
|
|||||||
val userGroups: UserGroupsConfig?
|
val userGroups: UserGroupsConfig?
|
||||||
fun getUserConfigs(): List<ConfigBase>
|
fun getUserConfigs(): List<ConfigBase>
|
||||||
fun persist(forConfigObject: ConfigBase, timestamp: Long)
|
fun persist(forConfigObject: ConfigBase, timestamp: Long)
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user