diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt index 302a9b0a18..e8ddda17a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt @@ -16,7 +16,6 @@ import network.loki.messenger.libsession_util.util.INVITE_STATUS_SENT import network.loki.messenger.libsession_util.util.UserPic import org.session.libsession.database.StorageProtocol import org.session.libsession.database.userAuth -import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.groups.GroupManagerV2 import org.session.libsession.messaging.jobs.InviteContactsJob @@ -282,7 +281,8 @@ class GroupManagerV2Impl @Inject constructor( ) .build() ).apply { this.sentTimestamp = timestamp } - MessageSender.send(updatedMessage, Address.fromSerialized(group.hexString)) + MessageSender.send(updatedMessage, Destination.ClosedGroup(group.hexString), false).await() + storage.insertGroupInfoChange(updatedMessage, group) } override suspend fun removeMembers( @@ -461,11 +461,13 @@ class GroupManagerV2Impl @Inject constructor( sentTimestamp = timestamp } - MessageSender.send(message, Address.fromSerialized(group.hexString)) + MessageSender.send(message, Destination.ClosedGroup(group.hexString), false).await() + storage.insertGroupInfoChange(message, group) } private suspend fun flagMembersForRemoval( - group: AccountId, members: List, + group: AccountId, + members: List, alsoRemoveMembersMessage: Boolean, sendMemberChangeMessage: Boolean ) { @@ -505,6 +507,7 @@ class GroupManagerV2Impl @Inject constructor( ).apply { sentTimestamp = timestamp } MessageSender.send(message, Destination.ClosedGroup(group.hexString), false).await() + storage.insertGroupInfoChange(message, group) } } @@ -576,28 +579,21 @@ class GroupManagerV2Impl @Inject constructor( groupName: String, authData: ByteArray, inviter: AccountId, - inviteMessageHash: String? - ) = withContext(dispatcher) { + inviteMessageHash: String, + inviteMessageTimestamp: Long, + ): Unit = withContext(dispatcher) { handleInvitation( groupId = groupId, groupName = groupName, authDataOrAdminKey = authData, fromPromotion = false, - inviter = inviter + inviter = inviter, + inviteMessageTimestamp = inviteMessageTimestamp, ) - // Delete the invite message remotely - if (inviteMessageHash != null) { - val auth = requireNotNull(storage.userAuth) { "No current user available" } - SnodeAPI.sendBatchRequest( - snode = SnodeAPI.getSingleTargetSnode(groupId.hexString).await(), - publicKey = auth.accountId.hexString, - request = SnodeAPI.buildAuthenticatedDeleteBatchInfo( - auth, - listOf(inviteMessageHash) - ), - ) - } + // Once we are done, delete the invite message remotely + val auth = requireNotNull(storage.userAuth) { "No current user available" } + SnodeAPI.deleteMessage(groupId.hexString, auth, listOf(inviteMessageHash)) } override suspend fun handlePromotion( @@ -605,8 +601,9 @@ class GroupManagerV2Impl @Inject constructor( groupName: String, adminKey: ByteArray, promoter: AccountId, - promoteMessageHash: String? - ) = withContext(dispatcher) { + promoteMessageHash: String, + promoteMessageTimestamp: Long, + ): Unit = withContext(dispatcher) { val userAuth = requireNotNull(storage.userAuth) { "No current user available" } val group = configFactory.getClosedGroup(groupId) @@ -620,6 +617,7 @@ class GroupManagerV2Impl @Inject constructor( authDataOrAdminKey = adminKey, fromPromotion = true, inviter = promoter, + inviteMessageTimestamp = promoteMessageTimestamp, ) } else { // If we have the group in the config, we can just update the admin key @@ -639,13 +637,11 @@ class GroupManagerV2Impl @Inject constructor( } // Delete the promotion message remotely - if (promoteMessageHash != null) { - SnodeAPI.deleteMessage( - userAuth.accountId.hexString, - userAuth, - listOf(promoteMessageHash) - ).await() - } + SnodeAPI.deleteMessage( + userAuth.accountId.hexString, + userAuth, + listOf(promoteMessageHash) + ) } /** @@ -664,6 +660,7 @@ class GroupManagerV2Impl @Inject constructor( authDataOrAdminKey: ByteArray, fromPromotion: Boolean, inviter: AccountId, + inviteMessageTimestamp: Long ) { // If we have already received an invitation in the past, we should not process this one if (configFactory.getClosedGroup(groupId)?.invited == true) { @@ -697,7 +694,7 @@ class GroupManagerV2Impl @Inject constructor( } else { lokiDatabase.addGroupInviteReferrer(groupThreadId, inviter.hexString) storage.insertGroupInviteControlMessage( - clock.currentTimeMills(), + inviteMessageTimestamp, inviter.hexString, groupId, groupName @@ -868,8 +865,7 @@ class GroupManagerV2Impl @Inject constructor( sentTimestamp = timestamp } - val groupAddress = Address.fromSerialized(groupId.hexString) - MessageSender.sendNonDurably(message, groupAddress, false).await() + MessageSender.send(message, Destination.ClosedGroup(groupId.hexString), false).await() } override suspend fun handleDeleteMemberContent( diff --git a/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt b/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt index c78dc6e762..7c5b58801d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt @@ -54,7 +54,8 @@ interface GroupManagerV2 { groupName: String, authData: ByteArray, inviter: AccountId, - inviteMessageHash: String? + inviteMessageHash: String, + inviteMessageTimestamp: Long, ) suspend fun handlePromotion( @@ -62,7 +63,8 @@ interface GroupManagerV2 { groupName: String, adminKey: ByteArray, promoter: AccountId, - promoteMessageHash: String? + promoteMessageHash: String, + promoteMessageTimestamp: Long, ) suspend fun respondToInvitation(groupId: AccountId, approved: Boolean): Unit? diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 54b6824804..77b474229b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -229,8 +229,8 @@ object MessageSender { if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend()) { SnodeModule.shared.broadcaster.broadcast("messageFailed", message.sentTimestamp!!) } - throw error } + try { val snodeMessage = buildWrappedMessageToSnode(destination, message, isSyncMessage) // TODO: this might change in future for config messages @@ -273,10 +273,10 @@ object MessageSender { runCatching { it.await() } } - val firstSuccess = sendTaskResults.firstOrNull { it.isSuccess } + val firstSuccess = sendTaskResults.firstOrNull { it.isSuccess }?.getOrNull() if (firstSuccess != null) { - message.serverHash = firstSuccess.getOrThrow().hash + message.serverHash = firstSuccess.hash handleSuccessfulMessageSend(message, destination, isSyncMessage) } else { // If all tasks failed, throw the first exception @@ -284,6 +284,7 @@ object MessageSender { } } catch (exception: Exception) { handleFailure(exception) + throw exception } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index be4756d835..333bdce1d6 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -665,7 +665,8 @@ private fun handlePromotionMessage(message: GroupUpdated) { groupName = promotion.name, adminKey = keyPair.secretKey, promoter = adminId, - promoteMessageHash = message.serverHash + promoteMessageHash = message.serverHash!!, + promoteMessageTimestamp = message.sentTimestamp!!, ) } catch (e: Exception) { Log.e("GroupUpdated", "Failed to handle promotion message", e) @@ -708,7 +709,8 @@ private fun MessageReceiver.handleNewLibSessionClosedGroupMessage(message: Group groupName = invite.name, authData = invite.memberAuthData.toByteArray(), inviter = adminId, - inviteMessageHash = message.serverHash + inviteMessageHash = message.serverHash!!, + inviteMessageTimestamp = message.sentTimestamp!!, ) } catch (e: Exception) { Log.e("GroupUpdated", "Failed to handle invite message", e)