Files
raspberry/iOS/Wallet/Sources/Account/Service/AccountServiceAuthorize.swift

105 lines
3.1 KiB
Swift

//
// 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<Void, Never> = self.updateAuthSubject.eraseToAnyPublisher()
private let updateAuthSubject = CurrentValueSubject<Void, Never>(())
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<timeval>.stride
// var boottime = timeval()
// var size = MemoryLayout<timeval>.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] = [] }
}
}