diff --git a/package-lock.json b/package-lock.json index e63f29cc..42cb2270 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@foxxmd/chromecast-client": "^1.0.4", "@foxxmd/get-version": "^0.0.3", "@foxxmd/logging": "^0.2.3", + "@foxxmd/redact-string": "^0.1.2", "@foxxmd/regex-buddy-core": "^0.1.2", "@foxxmd/string-sameness": "^0.4.0", "@gr2m/net-interceptor": "^1.0.0", @@ -64,7 +65,7 @@ "mpd-api": "^1.1.2", "nanoid": "^3.3.1", "normalize-url": "^8.0.1", - "ntfy": "^1.6.2", + "ntfy": "^1.7.6", "object-hash": "^3.0.0", "p-event": "^4.2.0", "passport": "^0.6.0", @@ -1133,6 +1134,16 @@ "npm": ">=9.3.0" } }, + "node_modules/@foxxmd/redact-string": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@foxxmd/redact-string/-/redact-string-0.1.2.tgz", + "integrity": "sha512-/YTLauymSs2AdlxtwWE86uk3kwQB0v/r7KzFRlnCojPjIdVzbiGxDPYuRxwfYY9hEg/8lRa47MbaYN2v4BqgTw==", + "license": "MIT", + "engines": { + "node": ">=16.20.0", + "npm": ">=8.19.4" + } + }, "node_modules/@foxxmd/regex-buddy-core": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@foxxmd/regex-buddy-core/-/regex-buddy-core-0.1.2.tgz", @@ -3588,13 +3599,13 @@ } }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "peer": true, + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -3866,6 +3877,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4659,6 +4683,20 @@ "node": ">=10" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer3": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", @@ -4709,12 +4747,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -4747,6 +4783,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -5453,12 +5516,15 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -5643,15 +5709,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -5670,6 +5742,19 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -5810,11 +5895,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5916,21 +6002,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5942,7 +6018,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -7273,6 +7348,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -7884,26 +7968,17 @@ } }, "node_modules/ntfy": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/ntfy/-/ntfy-1.6.2.tgz", - "integrity": "sha512-56ITDEDeSYDWWOsZbv4J9qawaJUIHEy0Rga1+FZh6F5eq/17UPMzZ64PhcmuM2YunM1zCTWH2tM5zIELel5S7Q==", + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/ntfy/-/ntfy-1.7.6.tgz", + "integrity": "sha512-CXYWnD2/2FcgqxZzrRw8coBXELJA2rjBf49iZoG2Dh3X6e21bDjjfS/ZkvRihrTULnQA/1Cv6pocUTIEUvqIpg==", + "license": "GPL-3.0", "dependencies": { - "axios": "1.7.4" + "axios": "1.11.0" }, "engines": { "node": ">= 18.0" } }, - "node_modules/ntfy/node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/nyc": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", diff --git a/package.json b/package.json index ceb2a2a4..d51be5b5 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@foxxmd/chromecast-client": "^1.0.4", "@foxxmd/get-version": "^0.0.3", "@foxxmd/logging": "^0.2.3", + "@foxxmd/redact-string": "^0.1.2", "@foxxmd/regex-buddy-core": "^0.1.2", "@foxxmd/string-sameness": "^0.4.0", "@gr2m/net-interceptor": "^1.0.0", @@ -96,7 +97,7 @@ "mpd-api": "^1.1.2", "nanoid": "^3.3.1", "normalize-url": "^8.0.1", - "ntfy": "^1.6.2", + "ntfy": "^1.7.6", "object-hash": "^3.0.0", "p-event": "^4.2.0", "passport": "^0.6.0", diff --git a/src/backend/common/infrastructure/config/health/webhooks.ts b/src/backend/common/infrastructure/config/health/webhooks.ts index 932bddee..c0ff69d2 100644 --- a/src/backend/common/infrastructure/config/health/webhooks.ts +++ b/src/backend/common/infrastructure/config/health/webhooks.ts @@ -82,6 +82,11 @@ export interface NtfyConfig extends CommonWebhookConfig { * */ password?: string + /** + * Use instead of username/password, required if topic is protected + */ + token?: string + /** * Priority of messages * diff --git a/src/backend/notifier/NtfyWebhookNotifier.ts b/src/backend/notifier/NtfyWebhookNotifier.ts index aee2e066..dcb44f09 100644 --- a/src/backend/notifier/NtfyWebhookNotifier.ts +++ b/src/backend/notifier/NtfyWebhookNotifier.ts @@ -1,6 +1,7 @@ import { Logger } from "@foxxmd/logging"; import { Config, publish } from 'ntfy'; import request from "superagent"; +import {redactString} from '@foxxmd/redact-string'; import { NtfyConfig, PrioritiesConfig, WebhookPayload } from "../common/infrastructure/config/health/webhooks.js"; import { AbstractWebhookNotifier } from "./AbstractWebhookNotifier.js"; import { URLData } from "../../core/Atomic.js"; @@ -33,7 +34,14 @@ export class NtfyWebhookNotifier extends AbstractWebhookNotifier { initialize = async () => { // check url is correct as a courtesy this.endpoint = normalizeWebAddress(this.config.url); - this.logger.verbose(`Config URL: '${this.config.url}' => Normalized: '${this.endpoint.normal}'`) + this.logger.verbose(`Config URL: '${this.config.url}' => Normalized: '${this.endpoint.normal}'`); + if(this.config.token !== undefined) { + this.logger.verbose(`Using Access Token '${redactString(this.config.token, 3)}' for authentication`); + } else if(this.config.username !== undefined) { + this.logger.verbose(`Using Username/Password '${redactString(this.config.username, 3)}/${redactString(this.config.password, 3)}' for authentication`); + } else { + this.logger.verbose('No authentication provided, will not be able to push to protected topics'); + } this.initialized = true; // always set as ready to go. Server issues may be transient. @@ -72,7 +80,9 @@ export class NtfyWebhookNotifier extends AbstractWebhookNotifier { server: this.endpoint.normal, priority: this.priorities[payload.priority], }; - if (this.config.username !== undefined) { + if(this.config.token !== undefined) { + req.authorization = this.config.token; + } else if (this.config.username !== undefined) { req.authorization = { username: this.config.username, password: this.config.password,