mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-21 17:33:29 +01:00
basic navidrome implementation
This commit is contained in:
91
src/navidrome.ts
Normal file
91
src/navidrome.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { Md5 } from "ts-md5/dist/md5";
|
||||
import { Credentials, MusicService } from "./music_service";
|
||||
import X2JS from "x2js";
|
||||
|
||||
import axios from "axios";
|
||||
import { Encryption } from "./encryption";
|
||||
import randomString from "./random_string";
|
||||
|
||||
export const t = (password: string, s: string) =>
|
||||
Md5.hashStr(`${password}${s}`);
|
||||
|
||||
export type SubconicEnvelope = {
|
||||
"subsonic-response": SubsonicResponse;
|
||||
};
|
||||
|
||||
export type SubsonicResponse = {
|
||||
_status: string;
|
||||
};
|
||||
|
||||
export type SubsonicError = SubsonicResponse & {
|
||||
error: {
|
||||
_code: string;
|
||||
_message: string;
|
||||
};
|
||||
};
|
||||
|
||||
export function isError(
|
||||
subsonicResponse: SubsonicResponse
|
||||
): subsonicResponse is SubsonicError {
|
||||
return (subsonicResponse as SubsonicError).error !== undefined;
|
||||
}
|
||||
|
||||
export class Navidrome implements MusicService {
|
||||
url: string;
|
||||
encryption: Encryption;
|
||||
|
||||
constructor(url: string, encryption: Encryption) {
|
||||
this.url = url;
|
||||
this.encryption = encryption;
|
||||
}
|
||||
|
||||
generateToken = async ({ username, password }: Credentials) => {
|
||||
const s = randomString();
|
||||
return axios
|
||||
.get(
|
||||
`${this.url}/rest/ping.view?u=${username}&t=${t(
|
||||
password,
|
||||
s
|
||||
)}&s=${s}&v=1.16.1.0&c=bonob`
|
||||
)
|
||||
.then((response) => new X2JS().xml2js(response.data) as SubconicEnvelope)
|
||||
.then((json) => json["subsonic-response"])
|
||||
.then((json) => {
|
||||
if (isError(json)) throw json.error._message;
|
||||
else return json;
|
||||
})
|
||||
.then((_) => {
|
||||
return {
|
||||
authToken: Buffer.from(
|
||||
JSON.stringify(
|
||||
this.encryption.encrypt(JSON.stringify({ username, password }))
|
||||
)
|
||||
).toString("base64"),
|
||||
userId: username,
|
||||
nickname: username,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
parseToken = (token: string): Credentials =>
|
||||
JSON.parse(
|
||||
this.encryption.decrypt(
|
||||
JSON.parse(Buffer.from(token, "base64").toString("ascii"))
|
||||
)
|
||||
);
|
||||
|
||||
async login(_: string) {
|
||||
// const credentials: Credentials = this.parseToken(token);
|
||||
return Promise.resolve({
|
||||
artists: () => [],
|
||||
artist: (id: string) => ({
|
||||
id,
|
||||
name: id,
|
||||
}),
|
||||
albums: ({ artistId }: { artistId?: string }) => {
|
||||
console.log(artistId);
|
||||
return [];
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user