Skip to content

Commit

Permalink
Restore icloud Backup
Browse files Browse the repository at this point in the history
- Fix delete cloud backup after local backup
- Fix some bugs
  • Loading branch information
ant013 committed May 31, 2023
1 parent 3695bc2 commit 4b03679
Show file tree
Hide file tree
Showing 36 changed files with 989 additions and 138 deletions.
118 changes: 91 additions & 27 deletions UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "no internet@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "no internet@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ extension BackupCryptoHelper {
return Crypto.sha3(data)
}

public static func valid(macHex: String, pass: String, message: Data, kdf: KdfParams) throws -> Bool {
public static func isValid(macHex: String, pass: String, message: Data, kdf: KdfParams) throws -> Bool {
let sha3 = try mac(pass: pass, message: message, kdf: kdf)
return macHex == sha3.hs.hex
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import UIKit
import ThemeKit
import HsToolKit

class BackupCloudModule {
static let minimumPassphraseLength = 8

static func backupTerms(account: Account) -> UIViewController {
let service = ICloudBackupTermsService(account: account)
let viewModel = ICloudBackupTermsViewModel(service: service)
let controller = ICloudBackupTermsViewController(viewModel: viewModel)

return ThemeNavigationController(rootViewController: controller)
}

static func backupName(account: Account) -> UIViewController {
let service = ICloudBackupNameService(iCloudManager: App.shared.cloudAccountBackupManager, account: account)
let viewModel = ICloudBackupNameViewModel(service: service)
let controller = ICloudBackupNameViewController(viewModel: viewModel)

return controller
}

static func backupPassword(account: Account, name: String) -> UIViewController {
let service = BackupCloudPassphraseService(iCloudManager: App.shared.cloudAccountBackupManager, account: account, name: name)
let viewModel = BackupCloudPassphraseViewModel(service: service)
let controller = BackupCloudPassphraseViewController(viewModel: viewModel)

return controller
}

}

extension BackupCloudModule {

enum PassphraseCharacterSet: CaseIterable {
case lowerCased
case upperCased
case digits
case customSymbols

var set: CharacterSet {
switch self {
case .upperCased: return CharacterSet.uppercaseLetters
case .lowerCased: return CharacterSet.lowercaseLetters
case .digits: return CharacterSet.decimalDigits
case .customSymbols: return CharacterSet(charactersIn: " '\"`&/?!:;.,~*$=+-[](){}<>\\_#@|%")
}
}

func contains(_ string: String) -> Bool {
string.rangeOfCharacter(from: set) != nil
}
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class ICloudBackupNameViewController: KeyboardAwareViewController {
return
}

let controller = ICloudBackupModule.backupPassword(account: viewModel.account, name: name)
let controller = BackupCloudModule.backupPassword(account: viewModel.account, name: name)
navigationController?.pushViewController(controller, animated: true)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import Foundation

class ICloudBackupPassphraseService {
private let minimumPassphraseLength = 8

class BackupCloudPassphraseService {
private let iCloudManager: CloudAccountBackupManager
private let account: Account
private let name: String
Expand All @@ -18,7 +16,7 @@ class ICloudBackupPassphraseService {

}

extension ICloudBackupPassphraseService {
extension BackupCloudPassphraseService {

func validate(text: String?) -> Bool {
PassphraseValidator.validate(text: text)
Expand All @@ -29,8 +27,13 @@ extension ICloudBackupPassphraseService {
throw CreateError.emptyPassphrase
}

guard passphrase.count >= minimumPassphraseLength else {
throw CreateError.tooShort
guard passphrase.count >= BackupCloudModule.minimumPassphraseLength else {
throw CreateError.simplePassword
}

let allSatisfy = BackupCloudModule.PassphraseCharacterSet.allCases.allSatisfy { set in set.contains(passphrase) }
if !allSatisfy {
throw CreateError.simplePassword
}

guard passphrase == passphraseConfirmation else {
Expand All @@ -49,11 +52,11 @@ extension ICloudBackupPassphraseService {

}

extension ICloudBackupPassphraseService {
extension BackupCloudPassphraseService {

enum CreateError: Error {
case emptyPassphrase
case tooShort
case simplePassword
case invalidConfirmation
case urlNotAvailable
case cantSaveFile(Error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import ComponentKit
import SectionsTableView
import UIExtensions

class ICloudBackupPassphraseViewController: KeyboardAwareViewController {
class BackupCloudPassphraseViewController: KeyboardAwareViewController {
private let wrapperViewHeight: CGFloat = .margin16 + .heightButton + .margin32

private let viewModel: ICloudBackupPassphraseViewModel
private let viewModel: BackupCloudPassphraseViewModel
private var cancellables = Set<AnyCancellable>()

private let tableView = SectionsTableView(style: .grouped)
Expand All @@ -28,7 +28,7 @@ class ICloudBackupPassphraseViewController: KeyboardAwareViewController {
private var keyboardShown = false
private var isLoaded = false

init(viewModel: ICloudBackupPassphraseViewModel) {
init(viewModel: BackupCloudPassphraseViewModel) {
self.viewModel = viewModel

super.init(scrollViews: [tableView], accessoryView: gradientWrapperView)
Expand Down Expand Up @@ -164,7 +164,7 @@ class ICloudBackupPassphraseViewController: KeyboardAwareViewController {

}

extension ICloudBackupPassphraseViewController: SectionsDataSource {
extension BackupCloudPassphraseViewController: SectionsDataSource {

func buildSections() -> [SectionProtocol] {
[
Expand Down Expand Up @@ -236,7 +236,7 @@ extension ICloudBackupPassphraseViewController: SectionsDataSource {

}

extension ICloudBackupPassphraseViewController: IDynamicHeightCellDelegate {
extension BackupCloudPassphraseViewController: IDynamicHeightCellDelegate {

func onChangeHeight() {
guard isLoaded else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import Combine
import Foundation
import HsExtensions

class ICloudBackupPassphraseViewModel {
class BackupCloudPassphraseViewModel {
private var cancellables = Set<AnyCancellable>()

private let service: ICloudBackupPassphraseService
private let service: BackupCloudPassphraseService
@Published public var passphraseCaution: Caution?
@Published public var passphraseConfirmationCaution: Caution?

private let clearInputsSubject = PassthroughSubject<Void, Never>()
private let showErrorSubject = PassthroughSubject<String, Never>()
private let finishSubject = PassthroughSubject<Void, Never>()

init(service: ICloudBackupPassphraseService) {
init(service: BackupCloudPassphraseService) {
self.service = service
}

Expand All @@ -29,7 +29,7 @@ class ICloudBackupPassphraseViewModel {

}

extension ICloudBackupPassphraseViewModel {
extension BackupCloudPassphraseViewModel {

var clearInputsPublisher: AnyPublisher<Void, Never> {
clearInputsSubject.eraseToAnyPublisher()
Expand Down Expand Up @@ -78,18 +78,17 @@ extension ICloudBackupPassphraseViewModel {
try await service.createBackup()
finishSubject.send(())
} catch {
switch (error as? ICloudBackupPassphraseService.CreateError) {
switch (error as? BackupCloudPassphraseService.CreateError) {
case .emptyPassphrase:
passphraseCaution = Caution(text: "backup.cloud.password.error.empty_passphrase".localized, type: .error)
case .tooShort:
passphraseCaution = Caution(text: "backup.cloud.password.error.minimum_required".localized, type: .error)
case .simplePassword:
passphraseCaution = Caution(text: "backup.cloud.password.error.minimum_requirement".localized, type: .error)
case .invalidConfirmation:
passphraseConfirmationCaution = Caution(text: "backup.cloud.password.confirm.error.doesnt_match".localized, type: .error)
case .urlNotAvailable:
showErrorSubject.send("backup.cloud.not_available".localized)
case .cantSaveFile(let error):
case .cantSaveFile:
showErrorSubject.send("backup.cloud.cant_create_file".localized)
print("Has Error while try save file: \(error)")
case .none:
showErrorSubject.send(error.smartDescription)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class ICloudBackupTermsViewController: ThemeViewController {
}

@objc private func onTapContinue() {
let controller = ICloudBackupModule.backupName(account: viewModel.account)
let controller = BackupCloudModule.backupName(account: viewModel.account)
navigationController?.pushViewController(controller, animated: true)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class BackupViewController: ThemeViewController {
}

@objc private func onTapVerify() {
guard let viewController = BackupVerifyWordsModule.viewController(account: viewModel.account) else {
guard let viewController = BackupVerifyWordsModule.viewController(account: viewModel.account, onComplete: onComplete) else {
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension BottomSheetModule {
image: .local(image: UIImage(named: "warning_2_24")?.withTintColor(.themeJacob)),
title: "backup_prompt.title".localized,
items: [
.highlightedDescription(text: "F".localized)
.highlightedDescription(text: "backup_prompt.warning".localized)
],
buttons: [
.init(style: .yellow, title: "backup_prompt.backup_manual".localized, imageName: "edit_24", actionType: .afterClose) { [weak sourceViewController] in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ class ManageAccountViewController: KeyboardAwareViewController {
subscribe(disposeBag, viewModel.openUnlockSignal) { [weak self] in self?.openUnlock() }
subscribe(disposeBag, viewModel.openRecoveryPhraseSignal) { [weak self] in self?.openRecoveryPhrase(account: $0) }
subscribe(disposeBag, viewModel.openBackupSignal) { [weak self] in self?.openBackup(account: $0) }
subscribe(disposeBag, viewModel.openBackupAndDeleteCloudSignal) { [weak self] in
self?.openBackup(account: $0) { [weak self] in
self?.deleteCloudBackup()
}
}
subscribe(disposeBag, viewModel.openCloudBackupSignal) { [weak self] in self?.openCloudBackup(account: $0) }
subscribe(disposeBag, viewModel.confirmDeleteCloudBackupSignal) { [weak self] in self?.confirmDeleteCloudBackup(manualBackedUp: $0) }
subscribe(disposeBag, viewModel.cloudBackupDeletedSignal) { [weak self] in self?.cloudBackupDeleted($0) }
Expand Down Expand Up @@ -127,7 +132,7 @@ class ManageAccountViewController: KeyboardAwareViewController {
}

private func openBackup(account: Account, onComplete: (() -> ())? = nil) {
guard let viewController = BackupModule.manualViewController(account: account) else {
guard let viewController = BackupModule.manualViewController(account: account, onComplete: onComplete) else {
return
}

Expand All @@ -153,6 +158,10 @@ class ManageAccountViewController: KeyboardAwareViewController {
}
}

private func deleteCloudBackup() {
viewModel.deleteCloudBackup()
}

private func cloudBackupDeleted(_ successful: Bool) {
if successful {
HudHelper.instance.show(banner: .deleted)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class ManageAccountViewModel {
private let openUnlockRelay = PublishRelay<()>()
private let openRecoveryPhraseRelay = PublishRelay<Account>()
private let openBackupRelay = PublishRelay<Account>()
private let openBackupAndDeleteCloudRelay = PublishRelay<Account>()
private let openCloudBackupRelay = PublishRelay<Account>()
private let confirmDeleteCloudBackupRelay = PublishRelay<Bool>()
private let cloudBackupDeletedRelay = PublishRelay<Bool>()
Expand Down Expand Up @@ -48,7 +49,9 @@ class ManageAccountViewModel {
backupActions.append(.backup(isCloudBackedUp: isCloudBackedUp))
}

backupActions.append(.cloudBackedUp(isCloudBackedUp, manualBackedUp: account.backedUp))
if !account.watchAccount {
backupActions.append(.cloudBackedUp(isCloudBackedUp, manualBackedUp: account.backedUp))
}

guard account.backedUp || isCloudBackedUp else {
return [backupActions]
Expand Down Expand Up @@ -107,6 +110,10 @@ extension ManageAccountViewModel {
openBackupRelay.asSignal()
}

var openBackupAndDeleteCloudSignal: Signal<Account> {
openBackupAndDeleteCloudRelay.asSignal()
}

var openCloudBackupSignal: Signal<Account> {
openCloudBackupRelay.asSignal()
}
Expand Down Expand Up @@ -139,6 +146,7 @@ extension ManageAccountViewModel {
switch unlockRequest {
case .recoveryPhrase: openRecoveryPhraseRelay.accept(service.account)
case .backup: openBackupRelay.accept(service.account)
case .backupAndDeleteCloud: openBackupAndDeleteCloudRelay.accept(service.account)
}
}

Expand Down Expand Up @@ -176,7 +184,13 @@ extension ManageAccountViewModel {
}

func deleteCloudBackupAfterManualBackup() {
onTapBackup()
if service.isPinSet {
unlockRequest = .backupAndDeleteCloud
openUnlockRelay.accept(())
} else {
openBackupAndDeleteCloudRelay.accept(service.account)
}

}


Expand Down Expand Up @@ -204,6 +218,7 @@ extension ManageAccountViewModel {
enum UnlockRequest {
case recoveryPhrase
case backup
case backupAndDeleteCloud
}

enum KeyAction {
Expand Down
Loading

0 comments on commit 4b03679

Please sign in to comment.