From d77bb935b75368f9fe5942444aef2a892e650fa6 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 29 Oct 2024 15:21:17 +0200 Subject: [PATCH] Incoming session verification support (#3428) * Fixes #1227 - Add support for receiving and interacting with incoming session verification requests. * Fix a couple of random small warnings * Move static view config to the view state * Update snapshots --- ElementX.xcodeproj/project.pbxproj | 6 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- .../en.lproj/Localizable.strings | 17 +- .../OnboardingFlowCoordinator.swift | 11 +- .../UserSessionFlowCoordinator.swift | 211 +++++++++++------- ElementX/Sources/Generated/Strings.swift | 18 +- ElementX/Sources/Mocks/ClientProxyMock.swift | 1 - .../Mocks/Generated/GeneratedMocks.swift | 207 +++++++++++------ .../Mocks/Generated/SDKGeneratedMocks.swift | 155 +++++++------ ...ssionVerificationControllerProxyMock.swift | 18 +- .../Other/AccessibilityIdentifiers.swift | 2 + ...SessionVerificationScreenCoordinator.swift | 10 +- .../SessionVerificationScreenModels.swift | 77 +++++-- ...essionVerificationScreenStateMachine.swift | 19 +- .../SessionVerificationScreenViewModel.swift | 51 ++++- ...essionVerificationRequestDetailsView.swift | 80 +++++++ .../View/SessionVerificationScreen.swift | 139 ++++++------ .../Timeline/TimelineInteractionHandler.swift | 1 + .../Sources/Services/Client/ClientProxy.swift | 63 ++++-- .../Services/Client/ClientProxyProtocol.swift | 4 +- .../ElementCall/ElementCallService.swift | 7 +- .../SessionVerificationControllerProxy.swift | 76 ++++++- ...nVerificationControllerProxyProtocol.swift | 20 +- .../UITests/UITestsAppCoordinator.swift | 3 +- .../Sources/GeneratedPreviewTests.swift | 6 + ...ackupKeyBackupScreen-iPad-en-GB.Set-up.png | 4 +- ...ckupKeyBackupScreen-iPad-pseudo.Set-up.png | 4 +- ...KeyBackupScreen-iPhone-16-en-GB.Set-up.png | 4 +- ...eyBackupScreen-iPhone-16-pseudo.Set-up.png | 4 +- ...ecoveryKeyScreen-iPad-en-GB.Generating.png | 4 +- ...ecoveryKeyScreen-iPad-en-GB.Not-set-up.png | 4 +- ...coveryKeyScreen-iPad-pseudo.Generating.png | 4 +- ...coveryKeyScreen-iPad-pseudo.Not-set-up.png | 4 +- ...ryKeyScreen-iPhone-16-en-GB.Generating.png | 4 +- ...ryKeyScreen-iPhone-16-en-GB.Not-set-up.png | 4 +- ...yKeyScreen-iPhone-16-pseudo.Generating.png | 4 +- ...yKeyScreen-iPhone-16-pseudo.Not-set-up.png | 4 +- ...ication-iPad-en-GB.Accepting-Challenge.png | 3 + ...d-en-GB.Accepting-Verification-Request.png | 3 + ...ssionVerification-iPad-en-GB.Cancelled.png | 4 +- ...ication-iPad-en-GB.Declining-Challenge.png | 3 + ...fication-iPad-en-GB.Initial-Initiator.png} | 0 ...ification-iPad-en-GB.Initial-Responder.png | 3 + ...ion-iPad-en-GB.Requesting-Verification.png | 4 +- ...on-iPad-en-GB.SAS-Verification-started.png | 3 + ...ification-iPad-en-GB.Showing-Challenge.png | 4 +- ...n-iPad-en-GB.Starting-SAS-Verification.png | 3 + ...cation-iPad-pseudo.Accepting-Challenge.png | 3 + ...-pseudo.Accepting-Verification-Request.png | 3 + ...sionVerification-iPad-pseudo.Cancelled.png | 4 +- ...cation-iPad-pseudo.Declining-Challenge.png | 3 + ...ication-iPad-pseudo.Initial-Initiator.png} | 0 ...fication-iPad-pseudo.Initial-Responder.png | 3 + ...on-iPad-pseudo.Requesting-Verification.png | 4 +- ...n-iPad-pseudo.SAS-Verification-started.png | 3 + ...fication-iPad-pseudo.Showing-Challenge.png | 4 +- ...-iPad-pseudo.Starting-SAS-Verification.png | 3 + ...on-iPhone-16-en-GB.Accepting-Challenge.png | 3 + ...6-en-GB.Accepting-Verification-Request.png | 3 + ...Verification-iPhone-16-en-GB.Cancelled.png | 4 +- ...on-iPhone-16-en-GB.Declining-Challenge.png | 3 + ...ion-iPhone-16-en-GB.Initial-Initiator.png} | 0 ...tion-iPhone-16-en-GB.Initial-Responder.png | 3 + ...Phone-16-en-GB.Requesting-Verification.png | 4 +- ...hone-16-en-GB.SAS-Verification-started.png | 3 + ...tion-iPhone-16-en-GB.Showing-Challenge.png | 4 +- ...one-16-en-GB.Starting-SAS-Verification.png | 3 + ...n-iPhone-16-pseudo.Accepting-Challenge.png | 3 + ...-pseudo.Accepting-Verification-Request.png | 3 + ...erification-iPhone-16-pseudo.Cancelled.png | 4 +- ...n-iPhone-16-pseudo.Declining-Challenge.png | 3 + ...on-iPhone-16-pseudo.Initial-Initiator.png} | 0 ...ion-iPhone-16-pseudo.Initial-Responder.png | 3 + ...hone-16-pseudo.Requesting-Verification.png | 4 +- ...one-16-pseudo.SAS-Verification-started.png | 3 + ...ion-iPhone-16-pseudo.Showing-Challenge.png | 4 +- ...ne-16-pseudo.Starting-SAS-Verification.png | 3 + ...icationRequestDetailsView-iPad-en-GB.1.png | 3 + ...cationRequestDetailsView-iPad-pseudo.1.png | 3 + ...onRequestDetailsView-iPhone-16-en-GB.1.png | 3 + ...nRequestDetailsView-iPhone-16-pseudo.1.png | 3 + ...teRoom-1-iPad-10th-generation-en-GB.UI.png | 4 +- .../createRoom-1-iPhone-16-en-GB.UI.png | 4 +- ...eateRoom-iPad-10th-generation-en-GB.UI.png | 4 +- .../createRoom-iPhone-16-en-GB.UI.png | 4 +- ...mNoUsers-iPad-10th-generation-en-GB.UI.png | 4 +- .../createRoomNoUsers-iPhone-16-en-GB.UI.png | 4 +- ...cation-0-iPad-10th-generation-en-GB.UI.png | 4 +- ...cation-1-iPad-10th-generation-en-GB.UI.png | 4 +- ...ssionVerification-1-iPhone-16-en-GB.UI.png | 4 +- ...cation-2-iPad-10th-generation-en-GB.UI.png | 4 +- ...ssionVerification-2-iPhone-16-en-GB.UI.png | 4 +- ...cation-3-iPad-10th-generation-en-GB.UI.png | 4 +- ...ssionVerification-3-iPhone-16-en-GB.UI.png | 4 +- ...cation-4-iPad-10th-generation-en-GB.UI.png | 4 +- ...ssionVerification-4-iPhone-16-en-GB.UI.png | 4 +- ...cation-5-iPad-10th-generation-en-GB.UI.png | 4 +- ...ssionVerification-5-iPhone-16-en-GB.UI.png | 4 +- ...cation-6-iPad-10th-generation-en-GB.UI.png | 4 +- ...cation-7-iPad-10th-generation-en-GB.UI.png | 4 +- ...ssionVerification-7-iPhone-16-en-GB.UI.png | 4 +- ...SessionVerificationStateMachineTests.swift | 2 +- .../SessionVerificationViewModelTests.swift | 8 +- project.yml | 2 +- 104 files changed, 995 insertions(+), 483 deletions(-) create mode 100644 ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationRequestDetailsView.swift create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Challenge.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Verification-Request.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Declining-Challenge.png rename PreviewTests/Sources/__Snapshots__/PreviewTests/{test_sessionVerification-iPad-en-GB.Initial.png => test_sessionVerification-iPad-en-GB.Initial-Initiator.png} (100%) create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial-Responder.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.SAS-Verification-started.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Starting-SAS-Verification.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Challenge.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Verification-Request.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Declining-Challenge.png rename PreviewTests/Sources/__Snapshots__/PreviewTests/{test_sessionVerification-iPad-pseudo.Initial.png => test_sessionVerification-iPad-pseudo.Initial-Initiator.png} (100%) create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial-Responder.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.SAS-Verification-started.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Starting-SAS-Verification.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Challenge.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Verification-Request.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Declining-Challenge.png rename PreviewTests/Sources/__Snapshots__/PreviewTests/{test_sessionVerification-iPhone-16-en-GB.Initial.png => test_sessionVerification-iPhone-16-en-GB.Initial-Initiator.png} (100%) create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial-Responder.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.SAS-Verification-started.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Starting-SAS-Verification.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Challenge.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Verification-Request.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Declining-Challenge.png rename PreviewTests/Sources/__Snapshots__/PreviewTests/{test_sessionVerification-iPhone-16-pseudo.Initial.png => test_sessionVerification-iPhone-16-pseudo.Initial-Initiator.png} (100%) create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial-Responder.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.SAS-Verification-started.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Starting-SAS-Verification.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-en-GB.1.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-pseudo.1.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-en-GB.1.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-pseudo.1.png diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 62b5b0931..418ce7292 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -666,6 +666,7 @@ 915B4CDAF220D9AEB4047D45 /* PollInteractionHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 259E5B05BDE6E20C26CF11B4 /* PollInteractionHandlerProtocol.swift */; }; 91ABC91758A6E4A5FAA2E9C4 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */; }; 91C6AC0E9D2B9C0C76CC6AD4 /* RoomDirectorySearchScreenScreenModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3984C93B8E9B10C92DADF9EE /* RoomDirectorySearchScreenScreenModelProtocol.swift */; }; + 91D1A46A733EC24C081DD353 /* SessionVerificationRequestDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A1265FAF2C0AF1C30605BE7 /* SessionVerificationRequestDetailsView.swift */; }; 92012C96039BC8C2CAEBA9E2 /* AuthenticationServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671C338B7259DC5774816885 /* AuthenticationServiceTests.swift */; }; 9219640F4D980CFC5FE855AD /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 536E72DCBEEC4A1FE66CFDCE /* target.yml */; }; 92720AB0DA9AB5EEF1DAF56B /* SecureBackupLogoutConfirmationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DC017C3CB6B0F7C63F460F2 /* SecureBackupLogoutConfirmationScreenViewModel.swift */; }; @@ -1314,6 +1315,7 @@ 190EC7285D3CFEF0D3011BCF /* GeoURI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoURI.swift; sourceTree = ""; }; 196004E7695FBA292A7944AF /* ScreenTrackerViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenTrackerViewModifier.swift; sourceTree = ""; }; 1A02406480C351B8C6E0682C /* MediaLoaderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaLoaderProtocol.swift; sourceTree = ""; }; + 1A1265FAF2C0AF1C30605BE7 /* SessionVerificationRequestDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationRequestDetailsView.swift; sourceTree = ""; }; 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = ""; }; 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStaticMap.swift; sourceTree = ""; }; 1A7ED2EF5BDBAD2A7DBC4636 /* GeoURITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoURITests.swift; sourceTree = ""; }; @@ -4650,6 +4652,7 @@ A722D372674EE5687E1A67E4 /* View */ = { isa = PBXGroup; children = ( + 1A1265FAF2C0AF1C30605BE7 /* SessionVerificationRequestDetailsView.swift */, 5FACD034DB52525A3CEF2BDF /* SessionVerificationScreen.swift */, ); path = View; @@ -6904,6 +6907,7 @@ 237FC70AA257B935F53316BA /* SessionVerificationControllerProxy.swift in Sources */, AE1A73B24D63DA3D63DC4EE3 /* SessionVerificationControllerProxyMock.swift in Sources */, 94A65DD8A353DF112EBEF67A /* SessionVerificationControllerProxyProtocol.swift in Sources */, + 91D1A46A733EC24C081DD353 /* SessionVerificationRequestDetailsView.swift in Sources */, 707E49BE07E8EB8A13C0EB1E /* SessionVerificationScreen.swift in Sources */, D02DEB36D32A72A1B365E452 /* SessionVerificationScreenCoordinator.swift in Sources */, 5710AAB27D5D866292C1FE06 /* SessionVerificationScreenModels.swift in Sources */, @@ -7828,7 +7832,7 @@ repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 1.0.61; + version = 1.0.62; }; }; 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 5e7bb11b6..97e4b2e1c 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -149,8 +149,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/element-hq/matrix-rust-components-swift", "state" : { - "revision" : "2e6378514e79a648d436e8faeb8cd8106910cf0b", - "version" : "1.0.61" + "revision" : "9b26e40ae6c27c56e233577c863569ff074f84fd", + "version" : "1.0.62" } }, { diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index b16f7076b..9b14f00f5 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -115,8 +115,9 @@ "banner_migrate_to_native_sliding_sync_description" = "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later."; "banner_migrate_to_native_sliding_sync_force_logout_title" = "Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app."; "banner_migrate_to_native_sliding_sync_title" = "Upgrade available"; -"banner.set_up_recovery.content" = "Generate a new recovery key that can be used to restore your encrypted message history in case you lose access to your devices."; -"banner.set_up_recovery.title" = "Set up recovery"; +"banner_set_up_recovery_submit" = "Set up recovery"; +"banner.set_up_recovery.content" = "Recover your cryptographic identity and message history with a recovery key if you have lost all your existing devices."; +"banner.set_up_recovery.title" = "Set up recovery to protect your account"; "common_about" = "About"; "common_acceptable_use_policy" = "Acceptable use policy"; "common_advanced_settings" = "Advanced settings"; @@ -454,7 +455,7 @@ "screen_change_server_form_notice" = "You can only connect to an existing server that supports sliding sync. Your homeserver admin will need to configure it. %1$@"; "screen_change_server_subtitle" = "What is the address of your server?"; "screen_change_server_title" = "Select your server"; -"screen_chat_backup_key_backup_action_disable" = "Turn off backup"; +"screen_chat_backup_key_backup_action_disable" = "Delete key storage"; "screen_chat_backup_key_backup_action_enable" = "Turn on backup"; "screen_chat_backup_key_backup_description" = "Store your cryptographic identity and message keys securely on the server. This will allow you to view your message history on any new devices. %1$@."; "screen_chat_backup_key_backup_title" = "Key storage"; @@ -538,10 +539,10 @@ "screen_key_backup_disable_confirmation_action_turn_off" = "Turn off"; "screen_key_backup_disable_confirmation_description" = "You will lose your encrypted messages if you are signed out of all devices."; "screen_key_backup_disable_confirmation_title" = "Are you sure you want to turn off backup?"; -"screen_key_backup_disable_description" = "Turning off backup will remove your current encryption key backup and turn off other security features. In this case, you will:"; -"screen_key_backup_disable_description_point_1" = "Not have encrypted message history on new devices"; -"screen_key_backup_disable_description_point_2" = "Lose access to your encrypted messages if you are signed out of %1$@ everywhere"; -"screen_key_backup_disable_title" = "Are you sure you want to turn off backup?"; +"screen_key_backup_disable_description" = "Deleting key storage will remove your cryptographic identity and message keys from the server and turn off the following security features:"; +"screen_key_backup_disable_description_point_1" = "You will not have encrypted message history on new devices"; +"screen_key_backup_disable_description_point_2" = "You will lose access to your encrypted messages if you are signed out of %1$@ everywhere"; +"screen_key_backup_disable_title" = "Are you sure you want to turn off key storage and delete it?"; "screen_login_error_deactivated_account" = "This account has been deactivated."; "screen_login_error_invalid_credentials" = "Incorrect username and/or password"; "screen_login_error_invalid_user_id" = "This is not a valid user identifier. Expected format: ‘@user:homeserver.org’"; @@ -652,7 +653,7 @@ "screen_recovery_key_save_title" = "Save your recovery key somewhere safe"; "screen_recovery_key_setup_confirmation_description" = "You will not be able to access your new recovery key after this step."; "screen_recovery_key_setup_confirmation_title" = "Have you saved your recovery key?"; -"screen_recovery_key_setup_description" = "Your chat backup is protected by a recovery key. If you need a new recovery key after setup you can recreate by selecting ‘Change recovery key’."; +"screen_recovery_key_setup_description" = "Your key storage is protected by a recovery key. If you need a new recovery key after setup, you can recreate it by selecting ‘Change recovery key’."; "screen_recovery_key_setup_generate_key" = "Generate your recovery key"; "screen_recovery_key_setup_generate_key_description" = "Do not share this with anyone!"; "screen_recovery_key_setup_success" = "Recovery setup successful"; diff --git a/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift index e64ff8f46..48428c2a8 100644 --- a/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift @@ -244,9 +244,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol { switch action { case .otherDevice: - Task { - await self.presentSessionVerificationScreen() - } + presentSessionVerificationScreen() case .recoveryKey: presentRecoveryKeyScreen() case .skip: @@ -263,12 +261,13 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol { presentCoordinator(coordinator) } - private func presentSessionVerificationScreen() async { - guard case let .success(sessionVerificationController) = await userSession.clientProxy.sessionVerificationControllerProxy() else { + private func presentSessionVerificationScreen() { + guard let sessionVerificationController = userSession.clientProxy.sessionVerificationController else { fatalError("The sessionVerificationController should aways be valid at this point") } - let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController) + let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController, + flow: .initiator) let coordinator = SessionVerificationScreenCoordinator(parameters: parameters) diff --git a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift index 37a960b68..012c26dfb 100644 --- a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift @@ -7,6 +7,7 @@ import AVKit import Combine +import MatrixRustSDK import SwiftUI enum UserSessionFlowCoordinatorAction { @@ -59,7 +60,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { /// For testing purposes. var statePublisher: AnyPublisher { stateMachine.statePublisher } - // swiftlint:disable:next function_body_length init(userSession: UserSessionProtocol, navigationRootCoordinator: NavigationRootCoordinator, appLockService: AppLockServiceProtocol, @@ -113,87 +113,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { setupStateMachine() - userSession.sessionSecurityStatePublisher - .map(\.verificationState) - .filter { $0 != .unknown } - .removeDuplicates() - .receive(on: DispatchQueue.main) - .sink { [weak self] _ in - guard let self else { return } - - attemptStartingOnboarding() - } - .store(in: &cancellables) - - settingsFlowCoordinator.actions.sink { [weak self] action in - guard let self else { return } - - switch action { - case .presentedSettings: - stateMachine.processEvent(.showSettingsScreen) - case .dismissedSettings: - stateMachine.processEvent(.dismissedSettingsScreen) - case .runLogoutFlow: - Task { await self.runLogoutFlow() } - case .clearCache: - actionsSubject.send(.clearCache) - case .forceLogout: - actionsSubject.send(.forceLogout) - } - } - .store(in: &cancellables) - - userSession.clientProxy.actionsPublisher - .receive(on: DispatchQueue.main) - .sink { action in - guard case let .receivedDecryptionError(info) = action else { - return - } - - let timeToDecryptMs: Int - if let unsignedTimeToDecryptMs = info.timeToDecryptMs { - timeToDecryptMs = Int(unsignedTimeToDecryptMs) - } else { - timeToDecryptMs = -1 - } - - switch info.cause { - case .unknown: - analytics.trackError(context: nil, domain: .E2EE, name: .UnknownError, timeToDecryptMillis: timeToDecryptMs) - case .unknownDevice: - analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedSentByInsecureDevice, timeToDecryptMillis: timeToDecryptMs) - case .unsignedDevice: - analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedSentByInsecureDevice, timeToDecryptMillis: timeToDecryptMs) - case .verificationViolation: - analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedVerificationViolation, timeToDecryptMillis: timeToDecryptMs) - case .sentBeforeWeJoined: - analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedDueToMembership, timeToDecryptMillis: timeToDecryptMs) - } - } - .store(in: &cancellables) - - elementCallService.actions - .receive(on: DispatchQueue.main) - .sink { [weak self] action in - switch action { - case .endCall: - self?.dismissCallScreenIfNeeded() - default: - break - } - } - .store(in: &cancellables) - - onboardingFlowCoordinator.actions - .sink { [weak self] action in - guard let self else { return } - - switch action { - case .logout: - logout() - } - } - .store(in: &cancellables) + setupObservers() } func start() { @@ -385,6 +305,129 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { } } + private func setupObservers() { + userSession.sessionSecurityStatePublisher + .map(\.verificationState) + .filter { $0 != .unknown } + .removeDuplicates() + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + guard let self else { return } + + attemptStartingOnboarding() + + setupSessionVerificationRequestsObserver() + } + .store(in: &cancellables) + + settingsFlowCoordinator.actions.sink { [weak self] action in + guard let self else { return } + + switch action { + case .presentedSettings: + stateMachine.processEvent(.showSettingsScreen) + case .dismissedSettings: + stateMachine.processEvent(.dismissedSettingsScreen) + case .runLogoutFlow: + Task { await self.runLogoutFlow() } + case .clearCache: + actionsSubject.send(.clearCache) + case .forceLogout: + actionsSubject.send(.forceLogout) + } + } + .store(in: &cancellables) + + userSession.clientProxy.actionsPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] action in + guard let self, case let .receivedDecryptionError(info) = action else { + return + } + + let timeToDecryptMs: Int + if let unsignedTimeToDecryptMs = info.timeToDecryptMs { + timeToDecryptMs = Int(unsignedTimeToDecryptMs) + } else { + timeToDecryptMs = -1 + } + + switch info.cause { + case .unknown: + analytics.trackError(context: nil, domain: .E2EE, name: .UnknownError, timeToDecryptMillis: timeToDecryptMs) + case .unknownDevice: + analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedSentByInsecureDevice, timeToDecryptMillis: timeToDecryptMs) + case .unsignedDevice: + analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedSentByInsecureDevice, timeToDecryptMillis: timeToDecryptMs) + case .verificationViolation: + analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedVerificationViolation, timeToDecryptMillis: timeToDecryptMs) + case .sentBeforeWeJoined: + analytics.trackError(context: nil, domain: .E2EE, name: .ExpectedDueToMembership, timeToDecryptMillis: timeToDecryptMs) + } + } + .store(in: &cancellables) + + elementCallService.actions + .receive(on: DispatchQueue.main) + .sink { [weak self] action in + switch action { + case .endCall: + self?.dismissCallScreenIfNeeded() + default: + break + } + } + .store(in: &cancellables) + + onboardingFlowCoordinator.actions + .sink { [weak self] action in + guard let self else { return } + + switch action { + case .logout: + logout() + } + } + .store(in: &cancellables) + } + + private func setupSessionVerificationRequestsObserver() { + userSession.clientProxy.sessionVerificationController?.actions + .receive(on: DispatchQueue.main) + .sink { [weak self] action in + guard let self, case .receivedVerificationRequest(let details) = action else { + return + } + + MXLog.info("Received session verification request") + + presentSessionVerificationScreen(details: details) + } + .store(in: &cancellables) + } + + private func presentSessionVerificationScreen(details: SessionVerificationRequestDetails) { + guard let sessionVerificationController = userSession.clientProxy.sessionVerificationController else { + fatalError("The sessionVerificationController should aways be valid at this point") + } + + let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController, + flow: .responder(details: details)) + + let coordinator = SessionVerificationScreenCoordinator(parameters: parameters) + + coordinator.actions + .sink { [weak self] action in + switch action { + case .done: + self?.navigationSplitCoordinator.setSheetCoordinator(nil) + } + } + .store(in: &cancellables) + + navigationSplitCoordinator.setSheetCoordinator(coordinator) + } + private func presentHomeScreen() { let parameters = HomeScreenCoordinatorParameters(userSession: userSession, bugReportService: bugReportService, @@ -569,7 +612,9 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { self?.stateMachine.processEvent(.dismissedStartChatScreen) } } - + + // MARK: Session Verification + // MARK: Calls private func presentCallScreen(genericCallLink url: URL) { diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index 7e52a6328..087a6974d 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -266,6 +266,8 @@ internal enum L10n { internal static var bannerMigrateToNativeSlidingSyncForceLogoutTitle: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_force_logout_title") } /// Upgrade available internal static var bannerMigrateToNativeSlidingSyncTitle: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_title") } + /// Set up recovery + internal static var bannerSetUpRecoverySubmit: String { return L10n.tr("Localizable", "banner_set_up_recovery_submit") } /// About internal static var commonAbout: String { return L10n.tr("Localizable", "common_about") } /// Acceptable use policy @@ -1009,7 +1011,7 @@ internal enum L10n { internal static var screenChangeServerSubtitle: String { return L10n.tr("Localizable", "screen_change_server_subtitle") } /// Select your server internal static var screenChangeServerTitle: String { return L10n.tr("Localizable", "screen_change_server_title") } - /// Turn off backup + /// Delete key storage internal static var screenChatBackupKeyBackupActionDisable: String { return L10n.tr("Localizable", "screen_chat_backup_key_backup_action_disable") } /// Turn on backup internal static var screenChatBackupKeyBackupActionEnable: String { return L10n.tr("Localizable", "screen_chat_backup_key_backup_action_enable") } @@ -1258,15 +1260,15 @@ internal enum L10n { internal static var screenKeyBackupDisableConfirmationDescription: String { return L10n.tr("Localizable", "screen_key_backup_disable_confirmation_description") } /// Are you sure you want to turn off backup? internal static var screenKeyBackupDisableConfirmationTitle: String { return L10n.tr("Localizable", "screen_key_backup_disable_confirmation_title") } - /// Turning off backup will remove your current encryption key backup and turn off other security features. In this case, you will: + /// Deleting key storage will remove your cryptographic identity and message keys from the server and turn off the following security features: internal static var screenKeyBackupDisableDescription: String { return L10n.tr("Localizable", "screen_key_backup_disable_description") } - /// Not have encrypted message history on new devices + /// You will not have encrypted message history on new devices internal static var screenKeyBackupDisableDescriptionPoint1: String { return L10n.tr("Localizable", "screen_key_backup_disable_description_point_1") } - /// Lose access to your encrypted messages if you are signed out of %1$@ everywhere + /// You will lose access to your encrypted messages if you are signed out of %1$@ everywhere internal static func screenKeyBackupDisableDescriptionPoint2(_ p1: Any) -> String { return L10n.tr("Localizable", "screen_key_backup_disable_description_point_2", String(describing: p1)) } - /// Are you sure you want to turn off backup? + /// Are you sure you want to turn off key storage and delete it? internal static var screenKeyBackupDisableTitle: String { return L10n.tr("Localizable", "screen_key_backup_disable_title") } /// This account has been deactivated. internal static var screenLoginErrorDeactivatedAccount: String { return L10n.tr("Localizable", "screen_login_error_deactivated_account") } @@ -1536,7 +1538,7 @@ internal enum L10n { internal static var screenRecoveryKeySetupConfirmationDescription: String { return L10n.tr("Localizable", "screen_recovery_key_setup_confirmation_description") } /// Have you saved your recovery key? internal static var screenRecoveryKeySetupConfirmationTitle: String { return L10n.tr("Localizable", "screen_recovery_key_setup_confirmation_title") } - /// Your chat backup is protected by a recovery key. If you need a new recovery key after setup you can recreate by selecting ‘Change recovery key’. + /// Your key storage is protected by a recovery key. If you need a new recovery key after setup, you can recreate it by selecting ‘Change recovery key’. internal static var screenRecoveryKeySetupDescription: String { return L10n.tr("Localizable", "screen_recovery_key_setup_description") } /// Generate your recovery key internal static var screenRecoveryKeySetupGenerateKey: String { return L10n.tr("Localizable", "screen_recovery_key_setup_generate_key") } @@ -2499,9 +2501,9 @@ internal enum L10n { internal enum Banner { internal enum SetUpRecovery { - /// Generate a new recovery key that can be used to restore your encrypted message history in case you lose access to your devices. + /// Recover your cryptographic identity and message history with a recovery key if you have lost all your existing devices. internal static var content: String { return L10n.tr("Localizable", "banner.set_up_recovery.content") } - /// Set up recovery + /// Set up recovery to protect your account internal static var title: String { return L10n.tr("Localizable", "banner.set_up_recovery.title") } } } diff --git a/ElementX/Sources/Mocks/ClientProxyMock.swift b/ElementX/Sources/Mocks/ClientProxyMock.swift index ac086c1c4..8cc4962f8 100644 --- a/ElementX/Sources/Mocks/ClientProxyMock.swift +++ b/ElementX/Sources/Mocks/ClientProxyMock.swift @@ -60,7 +60,6 @@ extension ClientProxyMock { logoutReturnValue = nil searchUsersSearchTermLimitReturnValue = .success(.init(results: [], limited: false)) profileForReturnValue = .success(.init(userID: "@a:b.com", displayName: "Some user")) - sessionVerificationControllerProxyReturnValue = .failure(.sdkError(ClientProxyMockError.generic)) ignoreUserReturnValue = .success(()) unignoreUserReturnValue = .success(()) diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 2438f6b7f..c7524379c 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2210,6 +2210,7 @@ class ClientProxyMock: ClientProxyProtocol { set(value) { underlyingSecureBackupController = value } } var underlyingSecureBackupController: SecureBackupControllerProtocol! + var sessionVerificationController: SessionVerificationControllerProxyProtocol? //MARK: - isOnlyDeviceLeft @@ -3519,70 +3520,6 @@ class ClientProxyMock: ClientProxyProtocol { return removeUserAvatarReturnValue } } - //MARK: - sessionVerificationControllerProxy - - var sessionVerificationControllerProxyUnderlyingCallsCount = 0 - var sessionVerificationControllerProxyCallsCount: Int { - get { - if Thread.isMainThread { - return sessionVerificationControllerProxyUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = sessionVerificationControllerProxyUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - sessionVerificationControllerProxyUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - sessionVerificationControllerProxyUnderlyingCallsCount = newValue - } - } - } - } - var sessionVerificationControllerProxyCalled: Bool { - return sessionVerificationControllerProxyCallsCount > 0 - } - - var sessionVerificationControllerProxyUnderlyingReturnValue: Result! - var sessionVerificationControllerProxyReturnValue: Result! { - get { - if Thread.isMainThread { - return sessionVerificationControllerProxyUnderlyingReturnValue - } else { - var returnValue: Result? = nil - DispatchQueue.main.sync { - returnValue = sessionVerificationControllerProxyUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - sessionVerificationControllerProxyUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - sessionVerificationControllerProxyUnderlyingReturnValue = newValue - } - } - } - } - var sessionVerificationControllerProxyClosure: (() async -> Result)? - - func sessionVerificationControllerProxy() async -> Result { - sessionVerificationControllerProxyCallsCount += 1 - if let sessionVerificationControllerProxyClosure = sessionVerificationControllerProxyClosure { - return await sessionVerificationControllerProxyClosure() - } else { - return sessionVerificationControllerProxyReturnValue - } - } //MARK: - deactivateAccount var deactivateAccountPasswordEraseDataUnderlyingCallsCount = 0 @@ -13435,12 +13372,146 @@ class SecureBackupControllerMock: SecureBackupControllerProtocol { } } class SessionVerificationControllerProxyMock: SessionVerificationControllerProxyProtocol { - var callbacks: PassthroughSubject { - get { return underlyingCallbacks } - set(value) { underlyingCallbacks = value } + var actions: PassthroughSubject { + get { return underlyingActions } + set(value) { underlyingActions = value } } - var underlyingCallbacks: PassthroughSubject! + var underlyingActions: PassthroughSubject! + //MARK: - acknowledgeVerificationRequest + + var acknowledgeVerificationRequestDetailsUnderlyingCallsCount = 0 + var acknowledgeVerificationRequestDetailsCallsCount: Int { + get { + if Thread.isMainThread { + return acknowledgeVerificationRequestDetailsUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = acknowledgeVerificationRequestDetailsUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + acknowledgeVerificationRequestDetailsUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + acknowledgeVerificationRequestDetailsUnderlyingCallsCount = newValue + } + } + } + } + var acknowledgeVerificationRequestDetailsCalled: Bool { + return acknowledgeVerificationRequestDetailsCallsCount > 0 + } + var acknowledgeVerificationRequestDetailsReceivedDetails: SessionVerificationRequestDetails? + var acknowledgeVerificationRequestDetailsReceivedInvocations: [SessionVerificationRequestDetails] = [] + + var acknowledgeVerificationRequestDetailsUnderlyingReturnValue: Result! + var acknowledgeVerificationRequestDetailsReturnValue: Result! { + get { + if Thread.isMainThread { + return acknowledgeVerificationRequestDetailsUnderlyingReturnValue + } else { + var returnValue: Result? = nil + DispatchQueue.main.sync { + returnValue = acknowledgeVerificationRequestDetailsUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + acknowledgeVerificationRequestDetailsUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + acknowledgeVerificationRequestDetailsUnderlyingReturnValue = newValue + } + } + } + } + var acknowledgeVerificationRequestDetailsClosure: ((SessionVerificationRequestDetails) async -> Result)? + + func acknowledgeVerificationRequest(details: SessionVerificationRequestDetails) async -> Result { + acknowledgeVerificationRequestDetailsCallsCount += 1 + acknowledgeVerificationRequestDetailsReceivedDetails = details + DispatchQueue.main.async { + self.acknowledgeVerificationRequestDetailsReceivedInvocations.append(details) + } + if let acknowledgeVerificationRequestDetailsClosure = acknowledgeVerificationRequestDetailsClosure { + return await acknowledgeVerificationRequestDetailsClosure(details) + } else { + return acknowledgeVerificationRequestDetailsReturnValue + } + } + //MARK: - acceptVerificationRequest + + var acceptVerificationRequestUnderlyingCallsCount = 0 + var acceptVerificationRequestCallsCount: Int { + get { + if Thread.isMainThread { + return acceptVerificationRequestUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = acceptVerificationRequestUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + acceptVerificationRequestUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + acceptVerificationRequestUnderlyingCallsCount = newValue + } + } + } + } + var acceptVerificationRequestCalled: Bool { + return acceptVerificationRequestCallsCount > 0 + } + + var acceptVerificationRequestUnderlyingReturnValue: Result! + var acceptVerificationRequestReturnValue: Result! { + get { + if Thread.isMainThread { + return acceptVerificationRequestUnderlyingReturnValue + } else { + var returnValue: Result? = nil + DispatchQueue.main.sync { + returnValue = acceptVerificationRequestUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + acceptVerificationRequestUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + acceptVerificationRequestUnderlyingReturnValue = newValue + } + } + } + } + var acceptVerificationRequestClosure: (() async -> Result)? + + func acceptVerificationRequest() async -> Result { + acceptVerificationRequestCallsCount += 1 + if let acceptVerificationRequestClosure = acceptVerificationRequestClosure { + return await acceptVerificationRequestClosure() + } else { + return acceptVerificationRequestReturnValue + } + } //MARK: - requestVerification var requestVerificationUnderlyingCallsCount = 0 diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index abc5a6099..ec51a42ed 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -16529,6 +16529,92 @@ open class SessionVerificationControllerSDKMock: MatrixRustSDK.SessionVerificati fileprivate var pointer: UnsafeMutableRawPointer! + //MARK: - acceptVerificationRequest + + open var acceptVerificationRequestThrowableError: Error? + var acceptVerificationRequestUnderlyingCallsCount = 0 + open var acceptVerificationRequestCallsCount: Int { + get { + if Thread.isMainThread { + return acceptVerificationRequestUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = acceptVerificationRequestUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + acceptVerificationRequestUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + acceptVerificationRequestUnderlyingCallsCount = newValue + } + } + } + } + open var acceptVerificationRequestCalled: Bool { + return acceptVerificationRequestCallsCount > 0 + } + open var acceptVerificationRequestClosure: (() async throws -> Void)? + + open override func acceptVerificationRequest() async throws { + if let error = acceptVerificationRequestThrowableError { + throw error + } + acceptVerificationRequestCallsCount += 1 + try await acceptVerificationRequestClosure?() + } + + //MARK: - acknowledgeVerificationRequest + + open var acknowledgeVerificationRequestSenderIdFlowIdThrowableError: Error? + var acknowledgeVerificationRequestSenderIdFlowIdUnderlyingCallsCount = 0 + open var acknowledgeVerificationRequestSenderIdFlowIdCallsCount: Int { + get { + if Thread.isMainThread { + return acknowledgeVerificationRequestSenderIdFlowIdUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = acknowledgeVerificationRequestSenderIdFlowIdUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + acknowledgeVerificationRequestSenderIdFlowIdUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + acknowledgeVerificationRequestSenderIdFlowIdUnderlyingCallsCount = newValue + } + } + } + } + open var acknowledgeVerificationRequestSenderIdFlowIdCalled: Bool { + return acknowledgeVerificationRequestSenderIdFlowIdCallsCount > 0 + } + open var acknowledgeVerificationRequestSenderIdFlowIdReceivedArguments: (senderId: String, flowId: String)? + open var acknowledgeVerificationRequestSenderIdFlowIdReceivedInvocations: [(senderId: String, flowId: String)] = [] + open var acknowledgeVerificationRequestSenderIdFlowIdClosure: ((String, String) async throws -> Void)? + + open override func acknowledgeVerificationRequest(senderId: String, flowId: String) async throws { + if let error = acknowledgeVerificationRequestSenderIdFlowIdThrowableError { + throw error + } + acknowledgeVerificationRequestSenderIdFlowIdCallsCount += 1 + acknowledgeVerificationRequestSenderIdFlowIdReceivedArguments = (senderId: senderId, flowId: flowId) + DispatchQueue.main.async { + self.acknowledgeVerificationRequestSenderIdFlowIdReceivedInvocations.append((senderId: senderId, flowId: flowId)) + } + try await acknowledgeVerificationRequestSenderIdFlowIdClosure?(senderId, flowId) + } + //MARK: - approveVerification open var approveVerificationThrowableError: Error? @@ -16649,75 +16735,6 @@ open class SessionVerificationControllerSDKMock: MatrixRustSDK.SessionVerificati try await declineVerificationClosure?() } - //MARK: - isVerified - - open var isVerifiedThrowableError: Error? - var isVerifiedUnderlyingCallsCount = 0 - open var isVerifiedCallsCount: Int { - get { - if Thread.isMainThread { - return isVerifiedUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isVerifiedUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isVerifiedUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isVerifiedUnderlyingCallsCount = newValue - } - } - } - } - open var isVerifiedCalled: Bool { - return isVerifiedCallsCount > 0 - } - - var isVerifiedUnderlyingReturnValue: Bool! - open var isVerifiedReturnValue: Bool! { - get { - if Thread.isMainThread { - return isVerifiedUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isVerifiedUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isVerifiedUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isVerifiedUnderlyingReturnValue = newValue - } - } - } - } - open var isVerifiedClosure: (() async throws -> Bool)? - - open override func isVerified() async throws -> Bool { - if let error = isVerifiedThrowableError { - throw error - } - isVerifiedCallsCount += 1 - if let isVerifiedClosure = isVerifiedClosure { - return try await isVerifiedClosure() - } else { - return isVerifiedReturnValue - } - } - //MARK: - requestVerification open var requestVerificationThrowableError: Error? diff --git a/ElementX/Sources/Mocks/SessionVerificationControllerProxyMock.swift b/ElementX/Sources/Mocks/SessionVerificationControllerProxyMock.swift index 377404e7a..55572db7b 100644 --- a/ElementX/Sources/Mocks/SessionVerificationControllerProxyMock.swift +++ b/ElementX/Sources/Mocks/SessionVerificationControllerProxyMock.swift @@ -16,16 +16,18 @@ extension SessionVerificationControllerProxyMock { SessionVerificationEmoji(symbol: "🏁", description: "Flag"), SessionVerificationEmoji(symbol: "🌏", description: "Globe")] - static func configureMock(callbacks: PassthroughSubject = .init(), + static func configureMock(actions: PassthroughSubject = .init(), isVerified: Bool = false, requestDelay: Duration = .seconds(1)) -> SessionVerificationControllerProxyMock { let mock = SessionVerificationControllerProxyMock() - mock.underlyingCallbacks = callbacks + mock.underlyingActions = actions + + mock.acknowledgeVerificationRequestDetailsReturnValue = .success(()) mock.requestVerificationClosure = { [unowned mock] in Task.detached { try await Task.sleep(for: requestDelay) - mock.callbacks.send(.acceptedVerificationRequest) + mock.actions.send(.acceptedVerificationRequest) } return .success(()) @@ -34,11 +36,11 @@ extension SessionVerificationControllerProxyMock { mock.startSasVerificationClosure = { [unowned mock] in Task.detached { try await Task.sleep(for: requestDelay) - mock.callbacks.send(.startedSasVerification) + mock.actions.send(.startedSasVerification) Task.detached { try await Task.sleep(for: requestDelay) - mock.callbacks.send(.receivedVerificationData(emojis)) + mock.actions.send(.receivedVerificationData(emojis)) } } @@ -48,7 +50,7 @@ extension SessionVerificationControllerProxyMock { mock.approveVerificationClosure = { [unowned mock] in Task.detached { try await Task.sleep(for: requestDelay) - mock.callbacks.send(.finished) + mock.actions.send(.finished) } return .success(()) @@ -57,7 +59,7 @@ extension SessionVerificationControllerProxyMock { mock.declineVerificationClosure = { [unowned mock] in Task.detached { try await Task.sleep(for: requestDelay) - mock.callbacks.send(.cancelled) + mock.actions.send(.cancelled) } return .success(()) @@ -66,7 +68,7 @@ extension SessionVerificationControllerProxyMock { mock.cancelVerificationClosure = { [unowned mock] in Task.detached { try await Task.sleep(for: requestDelay) - mock.callbacks.send(.cancelled) + mock.actions.send(.cancelled) } return .success(()) diff --git a/ElementX/Sources/Other/AccessibilityIdentifiers.swift b/ElementX/Sources/Other/AccessibilityIdentifiers.swift index df2c1d07d..63eb3aa73 100644 --- a/ElementX/Sources/Other/AccessibilityIdentifiers.swift +++ b/ElementX/Sources/Other/AccessibilityIdentifiers.swift @@ -184,6 +184,8 @@ enum A11yIdentifiers { } struct SessionVerificationScreen { + let acceptVerificationRequest = "session_verification-accept_verification_request" + let ignoreVerificationRequest = "session_verification-ignore_verification_request" let requestVerification = "session_verification-request_verification" let startSasVerification = "session_verification-start_sas_verification" let acceptChallenge = "session_verification-accept_challenge" diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenCoordinator.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenCoordinator.swift index adbd3adb5..9741f1970 100644 --- a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenCoordinator.swift @@ -6,14 +6,21 @@ // import Combine +import MatrixRustSDK import SwiftUI enum SessionVerificationScreenCoordinatorAction { case done } +enum SessionVerificationScreenFlow { + case initiator + case responder(details: SessionVerificationRequestDetails) +} + struct SessionVerificationScreenCoordinatorParameters { let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol + let flow: SessionVerificationScreenFlow } final class SessionVerificationScreenCoordinator: CoordinatorProtocol { @@ -27,7 +34,8 @@ final class SessionVerificationScreenCoordinator: CoordinatorProtocol { } init(parameters: SessionVerificationScreenCoordinatorParameters) { - viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy) + viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy, + flow: parameters.flow) } // MARK: - Public diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenModels.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenModels.swift index 404667595..ec7d72b44 100644 --- a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenModels.swift +++ b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenModels.swift @@ -11,13 +11,61 @@ enum SessionVerificationScreenViewModelAction { case finished } +enum SessionVerificationScreenViewAction { + case acceptVerificationRequest + case ignoreVerificationRequest + case requestVerification + case startSasVerification + case restart + case accept + case decline + case done +} + struct SessionVerificationScreenViewState: BindableState { - var verificationState: SessionVerificationScreenStateMachine.State = .initial + let flow: SessionVerificationScreenFlow + var verificationState: SessionVerificationScreenStateMachine.State + + var headerImageName: String { + switch verificationState { + case .initial: + return "lock" + case .acceptingVerificationRequest: + return "hourglass" + case .requestingVerification: + return "hourglass" + case .verificationRequestAccepted: + return "face.smiling" + case .startingSasVerification: + return "hourglass" + case .sasVerificationStarted: + return "hourglass" + case .cancelling: + return "hourglass" + case .acceptingChallenge: + return "hourglass" + case .decliningChallenge: + return "hourglass" + case .showingChallenge: + return "face.smiling" + case .verified: + return "checkmark.shield" + case .cancelled: + return "exclamationmark.shield" + } + } var title: String? { switch verificationState { case .initial: - return L10n.screenSessionVerificationOpenExistingSessionTitle + switch flow { + case .initiator: + return L10n.screenSessionVerificationOpenExistingSessionTitle + case .responder: + return L10n.screenSessionVerificationRequestTitle + } + case .acceptingVerificationRequest: + return L10n.screenSessionVerificationRequestTitle case .requestingVerification: return L10n.screenSessionVerificationWaitingToAcceptTitle case .verificationRequestAccepted: @@ -31,13 +79,13 @@ struct SessionVerificationScreenViewState: BindableState { case .acceptingChallenge: return L10n.screenSessionVerificationCompareEmojisTitle case .decliningChallenge: - return nil + return L10n.screenSessionVerificationCompareEmojisTitle case .verified: return L10n.commonVerificationComplete case .cancelling: return nil case .cancelled: - return L10n.commonVerificationCancelled + return L10n.commonVerificationFailed } } @@ -48,7 +96,14 @@ struct SessionVerificationScreenViewState: BindableState { var message: String { switch verificationState { case .initial: - return L10n.screenSessionVerificationOpenExistingSessionSubtitle + switch flow { + case .initiator: + return L10n.screenSessionVerificationOpenExistingSessionSubtitle + case .responder: + return L10n.screenSessionVerificationRequestSubtitle + } + case .acceptingVerificationRequest: + return L10n.screenSessionVerificationRequestSubtitle case .requestingVerification: return L10n.screenSessionVerificationWaitingToAcceptSubtitle case .verificationRequestAccepted: @@ -60,7 +115,7 @@ struct SessionVerificationScreenViewState: BindableState { case .acceptingChallenge: return L10n.screenSessionVerificationCompareEmojisSubtitle case .decliningChallenge: - return L10n.commonWaiting + return L10n.screenSessionVerificationCompareEmojisSubtitle case .cancelling: return L10n.commonWaiting case .showingChallenge: @@ -68,15 +123,7 @@ struct SessionVerificationScreenViewState: BindableState { case .verified: return L10n.screenSessionVerificationCompleteSubtitle case .cancelled: - return L10n.screenSessionVerificationCancelledSubtitle + return L10n.screenSessionVerificationFailedSubtitle } } } - -enum SessionVerificationScreenViewAction { - case requestVerification - case startSasVerification - case restart - case accept - case decline -} diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenStateMachine.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenStateMachine.swift index 1c90d5e9d..f3a0f00d3 100644 --- a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenStateMachine.swift +++ b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenStateMachine.swift @@ -13,6 +13,8 @@ class SessionVerificationScreenStateMachine { enum State: StateType { /// The initial state, before verification started case initial + /// Accepting the remote verification request + case acceptingVerificationRequest /// Waiting for verification acceptance case requestingVerification /// Verification request accepted. Waiting for start @@ -37,6 +39,8 @@ class SessionVerificationScreenStateMachine { /// Events that can be triggered on the SessionVerification state machine enum Event: EventType { + /// Accept the remote verification request + case acceptVerificationRequest /// Request verification case requestVerification /// The current verification request has been accepted @@ -69,16 +73,23 @@ class SessionVerificationScreenStateMachine { stateMachine.state } - init() { - stateMachine = StateMachine(state: .initial) + init(state: State) { + stateMachine = StateMachine(state: state) configure() } private func configure() { + stateMachine.addRoutes(event: .acceptVerificationRequest, transitions: [.initial => .acceptingVerificationRequest]) stateMachine.addRoutes(event: .requestVerification, transitions: [.initial => .requestingVerification]) - stateMachine.addRoutes(event: .didAcceptVerificationRequest, transitions: [.requestingVerification => .verificationRequestAccepted]) + + stateMachine.addRoutes(event: .didAcceptVerificationRequest, transitions: [.acceptingVerificationRequest => .verificationRequestAccepted, + .requestingVerification => .verificationRequestAccepted]) + stateMachine.addRoutes(event: .startSasVerification, transitions: [.verificationRequestAccepted => .startingSasVerification]) - stateMachine.addRoutes(event: .didFail, transitions: [.requestingVerification => .initial]) + + stateMachine.addRoutes(event: .didFail, transitions: [.requestingVerification => .initial, + .acceptingVerificationRequest => .initial]) + stateMachine.addRoutes(event: .restart, transitions: [.cancelled => .initial]) // Transitions with associated values need to be handled through `addRouteMapping` diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenViewModel.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenViewModel.swift index b1a57333e..7264b0041 100644 --- a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenViewModel.swift +++ b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/SessionVerificationScreenViewModel.swift @@ -12,6 +12,7 @@ typealias SessionVerificationViewModelType = StateStoreViewModel some View { + static func sessionVerificationScreen(state: SessionVerificationScreenStateMachine.State, + flow: SessionVerificationScreenFlow = .initiator) -> some View { let viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: SessionVerificationControllerProxyMock.configureMock(), + flow: flow, verificationState: state) return SessionVerificationScreen(context: viewModel.context) diff --git a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift index 36d3429c3..83b2bd23d 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift @@ -91,6 +91,7 @@ class TimelineInteractionHandler { } } + // swiftlint:disable:next cyclomatic_complexity func handleTimelineItemMenuAction(_ action: TimelineItemMenuAction, itemID: TimelineItemIdentifier) { guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID), let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else { diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 28ed38ee1..3db90f896 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -50,6 +50,8 @@ class ClientProxy: ClientProxyProtocol { let secureBackupController: SecureBackupControllerProtocol + private(set) var sessionVerificationController: SessionVerificationControllerProxyProtocol? + private static var roomCreationPowerLevelOverrides: PowerLevels { .init(usersDefault: nil, eventsDefault: nil, @@ -157,7 +159,16 @@ class ClientProxy: ClientProxyProtocol { updateVerificationState(client.encryption().verificationState()) verificationStateListenerTaskHandle = client.encryption().verificationStateListener(listener: VerificationStateListenerProxy { [weak self] verificationState in - self?.updateVerificationState(verificationState) + guard let self else { return } + + updateVerificationState(verificationState) + + // The session verification controller requires the user's identity which + // isn't available before a keys query response. Use the verification + // state updates as an aproximation for when that happens. + Task { + await self.buildSessionVerificationControllerProxyIfPossible(verificationState: verificationState) + } }) sendQueueListenerTaskHandle = client.subscribeToSendQueueStatus(listener: SendQueueRoomErrorListenerProxy { [weak self] roomID, error in @@ -484,7 +495,8 @@ class ClientProxy: ClientProxyProtocol { func roomPreviewForIdentifier(_ identifier: String, via: [String]) async -> Result { do { let roomPreview = try await client.getRoomPreviewFromRoomId(roomId: identifier, viaServers: via) - return .success(.init(roomPreview)) + let roomPreviewInfo = try roomPreview.info() + return .success(.init(roomPreviewInfo)) } catch let error as ClientError where error.code == .forbidden { return .failure(.roomPreviewIsPrivate) } catch { @@ -561,16 +573,6 @@ class ClientProxy: ClientProxyProtocol { } } - func sessionVerificationControllerProxy() async -> Result { - do { - let sessionVerificationController = try await client.getSessionVerificationController() - return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController)) - } catch { - MXLog.error("Failed retrieving session verification controller proxy with error: \(error)") - return .failure(.sdkError(error)) - } - } - func logout() async -> URL? { do { return try await client.logout().flatMap(URL.init(string:)) @@ -728,6 +730,19 @@ class ClientProxy: ClientProxyProtocol { verificationStateSubject.send(verificationState) } + + private func buildSessionVerificationControllerProxyIfPossible(verificationState: VerificationState) async { + guard sessionVerificationController == nil, verificationState != .unknown else { + return + } + + do { + let sessionVerificationController = try await client.getSessionVerificationController() + self.sessionVerificationController = SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController) + } catch { + MXLog.error("Failed retrieving session verification controller proxy with error: \(error)") + } + } private func loadUserAvatarURLFromCache() { loadCachedAvatarURLTask = Task { @@ -1079,17 +1094,17 @@ private class SendQueueRoomErrorListenerProxy: SendQueueRoomErrorListener { } private extension RoomPreviewDetails { - init(_ roomPreview: RoomPreview) { - self = RoomPreviewDetails(roomID: roomPreview.roomId, - name: roomPreview.name, - canonicalAlias: roomPreview.canonicalAlias, - topic: roomPreview.topic, - avatarURL: roomPreview.avatarUrl.flatMap(URL.init(string:)), - memberCount: UInt(roomPreview.numJoinedMembers), - isHistoryWorldReadable: roomPreview.isHistoryWorldReadable, - isJoined: roomPreview.isJoined, - isInvited: roomPreview.isInvited, - isPublic: roomPreview.isPublic, - canKnock: roomPreview.canKnock) + init(_ roomPreviewInfo: RoomPreviewInfo) { + self = RoomPreviewDetails(roomID: roomPreviewInfo.roomId, + name: roomPreviewInfo.name, + canonicalAlias: roomPreviewInfo.canonicalAlias, + topic: roomPreviewInfo.topic, + avatarURL: roomPreviewInfo.avatarUrl.flatMap(URL.init(string:)), + memberCount: UInt(roomPreviewInfo.numJoinedMembers), + isHistoryWorldReadable: roomPreviewInfo.isHistoryWorldReadable, + isJoined: roomPreviewInfo.membership == .joined, + isInvited: roomPreviewInfo.membership == .invited, + isPublic: roomPreviewInfo.joinRule == .public, + canKnock: roomPreviewInfo.joinRule == .knock) } } diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index 8bbf4ecb5..5a28fb6a6 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -115,6 +115,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { var secureBackupController: SecureBackupControllerProtocol { get } + var sessionVerificationController: SessionVerificationControllerProxyProtocol? { get } + func isOnlyDeviceLeft() async -> Result func startSync() @@ -155,8 +157,6 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { func setUserAvatar(media: MediaInfo) async -> Result func removeUserAvatar() async -> Result - - func sessionVerificationControllerProxy() async -> Result func deactivateAccount(password: String?, eraseData: Bool) async -> Result diff --git a/ElementX/Sources/Services/ElementCall/ElementCallService.swift b/ElementX/Sources/Services/ElementCall/ElementCallService.swift index 1a02da982..9ca9b4a05 100644 --- a/ElementX/Sources/Services/ElementCall/ElementCallService.swift +++ b/ElementX/Sources/Services/ElementCall/ElementCallService.swift @@ -246,10 +246,8 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe func provider(_ provider: CXProvider, perform action: CXEndCallAction) { #if targetEnvironment(simulator) // This gets called for no reason on simulators, where CallKit - // isn't even supported. Ignore - return - #endif - + // isn't even supported, ignore it. + #else if let ongoingCallID { actionsSubject.send(.endCall(roomID: ongoingCallID.roomID)) } @@ -257,6 +255,7 @@ class ElementCallService: NSObject, ElementCallServiceProtocol, PKPushRegistryDe tearDownCallSession(sendEndCallAction: false) action.fulfill() + #endif } // MARK: - Private diff --git a/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxy.swift b/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxy.swift index 4ae2052ef..72c77e1f1 100644 --- a/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxy.swift +++ b/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxy.swift @@ -18,6 +18,10 @@ private class WeakSessionVerificationControllerProxy: SessionVerificationControl // MARK: - SessionVerificationControllerDelegate + func didReceiveVerificationRequest(details: MatrixRustSDK.SessionVerificationRequestDetails) { + proxy?.didReceiveVerificationRequest(details: details) + } + func didReceiveVerificationData(data: MatrixRustSDK.SessionVerificationData) { switch data { // We can handle only emojis for now @@ -54,86 +58,142 @@ class SessionVerificationControllerProxy: SessionVerificationControllerProxyProt init(sessionVerificationController: SessionVerificationController) { self.sessionVerificationController = sessionVerificationController + sessionVerificationController.setDelegate(delegate: WeakSessionVerificationControllerProxy(proxy: self)) } deinit { sessionVerificationController.setDelegate(delegate: nil) } - let callbacks = PassthroughSubject() + let actions = PassthroughSubject() + + func acknowledgeVerificationRequest(details: SessionVerificationRequestDetails) async -> Result { + MXLog.info("Acknowledging verification request") + + do { + try await sessionVerificationController.acknowledgeVerificationRequest(senderId: details.senderID, flowId: details.flowID) + return .success(()) + } catch { + MXLog.error("Failed requesting session verification with error: \(error)") + return .failure(.failedAcknowledgingVerificationRequest) + } + } + + func acceptVerificationRequest() async -> Result { + MXLog.info("Accepting verification request") + + do { + try await sessionVerificationController.acceptVerificationRequest() + return .success(()) + } catch { + MXLog.error("Failed requesting session verification with error: \(error)") + return .failure(.failedAcceptingVerificationRequest) + } + } func requestVerification() async -> Result { - sessionVerificationController.setDelegate(delegate: WeakSessionVerificationControllerProxy(proxy: self)) + MXLog.info("Requesting session verification") do { try await sessionVerificationController.requestVerification() return .success(()) } catch { + MXLog.error("Failed requesting session verification with error: \(error)") return .failure(.failedRequestingVerification) } } func startSasVerification() async -> Result { + MXLog.info("Starting SAS verification") + do { try await sessionVerificationController.startSasVerification() return .success(()) } catch { + MXLog.error("Failed starting SAS verification with error: \(error)") return .failure(.failedStartingSasVerification) } } func approveVerification() async -> Result { + MXLog.info("Approving verification") + do { try await sessionVerificationController.approveVerification() return .success(()) } catch { + MXLog.error("Failed approving verification with error: \(error)") return .failure(.failedApprovingVerification) } } func declineVerification() async -> Result { + MXLog.info("Declining verification") + do { try await sessionVerificationController.declineVerification() return .success(()) } catch { + MXLog.error("Failed declining verification with error: \(error)") return .failure(.failedDecliningVerification) } } func cancelVerification() async -> Result { + MXLog.info("Cancelling verification") + do { try await sessionVerificationController.cancelVerification() return .success(()) } catch { + MXLog.error("Failed cancelling verification with error: \(error)") return .failure(.failedCancellingVerification) } } // MARK: - Private + fileprivate func didReceiveVerificationRequest(details: MatrixRustSDK.SessionVerificationRequestDetails) { + MXLog.info("Received verification request \(details)") + + let details = SessionVerificationRequestDetails(senderID: details.senderId, + flowID: details.flowId, + deviceID: details.deviceId, + displayName: details.displayName, + firstSeenDate: Date(timeIntervalSince1970: TimeInterval(details.firstSeenTimestamp / 1000))) + + actions.send(.receivedVerificationRequest(details: details)) + } + fileprivate func didAcceptVerificationRequest() { - callbacks.send(.acceptedVerificationRequest) + MXLog.info("Accepted verification request") + + actions.send(.acceptedVerificationRequest) } fileprivate func didStartSasVerification() { - callbacks.send(.startedSasVerification) + MXLog.info("Started SAS verification") + + actions.send(.startedSasVerification) } fileprivate func didReceiveData(_ data: [MatrixRustSDK.SessionVerificationEmoji]) { - callbacks.send(.receivedVerificationData(data.map { emoji in + MXLog.info("Received verification data") + + actions.send(.receivedVerificationData(data.map { emoji in SessionVerificationEmoji(symbol: emoji.symbol(), description: emoji.description()) })) } fileprivate func didFail() { - callbacks.send(.failed) + actions.send(.failed) } fileprivate func didFinish() { - callbacks.send(.finished) + actions.send(.finished) } fileprivate func didCancel() { - callbacks.send(.cancelled) + actions.send(.cancelled) } } diff --git a/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxyProtocol.swift b/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxyProtocol.swift index 9d1e95e22..8f2555245 100644 --- a/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxyProtocol.swift +++ b/ElementX/Sources/Services/SessionVerification/SessionVerificationControllerProxyProtocol.swift @@ -7,8 +7,11 @@ import Combine import Foundation +import MatrixRustSDK enum SessionVerificationControllerProxyError: Error { + case failedAcknowledgingVerificationRequest + case failedAcceptingVerificationRequest case failedRequestingVerification case failedStartingSasVerification case failedApprovingVerification @@ -16,7 +19,8 @@ enum SessionVerificationControllerProxyError: Error { case failedCancellingVerification } -enum SessionVerificationControllerProxyCallback { +enum SessionVerificationControllerProxyAction { + case receivedVerificationRequest(details: SessionVerificationRequestDetails) case acceptedVerificationRequest case startedSasVerification case receivedVerificationData([SessionVerificationEmoji]) @@ -25,6 +29,14 @@ enum SessionVerificationControllerProxyCallback { case failed } +struct SessionVerificationRequestDetails { + let senderID: String + let flowID: String + let deviceID: String + let displayName: String? + let firstSeenDate: Date +} + struct SessionVerificationEmoji: Hashable { let symbol: String let description: String @@ -36,7 +48,11 @@ struct SessionVerificationEmoji: Hashable { // sourcery: AutoMockable protocol SessionVerificationControllerProxyProtocol { - var callbacks: PassthroughSubject { get } + var actions: PassthroughSubject { get } + + func acknowledgeVerificationRequest(details: SessionVerificationRequestDetails) async -> Result + + func acceptVerificationRequest() async -> Result func requestVerification() async -> Result diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 1d4e6ca03..01cf66c47 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -519,7 +519,8 @@ class MockScreen: Identifiable { return navigationStackCoordinator case .sessionVerification: var sessionVerificationControllerProxy = SessionVerificationControllerProxyMock.configureMock(requestDelay: .seconds(5)) - let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationControllerProxy) + let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationControllerProxy, + flow: .initiator) return SessionVerificationScreenCoordinator(parameters: parameters) case .userSessionScreen, .userSessionScreenReply: let appSettings: AppSettings = ServiceLocator.shared.settings diff --git a/PreviewTests/Sources/GeneratedPreviewTests.swift b/PreviewTests/Sources/GeneratedPreviewTests.swift index c68538da0..92bc2aa7c 100644 --- a/PreviewTests/Sources/GeneratedPreviewTests.swift +++ b/PreviewTests/Sources/GeneratedPreviewTests.swift @@ -755,6 +755,12 @@ extension PreviewTests { } } + func test_sessionVerificationRequestDetailsView() { + for preview in SessionVerificationRequestDetailsView_Previews._allPreviews { + assertSnapshots(matching: preview) + } + } + func test_sessionVerification() { for preview in SessionVerification_Previews._allPreviews { assertSnapshots(matching: preview) diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-en-GB.Set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-en-GB.Set-up.png index 5fba7b07a..fee238dbd 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-en-GB.Set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-en-GB.Set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0df8343fdaca7ed2ffa9b81b493cb1a5ab896d0f2cef08f83c0721815eb6c59d -size 133003 +oid sha256:2642ca05da869cf59a8c275465b67e43db8d01f7d984543ee4442a1a72fee1c2 +size 140623 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-pseudo.Set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-pseudo.Set-up.png index f61b87852..f1c54e396 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-pseudo.Set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPad-pseudo.Set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0511b9ba854183d086141e097e2cb88e39af7225d235b136e23676dde7447e9b -size 179038 +oid sha256:77d646f5b1e3f8377c674eb61b184670ba3e6e5eb26e16644a1271ec75d79cbb +size 194850 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-en-GB.Set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-en-GB.Set-up.png index 9da5b29f6..91b57faa3 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-en-GB.Set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-en-GB.Set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e02892489581a9b285085fcda484561ff2f88e552934d6fdf3b78c9e53d8d04 -size 88970 +oid sha256:57ba61f6ee8a7d6a382851bfe161d922a8179a58d4ddd191a08eb9891ab8a30b +size 98103 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-pseudo.Set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-pseudo.Set-up.png index bd7a7f31a..b8bc03f32 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-pseudo.Set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupKeyBackupScreen-iPhone-16-pseudo.Set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9ad705443a5b1fdb27deae753c0fc4ffdddfa24316c6934b1e9ba1c9a2c250a -size 137811 +oid sha256:ea9ca53d25dd7f8fbd4453bca7dc02ffde0fd5bc43c0f183489080c5804fbc7c +size 153579 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Generating.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Generating.png index a4c309c22..38f0f60ea 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Generating.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Generating.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42456c30e4c48f49498df5fb78543864ba73475b0519bb845fd8aea2b2711d2e -size 122723 +oid sha256:ffd720a584f845b15c8174adddb75e35f9e6351e765a70bd014d7ed56b49b6ca +size 122368 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Not-set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Not-set-up.png index 0513d874d..ef9425c10 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Not-set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-en-GB.Not-set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d812c0830f2b0b88db0eba82fcbceb9b4c5698e7c55ad0e9e7fc5a9c83e96249 -size 123915 +oid sha256:f2c1eae53b77cd9dea156c19c53fbbfe28686b79d598ef81c462eccf7009dfa2 +size 123564 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Generating.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Generating.png index 3233c200c..23191e27d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Generating.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Generating.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af3a401be4780e063d611293d06988524e07ea45bd4558d51d0f4f0a937ce531 -size 150029 +oid sha256:27c5dcb193ec709f28df822e0caf323f2ec813cbb04eee7e8c92f97066a46f5f +size 149956 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Not-set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Not-set-up.png index b01b7ec75..ed1dc72b2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Not-set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPad-pseudo.Not-set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1500a5f539dc2ec3faae11c0d5a707f4329a15814d686de570baa901e1420fdf -size 151948 +oid sha256:624079d169186d352d6bc540df12a7b3f161d0653dc6659048027eef71f1e0d1 +size 151879 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Generating.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Generating.png index ed38a1f77..84ff377f9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Generating.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Generating.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1b0c218ffb7143d8da4567a02fa0741a94942449dd00c065b7415978a100e6d -size 76017 +oid sha256:f93b129a941aa558325a7124f9a72ca4c6a722d67b6325cdb38f6b0c64a6af6b +size 76045 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Not-set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Not-set-up.png index 17447ad8c..f725a97cd 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Not-set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-en-GB.Not-set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ba57bc91e2ca37583848b7127ebb0e6efc9f932cee136e596af6bd9f762490b -size 77531 +oid sha256:9d8b72b3b29a6d7ae5302fbff84c09e5364fc28f683fbc1d917a20a213accc06 +size 77564 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Generating.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Generating.png index da61400cb..017d38c6e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Generating.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Generating.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3dee45d086663e3348733885a809a68e3f86cc33c70ca4e49676daa04f8dcd02 -size 100956 +oid sha256:ccd9db4b98e04771c641c09e7d8c2bedcffd1eace9f2cb50628ac77051f81cd9 +size 101454 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Not-set-up.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Not-set-up.png index 633281d70..8899758d0 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Not-set-up.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_secureBackupRecoveryKeyScreen-iPhone-16-pseudo.Not-set-up.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6506e821995ed525758a557e0dc64c57c3331267c37cd4bcea742fc244cc435 -size 106296 +oid sha256:ce1816cf9eef04e5435a8a74c35d61fc8c8b5d4493c4577bad8bc267a0b00ea1 +size 106794 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Challenge.png new file mode 100644 index 000000000..58c12218f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78da542fab77c7138034ee29b3985d0b6198cb79600ec22679a9aa8cf6b7de7b +size 161895 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Verification-Request.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Verification-Request.png new file mode 100644 index 000000000..e1b75aa3f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Accepting-Verification-Request.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1e631e093fcbae1de84ecf012e2dad0feace858d4825f839adc9feae8d497ef +size 96902 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Cancelled.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Cancelled.png index 56240ba36..e9017e415 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Cancelled.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Cancelled.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94e76332e1728aac71a9684ee484eae180e84c88ea616798df0c5d883ac1e644 -size 93529 +oid sha256:5e2aacff101d124325e3966e44c22fa02ef1a307c23a723d6622d4ee64412c21 +size 95267 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Declining-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Declining-Challenge.png new file mode 100644 index 000000000..58c12218f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Declining-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78da542fab77c7138034ee29b3985d0b6198cb79600ec22679a9aa8cf6b7de7b +size 161895 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial-Initiator.png similarity index 100% rename from PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial.png rename to PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial-Initiator.png diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial-Responder.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial-Responder.png new file mode 100644 index 000000000..5eda7c579 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Initial-Responder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de6d5e5d95b4fee23d4b0a7fb771752ac426c6bf81499b9c6e3a357a10d2c2f8 +size 125144 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Requesting-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Requesting-Verification.png index ac0755928..8eed329f3 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Requesting-Verification.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Requesting-Verification.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a87fcdb4512157795aeaf16e9a94cab6a18677687f0015edbc0a696fc8a5215 -size 95084 +oid sha256:b6b0a9b619f1dc6f02399aa4976c3dc19796d987e2a41ed37e5c2a449c85c11d +size 98780 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.SAS-Verification-started.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.SAS-Verification-started.png new file mode 100644 index 000000000..93aa6d0e3 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.SAS-Verification-started.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:356ec08a1adbca9186d746bb84c3597ec1f7e324bcc975186b9233ee3d3813d5 +size 72478 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Showing-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Showing-Challenge.png index 79a6ef199..1728de522 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Showing-Challenge.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Showing-Challenge.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90f39070e7c681d4bce49d494fe4cd967092f68dd16767db450d275993ded1cc -size 165443 +oid sha256:c8741e91150e57869e2f8d94a13360e57b4d243e9054711d2335a514e5d9029b +size 165427 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Starting-SAS-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Starting-SAS-Verification.png new file mode 100644 index 000000000..93aa6d0e3 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-en-GB.Starting-SAS-Verification.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:356ec08a1adbca9186d746bb84c3597ec1f7e324bcc975186b9233ee3d3813d5 +size 72478 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Challenge.png new file mode 100644 index 000000000..0dbc6de5c --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28e89a7b00f5b07cc1ebef0034a38d2bfebdce8d8e924c20252877d8f4643d44 +size 180153 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Verification-Request.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Verification-Request.png new file mode 100644 index 000000000..a372662b1 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Accepting-Verification-Request.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55e04390c635595b18a60905e2ebffef065d27a88023484cd1a25e9a683ea378 +size 108580 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Cancelled.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Cancelled.png index ac4b4d386..877166a2c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Cancelled.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Cancelled.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec94f9759e1a8f8bba3feb88d0e35fceff8f4bd69b3860034cfd3596310f02cc -size 105774 +oid sha256:2c313669307a1f85aef0d367a1284685eee2ed0f07b4b0fcedfa3728f27b869f +size 108998 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Declining-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Declining-Challenge.png new file mode 100644 index 000000000..0dbc6de5c --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Declining-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28e89a7b00f5b07cc1ebef0034a38d2bfebdce8d8e924c20252877d8f4643d44 +size 180153 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial-Initiator.png similarity index 100% rename from PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial.png rename to PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial-Initiator.png diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial-Responder.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial-Responder.png new file mode 100644 index 000000000..7f1fd8249 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Initial-Responder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bad67fb36d792965b12fe728fae7c9664d4b8031c554117162fadd4b74502045 +size 146678 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Requesting-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Requesting-Verification.png index 54c3f0007..afa704e8d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Requesting-Verification.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Requesting-Verification.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:802b547e9461a061bc51df508d8474d59d0175f35da057469dbfa2e8b18414ae -size 106580 +oid sha256:fa39a6dc77a211f757f20bdfa63ef04bfd79dd3d3b69a5bb8e3d9fc454a18e06 +size 111330 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.SAS-Verification-started.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.SAS-Verification-started.png new file mode 100644 index 000000000..f577b869d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.SAS-Verification-started.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21a964833655bb12bbbb2ae486961cad6f3046bd3c2c6a2127c99821b14e0dcd +size 72175 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Showing-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Showing-Challenge.png index a4f937942..426bb9d73 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Showing-Challenge.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Showing-Challenge.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b083b28e3dd51259f7fcae01f7bd482c684b3458d30dc464aba0d4cc4094b51 -size 184847 +oid sha256:f25fc8b1b70ac00f2eb1cf5b6e55c4c3b5e509b3ed2e03458c99c36fa5abb30d +size 184353 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Starting-SAS-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Starting-SAS-Verification.png new file mode 100644 index 000000000..f577b869d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPad-pseudo.Starting-SAS-Verification.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21a964833655bb12bbbb2ae486961cad6f3046bd3c2c6a2127c99821b14e0dcd +size 72175 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Challenge.png new file mode 100644 index 000000000..99147967f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d039980194a63eb87c15b4179b6132cb98cd4b9c069a90483cc2761d771c7c6 +size 112841 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Verification-Request.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Verification-Request.png new file mode 100644 index 000000000..19feb7d54 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Accepting-Verification-Request.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8df3040ac64296541ce088a3c89d173874981fb413ec12168d4e6c976364c4a +size 54304 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Cancelled.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Cancelled.png index 8f36925c0..ac0a568b0 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Cancelled.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Cancelled.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40738872c62954bd5f86d4241f3128472c8328c3295fd3f6f46bfff2c38717f4 -size 52459 +oid sha256:d3eee192ba2ba7f7a04dc6b30ebd453ff037fd93cbdbc5f7385749f598718d2c +size 52650 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Declining-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Declining-Challenge.png new file mode 100644 index 000000000..99147967f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Declining-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d039980194a63eb87c15b4179b6132cb98cd4b9c069a90483cc2761d771c7c6 +size 112841 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial-Initiator.png similarity index 100% rename from PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial.png rename to PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial-Initiator.png diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial-Responder.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial-Responder.png new file mode 100644 index 000000000..e8d110ad6 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Initial-Responder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b4ab3956d6cdaab31410c633ad87f68b95992ed7f2f1fdcfe47d264833d925a +size 76508 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Requesting-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Requesting-Verification.png index 683e7ef27..f69522ee8 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Requesting-Verification.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Requesting-Verification.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b796634f5f0071e70fadfa6b13df5cc06425a42b450af365e91a4e14c0b6636 -size 52007 +oid sha256:c24f2aeb174dbaad526a45ea0aadc4a88e96af5acee0395dce735437f33fed37 +size 56314 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.SAS-Verification-started.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.SAS-Verification-started.png new file mode 100644 index 000000000..c19a7629e --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.SAS-Verification-started.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6f9ffc43e63a49254324af496f8aadda255e84f5ec97aae0f1a05542c8c1a5b +size 32123 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Showing-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Showing-Challenge.png index 8c0cbbd04..fd6ea1a9c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Showing-Challenge.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Showing-Challenge.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71eabdfd2d5cc1a86eb42043d1aa5e2a1c401722ecacdab7fd70e45898051c2c -size 114898 +oid sha256:d0c95e9f0f51109b8fef6f771a8fe27bcd33eac2e244eefbcad2f223c8228fc2 +size 115566 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Starting-SAS-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Starting-SAS-Verification.png new file mode 100644 index 000000000..c19a7629e --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-en-GB.Starting-SAS-Verification.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6f9ffc43e63a49254324af496f8aadda255e84f5ec97aae0f1a05542c8c1a5b +size 32123 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Challenge.png new file mode 100644 index 000000000..bec410d87 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:251fc57d77b23ca84e5b659dfb3cf51effba91e496566447dd5d5956f19eb81a +size 134250 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Verification-Request.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Verification-Request.png new file mode 100644 index 000000000..20dc47e8d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Accepting-Verification-Request.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61faed09ca05772707dc737fe7c9fbe7c59ddd5852b607f7df13a43071d1e82c +size 74935 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Cancelled.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Cancelled.png index d56b1dde9..4746b7935 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Cancelled.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Cancelled.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c6060f6ce1cd9d447f9d642dd2a007f1ddea9d56b877a567691f885e742e5aa -size 71244 +oid sha256:4cb1087bf68fc7dc34b5c26653ee7ddf3859f2f1de22df1513c1d7b944d68feb +size 71714 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Declining-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Declining-Challenge.png new file mode 100644 index 000000000..bec410d87 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Declining-Challenge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:251fc57d77b23ca84e5b659dfb3cf51effba91e496566447dd5d5956f19eb81a +size 134250 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial-Initiator.png similarity index 100% rename from PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial.png rename to PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial-Initiator.png diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial-Responder.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial-Responder.png new file mode 100644 index 000000000..9f49db15d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Initial-Responder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a7ffbb91030a6ba3d0e064bd6cbaaa0f109915cc4f04ceced27b0185b6a541f +size 101933 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Requesting-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Requesting-Verification.png index 644fc5b68..d3e5135cb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Requesting-Verification.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Requesting-Verification.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c1f50bc1cd49c71bed1e48f540497f82fca9e5ae2130114ed2257e42065a9f9 -size 69054 +oid sha256:c40c972bb56a40bbb70725248eee5ff642e9cced47e1b794128f1c2468309a84 +size 79541 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.SAS-Verification-started.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.SAS-Verification-started.png new file mode 100644 index 000000000..2d563d6a1 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.SAS-Verification-started.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cd1abe33be884130a8475ada0aab30cadd3ce7b1262e316bd0b4552aacead14 +size 33085 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Showing-Challenge.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Showing-Challenge.png index ddf00c2f4..fb252261b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Showing-Challenge.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Showing-Challenge.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:36baf8914073371e25859a9dcd82bd9e461efebc4a8905fea7b28eb1da84ae08 -size 135368 +oid sha256:91e8118f1315c91e4c4968fd6662253f0da5785dbf54a1c32aeb1b91a1785de9 +size 134584 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Starting-SAS-Verification.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Starting-SAS-Verification.png new file mode 100644 index 000000000..2d563d6a1 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerification-iPhone-16-pseudo.Starting-SAS-Verification.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cd1abe33be884130a8475ada0aab30cadd3ce7b1262e316bd0b4552aacead14 +size 33085 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-en-GB.1.png new file mode 100644 index 000000000..0b931ab12 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-en-GB.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db9bed799aae9732c42fc1361e72064f0b25e90abb4d8d07ec9cdc8441c8481e +size 92806 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-pseudo.1.png new file mode 100644 index 000000000..52be29cdb --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPad-pseudo.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d9d00be62424b27994eff708c279596bd6e3e64cdf733c9e350a4c21247db4c +size 101514 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-en-GB.1.png new file mode 100644 index 000000000..c96cbab3f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-en-GB.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c77f8338cafa5cb5f14fdc64e9855a78088bffc7d0017ccea69035417532693b +size 50064 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-pseudo.1.png new file mode 100644 index 000000000..701f2bdc1 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_sessionVerificationRequestDetailsView-iPhone-16-pseudo.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe6709b8a05591a74557ed266f980dfb9c8fcfd7b4d2ed94b5cd35dd692dd45e +size 59494 diff --git a/UITests/Sources/__Snapshots__/Application/createRoom-1-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/createRoom-1-iPad-10th-generation-en-GB.UI.png index fe99073c6..8ae26267c 100644 --- a/UITests/Sources/__Snapshots__/Application/createRoom-1-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/createRoom-1-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f3849e4c3756976f3a618f5e865abbf3541222785b40c8da614c788c83cb4d9 -size 139468 +oid sha256:c41e07b1476f8742d3d0bf6eb63bf03942715d40437082b9a3c6cb322742e860 +size 136314 diff --git a/UITests/Sources/__Snapshots__/Application/createRoom-1-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/createRoom-1-iPhone-16-en-GB.UI.png index 0f94ddfcd..8e531cb36 100644 --- a/UITests/Sources/__Snapshots__/Application/createRoom-1-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/createRoom-1-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b2d5bc69c3f0391f9981acb4f01bc327e4bf3a03a0a004185b343b725201b96 -size 177408 +oid sha256:2616b3ce1d12360d6c2d151d0647989bdd1ee452ea2efa6c7a24c25e8382c136 +size 167378 diff --git a/UITests/Sources/__Snapshots__/Application/createRoom-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/createRoom-iPad-10th-generation-en-GB.UI.png index 41d1da1a8..971eb3459 100644 --- a/UITests/Sources/__Snapshots__/Application/createRoom-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/createRoom-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86df341a29d0b0f1a284cc28f280d6c54d8d539f209270cf3fcc5e0b3b3da613 -size 143371 +oid sha256:8e0ace29cb70b56c0a4b23a44fa2a019036a6c29b8e5fcf5e72aa04c1e9cfeaa +size 138956 diff --git a/UITests/Sources/__Snapshots__/Application/createRoom-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/createRoom-iPhone-16-en-GB.UI.png index d9e0343b5..6a134b2a7 100644 --- a/UITests/Sources/__Snapshots__/Application/createRoom-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/createRoom-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd4e597b19ea7d5132e91427ec09ec980f4a485aea58f219a560c82003280e0a -size 182727 +oid sha256:40a328061699a3e9435f799bf20b009eaa48f66f6028037804f0435b16501fd5 +size 172709 diff --git a/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPad-10th-generation-en-GB.UI.png index fdd758a02..3cc86974e 100644 --- a/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86b80fb5bb11af1953261fcbe366b85d5d6486e6860884f546a8541212cda0f1 -size 122770 +oid sha256:7be6325cac7408df468f547a3cc1ef241c24efb652160fde4150e97109b2753c +size 119761 diff --git a/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPhone-16-en-GB.UI.png index 5953abdc1..4bfa63870 100644 --- a/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/createRoomNoUsers-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49d38ecb60a832ba39029a4e8f211439aa4c3948112fbdfd51e71538bb1d0fd1 -size 155107 +oid sha256:9ab4ce7eee2d029601e4d45b92aaac783df97a9b3ecb80b208a3d9cb2e9a1ce0 +size 144339 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-0-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-0-iPad-10th-generation-en-GB.UI.png index e322f4298..e5abbd632 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-0-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-0-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08b4681246a562c90a02a189663a7246fe135d037a7e5a0a1f5b4713a420fea1 -size 86484 +oid sha256:c548364f9ad63a7d7c1d53e53600572c3e1477b3fa1ea13d4b941a73cda76a8a +size 85908 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPad-10th-generation-en-GB.UI.png index bfd9392d6..268b46e9d 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ab61d812816d065aa8903c69df0459bba1142721cc9eef9e39ba05f7f505b66 -size 85240 +oid sha256:ccf7b17e2bad6bbce72d5b29e32a309865b2b2b9cb76a5af2447b675613b14c4 +size 89009 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPhone-16-en-GB.UI.png index 5fbf6aa90..90dc376dd 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-1-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3df7a0c44ac8ceeb5509c03f882ccaa57b5bb7fb6d54fa7f7f0ddb2c5be6d6ab -size 87190 +oid sha256:7970d3cce906d1e1947407d7a9de5e8994069bd2b191ef3dc7c0a6b6b889d3bf +size 93417 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPad-10th-generation-en-GB.UI.png index c68a1624d..2bc9fada1 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21932c55d7c3e55ce291c1ea410011a2b1b9647cd4e90d9295cefb85e74e8025 -size 84710 +oid sha256:8b375d9b216880cd6feea614a8ae9f722d1705e31e443d6c1620c20edb4a1a89 +size 83942 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPhone-16-en-GB.UI.png index 50cbef65e..b48b291b3 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-2-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e91b2715da11e04376bf99a910f9b441aa3e21d7fc9e4567b0667c84f8e85b3d -size 83835 +oid sha256:bf16f963d57f00a55133201b3fadd5820dc22d9af158d0d2163b088b675fe918 +size 84194 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPad-10th-generation-en-GB.UI.png index 8d9fc3b38..29a661411 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b58d6f9e5d1a4cc6d337634f96e2731fa9dea1cb128e2634d2ff2dc5858eb98b -size 65167 +oid sha256:cd87a89399242622d8176b1f4eb43f72b1f51314b0b8a01f0b5ac060516e65b3 +size 64449 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPhone-16-en-GB.UI.png index 77894f7b9..5645d68ad 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-3-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9728cb4db3d31f4b4c2a718c84cc8524aa18c4abdc5a7557099c82bd92c50726 -size 57405 +oid sha256:f7f4dd44b1ca63ee19ab316d3dfa4da2fa3dc65bbc875a94659074b7d454d4bb +size 56996 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPad-10th-generation-en-GB.UI.png index 0f9f26603..7ca009ad6 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d9c8b24cf3351eb186348ac79da58bbd3d54682cb37084b5f923887e8bdf8ed -size 148162 +oid sha256:d6dbe259250888fe47d35e40c377a88032e4cde2d1fdc5cbe7395afdd304cbae +size 147532 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPhone-16-en-GB.UI.png index 50598b817..c9bdb57b5 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-4-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78ba7b00929594e231aea48863e5224e864717e35a319a573d73af850fed6a08 -size 199952 +oid sha256:fe8a672f763bde80b901e4e8a0074658850942ed4f48e819b60bd67fef8bd025 +size 200840 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPad-10th-generation-en-GB.UI.png index c0da179fe..2d75cee45 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67c73fd1862c07dc1d93b0e4b98d13703a01b54a268d6352fe7776d0c58376f4 -size 146945 +oid sha256:050893bf116964c98d46d78d850cbcbfd92d11d612e5018c291f23d0ab4fffdd +size 144601 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPhone-16-en-GB.UI.png index 2aba6c0bb..4b33967bf 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-5-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3e372a52fe24ebede306c07107f482426b7ae2a8b8ef6c9e6a8a85af433b7a5 -size 197983 +oid sha256:9651e8d3e5ccc6f2a0ea0da2b4054f901ef28de0e2175ecb457d12ac318be64a +size 195662 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-6-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-6-iPad-10th-generation-en-GB.UI.png index fb67410bd..133318a2f 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-6-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-6-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2bff344e5fbc9b9ccb88b22866c511cd51cc6970127955947a54b33dfdcaa5da -size 85667 +oid sha256:35a2456bd43b0c5f15392cf37bad123ac10ca4362bde64e6a096f77be597d67e +size 84840 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPad-10th-generation-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPad-10th-generation-en-GB.UI.png index e087e3cc4..5b13865b0 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPad-10th-generation-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPad-10th-generation-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a154db9b1f771604817d54cc804309eaf80b92ec44632225c11cc9118f2ee6cb -size 85038 +oid sha256:3d0d342544d63dd9df0dd3f94e2a40d3bca7d9b91227e8b8b4e883efef85f19a +size 86265 diff --git a/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPhone-16-en-GB.UI.png b/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPhone-16-en-GB.UI.png index b10bda294..a0dd6b420 100644 --- a/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPhone-16-en-GB.UI.png +++ b/UITests/Sources/__Snapshots__/Application/sessionVerification-7-iPhone-16-en-GB.UI.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0714f4889baa952ec9597be6ab56c5aef38a706ee80bc881fd395d46f4bf958b -size 87063 +oid sha256:5c59e4b368e0bcb294803118a66eb88f6bdc51460067cbd2527ac0c878a094e5 +size 87335 diff --git a/UnitTests/Sources/SessionVerificationStateMachineTests.swift b/UnitTests/Sources/SessionVerificationStateMachineTests.swift index 472c86549..73fe84820 100644 --- a/UnitTests/Sources/SessionVerificationStateMachineTests.swift +++ b/UnitTests/Sources/SessionVerificationStateMachineTests.swift @@ -15,7 +15,7 @@ class SessionVerificationStateMachineTests: XCTestCase { @MainActor override func setUpWithError() throws { - stateMachine = SessionVerificationScreenStateMachine() + stateMachine = SessionVerificationScreenStateMachine(state: .initial) } func testAcceptChallenge() { diff --git a/UnitTests/Sources/SessionVerificationViewModelTests.swift b/UnitTests/Sources/SessionVerificationViewModelTests.swift index c19c2df46..ec284f712 100644 --- a/UnitTests/Sources/SessionVerificationViewModelTests.swift +++ b/UnitTests/Sources/SessionVerificationViewModelTests.swift @@ -18,7 +18,7 @@ class SessionVerificationViewModelTests: XCTestCase { override func setUpWithError() throws { sessionVerificationController = SessionVerificationControllerProxyMock.configureMock() - viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: sessionVerificationController) + viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: sessionVerificationController, flow: .initiator) context = viewModel.context } @@ -66,7 +66,7 @@ class SessionVerificationViewModelTests: XCTestCase { let waitForAcceptance = XCTestExpectation(description: "Wait for acceptance") - let cancellable = sessionVerificationController.callbacks + let cancellable = sessionVerificationController.actions .delay(for: .seconds(0.1), scheduler: DispatchQueue.main) // Allow the view model to process the callback first. .sink { callback in switch callback { @@ -94,7 +94,7 @@ class SessionVerificationViewModelTests: XCTestCase { let expectation = XCTestExpectation(description: "Wait for cancellation") - let cancellable = sessionVerificationController.callbacks + let cancellable = sessionVerificationController.actions .delay(for: .seconds(0.1), scheduler: DispatchQueue.main) // Allow the view model to process the callback first. .sink { callback in switch callback { @@ -124,7 +124,7 @@ class SessionVerificationViewModelTests: XCTestCase { let sasVerificationStartExpectation = XCTestExpectation(description: "Wait for SaS verification start") let verificationDataReceivalExpectation = XCTestExpectation(description: "Wait for Emoji data") - let cancellable = sessionVerificationController.callbacks + let cancellable = sessionVerificationController.actions .delay(for: .seconds(0.1), scheduler: DispatchQueue.main) // Allow the view model to process the callback first. .sink { callback in switch callback { diff --git a/project.yml b/project.yml index 51f71ea1c..0ba6976db 100644 --- a/project.yml +++ b/project.yml @@ -59,7 +59,7 @@ packages: # Element/Matrix dependencies MatrixRustSDK: url: https://github.com/element-hq/matrix-rust-components-swift - exactVersion: 1.0.61 + exactVersion: 1.0.62 # path: ../matrix-rust-sdk Compound: url: https://github.com/element-hq/compound-ios