Skip to content

Commit d833cd9

Browse files
[SES-4626] - Blinded message request improvement (#1542)
1 parent 76deb15 commit d833cd9

File tree

4 files changed

+88
-32
lines changed

4 files changed

+88
-32
lines changed

app/src/main/java/org/session/libsession/messaging/sending_receiving/MessageRequestResponseHandler.kt

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package org.session.libsession.messaging.sending_receiving
22

3+
import org.session.libsession.messaging.messages.Message
34
import org.session.libsession.messaging.messages.ProfileUpdateHandler
45
import org.session.libsession.messaging.messages.ProfileUpdateHandler.Updates.Companion.toUpdates
56
import org.session.libsession.messaging.messages.control.MessageRequestResponse
67
import org.session.libsession.messaging.messages.signal.IncomingMediaMessage
8+
import org.session.libsession.messaging.messages.visible.VisibleMessage
79
import org.session.libsession.utilities.Address
810
import org.session.libsession.utilities.Address.Companion.toAddress
911
import org.session.libsession.utilities.ConfigFactoryProtocol
12+
import org.session.libsession.utilities.recipients.Recipient
1013
import org.session.libsession.utilities.updateContact
1114
import org.session.libsession.utilities.upsertContact
1215
import org.session.libsignal.utilities.Log
@@ -30,23 +33,81 @@ class MessageRequestResponseHandler @Inject constructor(
3033
private val blindMappingRepository: BlindMappingRepository,
3134
) {
3235

33-
suspend fun handle(message: MessageRequestResponse) {
36+
suspend fun handleVisibleMessage(message: VisibleMessage) {
37+
val (sender, receiver) = fetchSenderAndReceiver(message) ?: return
38+
39+
val allBlindedAddresses = blindMappingRepository.calculateReverseMappings(
40+
contactAddress = sender.address as Address.Standard
41+
)
42+
43+
// Do we have an existing message request (including blinded requests)?
44+
val hasMessageRequest = configFactory.withUserConfigs { configs ->
45+
val existingContact = configs.contacts.get(sender.address.accountId.hexString)
46+
if (existingContact != null && existingContact.approved && !existingContact.approvedMe) {
47+
return@withUserConfigs true
48+
}
49+
50+
allBlindedAddresses.any { (_, blindedId) ->
51+
configs.contacts.getBlinded(blindedId.blindedId.hexString) != null
52+
}
53+
}
54+
55+
if (hasMessageRequest) {
56+
handleRequestResponse(
57+
messageSender = sender,
58+
messageReceiver = receiver,
59+
messageTimestampMs = message.sentTimestamp!!,
60+
)
61+
}
62+
}
63+
64+
suspend fun handleExplicitRequestResponseMessage(message: MessageRequestResponse) {
65+
val (sender, receiver) = fetchSenderAndReceiver(message) ?: return
66+
// Always handle explicit request response
67+
handleRequestResponse(
68+
messageSender = sender,
69+
messageReceiver = receiver,
70+
messageTimestampMs = message.sentTimestamp!!,
71+
)
72+
73+
// Always process the profile update if any. We don't need
74+
// to process profile for other kind of messages as they should be handled elsewhere
75+
message.profile?.toUpdates()?.let { updates ->
76+
profileUpdateHandler.get().handleProfileUpdate(
77+
senderId = (sender.address as Address.Standard).accountId,
78+
updates = updates,
79+
fromCommunity = null
80+
)
81+
}
82+
}
83+
84+
private suspend fun fetchSenderAndReceiver(message: Message): Pair<Recipient, Recipient>? {
3485
val messageSender = recipientRepository.getRecipient(
3586
requireNotNull(message.sender) {
3687
"MessageRequestResponse must have a sender"
3788
}.toAddress()
3889
)
3990

40-
if (messageSender.address !is Address.Standard) {
91+
return if (messageSender.address !is Address.Standard) {
4192
Log.e(TAG, "MessageRequestResponse sender must be a standard address, but got: ${messageSender.address.debugString}")
42-
return
93+
null
94+
} else {
95+
messageSender to recipientRepository.getRecipient(
96+
requireNotNull(message.recipient) {
97+
"MessageRequestResponse must have a receiver"
98+
}.toAddress()
99+
)
43100
}
101+
}
44102

45-
val messageReceiver = recipientRepository.getRecipient(
46-
requireNotNull(message.recipient) {
47-
"MessageRequestResponse must have a receiver"
48-
}.toAddress()
49-
)
103+
private fun handleRequestResponse(
104+
messageSender: Recipient,
105+
messageReceiver: Recipient,
106+
messageTimestampMs: Long,
107+
) {
108+
check(messageSender.address is Address.Standard) {
109+
"The sender address must be a standard address"
110+
}
50111

51112
Log.d(TAG, "Handling MessageRequestResponse from " +
52113
"${messageSender.address.debugString} to ${messageReceiver.address.debugString}")
@@ -71,17 +132,6 @@ class MessageRequestResponseHandler @Inject constructor(
71132
}
72133
}
73134

74-
75-
// Process the profile update if any
76-
message.profile?.toUpdates()?.let { updates ->
77-
profileUpdateHandler.get().handleProfileUpdate(
78-
senderId = messageSender.address.accountId,
79-
updates = updates,
80-
fromCommunity = null
81-
)
82-
}
83-
84-
85135
val threadId by lazy {
86136
threadDatabase.getOrCreateThreadIdFor(messageSender.address)
87137
}
@@ -92,7 +142,7 @@ class MessageRequestResponseHandler @Inject constructor(
92142
mmsDatabase.insertSecureDecryptedMessageInbox(
93143
retrieved = IncomingMediaMessage(
94144
messageSender.address,
95-
message.sentTimestamp!!,
145+
messageTimestampMs,
96146
-1,
97147
0L,
98148
0L,
@@ -153,7 +203,6 @@ class MessageRequestResponseHandler @Inject constructor(
153203

154204
}
155205
}
156-
157206
}
158207

159208
private fun moveConversation(fromThreadId: Long, toThreadId: Long) {

app/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,7 @@ class ReceivedMessageHandler @Inject constructor(
100100
private val profileUpdateHandler: Provider<ProfileUpdateHandler>,
101101
@param:ManagerScope private val scope: CoroutineScope,
102102
private val configFactory: ConfigFactoryProtocol,
103-
private val conversationRepository: ConversationRepository,
104103
private val messageRequestResponseHandler: Provider<MessageRequestResponseHandler>,
105-
private val recipientRepository: RecipientRepository,
106104
) {
107105

108106
suspend fun handle(
@@ -132,7 +130,7 @@ class ReceivedMessageHandler @Inject constructor(
132130
}
133131
is DataExtractionNotification -> handleDataExtractionNotification(message)
134132
is UnsendRequest -> handleUnsendRequest(message)
135-
is MessageRequestResponse -> messageRequestResponseHandler.get().handle(message)
133+
is MessageRequestResponse -> messageRequestResponseHandler.get().handleExplicitRequestResponseMessage(message)
136134
is VisibleMessage -> handleVisibleMessage(
137135
message = message,
138136
proto = proto,
@@ -286,7 +284,7 @@ class ReceivedMessageHandler @Inject constructor(
286284
return messageIdToDelete
287285
}
288286

289-
fun handleVisibleMessage(
287+
suspend fun handleVisibleMessage(
290288
message: VisibleMessage,
291289
proto: SignalServiceProtos.Content,
292290
context: VisibleMessageHandlerContext,
@@ -299,6 +297,7 @@ class ReceivedMessageHandler @Inject constructor(
299297
// Do nothing if the message was outdated
300298
if (messageIsOutdated(message, context.threadId)) { return null }
301299

300+
messageRequestResponseHandler.get().handleVisibleMessage(message)
302301

303302
// Handle group invite response if new closed group
304303
val threadRecipientAddress = context.threadAddress

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -657,9 +657,9 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
657657
viewModel.uiEvents.collect { event ->
658658
when (event) {
659659
is ConversationUiEvent.NavigateToConversation -> {
660-
finish()
661660
startActivity(
662661
createIntent(this@ConversationActivityV2, event.address)
662+
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NO_ANIMATION)
663663
)
664664
}
665665

@@ -1075,13 +1075,13 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
10751075
// Wait for exit signal
10761076
viewModel.shouldExit.first()
10771077

1078-
Toast.makeText(
1079-
this@ConversationActivityV2,
1080-
getString(R.string.conversationsDeleted),
1081-
Toast.LENGTH_LONG
1082-
).show()
1083-
10841078
if (!isFinishing) {
1079+
Toast.makeText(
1080+
this@ConversationActivityV2,
1081+
getString(R.string.conversationsDeleted),
1082+
Toast.LENGTH_LONG
1083+
).show()
1084+
10851085
finish()
10861086
}
10871087
}

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import kotlinx.coroutines.Dispatchers
1717
import kotlinx.coroutines.ExperimentalCoroutinesApi
1818
import kotlinx.coroutines.GlobalScope
1919
import kotlinx.coroutines.Job
20+
import kotlinx.coroutines.delay
2021
import kotlinx.coroutines.flow.Flow
2122
import kotlinx.coroutines.flow.MutableSharedFlow
2223
import kotlinx.coroutines.flow.MutableStateFlow
@@ -308,6 +309,13 @@ class ConversationViewModel @AssistedInject constructor(
308309

309310
// then wait until it is removed
310311
repository.conversationListAddressesFlow.first { !it.contains(address) }
312+
313+
// Wait for a bit so the unblinding navigation could take place first (basically
314+
// when a unblinding occurs, i.e. a blinded request has been accepted, the
315+
// blinded thread will be deleted. It would have come through here and we show "conversation
316+
// deleted" then quit, which is not ideal - so there's another coroutine that
317+
// try to navigate to the new conversation and we will make sure that coroutine goes first.
318+
delay(500L)
311319
emit(Unit)
312320
}
313321

0 commit comments

Comments
 (0)