feat(FN-4078): add ntfy access token support to notifications

Adds ntfy access token support to Fusion's notification system, wiring the token through the core settings schema, dashboard UI (SettingsModal), engine notifier, and notification pipeline, with corresponding tests across core, dashboard, and engine packages; also updates settings and storage documen

Fusion-Task-Id: FN-4078
This commit is contained in:
Fusion
2026-05-12 07:05:43 -07:00
committed by gsxdsm
parent 5bed5a004b
commit 2d46a882f0
17 changed files with 312 additions and 15 deletions

View File

@@ -169,6 +169,7 @@ describe("GlobalSettingsStore", () => {
// Defaults are filled in for missing fields
expect(settings.ntfyEnabled).toBe(false);
expect(settings.ntfyBaseUrl).toBeUndefined();
expect(settings.ntfyAccessToken).toBeUndefined();
expect(settings.defaultProvider).toBeUndefined();
});
@@ -260,6 +261,23 @@ describe("GlobalSettingsStore", () => {
expect(settings.ntfyTopic).toBeUndefined();
});
it("clearing ntfyAccessToken with null removes it from disk and returns undefined", async () => {
await store.init();
await store.updateSettings({ ntfyAccessToken: "secret-token" });
const raw = JSON.parse(await readFile(join(dir, "settings.json"), "utf-8"));
expect(raw.ntfyAccessToken).toBe("secret-token");
// @ts-expect-error - null is intentionally used to clear field (null-as-delete)
await store.updateSettings({ ntfyAccessToken: null });
const rawAfter = JSON.parse(await readFile(join(dir, "settings.json"), "utf-8"));
expect(rawAfter.ntfyAccessToken).toBeUndefined();
const settings = await store.getSettings();
expect(settings.ntfyAccessToken).toBeUndefined();
});
it("clearing ntfyDashboardHost with null removes it from disk", async () => {
await store.init();
await store.updateSettings({ ntfyDashboardHost: "https://dashboard.example.com" });

View File

@@ -23,6 +23,7 @@ export const DEFAULT_GLOBAL_SETTINGS = {
ntfyEnabled: false,
ntfyTopic: undefined,
ntfyBaseUrl: undefined,
ntfyAccessToken: undefined,
ntfyEvents: [
"in-review",
"merged",

View File

@@ -1608,6 +1608,10 @@ export interface GlobalSettings {
* Must be an http:// or https:// URL. When omitted, notifications default to
* https://ntfy.sh. Example: "https://ntfy.internal.example" */
ntfyBaseUrl?: string;
/** Optional ntfy access token used for authenticated publishes.
* When set, Fusion sends `Authorization: Bearer <token>` with ntfy requests.
* Leave undefined to publish without authentication. */
ntfyAccessToken?: string;
/** List of notification events to send via ntfy.sh.
* When ntfyEnabled is true, only events in this list will trigger notifications.
* If undefined or empty when ntfyEnabled is true, all events are sent (backward compatible).