Skip to main content

Module auth

Module auth 

Source
Expand description

Tidal authentication. See docs/specs/0002-auth.md.

Tokens never appear in Debug output or error messages (AC15).

Structs§

AuthConfig
Endpoints and client credentials, injected so tests use a mock server.
Authenticator
Owns the in-memory session and sends authenticated requests: bearer header, proactive and reactive refresh (single flight, persisted to the store), cross-process pickup, and the “session lost” state.
DeviceCode
Tidal’s answer to POST /device_authorization: what the user must open and type, and how to poll. Its Debug redacts device_code, which can be exchanged for tokens until it expires.
DeviceFlow
Runs the device flow: start_device_flow, show the code, then complete_login.
Login
What DeviceFlow::complete_login stored.
ManualClock
A manually driven clock for tests: sleep returns at once and advances the clock by the requested duration, which it also records.
MemoryStore
In-memory SessionStore, for tests and as a building block.
Session
A logged-in Tidal session, as stored between runs.
SystemClock
The real clock and tokio sleep.
TokenGrant
A 200 from POST /token: a device-code grant or a refresh. Its Debug redacts the tokens.

Enums§

AuthError
Errors from the device flow and the Authenticator. No variant ever carries a token or a server body (AC15).
AuthStatus
Whether the session is usable, for the player to broadcast Event::LoginRequired / Event::LoginRestored on changes.
PollOutcome
What one device-code poll says to do next (AC2).
RefreshClient
Which client a session’s access token was refreshed under (AC19).
RefreshFailure
How a failed refresh is handled (spec 0002, “When refresh fails”).
StoreError
Errors from a SessionStore.

Constants§

API_BASE
Production base URL of the Tidal v1 API.
AUTH_BASE
Production base URL of Tidal’s OAuth2 endpoints.
CLIENT_ID
Public client ID of the official Tidal app (spec 0002, decision 2).
CLIENT_SECRET
Public client secret of the official Tidal app (spec 0002, decision 2).
DEVICE_CODE_GRANT
Grant type of a device-code poll (RFC 8628).
LOSSY_WARNING
Warned (logged by the Authenticator, printed by login) when a token of the device-flow client is used because the PKCE client failed (AC19). It names no cause: at login it covers any failure, outages included.
LOST_RECHECK
In the “session lost” state, storage is re-read at most this often (AC9).
PKCE_CLIENT_ID
Public client ID of the official Android app’s PKCE login, used for every refresh: tokens of CLIENT_ID get AAC for 16-bit tracks (AC19). The client_id_pkce that tidalapi ships (spec 0002, decision 2).
PKCE_CLIENT_SECRET
Public client secret that goes with PKCE_CLIENT_ID (tidalapi’s client_secret_pkce).
REFRESH_MARGIN
A token that expires within this margin is refreshed before use (AC4).
SCOPE
OAuth2 scopes requested at login.
SLOW_DOWN_STEP
Added to the poll interval on slow_down (AC2).

Traits§

Clock
Source of the current time, injected so tests never wait.
SessionStore
Where the session lives between runs. Implementations block briefly (keyring call, small file), so they are synchronous.
Sleeper
Waits between device-flow polls, injected so tests never sleep.

Functions§

classify_poll
Maps one /token response to a device-code poll to what happens next (AC2). interval is the current poll interval. 5xx and 429 count as “not yet”, like transport errors.
classify_refresh_failure
Classifies a non-2xx refresh response (AC7). Network errors are RefreshFailure::Transient too, without reaching this function.
needs_refresh
Whether session’s access token expires within REFRESH_MARGIN of now, or already has (AC4).
session_from_login
Builds the session of a fresh login (AC3). Fails with AuthError::SessionInfo when the user ID or country is missing.
session_from_refresh
Builds the session after a refresh of previous (AC3, AC6): a missing refresh_token keeps the old one, missing account data keeps the old values (with a warning).

Type Aliases§

BoxFuture
A boxed Send future, as returned by Sleeper::sleep.