Use isolated per-item scopes for TOTP flows (#1384)

This commit is contained in:
Brian Yencho 2024-05-23 12:01:21 -05:00 committed by Álison Fernandes
parent 217de5c8ba
commit 0149da361c

View file

@ -8,6 +8,7 @@ import com.x8bit.bitwarden.data.platform.repository.model.DataState
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
import com.x8bit.bitwarden.data.vault.manager.model.VerificationCodeItem import com.x8bit.bitwarden.data.vault.manager.model.VerificationCodeItem
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -80,6 +81,10 @@ class TotpCodeManagerImpl(
val cipherId = cipher?.id ?: return MutableStateFlow(DataState.Loaded(null)) val cipherId = cipher?.id ?: return MutableStateFlow(DataState.Loaded(null))
return mutableVerificationCodeStateFlowMap.getOrPut(cipher) { return mutableVerificationCodeStateFlowMap.getOrPut(cipher) {
// Define a per-item scope so that we can clear the Flow from the scope when it is
// no longer needed.
val itemScope = CoroutineScope(dispatcherManager.unconfined)
flow<DataState<VerificationCodeItem?>> { flow<DataState<VerificationCodeItem?>> {
val totpCode = cipher val totpCode = cipher
.login .login
@ -139,9 +144,10 @@ class TotpCodeManagerImpl(
} }
.onCompletion { .onCompletion {
mutableVerificationCodeStateFlowMap.remove(cipher) mutableVerificationCodeStateFlowMap.remove(cipher)
itemScope.cancel()
} }
.stateIn( .stateIn(
scope = unconfinedScope, scope = itemScope,
started = SharingStarted.WhileSubscribed(), started = SharingStarted.WhileSubscribed(),
initialValue = DataState.Loading, initialValue = DataState.Loading,
) )