From 9a997510c5b8a47670b65ce4b1e87c84aab338b4 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Thu, 30 Nov 2023 14:19:58 +0100 Subject: [PATCH 1/4] MESSENGER-5271 crosssigning - verification request on button click --- Riot/Assets/de.lproj/Bwi.strings | 1 + Riot/Assets/en.lproj/Bwi.strings | 2 + Riot/Generated/BWIStrings.swift | 4 ++ ...ionSelfVerifyWaitViewController.storyboard | 46 ++++++++++++------- ...ficationSelfVerifyWaitViewController.swift | 16 +++++-- 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/Riot/Assets/de.lproj/Bwi.strings b/Riot/Assets/de.lproj/Bwi.strings index d921e96b2..48923b426 100644 --- a/Riot/Assets/de.lproj/Bwi.strings +++ b/Riot/Assets/de.lproj/Bwi.strings @@ -321,6 +321,7 @@ "key_verification_verified_this_session_information" = "Deine Anmeldung wurde erfolgreich verifiziert."; "key_verification_verified_other_session_information" = "Deine Anmeldung wurde erfolgreich verifiziert."; "key_verification_tile_request_alert_title" = "Verifizierung angefragt"; +"device_verification_crosssigning_wait_recover_secrets" = "Mit anderem Gerät verifizieren"; // MARK: - Secrets Recovery diff --git a/Riot/Assets/en.lproj/Bwi.strings b/Riot/Assets/en.lproj/Bwi.strings index 90e0d6b55..100ece5f1 100644 --- a/Riot/Assets/en.lproj/Bwi.strings +++ b/Riot/Assets/en.lproj/Bwi.strings @@ -242,6 +242,8 @@ "key_verification_verify_qr_code_information_other_device" = "Scan code either with this device or another."; "key_verification_verify_qr_code_cannot_scan_action" = "Compare with emojis instead"; "key_verification_tile_request_alert_title" = "Verification requested"; +"device_verification_crosssigning_wait_recover_secrets" = "Verify with other device"; + "room_participants_security_information_room_not_encrypted" = "Messages in this room are not end-to-end encrypted."; "room_participants_security_information_room_not_encrypted_for_dm" = "Messages here are not end-to-end encrypted."; diff --git a/Riot/Generated/BWIStrings.swift b/Riot/Generated/BWIStrings.swift index 31128d177..4fe23267e 100644 --- a/Riot/Generated/BWIStrings.swift +++ b/Riot/Generated/BWIStrings.swift @@ -727,6 +727,10 @@ public class BWIL10n: NSObject { public static var deviceVerificationCancelled: String { return BWIL10n.tr("Bwi", "device_verification_cancelled") } + /// Mit anderem Gerät verifizieren + public static var deviceVerificationCrosssigningWaitRecoverSecrets: String { + return BWIL10n.tr("Bwi", "device_verification_crosssigning_wait_recover_secrets") + } /// Anmeldung verifizieren public static var deviceVerificationOtherLoginVerifyWaitTitle: String { return BWIL10n.tr("Bwi", "device_verification_other_login_verify_wait_title") diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.storyboard b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.storyboard index 0dcf70679..733d959a6 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.storyboard +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,13 +17,13 @@ - + - + - + - + @@ -73,12 +73,25 @@ Open Element on one of your other devices and follow the instructions. - + + - + - - + - + diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift index 7baaaf89a..ba0ad4b82 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift @@ -41,6 +41,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { @IBOutlet private weak var recoverSecretsAvailabilityActivityIndicatorView: UIActivityIndicatorView! @IBOutlet private weak var recoverSecretsContainerView: UIView! @IBOutlet private weak var recoverSecretsButton: RoundedButton! + // bwi #5271 don't do crosssigning request at view start but as action on button click + @IBOutlet private weak var crosssigningButton: RoundedButton! @IBOutlet private weak var recoverSecretsAdditionalInformationLabel: UILabel! // MARK: Private @@ -77,12 +79,10 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.update(theme: self.theme) } - // BWI resend verificationrequest after cancling QR Code crosssigning override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.viewModel.viewDelegate = self - self.viewModel.process(viewAction: .loadData) } @@ -109,6 +109,7 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.recoverSecretsAvailabilityActivityIndicatorView.color = theme.tintColor // BWI: #4966 self.recoverSecretsButton.update(theme: theme) + self.crosssigningButton.update(theme: theme) } private func registerThemeServiceDidChangeThemeNotification() { @@ -140,8 +141,13 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.mobileClientImageView.image = Asset.Images.smartphone.image.withRenderingMode(.alwaysTemplate) self.recoverSecretsAdditionalInformationLabel.text = BWIL10n.deviceVerificationSelfVerifyWaitRecoverSecretsAdditionalInformation + + self.recoverSecretsButton.setTitle(BWIL10n.deviceVerificationSelfVerifyWaitRecoverSecretsWithPassphrase, for: .normal) + self.crosssigningButton.setTitle(BWIL10n.deviceVerificationCrosssigningWaitRecoverSecrets, for: .normal) + + self.recoverSecretsAvailabilityLoadingContainerView.isHidden = true } - + private func render(viewState: KeyVerificationSelfVerifyWaitViewState) { switch viewState { case .loading: @@ -237,6 +243,10 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { @IBAction private func recoverSecretsButtonAction(_ sender: Any) { self.viewModel.process(viewAction: .recoverSecrets) } + + @IBAction private func crossSigningButtonAction(_ sender: Any) { + self.viewModel.process(viewAction: .loadData) + } } From c8a32e3431f1b878de796472399068c566f67a47 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Tue, 5 Dec 2023 12:46:26 +0100 Subject: [PATCH 2/4] MESSENGER-5271 crosssigning - add alert and better strings, only show button when usable --- Riot/Assets/de.lproj/Bwi.strings | 3 ++ Riot/Assets/en.lproj/Bwi.strings | 4 +- Riot/Generated/BWIStrings.swift | 12 ++++++ ...erificationSelfVerifyWaitCoordinator.swift | 3 +- ...ficationSelfVerifyWaitViewController.swift | 41 ++++++++++++++++++- ...yVerificationSelfVerifyWaitViewModel.swift | 14 +++++++ ...ificationSelfVerifyWaitViewModelType.swift | 2 + ...yVerificationSelfVerifyWaitViewState.swift | 2 + 8 files changed, 78 insertions(+), 3 deletions(-) diff --git a/Riot/Assets/de.lproj/Bwi.strings b/Riot/Assets/de.lproj/Bwi.strings index 48923b426..ed0e57ad8 100644 --- a/Riot/Assets/de.lproj/Bwi.strings +++ b/Riot/Assets/de.lproj/Bwi.strings @@ -357,6 +357,9 @@ "secrets_reset_warning_message" = "Du verlierst dadurch deinen gesamten bisherigen Nachrichtenverlauf, sowie verfizierte Geräte oder Nutzer!"; "secrets_reset_reset_action" = "Zurücksetzen"; "secrets_reset_authentication_message" = "Bestätige mit deinem Passwort!"; +"secrets_recovery_verification_alert_title" = "Anmeldung verifizieren"; +"secrets_recovery_verification_alert_message" = "Eine Verifizierungsanfrage wurde gesendet. Öffne eine deiner anderen Sitzungen, um sie zu akzeptieren und mit der Verifizierung zu beginnen."; +"secrets_recovery_verification_alert_cancel" = "Ok"; // MARK: - PIN Protection diff --git a/Riot/Assets/en.lproj/Bwi.strings b/Riot/Assets/en.lproj/Bwi.strings index 100ece5f1..94b258abf 100644 --- a/Riot/Assets/en.lproj/Bwi.strings +++ b/Riot/Assets/en.lproj/Bwi.strings @@ -243,7 +243,9 @@ "key_verification_verify_qr_code_cannot_scan_action" = "Compare with emojis instead"; "key_verification_tile_request_alert_title" = "Verification requested"; "device_verification_crosssigning_wait_recover_secrets" = "Verify with other device"; - +"secrets_recovery_verification_alert_title" = "Verify"; +"secrets_recovery_verification_alert_message" = "A verification request has been sent. Open one of your sessions to accept and start the verification"; +"secrets_recovery_verification_alert_cancel" = "Ok"; "room_participants_security_information_room_not_encrypted" = "Messages in this room are not end-to-end encrypted."; "room_participants_security_information_room_not_encrypted_for_dm" = "Messages here are not end-to-end encrypted."; diff --git a/Riot/Generated/BWIStrings.swift b/Riot/Generated/BWIStrings.swift index 4fe23267e..a4734132b 100644 --- a/Riot/Generated/BWIStrings.swift +++ b/Riot/Generated/BWIStrings.swift @@ -1339,6 +1339,18 @@ public class BWIL10n: NSObject { public static var secretsRecoveryResetActionPart2: String { return BWIL10n.tr("Bwi", "secrets_recovery_reset_action_part_2") } + /// Ok + public static var secretsRecoveryVerificationAlertCancel: String { + return BWIL10n.tr("Bwi", "secrets_recovery_verification_alert_cancel") + } + /// Eine Verifizierungsanfrage wurde gesendet. Öffne eine deiner anderen Sitzungen, um sie zu akzeptieren und mit der Verifizierung zu beginnen. + public static var secretsRecoveryVerificationAlertMessage: String { + return BWIL10n.tr("Bwi", "secrets_recovery_verification_alert_message") + } + /// Anmeldung verifizieren + public static var secretsRecoveryVerificationAlertTitle: String { + return BWIL10n.tr("Bwi", "secrets_recovery_verification_alert_title") + } /// Gib dein Verschlüsselungskennwort ein, um auf deine verschlüsselten Nachrichten und deine Cross-Signing-Identität zuzugreifen. Mit der Cross-Signing-Identität kannst du andere Sitzungen verifizieren. public static var secretsRecoveryWithKeyInformationDefault: String { return BWIL10n.tr("Bwi", "secrets_recovery_with_key_information_default") diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift index 4c3281cb0..052dcb94c 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift @@ -49,8 +49,9 @@ final class KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyW // MARK: - Public methods - func start() { + func start() { self.keyVerificationSelfVerifyWaitViewModel.coordinatorDelegate = self + self.keyVerificationSelfVerifyWaitViewModel.checkCrosssigningDevices() } func toPresentable() -> UIViewController { diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift index ba0ad4b82..df1f6d45b 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift @@ -55,6 +55,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { private weak var cancelBarButtonItem: UIBarButtonItem? + private var verificationAlert: UIAlertController? + // MARK: - Setup class func instantiate(with viewModel: KeyVerificationSelfVerifyWaitViewModelType, cancellable: Bool) -> KeyVerificationSelfVerifyWaitViewController { @@ -77,12 +79,13 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.registerThemeServiceDidChangeThemeNotification() self.update(theme: self.theme) + + self.viewModel.viewDelegate = self } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - self.viewModel.viewDelegate = self } @@ -90,6 +93,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { return self.theme.statusBarStyle } + + // MARK: - Private private func update(theme: Theme) { @@ -146,6 +151,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.crosssigningButton.setTitle(BWIL10n.deviceVerificationCrosssigningWaitRecoverSecrets, for: .normal) self.recoverSecretsAvailabilityLoadingContainerView.isHidden = true + + self.crosssigningButton.isHidden = true } private func render(viewState: KeyVerificationSelfVerifyWaitViewState) { @@ -162,6 +169,10 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.renderCancelledByMe(reason: reason) case .error(let error): self.render(error: error) + case .verificationAccepted: + self.verificationAccepted() + case .crosssigningPossible(let possible): + self.showCrosssigningButton(possible) } } @@ -204,6 +215,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.recoverSecretsAvailabilityActivityIndicatorView.stopAnimating() self.recoverSecretsContainerView.isHidden = hideRecoverSecrets self.recoverSecretsButton.setTitle(recoverSecretsButtonTitle, for: .normal) + + self.showCrosssigningAlert() } private func renderCancelled(reason: MXTransactionCancelCode) { @@ -234,6 +247,32 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { } } + private func verificationAccepted() { + if let alert = self.verificationAlert { + alert.dismiss(animated: false) + } + } + + private func showCrosssigningButton(_ show: Bool) { + self.crosssigningButton.isHidden = !show + } + +o // bwi: show an alert when corsssigning button is pressed. This makes it clearer to the user what to do next + private func showCrosssigningAlert() { + self.verificationAlert = UIAlertController(title: BWIL10n.secretsRecoveryVerificationAlertTitle, + message: BWIL10n.secretsRecoveryVerificationAlertMessage, + preferredStyle: .alert) + + if let alert = self.verificationAlert { + let cancelActionTitle = BWIL10n.secretsRecoveryVerificationAlertCancel + let cancelAction = UIAlertAction(title: cancelActionTitle, style: .cancel) + + alert.addAction(cancelAction) + + present(alert, animated: true, completion: nil) + } + } + // MARK: - Actions private func cancelButtonAction() { diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift index 2f1b8a2ce..041a6ef43 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModel.swift @@ -83,6 +83,18 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai } } + // bwi: only show corsssigning button when there is more than one device in your account + func checkCrosssigningDevices() { + self.session.matrixRestClient.devices { [weak self] response in + switch response { + case .success(let devices): + self?.update(viewState: .crosssigningPossible(devices.count > 1)) + case .failure: + break + } + } + } + // MARK: - Private private func loadData() { @@ -258,6 +270,8 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai } if keyVerificationRequest.state == MXKeyVerificationRequestStateReady { + self.update(viewState: .verificationAccepted) + self.unregisterKeyVerificationRequestChangeNotification() self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, didAcceptKeyVerificationRequest: keyVerificationRequest) diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModelType.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModelType.swift index 66027c9e8..7c6f1832b 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModelType.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewModelType.swift @@ -36,4 +36,6 @@ protocol KeyVerificationSelfVerifyWaitViewModelType { var coordinatorDelegate: KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate? { get set } func process(viewAction: KeyVerificationSelfVerifyWaitViewAction) + + func checkCrosssigningDevices() } diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewState.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewState.swift index efd500b5e..409726e82 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewState.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewState.swift @@ -36,4 +36,6 @@ enum KeyVerificationSelfVerifyWaitViewState { case cancelled(MXTransactionCancelCode) case cancelledByMe(MXTransactionCancelCode) case error(Error) + case verificationAccepted + case crosssigningPossible(Bool) } From cd1b7053e8097378bf799a28714611c776f56aa7 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Tue, 5 Dec 2023 13:00:17 +0100 Subject: [PATCH 3/4] MESSENGER-5271 buildfix --- .../KeyVerificationSelfVerifyWaitViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift index df1f6d45b..fd5b76fe3 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift @@ -257,7 +257,7 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { self.crosssigningButton.isHidden = !show } -o // bwi: show an alert when corsssigning button is pressed. This makes it clearer to the user what to do next + // bwi: show an alert when corsssigning button is pressed. This makes it clearer to the user what to do next private func showCrosssigningAlert() { self.verificationAlert = UIAlertController(title: BWIL10n.secretsRecoveryVerificationAlertTitle, message: BWIL10n.secretsRecoveryVerificationAlertMessage, From 02fafc966e2b597f6e4c54b096b3192dc90a3ba0 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Tue, 5 Dec 2023 14:55:00 +0100 Subject: [PATCH 4/4] MESSENGER-5271 hide crosssigning information when only one device --- .../KeyVerificationSelfVerifyWaitViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift index fd5b76fe3..5df827d65 100644 --- a/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift +++ b/Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift @@ -255,6 +255,9 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController { private func showCrosssigningButton(_ show: Bool) { self.crosssigningButton.isHidden = !show + self.informationLabel.isHidden = !show + self.desktopClientImageView.isHidden = !show + self.mobileClientImageView.isHidden = !show } // bwi: show an alert when corsssigning button is pressed. This makes it clearer to the user what to do next