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 { enum Event: EventType {
case next case next
case nextSkippingIdentityConfimed
} }
private let stateMachine: StateMachine<State, Event> private let stateMachine: StateMachine<State, Event>
@@ -123,7 +124,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
} }
private func configureStateMachine() { private func configureStateMachine() {
stateMachine.addRouteMapping { [weak self] _, fromState, _ in stateMachine.addRouteMapping { [weak self] event, fromState, _ in
guard let self else { guard let self else {
return nil return nil
} }
@@ -141,8 +142,22 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
return .finished return .finished
case (.identityConfirmation, _, _, _, _): 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, _, _): case (.identityConfirmed, _, true, _, _):
return .appLockSetup return .appLockSetup
case (.identityConfirmed, _, false, true, _): case (.identityConfirmed, _, false, true, _):
@@ -216,14 +231,36 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
presentRecoveryKeyScreen() presentRecoveryKeyScreen()
case .skip: case .skip:
appSettings.hasRunIdentityConfirmationOnboarding = true appSettings.hasRunIdentityConfirmationOnboarding = true
stateMachine.tryEvent(.next) stateMachine.tryEvent(.nextSkippingIdentityConfimed)
case .reset: case .reset:
presentEncryptionResetScreen() presentEncryptionResetScreen()
} }
} }
.store(in: &cancellables) .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 { private func presentSessionVerificationScreen() async {
@@ -373,11 +410,11 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
presentCoordinator(coordinator) presentCoordinator(coordinator)
} }
private func presentCoordinator(_ coordinator: CoordinatorProtocol) { private func presentCoordinator(_ coordinator: CoordinatorProtocol, dismissalCallback: (() -> Void)? = nil) {
if navigationStackCoordinator.rootCoordinator == nil { if navigationStackCoordinator.rootCoordinator == nil {
navigationStackCoordinator.setRootCoordinator(coordinator) navigationStackCoordinator.setRootCoordinator(coordinator, dismissalCallback: dismissalCallback)
} else { } else {
navigationStackCoordinator.push(coordinator) navigationStackCoordinator.push(coordinator, dismissalCallback: dismissalCallback)
} }
} }