Skip to content

[Feature Request] Add /auth/login authentication and related endpoints for Navidrome #46

@LittleYe233

Description

@LittleYe233

Abstract

This feature request wants to start a discussion on refactoring network request functions (i.e. sendNavidromeGETRequest()) to support more endpoints other than RESTful ones (/rest) and an optional long-term middle-data storage.

Background

Navidrome supports some "internal" API endpoints starting with /api, like /api/song, /api/album, etc., as well as basic auth endpoint /auth/login. They can provide with more details of a music library, like total count of songs and artists, but may be regarded "optional" than RESTful endpoints written in Navidrome official documentation.

However, they can still be useful in some circumstances. For example, a "Play All" / "Shuffle All" button on songs screen needs to know the total count of all songs, which is very difficult to get by RESTful pagination endpoints. By contrast, there is one in the headers of response of /api/song interface, but needs an authenticated token from /auth/login. The latter one returns with a long-term login token that enables all /api endpoints, but it may automatically rotate and need to be manually updated when the server returns 401 code.

EDIT: It has raised known issues: the default pagination size of songs is 100. If the total number of songs is larger than 100, allSongsList variable in com.craftworks.music.ui.screens.SongsScreen class will need additional updates (e.g. scrolling up the screen to trigger the next fetch), and the whole shuffle pool will shrink to a smaller size than the full song library. So this feature may become necessary if a full random play is needed. Certainly we can choose to fetch the full list by pagination and store/cache it, but it must cause a laggy loading on first use.

Implementation plans

Refactor sendNavidromeGETRequest()

Currently the signature of this function is:

suspend fun sendNavidromeGETRequest(endpoint: String, ignoreCachedResponse: Boolean = false) : List<Any>

It is well-performed with good coverage on error handlers, but heavily coupled with hardcoded endpoint prefix /rest and HTTP method GET. So it is better to write a more general request function based on it. Also need to mention that though Navidrome supports POST requests other than GET and some endpoints should be accessed by POST (like /auth/login), all endpoints can only use one method, thus there may no conflict on NavidromeCache.

Long-term data storage

Sorry that I have no any experience on such technique, and do not sure if there are some handy libraries to fulfill this goal. Navidrome login tokens are not always invalid after a player / device becomes inactive, so they can be stored in filesystems etc., and only updated manually via a re-sent /auth/login request. Therefore, this storage is also associated with the network requester - as said before, the requester should handle 401 code to trigger that re-sent. It will be a much bigger piece of work than the upper one.

Approaches

I think there are two basic ways to perform the whole pipeline:

  • Approach 1: Only update auth token when needed: needs both refactoring and storage;
  • Approach 2: Always fetch a new auth token before any /api endpoints: only needs refactoring, but consumes more on network resources and may be more frequent to hit Navidrome server rate limit.

Apparently, the second choice is easier to implement, but not efficient enough, while the first one is harder but solves current and potential issues (especially feature requests) in the future. After all it is not my personal project and the feature is not necessary, so it may worth open to discussion and more important decisions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions