feat(auth): member accounts are valid sessions; typed entitlements
Qobuz answers `/user/login` with 200 for an account without an active subscription and the web player signs it in as a "Qobuz member" with its favorites, playlists, purchases and 30-second previews. QBZ threw that session away: `parse_login_response` returned `IneligibleUser` whenever `credential.parameters` was empty (verified 2026-09-02 with a lapsed account). The gate was ours, not Qobuz's. The parser now reads the entitlement flags (`lossy/lossless/hires/ hires_purchases/offline/mobile_streaming`) into a typed `Entitlements` on `UserSession`, labels a member "Member", and keeps `subscription. end_date`/`offer` as information (the embedded Qobuz fixture has a past end_date with every flag true: the flags are the verdict, the date is not). `StreamUrl` gains `sample`, the flag Qobuz sets when it serves a preview instead of the track. `IneligibleUser` stays in the enum for its existing matchers; nothing emits it from this path any more. Persisted pre-member sessions still load (`serde(default)`). cc
This commit is contained in:
8 files changed
+243
-36
No files matched your search
@@ -1269,9 +1269,7 @@ mod tests {
|
||||
email: "a@b.c".into(),
|
||||
display_name: "Tester".into(),
|
||||
subscription_label: "studio".into(),
|
||||
subscription_valid_until: None,
|
||||
country_code: None,
|
||||
language_code: None,
|
||||
..UserSession::default()
|
||||
};
|
||||
set_logged_in(&shared, &session);
|
||||
let s = shared.lock().unwrap();
|
||||
|
||||
Reference in new issue
Block a user