mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-20 14:42:09 +02:00
Merge pull request #4434 from vector-im/manu/4430_security_settings_update
Security settings: Improve the SECURE BACKUP section
This commit is contained in:
@@ -10,6 +10,9 @@ Changes to be released in next version
|
||||
* Integrated FLEX for debug builds.
|
||||
* VoIP: Add dial pad for PSTN capable servers to menu on homescreen.
|
||||
* VoIP: Replace call bar with PiP tiles for every type of calls.
|
||||
* Security settings: Display the cross-signing section (#4430).
|
||||
* Security settings: The Secure backup section has been updated to match element-web UX (#4430).
|
||||
* Wording: Replace Recovery Passphrase and Recovery Key by Security Phrase and Security Key (#4268).
|
||||
* Room directory: Join room by alias or id (#4429).
|
||||
|
||||
🐛 Bugfix
|
||||
|
||||
@@ -568,7 +568,7 @@ Tap the + to start adding people.";
|
||||
"settings_key_backup_info" = "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.";
|
||||
"settings_key_backup_info_checking" = "Checking…";
|
||||
"settings_key_backup_info_none" = "Your keys are not being backed up from this session.";
|
||||
"settings_key_backup_info_signout_warning" = "Connect this session to key backup before signing out to avoid losing any keys that may only be on this device.";
|
||||
"settings_key_backup_info_signout_warning" = "Back up your keys before signing out to avoid losing them.";
|
||||
"settings_key_backup_info_version" = "Key Backup Version: %@";
|
||||
"settings_key_backup_info_algorithm" = "Algorithm: %@";
|
||||
"settings_key_backup_info_valid" = "This session is backing up your keys.";
|
||||
@@ -622,10 +622,13 @@ Tap the + to start adding people.";
|
||||
"security_settings_crypto_sessions_description_2" = "If you don’t recognise a login, change your password and reset Secure Backup.";
|
||||
|
||||
"security_settings_secure_backup" = "SECURE BACKUP";
|
||||
"security_settings_secure_backup_description" = "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.";
|
||||
"security_settings_secure_backup_description" = "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.";
|
||||
"security_settings_secure_backup_info_checking" = "Checking…";
|
||||
"security_settings_secure_backup_info_valid" = "This session is backing up your keys.";
|
||||
"security_settings_secure_backup_setup" = "Set up";
|
||||
"security_settings_secure_backup_synchronise" = "Synchronise";
|
||||
"security_settings_secure_backup_delete" = "Delete";
|
||||
"security_settings_secure_backup_reset" = "Reset";
|
||||
"security_settings_secure_backup_restore" = "Restore from Backup";
|
||||
"security_settings_secure_backup_delete" = "Delete Backup";
|
||||
|
||||
"security_settings_backup" = "MESSAGE BACKUP";
|
||||
|
||||
@@ -633,9 +636,9 @@ Tap the + to start adding people.";
|
||||
"security_settings_crosssigning_info_not_bootstrapped" = "Cross-signing is not yet set up.";
|
||||
"security_settings_crosssigning_info_exists" = "Your account has a cross-signing identity, but it is not yet trusted by this session. Complete security of this session.";
|
||||
"security_settings_crosssigning_info_trusted" = "Cross-signing is enabled. You can trust other users and your other sessions based on cross-signing but you cannot cross-sign from this session because it does not have cross-signing private keys. Complete security of this session.";
|
||||
"security_settings_crosssigning_info_ok" = "Cross-signing is enabled.";
|
||||
"security_settings_crosssigning_bootstrap" = "Bootstrap cross-signing";
|
||||
"security_settings_crosssigning_reset" = "Reset cross-signing";
|
||||
"security_settings_crosssigning_info_ok" = "Cross-signing is ready for use.";
|
||||
"security_settings_crosssigning_bootstrap" = "Set up";
|
||||
"security_settings_crosssigning_reset" = "Reset";
|
||||
"security_settings_crosssigning_complete_security" = "Complete security";
|
||||
|
||||
"security_settings_cryptography" = "CRYPTOGRAPHY";
|
||||
@@ -899,7 +902,7 @@ Tap the + to start adding people.";
|
||||
|
||||
// Key backup wrong version
|
||||
"e2e_key_backup_wrong_version_title" = "New Key Backup";
|
||||
"e2e_key_backup_wrong_version" = "A new secure message key backup has been detected.\n\nIf this wasn’t you, set a new passphrase in Settings.";
|
||||
"e2e_key_backup_wrong_version" = "A new secure message key backup has been detected.\n\nIf this wasn’t you, set a new Security Phrase in Settings.";
|
||||
"e2e_key_backup_wrong_version_button_settings" = "Settings";
|
||||
"e2e_key_backup_wrong_version_button_wasme" = "It was me";
|
||||
|
||||
@@ -1025,7 +1028,7 @@ Tap the + to start adding people.";
|
||||
"secure_key_backup_setup_intro_use_security_key_title" = "Use a Security Key";
|
||||
"secure_key_backup_setup_intro_use_security_key_info" = "Generate a security key to store somewhere safe like a password manager or a safe.";
|
||||
|
||||
"secure_key_backup_setup_intro_use_security_passphrase_title" = "Use a Security Passphrase";
|
||||
"secure_key_backup_setup_intro_use_security_passphrase_title" = "Use a Security Phrase";
|
||||
"secure_key_backup_setup_intro_use_security_passphrase_info" = "Enter a secret phrase only you know, and generate a key for backup.";
|
||||
|
||||
"secure_key_backup_setup_existing_backup_error_title" = "A backup for messages already exists";
|
||||
@@ -1064,66 +1067,69 @@ Tap the + to start adding people.";
|
||||
|
||||
// Passphrase
|
||||
|
||||
"key_backup_setup_passphrase_title" = "Secure your backup with a Passphrase";
|
||||
"key_backup_setup_passphrase_info" = "We'll store an encrypted copy of your keys on our server. Protect your backup with a passphrase to keep it secure.\n\nFor maximum security, this should be different from your account password.";
|
||||
"key_backup_setup_passphrase_title" = "Secure your backup with a Security Phrase";
|
||||
"key_backup_setup_passphrase_info" = "We'll store an encrypted copy of your keys on our server. Protect your backup with a phrase to keep it secure.\n\nFor maximum security, this should be different from your account password.";
|
||||
"key_backup_setup_passphrase_passphrase_title" = "Enter";
|
||||
"key_backup_setup_passphrase_passphrase_placeholder" = "Enter passphrase";
|
||||
"key_backup_setup_passphrase_passphrase_placeholder" = "Enter phrase";
|
||||
"key_backup_setup_passphrase_passphrase_valid" = "Great!";
|
||||
"key_backup_setup_passphrase_passphrase_invalid" = "Try adding a word";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_title" = "Confirm";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_placeholder" = "Confirm passphrase";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_placeholder" = "Confirm phrase";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_valid" = "Great!";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_invalid" = "Passphrase doesn’t match";
|
||||
"key_backup_setup_passphrase_set_passphrase_action" = "Set Passphrase";
|
||||
"key_backup_setup_passphrase_setup_recovery_key_info" = "Or, secure your backup with a Recovery Key, saving it somewhere safe.";
|
||||
"key_backup_setup_passphrase_setup_recovery_key_action" = "(Advanced) Set up with Recovery Key";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_invalid" = "phrase doesn’t match";
|
||||
"key_backup_setup_passphrase_set_passphrase_action" = "Set Phrase";
|
||||
"key_backup_setup_passphrase_setup_recovery_key_info" = "Or, secure your backup with a Security Key, saving it somewhere safe.";
|
||||
"key_backup_setup_passphrase_setup_recovery_key_action" = "(Advanced) Set up with Security Key";
|
||||
|
||||
// Success
|
||||
|
||||
"key_backup_setup_success_title" = "Success!";
|
||||
|
||||
// Success from passphrase
|
||||
"key_backup_setup_success_from_passphrase_info" = "Your keys are being backed up.\n\nYour recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.\n\nKeep your recovery key somewhere very secure, like a password manager (or a safe).";
|
||||
"key_backup_setup_success_from_passphrase_save_recovery_key_action" = "Save Recovery Key";
|
||||
"key_backup_setup_success_from_passphrase_info" = "Your keys are being backed up.\n\nYour Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.\n\nKeep your Security Key somewhere very secure, like a password manager (or a safe).";
|
||||
"key_backup_setup_success_from_passphrase_save_recovery_key_action" = "Save Security Key";
|
||||
"key_backup_setup_success_from_passphrase_done_action" = "Done";
|
||||
|
||||
// Success from recovery key
|
||||
"key_backup_setup_success_from_recovery_key_info" = "Your keys are being backed up.\n\nMake a copy of this recovery key and keep it safe.";
|
||||
"key_backup_setup_success_from_recovery_key_recovery_key_title" = "Recovery Key";
|
||||
"key_backup_setup_success_from_recovery_key_info" = "Your keys are being backed up.\n\nMake a copy of this Security Key and keep it safe.";
|
||||
"key_backup_setup_success_from_recovery_key_recovery_key_title" = "Security Key";
|
||||
"key_backup_setup_success_from_recovery_key_make_copy_action" = "Make a Copy";
|
||||
"key_backup_setup_success_from_recovery_key_made_copy_action" = "I've made a copy";
|
||||
|
||||
// Success from secure backup
|
||||
"key_backup_setup_success_from_secure_backup_info" = "Your keys are being backed up.";
|
||||
|
||||
// MARK: Key backup recover
|
||||
|
||||
"key_backup_recover_title" = "Secure Messages";
|
||||
|
||||
"key_backup_recover_invalid_passphrase_title" = "Incorrect Recovery Passphrase";
|
||||
"key_backup_recover_invalid_passphrase" = "Backup could not be decrypted with this passphrase: please verify that you entered the correct recovery passphrase.";
|
||||
"key_backup_recover_invalid_recovery_key_title" = "Recovery Key Mismatch";
|
||||
"key_backup_recover_invalid_recovery_key" = "Backup could not be decrypted with this key: please verify that you entered the correct recovery key.";
|
||||
"key_backup_recover_invalid_passphrase_title" = "Incorrect Security Phrase";
|
||||
"key_backup_recover_invalid_passphrase" = "Backup could not be decrypted with this phrase: please verify that you entered the correct Security Phrase.";
|
||||
"key_backup_recover_invalid_recovery_key_title" = "Security Key Mismatch";
|
||||
"key_backup_recover_invalid_recovery_key" = "Backup could not be decrypted with this key: please verify that you entered the correct Security Key.";
|
||||
|
||||
// Recover from private key
|
||||
"key_backup_recover_from_private_key_info" = "Restoring backup…";
|
||||
|
||||
// Recover from passphrase
|
||||
|
||||
"key_backup_recover_from_passphrase_info" = "Use your recovery passphrase to unlock your secure message history";
|
||||
"key_backup_recover_from_passphrase_info" = "Use your Security Phrase to unlock your secure message history";
|
||||
"key_backup_recover_from_passphrase_passphrase_title" = "Enter";
|
||||
"key_backup_recover_from_passphrase_passphrase_placeholder" = "Enter Passphrase";
|
||||
"key_backup_recover_from_passphrase_passphrase_placeholder" = "Enter Phrase";
|
||||
"key_backup_recover_from_passphrase_recover_action" = "Unlock History";
|
||||
|
||||
"key_backup_recover_from_passphrase_lost_passphrase_action_part1" = "Don’t know your recovery passphrase? You can ";
|
||||
"key_backup_recover_from_passphrase_lost_passphrase_action_part2" = "use your recovery key";
|
||||
"key_backup_recover_from_passphrase_lost_passphrase_action_part1" = "Don’t know your Security Phrase? You can ";
|
||||
"key_backup_recover_from_passphrase_lost_passphrase_action_part2" = "use your Security Key";
|
||||
"key_backup_recover_from_passphrase_lost_passphrase_action_part3" = ".";
|
||||
|
||||
// Recover from recovery key
|
||||
|
||||
"key_backup_recover_from_recovery_key_info" = "Use your recovery key to unlock your secure message history";
|
||||
"key_backup_recover_from_recovery_key_info" = "Use your Security Key to unlock your secure message history";
|
||||
"key_backup_recover_from_recovery_key_recovery_key_title" = "Enter";
|
||||
"key_backup_recover_from_recovery_key_recovery_key_placeholder" = "Enter Recovery Key";
|
||||
"key_backup_recover_from_recovery_key_recovery_key_placeholder" = "Enter Security Key";
|
||||
"key_backup_recover_from_recovery_key_recover_action" = "Unlock History";
|
||||
|
||||
"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "Lost your recovery key? You can set up a new one in settings.";
|
||||
"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "Lost your Security Key You can set up a new one in settings.";
|
||||
|
||||
// Success
|
||||
|
||||
@@ -1200,8 +1206,8 @@ Tap the + to start adding people.";
|
||||
"device_verification_self_verify_wait_new_sign_in_title" = "Verify this login";
|
||||
"device_verification_self_verify_wait_information" = "Verify this session from one of your other sessions, granting it access to encrypted messages.\n\nUse the latest Element on your other devices:";
|
||||
"device_verification_self_verify_wait_additional_information" = "This works with Element and other cross-signing capable Matrix clients.";
|
||||
"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Use Recovery Key";
|
||||
"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Use Recovery Passphrase or Key";
|
||||
"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Use Security Key";
|
||||
"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Use Security Phrase or Key";
|
||||
"device_verification_self_verify_wait_recover_secrets_additional_information" = "If you can't access an existing session";
|
||||
"device_verification_self_verify_wait_recover_secrets_checking_availability" = "Checking for other verification capabilities ...";
|
||||
|
||||
@@ -1435,38 +1441,40 @@ Tap the + to start adding people.";
|
||||
|
||||
// Recover with passphrase
|
||||
|
||||
"secrets_recovery_with_passphrase_title" = "Recovery Passphrase";
|
||||
"secrets_recovery_with_passphrase_information_default" = "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.";
|
||||
"secrets_recovery_with_passphrase_information_verify_device" = "Use your Recovery Passphrase to verify this device.";
|
||||
"secrets_recovery_with_passphrase_title" = "Security Phrase";
|
||||
"secrets_recovery_with_passphrase_information_default" = "Access your secure message history and your cross-signing identity for verifying other sessions by entering your Security Phrase.";
|
||||
"secrets_recovery_with_passphrase_information_verify_device" = "Use your Security Phrase to verify this device.";
|
||||
"secrets_recovery_with_passphrase_passphrase_title" = "Enter";
|
||||
"secrets_recovery_with_passphrase_passphrase_placeholder" = "Enter Recovery Passphrase";
|
||||
"secrets_recovery_with_passphrase_recover_action" = "Use Passphrase";
|
||||
"secrets_recovery_with_passphrase_passphrase_placeholder" = "Enter Security Phrase";
|
||||
"secrets_recovery_with_passphrase_recover_action" = "Use Phrase";
|
||||
|
||||
"secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "Don’t know your recovery passphrase? You can ";
|
||||
"secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "use your recovery key";
|
||||
"secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "Don’t know your Security Phrase? You can ";
|
||||
"secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "use your Security Key";
|
||||
"secrets_recovery_with_passphrase_lost_passphrase_action_part3" = ".";
|
||||
|
||||
"secrets_recovery_with_passphrase_invalid_passphrase_title" = "Unable to access secret storage";
|
||||
"secrets_recovery_with_passphrase_invalid_passphrase_message" = "Please verify that you entered the correct recovery passphrase.";
|
||||
"secrets_recovery_with_passphrase_invalid_passphrase_message" = "Please verify that you entered the correct Security Phrase.";
|
||||
|
||||
// Recover with key
|
||||
|
||||
"secrets_recovery_with_key_title" = "Recovery Key";
|
||||
"secrets_recovery_with_key_information_default" = "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.";
|
||||
"secrets_recovery_with_key_information_verify_device" = "Use your Recovery Key to verify this device.";
|
||||
"secrets_recovery_with_key_title" = "Security Key";
|
||||
"secrets_recovery_with_key_information_default" = "Access your secure message history and your cross-signing identity for verifying other sessions by entering your Security Key.";
|
||||
"secrets_recovery_with_key_information_verify_device" = "Use your Security Key to verify this device.";
|
||||
"secrets_recovery_with_key_information_unlock_secure_backup_with_phrase" = "Enter your Security Phrase to continue.";
|
||||
"secrets_recovery_with_key_information_unlock_secure_backup_with_key" = "Enter your Security Key to continue.";
|
||||
"secrets_recovery_with_key_recovery_key_title" = "Enter";
|
||||
"secrets_recovery_with_key_recovery_key_placeholder" = "Enter Recovery Key";
|
||||
"secrets_recovery_with_key_recovery_key_placeholder" = "Enter Security Key";
|
||||
"secrets_recovery_with_key_recover_action" = "Use Key";
|
||||
|
||||
"secrets_recovery_with_key_invalid_recovery_key_title" = "Unable to access secret storage";
|
||||
"secrets_recovery_with_key_invalid_recovery_key_message" = "Please verify that you entered the correct recovery key.";
|
||||
"secrets_recovery_with_key_invalid_recovery_key_message" = "Please verify that you entered the correct Security Key.";
|
||||
|
||||
// MARK: - Secrets set up
|
||||
|
||||
// Recovery Key
|
||||
|
||||
"secrets_setup_recovery_key_title" = "Save your Security Key";
|
||||
"secrets_setup_recovery_key_information" = "Store your Recovery Key somewhere safe. It can be used to unlock your encrypted messages & data.";
|
||||
"secrets_setup_recovery_key_information" = "Store your Security Key somewhere safe. It can be used to unlock your encrypted messages & data.";
|
||||
"secrets_setup_recovery_key_loading" = "Loading…";
|
||||
"secrets_setup_recovery_key_export_action" = "Save";
|
||||
"secrets_setup_recovery_key_done_action" = "Done";
|
||||
@@ -1483,10 +1491,10 @@ Tap the + to start adding people.";
|
||||
|
||||
"secrets_setup_recovery_passphrase_confirm_information" = "Enter your Security Phrase again to confirm it.";
|
||||
"secrets_setup_recovery_passphrase_confirm_passphrase_title" = "Confirm";
|
||||
"secrets_setup_recovery_passphrase_confirm_passphrase_placeholder" = "Confirm passphrase";
|
||||
"secrets_setup_recovery_passphrase_confirm_passphrase_placeholder" = "Confirm phrase";
|
||||
|
||||
"key_backup_setup_passphrase_confirm_passphrase_valid" = "Great!";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_invalid" = "Passphrase doesn’t match";
|
||||
"key_backup_setup_passphrase_confirm_passphrase_invalid" = "Phrase doesn’t match";
|
||||
|
||||
"secrets_setup_recovery_passphrase_summary_title" = "Save your Security Phrase";
|
||||
"secrets_setup_recovery_passphrase_summary_information" = "Remember your Security Phrase. It can be used to unlock your encrypted messages & data.";
|
||||
|
||||
@@ -97,6 +97,11 @@ internal enum StoryboardScene {
|
||||
|
||||
internal static let initialScene = InitialSceneType<Riot.KeyBackupSetupSuccessFromRecoveryKeyViewController>(storyboard: KeyBackupSetupSuccessFromRecoveryKeyViewController.self)
|
||||
}
|
||||
internal enum KeyBackupSetupSuccessFromSecureBackupViewController: StoryboardType {
|
||||
internal static let storyboardName = "KeyBackupSetupSuccessFromSecureBackupViewController"
|
||||
|
||||
internal static let initialScene = InitialSceneType<Riot.KeyBackupSetupSuccessFromSecureBackupViewController>(storyboard: KeyBackupSetupSuccessFromSecureBackupViewController.self)
|
||||
}
|
||||
internal enum KeyVerificationDataLoadingViewController: StoryboardType {
|
||||
internal static let storyboardName = "KeyVerificationDataLoadingViewController"
|
||||
|
||||
|
||||
@@ -1034,11 +1034,11 @@ internal enum VectorL10n {
|
||||
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsCheckingAvailability: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_checking_availability")
|
||||
}
|
||||
/// Use Recovery Passphrase or Key
|
||||
/// Use Security Phrase or Key
|
||||
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsWithPassphrase: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_with_passphrase")
|
||||
}
|
||||
/// Use Recovery Key
|
||||
/// Use Security Key
|
||||
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsWithoutPassphrase: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_without_passphrase")
|
||||
}
|
||||
@@ -1142,7 +1142,7 @@ internal enum VectorL10n {
|
||||
internal static var e2eEnablingOnAppUpdate: String {
|
||||
return VectorL10n.tr("Vector", "e2e_enabling_on_app_update")
|
||||
}
|
||||
/// A new secure message key backup has been detected.\n\nIf this wasn’t you, set a new passphrase in Settings.
|
||||
/// A new secure message key backup has been detected.\n\nIf this wasn’t you, set a new Security Phrase in Settings.
|
||||
internal static var e2eKeyBackupWrongVersion: String {
|
||||
return VectorL10n.tr("Vector", "e2e_key_backup_wrong_version")
|
||||
}
|
||||
@@ -1614,15 +1614,15 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupRecoverDoneAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_done_action")
|
||||
}
|
||||
/// Use your recovery passphrase to unlock your secure message history
|
||||
/// Use your Security Phrase to unlock your secure message history
|
||||
internal static var keyBackupRecoverFromPassphraseInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_passphrase_info")
|
||||
}
|
||||
/// Don’t know your recovery passphrase? You can
|
||||
/// Don’t know your Security Phrase? You can
|
||||
internal static var keyBackupRecoverFromPassphraseLostPassphraseActionPart1: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_passphrase_lost_passphrase_action_part1")
|
||||
}
|
||||
/// use your recovery key
|
||||
/// use your Security Key
|
||||
internal static var keyBackupRecoverFromPassphraseLostPassphraseActionPart2: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_passphrase_lost_passphrase_action_part2")
|
||||
}
|
||||
@@ -1630,7 +1630,7 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupRecoverFromPassphraseLostPassphraseActionPart3: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_passphrase_lost_passphrase_action_part3")
|
||||
}
|
||||
/// Enter Passphrase
|
||||
/// Enter Phrase
|
||||
internal static var keyBackupRecoverFromPassphrasePassphrasePlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_passphrase_passphrase_placeholder")
|
||||
}
|
||||
@@ -1646,11 +1646,11 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupRecoverFromPrivateKeyInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_private_key_info")
|
||||
}
|
||||
/// Use your recovery key to unlock your secure message history
|
||||
/// Use your Security Key to unlock your secure message history
|
||||
internal static var keyBackupRecoverFromRecoveryKeyInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_info")
|
||||
}
|
||||
/// Lost your recovery key? You can set up a new one in settings.
|
||||
/// Lost your Security Key You can set up a new one in settings.
|
||||
internal static var keyBackupRecoverFromRecoveryKeyLostRecoveryKeyAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_lost_recovery_key_action")
|
||||
}
|
||||
@@ -1658,7 +1658,7 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupRecoverFromRecoveryKeyRecoverAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_recover_action")
|
||||
}
|
||||
/// Enter Recovery Key
|
||||
/// Enter Security Key
|
||||
internal static var keyBackupRecoverFromRecoveryKeyRecoveryKeyPlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_recovery_key_placeholder")
|
||||
}
|
||||
@@ -1666,19 +1666,19 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupRecoverFromRecoveryKeyRecoveryKeyTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_recovery_key_title")
|
||||
}
|
||||
/// Backup could not be decrypted with this passphrase: please verify that you entered the correct recovery passphrase.
|
||||
/// Backup could not be decrypted with this phrase: please verify that you entered the correct Security Phrase.
|
||||
internal static var keyBackupRecoverInvalidPassphrase: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_invalid_passphrase")
|
||||
}
|
||||
/// Incorrect Recovery Passphrase
|
||||
/// Incorrect Security Phrase
|
||||
internal static var keyBackupRecoverInvalidPassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_invalid_passphrase_title")
|
||||
}
|
||||
/// Backup could not be decrypted with this key: please verify that you entered the correct recovery key.
|
||||
/// Backup could not be decrypted with this key: please verify that you entered the correct Security Key.
|
||||
internal static var keyBackupRecoverInvalidRecoveryKey: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_invalid_recovery_key")
|
||||
}
|
||||
/// Recovery Key Mismatch
|
||||
/// Security Key Mismatch
|
||||
internal static var keyBackupRecoverInvalidRecoveryKeyTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_invalid_recovery_key_title")
|
||||
}
|
||||
@@ -1714,11 +1714,11 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupSetupIntroTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_intro_title")
|
||||
}
|
||||
/// Passphrase doesn’t match
|
||||
/// Phrase doesn’t match
|
||||
internal static var keyBackupSetupPassphraseConfirmPassphraseInvalid: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_confirm_passphrase_invalid")
|
||||
}
|
||||
/// Confirm passphrase
|
||||
/// Confirm phrase
|
||||
internal static var keyBackupSetupPassphraseConfirmPassphrasePlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_confirm_passphrase_placeholder")
|
||||
}
|
||||
@@ -1730,7 +1730,7 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupSetupPassphraseConfirmPassphraseValid: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_confirm_passphrase_valid")
|
||||
}
|
||||
/// We'll store an encrypted copy of your keys on our server. Protect your backup with a passphrase to keep it secure.\n\nFor maximum security, this should be different from your account password.
|
||||
/// We'll store an encrypted copy of your keys on our server. Protect your backup with a phrase to keep it secure.\n\nFor maximum security, this should be different from your account password.
|
||||
internal static var keyBackupSetupPassphraseInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_info")
|
||||
}
|
||||
@@ -1738,7 +1738,7 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupSetupPassphrasePassphraseInvalid: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_passphrase_invalid")
|
||||
}
|
||||
/// Enter passphrase
|
||||
/// Enter phrase
|
||||
internal static var keyBackupSetupPassphrasePassphrasePlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_passphrase_placeholder")
|
||||
}
|
||||
@@ -1750,19 +1750,19 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupSetupPassphrasePassphraseValid: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_passphrase_valid")
|
||||
}
|
||||
/// Set Passphrase
|
||||
/// Set Phrase
|
||||
internal static var keyBackupSetupPassphraseSetPassphraseAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_set_passphrase_action")
|
||||
}
|
||||
/// (Advanced) Set up with Recovery Key
|
||||
/// (Advanced) Set up with Security Key
|
||||
internal static var keyBackupSetupPassphraseSetupRecoveryKeyAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_setup_recovery_key_action")
|
||||
}
|
||||
/// Or, secure your backup with a Recovery Key, saving it somewhere safe.
|
||||
/// Or, secure your backup with a Security Key, saving it somewhere safe.
|
||||
internal static var keyBackupSetupPassphraseSetupRecoveryKeyInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_setup_recovery_key_info")
|
||||
}
|
||||
/// Secure your backup with a Passphrase
|
||||
/// Secure your backup with a Security Phrase
|
||||
internal static var keyBackupSetupPassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_passphrase_title")
|
||||
}
|
||||
@@ -1782,15 +1782,15 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupSetupSuccessFromPassphraseDoneAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_passphrase_done_action")
|
||||
}
|
||||
/// Your keys are being backed up.\n\nYour recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.\n\nKeep your recovery key somewhere very secure, like a password manager (or a safe).
|
||||
/// Your keys are being backed up.\n\nYour Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.\n\nKeep your Security Key somewhere very secure, like a password manager (or a safe).
|
||||
internal static var keyBackupSetupSuccessFromPassphraseInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_passphrase_info")
|
||||
}
|
||||
/// Save Recovery Key
|
||||
/// Save Security Key
|
||||
internal static var keyBackupSetupSuccessFromPassphraseSaveRecoveryKeyAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_passphrase_save_recovery_key_action")
|
||||
}
|
||||
/// Your keys are being backed up.\n\nMake a copy of this recovery key and keep it safe.
|
||||
/// Your keys are being backed up.\n\nMake a copy of this Security Key and keep it safe.
|
||||
internal static var keyBackupSetupSuccessFromRecoveryKeyInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_recovery_key_info")
|
||||
}
|
||||
@@ -1802,10 +1802,14 @@ internal enum VectorL10n {
|
||||
internal static var keyBackupSetupSuccessFromRecoveryKeyMakeCopyAction: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_recovery_key_make_copy_action")
|
||||
}
|
||||
/// Recovery Key
|
||||
/// Security Key
|
||||
internal static var keyBackupSetupSuccessFromRecoveryKeyRecoveryKeyTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_recovery_key_recovery_key_title")
|
||||
}
|
||||
/// Your keys are being backed up.
|
||||
internal static var keyBackupSetupSuccessFromSecureBackupInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_from_secure_backup_info")
|
||||
}
|
||||
/// Success!
|
||||
internal static var keyBackupSetupSuccessTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_setup_success_title")
|
||||
@@ -3554,15 +3558,23 @@ internal enum VectorL10n {
|
||||
internal static var secretsRecoveryResetActionPart2: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_reset_action_part_2")
|
||||
}
|
||||
/// Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.
|
||||
/// Access your secure message history and your cross-signing identity for verifying other sessions by entering your Security Key.
|
||||
internal static var secretsRecoveryWithKeyInformationDefault: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_information_default")
|
||||
}
|
||||
/// Use your Recovery Key to verify this device.
|
||||
/// Enter your Security Key to continue.
|
||||
internal static var secretsRecoveryWithKeyInformationUnlockSecureBackupWithKey: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_information_unlock_secure_backup_with_key")
|
||||
}
|
||||
/// Enter your Security Phrase to continue.
|
||||
internal static var secretsRecoveryWithKeyInformationUnlockSecureBackupWithPhrase: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_information_unlock_secure_backup_with_phrase")
|
||||
}
|
||||
/// Use your Security Key to verify this device.
|
||||
internal static var secretsRecoveryWithKeyInformationVerifyDevice: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_information_verify_device")
|
||||
}
|
||||
/// Please verify that you entered the correct recovery key.
|
||||
/// Please verify that you entered the correct Security Key.
|
||||
internal static var secretsRecoveryWithKeyInvalidRecoveryKeyMessage: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_invalid_recovery_key_message")
|
||||
}
|
||||
@@ -3574,7 +3586,7 @@ internal enum VectorL10n {
|
||||
internal static var secretsRecoveryWithKeyRecoverAction: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_recover_action")
|
||||
}
|
||||
/// Enter Recovery Key
|
||||
/// Enter Security Key
|
||||
internal static var secretsRecoveryWithKeyRecoveryKeyPlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_recovery_key_placeholder")
|
||||
}
|
||||
@@ -3582,19 +3594,19 @@ internal enum VectorL10n {
|
||||
internal static var secretsRecoveryWithKeyRecoveryKeyTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_recovery_key_title")
|
||||
}
|
||||
/// Recovery Key
|
||||
/// Security Key
|
||||
internal static var secretsRecoveryWithKeyTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_key_title")
|
||||
}
|
||||
/// Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.
|
||||
/// Access your secure message history and your cross-signing identity for verifying other sessions by entering your Security Phrase.
|
||||
internal static var secretsRecoveryWithPassphraseInformationDefault: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_information_default")
|
||||
}
|
||||
/// Use your Recovery Passphrase to verify this device.
|
||||
/// Use your Security Phrase to verify this device.
|
||||
internal static var secretsRecoveryWithPassphraseInformationVerifyDevice: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_information_verify_device")
|
||||
}
|
||||
/// Please verify that you entered the correct recovery passphrase.
|
||||
/// Please verify that you entered the correct Security Phrase.
|
||||
internal static var secretsRecoveryWithPassphraseInvalidPassphraseMessage: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_invalid_passphrase_message")
|
||||
}
|
||||
@@ -3602,11 +3614,11 @@ internal enum VectorL10n {
|
||||
internal static var secretsRecoveryWithPassphraseInvalidPassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_invalid_passphrase_title")
|
||||
}
|
||||
/// Don’t know your recovery passphrase? You can
|
||||
/// Don’t know your Security Phrase? You can
|
||||
internal static var secretsRecoveryWithPassphraseLostPassphraseActionPart1: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_lost_passphrase_action_part1")
|
||||
}
|
||||
/// use your recovery key
|
||||
/// use your Security Key
|
||||
internal static var secretsRecoveryWithPassphraseLostPassphraseActionPart2: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_lost_passphrase_action_part2")
|
||||
}
|
||||
@@ -3614,7 +3626,7 @@ internal enum VectorL10n {
|
||||
internal static var secretsRecoveryWithPassphraseLostPassphraseActionPart3: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_lost_passphrase_action_part3")
|
||||
}
|
||||
/// Enter Recovery Passphrase
|
||||
/// Enter Security Phrase
|
||||
internal static var secretsRecoveryWithPassphrasePassphrasePlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_passphrase_placeholder")
|
||||
}
|
||||
@@ -3622,11 +3634,11 @@ internal enum VectorL10n {
|
||||
internal static var secretsRecoveryWithPassphrasePassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_passphrase_title")
|
||||
}
|
||||
/// Use Passphrase
|
||||
/// Use Phrase
|
||||
internal static var secretsRecoveryWithPassphraseRecoverAction: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_recover_action")
|
||||
}
|
||||
/// Recovery Passphrase
|
||||
/// Security Phrase
|
||||
internal static var secretsRecoveryWithPassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "secrets_recovery_with_passphrase_title")
|
||||
}
|
||||
@@ -3662,7 +3674,7 @@ internal enum VectorL10n {
|
||||
internal static var secretsSetupRecoveryKeyExportAction: String {
|
||||
return VectorL10n.tr("Vector", "secrets_setup_recovery_key_export_action")
|
||||
}
|
||||
/// Store your Recovery Key somewhere safe. It can be used to unlock your encrypted messages & data.
|
||||
/// Store your Security Key somewhere safe. It can be used to unlock your encrypted messages & data.
|
||||
internal static var secretsSetupRecoveryKeyInformation: String {
|
||||
return VectorL10n.tr("Vector", "secrets_setup_recovery_key_information")
|
||||
}
|
||||
@@ -3690,7 +3702,7 @@ internal enum VectorL10n {
|
||||
internal static var secretsSetupRecoveryPassphraseConfirmInformation: String {
|
||||
return VectorL10n.tr("Vector", "secrets_setup_recovery_passphrase_confirm_information")
|
||||
}
|
||||
/// Confirm passphrase
|
||||
/// Confirm phrase
|
||||
internal static var secretsSetupRecoveryPassphraseConfirmPassphrasePlaceholder: String {
|
||||
return VectorL10n.tr("Vector", "secrets_setup_recovery_passphrase_confirm_passphrase_placeholder")
|
||||
}
|
||||
@@ -3770,7 +3782,7 @@ internal enum VectorL10n {
|
||||
internal static var secureKeyBackupSetupIntroUseSecurityPassphraseInfo: String {
|
||||
return VectorL10n.tr("Vector", "secure_key_backup_setup_intro_use_security_passphrase_info")
|
||||
}
|
||||
/// Use a Security Passphrase
|
||||
/// Use a Security Phrase
|
||||
internal static var secureKeyBackupSetupIntroUseSecurityPassphraseTitle: String {
|
||||
return VectorL10n.tr("Vector", "secure_key_backup_setup_intro_use_security_passphrase_title")
|
||||
}
|
||||
@@ -3806,7 +3818,7 @@ internal enum VectorL10n {
|
||||
internal static var securitySettingsCrosssigning: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crosssigning")
|
||||
}
|
||||
/// Bootstrap cross-signing
|
||||
/// Set up
|
||||
internal static var securitySettingsCrosssigningBootstrap: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crosssigning_bootstrap")
|
||||
}
|
||||
@@ -3822,7 +3834,7 @@ internal enum VectorL10n {
|
||||
internal static var securitySettingsCrosssigningInfoNotBootstrapped: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crosssigning_info_not_bootstrapped")
|
||||
}
|
||||
/// Cross-signing is enabled.
|
||||
/// Cross-signing is ready for use.
|
||||
internal static var securitySettingsCrosssigningInfoOk: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crosssigning_info_ok")
|
||||
}
|
||||
@@ -3830,7 +3842,7 @@ internal enum VectorL10n {
|
||||
internal static var securitySettingsCrosssigningInfoTrusted: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crosssigning_info_trusted")
|
||||
}
|
||||
/// Reset cross-signing
|
||||
/// Reset
|
||||
internal static var securitySettingsCrosssigningReset: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_crosssigning_reset")
|
||||
}
|
||||
@@ -3858,22 +3870,34 @@ internal enum VectorL10n {
|
||||
internal static var securitySettingsSecureBackup: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup")
|
||||
}
|
||||
/// Delete
|
||||
/// Delete Backup
|
||||
internal static var securitySettingsSecureBackupDelete: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_delete")
|
||||
}
|
||||
/// Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.
|
||||
/// Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.
|
||||
internal static var securitySettingsSecureBackupDescription: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_description")
|
||||
}
|
||||
/// Checking…
|
||||
internal static var securitySettingsSecureBackupInfoChecking: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_info_checking")
|
||||
}
|
||||
/// This session is backing up your keys.
|
||||
internal static var securitySettingsSecureBackupInfoValid: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_info_valid")
|
||||
}
|
||||
/// Reset
|
||||
internal static var securitySettingsSecureBackupReset: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_reset")
|
||||
}
|
||||
/// Restore from Backup
|
||||
internal static var securitySettingsSecureBackupRestore: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_restore")
|
||||
}
|
||||
/// Set up
|
||||
internal static var securitySettingsSecureBackupSetup: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_setup")
|
||||
}
|
||||
/// Synchronise
|
||||
internal static var securitySettingsSecureBackupSynchronise: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_secure_backup_synchronise")
|
||||
}
|
||||
/// Security
|
||||
internal static var securitySettingsTitle: String {
|
||||
return VectorL10n.tr("Vector", "security_settings_title")
|
||||
@@ -4250,7 +4274,7 @@ internal enum VectorL10n {
|
||||
internal static var settingsKeyBackupInfoProgressDone: String {
|
||||
return VectorL10n.tr("Vector", "settings_key_backup_info_progress_done")
|
||||
}
|
||||
/// Connect this session to key backup before signing out to avoid losing any keys that may only be on this device.
|
||||
/// Back up your keys before signing out to avoid losing them.
|
||||
internal static var settingsKeyBackupInfoSignoutWarning: String {
|
||||
return VectorL10n.tr("Vector", "settings_key_backup_info_signout_warning")
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
|
||||
- (void)presentSecureBackupSetup
|
||||
{
|
||||
SecureBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
|
||||
SecureBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession allowOverwrite:NO];
|
||||
keyBackupSetupCoordinatorBridgePresenter.delegate = self;
|
||||
|
||||
[keyBackupSetupCoordinatorBridgePresenter presentFrom:self animated:YES];
|
||||
|
||||
@@ -44,11 +44,11 @@ final class KeyBackupSetupCoordinator: KeyBackupSetupCoordinatorType {
|
||||
// MARK: - Public methods
|
||||
|
||||
func start() {
|
||||
|
||||
// Set key backup setup intro as root controller
|
||||
let keyBackupSetupIntroViewController = self.createSetupIntroViewController()
|
||||
keyBackupSetupIntroViewController.delegate = self
|
||||
self.navigationRouter.setRootModule(keyBackupSetupIntroViewController)
|
||||
if self.session.crypto.recoveryService.hasRecovery() {
|
||||
showUnlockSecureBackup()
|
||||
} else {
|
||||
showSetupIntro()
|
||||
}
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
@@ -57,6 +57,13 @@ final class KeyBackupSetupCoordinator: KeyBackupSetupCoordinatorType {
|
||||
|
||||
// MARK: - Private methods
|
||||
|
||||
private func showSetupIntro() {
|
||||
// Set key backup setup intro as root controller
|
||||
let keyBackupSetupIntroViewController = self.createSetupIntroViewController()
|
||||
keyBackupSetupIntroViewController.delegate = self
|
||||
self.navigationRouter.setRootModule(keyBackupSetupIntroViewController)
|
||||
}
|
||||
|
||||
private func createSetupIntroViewController() -> KeyBackupSetupIntroViewController {
|
||||
|
||||
let backupState = self.session.crypto.backup?.state ?? MXKeyBackupStateUnknown
|
||||
@@ -80,6 +87,17 @@ final class KeyBackupSetupCoordinator: KeyBackupSetupCoordinatorType {
|
||||
return KeyBackupSetupIntroViewController.instantiate(isABackupAlreadyExists: isABackupAlreadyExists, encryptionKeysExportPresenter: encryptionKeysExportPresenter)
|
||||
}
|
||||
|
||||
private func showUnlockSecureBackup() {
|
||||
let recoveryGoal: SecretsRecoveryGoal = .unlockSecureBackup { (privateKey, completion) in
|
||||
self.createKeyBackupUsingSecureBackup(privateKey: privateKey, completion: completion)
|
||||
}
|
||||
|
||||
let coordinator = SecretsRecoveryCoordinator(session: self.session, recoveryMode: .passphraseOrKey, recoveryGoal: recoveryGoal, navigationRouter: self.navigationRouter)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
self.add(childCoordinator: coordinator)
|
||||
}
|
||||
|
||||
private func showSetupPassphrase(animated: Bool) {
|
||||
let keyBackupSetupPassphraseCoordinator = KeyBackupSetupPassphraseCoordinator(session: self.session)
|
||||
keyBackupSetupPassphraseCoordinator.delegate = self
|
||||
@@ -104,6 +122,33 @@ final class KeyBackupSetupCoordinator: KeyBackupSetupCoordinatorType {
|
||||
viewController.delegate = self
|
||||
self.navigationRouter.push(viewController, animated: animated, popCompletion: nil)
|
||||
}
|
||||
|
||||
private func showSetupWithSecureBackupSuccess(animated: Bool) {
|
||||
let viewController = KeyBackupSetupSuccessFromSecureBackupViewController.instantiate()
|
||||
viewController.delegate = self
|
||||
self.navigationRouter.push(viewController, animated: animated, popCompletion: nil)
|
||||
}
|
||||
|
||||
private func createKeyBackupUsingSecureBackup(privateKey: Data, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let keyBackup = session.crypto.backup, let recoveryService = session.crypto.recoveryService else {
|
||||
return
|
||||
}
|
||||
|
||||
keyBackup.prepareKeyBackupVersion(withPassword: nil, success: { megolmBackupCreationInfo in
|
||||
keyBackup.createKeyBackupVersion(megolmBackupCreationInfo, success: { _ in
|
||||
recoveryService.updateRecovery(forSecrets: [MXSecretId.keyBackup.takeUnretainedValue() as String], withPrivateKey: privateKey) {
|
||||
completion(.success(Void()))
|
||||
} failure: { error in
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
||||
}, failure: { error in
|
||||
completion(.failure(error))
|
||||
})
|
||||
}, failure: { error in
|
||||
completion(.failure(error))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - KeyBackupSetupIntroViewControllerDelegate
|
||||
@@ -133,6 +178,17 @@ extension KeyBackupSetupCoordinator: KeyBackupSetupPassphraseCoordinatorDelegate
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SecretsRecoveryCoordinatorDelegate
|
||||
extension KeyBackupSetupCoordinator: SecretsRecoveryCoordinatorDelegate {
|
||||
func secretsRecoveryCoordinatorDidRecover(_ coordinator: SecretsRecoveryCoordinatorType) {
|
||||
self.showSetupWithSecureBackupSuccess(animated: true)
|
||||
}
|
||||
|
||||
func secretsRecoveryCoordinatorDidCancel(_ coordinator: SecretsRecoveryCoordinatorType) {
|
||||
self.delegate?.keyBackupSetupCoordinatorDidCancel(self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - KeyBackupSetupSuccessFromPassphraseViewControllerDelegate
|
||||
extension KeyBackupSetupCoordinator: KeyBackupSetupSuccessFromPassphraseViewControllerDelegate {
|
||||
func keyBackupSetupSuccessFromPassphraseViewControllerDidTapDoneAction(_ viewController: KeyBackupSetupSuccessFromPassphraseViewController) {
|
||||
@@ -146,3 +202,10 @@ extension KeyBackupSetupCoordinator: KeyBackupSetupSuccessFromRecoveryKeyViewCon
|
||||
self.delegate?.keyBackupSetupCoordinatorDidSetupRecoveryKey(self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - KeyBackupSetupSuccessFromSecureBackupViewControllerDelegate
|
||||
extension KeyBackupSetupCoordinator: KeyBackupSetupSuccessFromSecureBackupViewControllerDelegate {
|
||||
func keyBackupSetupSuccessFromSecureBackupViewControllerDidTapDoneAction(_ viewController: KeyBackupSetupSuccessFromSecureBackupViewController) {
|
||||
self.delegate?.keyBackupSetupCoordinatorDidSetupRecoveryKey(self)
|
||||
}
|
||||
}
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="b2C-jK-KPV">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Key Backup Setup Success From Secure Backup View Controller-->
|
||||
<scene sceneID="A4c-pi-pNE">
|
||||
<objects>
|
||||
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="b2C-jK-KPV" customClass="KeyBackupSetupSuccessFromSecureBackupViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="YAN-xg-EgW">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="S5g-F9-L3B">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a4X-9Q-mkr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="505"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="o2g-Ga-wwR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="505"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="key_backup_logo" translatesAutoresizingMaskIntoConstraints="NO" id="epg-Qy-eoD">
|
||||
<rect key="frame" x="163.5" y="40" width="48" height="46"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="48" id="V1N-K1-elw"/>
|
||||
<constraint firstAttribute="height" constant="46" id="Yzm-7B-uv2"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="xlp-uc-Mug">
|
||||
<rect key="frame" x="20" y="121" width="335" height="68.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Success!" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X7g-Ha-15I">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your keys are being backed up." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3eY-3I-XYH">
|
||||
<rect key="frame" x="0.0" y="50.5" width="335" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7aK-CF-d5d">
|
||||
<rect key="frame" x="0.0" y="435" width="375" height="50"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QxC-gf-8VN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="qB9-Kq-7Jw"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
|
||||
<state key="normal" title="Done">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<state key="disabled">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doneButtonAction:" destination="b2C-jK-KPV" eventType="touchUpInside" id="Vs7-qI-yBp"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="QxC-gf-8VN" secondAttribute="bottom" id="HQu-va-hRH"/>
|
||||
<constraint firstAttribute="trailing" secondItem="QxC-gf-8VN" secondAttribute="trailing" id="N4c-nq-GMC"/>
|
||||
<constraint firstItem="QxC-gf-8VN" firstAttribute="leading" secondItem="7aK-CF-d5d" secondAttribute="leading" id="Z8A-af-23Q"/>
|
||||
<constraint firstItem="QxC-gf-8VN" firstAttribute="top" secondItem="7aK-CF-d5d" secondAttribute="top" id="sed-9I-71h"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="7aK-CF-d5d" firstAttribute="leading" secondItem="o2g-Ga-wwR" secondAttribute="leading" id="1Hy-bc-46Y"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="500" id="4a2-Az-ekr"/>
|
||||
<constraint firstItem="epg-Qy-eoD" firstAttribute="centerX" secondItem="o2g-Ga-wwR" secondAttribute="centerX" id="K4J-2Y-7bW"/>
|
||||
<constraint firstItem="xlp-uc-Mug" firstAttribute="leading" secondItem="o2g-Ga-wwR" secondAttribute="leading" constant="20" id="drb-kN-IRX"/>
|
||||
<constraint firstItem="xlp-uc-Mug" firstAttribute="top" secondItem="epg-Qy-eoD" secondAttribute="bottom" constant="35" id="hyp-kS-l81"/>
|
||||
<constraint firstAttribute="bottom" secondItem="7aK-CF-d5d" secondAttribute="bottom" constant="20" id="nPL-nn-PpM"/>
|
||||
<constraint firstItem="epg-Qy-eoD" firstAttribute="top" secondItem="o2g-Ga-wwR" secondAttribute="top" constant="40" id="p1e-CF-Kln"/>
|
||||
<constraint firstAttribute="trailing" secondItem="7aK-CF-d5d" secondAttribute="trailing" id="wl8-ha-UIh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="xlp-uc-Mug" secondAttribute="trailing" constant="20" id="xIU-IL-ycK"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="o2g-Ga-wwR" firstAttribute="centerX" secondItem="a4X-9Q-mkr" secondAttribute="centerX" id="8Ps-hI-nHv"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="o2g-Ga-wwR" secondAttribute="trailing" id="GBk-AU-PAx"/>
|
||||
<constraint firstItem="o2g-Ga-wwR" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="a4X-9Q-mkr" secondAttribute="leading" id="Z9f-1y-sJV"/>
|
||||
<constraint firstAttribute="height" constant="505" id="dth-O0-khE"/>
|
||||
<constraint firstAttribute="bottom" secondItem="o2g-Ga-wwR" secondAttribute="bottom" id="kJP-Gd-vDF"/>
|
||||
<constraint firstItem="o2g-Ga-wwR" firstAttribute="top" secondItem="a4X-9Q-mkr" secondAttribute="top" id="zZX-fo-MMO"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="a4X-9Q-mkr" firstAttribute="top" secondItem="S5g-F9-L3B" secondAttribute="top" id="47v-Wy-vaA"/>
|
||||
<constraint firstItem="a4X-9Q-mkr" firstAttribute="width" secondItem="S5g-F9-L3B" secondAttribute="width" id="REA-MB-gew"/>
|
||||
<constraint firstAttribute="bottom" secondItem="a4X-9Q-mkr" secondAttribute="bottom" id="Sqk-TW-ccx"/>
|
||||
<constraint firstAttribute="trailing" secondItem="a4X-9Q-mkr" secondAttribute="trailing" id="keL-QJ-bja"/>
|
||||
<constraint firstItem="a4X-9Q-mkr" firstAttribute="leading" secondItem="S5g-F9-L3B" secondAttribute="leading" id="maD-UF-Wim"/>
|
||||
</constraints>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="hUM-zt-PJj"/>
|
||||
<color key="backgroundColor" red="0.94509803920000002" green="0.96078431369999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="hUM-zt-PJj" firstAttribute="trailing" secondItem="S5g-F9-L3B" secondAttribute="trailing" id="EAb-7P-Zsd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="S5g-F9-L3B" secondAttribute="bottom" id="Ham-fU-JWM"/>
|
||||
<constraint firstItem="hUM-zt-PJj" firstAttribute="top" secondItem="S5g-F9-L3B" secondAttribute="top" id="Zkl-TJ-HEv"/>
|
||||
<constraint firstItem="S5g-F9-L3B" firstAttribute="leading" secondItem="hUM-zt-PJj" secondAttribute="leading" id="sme-S5-pY5"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="doneButton" destination="QxC-gf-8VN" id="eOc-Ec-FgG"/>
|
||||
<outlet property="doneButtonBackgroundView" destination="7aK-CF-d5d" id="y7U-Ol-8Nk"/>
|
||||
<outlet property="informationLabel" destination="3eY-3I-XYH" id="ZT2-Lo-JlX"/>
|
||||
<outlet property="keyBackupLogoImageView" destination="epg-Qy-eoD" id="YOa-Pv-XrT"/>
|
||||
<outlet property="titleLabel" destination="X7g-Ha-15I" id="yMg-6G-6lF"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Yhm-Kv-QZF" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-3178" y="-675"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="key_backup_logo" width="48" height="46"/>
|
||||
</resources>
|
||||
</document>
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol KeyBackupSetupSuccessFromSecureBackupViewControllerDelegate: class {
|
||||
func keyBackupSetupSuccessFromSecureBackupViewControllerDidTapDoneAction(_ viewController: KeyBackupSetupSuccessFromSecureBackupViewController)
|
||||
}
|
||||
|
||||
final class KeyBackupSetupSuccessFromSecureBackupViewController: UIViewController {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
@IBOutlet private weak var keyBackupLogoImageView: UIImageView!
|
||||
@IBOutlet private weak var titleLabel: UILabel!
|
||||
@IBOutlet private weak var informationLabel: UILabel!
|
||||
|
||||
@IBOutlet private weak var doneButtonBackgroundView: UIView!
|
||||
@IBOutlet private weak var doneButton: UIButton!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var theme: Theme!
|
||||
|
||||
// MARK: Public
|
||||
|
||||
weak var delegate: KeyBackupSetupSuccessFromSecureBackupViewControllerDelegate?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
class func instantiate() -> KeyBackupSetupSuccessFromSecureBackupViewController {
|
||||
let viewController = StoryboardScene.KeyBackupSetupSuccessFromSecureBackupViewController.initialScene.instantiate()
|
||||
viewController.theme = ThemeService.shared().theme
|
||||
return viewController
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
self.title = VectorL10n.keyBackupSetupTitle
|
||||
|
||||
self.setupViews()
|
||||
self.registerThemeServiceDidChangeThemeNotification()
|
||||
self.update(theme: self.theme)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
// Hide back button
|
||||
self.navigationItem.setHidesBackButton(true, animated: animated)
|
||||
}
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return self.theme.statusBarStyle
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setupViews() {
|
||||
|
||||
let keybackupLogoImage = Asset.Images.keyBackupLogo.image.withRenderingMode(.alwaysTemplate)
|
||||
self.keyBackupLogoImageView.image = keybackupLogoImage
|
||||
|
||||
self.titleLabel.text = VectorL10n.keyBackupSetupSuccessTitle
|
||||
self.informationLabel.text = VectorL10n.keyBackupSetupSuccessFromSecureBackupInfo
|
||||
|
||||
self.doneButton.setTitle(VectorL10n.keyBackupSetupSuccessFromPassphraseDoneAction, for: .normal)
|
||||
}
|
||||
|
||||
private func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
|
||||
self.view.backgroundColor = theme.headerBackgroundColor
|
||||
|
||||
if let navigationBar = self.navigationController?.navigationBar {
|
||||
theme.applyStyle(onNavigationBar: navigationBar)
|
||||
}
|
||||
|
||||
self.keyBackupLogoImageView.tintColor = theme.textPrimaryColor
|
||||
self.titleLabel.textColor = theme.textPrimaryColor
|
||||
self.informationLabel.textColor = theme.textPrimaryColor
|
||||
|
||||
self.doneButtonBackgroundView.backgroundColor = theme.backgroundColor
|
||||
theme.applyStyle(onButton: self.doneButton)
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
|
||||
}
|
||||
|
||||
@objc private func themeDidChange() {
|
||||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@IBAction private func doneButtonAction(_ sender: Any) {
|
||||
self.delegate?.keyBackupSetupSuccessFromSecureBackupViewControllerDidTapDoneAction(self)
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,8 @@ final class SecretsRecoveryWithKeyViewController: UIViewController {
|
||||
switch self.viewModel.recoveryGoal {
|
||||
case .default, .keyBackup, .restoreSecureBackup:
|
||||
informationText = VectorL10n.secretsRecoveryWithKeyInformationDefault
|
||||
case .unlockSecureBackup(_):
|
||||
informationText = VectorL10n.secretsRecoveryWithKeyInformationUnlockSecureBackupWithKey
|
||||
case .verifyDevice:
|
||||
informationText = VectorL10n.secretsRecoveryWithKeyInformationVerifyDevice
|
||||
}
|
||||
|
||||
+2
@@ -106,6 +106,8 @@ final class SecretsRecoveryWithPassphraseViewController: UIViewController {
|
||||
switch self.viewModel.recoveryGoal {
|
||||
case .default, .keyBackup, .restoreSecureBackup:
|
||||
informationText = VectorL10n.secretsRecoveryWithPassphraseInformationDefault
|
||||
case .unlockSecureBackup(_):
|
||||
informationText = VectorL10n.secretsRecoveryWithKeyInformationUnlockSecureBackupWithPhrase
|
||||
case .verifyDevice:
|
||||
informationText = VectorL10n.secretsRecoveryWithPassphraseInformationVerifyDevice
|
||||
}
|
||||
|
||||
+53
-19
@@ -73,27 +73,13 @@ final class SecretsRecoveryWithPassphraseViewModel: SecretsRecoveryWithPassphras
|
||||
return
|
||||
}
|
||||
|
||||
let secretIds: [String]?
|
||||
|
||||
if case SecretsRecoveryGoal.keyBackup = self.recoveryGoal {
|
||||
secretIds = [MXSecretId.keyBackup.takeUnretainedValue() as String]
|
||||
} else {
|
||||
secretIds = nil
|
||||
switch self.recoveryGoal {
|
||||
case .unlockSecureBackup(let block):
|
||||
self.execute(block: block, privateKey: privateKey)
|
||||
default:
|
||||
self.recoverSecrets(privateKey: privateKey)
|
||||
}
|
||||
|
||||
self.recoveryService.recoverSecrets(secretIds, withPrivateKey: privateKey, recoverServices: true, success: { [weak self] _ in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
self.update(viewState: .loaded)
|
||||
self.coordinatorDelegate?.secretsRecoveryWithPassphraseViewModelDidRecover(self)
|
||||
}, failure: { [weak self] error in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
self.update(viewState: .error(error))
|
||||
})
|
||||
|
||||
}, failure: { [weak self] error in
|
||||
guard let self = self else {
|
||||
return
|
||||
@@ -102,6 +88,54 @@ final class SecretsRecoveryWithPassphraseViewModel: SecretsRecoveryWithPassphras
|
||||
})
|
||||
}
|
||||
|
||||
private func recoverSecrets(privateKey: Data) {
|
||||
let secretIds: [String]?
|
||||
|
||||
if case SecretsRecoveryGoal.keyBackup = self.recoveryGoal {
|
||||
secretIds = [MXSecretId.keyBackup.takeUnretainedValue() as String]
|
||||
} else {
|
||||
secretIds = nil
|
||||
}
|
||||
|
||||
self.recoveryService.recoverSecrets(secretIds, withPrivateKey: privateKey, recoverServices: true, success: { [weak self] _ in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
self.update(viewState: .loaded)
|
||||
self.coordinatorDelegate?.secretsRecoveryWithPassphraseViewModelDidRecover(self)
|
||||
}, failure: { [weak self] error in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
self.update(viewState: .error(error))
|
||||
})
|
||||
}
|
||||
|
||||
private func execute(block: @escaping (_ privateKey: Data, _ completion: @escaping (Result<Void, Error>) -> Void) -> Void, privateKey: Data) {
|
||||
// Check the private key is valid before using it
|
||||
self.recoveryService.checkPrivateKey(privateKey) { match in
|
||||
guard match else {
|
||||
// Reuse already managed error
|
||||
let error = NSError(domain: MXRecoveryServiceErrorDomain, code: Int(MXRecoveryServiceErrorCode.badRecoveryKeyErrorCode.rawValue), userInfo: nil)
|
||||
self.update(viewState: .error(error))
|
||||
return
|
||||
}
|
||||
|
||||
// Run the extenal code while the view state is .loading
|
||||
block(privateKey) { result in
|
||||
MXLog.debug("[SecretsRecoveryWithPassphraseViewModel] execute: Block returned: \(result)")
|
||||
|
||||
switch result {
|
||||
case .success:
|
||||
self.update(viewState: .loaded)
|
||||
self.coordinatorDelegate?.secretsRecoveryWithPassphraseViewModelDidRecover(self)
|
||||
case .failure(let error):
|
||||
self.update(viewState: .error(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func update(viewState: SecretsRecoveryWithPassphraseViewState) {
|
||||
self.viewDelegate?.secretsRecoveryWithPassphraseViewModel(self, didUpdateViewState: viewState)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ final class SecretsRecoveryCoordinatorBridgePresenter: NSObject {
|
||||
|
||||
private let session: MXSession
|
||||
private let recoveryMode: SecretsRecoveryMode
|
||||
let recoveryGoal: SecretsRecoveryGoal
|
||||
let recoveryGoal: SecretsRecoveryGoalBridge
|
||||
|
||||
private var coordinator: SecretsRecoveryCoordinator?
|
||||
|
||||
@@ -46,14 +46,14 @@ final class SecretsRecoveryCoordinatorBridgePresenter: NSObject {
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession, recoveryMode: SecretsRecoveryMode, recoveryGoal: SecretsRecoveryGoal) {
|
||||
init(session: MXSession, recoveryMode: SecretsRecoveryMode, recoveryGoal: SecretsRecoveryGoalBridge) {
|
||||
self.session = session
|
||||
self.recoveryMode = recoveryMode
|
||||
self.recoveryGoal = recoveryGoal
|
||||
super.init()
|
||||
}
|
||||
|
||||
init(session: MXSession, recoveryGoal: SecretsRecoveryGoal) {
|
||||
init(session: MXSession, recoveryGoal: SecretsRecoveryGoalBridge) {
|
||||
self.session = session
|
||||
|
||||
if case SecretsRecoveryAvailability.available(let secretMode) = session.crypto.recoveryService.vc_availability {
|
||||
@@ -74,7 +74,7 @@ final class SecretsRecoveryCoordinatorBridgePresenter: NSObject {
|
||||
|
||||
func present(from viewController: UIViewController, animated: Bool) {
|
||||
|
||||
let coordinator = SecretsRecoveryCoordinator(session: self.session, recoveryMode: self.recoveryMode, recoveryGoal: self.recoveryGoal)
|
||||
let coordinator = SecretsRecoveryCoordinator(session: self.session, recoveryMode: self.recoveryMode, recoveryGoal: self.recoveryGoal.goal)
|
||||
coordinator.delegate = self
|
||||
|
||||
let presentable = coordinator.toPresentable()
|
||||
|
||||
@@ -16,10 +16,28 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SecretsRecoveryGoal {
|
||||
case `default`
|
||||
case keyBackup
|
||||
/// Unlock the secure backup (4S) to get the private key and execute a closure during the flow
|
||||
case unlockSecureBackup ((_ privateKey: Data, _ completion: @escaping (Result<Void, Error>) -> Void) -> Void)
|
||||
case verifyDevice
|
||||
case restoreSecureBackup
|
||||
}
|
||||
|
||||
@objc
|
||||
enum SecretsRecoveryGoal: Int {
|
||||
enum SecretsRecoveryGoalBridge: Int {
|
||||
case `default`
|
||||
case keyBackup
|
||||
case verifyDevice
|
||||
case restoreSecureBackup
|
||||
|
||||
var goal: SecretsRecoveryGoal {
|
||||
switch self {
|
||||
case .default: return .default
|
||||
case .keyBackup: return .keyBackup
|
||||
case .verifyDevice: return .verifyDevice
|
||||
case .restoreSecureBackup: return .restoreSecureBackup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,9 @@ final class SecretsSetupRecoveryKeyCoordinator: SecretsSetupRecoveryKeyCoordinat
|
||||
|
||||
init(recoveryService: MXRecoveryService,
|
||||
passphrase: String?,
|
||||
passphraseOnly: Bool) {
|
||||
let secretsSetupRecoveryKeyViewModel = SecretsSetupRecoveryKeyViewModel(recoveryService: recoveryService, passphrase: passphrase, passphraseOnly: passphraseOnly)
|
||||
passphraseOnly: Bool,
|
||||
allowOverwrite: Bool = false) {
|
||||
let secretsSetupRecoveryKeyViewModel = SecretsSetupRecoveryKeyViewModel(recoveryService: recoveryService, passphrase: passphrase, passphraseOnly: passphraseOnly, allowOverwrite: allowOverwrite)
|
||||
let secretsSetupRecoveryKeyViewController = SecretsSetupRecoveryKeyViewController.instantiate(with: secretsSetupRecoveryKeyViewModel)
|
||||
self.secretsSetupRecoveryKeyViewModel = secretsSetupRecoveryKeyViewModel
|
||||
self.secretsSetupRecoveryKeyViewController = secretsSetupRecoveryKeyViewController
|
||||
|
||||
@@ -27,6 +27,7 @@ final class SecretsSetupRecoveryKeyViewModel: SecretsSetupRecoveryKeyViewModelTy
|
||||
private let recoveryService: MXRecoveryService
|
||||
private let passphrase: String?
|
||||
private let passphraseOnly: Bool
|
||||
private let allowOverwrite: Bool
|
||||
|
||||
// MARK: Public
|
||||
|
||||
@@ -35,10 +36,11 @@ final class SecretsSetupRecoveryKeyViewModel: SecretsSetupRecoveryKeyViewModelTy
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(recoveryService: MXRecoveryService, passphrase: String?, passphraseOnly: Bool) {
|
||||
init(recoveryService: MXRecoveryService, passphrase: String?, passphraseOnly: Bool, allowOverwrite: Bool = false) {
|
||||
self.recoveryService = recoveryService
|
||||
self.passphrase = passphrase
|
||||
self.passphraseOnly = passphraseOnly
|
||||
self.allowOverwrite = allowOverwrite
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -61,6 +63,16 @@ final class SecretsSetupRecoveryKeyViewModel: SecretsSetupRecoveryKeyViewModelTy
|
||||
|
||||
private func createSecureKey() {
|
||||
self.update(viewState: .loading)
|
||||
|
||||
if allowOverwrite && self.recoveryService.hasRecovery() {
|
||||
MXLog.debug("[SecretsSetupRecoveryKeyViewModel] createSecureKey: Overwrite existing secure backup")
|
||||
self.recoveryService.deleteRecovery(withDeleteServicesBackups: true) {
|
||||
self.createSecureKey()
|
||||
} failure: { error in
|
||||
self.update(viewState: .error(error))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
self.recoveryService.createRecovery(forSecrets: nil, withPassphrase: self.passphrase, createServicesBackups: true, success: { secretStorageKeyCreationInfo in
|
||||
self.update(viewState: .recoveryCreated(secretStorageKeyCreationInfo.recoveryKey))
|
||||
|
||||
@@ -30,6 +30,7 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
|
||||
private let recoveryService: MXRecoveryService
|
||||
private let keyBackup: MXKeyBackup?
|
||||
private let checkKeyBackup: Bool
|
||||
private let allowOverwrite: Bool
|
||||
|
||||
// MARK: Public
|
||||
|
||||
@@ -45,11 +46,12 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
|
||||
/// - session: The MXSession.
|
||||
/// - checkKeyBackup: Indicate false to ignore existing key backup.
|
||||
/// - navigationRouter: Use existing navigation router to plug this flow or let nil to use new one.
|
||||
init(session: MXSession, checkKeyBackup: Bool = true, navigationRouter: NavigationRouterType? = nil) {
|
||||
init(session: MXSession, checkKeyBackup: Bool = true, allowOverwrite: Bool = false, navigationRouter: NavigationRouterType? = nil) {
|
||||
self.session = session
|
||||
self.recoveryService = session.crypto.recoveryService
|
||||
self.keyBackup = session.crypto.backup
|
||||
self.checkKeyBackup = checkKeyBackup
|
||||
self.allowOverwrite = allowOverwrite
|
||||
|
||||
if let navigationRouter = navigationRouter {
|
||||
self.navigationRouter = navigationRouter
|
||||
@@ -85,7 +87,7 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
|
||||
}
|
||||
|
||||
private func showSetupKey(passphraseOnly: Bool, passphrase: String? = nil) {
|
||||
let coordinator = SecretsSetupRecoveryKeyCoordinator(recoveryService: self.recoveryService, passphrase: passphrase, passphraseOnly: passphraseOnly)
|
||||
let coordinator = SecretsSetupRecoveryKeyCoordinator(recoveryService: self.recoveryService, passphrase: passphrase, passphraseOnly: passphraseOnly, allowOverwrite: allowOverwrite)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ final class SecureBackupSetupCoordinatorBridgePresenter: NSObject {
|
||||
// MARK: Private
|
||||
|
||||
private let session: MXSession
|
||||
private let allowOverwrite: Bool
|
||||
private var coordinator: SecureBackupSetupCoordinator?
|
||||
|
||||
// MARK: Public
|
||||
@@ -40,9 +41,10 @@ final class SecureBackupSetupCoordinatorBridgePresenter: NSObject {
|
||||
weak var delegate: SecureBackupSetupCoordinatorBridgePresenterDelegate?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession) {
|
||||
|
||||
init(session: MXSession, allowOverwrite: Bool) {
|
||||
self.session = session
|
||||
self.allowOverwrite = allowOverwrite
|
||||
super.init()
|
||||
}
|
||||
|
||||
@@ -54,7 +56,7 @@ final class SecureBackupSetupCoordinatorBridgePresenter: NSObject {
|
||||
// }
|
||||
|
||||
func present(from viewController: UIViewController, animated: Bool) {
|
||||
let secureBackupSetupCoordinator = SecureBackupSetupCoordinator(session: self.session)
|
||||
let secureBackupSetupCoordinator = SecureBackupSetupCoordinator(session: self.session, allowOverwrite: self.allowOverwrite)
|
||||
secureBackupSetupCoordinator.delegate = self
|
||||
viewController.present(secureBackupSetupCoordinator.toPresentable(), animated: animated, completion: nil)
|
||||
secureBackupSetupCoordinator.start()
|
||||
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
@objc protocol SettingsSecureBackupTableViewSectionDelegate: class {
|
||||
// Table view rendering
|
||||
func settingsSecureBackupTableViewSectionDidUpdate(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection)
|
||||
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, textCellForRow: Int) -> MXKTableViewCellWithTextView
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, descriptionCellForRow: Int) -> MXKTableViewCell
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, buttonCellForRow: Int) -> MXKTableViewCellWithButton
|
||||
|
||||
// Secure backup
|
||||
func settingsSecureBackupTableViewSectionShowSecureBackupReset(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection)
|
||||
|
||||
// Key backup
|
||||
func settingsSecureBackupTableViewSectionShowKeyBackupCreate(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection)
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, showKeyBackupRecover keyBackupVersion: MXKeyBackupVersion)
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, showKeyBackupDeleteConfirm keyBackupVersion: MXKeyBackupVersion)
|
||||
|
||||
// Life cycle
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, showActivityIndicator show: Bool)
|
||||
func settingsSecureBackupTableViewSection(_ settingsSecureBackupTableViewSection: SettingsSecureBackupTableViewSection, showError error: Error)
|
||||
}
|
||||
|
||||
private enum BackupRows {
|
||||
case info(text: String)
|
||||
case description(text: String)
|
||||
case createSecureBackupAction
|
||||
case resetSecureBackupAction
|
||||
case createKeyBackupAction
|
||||
case restoreFromKeyBackupAction(keyBackupVersion: MXKeyBackupVersion, title: String)
|
||||
case deleteKeyBackupAction(keyBackupVersion: MXKeyBackupVersion)
|
||||
}
|
||||
|
||||
/// SettingsSecureBackupTableViewSection provides UITableViewCells to manage secure backup and key backup.
|
||||
///
|
||||
/// All states are described in SettingsSecureBackupViewState.
|
||||
/// All actions in SettingsSecureBackupViewAction.
|
||||
@objc final class SettingsSecureBackupTableViewSection: NSObject {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@objc weak var delegate: SettingsSecureBackupTableViewSectionDelegate?
|
||||
|
||||
// MARK: Private
|
||||
|
||||
// This view class holds the model because the model is in pure Swift
|
||||
// whereas this class can be used from objC
|
||||
private var viewModel: SettingsSecureBackupViewModelType!
|
||||
|
||||
// Need to know the state to make `cellForRow` deliver cells accordingly
|
||||
private var viewState: SettingsSecureBackupViewState = .loading {
|
||||
didSet {
|
||||
self.updateBackupRows()
|
||||
}
|
||||
}
|
||||
|
||||
private var userDevice: MXDeviceInfo
|
||||
|
||||
private var backupRows: [BackupRows] = []
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
@objc init(withRecoveryService recoveryService: MXRecoveryService, keyBackup: MXKeyBackup, userDevice: MXDeviceInfo) {
|
||||
self.viewModel = SettingsSecureBackupViewModel(recoveryService: recoveryService, keyBackup: keyBackup)
|
||||
self.userDevice = userDevice
|
||||
super.init()
|
||||
self.viewModel.viewDelegate = self
|
||||
|
||||
self.viewModel.process(viewAction: .load)
|
||||
}
|
||||
|
||||
@objc func numberOfRows() -> Int {
|
||||
return self.backupRows.count
|
||||
}
|
||||
|
||||
@objc func cellForRow(atRow row: Int) -> UITableViewCell {
|
||||
let backupRow = self.backupRows[row]
|
||||
|
||||
var cell: UITableViewCell
|
||||
switch backupRow {
|
||||
case .info(let text):
|
||||
cell = self.textCell(atRow: row, text: text)
|
||||
case .description(let text):
|
||||
cell = self.descriptionCell(atRow: row, text: text)
|
||||
case .createSecureBackupAction:
|
||||
cell = self.buttonCellForCreateSecureBackup(atRow: row)
|
||||
case .resetSecureBackupAction:
|
||||
cell = self.buttonCellForResetSecureBackup(atRow: row)
|
||||
case .createKeyBackupAction:
|
||||
cell = self.buttonCellForCreateKeyBackup(atRow: row)
|
||||
case .restoreFromKeyBackupAction(keyBackupVersion: let keyBackupVersion, let title):
|
||||
cell = self.buttonCellForRestoreFromKeyBackup(keyBackupVersion: keyBackupVersion, title: title, atRow: row)
|
||||
case .deleteKeyBackupAction(keyBackupVersion: let keyBackupVersion):
|
||||
cell = self.buttonCellForDeleteKeyBackup(keyBackupVersion: keyBackupVersion, atRow: row)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
@objc func reload() {
|
||||
self.viewModel.process(viewAction: .load)
|
||||
}
|
||||
|
||||
@objc func deleteKeyBackup(keyBackupVersion: MXKeyBackupVersion) {
|
||||
self.viewModel.process(viewAction: .deleteKeyBackup(keyBackupVersion))
|
||||
}
|
||||
|
||||
// MARK: - Data Computing
|
||||
|
||||
private func updateBackupRows() {
|
||||
|
||||
let backupRows: [BackupRows]
|
||||
|
||||
switch self.viewState {
|
||||
case .loading:
|
||||
backupRows = [
|
||||
.info(text: VectorL10n.securitySettingsSecureBackupInfoChecking),
|
||||
.description(text: VectorL10n.securitySettingsSecureBackupDescription)
|
||||
]
|
||||
|
||||
case .noSecureBackup(let keyBackupState):
|
||||
switch keyBackupState {
|
||||
case .noKeyBackup:
|
||||
let noBackup = VectorL10n.settingsKeyBackupInfoNone
|
||||
let signoutWarning = VectorL10n.settingsKeyBackupInfoSignoutWarning
|
||||
let infoText = [noBackup, signoutWarning].joined(separator: "\n")
|
||||
|
||||
backupRows = [
|
||||
.info(text: infoText),
|
||||
.createSecureBackupAction,
|
||||
.description(text: VectorL10n.securitySettingsSecureBackupDescription)
|
||||
]
|
||||
case .keyBackup(let keyBackupVersion, _, _),
|
||||
.keyBackupNotTrusted(let keyBackupVersion, _): // Manage the key backup in the same way for the moment
|
||||
backupRows = [
|
||||
.info(text: VectorL10n.securitySettingsSecureBackupInfoValid),
|
||||
.restoreFromKeyBackupAction(keyBackupVersion: keyBackupVersion, title: VectorL10n.securitySettingsSecureBackupRestore),
|
||||
.deleteKeyBackupAction(keyBackupVersion: keyBackupVersion),
|
||||
.description(text: VectorL10n.securitySettingsSecureBackupDescription)
|
||||
]
|
||||
}
|
||||
case .secureBackup(let keyBackupState):
|
||||
switch keyBackupState {
|
||||
case .noKeyBackup:
|
||||
let noBackup = VectorL10n.settingsKeyBackupInfoNone
|
||||
let signoutWarning = VectorL10n.settingsKeyBackupInfoSignoutWarning
|
||||
let infoText = [noBackup, signoutWarning].joined(separator: "\n")
|
||||
|
||||
backupRows = [
|
||||
.info(text: infoText),
|
||||
.createKeyBackupAction,
|
||||
.resetSecureBackupAction,
|
||||
.description(text: VectorL10n.securitySettingsSecureBackupDescription)
|
||||
]
|
||||
case .keyBackup(let keyBackupVersion, _, _),
|
||||
.keyBackupNotTrusted(let keyBackupVersion, _): // Manage the key backup in the same way for the moment
|
||||
backupRows = [
|
||||
.info(text: VectorL10n.securitySettingsSecureBackupInfoValid),
|
||||
.restoreFromKeyBackupAction(keyBackupVersion: keyBackupVersion, title: VectorL10n.securitySettingsSecureBackupRestore),
|
||||
.deleteKeyBackupAction(keyBackupVersion: keyBackupVersion),
|
||||
.resetSecureBackupAction,
|
||||
.description(text: VectorL10n.securitySettingsSecureBackupDescription)
|
||||
]
|
||||
}
|
||||
}
|
||||
self.backupRows = backupRows
|
||||
}
|
||||
|
||||
// MARK: - Cells -
|
||||
|
||||
private func textCell(atRow row: Int, text: String) -> UITableViewCell {
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell = delegate.settingsSecureBackupTableViewSection(self, textCellForRow: row)
|
||||
cell.mxkTextView.text = text
|
||||
return cell
|
||||
}
|
||||
|
||||
private func descriptionCell(atRow row: Int, text: String) -> UITableViewCell {
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell = delegate.settingsSecureBackupTableViewSection(self, descriptionCellForRow: row)
|
||||
cell.textLabel?.text = text
|
||||
return cell
|
||||
}
|
||||
|
||||
// MARK: - Button cells
|
||||
|
||||
private func buttonCellForCreateSecureBackup(atRow row: Int) -> UITableViewCell {
|
||||
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell: MXKTableViewCellWithButton = delegate.settingsSecureBackupTableViewSection(self, buttonCellForRow: row)
|
||||
|
||||
let btnTitle = VectorL10n.securitySettingsSecureBackupSetup
|
||||
cell.mxkButton.setTitle(btnTitle, for: .normal)
|
||||
cell.mxkButton.setTitle(btnTitle, for: .highlighted)
|
||||
|
||||
cell.mxkButton.vc_addAction {
|
||||
self.viewModel.process(viewAction: .createSecureBackup)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
private func buttonCellForResetSecureBackup(atRow row: Int) -> UITableViewCell {
|
||||
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell: MXKTableViewCellWithButton = delegate.settingsSecureBackupTableViewSection(self, buttonCellForRow: row)
|
||||
|
||||
let btnTitle = VectorL10n.securitySettingsSecureBackupReset
|
||||
cell.mxkButton.setTitle(btnTitle, for: .normal)
|
||||
cell.mxkButton.setTitle(btnTitle, for: .highlighted)
|
||||
cell.mxkButton.tintColor = ThemeService.shared().theme.warningColor
|
||||
|
||||
cell.mxkButton.vc_addAction {
|
||||
self.viewModel.process(viewAction: .resetSecureBackup)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
private func buttonCellForCreateKeyBackup(atRow row: Int) -> UITableViewCell {
|
||||
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell: MXKTableViewCellWithButton = delegate.settingsSecureBackupTableViewSection(self, buttonCellForRow: row)
|
||||
|
||||
let btnTitle = VectorL10n.securitySettingsSecureBackupSetup
|
||||
cell.mxkButton.setTitle(btnTitle, for: .normal)
|
||||
cell.mxkButton.setTitle(btnTitle, for: .highlighted)
|
||||
|
||||
cell.mxkButton.vc_addAction {
|
||||
self.viewModel.process(viewAction: .createKeyBackup)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
private func buttonCellForRestoreFromKeyBackup(keyBackupVersion: MXKeyBackupVersion, title: String, atRow row: Int) -> UITableViewCell {
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell: MXKTableViewCellWithButton = delegate.settingsSecureBackupTableViewSection(self, buttonCellForRow: row)
|
||||
cell.mxkButton.setTitle(title, for: .normal)
|
||||
cell.mxkButton.setTitle(title, for: .highlighted)
|
||||
cell.mxkButton.vc_addAction {
|
||||
self.viewModel.process(viewAction: .restoreFromKeyBackup(keyBackupVersion))
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
private func buttonCellForDeleteKeyBackup(keyBackupVersion: MXKeyBackupVersion, atRow row: Int) -> UITableViewCell {
|
||||
guard let delegate = self.delegate else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let cell: MXKTableViewCellWithButton = delegate.settingsSecureBackupTableViewSection(self, buttonCellForRow: row)
|
||||
let btnTitle = VectorL10n.securitySettingsSecureBackupDelete
|
||||
cell.mxkButton.setTitle(btnTitle, for: .normal)
|
||||
cell.mxkButton.setTitle(btnTitle, for: .highlighted)
|
||||
cell.mxkButton.tintColor = ThemeService.shared().theme.warningColor
|
||||
cell.mxkButton.vc_addAction {
|
||||
self.viewModel.process(viewAction: .confirmDeleteKeyBackup(keyBackupVersion))
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyBackupSetupRecoveryKeyViewModelViewDelegate
|
||||
extension SettingsSecureBackupTableViewSection: SettingsSecureBackupViewModelViewDelegate {
|
||||
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, didUpdateViewState viewState: SettingsSecureBackupViewState) {
|
||||
self.viewState = viewState
|
||||
|
||||
// The tableview datasource will call `self.cellForRow()`
|
||||
self.delegate?.settingsSecureBackupTableViewSectionDidUpdate(self)
|
||||
}
|
||||
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, didUpdateNetworkRequestViewState networkRequestViewSate: SettingsSecureBackupNetworkRequestViewState) {
|
||||
switch networkRequestViewSate {
|
||||
case .loading:
|
||||
self.delegate?.settingsSecureBackupTableViewSection(self, showActivityIndicator: true)
|
||||
case .loaded:
|
||||
self.delegate?.settingsSecureBackupTableViewSection(self, showActivityIndicator: false)
|
||||
case .error(let error):
|
||||
self.delegate?.settingsSecureBackupTableViewSection(self, showError: error)
|
||||
}
|
||||
}
|
||||
|
||||
func settingsSecureBackupViewModelShowSecureBackupReset(_ viewModel: SettingsSecureBackupViewModelType) {
|
||||
self.delegate?.settingsSecureBackupTableViewSectionShowSecureBackupReset(self)
|
||||
}
|
||||
|
||||
func settingsSecureBackupViewModelShowKeyBackupCreate(_ viewModel: SettingsSecureBackupViewModelType) {
|
||||
self.delegate?.settingsSecureBackupTableViewSectionShowKeyBackupCreate(self)
|
||||
}
|
||||
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, showKeyBackupRecover keyBackupVersion: MXKeyBackupVersion) {
|
||||
self.delegate?.settingsSecureBackupTableViewSection(self, showKeyBackupRecover: keyBackupVersion)
|
||||
}
|
||||
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, showKeyBackupDeleteConfirm keyBackupVersion: MXKeyBackupVersion) {
|
||||
self.delegate?.settingsSecureBackupTableViewSection(self, showKeyBackupDeleteConfirm: keyBackupVersion)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
enum SettingsSecureBackupViewAction {
|
||||
case load
|
||||
case createSecureBackup
|
||||
case resetSecureBackup
|
||||
case createKeyBackup
|
||||
case restoreFromKeyBackup(MXKeyBackupVersion)
|
||||
case confirmDeleteKeyBackup(MXKeyBackupVersion)
|
||||
case deleteKeyBackup(MXKeyBackupVersion)
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
final class SettingsSecureBackupViewModel: SettingsSecureBackupViewModelType {
|
||||
|
||||
// MARK: - Properties
|
||||
weak var viewDelegate: SettingsSecureBackupViewModelViewDelegate?
|
||||
|
||||
// MARK: Private
|
||||
private let recoveryService: MXRecoveryService
|
||||
private let keyBackup: MXKeyBackup
|
||||
|
||||
init(recoveryService: MXRecoveryService, keyBackup: MXKeyBackup) {
|
||||
self.recoveryService = recoveryService
|
||||
self.keyBackup = keyBackup
|
||||
self.registerKeyBackupVersionDidChangeStateNotification()
|
||||
}
|
||||
|
||||
private func registerKeyBackupVersionDidChangeStateNotification() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyBackupDidStateChange), name: NSNotification.Name.mxKeyBackupDidStateChange, object: self.keyBackup)
|
||||
}
|
||||
|
||||
@objc private func keyBackupDidStateChange() {
|
||||
self.checkKeyBackupState()
|
||||
}
|
||||
|
||||
func process(viewAction: SettingsSecureBackupViewAction) {
|
||||
guard let viewDelegate = self.viewDelegate else {
|
||||
return
|
||||
}
|
||||
|
||||
switch viewAction {
|
||||
case .load:
|
||||
viewDelegate.settingsSecureBackupViewModel(self, didUpdateViewState: .loading)
|
||||
self.checkKeyBackupState()
|
||||
case .resetSecureBackup,
|
||||
.createSecureBackup: // The implement supports both
|
||||
viewDelegate.settingsSecureBackupViewModelShowSecureBackupReset(self)
|
||||
case .createKeyBackup:
|
||||
viewDelegate.settingsSecureBackupViewModelShowKeyBackupCreate(self)
|
||||
case .restoreFromKeyBackup(let keyBackupVersion):
|
||||
viewDelegate.settingsSecureBackupViewModel(self, showKeyBackupRecover: keyBackupVersion)
|
||||
case .confirmDeleteKeyBackup(let keyBackupVersion):
|
||||
viewDelegate.settingsSecureBackupViewModel(self, showKeyBackupDeleteConfirm: keyBackupVersion)
|
||||
case .deleteKeyBackup(let keyBackupVersion):
|
||||
self.deleteKeyBackupVersion(keyBackupVersion)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
private func checkKeyBackupState() {
|
||||
|
||||
// Check homeserver update in background
|
||||
self.keyBackup.forceRefresh(nil, failure: nil)
|
||||
|
||||
if let keyBackupVersion = self.keyBackup.keyBackupVersion {
|
||||
|
||||
self.keyBackup.trust(for: keyBackupVersion, onComplete: { [weak self] (keyBackupVersionTrust) in
|
||||
|
||||
guard let sself = self else {
|
||||
return
|
||||
}
|
||||
|
||||
sself.computeState(withBackupVersionTrust: keyBackupVersionTrust)
|
||||
})
|
||||
} else {
|
||||
computeState()
|
||||
}
|
||||
}
|
||||
|
||||
private func computeState(withBackupVersionTrust keyBackupVersionTrust: MXKeyBackupVersionTrust? = nil) {
|
||||
|
||||
var viewState: SettingsSecureBackupViewState?
|
||||
var keyBackupState: SettingsSecureBackupViewState.KeyBackupState?
|
||||
switch self.keyBackup.state {
|
||||
|
||||
case MXKeyBackupStateUnknown,
|
||||
MXKeyBackupStateCheckingBackUpOnHomeserver:
|
||||
viewState = .loading
|
||||
|
||||
case MXKeyBackupStateDisabled, MXKeyBackupStateEnabling:
|
||||
keyBackupState = .noKeyBackup
|
||||
|
||||
case MXKeyBackupStateNotTrusted:
|
||||
guard let keyBackupVersion = self.keyBackup.keyBackupVersion, let keyBackupVersionTrust = keyBackupVersionTrust else {
|
||||
return
|
||||
}
|
||||
keyBackupState = .keyBackupNotTrusted(keyBackupVersion, keyBackupVersionTrust)
|
||||
|
||||
case MXKeyBackupStateReadyToBackUp, MXKeyBackupStateWillBackUp, MXKeyBackupStateBackingUp:
|
||||
guard let keyBackupVersion = self.keyBackup.keyBackupVersion, let keyBackupVersionTrust = keyBackupVersionTrust else {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the backup progress before updating the state
|
||||
self.keyBackup.backupProgress { [weak self] (progress) in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
|
||||
let keyBackupState: SettingsSecureBackupViewState.KeyBackupState = .keyBackup(keyBackupVersion, keyBackupVersionTrust, progress)
|
||||
let viewState: SettingsSecureBackupViewState = self.recoveryService.hasRecovery() ? .secureBackup(keyBackupState) : .noSecureBackup(keyBackupState)
|
||||
self.viewDelegate?.settingsSecureBackupViewModel(self, didUpdateViewState: viewState)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
// Turn secure backup and key back states into view state
|
||||
if let keyBackupState = keyBackupState {
|
||||
viewState = recoveryService.hasRecovery() ? .secureBackup(keyBackupState) : .noSecureBackup(keyBackupState)
|
||||
}
|
||||
|
||||
if let viewState = viewState {
|
||||
self.viewDelegate?.settingsSecureBackupViewModel(self, didUpdateViewState: viewState)
|
||||
}
|
||||
}
|
||||
|
||||
private func deleteKeyBackupVersion(_ keyBackupVersion: MXKeyBackupVersion) {
|
||||
guard let keyBackupVersionVersion = keyBackupVersion.version else {
|
||||
return
|
||||
}
|
||||
|
||||
self.viewDelegate?.settingsSecureBackupViewModel(self, didUpdateNetworkRequestViewState: .loading)
|
||||
|
||||
self.keyBackup.deleteVersion(keyBackupVersionVersion, success: { [weak self] () in
|
||||
guard let sself = self else {
|
||||
return
|
||||
}
|
||||
sself.viewDelegate?.settingsSecureBackupViewModel(sself, didUpdateNetworkRequestViewState: .loaded)
|
||||
|
||||
}, failure: { [weak self] error in
|
||||
guard let sself = self else {
|
||||
return
|
||||
}
|
||||
sself.viewDelegate?.settingsSecureBackupViewModel(sself, didUpdateNetworkRequestViewState: .error(error))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol SettingsSecureBackupViewModelViewDelegate: class {
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, didUpdateViewState viewState: SettingsSecureBackupViewState)
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, didUpdateNetworkRequestViewState networkRequestViewSate: SettingsSecureBackupNetworkRequestViewState)
|
||||
|
||||
func settingsSecureBackupViewModelShowSecureBackupReset(_ viewModel: SettingsSecureBackupViewModelType)
|
||||
|
||||
func settingsSecureBackupViewModelShowKeyBackupCreate(_ viewModel: SettingsSecureBackupViewModelType)
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, showKeyBackupRecover keyBackupVersion: MXKeyBackupVersion)
|
||||
func settingsSecureBackupViewModel(_ viewModel: SettingsSecureBackupViewModelType, showKeyBackupDeleteConfirm keyBackupVersion: MXKeyBackupVersion)
|
||||
}
|
||||
|
||||
protocol SettingsSecureBackupViewModelType {
|
||||
|
||||
var viewDelegate: SettingsSecureBackupViewModelViewDelegate? { get set }
|
||||
|
||||
func process(viewAction: SettingsSecureBackupViewAction)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
/// State of the Secure Backup section in securtiy settings.
|
||||
///
|
||||
/// It is a mixed of the state of the Secure Backup(4S) and the state of the Key Backup.
|
||||
///
|
||||
/// - loading: Load current state
|
||||
/// - noSecureBackup: The account has no secure backup
|
||||
/// - secureBackup: The account has a secure backup
|
||||
enum SettingsSecureBackupViewState {
|
||||
case loading
|
||||
case noSecureBackup(KeyBackupState)
|
||||
case secureBackup(KeyBackupState)
|
||||
|
||||
/// Internal key backup state. It is independent from the secure backup state.
|
||||
///
|
||||
/// - noKeyBackup: There is no backup on the homeserver
|
||||
/// - keyBackup: There is a valid running backup on the homeserver. Keys are being sent to it
|
||||
/// - keyBackupNotTrusted: There is a backup on the homeserver but it is not trusted
|
||||
enum KeyBackupState {
|
||||
case noKeyBackup
|
||||
case keyBackup(MXKeyBackupVersion, MXKeyBackupVersionTrust, Progress)
|
||||
case keyBackupNotTrusted(MXKeyBackupVersion, MXKeyBackupVersionTrust)
|
||||
}
|
||||
}
|
||||
|
||||
/// State representing a network request made by the module
|
||||
/// Only SettingsSecureBackupViewAction.delete generates such states
|
||||
enum SettingsSecureBackupNetworkRequestViewState {
|
||||
case loading
|
||||
case loaded
|
||||
case error(Error)
|
||||
}
|
||||
@@ -36,9 +36,9 @@ enum
|
||||
SECTION_PIN_CODE,
|
||||
SECTION_CRYPTO_SESSIONS,
|
||||
SECTION_SECURE_BACKUP,
|
||||
SECTION_CROSSSIGNING,
|
||||
SECTION_CRYPTOGRAPHY,
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
SECTION_CROSSSIGNING,
|
||||
SECTION_KEYBACKUP,
|
||||
#endif
|
||||
SECTION_ADVANCED,
|
||||
@@ -51,23 +51,6 @@ enum {
|
||||
CROSSSIGNING_SECOND_ACTION, // Reset
|
||||
};
|
||||
|
||||
enum {
|
||||
SECURE_BACKUP_DESCRIPTION,
|
||||
// TODO: We can display the state of 4S both locally and on the server. Then, provide actions according to all combinations.
|
||||
// - Does the 4S contains all the 4 keys server side?
|
||||
// - Advice the user to do a recovery if there is less keys locally
|
||||
// - Advice them to do a recovery if local keys are obsolete -> We cannot know now
|
||||
// - Advice them to fix a secure backup if there is 4S but no key backup
|
||||
// - Warm them if there is no 4S and they do not have all 3 signing keys locally. They will set up a not complete secure backup
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
SECURE_BACKUP_INFO,
|
||||
#endif
|
||||
SECURE_BACKUP_SETUP,
|
||||
SECURE_BACKUP_RESTORE,
|
||||
SECURE_BACKUP_DELETE,
|
||||
SECURE_BACKUP_MANAGE_MANUALLY, // TODO: What to do with that?
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_CODE_SETTING,
|
||||
PIN_CODE_DESCRIPTION,
|
||||
@@ -90,9 +73,10 @@ enum {
|
||||
|
||||
|
||||
@interface SecurityViewController () <
|
||||
SettingsSecureBackupTableViewSectionDelegate,
|
||||
KeyBackupSetupCoordinatorBridgePresenterDelegate,
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
SettingsKeyBackupTableViewSectionDelegate,
|
||||
KeyBackupSetupCoordinatorBridgePresenterDelegate,
|
||||
KeyBackupRecoverCoordinatorBridgePresenterDelegate,
|
||||
#endif
|
||||
UIDocumentInteractionControllerDelegate,
|
||||
@@ -107,9 +91,6 @@ TableViewSectionsDelegate>
|
||||
// Devices
|
||||
NSMutableArray<MXDevice *> *devicesArray;
|
||||
|
||||
// SECURE_BACKUP_* rows to display
|
||||
NSArray<NSNumber *> *secureBackupSectionState;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
@@ -123,13 +104,15 @@ TableViewSectionsDelegate>
|
||||
|
||||
// The current pushed view controller
|
||||
UIViewController *pushedViewController;
|
||||
|
||||
|
||||
SettingsSecureBackupTableViewSection *secureBackupSection;
|
||||
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
SettingsKeyBackupTableViewSection *keyBackupSection;
|
||||
KeyBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter;
|
||||
#endif
|
||||
|
||||
KeyBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter;
|
||||
KeyBackupRecoverCoordinatorBridgePresenter *keyBackupRecoverCoordinatorBridgePresenter;
|
||||
|
||||
SecretsRecoveryCoordinatorBridgePresenter *secretsRecoveryCoordinatorBridgePresenter;
|
||||
}
|
||||
|
||||
@@ -183,7 +166,6 @@ TableViewSectionsDelegate>
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedRowHeight = 50;
|
||||
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
if (self.mainSession.crypto.backup)
|
||||
{
|
||||
MXDeviceInfo *deviceInfo = [self.mainSession.crypto.deviceList storedDevice:self.mainSession.matrixRestClient.credentials.userId
|
||||
@@ -191,11 +173,15 @@ TableViewSectionsDelegate>
|
||||
|
||||
if (deviceInfo)
|
||||
{
|
||||
secureBackupSection = [[SettingsSecureBackupTableViewSection alloc] initWithRecoveryService:self.mainSession.crypto.recoveryService keyBackup:self.mainSession.crypto.backup userDevice:deviceInfo];
|
||||
secureBackupSection.delegate = self;
|
||||
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
keyBackupSection = [[SettingsKeyBackupTableViewSection alloc] initWithKeyBackup:self.mainSession.crypto.backup userDevice:deviceInfo];
|
||||
keyBackupSection.delegate = self;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
@@ -258,11 +244,8 @@ TableViewSectionsDelegate>
|
||||
kThemeServiceDidChangeThemeNotificationObserver = nil;
|
||||
}
|
||||
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
keyBackupSetupCoordinatorBridgePresenter = nil;
|
||||
#endif
|
||||
keyBackupRecoverCoordinatorBridgePresenter = nil;
|
||||
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
@@ -355,13 +338,19 @@ TableViewSectionsDelegate>
|
||||
|
||||
Section *secureBackupSection = [Section sectionWithTag:SECTION_SECURE_BACKUP];
|
||||
secureBackupSection.headerTitle = NSLocalizedStringFromTable(@"security_settings_secure_backup", @"Vector", nil);
|
||||
|
||||
[secureBackupSection addRowsWithCount:[self numberOfRowsInSecureBackupSection]];
|
||||
|
||||
if (secureBackupSection.rows.count)
|
||||
{
|
||||
[sections addObject:secureBackupSection];
|
||||
}
|
||||
|
||||
[secureBackupSection addRowsWithCount:self->secureBackupSection.numberOfRows];
|
||||
|
||||
[sections addObject:secureBackupSection];
|
||||
|
||||
// Cross-Signing
|
||||
|
||||
Section *crossSigningSection = [Section sectionWithTag:SECTION_CROSSSIGNING];
|
||||
crossSigningSection.headerTitle = NSLocalizedStringFromTable(@"security_settings_crosssigning", @"Vector", nil);
|
||||
|
||||
[crossSigningSection addRowsWithCount:[self numberOfRowsInCrossSigningSection]];
|
||||
|
||||
[sections addObject:crossSigningSection];
|
||||
|
||||
// Cryptograhpy
|
||||
|
||||
@@ -385,15 +374,6 @@ TableViewSectionsDelegate>
|
||||
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
|
||||
// Cross-Signing
|
||||
|
||||
Section *crossSigningSection = [Section sectionWithTag:SECTION_CROSSSIGNING];
|
||||
crossSigningSection.headerTitle = NSLocalizedStringFromTable(@"security_settings_crosssigning", @"Vector", nil);
|
||||
|
||||
[crossSigningSection addRowsWithCount:[self numberOfRowsInCrossSigningSection]];
|
||||
|
||||
[sections addObject:crossSigningSection];
|
||||
|
||||
// Keybackup
|
||||
|
||||
Section *keybackupSection = [Section sectionWithTag:SECTION_KEYBACKUP];
|
||||
@@ -582,8 +562,6 @@ TableViewSectionsDelegate>
|
||||
|
||||
- (void)reloadData
|
||||
{
|
||||
[self refreshSecureBackupSectionData];
|
||||
|
||||
// Update table view sections and trigger a tableView reloadData
|
||||
[self updateSections];
|
||||
}
|
||||
@@ -874,56 +852,6 @@ TableViewSectionsDelegate>
|
||||
|
||||
#pragma mark - SSSS
|
||||
|
||||
- (void)refreshSecureBackupSectionData
|
||||
{
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
NSMutableArray *secureBackupSectionState = [NSMutableArray new];
|
||||
if (recoveryService.hasRecovery)
|
||||
{
|
||||
if (RiotSettings.shared.settingsSecurityScreenShowRestoreBackup)
|
||||
{
|
||||
[secureBackupSectionState addObject:@(SECURE_BACKUP_RESTORE)];
|
||||
}
|
||||
if (RiotSettings.shared.settingsSecurityScreenShowDeleteBackup)
|
||||
{
|
||||
[secureBackupSectionState addObject:@(SECURE_BACKUP_DELETE)];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RiotSettings.shared.settingsSecurityScreenShowSetupBackup)
|
||||
{
|
||||
[secureBackupSectionState addObject:@(SECURE_BACKUP_SETUP)];
|
||||
}
|
||||
}
|
||||
|
||||
if (secureBackupSectionState.count)
|
||||
{
|
||||
[secureBackupSectionState addObject:@(SECURE_BACKUP_DESCRIPTION)];
|
||||
}
|
||||
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
[secureBackupSectionState addObject:@(SECURE_BACKUP_INFO)];
|
||||
#endif
|
||||
|
||||
self->secureBackupSectionState = secureBackupSectionState;
|
||||
}
|
||||
|
||||
- (NSUInteger)secureBackupSectionEnumForRow:(NSUInteger)row
|
||||
{
|
||||
if (row < secureBackupSectionState.count)
|
||||
{
|
||||
return secureBackupSectionState[row].unsignedIntegerValue;
|
||||
}
|
||||
|
||||
return SECURE_BACKUP_DESCRIPTION;
|
||||
}
|
||||
|
||||
- (NSUInteger)numberOfRowsInSecureBackupSection
|
||||
{
|
||||
return secureBackupSectionState.count;
|
||||
}
|
||||
|
||||
- (NSString*)secureBackupInformation
|
||||
{
|
||||
NSString *secureBackupInformation;
|
||||
@@ -1060,7 +988,7 @@ TableViewSectionsDelegate>
|
||||
|
||||
- (void)setupSecureBackup2
|
||||
{
|
||||
SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
|
||||
SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession allowOverwrite:YES];
|
||||
secureBackupSetupCoordinatorBridgePresenter.delegate = self;
|
||||
|
||||
[secureBackupSetupCoordinatorBridgePresenter presentFrom:self animated:YES];
|
||||
@@ -1068,32 +996,6 @@ TableViewSectionsDelegate>
|
||||
self.secureBackupSetupCoordinatorBridgePresenter = secureBackupSetupCoordinatorBridgePresenter;
|
||||
}
|
||||
|
||||
- (void)restoreFromSecureBackup
|
||||
{
|
||||
secretsRecoveryCoordinatorBridgePresenter = [[SecretsRecoveryCoordinatorBridgePresenter alloc] initWithSession:self.mainSession recoveryGoal:SecretsRecoveryGoalRestoreSecureBackup];
|
||||
|
||||
[secretsRecoveryCoordinatorBridgePresenter presentFrom:self animated:true];
|
||||
secretsRecoveryCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)deleteSecureBackup
|
||||
{
|
||||
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
|
||||
if (recoveryService)
|
||||
{
|
||||
[self startActivityIndicator];
|
||||
[recoveryService deleteRecoveryWithDeleteServicesBackups:YES success:^{
|
||||
[self stopActivityIndicator];
|
||||
[self reloadData];
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
[self stopActivityIndicator];
|
||||
[self reloadData];
|
||||
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Segues
|
||||
|
||||
@@ -1228,6 +1130,17 @@ TableViewSectionsDelegate>
|
||||
return textViewCell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCell*)descriptionCellForTableView:(UITableView*)tableView atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCell *cell = [self getDefaultTableViewCell:tableView];
|
||||
cell.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
cell.contentView.backgroundColor = ThemeService.shared.theme.headerBackgroundColor;
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithButton *)buttonCellForTableView:(UITableView*)tableView atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCellWithButton *cell = [self.tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
@@ -1360,71 +1273,14 @@ TableViewSectionsDelegate>
|
||||
}
|
||||
else if (section == SECTION_SECURE_BACKUP)
|
||||
{
|
||||
switch ([self secureBackupSectionEnumForRow:row])
|
||||
{
|
||||
case SECURE_BACKUP_DESCRIPTION:
|
||||
{
|
||||
cell = [self descriptionCellForTableView:tableView
|
||||
withText:NSLocalizedStringFromTable(@"security_settings_secure_backup_description", @"Vector", nil)];
|
||||
break;
|
||||
}
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
case SECURE_BACKUP_INFO:
|
||||
{
|
||||
cell = [self descriptionCellForTableView:tableView
|
||||
withText:self.secureBackupInformation];
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SECURE_BACKUP_SETUP:
|
||||
{
|
||||
MXKTableViewCellWithButton *buttonCell = [self buttonCellWithTitle:NSLocalizedStringFromTable(@"security_settings_secure_backup_setup", @"Vector", nil)
|
||||
action:@selector(setupSecureBackup)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
|
||||
cell = buttonCell;
|
||||
break;
|
||||
}
|
||||
case SECURE_BACKUP_RESTORE:
|
||||
{
|
||||
MXKTableViewCellWithButton *buttonCell = [self buttonCellWithTitle:NSLocalizedStringFromTable(@"security_settings_secure_backup_synchronise", @"Vector", nil)
|
||||
action:@selector(restoreFromSecureBackup)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
|
||||
cell = buttonCell;
|
||||
break;
|
||||
}
|
||||
case SECURE_BACKUP_DELETE:
|
||||
{
|
||||
MXKTableViewCellWithButton *buttonCell = [self buttonCellWithTitle:NSLocalizedStringFromTable(@"security_settings_secure_backup_delete", @"Vector", nil)
|
||||
action:@selector(deleteSecureBackup)
|
||||
forTableView:tableView
|
||||
atIndexPath:indexPath];
|
||||
buttonCell.mxkButton.tintColor = ThemeService.shared.theme.warningColor;
|
||||
|
||||
cell = buttonCell;
|
||||
break;
|
||||
}
|
||||
|
||||
case SECURE_BACKUP_MANAGE_MANUALLY:
|
||||
{
|
||||
MXKTableViewCellWithTextView *textCell = [self textViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
textCell.mxkTextView.text = @"Advanced: Manually manage keys"; // TODO
|
||||
[textCell vc_setAccessoryDisclosureIndicatorWithCurrentTheme];
|
||||
|
||||
cell = textCell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cell = [secureBackupSection cellForRowAtRow:row];
|
||||
}
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
else if (section == SECTION_KEYBACKUP)
|
||||
{
|
||||
cell = [keyBackupSection cellForRowAtRow:row];
|
||||
}
|
||||
#endif
|
||||
else if (section == SECTION_CROSSSIGNING)
|
||||
{
|
||||
switch (row)
|
||||
@@ -1444,7 +1300,6 @@ TableViewSectionsDelegate>
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (section == SECTION_CRYPTOGRAPHY)
|
||||
{
|
||||
switch (row)
|
||||
@@ -1739,6 +1594,155 @@ TableViewSectionsDelegate>
|
||||
[self.setPinCoordinatorBridgePresenter presentFrom:self animated:YES];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - SettingsSecureBackupTableViewSectionDelegate
|
||||
|
||||
- (void)settingsSecureBackupTableViewSectionDidUpdate:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection
|
||||
{
|
||||
[self reloadData];
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithTextView *)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection textCellForRow:(NSInteger)textCellForRow
|
||||
{
|
||||
MXKTableViewCellWithTextView *cell;
|
||||
|
||||
NSIndexPath *indexPath = [self.tableViewSections exactIndexPathForRowTag:textCellForRow sectionTag:SECTION_SECURE_BACKUP];
|
||||
|
||||
if (indexPath)
|
||||
{
|
||||
cell = [self textViewCellForTableView:self.tableView atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCell *)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection descriptionCellForRow:(NSInteger)textCellForRow
|
||||
{
|
||||
MXKTableViewCell *cell;
|
||||
|
||||
NSIndexPath *indexPath = [self.tableViewSections exactIndexPathForRowTag:textCellForRow sectionTag:SECTION_SECURE_BACKUP];
|
||||
|
||||
if (indexPath)
|
||||
{
|
||||
cell = [self descriptionCellForTableView:self.tableView atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithButton *)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection buttonCellForRow:(NSInteger)buttonCellForRow
|
||||
{
|
||||
MXKTableViewCellWithButton *cell;
|
||||
|
||||
NSIndexPath *indexPath = [self.tableViewSections exactIndexPathForRowTag:buttonCellForRow sectionTag:SECTION_SECURE_BACKUP];
|
||||
|
||||
if (indexPath)
|
||||
{
|
||||
cell = [self buttonCellForTableView:self.tableView atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)settingsSecureBackupTableViewSectionShowSecureBackupReset:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection
|
||||
{
|
||||
[self setupSecureBackup];
|
||||
}
|
||||
|
||||
- (void)settingsSecureBackupTableViewSectionShowKeyBackupCreate:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection
|
||||
{
|
||||
[self showKeyBackupSetupFromSignOutFlow:NO];
|
||||
}
|
||||
|
||||
- (void)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection showKeyBackupRecover:(MXKeyBackupVersion *)keyBackupVersion
|
||||
{
|
||||
self.currentkeyBackupVersion = keyBackupVersion;
|
||||
|
||||
// If key backup key is stored in SSSS, ask for secrets recovery before restoring key backup.
|
||||
if (!self.mainSession.crypto.backup.hasPrivateKeyInCryptoStore
|
||||
&& self.mainSession.crypto.recoveryService.hasRecovery
|
||||
&& [self.mainSession.crypto.recoveryService hasSecretWithSecretId:MXSecretId.keyBackup])
|
||||
{
|
||||
[self showSecretsRecovery];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self showKeyBackupRecover:keyBackupVersion fromViewController:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection showKeyBackupDeleteConfirm:(MXKeyBackupVersion *)keyBackupVersion
|
||||
{
|
||||
MXWeakify(self);
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
currentAlert =
|
||||
[UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"settings_key_backup_delete_confirmation_prompt_title", @"Vector", nil)
|
||||
message:NSLocalizedStringFromTable(@"settings_key_backup_delete_confirmation_prompt_msg", @"Vector", nil)
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"settings_key_backup_button_delete", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
[self->secureBackupSection deleteKeyBackupWithKeyBackupVersion:keyBackupVersion];
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCDeleteKeyBackup"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection showActivityIndicator:(BOOL)show
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
[self startActivityIndicator];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self stopActivityIndicator];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)settingsSecureBackupTableViewSection:(SettingsSecureBackupTableViewSection *)settingsSecureBackupTableViewSection showError:(NSError *)error
|
||||
{
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}
|
||||
|
||||
#pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
|
||||
|
||||
- (void)showKeyBackupSetupFromSignOutFlow:(BOOL)showFromSignOutFlow
|
||||
{
|
||||
keyBackupSetupCoordinatorBridgePresenter = [[KeyBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
|
||||
|
||||
[keyBackupSetupCoordinatorBridgePresenter presentFrom:self
|
||||
isStartedFromSignOut:showFromSignOutFlow
|
||||
animated:true];
|
||||
|
||||
keyBackupSetupCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)keyBackupSetupCoordinatorBridgePresenterDelegateDidCancel:(KeyBackupSetupCoordinatorBridgePresenter *)bridgePresenter {
|
||||
[keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated:true];
|
||||
keyBackupSetupCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
- (void)keyBackupSetupCoordinatorBridgePresenterDelegateDidSetupRecoveryKey:(KeyBackupSetupCoordinatorBridgePresenter *)bridgePresenter {
|
||||
[keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated:true];
|
||||
keyBackupSetupCoordinatorBridgePresenter = nil;
|
||||
|
||||
[secureBackupSection reload];
|
||||
}
|
||||
|
||||
#pragma mark - SettingsKeyBackupTableViewSectionDelegate
|
||||
#ifdef CROSS_SIGNING_AND_BACKUP_DEV
|
||||
- (void)settingsKeyBackupTableViewSectionDidUpdate:(SettingsKeyBackupTableViewSection *)settingsKeyBackupTableViewSection
|
||||
@@ -1768,7 +1772,7 @@ TableViewSectionsDelegate>
|
||||
|
||||
if (indexPath)
|
||||
{
|
||||
[self buttonCellForTableView:self.tableView atIndexPath:indexPath];
|
||||
cell = [self buttonCellForTableView:self.tableView atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
return cell;
|
||||
@@ -1843,31 +1847,6 @@ TableViewSectionsDelegate>
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}
|
||||
|
||||
#pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
|
||||
|
||||
- (void)showKeyBackupSetupFromSignOutFlow:(BOOL)showFromSignOutFlow
|
||||
{
|
||||
keyBackupSetupCoordinatorBridgePresenter = [[KeyBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
|
||||
|
||||
[keyBackupSetupCoordinatorBridgePresenter presentFrom:self
|
||||
isStartedFromSignOut:showFromSignOutFlow
|
||||
animated:true];
|
||||
|
||||
keyBackupSetupCoordinatorBridgePresenter.delegate = self;
|
||||
}
|
||||
|
||||
- (void)keyBackupSetupCoordinatorBridgePresenterDelegateDidCancel:(KeyBackupSetupCoordinatorBridgePresenter *)bridgePresenter {
|
||||
[keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated:true];
|
||||
keyBackupSetupCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
- (void)keyBackupSetupCoordinatorBridgePresenterDelegateDidSetupRecoveryKey:(KeyBackupSetupCoordinatorBridgePresenter *)bridgePresenter {
|
||||
[keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated:true];
|
||||
keyBackupSetupCoordinatorBridgePresenter = nil;
|
||||
|
||||
[keyBackupSection reload];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark - KeyBackupRecoverCoordinatorBridgePresenter
|
||||
@@ -1904,7 +1883,7 @@ TableViewSectionsDelegate>
|
||||
|
||||
- (void)showSecretsRecovery
|
||||
{
|
||||
secretsRecoveryCoordinatorBridgePresenter = [[SecretsRecoveryCoordinatorBridgePresenter alloc] initWithSession:self.mainSession recoveryGoal:SecretsRecoveryGoalKeyBackup];
|
||||
secretsRecoveryCoordinatorBridgePresenter = [[SecretsRecoveryCoordinatorBridgePresenter alloc] initWithSession:self.mainSession recoveryGoal:SecretsRecoveryGoalBridgeKeyBackup];
|
||||
|
||||
[secretsRecoveryCoordinatorBridgePresenter presentFrom:self animated:true];
|
||||
secretsRecoveryCoordinatorBridgePresenter.delegate = self;
|
||||
@@ -1920,7 +1899,7 @@ TableViewSectionsDelegate>
|
||||
{
|
||||
UIViewController *presentedViewController = [coordinatorBridgePresenter toPresentable];
|
||||
|
||||
if (coordinatorBridgePresenter.recoveryGoal == SecretsRecoveryGoalKeyBackup)
|
||||
if (coordinatorBridgePresenter.recoveryGoal == SecretsRecoveryGoalBridgeKeyBackup)
|
||||
{
|
||||
// Go to the true key backup recovery screen
|
||||
if ([presentedViewController isKindOfClass:UINavigationController.class])
|
||||
|
||||
@@ -4023,7 +4023,7 @@ TableViewSectionsDelegate>
|
||||
|
||||
- (void)setupSecureBackup2
|
||||
{
|
||||
SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
|
||||
SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession allowOverwrite:YES];
|
||||
secureBackupSetupCoordinatorBridgePresenter.delegate = self;
|
||||
|
||||
[secureBackupSetupCoordinatorBridgePresenter presentFrom:self animated:YES];
|
||||
|
||||
Reference in New Issue
Block a user