From d30459513ec44ab298fafd1bfe0edc08d6ab62e4 Mon Sep 17 00:00:00 2001 From: bndw Date: Sat, 14 Feb 2026 09:58:28 -0800 Subject: feat: rename allowed_pubkeys to allowed_npubs with normalization - Config now accepts npub format only (human-readable) - Automatically converts npubs to hex pubkeys at load time - Updated InterceptorOptions.AllowedPubkeys -> AllowedNpubs - Added validation to reject hex format in config (npub only) - Updated documentation to clarify npub-only config - Added comprehensive tests for npub normalization Config is for humans (npub), internal code uses hex pubkeys. --- internal/config/config.go | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'internal/config/config.go') diff --git a/internal/config/config.go b/internal/config/config.go index 91e79f7..0566537 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "northwest.io/muxstr/internal/nostr" "gopkg.in/yaml.v3" ) @@ -41,7 +42,7 @@ type AuthConfig struct { Enabled bool `yaml:"enabled"` Required bool `yaml:"required"` TimestampWindow int64 `yaml:"timestamp_window"` - AllowedPubkeys []string `yaml:"allowed_pubkeys"` + AllowedNpubs []string `yaml:"allowed_npubs"` // npub format only (bech32) - normalized to hex internally SkipMethods []string `yaml:"skip_methods"` } @@ -162,6 +163,11 @@ func Load(filename string) (*Config, error) { // Apply environment variable overrides applyEnvOverrides(cfg) + // Normalize npubs to hex pubkeys + if err := normalizeNpubs(cfg); err != nil { + return nil, fmt.Errorf("failed to normalize npubs: %w", err) + } + // Validate if err := cfg.Validate(); err != nil { return nil, fmt.Errorf("invalid configuration: %w", err) @@ -170,6 +176,41 @@ func Load(filename string) (*Config, error) { return cfg, nil } +// normalizeNpubs converts all npub (bech32) pubkeys to hex format. +// Config only accepts npub format (human-readable), which is converted +// to hex format (computer-readable) for internal use. +func normalizeNpubs(cfg *Config) error { + if len(cfg.Auth.AllowedNpubs) == 0 { + return nil + } + + normalized := make([]string, 0, len(cfg.Auth.AllowedNpubs)) + for _, npub := range cfg.Auth.AllowedNpubs { + // Skip empty strings + npub = strings.TrimSpace(npub) + if npub == "" { + continue + } + + // Validate npub format + if !strings.HasPrefix(npub, "npub1") { + return fmt.Errorf("invalid npub format %q: must start with 'npub1'", npub) + } + + // Parse npub to get hex pubkey + key, err := nostr.ParsePublicKey(npub) + if err != nil { + return fmt.Errorf("invalid npub %q: %w", npub, err) + } + + // Get the hex representation for internal use + normalized = append(normalized, key.Public()) + } + + cfg.Auth.AllowedNpubs = normalized + return nil +} + // Validate validates the configuration. func (c *Config) Validate() error { // Validate server addresses @@ -251,8 +292,8 @@ func applyEnvOverrides(cfg *Config) { cfg.Auth.TimestampWindow = n } } - if val := os.Getenv("MUXSTR_AUTH_ALLOWED_PUBKEYS"); val != "" { - cfg.Auth.AllowedPubkeys = strings.Split(val, ",") + if val := os.Getenv("MUXSTR_AUTH_ALLOWED_NPUBS"); val != "" { + cfg.Auth.AllowedNpubs = strings.Split(val, ",") } // Rate limit -- cgit v1.2.3