Files
steipete--codexbar/Sources/CodexBarCore/KeychainNoUIQuery.swift
T
2026-07-13 12:22:33 +08:00

42 lines
1.4 KiB
Swift

import Foundation
#if os(macOS)
import Darwin
import LocalAuthentication
import Security
enum KeychainNoUIQuery {
private static let uiFailPolicy = KeychainNoUIQuery.resolveUIFailPolicy()
static func apply(to query: inout [String: Any]) {
let context = LAContext()
context.interactionNotAllowed = true
query[kSecUseAuthenticationContext as String] = context
// Keep explicit UI-fail policy for legacy keychain behavior on macOS where
// `interactionNotAllowed` alone can still surface Allow/Deny prompts.
query[kSecUseAuthenticationUI as String] = self.uiFailPolicy as CFString
}
static func uiFailPolicyForTesting() -> String {
self.uiFailPolicy
}
private static func resolveUIFailPolicy() -> String {
// Resolve the Security symbol at runtime to preserve the true constant value
// without directly referencing deprecated API at compile time.
let securityPath = "/System/Library/Frameworks/Security.framework/Security"
guard let handle = dlopen(securityPath, RTLD_NOW) else {
return "u_AuthUIF"
}
defer { dlclose(handle) }
guard let symbol = dlsym(handle, "kSecUseAuthenticationUIFail") else {
return "u_AuthUIF"
}
let valuePointer = symbol.assumingMemoryBound(to: CFString?.self)
return (valuePointer.pointee as String?) ?? "u_AuthUIF"
}
}
#endif