refactor(auth): replace untyped JWT claims with typed Claims struct

Introduced a typed Claims struct in core/auth to replace the raw
map[string]any approach used for JWT claims throughout the codebase.
This provides compile-time safety and better readability when creating,
validating, and extracting JWT tokens. Also upgraded lestrrat-go/jwx
from v2 to v3 and go-chi/jwtauth to v5.4.0, adapting all callers to
the new API where token accessor methods now return tuples instead of
bare values. Updated all affected handlers, middleware, and tests.

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan
2026-03-02 13:15:31 -05:00
parent 3d86d44fd9
commit 82f9f88c0f
16 changed files with 284 additions and 125 deletions
+5 -14
View File
@@ -7,7 +7,6 @@ import (
"net/http"
"time"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/navidrome/navidrome/core/artwork"
"github.com/navidrome/navidrome/core/auth"
"github.com/navidrome/navidrome/log"
@@ -76,22 +75,14 @@ func decodeArtworkID(tokenString string) (model.ArtworkID, error) {
if token == nil {
return model.ArtworkID{}, errors.New("unauthorized")
}
err = jwt.Validate(token, jwt.WithRequiredClaim("id"))
if err != nil {
return model.ArtworkID{}, err
c := auth.ClaimsFromToken(token)
if c.ID == "" {
return model.ArtworkID{}, errors.New("required claim \"id\" not found")
}
claims, err := token.AsMap(context.Background())
if err != nil {
return model.ArtworkID{}, err
}
id, ok := claims["id"].(string)
if !ok {
return model.ArtworkID{}, errors.New("invalid id type")
}
artID, err := model.ParseArtworkID(id)
artID, err := model.ParseArtworkID(c.ID)
if err == nil {
return artID, nil
}
// Try to default to mediafile artworkId (if used with a mediafileShare token)
return model.ParseArtworkID("mf-" + id)
return model.ParseArtworkID("mf-" + c.ID)
}