feat(jellyfin): user views and current-user endpoints

This commit is contained in:
Deluan 2026-07-05 15:07:43 -04:00
commit aacc46f7f5
3 changed files with 79 additions and 1 deletions

View file

@ -48,10 +48,14 @@ func (api *Router) routes() http.Handler {
r.Post("/System/Ping", api.ping)
r.Get("/QuickConnect/Enabled", api.quickConnectEnabled)
r.Post("/Users/AuthenticateByName", api.authenticateByName)
r.Get("/Users/Public", api.getPublicUsers)
r.Group(func(r chi.Router) {
r.Use(api.authenticate)
// authenticated endpoints are registered by later tasks
r.Get("/UserViews", api.getUserViews)
r.Get("/Users/{userId}/Views", api.getUserViews)
r.Get("/Users/Me", api.getCurrentUser)
r.Get("/Users/{userId}", api.getCurrentUser)
})
return r

31
server/jellyfin/users.go Normal file
View file

@ -0,0 +1,31 @@
package jellyfin
import (
"net/http"
"github.com/navidrome/navidrome/model/request"
"github.com/navidrome/navidrome/server/jellyfin/dto"
)
const musicViewID = "music"
func (api *Router) getUserViews(w http.ResponseWriter, r *http.Request) {
view := dto.BaseItemDto{
Name: api.serverName(),
Id: musicViewID,
Type: "CollectionFolder",
CollectionType: "music",
IsFolder: true,
BackdropImageTags: []string{},
}
api.ok(w, r, dto.QueryResult{Items: []dto.BaseItemDto{view}, TotalRecordCount: 1, StartIndex: 0})
}
func (api *Router) getCurrentUser(w http.ResponseWriter, r *http.Request) {
u, _ := request.UserFrom(r.Context())
api.ok(w, r, userToDto(&u, api.serverName()))
}
func (api *Router) getPublicUsers(w http.ResponseWriter, r *http.Request) {
api.ok(w, r, []dto.UserDto{}) // manual login only
}

View file

@ -0,0 +1,43 @@
package jellyfin
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/model/request"
"github.com/navidrome/navidrome/server/jellyfin/dto"
"github.com/navidrome/navidrome/tests"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Users", func() {
var api *Router
authed := func(r *http.Request) *http.Request {
ctx := request.WithUser(context.Background(), model.User{ID: "u1", UserName: "alice"})
return r.WithContext(ctx)
}
BeforeEach(func() { api = &Router{ds: &tests.MockDataStore{}} })
It("returns a single music view", func() {
w := httptest.NewRecorder()
api.getUserViews(w, authed(httptest.NewRequest("GET", "/UserViews", nil)))
Expect(w.Code).To(Equal(http.StatusOK))
var res dto.QueryResult
Expect(json.Unmarshal(w.Body.Bytes(), &res)).To(Succeed())
Expect(res.Items).To(HaveLen(1))
Expect(res.Items[0].CollectionType).To(Equal("music"))
Expect(res.Items[0].Type).To(Equal("CollectionFolder"))
})
It("returns the current user", func() {
w := httptest.NewRecorder()
api.getCurrentUser(w, authed(httptest.NewRequest("GET", "/Users/Me", nil)))
var u dto.UserDto
Expect(json.Unmarshal(w.Body.Bytes(), &u)).To(Succeed())
Expect(u.Name).To(Equal("alice"))
})
})