diff options
| author | bndw <ben@bdw.to> | 2026-02-14 09:58:28 -0800 |
|---|---|---|
| committer | bndw <ben@bdw.to> | 2026-02-14 09:58:28 -0800 |
| commit | d30459513ec44ab298fafd1bfe0edc08d6ab62e4 (patch) | |
| tree | 1e4442f940c11544cd60b6bf72f2038338da67ce /internal/auth | |
| parent | fe3708eaf495613cc6e2340b821795f25811d6ed (diff) | |
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.
Diffstat (limited to 'internal/auth')
| -rw-r--r-- | internal/auth/README.md | 4 | ||||
| -rw-r--r-- | internal/auth/interceptor.go | 13 |
2 files changed, 10 insertions, 7 deletions
diff --git a/internal/auth/README.md b/internal/auth/README.md index c41b6cb..df0de6a 100644 --- a/internal/auth/README.md +++ b/internal/auth/README.md | |||
| @@ -209,7 +209,9 @@ authOpts := &auth.InterceptorOptions{ | |||
| 209 | - **`TimestampWindow`**: Maximum age of events in seconds (default: 60) | 209 | - **`TimestampWindow`**: Maximum age of events in seconds (default: 60) |
| 210 | - **`Required`**: Whether to reject unauthenticated requests (default: false) | 210 | - **`Required`**: Whether to reject unauthenticated requests (default: false) |
| 211 | - **`ValidatePayload`**: Whether to verify payload hash when present (default: false) | 211 | - **`ValidatePayload`**: Whether to verify payload hash when present (default: false) |
| 212 | - **`AllowedPubkeys`**: Optional whitelist of allowed pubkeys (nil = allow all) | 212 | - **`AllowedNpubs`**: Optional whitelist of allowed pubkeys (nil = allow all) |
| 213 | - Config accepts npub format only (human-readable bech32) | ||
| 214 | - Automatically normalized to hex format (computer-readable) at config load time | ||
| 213 | 215 | ||
| 214 | ### NostrCredentials Options | 216 | ### NostrCredentials Options |
| 215 | 217 | ||
diff --git a/internal/auth/interceptor.go b/internal/auth/interceptor.go index c055a15..7d785bf 100644 --- a/internal/auth/interceptor.go +++ b/internal/auth/interceptor.go | |||
| @@ -35,10 +35,11 @@ type InterceptorOptions struct { | |||
| 35 | // Default: false | 35 | // Default: false |
| 36 | ValidatePayload bool | 36 | ValidatePayload bool |
| 37 | 37 | ||
| 38 | // AllowedPubkeys is an optional whitelist of allowed pubkeys. | 38 | // AllowedNpubs is an optional whitelist of allowed pubkeys (hex format). |
| 39 | // Config accepts npub format only, normalized to hex at load time. | ||
| 39 | // If nil or empty, all valid signatures are accepted. | 40 | // If nil or empty, all valid signatures are accepted. |
| 40 | // Default: nil (allow all) | 41 | // Default: nil (allow all) |
| 41 | AllowedPubkeys []string | 42 | AllowedNpubs []string |
| 42 | 43 | ||
| 43 | // SkipMethods is a list of gRPC methods that bypass authentication. | 44 | // SkipMethods is a list of gRPC methods that bypass authentication. |
| 44 | // Useful for public endpoints like health checks or relay info. | 45 | // Useful for public endpoints like health checks or relay info. |
| @@ -53,7 +54,7 @@ func DefaultInterceptorOptions() *InterceptorOptions { | |||
| 53 | TimestampWindow: 60, | 54 | TimestampWindow: 60, |
| 54 | Required: false, | 55 | Required: false, |
| 55 | ValidatePayload: false, | 56 | ValidatePayload: false, |
| 56 | AllowedPubkeys: nil, | 57 | AllowedNpubs: nil, |
| 57 | SkipMethods: nil, | 58 | SkipMethods: nil, |
| 58 | } | 59 | } |
| 59 | } | 60 | } |
| @@ -168,9 +169,9 @@ func validateAuthFromContext(ctx context.Context, method string, opts *Intercept | |||
| 168 | // Extract pubkey | 169 | // Extract pubkey |
| 169 | pubkey := ExtractPubkey(event) | 170 | pubkey := ExtractPubkey(event) |
| 170 | 171 | ||
| 171 | // Check whitelist if configured | 172 | // Check whitelist if configured (all values are already normalized to hex) |
| 172 | if len(opts.AllowedPubkeys) > 0 { | 173 | if len(opts.AllowedNpubs) > 0 { |
| 173 | if !contains(opts.AllowedPubkeys, pubkey) { | 174 | if !contains(opts.AllowedNpubs, pubkey) { |
| 174 | return "", fmt.Errorf("pubkey not in whitelist") | 175 | return "", fmt.Errorf("pubkey not in whitelist") |
| 175 | } | 176 | } |
| 176 | } | 177 | } |
