Expand description
Tidal authentication. See docs/specs/0002-auth.md.
Sessionand theSessionStoreseam the binary implements (keyring, encrypted file)- the OAuth2 device flow:
DeviceFlow(AC1–AC3) Authenticator: owns the in-memory session, sends authenticated requests, refreshes (single flight, persisted) and recovers (AC4–AC9)- the pure classifiers the above are built on (
classify_poll,classify_refresh_failure,needs_refresh)
Tokens never appear in Debug output or error messages (AC15).
Structs§
- Auth
Config - 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.
- Device
Code - Tidal’s answer to
POST /device_authorization: what the user must open and type, and how to poll. ItsDebugredactsdevice_code, which can be exchanged for tokens until it expires. - Device
Flow - Runs the device flow:
start_device_flow, show the code, thencomplete_login. - Login
- What
DeviceFlow::complete_loginstored. - Manual
Clock - A manually driven clock for tests:
sleepreturns at once and advances the clock by the requested duration, which it also records. - Memory
Store - In-memory
SessionStore, for tests and as a building block. - Session
- A logged-in Tidal session, as stored between runs.
- System
Clock - The real clock and
tokiosleep. - Token
Grant - A
200fromPOST /token: a device-code grant or a refresh. ItsDebugredacts the tokens.
Enums§
- Auth
Error - Errors from the device flow and the
Authenticator. No variant ever carries a token or a server body (AC15). - Auth
Status - Whether the session is usable, for the player to broadcast
Event::LoginRequired/Event::LoginRestoredon changes. - Poll
Outcome - What one device-code poll says to do next (AC2).
- Refresh
Client - Which client a session’s access token was refreshed under (AC19).
- Refresh
Failure - How a failed refresh is handled (spec 0002, “When refresh fails”).
- Store
Error - 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 bylogin) 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_IDget AAC for 16-bit tracks (AC19). Theclient_id_pkcethattidalapiships (spec 0002, decision 2). - PKCE_
CLIENT_ SECRET - Public client secret that goes with
PKCE_CLIENT_ID(tidalapi’sclient_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.
- Session
Store - 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
/tokenresponse to a device-code poll to what happens next (AC2).intervalis the current poll interval.5xxand429count as “not yet”, like transport errors. - classify_
refresh_ failure - Classifies a non-
2xxrefresh response (AC7). Network errors areRefreshFailure::Transienttoo, without reaching this function. - needs_
refresh - Whether
session’s access token expires withinREFRESH_MARGINofnow, or already has (AC4). - session_
from_ login - Builds the session of a fresh login (AC3). Fails with
AuthError::SessionInfowhen the user ID or country is missing. - session_
from_ refresh - Builds the session after a refresh of
previous(AC3, AC6): a missingrefresh_tokenkeeps the old one, missing account data keeps the old values (with a warning).
Type Aliases§
- BoxFuture
- A boxed
Sendfuture, as returned bySleeper::sleep.