more config and auth fixes

This commit is contained in:
Enki 2025-05-11 22:33:14 -07:00
parent a767b9d3b0
commit 3f15f1f78d
3 changed files with 69 additions and 9 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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