From f2ef3568557a49d4067b71374603729180968f20 Mon Sep 17 00:00:00 2001 From: Kieran Klukas Date: Sun, 23 Nov 2025 14:45:53 -0500 Subject: [PATCH] fix(config): use platform-specific keyring features and standardize config path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use apple-native keyring feature on macOS instead of linux-only sync-secret-service - Use windows-native keyring feature on Windows - Move config directory to ~/.config/tangled on all platforms for consistency - Improve keychain error messages 💘 Generated with Crush Assisted-by: Claude Sonnet 4.5 via Crush --- Cargo.lock | 33 ++++++++++++++++++++++++--- Cargo.toml | 2 +- crates/tangled-config/Cargo.toml | 10 +++++++- crates/tangled-config/src/config.rs | 11 ++++++--- crates/tangled-config/src/keychain.rs | 4 ++-- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b17b8c..617a935 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,6 +387,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1117,9 +1127,13 @@ version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c" dependencies = [ + "byteorder", "dbus-secret-service", "log", "openssl", + "security-framework 2.11.1", + "security-framework 3.5.1", + "windows-sys 0.60.2", "zeroize", ] @@ -1316,7 +1330,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -1831,7 +1845,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -2055,7 +2082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 383acc3..1a603b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ console = "0.15" # Storage dirs = "5.0" -keyring = { version = "3.6", features = ["sync-secret-service", "vendored"] } +keyring = "3.6" # Error Handling anyhow = "1.0" diff --git a/crates/tangled-config/Cargo.toml b/crates/tangled-config/Cargo.toml index 94445e4..9718d92 100644 --- a/crates/tangled-config/Cargo.toml +++ b/crates/tangled-config/Cargo.toml @@ -8,9 +8,17 @@ license = "MIT OR Apache-2.0" [dependencies] anyhow = { workspace = true } dirs = { workspace = true } -keyring = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } toml = { workspace = true } chrono = { workspace = true } +[target.'cfg(target_os = "macos")'.dependencies] +keyring = { workspace = true, features = ["apple-native"] } + +[target.'cfg(target_os = "linux")'.dependencies] +keyring = { workspace = true, features = ["sync-secret-service", "vendored"] } + +[target.'cfg(target_os = "windows")'.dependencies] +keyring = { workspace = true, features = ["windows-native"] } + diff --git a/crates/tangled-config/src/config.rs b/crates/tangled-config/src/config.rs index 660e707..d5f2fa6 100644 --- a/crates/tangled-config/src/config.rs +++ b/crates/tangled-config/src/config.rs @@ -2,7 +2,6 @@ use std::fs; use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; -use dirs::config_dir; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -55,8 +54,14 @@ pub struct UiSection { } pub fn default_config_path() -> Result { - let base = config_dir().context("Could not determine platform config directory")?; - Ok(base.join("tangled").join("config.toml")) + // Use ~/.config/tangled on all platforms for consistency + let home = std::env::var("HOME") + .or_else(|_| std::env::var("USERPROFILE")) + .context("Could not determine home directory")?; + Ok(PathBuf::from(home) + .join(".config") + .join("tangled") + .join("config.toml")) } pub fn load_config(path: Option<&Path>) -> Result> { diff --git a/crates/tangled-config/src/keychain.rs b/crates/tangled-config/src/keychain.rs index 7bf4b6d..f0691f8 100644 --- a/crates/tangled-config/src/keychain.rs +++ b/crates/tangled-config/src/keychain.rs @@ -21,13 +21,13 @@ impl Keychain { pub fn set_password(&self, secret: &str) -> Result<()> { self.entry()? .set_password(secret) - .map_err(|e| anyhow!("keyring error: {e}")) + .map_err(|e| anyhow!("Failed to save credentials to keychain: {e}")) } pub fn get_password(&self) -> Result { self.entry()? .get_password() - .map_err(|e| anyhow!("keyring error: {e}")) + .map_err(|e| anyhow!("Failed to load credentials from keychain: {e}")) } pub fn delete_password(&self) -> Result<()> { -- 2.50.1 (Apple Git-155)