feat(jellyfin): advertise Jellyfin-compatible version, brand ServerName with Navidrome version

This commit is contained in:
Deluan 2026-07-05 14:38:43 -04:00
commit 2a18863c06
3 changed files with 16 additions and 4 deletions

View file

@ -856,7 +856,7 @@ func setViperDefaults() {
viper.SetDefault("listenbrainz.artistalgorithm", consts.DefaultListenBrainzArtistAlgorithm)
viper.SetDefault("listenbrainz.trackalgorithm", consts.DefaultListenBrainzTrackAlgorithm)
viper.SetDefault("jellyfin.enabled", false)
viper.SetDefault("jellyfin.servername", "Navidrome")
viper.SetDefault("jellyfin.servername", "")
viper.SetDefault("enablescrobblehistory", true)
viper.SetDefault("httpheaders.frameoptions", "DENY")
viper.SetDefault("backup.path", "")

View file

@ -2,6 +2,7 @@ package jellyfin
import (
"context"
"fmt"
"net/http"
"github.com/google/uuid"
@ -11,11 +12,16 @@ import (
"github.com/navidrome/navidrome/server/jellyfin/dto"
)
// jellyfinVersion is the Jellyfin API version we advertise in the handshake. Clients parse
// Version as a Jellyfin release and feature-gate on it, so it must stay a real Jellyfin
// version rather than Navidrome's own.
const jellyfinVersion = "10.8.13"
func (api *Router) serverName() string {
if conf.Server.Jellyfin.ServerName != "" {
return conf.Server.Jellyfin.ServerName
}
return consts.AppName
return fmt.Sprintf("Navidrome %s", consts.Version)
}
// serverID returns a stable Id that survives restarts, get-or-created in the Property table
@ -46,7 +52,7 @@ func (api *Router) serverID(ctx context.Context) string {
func (api *Router) publicInfo(ctx context.Context) dto.PublicSystemInfo {
return dto.PublicSystemInfo{
ServerName: api.serverName(),
Version: consts.Version,
Version: jellyfinVersion,
ProductName: "Jellyfin Server",
Id: api.serverID(ctx),
StartupWizardCompleted: true,

View file

@ -6,6 +6,8 @@ import (
"net/http"
"net/http/httptest"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/conf/configtest"
"github.com/navidrome/navidrome/server/jellyfin/dto"
"github.com/navidrome/navidrome/tests"
. "github.com/onsi/ginkgo/v2"
@ -17,6 +19,9 @@ var _ = Describe("System", func() {
BeforeEach(func() { api = &Router{} })
It("returns public system info without auth", func() {
DeferCleanup(configtest.SetupConfig())
conf.Server.Jellyfin.ServerName = ""
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/System/Info/Public", nil)
api.getPublicSystemInfo(w, r)
@ -26,8 +31,9 @@ var _ = Describe("System", func() {
var info dto.PublicSystemInfo
Expect(json.Unmarshal(w.Body.Bytes(), &info)).To(Succeed())
Expect(info.Id).ToNot(BeEmpty())
Expect(info.Version).ToNot(BeEmpty())
Expect(info.Version).To(Equal(jellyfinVersion))
Expect(info.ProductName).To(Equal("Jellyfin Server"))
Expect(info.ServerName).To(HavePrefix("Navidrome"))
})
It("responds to ping with the server name", func() {