Dactyloidae/mobile/ios/Client/Frontend/AuthenticationManager/AppAuthenticator.swift
2026-06-26 21:04:09 -07:00

55 lines
2.4 KiB
Swift

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
import Shared
import SwiftKeychainWrapper
import LocalAuthentication
class AppAuthenticator {
static func presentAuthenticationUsingInfo(_ authenticationInfo: AuthenticationKeychainInfo, touchIDReason: String, success: (() -> Void)?, cancel: (() -> Void)?, fallback: (() -> Void)?) {
if authenticationInfo.useTouchID {
let localAuthContext = LAContext()
localAuthContext.localizedFallbackTitle = AuthenticationStrings.enterPasscode
localAuthContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: touchIDReason) { didSucceed, error in
if didSucceed {
// Update our authentication info's last validation timestamp so we don't ask again based
// on the set required interval
authenticationInfo.recordValidation()
KeychainWrapper.sharedAppContainerKeychain.setAuthenticationInfo(authenticationInfo)
DispatchQueue.main.async {
success?()
}
return
}
guard let authError = error,
let code = LAError.Code(rawValue: authError._code) else {
return
}
DispatchQueue.main.async {
switch code {
case .userFallback, .touchIDNotEnrolled, .touchIDNotAvailable, .touchIDLockout:
fallback?()
case .userCancel:
cancel?()
default:
cancel?()
}
}
}
} else {
fallback?()
}
}
static func presentPasscodeAuthentication(_ presentingNavController: UINavigationController?, delegate: PasscodeEntryDelegate?) {
let passcodeVC = PasscodeEntryViewController()
passcodeVC.delegate = delegate
let navController = UINavigationController(rootViewController: passcodeVC)
navController.modalPresentationStyle = .formSheet
presentingNavController?.present(navController, animated: true, completion: nil)
}
}