mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
refactor(subsonic): centralize the REST protocol version in one constant
The Subsonic protocol version (v=1.16.1) was hardcoded across six call sites. Hoist it into a single SUBSONIC_API_VERSION constant next to SUBSONIC_CLIENT so it can be reasoned about and adjusted in one place. No behaviour change.
This commit is contained in:
@@ -8,6 +8,15 @@ import { findServerByIdOrIndexKey, resolveServerIdForIndexKey } from '../utils/s
|
||||
|
||||
export const SUBSONIC_CLIENT = `psysonic/${version}`;
|
||||
|
||||
/**
|
||||
* Subsonic REST protocol version sent on every request. A server returns
|
||||
* error 30 ("Incompatible REST protocol version") if the client asks for a
|
||||
* HIGHER version than it supports — surfaced to the user via the connection
|
||||
* error toast. OpenSubsonic extensions are negotiated via the `openSubsonic`
|
||||
* response flag, not this number.
|
||||
*/
|
||||
export const SUBSONIC_API_VERSION = '1.16.1';
|
||||
|
||||
export function secureRandomSalt(): string {
|
||||
const buf = new Uint8Array(8);
|
||||
crypto.getRandomValues(buf);
|
||||
@@ -17,7 +26,7 @@ export function secureRandomSalt(): string {
|
||||
export function getAuthParams(username: string, password: string) {
|
||||
const salt = secureRandomSalt();
|
||||
const token = md5(password + salt);
|
||||
return { u: username, t: token, s: salt, v: '1.16.1', c: SUBSONIC_CLIENT, f: 'json' };
|
||||
return { u: username, t: token, s: salt, v: SUBSONIC_API_VERSION, c: SUBSONIC_CLIENT, f: 'json' };
|
||||
}
|
||||
|
||||
export function restBaseFromUrl(serverUrl: string): string {
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { CoverArtTier } from '../cover/types';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { connectBaseUrlForServer } from '../utils/server/serverEndpoint';
|
||||
import { findServerByIdOrIndexKey } from '../utils/server/serverLookup';
|
||||
import { restBaseFromUrl, SUBSONIC_CLIENT, secureRandomSalt } from './subsonicClient';
|
||||
import { restBaseFromUrl, SUBSONIC_CLIENT, SUBSONIC_API_VERSION, secureRandomSalt } from './subsonicClient';
|
||||
|
||||
function coverArtQueryParams(username: string, password: string, id: string, size: number): URLSearchParams {
|
||||
const salt = secureRandomSalt();
|
||||
@@ -16,7 +16,7 @@ function coverArtQueryParams(username: string, password: string, id: string, siz
|
||||
u: username,
|
||||
t: token,
|
||||
s: salt,
|
||||
v: '1.16.1',
|
||||
v: SUBSONIC_API_VERSION,
|
||||
c: SUBSONIC_CLIENT,
|
||||
f: 'json',
|
||||
});
|
||||
@@ -36,7 +36,7 @@ function streamUrlFromProfile(
|
||||
u: username,
|
||||
t: token,
|
||||
s: salt,
|
||||
v: '1.16.1',
|
||||
v: SUBSONIC_API_VERSION,
|
||||
c: SUBSONIC_CLIENT,
|
||||
f: 'json',
|
||||
});
|
||||
@@ -116,7 +116,7 @@ export function buildDownloadUrl(id: string): string {
|
||||
const p = new URLSearchParams({
|
||||
id,
|
||||
u: server?.username ?? '',
|
||||
t: token, s: salt, v: '1.16.1', c: SUBSONIC_CLIENT, f: 'json',
|
||||
t: token, s: salt, v: SUBSONIC_API_VERSION, c: SUBSONIC_CLIENT, f: 'json',
|
||||
});
|
||||
return `${baseUrl}/rest/download.view?${p.toString()}`;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import md5 from 'md5';
|
||||
import { apiWithCredentials, restBaseFromUrl, secureRandomSalt, SUBSONIC_CLIENT } from '../../api/subsonicClient';
|
||||
import { apiWithCredentials, restBaseFromUrl, secureRandomSalt, SUBSONIC_CLIENT, SUBSONIC_API_VERSION } from '../../api/subsonicClient';
|
||||
import type { ServerProfile } from '../../store/authStoreTypes';
|
||||
import { allNormalizedAddresses } from './serverEndpoint';
|
||||
|
||||
@@ -64,7 +64,7 @@ async function fetchPingFingerprint(
|
||||
u: username,
|
||||
t: token,
|
||||
s: salt,
|
||||
v: '1.16.1',
|
||||
v: SUBSONIC_API_VERSION,
|
||||
c: SUBSONIC_CLIENT,
|
||||
f: 'json',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user