From 09c3ae91830bd9c7543b401b19f8c65a15205d32 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Thu, 5 Mar 2026 15:03:37 +0000 Subject: fix(whoami): detect and fall back to system git config for nostr login Add GitSystem to SignerInfoSource so credentials stored in the system git config (/etc/gitconfig) are included in the priority fallback chain (local > global > system) and shown as a separate level in whoami output. --- src/lib/git/mod.rs | 16 ++++++++++++++++ src/lib/login/existing.rs | 35 ++++++++++++++++++++++++++++++++--- src/lib/login/mod.rs | 2 ++ 3 files changed, 50 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs index 23fa5f0..ca7aa3f 100644 --- a/src/lib/git/mod.rs +++ b/src/lib/git/mod.rs @@ -1089,6 +1089,22 @@ pub fn get_git_config_item(git_repo: &Option<&Repo>, item: &str) -> Result Result> { + let config = git2::Config::open_default().context("failed to open git config")?; + // Try system level first, then ProgramData (Windows equivalent) + for level in [git2::ConfigLevel::System, git2::ConfigLevel::ProgramData] { + if let Ok(level_config) = config.open_level(level) { + match level_config.get_entry(item) { + Ok(entry) => return Ok(entry.value().map(|v| v.to_string())), + Err(_) => continue, + } + } + } + Ok(None) +} + pub fn save_git_config_item(git_repo: &Option<&Repo>, item: &str, value: &str) -> Result<()> { if let Some(git_repo) = git_repo { git_repo.save_git_config_item(item, value, false) diff --git a/src/lib/login/existing.rs b/src/lib/login/existing.rs index e60621d..2e45ca4 100644 --- a/src/lib/login/existing.rs +++ b/src/lib/login/existing.rs @@ -18,7 +18,7 @@ use crate::client::MockConnect; use crate::{ cli_interactor::{Interactor, InteractorPrompt, PromptPasswordParms}, client::fetch_public_key, - git::{Repo, RepoActions, get_git_config_item}, + git::{Repo, RepoActions, get_git_config_item, get_git_config_item_system}, }; /// load signer from git config and UserProfile from cache or relays @@ -62,7 +62,8 @@ pub async fn load_existing_login( Ok((signer, user_ref, source)) } -/// priority order: cli arguments, local git config, global git config +/// priority order: cli arguments, local git config, global git config, system +/// git config pub fn get_signer_info( git_repo: &Option<&Repo>, signer_info: &Option, @@ -82,6 +83,7 @@ pub fn get_signer_info( SignerInfoSource::CommandLineArguments, SignerInfoSource::GitLocal, SignerInfoSource::GitGlobal, + SignerInfoSource::GitSystem, ] } { if let Ok(res) = @@ -91,7 +93,7 @@ pub fn get_signer_info( break; } } - result.context("failed to get or find signer info in cli arguments, local git config or global git config")? + result.context("failed to get or find signer info in cli arguments, local git config, global git config or system git config")? } Some(SignerInfoSource::CommandLineArguments) => { if let Some(signer_info) = signer_info { @@ -158,6 +160,33 @@ pub fn get_signer_info( bail!("no signer info in global git config") } } + Some(SignerInfoSource::GitSystem) => { + if let Some(nsec) = get_git_config_item_system("nostr.nsec") + .context("failed to get system git config")? + { + ( + SignerInfo::Nsec { + nsec: nsec.to_string(), + password: password.clone(), + npub: get_git_config_item_system("nostr.npub") + .context("failed to get system git config")?, + }, + SignerInfoSource::GitSystem, + ) + } else if let Some(bunker_uri) = get_git_config_item_system("nostr.bunker-uri") + .context("failed to get system git config")? + { + (SignerInfo::Bunker { + bunker_uri, bunker_app_key: get_git_config_item_system("nostr.bunker-app-key") + .context("failed to get system git config")? + .context("system git config item nostr.bunker-uri exists but nostr.bunker-app-key doesn't")?, + npub: get_git_config_item_system("nostr.npub") + .context("failed to get system git config")?, + }, SignerInfoSource::GitSystem) + } else { + bail!("no signer info in system git config") + } + } }) } diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs index 47847c3..938cec4 100644 --- a/src/lib/login/mod.rs +++ b/src/lib/login/mod.rs @@ -65,6 +65,7 @@ pub enum SignerInfo { pub enum SignerInfoSource { GitLocal, GitGlobal, + GitSystem, CommandLineArguments, } @@ -91,6 +92,7 @@ fn print_logged_in_as( SignerInfoSource::CommandLineArguments => " via cli arguments", SignerInfoSource::GitLocal => " to local repository", SignerInfoSource::GitGlobal => "", + SignerInfoSource::GitSystem => " via system git config", } ); Ok(()) -- cgit v1.2.3