From 678b13baeb52983b1d6359d607e9445086bce9cf Mon Sep 17 00:00:00 2001 From: Alexander Chen Date: Sat, 21 Mar 2026 23:35:44 -0700 Subject: [PATCH 1/2] Fix tracking config hydration when secrets are stored in config file The hydrateConfig function was incorrectly loading secrets from keyring whenever TrackingKey or AdminKey was empty in the config file, even if SecretsInKeyring was set to false. This caused keys stored in the config file to be overwritten with empty values from keyring lookups. Now, secrets are only loaded from keyring when SecretsInKeyring is true. When secrets are stored in the config file directly, they are preserved and used as-is. Fixes: gog gmail track opens returning 'unauthorized: admin key may be incorrect' when keys are stored in config file rather than keyring. --- internal/tracking/config.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/tracking/config.go b/internal/tracking/config.go index 2b9ff9e4..bf8cc47f 100644 --- a/internal/tracking/config.go +++ b/internal/tracking/config.go @@ -181,17 +181,18 @@ func (c *Config) IsConfigured() bool { } func hydrateConfig(account string, cfg *Config) (*Config, error) { - if strings.TrimSpace(cfg.TrackingKey) == "" || strings.TrimSpace(cfg.AdminKey) == "" || cfg.SecretsInKeyring { + // Only load from keyring if explicitly configured to do so + if cfg.SecretsInKeyring { trackingKey, adminKey, secretErr := LoadSecrets(account) if secretErr != nil { return nil, secretErr } - if strings.TrimSpace(cfg.TrackingKey) == "" { + if strings.TrimSpace(trackingKey) != "" { cfg.TrackingKey = trackingKey } - if strings.TrimSpace(cfg.AdminKey) == "" { + if strings.TrimSpace(adminKey) != "" { cfg.AdminKey = adminKey } } From fac4d254804e32355dd5a68f729af4a0828a12c1 Mon Sep 17 00:00:00 2001 From: Alexander Chen Date: Sat, 21 Mar 2026 23:43:06 -0700 Subject: [PATCH 2/2] Fix tracking config hydration when secrets stored in config file The hydrateConfig function incorrectly loaded secrets from keyring whenever TrackingKey or AdminKey was empty, even if SecretsInKeyring was false. This overwrote valid config file keys with empty values. Fix: Only load from keyring when SecretsInKeyring is explicitly true. Add backward compatibility fallback for legacy configs that have keys in keyring but no SecretsInKeyring flag (defaults to false in Go). Changes: - Check SecretsInKeyring before attempting keyring lookup - If SecretsInKeyring=false but both keys are empty, fallback to keyring (legacy behavior for older configs) - Only overwrite config values if keyring returns non-empty values Fixes: gog gmail track opens 'unauthorized' when keys in config file --- internal/tracking/config.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/tracking/config.go b/internal/tracking/config.go index bf8cc47f..78e3128c 100644 --- a/internal/tracking/config.go +++ b/internal/tracking/config.go @@ -181,8 +181,17 @@ func (c *Config) IsConfigured() bool { } func hydrateConfig(account string, cfg *Config) (*Config, error) { - // Only load from keyring if explicitly configured to do so - if cfg.SecretsInKeyring { + shouldLoadFromKeyring := cfg.SecretsInKeyring + + // Backward compat: if no SecretsInKeyring flag but keys are empty, + // try keyring as fallback (legacy behavior) + if !shouldLoadFromKeyring && + strings.TrimSpace(cfg.TrackingKey) == "" && + strings.TrimSpace(cfg.AdminKey) == "" { + shouldLoadFromKeyring = true + } + + if shouldLoadFromKeyring { trackingKey, adminKey, secretErr := LoadSecrets(account) if secretErr != nil { return nil, secretErr