Secure backup setup: Manage the case when the user has already a key backup

but we do not have the private key
This commit is contained in:
manuroe
2020-06-30 14:15:18 +02:00
parent 7e97422624
commit 4e419d870c
4 changed files with 142 additions and 5 deletions
@@ -19,7 +19,8 @@ import UIKit
protocol SecureBackupSetupIntroViewControllerDelegate: class {
func secureBackupSetupIntroViewControllerDidTapUseKey(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController)
func secureBackupSetupIntroViewControllerDidTapUsePassphrase(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController)
func secureBackupSetupIntroViewControllerDidCancel(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController)
func secureBackupSetupIntroViewControllerDidCancel(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController, showSkipAlert: Bool)
func secureBackupSetupIntroViewControllerDidTapConnectToKeyBackup(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController)
}
@objcMembers
@@ -39,10 +40,17 @@ final class SecureBackupSetupIntroViewController: UIViewController {
private var theme: Theme!
private var activityIndicatorPresenter: ActivityIndicatorPresenter!
private var errorPresenter: MXKErrorPresentation!
// MARK: Public
weak var delegate: SecureBackupSetupIntroViewControllerDelegate?
// This is evil
// TODO: refactor it
weak var keyBackup: MXKeyBackup?
// MARK: - Setup
class func instantiate() -> SecureBackupSetupIntroViewController {
@@ -61,10 +69,17 @@ final class SecureBackupSetupIntroViewController: UIViewController {
self.vc_removeBackTitle()
self.setupViews()
self.activityIndicatorPresenter = ActivityIndicatorPresenter()
self.errorPresenter = MXKErrorAlertPresentation()
self.registerThemeServiceDidChangeThemeNotification()
self.update(theme: self.theme)
}
override func viewDidAppear(_ animated: Bool) {
self.checkKeyBackup()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
@@ -76,7 +91,7 @@ final class SecureBackupSetupIntroViewController: UIViewController {
guard let self = self else {
return
}
self.delegate?.secureBackupSetupIntroViewControllerDidCancel(self)
self.delegate?.secureBackupSetupIntroViewControllerDidCancel(self, showSkipAlert: true)
}
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
@@ -107,6 +122,19 @@ final class SecureBackupSetupIntroViewController: UIViewController {
}
}
private func renderLoading() {
self.activityIndicatorPresenter.presentActivityIndicator(on: self.view, animated: true)
}
private func renderLoaded() {
self.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true)
}
private func render(error: Error) {
self.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
}
private func update(theme: Theme) {
self.theme = theme
@@ -130,4 +158,59 @@ final class SecureBackupSetupIntroViewController: UIViewController {
@objc private func themeDidChange() {
self.update(theme: ThemeService.shared().theme)
}
// TODO: To remove
private func checkKeyBackup() {
guard let keyBackup = self.keyBackup else {
return
}
// If a backup already exists and we do not have the private key,
// we need to get this private key first. Ask the user to make a key backup restore to catch it
if keyBackup.keyBackupVersion != nil && keyBackup.hasPrivateKeyInCryptoStore == false {
let alertContoller = UIAlertController(title: VectorL10n.secureKeyBackupSetupExistingBackupErrorTitle,
message: VectorL10n.secureKeyBackupSetupExistingBackupErrorInfo,
preferredStyle: .alert)
let connectAction = UIAlertAction(title: VectorL10n.secureKeyBackupSetupExistingBackupErrorUnlockIt, style: .default) { (_) in
self.delegate?.secureBackupSetupIntroViewControllerDidTapConnectToKeyBackup(self)
}
let resetAction = UIAlertAction(title: VectorL10n.secureKeyBackupSetupExistingBackupErrorDeleteIt, style: .destructive) { (_) in
self.deleteKeybackup()
}
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel) { (_) in
self.delegate?.secureBackupSetupIntroViewControllerDidCancel(self, showSkipAlert: false)
}
alertContoller.addAction(connectAction)
alertContoller.addAction(resetAction)
alertContoller.addAction(cancelAction)
self.present(alertContoller, animated: true)
}
}
func deleteKeybackup() {
guard let keyBackup = self.keyBackup, let keybackupVersion = keyBackup.keyBackupVersion?.version else {
return
}
self.renderLoading()
keyBackup.deleteVersion(keybackupVersion, success: { [weak self] in
guard let self = self else {
return
}
self.renderLoaded()
self.checkKeyBackup()
}, failure: { [weak self] (error) in
guard let self = self else {
return
}
self.render(error: error)
})
}
}
@@ -26,8 +26,10 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
// MARK: Private
private let navigationRouter: NavigationRouterType
private let session: MXSession
private let recoveryService: MXRecoveryService
private let keyBackup: MXKeyBackup?
// MARK: Public
// Must be used only internally
@@ -39,7 +41,9 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
init(session: MXSession) {
self.navigationRouter = NavigationRouter(navigationController: RiotNavigationController())
self.session = session
self.recoveryService = session.crypto.recoveryService
self.keyBackup = session.crypto.backup
}
// MARK: - Public methods
@@ -58,6 +62,7 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
private func createIntro() -> SecureBackupSetupIntroViewController {
let introViewController = SecureBackupSetupIntroViewController.instantiate()
introViewController.delegate = self
introViewController.keyBackup = self.keyBackup
return introViewController
}
@@ -109,6 +114,18 @@ final class SecureBackupSetupCoordinator: SecureBackupSetupCoordinatorType {
self.navigationRouter.present(alertController, animated: true)
}
private func showKeyBackupRestore() {
guard let keyBackupVersion = self.keyBackup?.keyBackupVersion else {
return
}
let coordinator = KeyBackupRecoverCoordinator(session: self.session, keyBackupVersion: keyBackupVersion, navigationRouter: self.navigationRouter)
self.add(childCoordinator: coordinator)
coordinator.delegate = self
coordinator.start() // Will trigger view controller push
}
private func didCancel(showSkipAlert: Bool = true) {
if showSkipAlert {
self.showCancelAlert()
@@ -133,8 +150,12 @@ extension SecureBackupSetupCoordinator: SecureBackupSetupIntroViewControllerDele
self.showSetupPassphrase()
}
func secureBackupSetupIntroViewControllerDidCancel(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController) {
self.didCancel()
func secureBackupSetupIntroViewControllerDidCancel(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController, showSkipAlert: Bool) {
self.didCancel(showSkipAlert: showSkipAlert)
}
func secureBackupSetupIntroViewControllerDidTapConnectToKeyBackup(_ secureBackupSetupIntroViewController: SecureBackupSetupIntroViewController) {
self.showKeyBackupRestore()
}
}
@@ -169,3 +190,14 @@ extension SecureBackupSetupCoordinator: SecretsSetupRecoveryPassphraseCoordinato
self.didCancel()
}
}
// MARK: - KeyBackupRecoverCoordinatorDelegate
extension SecureBackupSetupCoordinator: KeyBackupRecoverCoordinatorDelegate {
func keyBackupRecoverCoordinatorDidCancel(_ keyBackupRecoverCoordinator: KeyBackupRecoverCoordinatorType) {
self.navigationRouter.popToRootModule(animated: true)
}
func keyBackupRecoverCoordinatorDidRecover(_ keyBackupRecoverCoordinator: KeyBackupRecoverCoordinatorType) {
self.navigationRouter.popToRootModule(animated: true)
}
}