const std = @import("std"); /// Secure credential storage using macOS Keychain pub const SecureStorage = struct { const ServiceName = "com.fetchml.cli"; /// Store API key in macOS Keychain pub fn storeApiKey(api_key: []const u8) !void { const result = std.process.Child.run(.{ .allocator = std.heap.page_allocator, .argv = &.{ "security", "add-generic-password", "-s", ServiceName, "-a", "api_key", "-w", api_key, "-U", }, }) catch return error.KeychainError; if (result.term.Exited != 0) { return error.KeychainError; } } /// Retrieve API key from macOS Keychain pub fn retrieveApiKey(allocator: std.mem.Allocator) !?[]u8 { const result = std.process.Child.run(.{ .allocator = allocator, .argv = &.{ "security", "find-generic-password", "-s", ServiceName, "-a", "api_key", "-w", }, }) catch return null; if (result.term.Exited != 0) { return null; } const stdout = result.stdout; if (stdout.len > 0 and stdout[stdout.len - 1] == '\n') { return try allocator.dupe(u8, stdout[0 .. stdout.len - 1]); } return try allocator.dupe(u8, stdout); } /// Delete stored API key pub fn deleteApiKey() void { _ = std.process.Child.run(.{ .allocator = std.heap.page_allocator, .argv = &.{ "security", "delete-generic-password", "-s", ServiceName, "-a", "api_key", }, }) catch {}; } };