From 1be813d7a7e1c49177ad7f29ab0b673d68a0e013 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Mon, 11 May 2020 16:49:29 +0700 Subject: [PATCH 01/10] Add ToggleSettingsItem --- Library/Scenes/Settings/GroupedTableViewController.swift | 8 ++++++++ Library/Scenes/Settings/Items/SettingsItem.swift | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/Library/Scenes/Settings/GroupedTableViewController.swift b/Library/Scenes/Settings/GroupedTableViewController.swift index 8ea569d98..0f53fddff 100644 --- a/Library/Scenes/Settings/GroupedTableViewController.swift +++ b/Library/Scenes/Settings/GroupedTableViewController.swift @@ -48,6 +48,14 @@ class GroupedTableViewController: UITableViewController { .bind(to: detailLabel.reactive.text) .dispose(in: reactive.bag) } + } else if let item = item as? ToggleSettingsItem { + cell = UITableViewCell(style: .default, reuseIdentifier: "ToggleSettingsCell") + + let toggle = UISwitch() + toggle.isOn = item.isToggled.value + toggle.reactive.isOn.bind(to: item.isToggled) + + cell.accessoryView = toggle } else { cell = UITableViewCell(style: .default, reuseIdentifier: "DefaultSettingsCell") } diff --git a/Library/Scenes/Settings/Items/SettingsItem.swift b/Library/Scenes/Settings/Items/SettingsItem.swift index 5de8ec662..9069fd05d 100644 --- a/Library/Scenes/Settings/Items/SettingsItem.swift +++ b/Library/Scenes/Settings/Items/SettingsItem.swift @@ -24,3 +24,7 @@ protocol SubtitleSettingsItem: SettingsItem { protocol SelectableSettingsItem: SettingsItem { var isSelectedOption: Observable { get } } + +protocol ToggleSettingsItem: SettingsItem { + var isToggled: Observable { get } +} From 633be6af282f4e49dd6436925564f325f563f1e5 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Mon, 11 May 2020 17:07:30 +0700 Subject: [PATCH 02/10] Add 'Payments PIN protection' setting --- Library/Generated/strings.swift | 2 ++ .../PaymentsPINProtectionSettingsItem.swift | 24 +++++++++++++++++++ Library/Scenes/Settings/Settings.swift | 8 +++++++ .../Settings/SettingsViewController.swift | 3 ++- Library/en.lproj/Localizable.strings | 1 + Zap.xcodeproj/project.pbxproj | 4 ++++ 6 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift diff --git a/Library/Generated/strings.swift b/Library/Generated/strings.swift index 1e65f3ccf..bb2ff08f1 100644 --- a/Library/Generated/strings.swift +++ b/Library/Generated/strings.swift @@ -682,6 +682,8 @@ internal enum L10n { /// Settings internal static let title = L10n.tr("Localizable", "scene.settings.title") internal enum Item { + /// Authenticate spendings + internal static let paymentsPINProtection = L10n.tr("Localizable", "scene.settings.item.payments_pin_protection") /// Bitcoin Unit internal static let bitcoinUnit = L10n.tr("Localizable", "scene.settings.item.bitcoin_unit") /// Block Explorer diff --git a/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift b/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift new file mode 100644 index 000000000..0d7fdd0c3 --- /dev/null +++ b/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift @@ -0,0 +1,24 @@ +// +// Library +// +// Created by Ivan Kuznetsov on 11.05.2020. +// Copyright © 2020 Zap. All rights reserved. +// + +import Bond +import UIKit + +final class PaymentsPINProtectionSettingsItem: NSObject, ToggleSettingsItem { + var isToggled = Observable(Settings.shared.paymentsPINProtection.value) + + let title = L10n.Scene.Settings.Item.paymentsPINProtection + + override init() { + super.init() + + isToggled.bind(to: Settings.shared.paymentsPINProtection).dispose(in: reactive.bag) + } + + func didSelectItem(from fromViewController: UIViewController) { + } +} diff --git a/Library/Scenes/Settings/Settings.swift b/Library/Scenes/Settings/Settings.swift index fb7aa4336..656cfb6ed 100644 --- a/Library/Scenes/Settings/Settings.swift +++ b/Library/Scenes/Settings/Settings.swift @@ -28,6 +28,7 @@ public final class Settings: NSObject, Persistable { var blockExplorer: BlockExplorer? var onChainRequestAddressType: OnChainRequestAddressType? var lightningRequestExpiry: ExpiryTime? + var paymentsPINProtection: Bool? } public let primaryCurrency: Observable @@ -38,6 +39,7 @@ public final class Settings: NSObject, Persistable { let blockExplorer: Observable let onChainRequestAddressType: Observable let lightningRequestExpiry: Observable + let paymentsPINProtection: Observable public static let shared = Settings() @@ -55,6 +57,7 @@ public final class Settings: NSObject, Persistable { blockExplorer = Observable(data?.blockExplorer ?? .blockstream) onChainRequestAddressType = Observable(data?.onChainRequestAddressType ?? .witnessPubkeyHash) lightningRequestExpiry = Observable(data?.lightningRequestExpiry ?? .oneHour) + paymentsPINProtection = Observable(data?.paymentsPINProtection ?? true) super.init() @@ -95,6 +98,11 @@ public final class Settings: NSObject, Persistable { .dropFirst(1) .observeNext { [weak self] in self?.data.lightningRequestExpiry = $0 + }, + paymentsPINProtection + .dropFirst(1) + .observeNext { [weak self] in + self?.data.paymentsPINProtection = $0 } ].dispose(in: reactive.bag) } diff --git a/Library/Scenes/Settings/SettingsViewController.swift b/Library/Scenes/Settings/SettingsViewController.swift index 85d6e230d..72bc6aa2b 100644 --- a/Library/Scenes/Settings/SettingsViewController.swift +++ b/Library/Scenes/Settings/SettingsViewController.swift @@ -40,7 +40,8 @@ final class SettingsViewController: GroupedTableViewController { BitcoinUnitSelectionSettingsItem(), OnChainRequestAddressTypeSelectionSettingsItem(), BlockExplorerSelectionSettingsItem(), - LightningRequestExpirySelectionSettingsItem() + LightningRequestExpirySelectionSettingsItem(), + PaymentsPINProtectionSettingsItem() ]) ] sections.append(contentsOf: [ diff --git a/Library/en.lproj/Localizable.strings b/Library/en.lproj/Localizable.strings index bb353538a..85d5ad7cf 100644 --- a/Library/en.lproj/Localizable.strings +++ b/Library/en.lproj/Localizable.strings @@ -91,6 +91,7 @@ "scene.settings.item.help" = "Need Help?"; "scene.settings.item.privacy_policy" = "Privacy Policy"; "scene.settings.item.lnd_log" = "Show lnd Log"; +"scene.settings.item.payments_pin_protection" = "Payments PIN protection"; "scene.request.title" = "Receive"; "scene.request.lightning_button" = "Lightning"; diff --git a/Zap.xcodeproj/project.pbxproj b/Zap.xcodeproj/project.pbxproj index 0cca64edc..051e78440 100644 --- a/Zap.xcodeproj/project.pbxproj +++ b/Zap.xcodeproj/project.pbxproj @@ -402,6 +402,7 @@ ADFEFA7120E628AC00FE1557 /* Lightning.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD536BE620E62763002279BC /* Lightning.framework */; }; ADFEFA7920E62B1800FE1557 /* BlockChainHeightUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D3C97F20629B9D0015C5D7 /* BlockChainHeightUpdater.swift */; }; B7136A44ACFDB94442D05503 /* Pods_Zap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B5CE8ECCAF4EA900FB2EDE1 /* Pods_Zap.framework */; }; + B8C7C0FA246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C7C0F9246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift */; }; CF11A5026DB63D2F0617B3CD /* Pods_LightningTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B7944BECD4B9EE6982B31E9A /* Pods_LightningTests.framework */; }; D191A2ABA2BF895DAD01E919 /* Pods_RPC_Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C3A10DFB274187D3242E528 /* Pods_RPC_Widget.framework */; }; /* End PBXBuildFile section */ @@ -1028,6 +1029,7 @@ ADFE537F20D693F500B3BA2A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; ADFEFA7320E6294000FE1557 /* OnChainRequestAddressType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnChainRequestAddressType.swift; sourceTree = ""; }; B7944BECD4B9EE6982B31E9A /* Pods_LightningTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LightningTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B8C7C0F9246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentsPINProtectionSettingsItem.swift; sourceTree = ""; }; BFEA939DE8A6736499979EAF /* Pods-RPC-Lightning.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RPC-Lightning.release.xcconfig"; path = "Target Support Files/Pods-RPC-Lightning/Pods-RPC-Lightning.release.xcconfig"; sourceTree = ""; }; C3CC119794C04517509253C2 /* Pods-RPC-Widget.debugremote.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RPC-Widget.debugremote.xcconfig"; path = "Target Support Files/Pods-RPC-Widget/Pods-RPC-Widget.debugremote.xcconfig"; sourceTree = ""; }; C480EBE1AF18EF4DEB4BA918 /* Pods-Zap.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Zap.debug.xcconfig"; path = "Target Support Files/Pods-Zap/Pods-Zap.debug.xcconfig"; sourceTree = ""; }; @@ -1302,6 +1304,7 @@ A091914A203B297D00FA525A /* CurrencySettingsItem.swift */, 5C18BB70234C09EB00BCF9D9 /* LightningRequestExpirySettingsItem.swift */, AD6FFCA520AB0A3700B57330 /* OnChainRequestAddressTypeSettingsItem.swift */, + B8C7C0F9246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift */, ADFE2E4B216CF4A800988243 /* PushViewControllerSettingsItem.swift */, AD81C21621B80FCD00FA3FA9 /* SafariSettingsItem.swift */, A0DDC06B2018C07100AEFF94 /* SettingsItem.swift */, @@ -3289,6 +3292,7 @@ AD967FF021062AB20048085B /* RPCConnectQRCodeError+Localizable.swift in Sources */, AD3DDF7122D39BC30031BFC8 /* Emoji.swift in Sources */, AD615CF7211CAB0900680790 /* PaddingLabel.swift in Sources */, + B8C7C0FA246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift in Sources */, AD391C6E20D16F89007EE22A /* SetupPinViewModel.swift in Sources */, ADA179C62152864E001401F3 /* Storage.swift in Sources */, ADA865BE20ECB88500B1B74B /* FilterViewController.swift in Sources */, From 80c0a1601ec786e0632c5bf1974f7a57d03091c2 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Mon, 11 May 2020 17:17:25 +0700 Subject: [PATCH 03/10] Rerun SwiftGen to fix a localization --- Library/Generated/strings.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Generated/strings.swift b/Library/Generated/strings.swift index bb2ff08f1..e9f050502 100644 --- a/Library/Generated/strings.swift +++ b/Library/Generated/strings.swift @@ -682,8 +682,6 @@ internal enum L10n { /// Settings internal static let title = L10n.tr("Localizable", "scene.settings.title") internal enum Item { - /// Authenticate spendings - internal static let paymentsPINProtection = L10n.tr("Localizable", "scene.settings.item.payments_pin_protection") /// Bitcoin Unit internal static let bitcoinUnit = L10n.tr("Localizable", "scene.settings.item.bitcoin_unit") /// Block Explorer @@ -702,6 +700,8 @@ internal enum L10n { internal static let lndLog = L10n.tr("Localizable", "scene.settings.item.lnd_log") /// Manage Channels internal static let manageChannels = L10n.tr("Localizable", "scene.settings.item.manage_channels") + /// Payments PIN protection + internal static let paymentsPinProtection = L10n.tr("Localizable", "scene.settings.item.payments_pin_protection") /// Privacy Policy internal static let privacyPolicy = L10n.tr("Localizable", "scene.settings.item.privacy_policy") /// Manage Wallets From bdd848def43c47eb48a28f8f34844fd8a4a08790 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Mon, 11 May 2020 18:51:05 +0700 Subject: [PATCH 04/10] Fix a localization name, SwiftGen doesn't capitalize all the letters --- .../Settings/Items/PaymentsPINProtectionSettingsItem.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift b/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift index 0d7fdd0c3..eaec4d348 100644 --- a/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift +++ b/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift @@ -11,7 +11,7 @@ import UIKit final class PaymentsPINProtectionSettingsItem: NSObject, ToggleSettingsItem { var isToggled = Observable(Settings.shared.paymentsPINProtection.value) - let title = L10n.Scene.Settings.Item.paymentsPINProtection + let title = L10n.Scene.Settings.Item.paymentsPinProtection override init() { super.init() From 04b0489b4cb1af8349e5eed4fd8ed6a72f979e16 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Tue, 12 May 2020 16:16:30 +0700 Subject: [PATCH 05/10] Don't authenticate when 'Payments PIN protection' is disabled --- Library/Scenes/ModalDetail/Send/SendViewController.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Library/Scenes/ModalDetail/Send/SendViewController.swift b/Library/Scenes/ModalDetail/Send/SendViewController.swift index a99c78520..b518647dd 100644 --- a/Library/Scenes/ModalDetail/Send/SendViewController.swift +++ b/Library/Scenes/ModalDetail/Send/SendViewController.swift @@ -160,6 +160,10 @@ final class SendViewController: ModalDetailViewController { } private func sendButtonTapped() { + if !Settings.shared.paymentsPINProtection.value { + return self.send() + } + authenticate { [weak self] result in switch result { case .success: From 7e708a91b446102d32f999b82039b5a710cdf29e Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Tue, 12 May 2020 16:28:43 +0700 Subject: [PATCH 06/10] Rename 'Payments PIN protection' because it controls all authentication methods --- Library/Generated/strings.swift | 4 ++-- .../ModalDetail/Send/SendViewController.swift | 2 +- .../PaymentsAuthenticationSettingsItem.swift | 24 +++++++++++++++++++ .../PaymentsPINProtectionSettingsItem.swift | 24 ------------------- Library/Scenes/Settings/Settings.swift | 6 ++--- .../Settings/SettingsViewController.swift | 2 +- Library/en.lproj/Localizable.strings | 2 +- Zap.xcodeproj/project.pbxproj | 8 +++---- 8 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift delete mode 100644 Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift diff --git a/Library/Generated/strings.swift b/Library/Generated/strings.swift index e9f050502..89c9b0465 100644 --- a/Library/Generated/strings.swift +++ b/Library/Generated/strings.swift @@ -700,8 +700,8 @@ internal enum L10n { internal static let lndLog = L10n.tr("Localizable", "scene.settings.item.lnd_log") /// Manage Channels internal static let manageChannels = L10n.tr("Localizable", "scene.settings.item.manage_channels") - /// Payments PIN protection - internal static let paymentsPinProtection = L10n.tr("Localizable", "scene.settings.item.payments_pin_protection") + /// Authenticate payments + internal static let paymentsAuthentication = L10n.tr("Localizable", "scene.settings.item.paymentsAuthentication") /// Privacy Policy internal static let privacyPolicy = L10n.tr("Localizable", "scene.settings.item.privacy_policy") /// Manage Wallets diff --git a/Library/Scenes/ModalDetail/Send/SendViewController.swift b/Library/Scenes/ModalDetail/Send/SendViewController.swift index b518647dd..c3ac7879e 100644 --- a/Library/Scenes/ModalDetail/Send/SendViewController.swift +++ b/Library/Scenes/ModalDetail/Send/SendViewController.swift @@ -160,7 +160,7 @@ final class SendViewController: ModalDetailViewController { } private func sendButtonTapped() { - if !Settings.shared.paymentsPINProtection.value { + if !Settings.shared.paymentsAuthentication.value { return self.send() } diff --git a/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift b/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift new file mode 100644 index 000000000..bed86ae5b --- /dev/null +++ b/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift @@ -0,0 +1,24 @@ +// +// Library +// +// Created by Ivan Kuznetsov on 11.05.2020. +// Copyright © 2020 Zap. All rights reserved. +// + +import Bond +import UIKit + +final class PaymentsAuthenticationSettingsItem: NSObject, ToggleSettingsItem { + var isToggled = Observable(Settings.shared.paymentsAuthentication.value) + + let title = L10n.Scene.Settings.Item.paymentsAuthentication + + override init() { + super.init() + + isToggled.bind(to: Settings.shared.paymentsAuthentication).dispose(in: reactive.bag) + } + + func didSelectItem(from fromViewController: UIViewController) { + } +} diff --git a/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift b/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift deleted file mode 100644 index eaec4d348..000000000 --- a/Library/Scenes/Settings/Items/PaymentsPINProtectionSettingsItem.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// Library -// -// Created by Ivan Kuznetsov on 11.05.2020. -// Copyright © 2020 Zap. All rights reserved. -// - -import Bond -import UIKit - -final class PaymentsPINProtectionSettingsItem: NSObject, ToggleSettingsItem { - var isToggled = Observable(Settings.shared.paymentsPINProtection.value) - - let title = L10n.Scene.Settings.Item.paymentsPinProtection - - override init() { - super.init() - - isToggled.bind(to: Settings.shared.paymentsPINProtection).dispose(in: reactive.bag) - } - - func didSelectItem(from fromViewController: UIViewController) { - } -} diff --git a/Library/Scenes/Settings/Settings.swift b/Library/Scenes/Settings/Settings.swift index 656cfb6ed..11c2c0118 100644 --- a/Library/Scenes/Settings/Settings.swift +++ b/Library/Scenes/Settings/Settings.swift @@ -39,7 +39,7 @@ public final class Settings: NSObject, Persistable { let blockExplorer: Observable let onChainRequestAddressType: Observable let lightningRequestExpiry: Observable - let paymentsPINProtection: Observable + let paymentsAuthentication: Observable public static let shared = Settings() @@ -57,7 +57,7 @@ public final class Settings: NSObject, Persistable { blockExplorer = Observable(data?.blockExplorer ?? .blockstream) onChainRequestAddressType = Observable(data?.onChainRequestAddressType ?? .witnessPubkeyHash) lightningRequestExpiry = Observable(data?.lightningRequestExpiry ?? .oneHour) - paymentsPINProtection = Observable(data?.paymentsPINProtection ?? true) + paymentsAuthentication = Observable(data?.paymentsPINProtection ?? true) super.init() @@ -99,7 +99,7 @@ public final class Settings: NSObject, Persistable { .observeNext { [weak self] in self?.data.lightningRequestExpiry = $0 }, - paymentsPINProtection + paymentsAuthentication .dropFirst(1) .observeNext { [weak self] in self?.data.paymentsPINProtection = $0 diff --git a/Library/Scenes/Settings/SettingsViewController.swift b/Library/Scenes/Settings/SettingsViewController.swift index 72bc6aa2b..dfeeabfa8 100644 --- a/Library/Scenes/Settings/SettingsViewController.swift +++ b/Library/Scenes/Settings/SettingsViewController.swift @@ -41,7 +41,7 @@ final class SettingsViewController: GroupedTableViewController { OnChainRequestAddressTypeSelectionSettingsItem(), BlockExplorerSelectionSettingsItem(), LightningRequestExpirySelectionSettingsItem(), - PaymentsPINProtectionSettingsItem() + PaymentsAuthenticationSettingsItem() ]) ] sections.append(contentsOf: [ diff --git a/Library/en.lproj/Localizable.strings b/Library/en.lproj/Localizable.strings index 85d5ad7cf..dcbeab8c7 100644 --- a/Library/en.lproj/Localizable.strings +++ b/Library/en.lproj/Localizable.strings @@ -91,7 +91,7 @@ "scene.settings.item.help" = "Need Help?"; "scene.settings.item.privacy_policy" = "Privacy Policy"; "scene.settings.item.lnd_log" = "Show lnd Log"; -"scene.settings.item.payments_pin_protection" = "Payments PIN protection"; +"scene.settings.item.paymentsAuthentication" = "Authenticate payments"; "scene.request.title" = "Receive"; "scene.request.lightning_button" = "Lightning"; diff --git a/Zap.xcodeproj/project.pbxproj b/Zap.xcodeproj/project.pbxproj index 051e78440..f27246161 100644 --- a/Zap.xcodeproj/project.pbxproj +++ b/Zap.xcodeproj/project.pbxproj @@ -402,7 +402,7 @@ ADFEFA7120E628AC00FE1557 /* Lightning.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD536BE620E62763002279BC /* Lightning.framework */; }; ADFEFA7920E62B1800FE1557 /* BlockChainHeightUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D3C97F20629B9D0015C5D7 /* BlockChainHeightUpdater.swift */; }; B7136A44ACFDB94442D05503 /* Pods_Zap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B5CE8ECCAF4EA900FB2EDE1 /* Pods_Zap.framework */; }; - B8C7C0FA246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C7C0F9246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift */; }; + B8C7C0FA246930DF00B4556A /* PaymentsAuthenticationSettingsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C7C0F9246930DF00B4556A /* PaymentsAuthenticationSettingsItem.swift */; }; CF11A5026DB63D2F0617B3CD /* Pods_LightningTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B7944BECD4B9EE6982B31E9A /* Pods_LightningTests.framework */; }; D191A2ABA2BF895DAD01E919 /* Pods_RPC_Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C3A10DFB274187D3242E528 /* Pods_RPC_Widget.framework */; }; /* End PBXBuildFile section */ @@ -1029,7 +1029,7 @@ ADFE537F20D693F500B3BA2A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; ADFEFA7320E6294000FE1557 /* OnChainRequestAddressType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnChainRequestAddressType.swift; sourceTree = ""; }; B7944BECD4B9EE6982B31E9A /* Pods_LightningTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LightningTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B8C7C0F9246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentsPINProtectionSettingsItem.swift; sourceTree = ""; }; + B8C7C0F9246930DF00B4556A /* PaymentsAuthenticationSettingsItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentsAuthenticationSettingsItem.swift; sourceTree = ""; }; BFEA939DE8A6736499979EAF /* Pods-RPC-Lightning.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RPC-Lightning.release.xcconfig"; path = "Target Support Files/Pods-RPC-Lightning/Pods-RPC-Lightning.release.xcconfig"; sourceTree = ""; }; C3CC119794C04517509253C2 /* Pods-RPC-Widget.debugremote.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RPC-Widget.debugremote.xcconfig"; path = "Target Support Files/Pods-RPC-Widget/Pods-RPC-Widget.debugremote.xcconfig"; sourceTree = ""; }; C480EBE1AF18EF4DEB4BA918 /* Pods-Zap.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Zap.debug.xcconfig"; path = "Target Support Files/Pods-Zap/Pods-Zap.debug.xcconfig"; sourceTree = ""; }; @@ -1304,7 +1304,7 @@ A091914A203B297D00FA525A /* CurrencySettingsItem.swift */, 5C18BB70234C09EB00BCF9D9 /* LightningRequestExpirySettingsItem.swift */, AD6FFCA520AB0A3700B57330 /* OnChainRequestAddressTypeSettingsItem.swift */, - B8C7C0F9246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift */, + B8C7C0F9246930DF00B4556A /* PaymentsAuthenticationSettingsItem.swift */, ADFE2E4B216CF4A800988243 /* PushViewControllerSettingsItem.swift */, AD81C21621B80FCD00FA3FA9 /* SafariSettingsItem.swift */, A0DDC06B2018C07100AEFF94 /* SettingsItem.swift */, @@ -3292,7 +3292,7 @@ AD967FF021062AB20048085B /* RPCConnectQRCodeError+Localizable.swift in Sources */, AD3DDF7122D39BC30031BFC8 /* Emoji.swift in Sources */, AD615CF7211CAB0900680790 /* PaddingLabel.swift in Sources */, - B8C7C0FA246930DF00B4556A /* PaymentsPINProtectionSettingsItem.swift in Sources */, + B8C7C0FA246930DF00B4556A /* PaymentsAuthenticationSettingsItem.swift in Sources */, AD391C6E20D16F89007EE22A /* SetupPinViewModel.swift in Sources */, ADA179C62152864E001401F3 /* Storage.swift in Sources */, ADA865BE20ECB88500B1B74B /* FilterViewController.swift in Sources */, From 2a52597f576877b86fbc726db6dacabde552ecaa Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Tue, 12 May 2020 17:14:11 +0700 Subject: [PATCH 07/10] Disabling payments authentication requires authentication --- .../Settings/GroupedTableViewController.swift | 2 +- .../PaymentsAuthenticationSettingsItem.swift | 19 +++++++++++++++++-- .../Settings/SettingsViewController.swift | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Library/Scenes/Settings/GroupedTableViewController.swift b/Library/Scenes/Settings/GroupedTableViewController.swift index 0f53fddff..6468c7e55 100644 --- a/Library/Scenes/Settings/GroupedTableViewController.swift +++ b/Library/Scenes/Settings/GroupedTableViewController.swift @@ -53,7 +53,7 @@ class GroupedTableViewController: UITableViewController { let toggle = UISwitch() toggle.isOn = item.isToggled.value - toggle.reactive.isOn.bind(to: item.isToggled) + toggle.reactive.isOn.bidirectionalBind(to: item.isToggled) cell.accessoryView = toggle } else { diff --git a/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift b/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift index bed86ae5b..45b3d2bf1 100644 --- a/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift +++ b/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift @@ -13,10 +13,25 @@ final class PaymentsAuthenticationSettingsItem: NSObject, ToggleSettingsItem { let title = L10n.Scene.Settings.Item.paymentsAuthentication - override init() { + init(authenticationViewModel: AuthenticationViewModel) { super.init() - isToggled.bind(to: Settings.shared.paymentsAuthentication).dispose(in: reactive.bag) + isToggled.observeNext { [weak self] isOn in + if !isOn && Settings.shared.paymentsAuthentication.value { + ModalPinViewController.authenticate(authenticationViewModel: authenticationViewModel) { [weak self] result in + switch result { + case .success: + Settings.shared.paymentsAuthentication.value = isOn + + case .failure: + self?.isToggled.send(!isOn) + } + } + } else { + Settings.shared.paymentsAuthentication.value = isOn + } + } + .dispose(in: reactive.bag) } func didSelectItem(from fromViewController: UIViewController) { diff --git a/Library/Scenes/Settings/SettingsViewController.swift b/Library/Scenes/Settings/SettingsViewController.swift index dfeeabfa8..4c92d479d 100644 --- a/Library/Scenes/Settings/SettingsViewController.swift +++ b/Library/Scenes/Settings/SettingsViewController.swift @@ -41,7 +41,7 @@ final class SettingsViewController: GroupedTableViewController { OnChainRequestAddressTypeSelectionSettingsItem(), BlockExplorerSelectionSettingsItem(), LightningRequestExpirySelectionSettingsItem(), - PaymentsAuthenticationSettingsItem() + PaymentsAuthenticationSettingsItem(authenticationViewModel: authenticationViewModel) ]) ] sections.append(contentsOf: [ From 98bd2d7403cf720303e45e633a30ed6de2855fb7 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Tue, 12 May 2020 19:12:14 +0700 Subject: [PATCH 08/10] Change UISwitch color to lightningOrange --- Library/Scenes/Settings/GroupedTableViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Scenes/Settings/GroupedTableViewController.swift b/Library/Scenes/Settings/GroupedTableViewController.swift index 6468c7e55..b800128ef 100644 --- a/Library/Scenes/Settings/GroupedTableViewController.swift +++ b/Library/Scenes/Settings/GroupedTableViewController.swift @@ -52,6 +52,7 @@ class GroupedTableViewController: UITableViewController { cell = UITableViewCell(style: .default, reuseIdentifier: "ToggleSettingsCell") let toggle = UISwitch() + toggle.onTintColor = UIColor.Zap.lightningOrange toggle.isOn = item.isToggled.value toggle.reactive.isOn.bidirectionalBind(to: item.isToggled) From b5245591adeb46610e2a422678b92d51e6738e2c Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Wed, 13 May 2020 19:24:07 +0700 Subject: [PATCH 09/10] Biometrics + PIN when disabling payments authentication --- .../PaymentsAuthenticationSettingsItem.swift | 26 ++++++++++++++++--- .../Settings/SettingsViewController.swift | 9 ++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift b/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift index 45b3d2bf1..d59900d10 100644 --- a/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift +++ b/Library/Scenes/Settings/Items/PaymentsAuthenticationSettingsItem.swift @@ -6,23 +6,28 @@ // import Bond +import SwiftLnd import UIKit final class PaymentsAuthenticationSettingsItem: NSObject, ToggleSettingsItem { var isToggled = Observable(Settings.shared.paymentsAuthentication.value) let title = L10n.Scene.Settings.Item.paymentsAuthentication - + + private let authenticationViewModel: AuthenticationViewModel + var fakeAuthViewController = UIViewController() + init(authenticationViewModel: AuthenticationViewModel) { + self.authenticationViewModel = authenticationViewModel + super.init() isToggled.observeNext { [weak self] isOn in if !isOn && Settings.shared.paymentsAuthentication.value { - ModalPinViewController.authenticate(authenticationViewModel: authenticationViewModel) { [weak self] result in + self?.authenticate { [weak self] result in switch result { case .success: Settings.shared.paymentsAuthentication.value = isOn - case .failure: self?.isToggled.send(!isOn) } @@ -36,4 +41,19 @@ final class PaymentsAuthenticationSettingsItem: NSObject, ToggleSettingsItem { func didSelectItem(from fromViewController: UIViewController) { } + + private func authenticate(completion: @escaping (Result) -> Void) { + if BiometricAuthentication.type == .none { + ModalPinViewController.authenticate(authenticationViewModel: authenticationViewModel) { completion($0) } + } else { + BiometricAuthentication.authenticate(viewController: fakeAuthViewController) { [authenticationViewModel] result in + if case .failure(let error) = result, + error == AuthenticationError.useFallback { + ModalPinViewController.authenticate(authenticationViewModel: authenticationViewModel) { completion($0) } + } else { + completion(result) + } + } + } + } } diff --git a/Library/Scenes/Settings/SettingsViewController.swift b/Library/Scenes/Settings/SettingsViewController.swift index 4c92d479d..37c3cbc90 100644 --- a/Library/Scenes/Settings/SettingsViewController.swift +++ b/Library/Scenes/Settings/SettingsViewController.swift @@ -24,6 +24,7 @@ final class SettingsViewController: GroupedTableViewController { authenticationViewModel: AuthenticationViewModel, pushLndLogViewController: @escaping (UINavigationController) -> Void ) { +// super.init(sections: [Section]()) self.info = info var walletRows: [SettingsItem] = [ @@ -34,6 +35,10 @@ final class SettingsViewController: GroupedTableViewController { walletRows.append(PushViewControllerSettingsItem(title: L10n.Scene.Settings.Item.lndLog, pushViewController: pushLndLogViewController)) } + let paymentsAuthenticationSetting = PaymentsAuthenticationSettingsItem( + authenticationViewModel: authenticationViewModel + ) + var sections: [Section] = [ Section(title: L10n.Scene.Settings.title, rows: [ CurrencySelectionSettingsItem(), @@ -41,7 +46,7 @@ final class SettingsViewController: GroupedTableViewController { OnChainRequestAddressTypeSelectionSettingsItem(), BlockExplorerSelectionSettingsItem(), LightningRequestExpirySelectionSettingsItem(), - PaymentsAuthenticationSettingsItem(authenticationViewModel: authenticationViewModel) + paymentsAuthenticationSetting ]) ] sections.append(contentsOf: [ @@ -56,6 +61,8 @@ final class SettingsViewController: GroupedTableViewController { ]), at: 0) } super.init(sections: sections) + + paymentsAuthenticationSetting.fakeAuthViewController = self } required init?(coder aDecoder: NSCoder) { From 46b7a2d741bf945b9f16c61ef273b20a9e6f3130 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Wed, 13 May 2020 19:48:57 +0700 Subject: [PATCH 10/10] Move Authenticate payments setting to the Wallet section --- .../Scenes/Settings/SettingsViewController.swift | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Library/Scenes/Settings/SettingsViewController.swift b/Library/Scenes/Settings/SettingsViewController.swift index 37c3cbc90..6a20e189c 100644 --- a/Library/Scenes/Settings/SettingsViewController.swift +++ b/Library/Scenes/Settings/SettingsViewController.swift @@ -24,10 +24,14 @@ final class SettingsViewController: GroupedTableViewController { authenticationViewModel: AuthenticationViewModel, pushLndLogViewController: @escaping (UINavigationController) -> Void ) { -// super.init(sections: [Section]()) self.info = info + let paymentsAuthenticationSetting = PaymentsAuthenticationSettingsItem( + authenticationViewModel: authenticationViewModel + ) + var walletRows: [SettingsItem] = [ + paymentsAuthenticationSetting, ChangePinSettingsItem(authenticationViewModel: authenticationViewModel) ] @@ -35,18 +39,13 @@ final class SettingsViewController: GroupedTableViewController { walletRows.append(PushViewControllerSettingsItem(title: L10n.Scene.Settings.Item.lndLog, pushViewController: pushLndLogViewController)) } - let paymentsAuthenticationSetting = PaymentsAuthenticationSettingsItem( - authenticationViewModel: authenticationViewModel - ) - var sections: [Section] = [ Section(title: L10n.Scene.Settings.title, rows: [ CurrencySelectionSettingsItem(), BitcoinUnitSelectionSettingsItem(), OnChainRequestAddressTypeSelectionSettingsItem(), BlockExplorerSelectionSettingsItem(), - LightningRequestExpirySelectionSettingsItem(), - paymentsAuthenticationSetting + LightningRequestExpirySelectionSettingsItem() ]) ] sections.append(contentsOf: [