From 3f15f1f78d5a61de55b09ec8450e012bfa40b7bd Mon Sep 17 00:00:00 2001 From: enki Date: Sun, 11 May 2025 22:33:14 -0700 Subject: [PATCH] more config and auth fixes --- internal/auth/auth.go | 59 ++++++++++++++++++++++++++++++++++------ internal/utils/nip-19.go | 15 ++++++++++ web/assets/js/content.js | 4 +++ 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 2ea00ac..c1df7b9 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -13,6 +13,7 @@ import ( "github.com/nbd-wtf/go-nostr" "git.sovbit.dev/Enki/nostr-poster/internal/db" + "git.sovbit.dev/Enki/nostr-poster/internal/utils" "go.uber.org/zap" ) @@ -69,11 +70,30 @@ func NewService(db *db.DB, logger *zap.Logger, secretKey string, tokenDuration t // Login handles user login with a Nostr signature func (s *Service) Login(pubkey, signature, eventJSON string) (string, error) { // Check if there's a whitelist and enforce it - if s.allowedNpub != "" && s.allowedNpub != pubkey { - s.logger.Warn("Login attempt from non-whitelisted pubkey", - zap.String("attempt_pubkey", pubkey), - zap.String("allowed_npub", s.allowedNpub)) - return "", errors.New("unauthorized: only the configured npub is allowed to log in") + if s.allowedNpub != "" { + // If the allowed value starts with "npub", we need to decode it to hex + allowedHexPubkey := s.allowedNpub + if strings.HasPrefix(s.allowedNpub, "npub") { + // Try to decode the npub to hex + decodedPubkey, err := utils.DecodeNpub(s.allowedNpub) + if err != nil { + s.logger.Error("Failed to decode allowed_npub", + zap.String("allowed_npub", s.allowedNpub), + zap.Error(err)) + // If we can't decode, we'll just use the original value + } else { + allowedHexPubkey = decodedPubkey + } + } + + // Compare with the provided pubkey + if allowedHexPubkey != pubkey { + s.logger.Warn("Login attempt from non-whitelisted pubkey", + zap.String("attempt_pubkey", pubkey), + zap.String("allowed_pubkey", allowedHexPubkey), + zap.String("allowed_npub", s.allowedNpub)) + return "", errors.New("unauthorized: only the configured npub is allowed to log in") + } } // Parse the event @@ -116,24 +136,45 @@ func (s *Service) Login(pubkey, signature, eventJSON string) (string, error) { func (s *Service) VerifyToken(tokenStr string) (string, error) { // Remove the "Bearer " prefix if present tokenStr = strings.TrimPrefix(tokenStr, "Bearer ") - + // Decode the token tokenData, err := base64.StdEncoding.DecodeString(tokenStr) if err != nil { return "", ErrInvalidToken } - + // Parse the token var token Token if err := json.Unmarshal(tokenData, &token); err != nil { return "", ErrInvalidToken } - + // Check if the token has expired if time.Now().After(token.ExpiresAt) { return "", ErrTokenExpired } - + + // Additional check for whitelist if it's configured + if s.allowedNpub != "" { + // If the allowed value starts with "npub", we need to decode it to hex + allowedHexPubkey := s.allowedNpub + if strings.HasPrefix(s.allowedNpub, "npub") { + // Try to decode the npub to hex + decodedPubkey, err := utils.DecodeNpub(s.allowedNpub) + if err == nil { + allowedHexPubkey = decodedPubkey + } + } + + // Compare with the token's pubkey + if allowedHexPubkey != token.Pubkey { + s.logger.Warn("Token verification from non-whitelisted pubkey", + zap.String("token_pubkey", token.Pubkey), + zap.String("allowed_pubkey", allowedHexPubkey)) + return "", errors.New("unauthorized: token is for a non-whitelisted pubkey") + } + } + return token.Pubkey, nil } diff --git a/internal/utils/nip-19.go b/internal/utils/nip-19.go index 8ffae14..4436175 100644 --- a/internal/utils/nip-19.go +++ b/internal/utils/nip-19.go @@ -27,4 +27,19 @@ func EncodePubkey(pubkey string) (string, error) { return "", err } return npub, nil +} + +// DecodeNpub decodes a NIP-19 "npub" identifier into a public key +func DecodeNpub(npub string) (string, error) { + prefix, data, err := nip19.Decode(npub) + if err != nil { + return "", err + } + + if prefix != "npub" { + return "", err + } + + // Return the hex pubkey + return data.(string), nil } \ No newline at end of file diff --git a/web/assets/js/content.js b/web/assets/js/content.js index 447d1d4..8d9525b 100644 --- a/web/assets/js/content.js +++ b/web/assets/js/content.js @@ -1,4 +1,8 @@ // content.js - JavaScript for the content management page + +// Define API_ENDPOINT (same as in main.js) +const API_ENDPOINT = ""; // Empty string means use the current domain + document.addEventListener('DOMContentLoaded', () => { // =================================================== // Global Variables