Merge pull request #3426 from element-hq/feature/fga/fix_self_verification_flow
Feature/fga/fix self verification flow
This commit is contained in:
commit
aa40c3618b
2 changed files with 39 additions and 29 deletions
|
|
@ -70,8 +70,17 @@ fun VerifySelfSessionView(
|
||||||
onSuccessLogout: (String?) -> Unit,
|
onSuccessLogout: (String?) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
fun resetFlow() {
|
fun cancelOrResetFlow() {
|
||||||
state.eventSink(VerifySelfSessionViewEvents.Reset)
|
when (state.verificationFlowStep) {
|
||||||
|
is FlowStep.Canceled -> state.eventSink(VerifySelfSessionViewEvents.Reset)
|
||||||
|
is FlowStep.AwaitingOtherDeviceResponse, FlowStep.Ready -> state.eventSink(VerifySelfSessionViewEvents.Cancel)
|
||||||
|
is FlowStep.Verifying -> {
|
||||||
|
if (!state.verificationFlowStep.state.isLoading()) {
|
||||||
|
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val latestOnFinish by rememberUpdatedState(newValue = onFinish)
|
val latestOnFinish by rememberUpdatedState(newValue = onFinish)
|
||||||
|
|
@ -81,16 +90,7 @@ fun VerifySelfSessionView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BackHandler {
|
BackHandler {
|
||||||
when (state.verificationFlowStep) {
|
cancelOrResetFlow()
|
||||||
is FlowStep.Canceled -> resetFlow()
|
|
||||||
is FlowStep.AwaitingOtherDeviceResponse, FlowStep.Ready -> state.eventSink(VerifySelfSessionViewEvents.Cancel)
|
|
||||||
is FlowStep.Verifying -> {
|
|
||||||
if (!state.verificationFlowStep.state.isLoading()) {
|
|
||||||
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val verificationFlowStep = state.verificationFlowStep
|
val verificationFlowStep = state.verificationFlowStep
|
||||||
|
|
||||||
|
|
@ -133,9 +133,9 @@ fun VerifySelfSessionView(
|
||||||
footer = {
|
footer = {
|
||||||
BottomMenu(
|
BottomMenu(
|
||||||
screenState = state,
|
screenState = state,
|
||||||
goBack = ::resetFlow,
|
onCancelClick = ::cancelOrResetFlow,
|
||||||
onEnterRecoveryKey = onEnterRecoveryKey,
|
onEnterRecoveryKey = onEnterRecoveryKey,
|
||||||
onFinish = onFinish,
|
onContinueClick = onFinish,
|
||||||
onResetKey = onResetKey,
|
onResetKey = onResetKey,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -268,8 +268,8 @@ private fun BottomMenu(
|
||||||
screenState: VerifySelfSessionState,
|
screenState: VerifySelfSessionState,
|
||||||
onEnterRecoveryKey: () -> Unit,
|
onEnterRecoveryKey: () -> Unit,
|
||||||
onResetKey: () -> Unit,
|
onResetKey: () -> Unit,
|
||||||
goBack: () -> Unit,
|
onCancelClick: () -> Unit,
|
||||||
onFinish: () -> Unit,
|
onContinueClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val verificationViewState = screenState.verificationFlowStep
|
val verificationViewState = screenState.verificationFlowStep
|
||||||
val eventSink = screenState.eventSink
|
val eventSink = screenState.eventSink
|
||||||
|
|
@ -316,7 +316,7 @@ private fun BottomMenu(
|
||||||
TextButton(
|
TextButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(CommonStrings.action_cancel),
|
text = stringResource(CommonStrings.action_cancel),
|
||||||
onClick = goBack,
|
onClick = onCancelClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -330,7 +330,7 @@ private fun BottomMenu(
|
||||||
TextButton(
|
TextButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(CommonStrings.action_cancel),
|
text = stringResource(CommonStrings.action_cancel),
|
||||||
onClick = goBack,
|
onClick = onCancelClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -375,7 +375,7 @@ private fun BottomMenu(
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(CommonStrings.action_continue),
|
text = stringResource(CommonStrings.action_continue),
|
||||||
onClick = onFinish,
|
onClick = onContinueClick,
|
||||||
)
|
)
|
||||||
// Placeholder so the 1st button keeps its vertical position
|
// Placeholder so the 1st button keeps its vertical position
|
||||||
Spacer(modifier = Modifier.height(48.dp))
|
Spacer(modifier = Modifier.height(48.dp))
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
import org.matrix.rustcomponents.sdk.Client
|
import org.matrix.rustcomponents.sdk.Client
|
||||||
import org.matrix.rustcomponents.sdk.Encryption
|
import org.matrix.rustcomponents.sdk.Encryption
|
||||||
|
|
@ -95,18 +97,19 @@ class RustSessionVerificationService(
|
||||||
updateVerificationStatus()
|
updateVerificationStatus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(sessionCoroutineScope)
|
.launchIn(sessionCoroutineScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun requestVerification() = tryOrFail {
|
override suspend fun requestVerification() = tryOrFail {
|
||||||
if (!this::verificationController.isInitialized) {
|
initVerificationControllerIfNeeded()
|
||||||
verificationController = client.getSessionVerificationController()
|
|
||||||
verificationController.setDelegate(this)
|
|
||||||
}
|
|
||||||
verificationController.requestVerification()
|
verificationController.requestVerification()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun cancelVerification() = tryOrFail { verificationController.cancelVerification() }
|
override suspend fun cancelVerification() = tryOrFail {
|
||||||
|
verificationController.cancelVerification()
|
||||||
|
// We need to manually set the state to canceled, as the Rust SDK doesn't always call `didCancel` when it should
|
||||||
|
didCancel()
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun approveVerification() = tryOrFail { verificationController.approveVerification() }
|
override suspend fun approveVerification() = tryOrFail { verificationController.approveVerification() }
|
||||||
|
|
||||||
|
|
@ -193,6 +196,16 @@ class RustSessionVerificationService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var initControllerMutex = Mutex()
|
||||||
|
|
||||||
|
private suspend fun initVerificationControllerIfNeeded() = initControllerMutex.withLock {
|
||||||
|
if (!this::verificationController.isInitialized) {
|
||||||
|
tryOrFail {
|
||||||
|
verificationController = client.getSessionVerificationController()
|
||||||
|
verificationController.setDelegate(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private suspend fun updateVerificationStatus() {
|
private suspend fun updateVerificationStatus() {
|
||||||
if (verificationFlowState.value == VerificationFlowState.Finished) {
|
if (verificationFlowState.value == VerificationFlowState.Finished) {
|
||||||
// Calling `encryptionService.verificationState()` performs a network call and it will deadlock if there is no network
|
// Calling `encryptionService.verificationState()` performs a network call and it will deadlock if there is no network
|
||||||
|
|
@ -212,10 +225,7 @@ class RustSessionVerificationService(
|
||||||
// Otherwise, just check the current verification status from the session verification controller instead
|
// Otherwise, just check the current verification status from the session verification controller instead
|
||||||
Timber.d("Updating verification status: flow is pending or was finished some time ago")
|
Timber.d("Updating verification status: flow is pending or was finished some time ago")
|
||||||
runCatching {
|
runCatching {
|
||||||
if (!this@RustSessionVerificationService::verificationController.isInitialized) {
|
initVerificationControllerIfNeeded()
|
||||||
verificationController = client.getSessionVerificationController()
|
|
||||||
verificationController.setDelegate(this@RustSessionVerificationService)
|
|
||||||
}
|
|
||||||
_sessionVerifiedStatus.value = if (verificationController.isVerified()) {
|
_sessionVerifiedStatus.value = if (verificationController.isVerified()) {
|
||||||
SessionVerifiedStatus.Verified
|
SessionVerifiedStatus.Verified
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue