153 lines
5.2 KiB
Swift
153 lines
5.2 KiB
Swift
/*
|
|
Copyright 2019-2024 New Vector Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import Foundation
|
|
|
|
final class KeyBackupSetupPassphraseViewModel: KeyBackupSetupPassphraseViewModelType {
|
|
|
|
// MARK: - Properties
|
|
|
|
// MARK: Private
|
|
|
|
private(set) var passphraseStrength: PasswordStrength = .tooGuessable
|
|
private let passwordStrengthManager: PasswordStrengthManager
|
|
private let keyBackup: MXKeyBackup
|
|
private let coordinatorDelegateQueue: OperationQueue
|
|
private var createKeyBackupOperation: MXHTTPOperation?
|
|
|
|
// MARK: Public
|
|
|
|
var passphrase: String? {
|
|
didSet {
|
|
self.updatePassphraseStrength()
|
|
}
|
|
}
|
|
|
|
var confirmPassphrase: String?
|
|
|
|
var isPassphraseValid: Bool {
|
|
return self.passphraseStrength == .veryUnguessable
|
|
}
|
|
|
|
var isConfirmPassphraseValid: Bool {
|
|
guard self.isPassphraseValid, let confirmPassphrase = self.confirmPassphrase else {
|
|
return false
|
|
}
|
|
return confirmPassphrase == passphrase
|
|
}
|
|
|
|
var isFormValid: Bool {
|
|
return self.isPassphraseValid && self.isConfirmPassphraseValid
|
|
}
|
|
|
|
weak var viewDelegate: KeyBackupSetupPassphraseViewModelViewDelegate?
|
|
weak var coordinatorDelegate: KeyBackupSetupPassphraseViewModelCoordinatorDelegate?
|
|
|
|
// MARK: - Setup
|
|
|
|
init(keyBackup: MXKeyBackup) {
|
|
self.passwordStrengthManager = PasswordStrengthManager()
|
|
self.keyBackup = keyBackup
|
|
self.coordinatorDelegateQueue = OperationQueue.vc_createSerialOperationQueue(name: "\(type(of: self)).coordinatorDelegateQueue")
|
|
}
|
|
|
|
deinit {
|
|
self.createKeyBackupOperation?.cancel()
|
|
}
|
|
|
|
// MARK: - Public
|
|
|
|
func process(viewAction: KeyBackupSetupPassphraseViewAction) {
|
|
switch viewAction {
|
|
case .setupPassphrase:
|
|
self.setupPassphrase()
|
|
case .setupRecoveryKey:
|
|
self.setupRecoveryKey()
|
|
case .skip:
|
|
self.coordinatorDelegateQueue.vc_pause()
|
|
self.viewDelegate?.keyBackupSetupPassphraseViewModelShowSkipAlert(self)
|
|
case.skipAlertContinue:
|
|
self.coordinatorDelegateQueue.vc_resume()
|
|
case.skipAlertSkip:
|
|
self.coordinatorDelegateQueue.cancelAllOperations()
|
|
self.coordinatorDelegate?.keyBackupSetupPassphraseViewModelDidCancel(self)
|
|
}
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private func setupPassphrase() {
|
|
guard let passphrase = self.passphrase else {
|
|
return
|
|
}
|
|
|
|
self.update(viewState: .loading)
|
|
|
|
self.keyBackup.prepareKeyBackupVersion(withPassword: passphrase, algorithm: nil, success: { [weak self] (megolmBackupCreationInfo) in
|
|
guard let sself = self else {
|
|
return
|
|
}
|
|
|
|
sself.createKeyBackupOperation = sself.keyBackup.createKeyBackupVersion(megolmBackupCreationInfo, success: { (_) in
|
|
|
|
sself.update(viewState: .loaded)
|
|
|
|
sself.coordinatorDelegateQueue.addOperation {
|
|
DispatchQueue.main.async {
|
|
sself.coordinatorDelegate?.keyBackupSetupPassphraseViewModel(sself, didCreateBackupFromPassphraseWithResultingRecoveryKey: megolmBackupCreationInfo.recoveryKey)
|
|
}
|
|
}
|
|
|
|
}, failure: { (error) in
|
|
self?.update(viewState: .error(error))
|
|
})
|
|
}, failure: { [weak self] error in
|
|
self?.update(viewState: .error(error))
|
|
})
|
|
}
|
|
|
|
private func setupRecoveryKey() {
|
|
self.update(viewState: .loading)
|
|
|
|
self.keyBackup.prepareKeyBackupVersion(withPassword: nil, algorithm: nil, success: { [weak self] (megolmBackupCreationInfo) in
|
|
guard let sself = self else {
|
|
return
|
|
}
|
|
|
|
sself.createKeyBackupOperation = sself.keyBackup.createKeyBackupVersion(megolmBackupCreationInfo, success: { (_) in
|
|
|
|
sself.update(viewState: .loaded)
|
|
|
|
sself.coordinatorDelegateQueue.addOperation {
|
|
DispatchQueue.main.async {
|
|
sself.coordinatorDelegate?.keyBackupSetupPassphraseViewModel(sself, didCreateBackupFromRecoveryKey: megolmBackupCreationInfo.recoveryKey)
|
|
}
|
|
}
|
|
}, failure: { (error) in
|
|
self?.update(viewState: .error(error))
|
|
})
|
|
}, failure: { [weak self] error in
|
|
self?.update(viewState: .error(error))
|
|
})
|
|
}
|
|
|
|
private func updatePassphraseStrength() {
|
|
self.passphraseStrength = self.passwordStrength(for: self.passphrase)
|
|
}
|
|
|
|
private func passwordStrength(for password: String?) -> PasswordStrength {
|
|
guard let password = password else {
|
|
return .tooGuessable
|
|
}
|
|
return self.passwordStrengthManager.passwordStrength(for: password)
|
|
}
|
|
|
|
private func update(viewState: KeyBackupSetupPassphraseViewState) {
|
|
self.viewDelegate?.keyBackupSetupPassphraseViewModel(self, didUpdateViewState: viewState)
|
|
}
|
|
}
|