From 55c1d9e48e3c9f5809fb2f1bd60c58cbac511e8b Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Mon, 30 Jul 2018 16:52:45 +0300 Subject: [PATCH 01/16] Add generic passwork checker before sending transaction --- .../LockEnterPasscodeCoordinator.swift | 11 ++++++++- .../ConfirmPaymentViewController.swift | 23 +++++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift b/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift index e4531b3872..5125911ba7 100644 --- a/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift +++ b/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift @@ -2,6 +2,8 @@ import UIKit +typealias UnlockResult = ((_ success: Bool, _ bioUnlock: Bool) -> Void) + final class LockEnterPasscodeCoordinator: Coordinator { var coordinators: [Coordinator] = [] let window: UIWindow = UIWindow() @@ -10,23 +12,30 @@ final class LockEnterPasscodeCoordinator: Coordinator { private lazy var lockEnterPasscodeViewController: LockEnterPasscodeViewController = { return LockEnterPasscodeViewController(model: model) }() + private var waitForUnlockResult: UnlockResult? init(model: LockEnterPasscodeViewModel, lock: LockInterface = Lock()) { self.window.windowLevel = UIWindowLevelStatusBar + 1.0 self.model = model self.lock = lock lockEnterPasscodeViewController.unlockWithResult = { [weak self] (state, bioUnlock) in + self?.waitForUnlockResult?(state, bioUnlock) if state { self?.stop() } } } - func start() { + func start(unlockResult: UnlockResult? = nil) { guard lock.shouldShowProtection() else { return } window.rootViewController = lockEnterPasscodeViewController window.makeKeyAndVisible() + + if let unlockResult = unlockResult { + lockEnterPasscodeViewController.unlockWithResult = unlockResult + } } + //This method should be refactored!!! func showAuthentication() { guard window.isKeyWindow, lock.isPasscodeSet() else { diff --git a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift index 0c7500241e..b391705c36 100644 --- a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift +++ b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift @@ -23,6 +23,9 @@ class ConfirmPaymentViewController: UIViewController { lazy var sendTransactionCoordinator = { return SendTransactionCoordinator(session: self.session, keystore: keystore, confirmType: confirmType, server: server) }() + lazy var confirmEnterPasscodeCoordinator: LockEnterPasscodeCoordinator = { + return LockEnterPasscodeCoordinator(model: LockEnterPasscodeViewModel()) + }() lazy var submitButton: UIButton = { let button = Button(size: .large, style: .solid) button.translatesAutoresizingMaskIntoConstraints = false @@ -207,13 +210,19 @@ class ConfirmPaymentViewController: UIViewController { } @objc func send() { - self.displayLoading() - - let transaction = configurator.signTransaction - self.sendTransactionCoordinator.send(transaction: transaction) { [weak self] result in - guard let `self` = self else { return } - self.didCompleted?(result) - self.hideLoading() + confirmEnterPasscodeCoordinator.start { [weak self] (success, _) in + if success { + self?.displayLoading() + + guard let transaction = self?.configurator.signTransaction else { + return + } + self?.sendTransactionCoordinator.send(transaction: transaction) { [weak self] result in + guard let `self` = self else { return } + self.didCompleted?(result) + self.hideLoading() + } + } } } } From 644a594e0057d9efc83c9a7b08331250fcdc3086 Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Tue, 31 Jul 2018 10:22:45 +0300 Subject: [PATCH 02/16] Use AuthenticateUserCoordinator --- .../AuthenticateUserCoordinator.swift | 12 ++++-- .../LockEnterPasscodeCoordinator.swift | 14 ++----- .../LockEnterPasscodeViewController.swift | 4 +- .../Coordinators/ConfirmCoordinator.swift | 18 ++++++++- .../ConfirmPaymentViewController.swift | 37 ++++++++++--------- 5 files changed, 52 insertions(+), 33 deletions(-) diff --git a/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift b/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift index 39d3b7e4ff..edb7433505 100644 --- a/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift +++ b/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift @@ -5,6 +5,7 @@ import Foundation final class AuthenticateUserCoordinator: Coordinator { var coordinators: [Coordinator] = [] + private var waitForUnlockResult: UnlockResult? let navigationController: NavigationController private let model: LockEnterPasscodeViewModel private let lock: LockInterface @@ -21,17 +22,22 @@ final class AuthenticateUserCoordinator: Coordinator { self.model = model self.lock = lock - lockEnterPasscodeViewController.unlockWithResult = { [weak self] (state, bioUnlock) in - if state { + lockEnterPasscodeViewController.unlockWithResult = { [weak self] (success, bioUnlock) in + self?.waitForUnlockResult?(success, bioUnlock) + if success { self?.stop() } } } - func start() { + func start(unlockResult: UnlockResult? = nil) { guard lock.shouldShowProtection() else { return } navigationController.present(lockEnterPasscodeViewController, animated: true) + + if let unlockResult = unlockResult { + lockEnterPasscodeViewController.unlockWithResult = unlockResult + } } func showAuthentication() { diff --git a/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift b/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift index 5125911ba7..f1a2b91aba 100644 --- a/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift +++ b/Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift @@ -2,8 +2,6 @@ import UIKit -typealias UnlockResult = ((_ success: Bool, _ bioUnlock: Bool) -> Void) - final class LockEnterPasscodeCoordinator: Coordinator { var coordinators: [Coordinator] = [] let window: UIWindow = UIWindow() @@ -12,28 +10,22 @@ final class LockEnterPasscodeCoordinator: Coordinator { private lazy var lockEnterPasscodeViewController: LockEnterPasscodeViewController = { return LockEnterPasscodeViewController(model: model) }() - private var waitForUnlockResult: UnlockResult? init(model: LockEnterPasscodeViewModel, lock: LockInterface = Lock()) { self.window.windowLevel = UIWindowLevelStatusBar + 1.0 self.model = model self.lock = lock - lockEnterPasscodeViewController.unlockWithResult = { [weak self] (state, bioUnlock) in - self?.waitForUnlockResult?(state, bioUnlock) - if state { + lockEnterPasscodeViewController.unlockWithResult = { [weak self] (success, bioUnlock) in + if success { self?.stop() } } } - func start(unlockResult: UnlockResult? = nil) { + func start() { guard lock.shouldShowProtection() else { return } window.rootViewController = lockEnterPasscodeViewController window.makeKeyAndVisible() - - if let unlockResult = unlockResult { - lockEnterPasscodeViewController.unlockWithResult = unlockResult - } } //This method should be refactored!!! diff --git a/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift b/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift index 1583fe39fa..9695c65390 100644 --- a/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift +++ b/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift @@ -3,11 +3,13 @@ import UIKit import LocalAuthentication +typealias UnlockResult = ((_ success: Bool, _ bioUnlock: Bool) -> Void) + final class LockEnterPasscodeViewController: LockPasscodeViewController { private lazy var lockEnterPasscodeViewModel: LockEnterPasscodeViewModel = { return self.model as! LockEnterPasscodeViewModel }() - var unlockWithResult: ((_ success: Bool, _ bioUnlock: Bool) -> Void)? + var unlockWithResult: UnlockResult? private var context: LAContext! override func viewDidLoad() { super.viewDidLoad() diff --git a/Trust/Transfer/Coordinators/ConfirmCoordinator.swift b/Trust/Transfer/Coordinators/ConfirmCoordinator.swift index 89d6771a24..2fa08d38af 100644 --- a/Trust/Transfer/Coordinators/ConfirmCoordinator.swift +++ b/Trust/Transfer/Coordinators/ConfirmCoordinator.swift @@ -27,6 +27,10 @@ final class ConfirmCoordinator: RootCoordinator { return controller } + private lazy var authenticateUserCoordinator: AuthenticateUserCoordinator = { + return AuthenticateUserCoordinator(navigationController: navigationController) + }() + private lazy var controller: ConfirmPaymentViewController = { return ConfirmPaymentViewController( session: session, @@ -55,7 +59,8 @@ final class ConfirmCoordinator: RootCoordinator { self.type = type self.server = server - controller.didCompleted = { [weak self] result in + controller.delegate = self + controller.didComplete = { [weak self] result in guard let `self` = self else { return } switch result { case .success(let data): @@ -76,3 +81,14 @@ final class ConfirmCoordinator: RootCoordinator { delegate?.didCancel(in: self) } } + +extension ConfirmCoordinator: ConfirmPaymentAuthenticationDelegate { + func confirmPaymentControllerNeedsAuthentication(_ controller: ConfirmPaymentViewController) { + authenticateUserCoordinator.start { [weak self] (success, _) in + if success { + self?.controller.sendTransaction() + self?.authenticateUserCoordinator.stop() + } + } + } +} diff --git a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift index b391705c36..8bff2f406a 100644 --- a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift +++ b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift @@ -16,16 +16,18 @@ enum ConfirmResult { case sentTransaction(SentTransaction) } +protocol ConfirmPaymentAuthenticationDelegate: class { + func confirmPaymentControllerNeedsAuthentication(_ controller: ConfirmPaymentViewController) +} + class ConfirmPaymentViewController: UIViewController { private let keystore: Keystore let session: WalletSession + public weak var delegate: ConfirmPaymentAuthenticationDelegate? lazy var sendTransactionCoordinator = { return SendTransactionCoordinator(session: self.session, keystore: keystore, confirmType: confirmType, server: server) }() - lazy var confirmEnterPasscodeCoordinator: LockEnterPasscodeCoordinator = { - return LockEnterPasscodeCoordinator(model: LockEnterPasscodeViewModel()) - }() lazy var submitButton: UIButton = { let button = Button(size: .large, style: .solid) button.translatesAutoresizingMaskIntoConstraints = false @@ -40,7 +42,7 @@ class ConfirmPaymentViewController: UIViewController { var configurator: TransactionConfigurator let confirmType: ConfirmType let server: RPCServer - var didCompleted: ((Result) -> Void)? + var didComplete: ((Result) -> Void)? lazy var stackView: UIStackView = { let stackView = UIStackView() @@ -210,19 +212,20 @@ class ConfirmPaymentViewController: UIViewController { } @objc func send() { - confirmEnterPasscodeCoordinator.start { [weak self] (success, _) in - if success { - self?.displayLoading() - - guard let transaction = self?.configurator.signTransaction else { - return - } - self?.sendTransactionCoordinator.send(transaction: transaction) { [weak self] result in - guard let `self` = self else { return } - self.didCompleted?(result) - self.hideLoading() - } - } + if true { + delegate?.confirmPaymentControllerNeedsAuthentication(self) + } else { + sendTransaction() + } + } + + public func sendTransaction() { + self.displayLoading() + let transaction = self.configurator.signTransaction + self.sendTransactionCoordinator.send(transaction: transaction) { [weak self] result in + guard let `self` = self else { return } + self.didComplete?(result) + self.hideLoading() } } } From a323fef602739eb18d9538e6778a39d5e1e52f96 Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Tue, 31 Jul 2018 12:01:16 +0300 Subject: [PATCH 03/16] Add properly in user defaults. Implemented functionality of checking passcode. --- Trust/Settings/Types/PreferenceOption.swift | 2 ++ .../SettingsViewController.swift | 13 ++++++++++++ .../ViewModels/SettingsViewModel.swift | 20 +++++++++++++++++++ .../ConfirmPaymentViewController.swift | 7 ++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Trust/Settings/Types/PreferenceOption.swift b/Trust/Settings/Types/PreferenceOption.swift index 0a90ecb826..51c7b1c785 100644 --- a/Trust/Settings/Types/PreferenceOption.swift +++ b/Trust/Settings/Types/PreferenceOption.swift @@ -6,12 +6,14 @@ enum PreferenceOption { case airdropNotifications case browserSearchEngine case testNetworks + case isPasscodeTransactionLockEnabled var key: String { switch self { case .airdropNotifications: return "airdropNotifications" case .browserSearchEngine: return "browserSearchEngine" case .testNetworks: return "browserSearchEngine" + case .isPasscodeTransactionLockEnabled: return "isPasscodeTransactionLockEnabled" } } } diff --git a/Trust/Settings/ViewControllers/SettingsViewController.swift b/Trust/Settings/ViewControllers/SettingsViewController.swift index c9743a2a04..7e730c1fd7 100644 --- a/Trust/Settings/ViewControllers/SettingsViewController.swift +++ b/Trust/Settings/ViewControllers/SettingsViewController.swift @@ -16,6 +16,7 @@ final class SettingsViewController: FormViewController, Coordinator { static let currencyPopularKey = "0" static let currencyAllKey = "1" static let passcodeRow = "PasscodeRow" + static let passcodeTransactionLockRow = "PasscodeTransactionLockRow" } private var config = Config() @@ -97,6 +98,18 @@ final class SettingsViewController: FormViewController, Coordinator { cell.imageView?.image = R.image.settings_colorful_security() } + <<< SwitchRow(Values.passcodeTransactionLockRow) { [weak self] in + $0.title = self?.viewModel.verifyTransactionsWithPasscodeTitle + $0.value = self?.viewModel.isPasscodeTransactionLockEnabled + }.onChange { [unowned self] row in + if let value = row.value { + self.viewModel.isPasscodeTransactionLockEnabled = value + row.updateCell() + } + }.cellSetup { cell, _ in + cell.imageView?.image = R.image.settings_colorful_security() + } + <<< autoLockRow <<< AppFormAppearance.button { [weak self] row in diff --git a/Trust/Settings/ViewModels/SettingsViewModel.swift b/Trust/Settings/ViewModels/SettingsViewModel.swift index a08ee969a6..29e8189f64 100644 --- a/Trust/Settings/ViewModels/SettingsViewModel.swift +++ b/Trust/Settings/ViewModels/SettingsViewModel.swift @@ -48,6 +48,26 @@ struct SettingsViewModel { } } + var isPasscodeTransactionLockEnabled: Bool { + get { + let option = PreferenceOption.isPasscodeTransactionLockEnabled + guard let boolValue = PreferencesController() + .get(for: option.key) as? Bool else { + PreferencesController().set(value: false, for: option) + return false + } + return boolValue + } + set { + PreferencesController().set(value: newValue, for: PreferenceOption.isPasscodeTransactionLockEnabled) + } + } + + var verifyTransactionsWithPasscodeTitle: String { + return "Lock Transactions" +// return NSLocalizedString("settings.verifyTransactions.label.title", value: "Verify Transactions with Passcode", comment: "") + } + var networkTitle: String { return NSLocalizedString("settings.network.button.title", value: "Network", comment: "") } diff --git a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift index 8bff2f406a..43bfd438fa 100644 --- a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift +++ b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift @@ -212,7 +212,12 @@ class ConfirmPaymentViewController: UIViewController { } @objc func send() { - if true { + guard let needsPasscodeCheck = PreferencesController() + .get(for: PreferenceOption.isPasscodeTransactionLockEnabled.key) as? Bool else { + return + } + + if needsPasscodeCheck { delegate?.confirmPaymentControllerNeedsAuthentication(self) } else { sendTransaction() From 863d4448677a81fccb37a4db074a7fec6dceba9e Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Tue, 31 Jul 2018 12:33:43 +0300 Subject: [PATCH 04/16] Add protocol for view model in LockEnterPasscodeViewController --- .../AuthenticateUserCoordinator.swift | 4 ++-- .../LockEnterPasscodeViewController.swift | 4 ++-- .../AuthenticateEnterPasscodeViewModel.swift | 16 ++++++++++++++++ .../EnterPasscodeViewModelInterface.swift | 9 +++++++++ .../ViewModels/LockEnterPasscodeViewModel.swift | 14 ++++++++++---- 5 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift create mode 100644 Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift diff --git a/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift b/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift index edb7433505..fe5570de7a 100644 --- a/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift +++ b/Trust/Lock/Coordinators/AuthenticateUserCoordinator.swift @@ -7,7 +7,7 @@ final class AuthenticateUserCoordinator: Coordinator { var coordinators: [Coordinator] = [] private var waitForUnlockResult: UnlockResult? let navigationController: NavigationController - private let model: LockEnterPasscodeViewModel + private let model: AuthenticateEnterPasscodeViewModel private let lock: LockInterface private lazy var lockEnterPasscodeViewController: LockEnterPasscodeViewController = { return LockEnterPasscodeViewController(model: model) @@ -15,7 +15,7 @@ final class AuthenticateUserCoordinator: Coordinator { init( navigationController: NavigationController, - model: LockEnterPasscodeViewModel = LockEnterPasscodeViewModel(), + model: AuthenticateEnterPasscodeViewModel = AuthenticateEnterPasscodeViewModel(), lock: LockInterface = Lock() ) { self.navigationController = navigationController diff --git a/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift b/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift index 9695c65390..afd37e50a2 100644 --- a/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift +++ b/Trust/Lock/ViewControllers/LockEnterPasscodeViewController.swift @@ -6,8 +6,8 @@ import LocalAuthentication typealias UnlockResult = ((_ success: Bool, _ bioUnlock: Bool) -> Void) final class LockEnterPasscodeViewController: LockPasscodeViewController { - private lazy var lockEnterPasscodeViewModel: LockEnterPasscodeViewModel = { - return self.model as! LockEnterPasscodeViewModel + private lazy var lockEnterPasscodeViewModel: EnterPasscodeViewModelInterface = { + return self.model as! EnterPasscodeViewModelInterface }() var unlockWithResult: UnlockResult? private var context: LAContext! diff --git a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift new file mode 100644 index 0000000000..26f16e28d6 --- /dev/null +++ b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift @@ -0,0 +1,16 @@ +// Copyright DApps Platform Inc. All rights reserved. + +import Foundation + +final class AuthenticateEnterPasscodeViewModel: LockViewModel, EnterPasscodeViewModelInterface { + var initialLabelText: String { + return NSLocalizedString("lock.enter.passcode.view.model.initial", value: "Enter your passcode.", comment: "") + } + var tryAfterOneMinute: String { + return NSLocalizedString("lock.enter.passcode.view.model.try.after.one.minute", value: "Try after 1 minute.", comment: "") + } + var loginReason: String { + return "Authenticating with Touch ID" + // let loginReason = NSLocalizedString("lock.enter.passcode.view.model.touch.id", value: "Logging in with Touch ID", comment: "") + } +} diff --git a/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift b/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift new file mode 100644 index 0000000000..daf1c70695 --- /dev/null +++ b/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift @@ -0,0 +1,9 @@ +// Copyright DApps Platform Inc. All rights reserved. + +import Foundation + +protocol EnterPasscodeViewModelInterface: class { + var initialLabelText: String { get } + var tryAfterOneMinute: String { get } + var loginReason: String { get } +} diff --git a/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift index 6f12ceb5d5..17fcb6b71a 100644 --- a/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift @@ -2,8 +2,14 @@ import UIKit -final class LockEnterPasscodeViewModel: LockViewModel { - let initialLabelText = NSLocalizedString("lock.enter.passcode.view.model.initial", value: "Enter your passcode.", comment: "") - let tryAfterOneMinute = NSLocalizedString("lock.enter.passcode.view.model.try.after.one.minute", value: "Try after 1 minute.", comment: "") - let loginReason = NSLocalizedString("lock.enter.passcode.view.model.touch.id", value: "Logging in with Touch ID", comment: "") +final class LockEnterPasscodeViewModel: LockViewModel, EnterPasscodeViewModelInterface { + var initialLabelText: String { + return NSLocalizedString("lock.enter.passcode.view.model.initial", value: "Enter your passcode.", comment: "") + } + var tryAfterOneMinute: String { + return NSLocalizedString("lock.enter.passcode.view.model.try.after.one.minute", value: "Try after 1 minute.", comment: "") + } + var loginReason: String { + return NSLocalizedString("lock.enter.passcode.view.model.touch.id", value: "Logging in with Touch ID", comment: "") + } } From 3f990bca1052666f608b7458f67636563457d17f Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Tue, 31 Jul 2018 12:34:33 +0300 Subject: [PATCH 05/16] Add new files in folder hierarchy --- Trust.xcodeproj/project.pbxproj | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Trust.xcodeproj/project.pbxproj b/Trust.xcodeproj/project.pbxproj index bed3577573..4133a4f606 100644 --- a/Trust.xcodeproj/project.pbxproj +++ b/Trust.xcodeproj/project.pbxproj @@ -251,6 +251,8 @@ 61FC5ECF1FCFBAE500CCB12A /* EtherNumberFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FC5ECE1FCFBAE500CCB12A /* EtherNumberFormatter.swift */; }; 61FC5ED11FCFBDEB00CCB12A /* EtherNumberFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FC5ED01FCFBDEB00CCB12A /* EtherNumberFormatterTests.swift */; }; 664D11A12007D59F0041A0B0 /* EstimateGasRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664D11A02007D59F0041A0B0 /* EstimateGasRequest.swift */; }; + 71684E5521105E4200D8FD4B /* AuthenticateEnterPasscodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71684E5421105E4200D8FD4B /* AuthenticateEnterPasscodeViewModel.swift */; }; + 71684E5721105F3E00D8FD4B /* EnterPasscodeViewModelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71684E5621105F3E00D8FD4B /* EnterPasscodeViewModelInterface.swift */; }; 7301BA9220A3117000E1AFE5 /* AutoLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7301BA9120A3117000E1AFE5 /* AutoLock.swift */; }; 7301BA9620AB1E5600E1AFE5 /* CookiesStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7301BA9520AB1E5600E1AFE5 /* CookiesStore.swift */; }; 7302405C204C65DF00B327DF /* NonFungibleTokenCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7302405B204C65DF00B327DF /* NonFungibleTokenCategory.swift */; }; @@ -746,6 +748,8 @@ 61FC5ED01FCFBDEB00CCB12A /* EtherNumberFormatterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EtherNumberFormatterTests.swift; sourceTree = ""; }; 646C8C822C986358D7388602 /* Pods_Trust.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Trust.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 664D11A02007D59F0041A0B0 /* EstimateGasRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EstimateGasRequest.swift; sourceTree = ""; }; + 71684E5421105E4200D8FD4B /* AuthenticateEnterPasscodeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticateEnterPasscodeViewModel.swift; sourceTree = ""; }; + 71684E5621105F3E00D8FD4B /* EnterPasscodeViewModelInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterPasscodeViewModelInterface.swift; sourceTree = ""; }; 7301BA9120A3117000E1AFE5 /* AutoLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoLock.swift; sourceTree = ""; }; 7301BA9520AB1E5600E1AFE5 /* CookiesStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookiesStore.swift; sourceTree = ""; }; 7302405B204C65DF00B327DF /* NonFungibleTokenCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonFungibleTokenCategory.swift; sourceTree = ""; }; @@ -2099,8 +2103,8 @@ 73ACEEF720163B4E003DD71D /* Coordinators */ = { isa = PBXGroup; children = ( - 73ACEF0420163F46003DD71D /* LockEnterPasscodeCoordinator.swift */, 73C41C74201B65AD00243C6C /* LockCreatePasscodeCoordinator.swift */, + 73ACEF0420163F46003DD71D /* LockEnterPasscodeCoordinator.swift */, 772C6DBA210A842200FCE4F1 /* AuthenticateUserCoordinator.swift */, ); path = Coordinators; @@ -2120,8 +2124,10 @@ isa = PBXGroup; children = ( 73ACEF0020163ED4003DD71D /* LockViewModel.swift */, - 73C41C70201B46AD00243C6C /* LockEnterPasscodeViewModel.swift */, 73C41C72201B5EFF00243C6C /* LockCreatePasscodeViewModel.swift */, + 73C41C70201B46AD00243C6C /* LockEnterPasscodeViewModel.swift */, + 71684E5421105E4200D8FD4B /* AuthenticateEnterPasscodeViewModel.swift */, + 71684E5621105F3E00D8FD4B /* EnterPasscodeViewModelInterface.swift */, ); path = ViewModels; sourceTree = ""; @@ -2919,6 +2925,7 @@ 29E14FDB1F7F4F3D00185568 /* Transaction.swift in Sources */, 7712437A20FD97730097296E /* WalletAccountViewModel.swift in Sources */, BBF4F9B72029D0B3009E04C0 /* GasViewModel.swift in Sources */, + 71684E5721105F3E00D8FD4B /* EnterPasscodeViewModelInterface.swift in Sources */, 73C41C75201B65AD00243C6C /* LockCreatePasscodeCoordinator.swift in Sources */, 7301BA9220A3117000E1AFE5 /* AutoLock.swift in Sources */, 296106C81F7646590006164B /* TokensViewModel.swift in Sources */, @@ -3015,6 +3022,7 @@ 90DDF48520518AE50016E6D4 /* BookmarkViewModel.swift in Sources */, BBB61E122050993A00428BBD /* BrowserErrorView.swift in Sources */, 29C80D4B1FB51C460037B1E0 /* Decimal.swift in Sources */, + 71684E5521105E4200D8FD4B /* AuthenticateEnterPasscodeViewModel.swift in Sources */, 297800521F71FDCF003185C1 /* FormAppearance.swift in Sources */, 77B3BF3C201908ED00EEC15A /* ConfirmCoordinator.swift in Sources */, 7704837020FFD2F700837735 /* TransactionsViewController.swift in Sources */, From ea7bf5223ba2acbe660d5c64abea0ce4b4ab600d Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Tue, 31 Jul 2018 12:42:08 +0300 Subject: [PATCH 06/16] Add localized string for lock.authenticate.enter.passcode.view.model.touch.id --- Trust/Localization/de.lproj/Localizable.strings | 1 + Trust/Localization/en.lproj/Localizable.strings | 1 + Trust/Localization/fr.lproj/Localizable.strings | 1 + Trust/Localization/ja.lproj/Localizable.strings | 1 + Trust/Localization/vi.lproj/Localizable.strings | 1 + Trust/Localization/zh-Hans.lproj/Localizable.strings | 1 + Trust/Localization/zh-Hant.lproj/Localizable.strings | 1 + Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift | 3 +-- 8 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Trust/Localization/de.lproj/Localizable.strings b/Trust/Localization/de.lproj/Localizable.strings index de8690342a..ff06fca412 100644 --- a/Trust/Localization/de.lproj/Localizable.strings +++ b/Trust/Localization/de.lproj/Localizable.strings @@ -142,6 +142,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Falsche PIN. Sie haben %d Versuche."; "lock.enter.passcode.view.model.initial" = "Geben Sie Ihre PIN ein"; "lock.enter.passcode.view.model.touch.id" = "Mit Touch ID anmelden"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentifizieren mit Touch ID" "lock.enter.passcode.view.model.try.after.one.minute" = "Versuchen Sie es in 1 Minute erneut"; "Name" = "Name"; "send.action.copy.transaction.title" = "Transaktions-ID kopieren"; diff --git a/Trust/Localization/en.lproj/Localizable.strings b/Trust/Localization/en.lproj/Localizable.strings index ed6a36eb60..a0a0c0f41d 100644 --- a/Trust/Localization/en.lproj/Localizable.strings +++ b/Trust/Localization/en.lproj/Localizable.strings @@ -142,6 +142,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Incorrect passcode. You have %li attempts left."; "lock.enter.passcode.view.model.initial" = "Enter your passcode."; "lock.enter.passcode.view.model.touch.id" = "Logging in with Touch ID"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "Authenticating with Touch ID" "lock.enter.passcode.view.model.try.after.one.minute" = "Try after 1 minute."; "Name" = "Name"; "send.action.copy.transaction.title" = "Copy Transaction ID"; diff --git a/Trust/Localization/fr.lproj/Localizable.strings b/Trust/Localization/fr.lproj/Localizable.strings index 0764796806..11713718c4 100644 --- a/Trust/Localization/fr.lproj/Localizable.strings +++ b/Trust/Localization/fr.lproj/Localizable.strings @@ -142,6 +142,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Code d'accès incorrect. Il vous reste %li tentatives."; "lock.enter.passcode.view.model.initial" = "Entrez votre code d'accès."; "lock.enter.passcode.view.model.touch.id" = "Se connecter avec Touch ID"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentification avec Touch ID" "lock.enter.passcode.view.model.try.after.one.minute" = "Essayez après 1 minute."; "Name" = "Nom"; "send.action.copy.transaction.title" = "Copier l'ID de transaction"; diff --git a/Trust/Localization/ja.lproj/Localizable.strings b/Trust/Localization/ja.lproj/Localizable.strings index bca22132e3..23caf07e00 100644 --- a/Trust/Localization/ja.lproj/Localizable.strings +++ b/Trust/Localization/ja.lproj/Localizable.strings @@ -142,6 +142,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "パスコードが間違っています。残り%li回試行できます。"; "lock.enter.passcode.view.model.initial" = "パスコードを入力してください。"; "lock.enter.passcode.view.model.touch.id" = "Touch IDでログイン"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "タッチIDによる認証" "lock.enter.passcode.view.model.try.after.one.minute" = "1分後に試してください。"; "Name" = "名称"; "send.action.copy.transaction.title" = "トランザクション ID をコピー"; diff --git a/Trust/Localization/vi.lproj/Localizable.strings b/Trust/Localization/vi.lproj/Localizable.strings index c5d5c8c764..02e5c80908 100644 --- a/Trust/Localization/vi.lproj/Localizable.strings +++ b/Trust/Localization/vi.lproj/Localizable.strings @@ -142,6 +142,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Mật mã không chính xác. Bạn còn %d lần thử."; "lock.enter.passcode.view.model.initial" = "Nhập mã khóa của bạn."; "lock.enter.passcode.view.model.touch.id" = "Đăng nhập bằng Vân tay"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "Xác thực bằng ID cảm ứng" "lock.enter.passcode.view.model.try.after.one.minute" = "Thử lại sau 1 phút."; "Name" = "Tên"; "send.action.copy.transaction.title" = "Sao chép ID giao dịch"; diff --git a/Trust/Localization/zh-Hans.lproj/Localizable.strings b/Trust/Localization/zh-Hans.lproj/Localizable.strings index 6e17588c7c..3ec927d138 100644 --- a/Trust/Localization/zh-Hans.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hans.lproj/Localizable.strings @@ -142,6 +142,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "密码不正确。你还有 %d 次尝试机会。"; "lock.enter.passcode.view.model.initial" = "请输入密码。"; "lock.enter.passcode.view.model.touch.id" = "使用 Touch ID 登录"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID进行身份验证" "lock.enter.passcode.view.model.try.after.one.minute" = "请1分钟后再试。"; "Name" = "名称"; "send.action.copy.transaction.title" = "复制交易 ID"; diff --git a/Trust/Localization/zh-Hant.lproj/Localizable.strings b/Trust/Localization/zh-Hant.lproj/Localizable.strings index b0f5d85349..63cbe3f313 100644 --- a/Trust/Localization/zh-Hant.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hant.lproj/Localizable.strings @@ -143,6 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "密碼不正確。你還有 %d 次嘗試機會。"; "lock.enter.passcode.view.model.initial" = "請輸入密碼。"; "lock.enter.passcode.view.model.touch.id" = "使用 Touch ID 登錄"; +"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID進行身份驗證" "lock.enter.passcode.view.model.try.after.one.minute" = "請1分鐘後再試。"; "Name" = "名稱"; "send.action.copy.transaction.title" = "複製交易 ID"; diff --git a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift index 26f16e28d6..f4aee2fe66 100644 --- a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift @@ -10,7 +10,6 @@ final class AuthenticateEnterPasscodeViewModel: LockViewModel, EnterPasscodeView return NSLocalizedString("lock.enter.passcode.view.model.try.after.one.minute", value: "Try after 1 minute.", comment: "") } var loginReason: String { - return "Authenticating with Touch ID" - // let loginReason = NSLocalizedString("lock.enter.passcode.view.model.touch.id", value: "Logging in with Touch ID", comment: "") + return NSLocalizedString("lock.authenticate.enter.passcode.view.model.touch.id", value: "Authenticating with Touch ID", comment: "") } } From 947a1582459be7d619cf0cf777f17359df32a833 Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Tue, 31 Jul 2018 12:50:58 +0300 Subject: [PATCH 07/16] Add localized strings for settings.lockTransactions.label.title --- Trust/Localization/ar.lproj/Localizable.strings | 1 + Trust/Localization/de.lproj/Localizable.strings | 1 + Trust/Localization/en.lproj/Localizable.strings | 1 + Trust/Localization/es.lproj/Localizable.strings | 1 + Trust/Localization/fr.lproj/Localizable.strings | 1 + Trust/Localization/it.lproj/Localizable.strings | 1 + Trust/Localization/ja.lproj/Localizable.strings | 1 + Trust/Localization/ru.lproj/Localizable.strings | 1 + Trust/Localization/vi.lproj/Localizable.strings | 1 + Trust/Localization/zh-Hans.lproj/Localizable.strings | 1 + Trust/Localization/zh-Hant.lproj/Localizable.strings | 1 + Trust/Settings/ViewModels/SettingsViewModel.swift | 3 +-- 12 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Trust/Localization/ar.lproj/Localizable.strings b/Trust/Localization/ar.lproj/Localizable.strings index fd90552e15..065bda1b4c 100644 --- a/Trust/Localization/ar.lproj/Localizable.strings +++ b/Trust/Localization/ar.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "ردود الفعل موثوقة"; "settings.navigation.title" = "الإعدادات"; "settings.network.button.title" = "شبكة"; +"settings.lockTransactions.label.title" = "توثيق المعاملات"; "settings.openSourceDevelopment.label.title" = "تطوير المصادر المفتوحة"; "settings.privacyPolicy.button.title" = "سياسة الخصوصية"; "settings.pushNotifications.button.title" = "دفع الإخطارات"; diff --git a/Trust/Localization/de.lproj/Localizable.strings b/Trust/Localization/de.lproj/Localizable.strings index ff06fca412..ebc8fbca2f 100644 --- a/Trust/Localization/de.lproj/Localizable.strings +++ b/Trust/Localization/de.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Trust Feedback"; "settings.navigation.title" = "Einstellungen"; "settings.network.button.title" = "Netzwerk"; +"settings.lockTransactions.label.title" = "Transaktionen authentifizieren"; "settings.openSourceDevelopment.label.title" = "Open-Source-Entwicklung"; "settings.privacyPolicy.button.title" = "Datenschutzbestimmungen"; "settings.pushNotifications.button.title" = "Push-Benachrichtigungen"; diff --git a/Trust/Localization/en.lproj/Localizable.strings b/Trust/Localization/en.lproj/Localizable.strings index a0a0c0f41d..11e98d4c6a 100644 --- a/Trust/Localization/en.lproj/Localizable.strings +++ b/Trust/Localization/en.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Trust Feedback"; "settings.navigation.title" = "Settings"; "settings.network.button.title" = "Network"; +"settings.lockTransactions.label.title" = "Authenticate Transactions"; "settings.openSourceDevelopment.label.title" = "Open Source Development"; "settings.privacyPolicy.button.title" = "Privacy Policy"; "settings.pushNotifications.button.title" = "Push Notifications"; diff --git a/Trust/Localization/es.lproj/Localizable.strings b/Trust/Localization/es.lproj/Localizable.strings index d20e67b913..dda6e44cce 100644 --- a/Trust/Localization/es.lproj/Localizable.strings +++ b/Trust/Localization/es.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Comentarios sobre Trust"; "settings.navigation.title" = "Configuración"; "settings.network.button.title" = "Red"; +"settings.lockTransactions.label.title" = "Autenticar transacciones"; "settings.openSourceDevelopment.label.title" = "Desarrollo en abierto"; "settings.privacyPolicy.button.title" = "Política de privacidad"; "settings.pushNotifications.button.title" = "Notificaciones Push"; diff --git a/Trust/Localization/fr.lproj/Localizable.strings b/Trust/Localization/fr.lproj/Localizable.strings index 11713718c4..a957e71692 100644 --- a/Trust/Localization/fr.lproj/Localizable.strings +++ b/Trust/Localization/fr.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Commentaires sur la confiance"; "settings.navigation.title" = "Paramètres"; "settings.network.button.title" = "Réseau"; +"settings.lockTransactions.label.title" = "Authentifier les transactions"; "settings.openSourceDevelopment.label.title" = "Développement Open Source"; "settings.privacyPolicy.button.title" = "Politique de confidentialité"; "settings.pushNotifications.button.title" = "Notifications push"; diff --git a/Trust/Localization/it.lproj/Localizable.strings b/Trust/Localization/it.lproj/Localizable.strings index e09691381d..61c6ed5b07 100644 --- a/Trust/Localization/it.lproj/Localizable.strings +++ b/Trust/Localization/it.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Trust Feedback"; "settings.navigation.title" = "Impostazioni"; "settings.network.button.title" = "Rete"; +"settings.lockTransactions.label.title" = "Autenticare le transazioni"; "settings.openSourceDevelopment.label.title" = "Sviluppo open source"; "settings.privacyPolicy.button.title" = "Politica sulla privacy"; "settings.pushNotifications.button.title" = "Notifiche push"; diff --git a/Trust/Localization/ja.lproj/Localizable.strings b/Trust/Localization/ja.lproj/Localizable.strings index 23caf07e00..8ec2c4e335 100644 --- a/Trust/Localization/ja.lproj/Localizable.strings +++ b/Trust/Localization/ja.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Trust フィードバック"; "settings.navigation.title" = "設定"; "settings.network.button.title" = "ネットワーク"; +"settings.lockTransactions.label.title" = "トランザクションの認証"; "settings.openSourceDevelopment.label.title" = "オープンソース開発"; "settings.privacyPolicy.button.title" = "個人情報保護方針"; "settings.pushNotifications.button.title" = "プッシュ通知"; diff --git a/Trust/Localization/ru.lproj/Localizable.strings b/Trust/Localization/ru.lproj/Localizable.strings index 6f5f03e5a5..364e8d17a6 100644 --- a/Trust/Localization/ru.lproj/Localizable.strings +++ b/Trust/Localization/ru.lproj/Localizable.strings @@ -60,6 +60,7 @@ "settings.feedback.email.title" = "Обратная связь "; "settings.navigation.title" = "Настройки"; "settings.network.button.title" = "Сеть"; +"settings.lockTransactions.label.title" = "Аутентификация транзакций"; "settings.openSourceDevelopment.label.title" = "Разработка с открытым исходным кодом"; "settings.privacyPolicy.button.title" = "Политика Конфиденциальности"; "settings.pushNotifications.button.title" = "Push-Уведомления"; diff --git a/Trust/Localization/vi.lproj/Localizable.strings b/Trust/Localization/vi.lproj/Localizable.strings index 02e5c80908..9d97c57b91 100644 --- a/Trust/Localization/vi.lproj/Localizable.strings +++ b/Trust/Localization/vi.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Phản hồi tới Trust"; "settings.navigation.title" = "Cài đặt"; "settings.network.button.title" = "Mạng lưới"; +"settings.lockTransactions.label.title" = "Xác thực giao dịch"; "settings.openSourceDevelopment.label.title" = "Phát triển nguồn mở"; "settings.privacyPolicy.button.title" = "Chính sách bảo mật"; "settings.pushNotifications.button.title" = "Các thông báo đẩy"; diff --git a/Trust/Localization/zh-Hans.lproj/Localizable.strings b/Trust/Localization/zh-Hans.lproj/Localizable.strings index 3ec927d138..3dbb75bc7c 100644 --- a/Trust/Localization/zh-Hans.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hans.lproj/Localizable.strings @@ -59,6 +59,7 @@ "settings.feedback.email.title" = "Trust 反馈"; "settings.navigation.title" = "设置"; "settings.network.button.title" = "网络"; +"settings.lockTransactions.label.title" = "验证交易"; "settings.openSourceDevelopment.label.title" = "开源式开发"; "settings.privacyPolicy.button.title" = "隐私政策"; "settings.pushNotifications.button.title" = "推送通知"; diff --git a/Trust/Localization/zh-Hant.lproj/Localizable.strings b/Trust/Localization/zh-Hant.lproj/Localizable.strings index 63cbe3f313..bf7e60a08b 100644 --- a/Trust/Localization/zh-Hant.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hant.lproj/Localizable.strings @@ -60,6 +60,7 @@ "settings.feedback.email.title" = "Trust 反饋"; "settings.navigation.title" = "設置"; "settings.network.button.title" = "網絡"; +"settings.lockTransactions.label.title" = "驗證交易"; "settings.openSourceDevelopment.label.title" = "開源式開發"; "settings.privacyPolicy.button.title" = "隱私政策"; "settings.pushNotifications.button.title" = "推送通知"; diff --git a/Trust/Settings/ViewModels/SettingsViewModel.swift b/Trust/Settings/ViewModels/SettingsViewModel.swift index 29e8189f64..336a519929 100644 --- a/Trust/Settings/ViewModels/SettingsViewModel.swift +++ b/Trust/Settings/ViewModels/SettingsViewModel.swift @@ -64,8 +64,7 @@ struct SettingsViewModel { } var verifyTransactionsWithPasscodeTitle: String { - return "Lock Transactions" -// return NSLocalizedString("settings.verifyTransactions.label.title", value: "Verify Transactions with Passcode", comment: "") + return NSLocalizedString("settings.lockTransactions.label.title", value: "Authenticate Transactions", comment: "") } var networkTitle: String { From 86c17c3e3382528bb3aa630a06016c95abe7766e Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Thu, 2 Aug 2018 11:22:48 +0300 Subject: [PATCH 08/16] Check if user needs to confirm with a password on Coordinator level --- .../Coordinators/ConfirmCoordinator.swift | 16 ++++++++++++---- .../ConfirmPaymentViewController.swift | 11 +---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Trust/Transfer/Coordinators/ConfirmCoordinator.swift b/Trust/Transfer/Coordinators/ConfirmCoordinator.swift index 2fa08d38af..f9712cb80d 100644 --- a/Trust/Transfer/Coordinators/ConfirmCoordinator.swift +++ b/Trust/Transfer/Coordinators/ConfirmCoordinator.swift @@ -84,11 +84,19 @@ final class ConfirmCoordinator: RootCoordinator { extension ConfirmCoordinator: ConfirmPaymentAuthenticationDelegate { func confirmPaymentControllerNeedsAuthentication(_ controller: ConfirmPaymentViewController) { - authenticateUserCoordinator.start { [weak self] (success, _) in - if success { - self?.controller.sendTransaction() - self?.authenticateUserCoordinator.stop() + guard let needsPasscodeCheck = PreferencesController() + .get(for: PreferenceOption.isPasscodeTransactionLockEnabled.key) as? Bool else { + return + } + if needsPasscodeCheck { + authenticateUserCoordinator.start { [weak self] (success, _) in + if success { + self?.controller.sendTransaction() + self?.authenticateUserCoordinator.stop() + } } + } else { + self.controller.sendTransaction() } } } diff --git a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift index 43bfd438fa..185de3d4ea 100644 --- a/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift +++ b/Trust/Transfer/ViewControllers/ConfirmPaymentViewController.swift @@ -212,16 +212,7 @@ class ConfirmPaymentViewController: UIViewController { } @objc func send() { - guard let needsPasscodeCheck = PreferencesController() - .get(for: PreferenceOption.isPasscodeTransactionLockEnabled.key) as? Bool else { - return - } - - if needsPasscodeCheck { - delegate?.confirmPaymentControllerNeedsAuthentication(self) - } else { - sendTransaction() - } + delegate?.confirmPaymentControllerNeedsAuthentication(self) } public func sendTransaction() { From 15f678bfb41171a8998457cdf949a80ec9c1f9ae Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Thu, 2 Aug 2018 11:59:41 +0300 Subject: [PATCH 09/16] Use R.string.localizable. Fix issue with Localizable files --- Trust/Localization/de.lproj/Localizable.strings | 2 +- Trust/Localization/en.lproj/Localizable.strings | 2 +- Trust/Localization/fr.lproj/Localizable.strings | 2 +- Trust/Localization/ja.lproj/Localizable.strings | 2 +- Trust/Localization/vi.lproj/Localizable.strings | 2 +- Trust/Localization/zh-Hans.lproj/Localizable.strings | 2 +- Trust/Localization/zh-Hant.lproj/Localizable.strings | 2 +- .../ViewModels/AuthenticateEnterPasscodeViewModel.swift | 6 +++--- Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift | 6 +++--- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Trust/Localization/de.lproj/Localizable.strings b/Trust/Localization/de.lproj/Localizable.strings index ebc8fbca2f..319c80e95f 100644 --- a/Trust/Localization/de.lproj/Localizable.strings +++ b/Trust/Localization/de.lproj/Localizable.strings @@ -143,7 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Falsche PIN. Sie haben %d Versuche."; "lock.enter.passcode.view.model.initial" = "Geben Sie Ihre PIN ein"; "lock.enter.passcode.view.model.touch.id" = "Mit Touch ID anmelden"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentifizieren mit Touch ID" +"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentifizieren mit Touch ID"; "lock.enter.passcode.view.model.try.after.one.minute" = "Versuchen Sie es in 1 Minute erneut"; "Name" = "Name"; "send.action.copy.transaction.title" = "Transaktions-ID kopieren"; diff --git a/Trust/Localization/en.lproj/Localizable.strings b/Trust/Localization/en.lproj/Localizable.strings index 11e98d4c6a..36606a6eae 100644 --- a/Trust/Localization/en.lproj/Localizable.strings +++ b/Trust/Localization/en.lproj/Localizable.strings @@ -143,7 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Incorrect passcode. You have %li attempts left."; "lock.enter.passcode.view.model.initial" = "Enter your passcode."; "lock.enter.passcode.view.model.touch.id" = "Logging in with Touch ID"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Authenticating with Touch ID" +"lock.authenticate.enter.passcode.view.model.touch.id" = "Authenticating with Touch ID"; "lock.enter.passcode.view.model.try.after.one.minute" = "Try after 1 minute."; "Name" = "Name"; "send.action.copy.transaction.title" = "Copy Transaction ID"; diff --git a/Trust/Localization/fr.lproj/Localizable.strings b/Trust/Localization/fr.lproj/Localizable.strings index a957e71692..a6e2fab0a7 100644 --- a/Trust/Localization/fr.lproj/Localizable.strings +++ b/Trust/Localization/fr.lproj/Localizable.strings @@ -143,7 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Code d'accès incorrect. Il vous reste %li tentatives."; "lock.enter.passcode.view.model.initial" = "Entrez votre code d'accès."; "lock.enter.passcode.view.model.touch.id" = "Se connecter avec Touch ID"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentification avec Touch ID" +"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentification avec Touch ID"; "lock.enter.passcode.view.model.try.after.one.minute" = "Essayez après 1 minute."; "Name" = "Nom"; "send.action.copy.transaction.title" = "Copier l'ID de transaction"; diff --git a/Trust/Localization/ja.lproj/Localizable.strings b/Trust/Localization/ja.lproj/Localizable.strings index 8ec2c4e335..085c4c40f6 100644 --- a/Trust/Localization/ja.lproj/Localizable.strings +++ b/Trust/Localization/ja.lproj/Localizable.strings @@ -143,7 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "パスコードが間違っています。残り%li回試行できます。"; "lock.enter.passcode.view.model.initial" = "パスコードを入力してください。"; "lock.enter.passcode.view.model.touch.id" = "Touch IDでログイン"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "タッチIDによる認証" +"lock.authenticate.enter.passcode.view.model.touch.id" = "タッチIDによる認証"; "lock.enter.passcode.view.model.try.after.one.minute" = "1分後に試してください。"; "Name" = "名称"; "send.action.copy.transaction.title" = "トランザクション ID をコピー"; diff --git a/Trust/Localization/vi.lproj/Localizable.strings b/Trust/Localization/vi.lproj/Localizable.strings index 9d97c57b91..fc6562ef8f 100644 --- a/Trust/Localization/vi.lproj/Localizable.strings +++ b/Trust/Localization/vi.lproj/Localizable.strings @@ -143,7 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Mật mã không chính xác. Bạn còn %d lần thử."; "lock.enter.passcode.view.model.initial" = "Nhập mã khóa của bạn."; "lock.enter.passcode.view.model.touch.id" = "Đăng nhập bằng Vân tay"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Xác thực bằng ID cảm ứng" +"lock.authenticate.enter.passcode.view.model.touch.id" = "Xác thực bằng ID cảm ứng"; "lock.enter.passcode.view.model.try.after.one.minute" = "Thử lại sau 1 phút."; "Name" = "Tên"; "send.action.copy.transaction.title" = "Sao chép ID giao dịch"; diff --git a/Trust/Localization/zh-Hans.lproj/Localizable.strings b/Trust/Localization/zh-Hans.lproj/Localizable.strings index 3dbb75bc7c..c00aa23971 100644 --- a/Trust/Localization/zh-Hans.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hans.lproj/Localizable.strings @@ -143,7 +143,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "密码不正确。你还有 %d 次尝试机会。"; "lock.enter.passcode.view.model.initial" = "请输入密码。"; "lock.enter.passcode.view.model.touch.id" = "使用 Touch ID 登录"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID进行身份验证" +"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID进行身份验证"; "lock.enter.passcode.view.model.try.after.one.minute" = "请1分钟后再试。"; "Name" = "名称"; "send.action.copy.transaction.title" = "复制交易 ID"; diff --git a/Trust/Localization/zh-Hant.lproj/Localizable.strings b/Trust/Localization/zh-Hant.lproj/Localizable.strings index bf7e60a08b..d52198a97c 100644 --- a/Trust/Localization/zh-Hant.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hant.lproj/Localizable.strings @@ -144,7 +144,7 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "密碼不正確。你還有 %d 次嘗試機會。"; "lock.enter.passcode.view.model.initial" = "請輸入密碼。"; "lock.enter.passcode.view.model.touch.id" = "使用 Touch ID 登錄"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID進行身份驗證" +"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID進行身份驗證"; "lock.enter.passcode.view.model.try.after.one.minute" = "請1分鐘後再試。"; "Name" = "名稱"; "send.action.copy.transaction.title" = "複製交易 ID"; diff --git a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift index f4aee2fe66..5e102a4338 100644 --- a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift @@ -4,12 +4,12 @@ import Foundation final class AuthenticateEnterPasscodeViewModel: LockViewModel, EnterPasscodeViewModelInterface { var initialLabelText: String { - return NSLocalizedString("lock.enter.passcode.view.model.initial", value: "Enter your passcode.", comment: "") + return R.string.localizable.lockEnterPasscodeViewModelInitial() } var tryAfterOneMinute: String { - return NSLocalizedString("lock.enter.passcode.view.model.try.after.one.minute", value: "Try after 1 minute.", comment: "") + return R.string.localizable.lockEnterPasscodeViewModelTryAfterOneMinute() } var loginReason: String { - return NSLocalizedString("lock.authenticate.enter.passcode.view.model.touch.id", value: "Authenticating with Touch ID", comment: "") + return R.string.localizable.lockAuthenticateEnterPasscodeViewModelTouchId() } } diff --git a/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift index 17fcb6b71a..96f50e7d6f 100644 --- a/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift @@ -4,12 +4,12 @@ import UIKit final class LockEnterPasscodeViewModel: LockViewModel, EnterPasscodeViewModelInterface { var initialLabelText: String { - return NSLocalizedString("lock.enter.passcode.view.model.initial", value: "Enter your passcode.", comment: "") + return R.string.localizable.lockEnterPasscodeViewModelInitial() } var tryAfterOneMinute: String { - return NSLocalizedString("lock.enter.passcode.view.model.try.after.one.minute", value: "Try after 1 minute.", comment: "") + return R.string.localizable.lockEnterPasscodeViewModelTryAfterOneMinute() } var loginReason: String { - return NSLocalizedString("lock.enter.passcode.view.model.touch.id", value: "Logging in with Touch ID", comment: "") + return R.string.localizable.lockEnterPasscodeViewModelTouchId() } } From ef83945536d981bb40bce517d96d07dc4705fe5b Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Thu, 2 Aug 2018 12:02:39 +0300 Subject: [PATCH 10/16] Change LockCreatePasscodeViewModel to use R.string.localizable --- Trust/Lock/ViewModels/LockCreatePasscodeViewModel.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Trust/Lock/ViewModels/LockCreatePasscodeViewModel.swift b/Trust/Lock/ViewModels/LockCreatePasscodeViewModel.swift index 956e343062..e2a5fa7f0d 100644 --- a/Trust/Lock/ViewModels/LockCreatePasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/LockCreatePasscodeViewModel.swift @@ -3,7 +3,7 @@ import UIKit final class LockCreatePasscodeViewModel: LockViewModel { - let title = NSLocalizedString("lock.create.passcode.view.model.title", value: "Set Passcode", comment: "") - let initialLabelText = NSLocalizedString("lock.create.passcode.view.model.initial", value: "Enter a new passcode", comment: "") - let confirmLabelText = NSLocalizedString("lock.create.passcode.view.model.confirm", value: "Please re-enter your passcode", comment: "") + let title = R.string.localizable.lockCreatePasscodeViewModelTitle() + let initialLabelText = R.string.localizable.lockCreatePasscodeViewModelInitial() + let confirmLabelText = R.string.localizable.lockCreatePasscodeViewModelConfirm() } From f1d62afd5792ecf3479af857df295f84c676e711 Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Thu, 2 Aug 2018 12:08:06 +0300 Subject: [PATCH 11/16] Remove duplication --- .../AuthenticateEnterPasscodeViewModel.swift | 6 ------ .../ViewModels/EnterPasscodeViewModelInterface.swift | 11 +++++++++-- .../Lock/ViewModels/LockEnterPasscodeViewModel.swift | 6 ------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift index 5e102a4338..0d8f666394 100644 --- a/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/AuthenticateEnterPasscodeViewModel.swift @@ -3,12 +3,6 @@ import Foundation final class AuthenticateEnterPasscodeViewModel: LockViewModel, EnterPasscodeViewModelInterface { - var initialLabelText: String { - return R.string.localizable.lockEnterPasscodeViewModelInitial() - } - var tryAfterOneMinute: String { - return R.string.localizable.lockEnterPasscodeViewModelTryAfterOneMinute() - } var loginReason: String { return R.string.localizable.lockAuthenticateEnterPasscodeViewModelTouchId() } diff --git a/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift b/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift index daf1c70695..68bd2a6181 100644 --- a/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift +++ b/Trust/Lock/ViewModels/EnterPasscodeViewModelInterface.swift @@ -3,7 +3,14 @@ import Foundation protocol EnterPasscodeViewModelInterface: class { - var initialLabelText: String { get } - var tryAfterOneMinute: String { get } var loginReason: String { get } } + +extension EnterPasscodeViewModelInterface { + var initialLabelText: String { + return R.string.localizable.lockEnterPasscodeViewModelInitial() + } + var tryAfterOneMinute: String { + return R.string.localizable.lockEnterPasscodeViewModelTryAfterOneMinute() + } +} diff --git a/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift b/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift index 96f50e7d6f..431302a9d6 100644 --- a/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift +++ b/Trust/Lock/ViewModels/LockEnterPasscodeViewModel.swift @@ -3,12 +3,6 @@ import UIKit final class LockEnterPasscodeViewModel: LockViewModel, EnterPasscodeViewModelInterface { - var initialLabelText: String { - return R.string.localizable.lockEnterPasscodeViewModelInitial() - } - var tryAfterOneMinute: String { - return R.string.localizable.lockEnterPasscodeViewModelTryAfterOneMinute() - } var loginReason: String { return R.string.localizable.lockEnterPasscodeViewModelTouchId() } From bef4c80ada76912e6717b68a039489d50b5bfddb Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Thu, 2 Aug 2018 12:51:24 +0300 Subject: [PATCH 12/16] Passcode protect transaction option only visible if passcode lock is set --- .../SettingsViewController.swift | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/Trust/Settings/ViewControllers/SettingsViewController.swift b/Trust/Settings/ViewControllers/SettingsViewController.swift index 7e730c1fd7..2e39da8b84 100644 --- a/Trust/Settings/ViewControllers/SettingsViewController.swift +++ b/Trust/Settings/ViewControllers/SettingsViewController.swift @@ -59,6 +59,23 @@ final class SettingsViewController: FormViewController, Coordinator { } }() + lazy var passcodeTransactionLockRow: SwitchRow = { + return SwitchRow(Values.passcodeTransactionLockRow) { [weak self] in + $0.title = self?.viewModel.verifyTransactionsWithPasscodeTitle + $0.value = self?.viewModel.isPasscodeTransactionLockEnabled + $0.hidden = Condition.function([Values.passcodeRow], { form in + return !((form.rowBy(tag: Values.passcodeRow) as? SwitchRow)?.value ?? false) + }) + }.onChange { [unowned self] row in + if let value = row.value { + self.viewModel.isPasscodeTransactionLockEnabled = value + row.updateCell() + } + }.cellSetup { cell, _ in + cell.imageView?.image = R.image.settings_colorful_security() + } + }() + let session: WalletSession let keystore: Keystore @@ -93,22 +110,13 @@ final class SettingsViewController: FormViewController, Coordinator { } else { self.lock.deletePasscode() self.updateAutoLockRow(with: AutoLock.immediate) + self.updatePasscodeTransactionLockRow(enabled: false) } }.cellSetup { cell, _ in cell.imageView?.image = R.image.settings_colorful_security() } - <<< SwitchRow(Values.passcodeTransactionLockRow) { [weak self] in - $0.title = self?.viewModel.verifyTransactionsWithPasscodeTitle - $0.value = self?.viewModel.isPasscodeTransactionLockEnabled - }.onChange { [unowned self] row in - if let value = row.value { - self.viewModel.isPasscodeTransactionLockEnabled = value - row.updateCell() - } - }.cellSetup { cell, _ in - cell.imageView?.image = R.image.settings_colorful_security() - } + <<< passcodeTransactionLockRow <<< autoLockRow @@ -341,6 +349,12 @@ final class SettingsViewController: FormViewController, Coordinator { self.autoLockRow.reload() } + private func updatePasscodeTransactionLockRow(enabled: Bool) { + self.viewModel.isPasscodeTransactionLockEnabled = enabled + self.passcodeTransactionLockRow.value = enabled + self.passcodeTransactionLockRow.reload() + } + func run(action: SettingsAction) { delegate?.didAction(action: action, in: self) } From 9faf26ba9ad3bda83d9170ba85f8576c658ecd2a Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Thu, 2 Aug 2018 21:15:20 +0300 Subject: [PATCH 13/16] Fix localizable string. Remove 'self'. Add general reference to passcodeRow. --- .../SettingsViewController.swift | 18 +++++++++++------- .../ViewModels/SettingsViewModel.swift | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Trust/Settings/ViewControllers/SettingsViewController.swift b/Trust/Settings/ViewControllers/SettingsViewController.swift index 2e39da8b84..b642de2a4e 100644 --- a/Trust/Settings/ViewControllers/SettingsViewController.swift +++ b/Trust/Settings/ViewControllers/SettingsViewController.swift @@ -29,6 +29,10 @@ final class SettingsViewController: FormViewController, Coordinator { return lock.isPasscodeSet() } + var passcodeRow: SwitchRow? { + return form.rowBy(tag: Values.passcodeRow) as? SwitchRow + } + lazy var viewModel: SettingsViewModel = { return SettingsViewModel(isDebug: isDebug) }() @@ -45,8 +49,8 @@ final class SettingsViewController: FormViewController, Coordinator { $0.displayValueFor = { value in return value?.displayName } - $0.hidden = Condition.function([Values.passcodeRow], { form in - return !((form.rowBy(tag: Values.passcodeRow) as? SwitchRow)?.value ?? false) + $0.hidden = Condition.function([Values.passcodeRow], { [weak self] form in + return !(self?.passcodeRow?.value ?? false) }) }.onChange { [weak self] row in let autoLockType = row.value ?? AutoLock.immediate @@ -63,8 +67,8 @@ final class SettingsViewController: FormViewController, Coordinator { return SwitchRow(Values.passcodeTransactionLockRow) { [weak self] in $0.title = self?.viewModel.verifyTransactionsWithPasscodeTitle $0.value = self?.viewModel.isPasscodeTransactionLockEnabled - $0.hidden = Condition.function([Values.passcodeRow], { form in - return !((form.rowBy(tag: Values.passcodeRow) as? SwitchRow)?.value ?? false) + $0.hidden = Condition.function([Values.passcodeRow], { [weak self] form in + return !(self?.passcodeRow?.value ?? false) }) }.onChange { [unowned self] row in if let value = row.value { @@ -350,9 +354,9 @@ final class SettingsViewController: FormViewController, Coordinator { } private func updatePasscodeTransactionLockRow(enabled: Bool) { - self.viewModel.isPasscodeTransactionLockEnabled = enabled - self.passcodeTransactionLockRow.value = enabled - self.passcodeTransactionLockRow.reload() + viewModel.isPasscodeTransactionLockEnabled = enabled + passcodeTransactionLockRow.value = enabled + passcodeTransactionLockRow.reload() } func run(action: SettingsAction) { diff --git a/Trust/Settings/ViewModels/SettingsViewModel.swift b/Trust/Settings/ViewModels/SettingsViewModel.swift index 336a519929..47cbfffa9a 100644 --- a/Trust/Settings/ViewModels/SettingsViewModel.swift +++ b/Trust/Settings/ViewModels/SettingsViewModel.swift @@ -64,7 +64,7 @@ struct SettingsViewModel { } var verifyTransactionsWithPasscodeTitle: String { - return NSLocalizedString("settings.lockTransactions.label.title", value: "Authenticate Transactions", comment: "") + return R.string.localizable.settingsLockTransactionsLabelTitle() } var networkTitle: String { From d453f524a7a05c5bc81e879f7a4440bbe2ac0b22 Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Fri, 3 Aug 2018 10:28:20 +0300 Subject: [PATCH 14/16] Change user defaults to keychain --- Trust/Lock/Lock.swift | 18 ++++++++++++++++++ Trust/Settings/Types/PreferenceOption.swift | 2 -- .../SettingsViewController.swift | 10 +++++----- .../ViewModels/SettingsViewModel.swift | 15 --------------- .../Coordinators/ConfirmCoordinator.swift | 5 +---- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/Trust/Lock/Lock.swift b/Trust/Lock/Lock.swift index 82120f68ad..7ef007d08d 100644 --- a/Trust/Lock/Lock.swift +++ b/Trust/Lock/Lock.swift @@ -7,6 +7,7 @@ import KeychainSwift protocol LockInterface { func isPasscodeSet() -> Bool func shouldShowProtection() -> Bool + func shouldAuthorizeTransactions() -> Bool } final class Lock: LockInterface { @@ -20,12 +21,17 @@ final class Lock: LockInterface { private let maxAttemptTime = "maxAttemptTime" private let autoLockType = "autoLockType" private let autoLockTime = "autoLockTime" + private let authorizeTransactions = "authorizeTransactions" private let keychain = KeychainSwift(keyPrefix: Constants.keychainKeyPrefix) func shouldShowProtection() -> Bool { return isPasscodeSet() && autoLockTriggered() } + func shouldAuthorizeTransactions() -> Bool { + return isPasscodeSet() && authorizeTransactionsValue() + } + func isPasscodeSet() -> Bool { return currentPasscode() != nil } @@ -34,6 +40,14 @@ final class Lock: LockInterface { return SAMKeychain.password(forService: Keys.service, account: Keys.account) } + func authorizeTransactionsValue() -> Bool { + if let value = keychain.getBool(authorizeTransactions) { + return value + } + setShouldAuthorizeTransactions(enabled: false) + return false + } + func isPasscodeValid(passcode: String) -> Bool { return passcode == currentPasscode() } @@ -67,6 +81,10 @@ final class Lock: LockInterface { SAMKeychain.setPassword(passcode, forService: Keys.service, account: Keys.account) } + func setShouldAuthorizeTransactions(enabled: Bool) { + keychain.set(enabled, forKey: authorizeTransactions) + } + func deletePasscode() { SAMKeychain.deletePassword(forService: Keys.service, account: Keys.account) resetPasscodeAttemptHistory() diff --git a/Trust/Settings/Types/PreferenceOption.swift b/Trust/Settings/Types/PreferenceOption.swift index 51c7b1c785..0a90ecb826 100644 --- a/Trust/Settings/Types/PreferenceOption.swift +++ b/Trust/Settings/Types/PreferenceOption.swift @@ -6,14 +6,12 @@ enum PreferenceOption { case airdropNotifications case browserSearchEngine case testNetworks - case isPasscodeTransactionLockEnabled var key: String { switch self { case .airdropNotifications: return "airdropNotifications" case .browserSearchEngine: return "browserSearchEngine" case .testNetworks: return "browserSearchEngine" - case .isPasscodeTransactionLockEnabled: return "isPasscodeTransactionLockEnabled" } } } diff --git a/Trust/Settings/ViewControllers/SettingsViewController.swift b/Trust/Settings/ViewControllers/SettingsViewController.swift index 323bbcb934..4a5dc0836d 100644 --- a/Trust/Settings/ViewControllers/SettingsViewController.swift +++ b/Trust/Settings/ViewControllers/SettingsViewController.swift @@ -49,7 +49,7 @@ final class SettingsViewController: FormViewController, Coordinator { $0.displayValueFor = { value in return value?.displayName } - $0.hidden = Condition.function([Values.passcodeRow], { [weak self] form in + $0.hidden = Condition.function([Values.passcodeRow], { [weak self] _ in return !(self?.passcodeRow?.value ?? false) }) }.onChange { [weak self] row in @@ -66,13 +66,13 @@ final class SettingsViewController: FormViewController, Coordinator { lazy var passcodeTransactionLockRow: SwitchRow = { return SwitchRow(Values.passcodeTransactionLockRow) { [weak self] in $0.title = self?.viewModel.verifyTransactionsWithPasscodeTitle - $0.value = self?.viewModel.isPasscodeTransactionLockEnabled - $0.hidden = Condition.function([Values.passcodeRow], { [weak self] form in + $0.value = self?.lock.shouldAuthorizeTransactions() + $0.hidden = Condition.function([Values.passcodeRow], { [weak self] _ in return !(self?.passcodeRow?.value ?? false) }) }.onChange { [unowned self] row in if let value = row.value { - self.viewModel.isPasscodeTransactionLockEnabled = value + self.lock.setShouldAuthorizeTransactions(enabled: value) row.updateCell() } }.cellSetup { cell, _ in @@ -329,7 +329,7 @@ final class SettingsViewController: FormViewController, Coordinator { } private func updatePasscodeTransactionLockRow(enabled: Bool) { - viewModel.isPasscodeTransactionLockEnabled = enabled + lock.setShouldAuthorizeTransactions(enabled: enabled) passcodeTransactionLockRow.value = enabled passcodeTransactionLockRow.reload() } diff --git a/Trust/Settings/ViewModels/SettingsViewModel.swift b/Trust/Settings/ViewModels/SettingsViewModel.swift index 47cbfffa9a..28cbc3d44a 100644 --- a/Trust/Settings/ViewModels/SettingsViewModel.swift +++ b/Trust/Settings/ViewModels/SettingsViewModel.swift @@ -48,21 +48,6 @@ struct SettingsViewModel { } } - var isPasscodeTransactionLockEnabled: Bool { - get { - let option = PreferenceOption.isPasscodeTransactionLockEnabled - guard let boolValue = PreferencesController() - .get(for: option.key) as? Bool else { - PreferencesController().set(value: false, for: option) - return false - } - return boolValue - } - set { - PreferencesController().set(value: newValue, for: PreferenceOption.isPasscodeTransactionLockEnabled) - } - } - var verifyTransactionsWithPasscodeTitle: String { return R.string.localizable.settingsLockTransactionsLabelTitle() } diff --git a/Trust/Transfer/Coordinators/ConfirmCoordinator.swift b/Trust/Transfer/Coordinators/ConfirmCoordinator.swift index f9712cb80d..572b3804cf 100644 --- a/Trust/Transfer/Coordinators/ConfirmCoordinator.swift +++ b/Trust/Transfer/Coordinators/ConfirmCoordinator.swift @@ -84,10 +84,7 @@ final class ConfirmCoordinator: RootCoordinator { extension ConfirmCoordinator: ConfirmPaymentAuthenticationDelegate { func confirmPaymentControllerNeedsAuthentication(_ controller: ConfirmPaymentViewController) { - guard let needsPasscodeCheck = PreferencesController() - .get(for: PreferenceOption.isPasscodeTransactionLockEnabled.key) as? Bool else { - return - } + let needsPasscodeCheck = Lock().shouldAuthorizeTransactions() if needsPasscodeCheck { authenticateUserCoordinator.start { [weak self] (success, _) in if success { From 14121c6f93484dc9bea2161c590ff4dc97a17a7f Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Fri, 3 Aug 2018 10:33:37 +0300 Subject: [PATCH 15/16] Removed localized strings --- Trust/Localization/ar.lproj/Localizable.strings | 1 - Trust/Localization/de.lproj/Localizable.strings | 2 -- Trust/Localization/es.lproj/Localizable.strings | 1 - Trust/Localization/fr.lproj/Localizable.strings | 2 -- Trust/Localization/it.lproj/Localizable.strings | 1 - Trust/Localization/ja.lproj/Localizable.strings | 2 -- Trust/Localization/ru.lproj/Localizable.strings | 1 - Trust/Localization/vi.lproj/Localizable.strings | 2 -- Trust/Localization/zh-Hans.lproj/Localizable.strings | 2 -- Trust/Localization/zh-Hant.lproj/Localizable.strings | 2 -- 10 files changed, 16 deletions(-) diff --git a/Trust/Localization/ar.lproj/Localizable.strings b/Trust/Localization/ar.lproj/Localizable.strings index 065bda1b4c..fd90552e15 100644 --- a/Trust/Localization/ar.lproj/Localizable.strings +++ b/Trust/Localization/ar.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "ردود الفعل موثوقة"; "settings.navigation.title" = "الإعدادات"; "settings.network.button.title" = "شبكة"; -"settings.lockTransactions.label.title" = "توثيق المعاملات"; "settings.openSourceDevelopment.label.title" = "تطوير المصادر المفتوحة"; "settings.privacyPolicy.button.title" = "سياسة الخصوصية"; "settings.pushNotifications.button.title" = "دفع الإخطارات"; diff --git a/Trust/Localization/de.lproj/Localizable.strings b/Trust/Localization/de.lproj/Localizable.strings index ef27417f05..19dfa9d41c 100644 --- a/Trust/Localization/de.lproj/Localizable.strings +++ b/Trust/Localization/de.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Trust Feedback"; "settings.navigation.title" = "Einstellungen"; "settings.network.button.title" = "Netzwerk"; -"settings.lockTransactions.label.title" = "Transaktionen authentifizieren"; "settings.openSourceDevelopment.label.title" = "Open-Source-Entwicklung"; "settings.privacyPolicy.button.title" = "Datenschutzbestimmungen"; "settings.pushNotifications.button.title" = "Push-Benachrichtigungen"; @@ -143,7 +142,6 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Falsche PIN. Sie haben %d Versuche."; "lock.enter.passcode.view.model.initial" = "Geben Sie Ihre PIN ein"; "lock.enter.passcode.view.model.touch.id" = "Mit Touch ID anmelden"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentifizieren mit Touch ID"; "lock.enter.passcode.view.model.try.after.one.minute" = "Versuchen Sie es in 1 Minute erneut"; "Name" = "Name"; "send.action.copy.transaction.title" = "Transaktions-ID kopieren"; diff --git a/Trust/Localization/es.lproj/Localizable.strings b/Trust/Localization/es.lproj/Localizable.strings index dda6e44cce..d20e67b913 100644 --- a/Trust/Localization/es.lproj/Localizable.strings +++ b/Trust/Localization/es.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Comentarios sobre Trust"; "settings.navigation.title" = "Configuración"; "settings.network.button.title" = "Red"; -"settings.lockTransactions.label.title" = "Autenticar transacciones"; "settings.openSourceDevelopment.label.title" = "Desarrollo en abierto"; "settings.privacyPolicy.button.title" = "Política de privacidad"; "settings.pushNotifications.button.title" = "Notificaciones Push"; diff --git a/Trust/Localization/fr.lproj/Localizable.strings b/Trust/Localization/fr.lproj/Localizable.strings index 5ccce2ee98..0b600ff58a 100644 --- a/Trust/Localization/fr.lproj/Localizable.strings +++ b/Trust/Localization/fr.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Commentaires sur la confiance"; "settings.navigation.title" = "Paramètres"; "settings.network.button.title" = "Réseau"; -"settings.lockTransactions.label.title" = "Authentifier les transactions"; "settings.openSourceDevelopment.label.title" = "Développement Open Source"; "settings.privacyPolicy.button.title" = "Politique de confidentialité"; "settings.pushNotifications.button.title" = "Notifications push"; @@ -143,7 +142,6 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Code d'accès incorrect. Il vous reste %li tentatives."; "lock.enter.passcode.view.model.initial" = "Entrez votre code d'accès."; "lock.enter.passcode.view.model.touch.id" = "Se connecter avec Touch ID"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Authentification avec Touch ID"; "lock.enter.passcode.view.model.try.after.one.minute" = "Essayez après 1 minute."; "Name" = "Nom"; "send.action.copy.transaction.title" = "Copier l'ID de transaction"; diff --git a/Trust/Localization/it.lproj/Localizable.strings b/Trust/Localization/it.lproj/Localizable.strings index 61c6ed5b07..e09691381d 100644 --- a/Trust/Localization/it.lproj/Localizable.strings +++ b/Trust/Localization/it.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Trust Feedback"; "settings.navigation.title" = "Impostazioni"; "settings.network.button.title" = "Rete"; -"settings.lockTransactions.label.title" = "Autenticare le transazioni"; "settings.openSourceDevelopment.label.title" = "Sviluppo open source"; "settings.privacyPolicy.button.title" = "Politica sulla privacy"; "settings.pushNotifications.button.title" = "Notifiche push"; diff --git a/Trust/Localization/ja.lproj/Localizable.strings b/Trust/Localization/ja.lproj/Localizable.strings index c3a8c6e3e5..074097d2ed 100644 --- a/Trust/Localization/ja.lproj/Localizable.strings +++ b/Trust/Localization/ja.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Trust フィードバック"; "settings.navigation.title" = "設定"; "settings.network.button.title" = "ネットワーク"; -"settings.lockTransactions.label.title" = "トランザクションの認証"; "settings.openSourceDevelopment.label.title" = "オープンソース開発"; "settings.privacyPolicy.button.title" = "個人情報保護方針"; "settings.pushNotifications.button.title" = "プッシュ通知"; @@ -143,7 +142,6 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "パスコードが間違っています。残り%li回試行できます。"; "lock.enter.passcode.view.model.initial" = "パスコードを入力してください。"; "lock.enter.passcode.view.model.touch.id" = "Touch IDでログイン"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "タッチIDによる認証"; "lock.enter.passcode.view.model.try.after.one.minute" = "1分後に試してください。"; "Name" = "名称"; "send.action.copy.transaction.title" = "トランザクション ID をコピー"; diff --git a/Trust/Localization/ru.lproj/Localizable.strings b/Trust/Localization/ru.lproj/Localizable.strings index b8df955845..19f9538421 100644 --- a/Trust/Localization/ru.lproj/Localizable.strings +++ b/Trust/Localization/ru.lproj/Localizable.strings @@ -60,7 +60,6 @@ "settings.feedback.email.title" = "Обратная связь "; "settings.navigation.title" = "Настройки"; "settings.network.button.title" = "Сеть"; -"settings.lockTransactions.label.title" = "Аутентификация транзакций"; "settings.openSourceDevelopment.label.title" = "Разработка с открытым исходным кодом"; "settings.privacyPolicy.button.title" = "Политика Конфиденциальности"; "settings.pushNotifications.button.title" = "Push-Уведомления"; diff --git a/Trust/Localization/vi.lproj/Localizable.strings b/Trust/Localization/vi.lproj/Localizable.strings index b07db2316c..43bd949ebd 100644 --- a/Trust/Localization/vi.lproj/Localizable.strings +++ b/Trust/Localization/vi.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Phản hồi tới Trust"; "settings.navigation.title" = "Cài đặt"; "settings.network.button.title" = "Mạng lưới"; -"settings.lockTransactions.label.title" = "Xác thực giao dịch"; "settings.openSourceDevelopment.label.title" = "Phát triển nguồn mở"; "settings.privacyPolicy.button.title" = "Chính sách bảo mật"; "settings.pushNotifications.button.title" = "Các thông báo đẩy"; @@ -143,7 +142,6 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "Mật mã không chính xác. Bạn còn %d lần thử."; "lock.enter.passcode.view.model.initial" = "Nhập mã khóa của bạn."; "lock.enter.passcode.view.model.touch.id" = "Đăng nhập bằng Vân tay"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "Xác thực bằng ID cảm ứng"; "lock.enter.passcode.view.model.try.after.one.minute" = "Thử lại sau 1 phút."; "Name" = "Tên"; "send.action.copy.transaction.title" = "Sao chép ID giao dịch"; diff --git a/Trust/Localization/zh-Hans.lproj/Localizable.strings b/Trust/Localization/zh-Hans.lproj/Localizable.strings index a190456e09..868ff932fa 100644 --- a/Trust/Localization/zh-Hans.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hans.lproj/Localizable.strings @@ -59,7 +59,6 @@ "settings.feedback.email.title" = "Trust 反馈"; "settings.navigation.title" = "设置"; "settings.network.button.title" = "网络"; -"settings.lockTransactions.label.title" = "验证交易"; "settings.openSourceDevelopment.label.title" = "开源式开发"; "settings.privacyPolicy.button.title" = "隐私政策"; "settings.pushNotifications.button.title" = "推送通知"; @@ -143,7 +142,6 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "密码不正确。你还有 %d 次尝试机会。"; "lock.enter.passcode.view.model.initial" = "请输入密码。"; "lock.enter.passcode.view.model.touch.id" = "使用 Touch ID 登录"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID进行身份验证"; "lock.enter.passcode.view.model.try.after.one.minute" = "请1分钟后再试。"; "Name" = "名称"; "send.action.copy.transaction.title" = "复制交易 ID"; diff --git a/Trust/Localization/zh-Hant.lproj/Localizable.strings b/Trust/Localization/zh-Hant.lproj/Localizable.strings index d52198a97c..b0f5d85349 100644 --- a/Trust/Localization/zh-Hant.lproj/Localizable.strings +++ b/Trust/Localization/zh-Hant.lproj/Localizable.strings @@ -60,7 +60,6 @@ "settings.feedback.email.title" = "Trust 反饋"; "settings.navigation.title" = "設置"; "settings.network.button.title" = "網絡"; -"settings.lockTransactions.label.title" = "驗證交易"; "settings.openSourceDevelopment.label.title" = "開源式開發"; "settings.privacyPolicy.button.title" = "隱私政策"; "settings.pushNotifications.button.title" = "推送通知"; @@ -144,7 +143,6 @@ "lock.enter.passcode.view.model.incorrect.passcode" = "密碼不正確。你還有 %d 次嘗試機會。"; "lock.enter.passcode.view.model.initial" = "請輸入密碼。"; "lock.enter.passcode.view.model.touch.id" = "使用 Touch ID 登錄"; -"lock.authenticate.enter.passcode.view.model.touch.id" = "使用Touch ID進行身份驗證"; "lock.enter.passcode.view.model.try.after.one.minute" = "請1分鐘後再試。"; "Name" = "名稱"; "send.action.copy.transaction.title" = "複製交易 ID"; From ee2dc8acd3cb87c17a3e6a7171be070b9ebcf00e Mon Sep 17 00:00:00 2001 From: Taras Pasichnyk Date: Fri, 3 Aug 2018 11:25:03 +0300 Subject: [PATCH 16/16] Updated fake lock protocol --- TrustTests/Factories/FakeLockProtocol.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/TrustTests/Factories/FakeLockProtocol.swift b/TrustTests/Factories/FakeLockProtocol.swift index 37b1e5112d..b9c5fcf3fb 100644 --- a/TrustTests/Factories/FakeLockProtocol.swift +++ b/TrustTests/Factories/FakeLockProtocol.swift @@ -7,6 +7,7 @@ class FakeLockProtocol: LockInterface { var passcodeSet = true var showProtection = true + var authorizeTransactions = true func isPasscodeSet() -> Bool { return passcodeSet @@ -15,4 +16,12 @@ class FakeLockProtocol: LockInterface { func shouldShowProtection() -> Bool { return isPasscodeSet() && showProtection } + + func authorizeTransactionsValue() -> Bool { + return authorizeTransactions + } + + func shouldAuthorizeTransactions() -> Bool { + return isPasscodeSet() && authorizeTransactionsValue() + } }