Feature: ntfy widget (#6601)
Docker CI / Docker Build & Push (push) Has been cancelled
Lint / Linting Checks (push) Has been cancelled
Release Drafter / Update Release Draft (push) Has been cancelled
Release Drafter / Auto Label PR (push) Has been cancelled
Tests / vitest (1) (push) Has been cancelled
Tests / vitest (2) (push) Has been cancelled
Tests / vitest (3) (push) Has been cancelled
Tests / vitest (4) (push) Has been cancelled

Co-authored-by: Jim Strang <jimstrang@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
Jim Strang
2026-04-26 20:38:14 -07:00
committed by GitHub
co-authored by Jim Strang shamoon
parent 9b8e771268
commit c3b4fc17c4
11 changed files with 409 additions and 0 deletions
@@ -34,6 +34,7 @@ vi.mock("widgets/widgets", () => ({
paperlessngx: { api: "{url}/api/{endpoint}" },
proxmox: { api: "{url}/api2/json/{endpoint}" },
truenas: { api: "{url}/api/v2.0/{endpoint}" },
ntfy: { api: "{url}/{endpoint}" },
proxmoxbackupserver: { api: "{url}/api2/json/{endpoint}" },
checkmk: { api: "{url}/{endpoint}" },
stocks: { api: "{url}/{endpoint}" },
@@ -185,6 +186,51 @@ describe("utils/proxy/handlers/credentialed", () => {
expect(params.headers.Authorization).toBe("Bearer k");
});
it("uses Bearer auth for ntfy when key is provided", async () => {
getServiceWidget.mockResolvedValue({ type: "ntfy", url: "http://ntfy", topic: "alerts", key: "tk_test" });
httpProxy.mockResolvedValue([200, "application/json", { ok: true }]);
const req = { method: "GET", query: { group: "g", service: "s", endpoint: "alerts/json", index: 0 } };
const res = createMockRes();
await credentialedProxyHandler(req, res);
const [, params] = httpProxy.mock.calls.at(-1);
expect(params.headers.Authorization).toBe("Bearer tk_test");
});
it("uses Basic auth for ntfy when username/password are provided", async () => {
getServiceWidget.mockResolvedValue({
type: "ntfy",
url: "http://ntfy",
topic: "alerts",
username: "u",
password: "p",
});
httpProxy.mockResolvedValue([200, "application/json", { ok: true }]);
const req = { method: "GET", query: { group: "g", service: "s", endpoint: "alerts/json", index: 0 } };
const res = createMockRes();
await credentialedProxyHandler(req, res);
const [, params] = httpProxy.mock.calls.at(-1);
expect(params.headers.Authorization).toMatch(/^Basic /);
});
it("sends no auth header for ntfy when no credentials are configured", async () => {
getServiceWidget.mockResolvedValue({ type: "ntfy", url: "http://ntfy", topic: "alerts" });
httpProxy.mockResolvedValue([200, "application/json", { ok: true }]);
const req = { method: "GET", query: { group: "g", service: "s", endpoint: "alerts/json", index: 0 } };
const res = createMockRes();
await credentialedProxyHandler(req, res);
const [, params] = httpProxy.mock.calls.at(-1);
expect(params.headers.Authorization).toBeUndefined();
});
it.each([
[{ type: "paperlessngx", url: "http://x", key: "k" }, { Authorization: "Token k" }],
[