Skip to content

Commit

Permalink
feat: support authKey authentication
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Dec 6, 2024
1 parent 24bd7d7 commit 7ae0427
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 19 deletions.
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,22 @@ interface SubsonicConfig {
url: string;

// The authentication details to use when connecting to the server.
auth: {
username: string;
password: string;
};

// A salt to use when hashing the password
auth:
| {
username: string;
password: string;
}
| {
// See https://opensubsonic.netlify.app/docs/extensions/apikeyauth/
apiKey: string;
};

// A salt to use when hashing the password. Not used if `auth.apiKey` is provided.
salt?: string;

// Whether to reuse generated salts. If not provided,
// a random salt will be generated for each request.
// Ignored if `salt` is provided.
// Ignored if `salt` is provided or `auth.apiKey` is used.
reuseSalt?: boolean;

// Whether to use a POST requests instead of GET requests.
Expand Down
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"bun-types": "^1.1.34",
"bun-types": "^1.1.38",
"esbuild": "^0.24.0",
"release-it": "^17.10.0"
},
Expand Down
39 changes: 28 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ interface SubsonicConfig {
url: string;

/** The authentication details to use when connecting to the server. */
auth: {
username: string;
password: string;
};
auth:
| {
username: string;
password: string;
apiKey: undefined;
}
| {
username: undefined;
password: undefined;
apiKey: string;
};

/** A salt to use when hashing the password (optional). */
salt?: string;
Expand Down Expand Up @@ -68,8 +75,11 @@ export default class SubsonicAPI {
if (!config) throw new Error("no config provided");
if (!config.url) throw new Error("no url provided");
if (!config.auth) throw new Error("no auth provided");
if (!config.auth.username) throw new Error("no username provided");
if (!config.auth.password) throw new Error("no password provided");

if (!config.auth.apiKey) {
if (!config.auth.username) throw new Error("no username provided");
if (!config.auth.password) throw new Error("no password provided");
}

this.#config = config;
this.#crypto = config.crypto || globalThis.crypto;
Expand Down Expand Up @@ -166,7 +176,6 @@ export default class SubsonicAPI {
url.searchParams.set("v", "1.16.1");
url.searchParams.set("c", "subsonic-api");
url.searchParams.set("f", "json");
url.searchParams.set("u", this.#config.auth.username);

if (params) {
for (const [key, value] of Object.entries(params)) {
Expand All @@ -181,9 +190,16 @@ export default class SubsonicAPI {
}
}

const { token, salt } = await this.#generateToken(this.#config.auth.password);
url.searchParams.set("t", token);
url.searchParams.set("s", salt);
if (this.#config.auth.apiKey) {
url.searchParams.set("apiKey", this.#config.auth.apiKey);
} else if (this.#config.auth.username) {
url.searchParams.set("u", this.#config.auth.username);
const { token, salt } = await this.#generateToken(this.#config.auth.password);
url.searchParams.set("t", token);
url.searchParams.set("s", salt);
} else {
throw new Error("no auth provided");
}

if (this.#config.post) {
const [path, search] = url.toString().split("?");
Expand Down Expand Up @@ -884,7 +900,8 @@ export default class SubsonicAPI {
return this.#requestJSON<SubsonicBaseResponse & Partial<{ playQueue: PlayQueue }>>("getPlayQueue", {});
}

async savePlayQueue(args: { id: string; current?: string; position: number }) {
// id is optional on OpenSubsonic compatible servers
async savePlayQueue(args: { id?: string; current?: string; position: number }) {
return this.#requestJSON<SubsonicBaseResponse>("savePlayQueue", args);
}

Expand Down

0 comments on commit 7ae0427

Please sign in to comment.