feat(web): DELETE /api/config?field= to clear a credential
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, beforeAll } from "vitest";
|
||||
import { GET, PUT } from "./route";
|
||||
import { GET, PUT, DELETE } from "./route";
|
||||
import { prisma } from "@/lib/db";
|
||||
|
||||
beforeAll(() => {
|
||||
@@ -14,6 +14,10 @@ function putReq(body: unknown) {
|
||||
});
|
||||
}
|
||||
|
||||
function delReq(field: string) {
|
||||
return new Request(`http://localhost/api/config?field=${field}`, { method: "DELETE" });
|
||||
}
|
||||
|
||||
describe("config API", () => {
|
||||
it("stores plain fields verbatim and secret fields encrypted", async () => {
|
||||
await PUT(putReq({ qobuzEmail: "me@example.com", qobuzPassword: "hunter2", slskdUrl: "http://slskd:5030", slskdApiKey: "abc" }));
|
||||
@@ -59,3 +63,25 @@ describe("config API", () => {
|
||||
expect(pw).not.toBeNull(); // still present, not wiped
|
||||
});
|
||||
});
|
||||
|
||||
describe("config DELETE", () => {
|
||||
it("removes a stored secret by field name", async () => {
|
||||
await PUT(putReq({ qobuzPassword: "hunter2" }));
|
||||
expect(await prisma.config.findUnique({ where: { key: "qobuz.password" } })).not.toBeNull();
|
||||
const res = await DELETE(delReq("qobuzPassword"));
|
||||
expect(res.status).toBe(200);
|
||||
expect(await prisma.config.findUnique({ where: { key: "qobuz.password" } })).toBeNull();
|
||||
// GET now reports it unset
|
||||
expect((await (await GET()).json()).qobuzPasswordSet).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects an unknown field with 400 and deletes nothing", async () => {
|
||||
const res = await DELETE(delReq("monitor.enabled"));
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
|
||||
it("is idempotent — deleting an absent field returns 200", async () => {
|
||||
const res = await DELETE(delReq("slskdApiKey"));
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,3 +45,13 @@ export async function GET() {
|
||||
slskdApiKeySet: byKey.has("slskd.api_key"),
|
||||
});
|
||||
}
|
||||
|
||||
export async function DELETE(request: Request) {
|
||||
const field = new URL(request.url).searchParams.get("field") ?? "";
|
||||
const entry = FIELDS[field];
|
||||
if (!entry) {
|
||||
return Response.json({ error: "unknown field" }, { status: 400 });
|
||||
}
|
||||
await prisma.config.deleteMany({ where: { key: entry.key } }); // idempotent
|
||||
return Response.json({ ok: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user