Files
Андрей Геращенко f52cdb51bc MALINKA-1095: Password logic refactoring
2023-03-10 11:40:54 +03:00

192 lines
7.5 KiB
Swift

//
// SettingsViewController.swift
// Wallet
//
// Created by Saveliy Stavitsky on 9/9/21.
// Copyright © 2021 AM. All rights reserved.
//
import UIKit
import Combine
final class SettingsViewController: UIViewController {
@IBOutlet private var settingsView: AccountViewSettings!
private var cancellables = Set<AnyCancellable>()
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = L10n.Account.Settings.title
self.navigationItem.leftBarButtonItem = .pop(self)
self.notificationSwitch()
NotificationCenter.default.addObserver(self,
selector: #selector(self.notificationSwitch),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.settingsView.actionPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] in self?.handleAction($0) }
.store(in: &self.cancellables)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.cancellables.removeAll()
}
// MARK: - Private
private func handleAction(_ action: AccountViewSettings.Action) {
switch action {
case .password:
self.handlePasswordAction()
case .about:
self.handleAboutAction()
case .changeInterfaceStyle:
self.handleChangeInterfaceStyleAction()
case .changeProtection:
self.handleChangeProtectionAction()
}
}
private func handlePasswordAction() {
self.dismiss(animated: true)
guard UserDefaults.standard.bool(forKey: "isPinPwdMode") else {
AccountViewPassword.show(in: self)
return
}
let accountControollerPin = WalletPinController.instantiate()
let ctrl = UINavigationController(rootViewController: accountControollerPin)
accountControollerPin.type = .old
accountControollerPin.viewModel.validatePin = { [weak ctrl, weak self] (pin: String) -> Bool in
guard Account.Service.check(password: pin), !pin.isEmpty, pin.count == 4 else {
Account.Service.Authorize.shared.savePinTry()
return false
}
ctrl?.dismiss(animated: false)
Account.Service.Authorize.shared.update(password: pin)
let accountControollerPin = WalletPinController.instantiate()
let ctrl = UINavigationController(rootViewController: accountControollerPin)
accountControollerPin.type = .new
accountControollerPin.viewModel.validatePin = { [weak ctrl] (newPin: String) -> Bool in
if Account.Service.check(password: pin) {
do {
try Accounts().update(password: newPin, old: pin)
} catch {
Alert.error(text: L10n.Account.Password.currentWrong)
return false
}
Account.Service.Authorize.shared.update(password: newPin)
ctrl?.dismiss(animated: true)
return true
} else {
Alert.error(text: L10n.Account.Password.currentWrong)
return false
}
}
ctrl.modalPresentationStyle = .fullScreen
self?.present(ctrl, animated: true)
Account.Service.Authorize.shared.clearPinTries()
return true
}
ctrl.modalPresentationStyle = .fullScreen
self.present(ctrl, animated: true)
}
private func handleAboutAction() {
self.navigationController?.pushViewController(AccountControllerAbout(), animated: true)
}
private func handleChangeInterfaceStyleAction() {
self.dismiss(animated: true)
let vc = StoryboardScene.AccountOnboarding.accountOnboardingControllerInterfaceType.instantiate()
vc.isStep = false
self.present(vc, animated: true)
}
private func handleChangeProtectionAction() {
self.dismiss(animated: true)
AccountViewAuthorize.showGetPassword(in: self, { [weak self] oldPassword in
guard let self else { return }
let view = AccountViewProtectionLevel()
view.didSubmit = { submitted in
self.dismiss(animated: true)
guard submitted else { return }
if UserDefaults.standard.bool(forKey: "isPinPwdMode") {
AccountViewPassword.show(in: self, oldPassword: oldPassword)
} else {
let accountControollerPin = WalletPinController.instantiate()
let ctrl = UINavigationController(rootViewController: accountControollerPin)
accountControollerPin.type = .new
accountControollerPin.viewModel.validatePin = { [weak ctrl] (pin: String) -> Bool in
if Account.Service.check(password: oldPassword) {
do {
try Accounts().update(password: pin, old: oldPassword)
UserDefaults.standard.setValue(!UserDefaults.standard.bool(forKey: "isPinPwdMode"), forKey: "isPinPwdMode")
Account.Service.Authorize.shared.update(password: pin)
ctrl?.dismiss(animated: true)
return true
} catch {
Alert.error(text: L10n.Account.Password.currentWrong)
return false
}
} else {
Alert.error(text: L10n.Account.Password.currentWrong)
return false
}
}
ctrl.modalPresentationStyle = .fullScreen
self.present(ctrl, animated: true)
}
}
let viewController =
CommonControllerPopup(image: UserDefaults.standard.bool(forKey: "isPinPwdMode")
? Asset.accountProtectionUnlocked.image
: Asset.accountProtectionLocked.image,
title: L10n.Account.Settings.protection,
views: [view], spacing: 0)
self.present(viewController, animated: true)
})
}
@objc
private func notificationSwitch() {
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { settings in
switch settings.authorizationStatus {
case .authorized, .provisional:
DispatchQueue.main.async { [weak self] in
self?.settingsView.notificationsEnabledLabel.text = L10n.Account.Settings.notificationsEnabled
}
default:
DispatchQueue.main.async { [weak self] in
self?.settingsView.notificationsEnabledLabel.text = L10n.Account.Settings.notificationsDisabled
}
}
}
}
}