New SDK components extracted from product apps: - BLBlobClient — Azure Blob Storage upload via SAS tokens (from LysnrAI BlobService) - BLKillSwitchClient — Kill switch check from platform-service (from LysnrAI KillSwitchService) - BLLicenseClient — License key activation + status (from LysnrAI LicenseService) - BLBiometricAuth — Face ID / Touch ID wrapper (from LysnrAI BiometricAuth) - BLCrashReporter — MetricKit crash reporting (from ChronoMind CrashReporter) - BLAuditLogger — Local rotating JSON audit log (from LysnrAI AuditLogger) SDK now has 13 source files. Updated README with full component table and migration status (3 apps fully migrated, 18 wrappers total).
73 lines
2.4 KiB
Swift
73 lines
2.4 KiB
Swift
// ── Biometric Authentication ────────────────────────────────
|
|
// Generic Face ID / Touch ID wrapper using LocalAuthentication.
|
|
// Product apps pass a custom reason string for the biometric prompt.
|
|
|
|
import Foundation
|
|
import LocalAuthentication
|
|
|
|
/// Generic biometric authentication for all ByteLyst iOS apps.
|
|
public enum BLBiometricAuth {
|
|
|
|
public enum BiometricType {
|
|
case faceID, touchID, none
|
|
}
|
|
|
|
/// Check what biometric type is available on this device.
|
|
public static var availableType: BiometricType {
|
|
let context = LAContext()
|
|
var error: NSError?
|
|
guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
|
|
return .none
|
|
}
|
|
switch context.biometryType {
|
|
case .faceID: return .faceID
|
|
case .touchID: return .touchID
|
|
default: return .none
|
|
}
|
|
}
|
|
|
|
/// Whether biometric auth is available on this device.
|
|
public static var isAvailable: Bool {
|
|
availableType != .none
|
|
}
|
|
|
|
/// Whether the user has enabled biometric lock in settings.
|
|
/// Uses a configurable UserDefaults key.
|
|
public static func isEnabled(key: String = "biometric_lock_enabled") -> Bool {
|
|
UserDefaults.standard.bool(forKey: key)
|
|
}
|
|
|
|
/// Set biometric lock enabled state.
|
|
public static func setEnabled(_ enabled: Bool, key: String = "biometric_lock_enabled") {
|
|
UserDefaults.standard.set(enabled, forKey: key)
|
|
}
|
|
|
|
/// Authenticate with biometrics only. Returns true on success.
|
|
public static func authenticate(reason: String = "Unlock app") async -> Bool {
|
|
let context = LAContext()
|
|
context.localizedCancelTitle = "Use Password"
|
|
|
|
do {
|
|
return try await context.evaluatePolicy(
|
|
.deviceOwnerAuthenticationWithBiometrics,
|
|
localizedReason: reason
|
|
)
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
/// Authenticate with biometrics or device passcode fallback.
|
|
public static func authenticateWithPasscode(reason: String = "Unlock app") async -> Bool {
|
|
let context = LAContext()
|
|
do {
|
|
return try await context.evaluatePolicy(
|
|
.deviceOwnerAuthentication,
|
|
localizedReason: reason
|
|
)
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
}
|