Skip to content

Commit

Permalink
Merge pull request #3426 from element-hq/feature/fga/fix_self_verific…
Browse files Browse the repository at this point in the history
…ation_flow

Feature/fga/fix self verification flow
  • Loading branch information
ganfra authored Sep 9, 2024
2 parents fc0bb64 + a7ab8ee commit a284177
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,9 @@ fun VerifySelfSessionView(
onSuccessLogout: (String?) -> Unit,
modifier: Modifier = Modifier,
) {
fun resetFlow() {
state.eventSink(VerifySelfSessionViewEvents.Reset)
}

val latestOnFinish by rememberUpdatedState(newValue = onFinish)
LaunchedEffect(state.verificationFlowStep, latestOnFinish) {
if (state.verificationFlowStep is FlowStep.Skipped) {
latestOnFinish()
}
}
BackHandler {
fun cancelOrResetFlow() {
when (state.verificationFlowStep) {
is FlowStep.Canceled -> resetFlow()
is FlowStep.Canceled -> state.eventSink(VerifySelfSessionViewEvents.Reset)
is FlowStep.AwaitingOtherDeviceResponse, FlowStep.Ready -> state.eventSink(VerifySelfSessionViewEvents.Cancel)
is FlowStep.Verifying -> {
if (!state.verificationFlowStep.state.isLoading()) {
Expand All @@ -92,6 +82,16 @@ fun VerifySelfSessionView(
else -> Unit
}
}

val latestOnFinish by rememberUpdatedState(newValue = onFinish)
LaunchedEffect(state.verificationFlowStep, latestOnFinish) {
if (state.verificationFlowStep is FlowStep.Skipped) {
latestOnFinish()
}
}
BackHandler {
cancelOrResetFlow()
}
val verificationFlowStep = state.verificationFlowStep

if (state.verificationFlowStep is FlowStep.Loading ||
Expand Down Expand Up @@ -133,9 +133,9 @@ fun VerifySelfSessionView(
footer = {
BottomMenu(
screenState = state,
goBack = ::resetFlow,
onCancelClick = ::cancelOrResetFlow,
onEnterRecoveryKey = onEnterRecoveryKey,
onFinish = onFinish,
onContinueClick = onFinish,
onResetKey = onResetKey,
)
}
Expand Down Expand Up @@ -268,8 +268,8 @@ private fun BottomMenu(
screenState: VerifySelfSessionState,
onEnterRecoveryKey: () -> Unit,
onResetKey: () -> Unit,
goBack: () -> Unit,
onFinish: () -> Unit,
onCancelClick: () -> Unit,
onContinueClick: () -> Unit,
) {
val verificationViewState = screenState.verificationFlowStep
val eventSink = screenState.eventSink
Expand Down Expand Up @@ -316,7 +316,7 @@ private fun BottomMenu(
TextButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(CommonStrings.action_cancel),
onClick = goBack,
onClick = onCancelClick,
)
}
}
Expand All @@ -330,7 +330,7 @@ private fun BottomMenu(
TextButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(CommonStrings.action_cancel),
onClick = goBack,
onClick = onCancelClick,
)
}
}
Expand Down Expand Up @@ -375,7 +375,7 @@ private fun BottomMenu(
Button(
modifier = Modifier.fillMaxWidth(),
text = stringResource(CommonStrings.action_continue),
onClick = onFinish,
onClick = onContinueClick,
)
// Placeholder so the 1st button keeps its vertical position
Spacer(modifier = Modifier.height(48.dp))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withTimeout
import org.matrix.rustcomponents.sdk.Client
import org.matrix.rustcomponents.sdk.Encryption
Expand Down Expand Up @@ -95,18 +97,19 @@ class RustSessionVerificationService(
updateVerificationStatus()
}
}
.launchIn(sessionCoroutineScope)
.launchIn(sessionCoroutineScope)
}

override suspend fun requestVerification() = tryOrFail {
if (!this::verificationController.isInitialized) {
verificationController = client.getSessionVerificationController()
verificationController.setDelegate(this)
}
initVerificationControllerIfNeeded()
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() }

Expand Down Expand Up @@ -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() {
if (verificationFlowState.value == VerificationFlowState.Finished) {
// Calling `encryptionService.verificationState()` performs a network call and it will deadlock if there is no network
Expand All @@ -212,10 +225,7 @@ class RustSessionVerificationService(
// 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")
runCatching {
if (!this@RustSessionVerificationService::verificationController.isInitialized) {
verificationController = client.getSessionVerificationController()
verificationController.setDelegate(this@RustSessionVerificationService)
}
initVerificationControllerIfNeeded()
_sessionVerifiedStatus.value = if (verificationController.isVerified()) {
SessionVerifiedStatus.Verified
} else {
Expand Down

0 comments on commit a284177

Please sign in to comment.