element-ios/Riot/Modules/Secrets/Recover/RecoverWithKey/SecretsRecoveryWithKeyViewM...

99 lines
3.0 KiB
Swift

/*
Copyright 2020-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 SecretsRecoveryWithKeyViewModel: SecretsRecoveryWithKeyViewModelType {
// MARK: - Properties
// MARK: Private
private let recoveryService: MXRecoveryService
private let dehydrationService: DehydrationService?
// MARK: Public
let recoveryGoal: SecretsRecoveryGoal
var recoveryKey: String?
var isFormValid: Bool {
return self.recoveryKey?.isEmpty == false
}
weak var viewDelegate: SecretsRecoveryWithKeyViewModelViewDelegate?
weak var coordinatorDelegate: SecretsRecoveryWithKeyViewModelCoordinatorDelegate?
// MARK: - Setup
init(recoveryService: MXRecoveryService, recoveryGoal: SecretsRecoveryGoal, dehydrationService: DehydrationService?) {
self.recoveryService = recoveryService
self.dehydrationService = dehydrationService
self.recoveryGoal = recoveryGoal
}
// MARK: - Public
func process(viewAction: SecretsRecoveryWithKeyViewAction) {
switch viewAction {
case .recover:
self.recover()
case .resetSecrets:
self.coordinatorDelegate?.secretsRecoveryWithKeyViewModelWantsToResetSecrets(self)
case .cancel:
self.coordinatorDelegate?.secretsRecoveryWithKeyViewModelDidCancel(self)
}
}
// MARK: - Private
private func recover() {
guard let recoveryKey = self.recoveryKey else {
return
}
self.update(viewState: .loading)
do {
let secretIds: [String]?
if case SecretsRecoveryGoal.keyBackup = self.recoveryGoal {
secretIds = [MXSecretId.keyBackup.takeUnretainedValue() as String]
} else {
secretIds = nil
}
let privateKey = try self.recoveryService.privateKey(fromRecoveryKey: recoveryKey)
self.recoveryService.recoverSecrets(secretIds, withPrivateKey: privateKey, recoverServices: true, success: { [weak self] _ in
guard let self = self else {
return
}
self.update(viewState: .loaded)
self.coordinatorDelegate?.secretsRecoveryWithKeyViewModelDidRecover(self)
Task {
await self.dehydrationService?.runDeviceDehydrationFlow(privateKeyData: privateKey)
}
}, failure: { [weak self] error in
guard let self = self else {
return
}
self.update(viewState: .error(error))
})
} catch {
self.update(viewState: .error(error))
}
}
private func update(viewState: SecretsRecoveryWithKeyViewState) {
self.viewDelegate?.secretsRecoveryWithKeyViewModel(self, didUpdateViewState: viewState)
}
}