fix: address code review findings
This commit is contained in:
@@ -7,12 +7,25 @@ import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"naviwatcher/internal/config"
|
||||
"naviwatcher/internal/database"
|
||||
"naviwatcher/internal/scanner"
|
||||
)
|
||||
|
||||
// idPattern bounds the {id} path segment accepted by artist routes. Artist IDs
|
||||
// come from Navidrome (numeric/UUID) and MusicBrainz (UUID), so word
|
||||
// characters and hyphens cover every legitimate value. Rejecting anything else
|
||||
// prevents a crafted id (containing "/", control characters, or whitespace)
|
||||
// from breaking route matching or being reflected into a Location header.
|
||||
var idPattern = regexp.MustCompile(`^[\w-]+$`)
|
||||
|
||||
// isValidID reports whether s is a safe artist-ID path segment.
|
||||
func isValidID(s string) bool {
|
||||
return idPattern.MatchString(s)
|
||||
}
|
||||
|
||||
//go:embed templates/*.html
|
||||
var templates embed.FS
|
||||
|
||||
@@ -84,7 +97,7 @@ func (s *Server) handleArtist(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// The enhanced ServeMux extracts the {id} path segment for us.
|
||||
id := r.PathValue("id")
|
||||
if id == "" {
|
||||
if id == "" || !isValidID(id) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
@@ -156,7 +169,7 @@ func (s *Server) buildArtistData(ctx context.Context, id string) (*ArtistData, e
|
||||
|
||||
// ArchiveData is the view model for the ignored-releases archive page.
|
||||
type ArchiveData struct {
|
||||
Releases []MissingReleaseView
|
||||
Releases []MissingReleaseView
|
||||
UIBaseURL string
|
||||
}
|
||||
|
||||
@@ -196,15 +209,27 @@ func (s *Server) handleArchive(w http.ResponseWriter, r *http.Request) {
|
||||
// *config.Config (mirroring how the app constructs other components). It
|
||||
// forwards the server sub-config and derives uiBaseURL from the configured
|
||||
// public_url, falling back to a best-effort host:port.
|
||||
// ResolveUIBaseURL derives the externally-reachable base URL of the Web UI from
|
||||
// config. An explicit public_url (e.g. behind a reverse proxy) is preferred.
|
||||
// When unset, it falls back to http://host:port — unless the bind host is the
|
||||
// unspecified "0.0.0.0" (not reachable from outside the host), in which case an
|
||||
// empty string is returned so callers omit the link rather than advertise an
|
||||
// unusable address. The same derivation is used by both the Web UI and the
|
||||
// Telegram notifier so dashboard links are consistent across surfaces.
|
||||
func ResolveUIBaseURL(cfg *config.ServerConfig) string {
|
||||
base := cfg.PublicURL
|
||||
if base == "" && cfg.Host != "0.0.0.0" && cfg.Host != "" {
|
||||
base = fmt.Sprintf("http://%s:%d", cfg.Host, cfg.Port)
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
func NewServerWithConfig(cfg *config.Config, db *database.DB) *Server {
|
||||
// Prefer an explicit, externally-reachable public_url (e.g. behind a
|
||||
// reverse proxy). Fall back to host:port — but if the bind host is the
|
||||
// unspecified "0.0.0.0", it is not reachable from outside the host, so
|
||||
// omit the link rather than advertise an unusable address.
|
||||
base := cfg.Server.PublicURL
|
||||
if base == "" && cfg.Server.Host != "0.0.0.0" && cfg.Server.Host != "" {
|
||||
base = fmt.Sprintf("http://%s:%d", cfg.Server.Host, cfg.Server.Port)
|
||||
}
|
||||
base := ResolveUIBaseURL(&cfg.Server)
|
||||
return NewServer(&cfg.Server, db, base, cfg.Scanner.FuzzyThreshold)
|
||||
}
|
||||
|
||||
@@ -219,7 +244,7 @@ func (s *Server) ignoreOrRestore(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
id := r.PathValue("id")
|
||||
if id == "" {
|
||||
if id == "" || !isValidID(id) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
@@ -270,7 +295,7 @@ func (s *Server) toggleIgnoreSingles(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
id := r.PathValue("id")
|
||||
if id == "" {
|
||||
if id == "" || !isValidID(id) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
@@ -289,4 +314,3 @@ func (s *Server) toggleIgnoreSingles(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
http.Redirect(w, r, "/artist/"+id, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user