fix(music-network): keep API suffix for self-hosted paste-token providers (#1085)

* fix(music-network): keep API suffix for self-hosted paste-token providers

The api_key_only connect strategy persisted the raw origin from the baseUrl
field instead of the resolved API base, dropping the preset's
selfHostedApiSuffix (e.g. /apis/listenbrainz). Scrobbles and now-playing then
hit <origin>/1/submit-listens (404/405, silently unlogged) instead of
<origin>/apis/listenbrainz/1/submit-listens, so nothing was recorded.

Return the runtime-resolved ctx.baseUrl (origin + suffix) and fall back to the
field only when it is absent. Fixes Koito and both Maloja compat surfaces
(ListenBrainz and Audioscrobbler). Existing accounts must reconnect to
re-persist the corrected base.

* docs(changelog): self-hosted scrobble URL fix (#1085)
This commit is contained in:
Psychotoxical
2026-06-14 00:27:30 +02:00
committed by GitHub
parent 028eb65f7d
commit 41c8187186
3 changed files with 24 additions and 4 deletions
@@ -31,11 +31,17 @@ describe('apiKeyOnlyStrategy', () => {
await expect(apiKeyOnlyStrategy.connect(ctx({}))).rejects.toBeInstanceOf(MusicNetworkError);
});
it('prefers a field baseUrl over the context baseUrl', async () => {
it('returns the resolved API base (with suffix), not the raw field origin', async () => {
// The runtime passes ctx.baseUrl already resolved to origin + selfHostedApiSuffix
// (e.g. /apis/listenbrainz for Koito). The strategy must persist that, not the
// bare fields.baseUrl — otherwise scrobbles miss the /apis/listenbrainz path.
const res = await apiKeyOnlyStrategy.connect(
ctx({ token: 't', baseUrl: 'https://maloja.example' }, 'https://fallback'),
ctx(
{ token: 't', baseUrl: 'https://koito.example' },
'https://koito.example/apis/listenbrainz',
),
);
expect(res.baseUrl).toBe('https://maloja.example');
expect(res.baseUrl).toBe('https://koito.example/apis/listenbrainz');
});
it('falls back to the context baseUrl when no field given', async () => {