Discard timed out user verification requests (#4385)

This commit is contained in:
Jorge Martin Espinosa
2025-03-10 18:38:38 +01:00
committed by GitHub
parent 765bd85b6d
commit 6f8b1547ea

View File

@@ -77,17 +77,20 @@ import io.element.android.libraries.matrix.api.verification.SessionVerificationS
import io.element.android.libraries.matrix.api.verification.VerificationRequest
import io.element.android.services.appnavstate.api.AppNavigationStateService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout
import kotlinx.parcelize.Parcelize
import timber.log.Timber
import java.time.Duration
import java.time.Instant
import java.util.Optional
import java.util.UUID
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
import kotlin.time.toKotlinDuration
@ContributesNode(SessionScope::class)
class LoggedInFlowNode @AssistedInject constructor(
@@ -134,12 +137,29 @@ class LoggedInFlowNode @AssistedInject constructor(
override fun onIncomingSessionRequest(verificationRequest: VerificationRequest.Incoming) {
// Without this launch the rendering and actual state of this Appyx node's children gets out of sync, resulting in a crash.
// This might be because this method is called back from Rust in a background thread.
MainScope().launch {
lifecycleScope.launch {
val receivedAt = Instant.now()
// Wait until the app is in foreground to display the incoming verification request
appNavigationStateService.appNavigationState.first { it.isInForeground }
// Wait for the UI to be ready
delay(500.milliseconds)
// TODO there should also be a timeout for > 10 minutes elapsed since the request was created, but the SDK doesn't expose that info yet
val now = Instant.now()
val elapsedTimeSinceReceived = Duration.between(receivedAt, now).toKotlinDuration()
// Discard the incoming verification request if it has timed out
if (elapsedTimeSinceReceived > 2.minutes) {
Timber.w("Incoming verification request ${verificationRequest.details.flowId} discarded due to timeout.")
return@launch
}
// Wait for the RoomList UI to be ready so the incoming verification screen can be displayed on top of it
// Otherwise, the RoomList UI may be incorrectly displayed on top
withTimeout(5.seconds) {
backstack.elements.first { elements ->
elements.any { it.key.navTarget == NavTarget.RoomList }
}
}
backstack.singleTop(NavTarget.IncomingVerificationRequest(verificationRequest))
}