Fixes #3126 - Prevent identity confirmation from blocking the user's progress after registering through OIDC (#3141)

- happened because `hasRunIdentityConfirmationOnboarding` is false while the verification state is still `.unknown`
- verification eventually changes to `.verified` but the flow coordinator doesn't catch up on it and blocks the flow
This commit is contained in:
Stefan Ceriu
2024-08-09 13:14:59 +03:00
committed by GitHub
parent b84c436551
commit e32067c069
@@ -43,6 +43,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
enum Event: EventType {
case next
case nextSkippingIdentityConfimed
}
private let stateMachine: StateMachine<State, Event>
@@ -123,7 +124,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
}
private func configureStateMachine() {
stateMachine.addRouteMapping { [weak self] _, fromState, _ in
stateMachine.addRouteMapping { [weak self] event, fromState, _ in
guard let self else {
return nil
}
@@ -141,8 +142,22 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
return .finished
case (.identityConfirmation, _, _, _, _):
return .identityConfirmed
if event == .nextSkippingIdentityConfimed {
// Used when the verification state has updated to verified
// after starting the onboarding flow
switch (requiresAppLockSetup, requiresAnalyticsSetup, requiresNotificationsSetup) {
case (true, _, _):
return .appLockSetup
case (false, true, _):
return .analyticsPrompt
case (false, false, true):
return .notificationPermissions
case (false, false, false):
return .finished
}
} else {
return .identityConfirmed
}
case (.identityConfirmed, _, true, _, _):
return .appLockSetup
case (.identityConfirmed, _, false, true, _):
@@ -216,14 +231,36 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
presentRecoveryKeyScreen()
case .skip:
appSettings.hasRunIdentityConfirmationOnboarding = true
stateMachine.tryEvent(.next)
stateMachine.tryEvent(.nextSkippingIdentityConfimed)
case .reset:
presentEncryptionResetScreen()
}
}
.store(in: &cancellables)
presentCoordinator(coordinator)
// If the verification state is still unknown wait for it to resolve
// and just move on to the next steps if verified
var verificationStateCancellable: AnyCancellable?
if userSession.sessionSecurityStatePublisher.value.verificationState == .unknown {
verificationStateCancellable = userSession.sessionSecurityStatePublisher
.map(\.verificationState)
.removeDuplicates()
.sink { [weak self] value in
guard let self else { return }
if value == .verified {
appSettings.hasRunIdentityConfirmationOnboarding = true
stateMachine.tryEvent(.nextSkippingIdentityConfimed)
} else {
// Captured by the block below, nil-ing it wouldn't work
verificationStateCancellable?.cancel()
}
}
}
presentCoordinator(coordinator) { [verificationStateCancellable] in
verificationStateCancellable?.cancel()
}
}
private func presentSessionVerificationScreen() async {
@@ -373,11 +410,11 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
presentCoordinator(coordinator)
}
private func presentCoordinator(_ coordinator: CoordinatorProtocol) {
private func presentCoordinator(_ coordinator: CoordinatorProtocol, dismissalCallback: (() -> Void)? = nil) {
if navigationStackCoordinator.rootCoordinator == nil {
navigationStackCoordinator.setRootCoordinator(coordinator)
navigationStackCoordinator.setRootCoordinator(coordinator, dismissalCallback: dismissalCallback)
} else {
navigationStackCoordinator.push(coordinator)
navigationStackCoordinator.push(coordinator, dismissalCallback: dismissalCallback)
}
}