import Foundation import Security /// Native cookies, separate from WebKit and scoped to one configured origin. struct NativeSessionVault: Sendable { let origin: String private var query: [String: Any] { [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: "community.yuvomi.mobile.native-session", kSecAttrAccount as String: origin, ] } func load() -> Data? { var request = query request[kSecReturnData as String] = true request[kSecMatchLimit as String] = kSecMatchLimitOne var result: CFTypeRef? guard SecItemCopyMatching(request as CFDictionary, &result) == errSecSuccess else { return nil } return result as? Data } func save(_ data: Data) throws { let attributes: [String: Any] = [ kSecValueData as String: data, kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, ] let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary) if status == errSecItemNotFound { var request = query for (key, value) in attributes { request[key] = value } guard SecItemAdd(request as CFDictionary, nil) == errSecSuccess else { throw NativeAPIError.unavailable } } else if status != errSecSuccess { throw NativeAPIError.unavailable } } func clear() throws { let status = SecItemDelete(query as CFDictionary) guard status == errSecSuccess || status == errSecItemNotFound else { throw NativeAPIError.unavailable } } }