feat: Qobuz auth-token (user_id + token) login as a reliable alternative to email/password
Qobuz's email/password API login returns 401 even with valid credentials (a known Qobuz limitation, unaffected by streamrip version). Add settings fields for a Qobuz user ID + auth token (token stored encrypted); when both are present StreamripClient uses use_auth_token=True, else falls back to email/password. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,22 @@ describe("config API", () => {
|
||||
expect(JSON.stringify(body)).not.toContain("hunter2");
|
||||
});
|
||||
|
||||
it("stores the Qobuz user id (plain) and auth token (encrypted), masked on GET", async () => {
|
||||
await PUT(putReq({ qobuzUserId: "123456", qobuzToken: "secrettoken" }));
|
||||
|
||||
const uid = await prisma.config.findUnique({ where: { key: "qobuz.user_id" } });
|
||||
const tok = await prisma.config.findUnique({ where: { key: "qobuz.auth_token" } });
|
||||
expect(uid!.value).toBe("123456");
|
||||
expect(uid!.secret).toBe(false);
|
||||
expect(tok!.secret).toBe(true);
|
||||
expect(tok!.value).not.toContain("secrettoken"); // encrypted envelope
|
||||
|
||||
const body = await (await GET()).json();
|
||||
expect(body.qobuzUserId).toBe("123456");
|
||||
expect(body.qobuzTokenSet).toBe(true);
|
||||
expect(JSON.stringify(body)).not.toContain("secrettoken");
|
||||
});
|
||||
|
||||
it("empty string leaves a field unchanged", async () => {
|
||||
await PUT(putReq({ qobuzPassword: "first" }));
|
||||
await PUT(putReq({ qobuzPassword: "" }));
|
||||
|
||||
@@ -5,6 +5,8 @@ import { encryptSecret } from "@/lib/crypto";
|
||||
const FIELDS: Record<string, { key: string; secret: boolean }> = {
|
||||
qobuzEmail: { key: "qobuz.email", secret: false },
|
||||
qobuzPassword: { key: "qobuz.password", secret: true },
|
||||
qobuzUserId: { key: "qobuz.user_id", secret: false },
|
||||
qobuzToken: { key: "qobuz.auth_token", secret: true },
|
||||
slskdUrl: { key: "slskd.url", secret: false },
|
||||
slskdApiKey: { key: "slskd.api_key", secret: true },
|
||||
};
|
||||
@@ -36,8 +38,10 @@ export async function GET() {
|
||||
const byKey = new Map(rows.map((r) => [r.key, r]));
|
||||
return Response.json({
|
||||
qobuzEmail: byKey.get("qobuz.email")?.value ?? "",
|
||||
qobuzUserId: byKey.get("qobuz.user_id")?.value ?? "",
|
||||
slskdUrl: byKey.get("slskd.url")?.value ?? "",
|
||||
qobuzPasswordSet: byKey.has("qobuz.password"),
|
||||
qobuzTokenSet: byKey.has("qobuz.auth_token"),
|
||||
slskdApiKeySet: byKey.has("slskd.api_key"),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user