- Refactor command structure for better organization - Improve WebSocket client frame handling - Add response handler improvements - Update queue, requeue, and status commands - Add security module for CLI authentication
59 lines
1.8 KiB
Zig
59 lines
1.8 KiB
Zig
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 {};
|
|
}
|
|
};
|