mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Fixes #2470 - Allow verifiying a session through entering the recovery key
This commit is contained in:
committed by
Stefan Ceriu
parent
46f0cf45bd
commit
023e10edf2
@@ -567,6 +567,7 @@
|
|||||||
"screen_session_verification_compare_numbers_subtitle" = "Confirm that the numbers below match those shown on your other session.";
|
"screen_session_verification_compare_numbers_subtitle" = "Confirm that the numbers below match those shown on your other session.";
|
||||||
"screen_session_verification_compare_numbers_title" = "Compare numbers";
|
"screen_session_verification_compare_numbers_title" = "Compare numbers";
|
||||||
"screen_session_verification_complete_subtitle" = "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.";
|
"screen_session_verification_complete_subtitle" = "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.";
|
||||||
|
"screen_session_verification_enter_recovery_key" = "Enter recovery key";
|
||||||
"screen_session_verification_open_existing_session_subtitle" = "Prove it’s you in order to access your encrypted message history.";
|
"screen_session_verification_open_existing_session_subtitle" = "Prove it’s you in order to access your encrypted message history.";
|
||||||
"screen_session_verification_open_existing_session_title" = "Open an existing session";
|
"screen_session_verification_open_existing_session_title" = "Open an existing session";
|
||||||
"screen_session_verification_positive_button_canceled" = "Retry verification";
|
"screen_session_verification_positive_button_canceled" = "Retry verification";
|
||||||
|
|||||||
@@ -208,7 +208,8 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
fatalError("The sessionVerificationController should aways be valid at this point")
|
fatalError("The sessionVerificationController should aways be valid at this point")
|
||||||
}
|
}
|
||||||
|
|
||||||
let verificationParameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
|
let verificationParameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController,
|
||||||
|
recoveryState: parameters.userSession.sessionSecurityStatePublisher.value.recoveryState)
|
||||||
let coordinator = SessionVerificationScreenCoordinator(parameters: verificationParameters)
|
let coordinator = SessionVerificationScreenCoordinator(parameters: verificationParameters)
|
||||||
|
|
||||||
coordinator.actions
|
coordinator.actions
|
||||||
@@ -216,6 +217,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
|
case .recoveryKey:
|
||||||
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
|
handleAppRoute(.chatBackupSettings, animated: true)
|
||||||
case .done:
|
case .done:
|
||||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case (.roomList, .showLogoutConfirmationScreen, .logoutConfirmationScreen):
|
case (.roomList, .showLogoutConfirmationScreen, .logoutConfirmationScreen):
|
||||||
presentSecureBackupConfirmationScreen()
|
presentSecureBackupLogoutConfirmationScreen()
|
||||||
case (.logoutConfirmationScreen, .dismissedLogoutConfirmationScreen, .roomList):
|
case (.logoutConfirmationScreen, .dismissedLogoutConfirmationScreen, .roomList):
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -400,7 +400,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
presentSecureBackupConfirmationScreen()
|
presentSecureBackupLogoutConfirmationScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Session verification
|
// MARK: Session verification
|
||||||
@@ -410,7 +410,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
fatalError("The sessionVerificationController should aways be valid at this point")
|
fatalError("The sessionVerificationController should aways be valid at this point")
|
||||||
}
|
}
|
||||||
|
|
||||||
let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
|
let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController,
|
||||||
|
recoveryState: userSession.sessionSecurityStatePublisher.value.recoveryState)
|
||||||
|
|
||||||
let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)
|
let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
@@ -419,6 +420,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
|
case .recoveryKey:
|
||||||
|
settingsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
||||||
case .done:
|
case .done:
|
||||||
navigationSplitCoordinator.setSheetCoordinator(nil)
|
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||||
}
|
}
|
||||||
@@ -511,7 +514,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
// MARK: Secure backup confirmation
|
// MARK: Secure backup confirmation
|
||||||
|
|
||||||
private func presentSecureBackupConfirmationScreen() {
|
private func presentSecureBackupLogoutConfirmationScreen() {
|
||||||
let coordinator = SecureBackupLogoutConfirmationScreenCoordinator(parameters: .init(secureBackupController: userSession.clientProxy.secureBackupController,
|
let coordinator = SecureBackupLogoutConfirmationScreenCoordinator(parameters: .init(secureBackupController: userSession.clientProxy.secureBackupController,
|
||||||
networkMonitor: ServiceLocator.shared.networkMonitor))
|
networkMonitor: ServiceLocator.shared.networkMonitor))
|
||||||
|
|
||||||
|
|||||||
@@ -1392,6 +1392,8 @@ public enum L10n {
|
|||||||
public static var screenSessionVerificationCompareNumbersTitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_numbers_title") }
|
public static var screenSessionVerificationCompareNumbersTitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_numbers_title") }
|
||||||
/// Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.
|
/// Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.
|
||||||
public static var screenSessionVerificationCompleteSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_complete_subtitle") }
|
public static var screenSessionVerificationCompleteSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_complete_subtitle") }
|
||||||
|
/// Enter recovery key
|
||||||
|
public static var screenSessionVerificationEnterRecoveryKey: String { return L10n.tr("Localizable", "screen_session_verification_enter_recovery_key") }
|
||||||
/// Prove it’s you in order to access your encrypted message history.
|
/// Prove it’s you in order to access your encrypted message history.
|
||||||
public static var screenSessionVerificationOpenExistingSessionSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_open_existing_session_subtitle") }
|
public static var screenSessionVerificationOpenExistingSessionSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_open_existing_session_subtitle") }
|
||||||
/// Open an existing session
|
/// Open an existing session
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ enum A11yIdentifiers {
|
|||||||
let emojiWrapper = "session_verification-emojis"
|
let emojiWrapper = "session_verification-emojis"
|
||||||
let verificationComplete = "session_verification-verification_complete"
|
let verificationComplete = "session_verification-verification_complete"
|
||||||
let close = "session_verification-close"
|
let close = "session_verification-close"
|
||||||
|
let enterRecoveryKey = "session_verification-enter_recovery_key"
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SettingsScreen {
|
struct SettingsScreen {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
case (.unverifiedLastSession, .incomplete):
|
case (.unverifiedLastSession, .incomplete):
|
||||||
state.requiresExtraAccountSetup = true
|
state.requiresExtraAccountSetup = true
|
||||||
if state.securityBannerMode != .dismissed {
|
if state.securityBannerMode != .dismissed {
|
||||||
state.securityBannerMode = .recoveryKeyConfirmation
|
state.securityBannerMode = .sessionVerification
|
||||||
}
|
}
|
||||||
case (.verified, .disabled):
|
case (.verified, .disabled):
|
||||||
state.requiresExtraAccountSetup = true
|
state.requiresExtraAccountSetup = true
|
||||||
|
|||||||
+6
-1
@@ -18,11 +18,13 @@ import Combine
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum SessionVerificationScreenCoordinatorAction {
|
enum SessionVerificationScreenCoordinatorAction {
|
||||||
|
case recoveryKey
|
||||||
case done
|
case done
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SessionVerificationScreenCoordinatorParameters {
|
struct SessionVerificationScreenCoordinatorParameters {
|
||||||
let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol
|
let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol
|
||||||
|
let recoveryState: SecureBackupRecoveryState
|
||||||
}
|
}
|
||||||
|
|
||||||
final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
|
final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
|
||||||
@@ -36,7 +38,8 @@ final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(parameters: SessionVerificationScreenCoordinatorParameters) {
|
init(parameters: SessionVerificationScreenCoordinatorParameters) {
|
||||||
viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy)
|
viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy,
|
||||||
|
recoveryState: parameters.recoveryState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@@ -47,6 +50,8 @@ final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
|
|||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
|
case .recoveryKey:
|
||||||
|
actionsSubject.send(.recoveryKey)
|
||||||
case .finished:
|
case .finished:
|
||||||
actionsSubject.send(.done)
|
actionsSubject.send(.done)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -17,10 +17,13 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum SessionVerificationScreenViewModelAction {
|
enum SessionVerificationScreenViewModelAction {
|
||||||
|
case recoveryKey
|
||||||
case finished
|
case finished
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SessionVerificationScreenViewState: BindableState {
|
struct SessionVerificationScreenViewState: BindableState {
|
||||||
|
let showRecoveryOption: Bool
|
||||||
|
|
||||||
var verificationState: SessionVerificationScreenStateMachine.State = .initial
|
var verificationState: SessionVerificationScreenStateMachine.State = .initial
|
||||||
|
|
||||||
var title: String? {
|
var title: String? {
|
||||||
@@ -83,6 +86,7 @@ struct SessionVerificationScreenViewState: BindableState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum SessionVerificationScreenViewAction {
|
enum SessionVerificationScreenViewAction {
|
||||||
|
case recoveryKey
|
||||||
case requestVerification
|
case requestVerification
|
||||||
case startSasVerification
|
case startSasVerification
|
||||||
case restart
|
case restart
|
||||||
|
|||||||
+5
-2
@@ -31,12 +31,13 @@ class SessionVerificationScreenViewModel: SessionVerificationViewModelType, Sess
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol,
|
init(sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol,
|
||||||
initialState: SessionVerificationScreenViewState = SessionVerificationScreenViewState()) {
|
recoveryState: SecureBackupRecoveryState,
|
||||||
|
verificationState: SessionVerificationScreenStateMachine.State = .initial) {
|
||||||
self.sessionVerificationControllerProxy = sessionVerificationControllerProxy
|
self.sessionVerificationControllerProxy = sessionVerificationControllerProxy
|
||||||
|
|
||||||
stateMachine = SessionVerificationScreenStateMachine()
|
stateMachine = SessionVerificationScreenStateMachine()
|
||||||
|
|
||||||
super.init(initialViewState: initialState)
|
super.init(initialViewState: .init(showRecoveryOption: recoveryState == .incomplete, verificationState: verificationState))
|
||||||
|
|
||||||
setupStateMachine()
|
setupStateMachine()
|
||||||
|
|
||||||
@@ -70,6 +71,8 @@ class SessionVerificationScreenViewModel: SessionVerificationViewModelType, Sess
|
|||||||
|
|
||||||
override func process(viewAction: SessionVerificationScreenViewAction) {
|
override func process(viewAction: SessionVerificationScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
|
case .recoveryKey:
|
||||||
|
actionsSubject.send(.recoveryKey)
|
||||||
case .requestVerification:
|
case .requestVerification:
|
||||||
stateMachine.processEvent(.requestVerification)
|
stateMachine.processEvent(.requestVerification)
|
||||||
case .startSasVerification:
|
case .startSasVerification:
|
||||||
|
|||||||
+16
-6
@@ -128,12 +128,21 @@ struct SessionVerificationScreen: View {
|
|||||||
private var actionButtons: some View {
|
private var actionButtons: some View {
|
||||||
switch context.viewState.verificationState {
|
switch context.viewState.verificationState {
|
||||||
case .initial:
|
case .initial:
|
||||||
Button(L10n.actionStartVerification) {
|
VStack(spacing: 32) {
|
||||||
context.send(viewAction: .requestVerification)
|
Button(L10n.actionStartVerification) {
|
||||||
|
context.send(viewAction: .requestVerification)
|
||||||
|
}
|
||||||
|
.buttonStyle(.compound(.primary))
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.sessionVerificationScreen.requestVerification)
|
||||||
|
|
||||||
|
if context.viewState.showRecoveryOption {
|
||||||
|
Button(L10n.screenSessionVerificationEnterRecoveryKey) {
|
||||||
|
context.send(viewAction: .recoveryKey)
|
||||||
|
}
|
||||||
|
.buttonStyle(.compound(.plain))
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.sessionVerificationScreen.enterRecoveryKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.compound(.primary))
|
|
||||||
.accessibilityIdentifier(A11yIdentifiers.sessionVerificationScreen.requestVerification)
|
|
||||||
|
|
||||||
case .cancelled:
|
case .cancelled:
|
||||||
Button(L10n.actionRetry) {
|
Button(L10n.actionRetry) {
|
||||||
context.send(viewAction: .restart)
|
context.send(viewAction: .restart)
|
||||||
@@ -235,7 +244,8 @@ struct SessionVerification_Previews: PreviewProvider, TestablePreview {
|
|||||||
|
|
||||||
static func sessionVerificationScreen(state: SessionVerificationScreenStateMachine.State) -> some View {
|
static func sessionVerificationScreen(state: SessionVerificationScreenStateMachine.State) -> some View {
|
||||||
let viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: SessionVerificationControllerProxyMock.configureMock(),
|
let viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: SessionVerificationControllerProxyMock.configureMock(),
|
||||||
initialState: SessionVerificationScreenViewState(verificationState: state))
|
recoveryState: .incomplete,
|
||||||
|
verificationState: state)
|
||||||
|
|
||||||
return SessionVerificationScreen(context: viewModel.context)
|
return SessionVerificationScreen(context: viewModel.context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
|||||||
state.securitySectionMode = .sessionVerification
|
state.securitySectionMode = .sessionVerification
|
||||||
case (.unverifiedLastSession, .incomplete):
|
case (.unverifiedLastSession, .incomplete):
|
||||||
state.showSecuritySectionBadge = true
|
state.showSecuritySectionBadge = true
|
||||||
state.securitySectionMode = .secureBackup
|
state.securitySectionMode = .sessionVerification
|
||||||
case (.verified, .disabled):
|
case (.verified, .disabled):
|
||||||
state.showSecuritySectionBadge = true
|
state.showSecuritySectionBadge = true
|
||||||
state.securitySectionMode = .secureBackup
|
state.securitySectionMode = .secureBackup
|
||||||
|
|||||||
@@ -25,5 +25,5 @@ struct MockUserSession: UserSessionProtocol {
|
|||||||
let clientProxy: ClientProxyProtocol
|
let clientProxy: ClientProxyProtocol
|
||||||
let mediaProvider: MediaProviderProtocol
|
let mediaProvider: MediaProviderProtocol
|
||||||
let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol
|
let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol
|
||||||
var sessionSecurityStatePublisher: AnyPublisher<SessionSecurityState, Never> = CurrentValueSubject<SessionSecurityState, Never>(.init(verificationState: .verified, recoveryState: .enabled)).eraseToAnyPublisher()
|
var sessionSecurityStatePublisher = CurrentValueSubject<SessionSecurityState, Never>(.init(verificationState: .verified, recoveryState: .enabled)).asCurrentValuePublisher()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,22 +51,16 @@ class UserSession: UserSessionProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sessionSecurityStatePublisher: AnyPublisher<SessionSecurityState, Never>
|
let sessionSecurityStateSubject = CurrentValueSubject<SessionSecurityState, Never>(.init(verificationState: .unknown, recoveryState: .unknown))
|
||||||
|
var sessionSecurityStatePublisher: CurrentValuePublisher<SessionSecurityState, Never> {
|
||||||
|
sessionSecurityStateSubject.asCurrentValuePublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(clientProxy: ClientProxyProtocol, mediaProvider: MediaProviderProtocol, voiceMessageMediaManager: VoiceMessageMediaManagerProtocol) {
|
init(clientProxy: ClientProxyProtocol, mediaProvider: MediaProviderProtocol, voiceMessageMediaManager: VoiceMessageMediaManagerProtocol) {
|
||||||
self.clientProxy = clientProxy
|
self.clientProxy = clientProxy
|
||||||
self.mediaProvider = mediaProvider
|
self.mediaProvider = mediaProvider
|
||||||
self.voiceMessageMediaManager = voiceMessageMediaManager
|
self.voiceMessageMediaManager = voiceMessageMediaManager
|
||||||
|
|
||||||
sessionSecurityStatePublisher = Publishers.CombineLatest(sessionVerificationStateSubject, clientProxy.secureBackupController.recoveryState)
|
|
||||||
.map {
|
|
||||||
MXLog.info("Session security state changed, verificationState: \($0), recoveryState: \($1)")
|
|
||||||
return SessionSecurityState(verificationState: $0, recoveryState: $1)
|
|
||||||
}
|
|
||||||
.removeDuplicates()
|
|
||||||
.receive(on: DispatchQueue.main)
|
|
||||||
.eraseToAnyPublisher()
|
|
||||||
|
|
||||||
clientProxy.callbacks
|
clientProxy.callbacks
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] callback in
|
.sink { [weak self] callback in
|
||||||
@@ -88,6 +82,18 @@ class UserSession: UserSessionProtocol {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Publishers.CombineLatest(sessionVerificationStateSubject, clientProxy.secureBackupController.recoveryState)
|
||||||
|
.map {
|
||||||
|
MXLog.info("Session security state changed, verificationState: \($0), recoveryState: \($1)")
|
||||||
|
return SessionSecurityState(verificationState: $0, recoveryState: $1)
|
||||||
|
}
|
||||||
|
.removeDuplicates()
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] value in
|
||||||
|
self?.sessionSecurityStateSubject.send(value)
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ protocol UserSessionProtocol {
|
|||||||
var mediaProvider: MediaProviderProtocol { get }
|
var mediaProvider: MediaProviderProtocol { get }
|
||||||
var voiceMessageMediaManager: VoiceMessageMediaManagerProtocol { get }
|
var voiceMessageMediaManager: VoiceMessageMediaManagerProtocol { get }
|
||||||
|
|
||||||
var sessionSecurityStatePublisher: AnyPublisher<SessionSecurityState, Never> { get }
|
var sessionSecurityStatePublisher: CurrentValuePublisher<SessionSecurityState, Never> { get }
|
||||||
var sessionVerificationController: SessionVerificationControllerProxyProtocol? { get }
|
var sessionVerificationController: SessionVerificationControllerProxyProtocol? { get }
|
||||||
|
|
||||||
var callbacks: PassthroughSubject<UserSessionCallback, Never> { get }
|
var callbacks: PassthroughSubject<UserSessionCallback, Never> { get }
|
||||||
|
|||||||
@@ -552,7 +552,8 @@ class MockScreen: Identifiable {
|
|||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .sessionVerification:
|
case .sessionVerification:
|
||||||
var sessionVerificationControllerProxy = SessionVerificationControllerProxyMock.configureMock(requestDelay: .seconds(5))
|
var sessionVerificationControllerProxy = SessionVerificationControllerProxyMock.configureMock(requestDelay: .seconds(5))
|
||||||
let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationControllerProxy)
|
let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationControllerProxy,
|
||||||
|
recoveryState: .unknown)
|
||||||
return SessionVerificationScreenCoordinator(parameters: parameters)
|
return SessionVerificationScreenCoordinator(parameters: parameters)
|
||||||
case .userSessionScreen, .userSessionScreenReply, .userSessionScreenRTE:
|
case .userSessionScreen, .userSessionScreenReply, .userSessionScreenRTE:
|
||||||
let appSettings: AppSettings = ServiceLocator.shared.settings
|
let appSettings: AppSettings = ServiceLocator.shared.settings
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ class SessionVerificationViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
sessionVerificationController = SessionVerificationControllerProxyMock.configureMock()
|
sessionVerificationController = SessionVerificationControllerProxyMock.configureMock()
|
||||||
viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: sessionVerificationController)
|
viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: sessionVerificationController,
|
||||||
|
recoveryState: .incomplete)
|
||||||
context = viewModel.context
|
context = viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d0c8f14034cf3b7ec84ea309e02ef139ae9ef6556137c1c0a4348286faac3a8f
|
oid sha256:768819e156631bd2188b55376ce95e270a16828b0d70c3f2c3559a979e558d19
|
||||||
size 98718
|
size 105136
|
||||||
|
|||||||
Reference in New Issue
Block a user