import Foundation #if canImport(SweetCookieKit) import SweetCookieKit #endif public enum KeychainAccessGate { private static let flagKey = "debugDisableKeychainAccess" static let disableAccessEnvironmentKey = "CODEXBAR_DISABLE_KEYCHAIN_ACCESS" @TaskLocal private static var taskOverrideValue: Bool? private nonisolated(unsafe) static var overrideValue: Bool? private static let processForceDisabledLock = NSLock() private nonisolated(unsafe) static var processForceDisabledReason: String? public nonisolated(unsafe) static var isDisabled: Bool { get { if let taskOverrideValue { return taskOverrideValue } if self.isDisabledByEnvironment() { return true } #if DEBUG if Self.forcesDisabledUnderTests { return true } #endif if self.processDisableReason != nil { return true } if let overrideValue { return overrideValue } if UserDefaults.standard.bool(forKey: Self.flagKey) { return true } if let shared = AppGroupSupport.sharedDefaults(), shared.bool(forKey: Self.flagKey) { return true } return false } set { overrideValue = newValue #if os(macOS) && canImport(SweetCookieKit) BrowserCookieKeychainAccessGate.isDisabled = self.isDisabled #endif } } static func isDisabledByEnvironment( _ environment: [String: String] = ProcessInfo.processInfo.environment) -> Bool { environment[self.disableAccessEnvironmentKey] == "1" } public static func forceDisabledForProcess(reason: String) { self.processForceDisabledLock.lock() self.processForceDisabledReason = reason self.processForceDisabledLock.unlock() #if os(macOS) && canImport(SweetCookieKit) BrowserCookieKeychainAccessGate.isDisabled = self.isDisabled #endif } public static var processDisableReason: String? { self.processForceDisabledLock.lock() defer { self.processForceDisabledLock.unlock() } return self.processForceDisabledReason } #if DEBUG private nonisolated(unsafe) static var forcesDisabledUnderTests: Bool { KeychainTestSafety.shouldBlockRealKeychainAccess() } #endif static func withTaskOverrideForTesting( _ disabled: Bool?, operation: () throws -> T) rethrows -> T { try self.$taskOverrideValue.withValue(disabled) { try operation() } } static func withTaskOverrideForTesting( _ disabled: Bool?, isolation _: isolated (any Actor)? = #isolation, operation: () async throws -> T) async rethrows -> T { try await self.$taskOverrideValue.withValue(disabled) { try await operation() } } static var currentOverrideForTesting: Bool? { self.taskOverrideValue ?? self.overrideValue } #if DEBUG static func resetOverrideForTesting() { self.overrideValue = nil self.processForceDisabledLock.lock() self.processForceDisabledReason = nil self.processForceDisabledLock.unlock() #if os(macOS) && canImport(SweetCookieKit) BrowserCookieKeychainAccessGate.isDisabled = self.isDisabled #endif } #endif }