// // Account.Service.Authorize.swift // Wallet // // Created by Saveliy Stavitsky on 12/8/20. // Copyright © 2020 List. All rights reserved. // import Foundation import Combine import WalletFoundation import WalletKit private let pinTriesKey = CommonKey("Account.Service.Authorize.pinTries") extension Account.Service { final class Authorize { enum UpdateType { case toggle case change case both } static let shared = Authorize() private init() { } lazy var updateAuthPublisher: AnyPublisher = self.updateAuthSubject.eraseToAnyPublisher() private let updateAuthSubject = CurrentValueSubject(()) func saveUptime() { self.uptimeTemp = uptime() } func clearUptime() { if let uptimeTemp = self.uptimeTemp { print(uptime() - uptimeTemp) print(uptime() - uptimeTemp > 30) if uptime() - uptimeTemp > 30 { password = nil } } uptimeTemp = nil } private(set) var password: String? func update(password value: String?, type: UpdateType = .change) { switch type { case .change: if self.password == nil, let value { // TODO: Call only once on initialization, not on update! Needs to refactor in AccountServiceAuthorize task try? Village.set(password: value) } self.password = value case .toggle: self.updateAuthSubject.send(()) case .both: self.password = value self.updateAuthSubject.send(()) } } private var uptimeTemp: time_t? private func uptime() -> time_t { var boottime = timeval() var mib: [Int32] = [CTL_KERN, KERN_BOOTTIME] var size = MemoryLayout.stride // var boottime = timeval() // var size = MemoryLayout.stride // sysctlbyname("kern.boottime", &boottime, &size, nil, 0) var now = time_t() var uptime: time_t = -1 time(&now) if sysctl(&mib, 2, &boottime, &size, nil, 0) != -1, boottime.tv_sec != 0 { uptime = now - boottime.tv_sec } return uptime } @discardableResult func savePinTry() -> [Int] { Settings.shared[pinTriesKey] = getPinTries() + [uptime()] return [] } func getPinTries() -> [Int] { let pinTries: [Int] = (Settings.shared[pinTriesKey] ?? []).filter({ $0 < uptime() }) // print("count = \(pinTries.count) max = \(pinTries.max()) values = \(pinTries)") return pinTries } // func lastPinTryTimeout() -> Int? { // if let max = getPinTries().max() { // return uptime() - max // } else { // return nil // } // } func clearPinTries() { Settings.shared[pinTriesKey] = [] } } }