From 02f16c0d8f6aa0645565e9a2b742ebd271907c78 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Sat, 28 Feb 2026 11:34:19 +0100 Subject: [PATCH 1/8] ntfy: add markdown formatting --- server/lib/notifications/agents/ntfy.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index 561df2c847..b0cf3966bb 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -35,7 +35,10 @@ class NtfyAgent let message = payload.message ?? ''; if (payload.request) { - message += `\n\nRequested By: ${payload.request.requestedBy.displayName}`; + if (message) { + message = `**- Description:**\n${message}`; + } + message += `\n\n**- Requested By:** ${payload.request.requestedBy.displayName}`; let status = ''; switch (type) { @@ -58,14 +61,18 @@ class NtfyAgent } if (status) { - message += `\nRequest Status: ${status}`; + message += `\n**- Request Status:** ${status}`; } } else if (payload.comment) { - message += `\nComment from ${payload.comment.user.displayName}:\n${payload.comment.message}`; + message = `**- Comment:**\n${payload.comment.message}`; + message += `\n\n**- Comment from:** ${payload.comment.user.displayName}`; } else if (payload.issue) { - message += `\n\nReported By: ${payload.issue.createdBy.displayName}`; - message += `\nIssue Type: ${IssueTypeName[payload.issue.issueType]}`; - message += `\nIssue Status: ${ + if (message) { + message = `**- Comment:**\n${message}`; + } + message += `\n\n**- Reported By:** ${payload.issue.createdBy.displayName}`; + message += `\n**- Issue Type:** ${IssueTypeName[payload.issue.issueType]}`; + message += `\n**- Issue Status:** ${ payload.issue.status === IssueStatus.OPEN ? 'Open' : 'Resolved' }`; } @@ -86,6 +93,7 @@ class NtfyAgent priority, title, message, + markdown: true, attach, click, }; From 95e15a52f0fd91877443108a4f5094c364f98d51 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:20:06 +0100 Subject: [PATCH 2/8] fix: Comment branch drops payload.message --- server/lib/notifications/agents/ntfy.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index b0cf3966bb..1a1c3e5ed4 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -64,7 +64,10 @@ class NtfyAgent message += `\n**- Request Status:** ${status}`; } } else if (payload.comment) { - message = `**- Comment:**\n${payload.comment.message}`; + if (message) { + message = `**- Description:**\n${message}\n\n`; + } + message += `**- Comment:**\n${payload.comment.message}`; message += `\n\n**- Comment from:** ${payload.comment.user.displayName}`; } else if (payload.issue) { if (message) { From 8a7230a61db1880bedfaef3af4967d02613d4303 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:21:01 +0100 Subject: [PATCH 3/8] fix: Leading blank lines when message is empty --- server/lib/notifications/agents/ntfy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index 1a1c3e5ed4..ed769ea041 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -38,7 +38,7 @@ class NtfyAgent if (message) { message = `**- Description:**\n${message}`; } - message += `\n\n**- Requested By:** ${payload.request.requestedBy.displayName}`; + message += `${message ? '\n\n' : ''}**- Requested By:** ${payload.request.requestedBy.displayName}`; let status = ''; switch (type) { From b994149bcf818eb3f9b8b2b32e3cf796c4b32b76 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:22:04 +0100 Subject: [PATCH 4/8] fix: Leading blank lines when message is empty --- server/lib/notifications/agents/ntfy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index ed769ea041..518cda1769 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -73,7 +73,7 @@ class NtfyAgent if (message) { message = `**- Comment:**\n${message}`; } - message += `\n\n**- Reported By:** ${payload.issue.createdBy.displayName}`; + message += `${message ? '\n\n' : ''}**- Reported By:** ${payload.issue.createdBy.displayName}`; message += `\n**- Issue Type:** ${IssueTypeName[payload.issue.issueType]}`; message += `\n**- Issue Status:** ${ payload.issue.status === IssueStatus.OPEN ? 'Open' : 'Resolved' From 8ee778968fcfc5e7be7140ead69fd3eceea392ee Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:24:13 +0100 Subject: [PATCH 5/8] fix: Escape displayName for markdown injection --- server/lib/notifications/agents/ntfy.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index 518cda1769..1021b97f9d 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -21,6 +21,10 @@ class NtfyAgent return settings.notifications.agents.ntfy; } + private escapeMarkdown(text: string): string { + return text.replace(/([\\`*_{}[\]()#+\-.!|>])/g, '\\$1'); + } + private buildPayload(type: Notification, payload: NotificationPayload) { const settings = getSettings(); const { applicationUrl } = settings.main; @@ -38,7 +42,7 @@ class NtfyAgent if (message) { message = `**- Description:**\n${message}`; } - message += `${message ? '\n\n' : ''}**- Requested By:** ${payload.request.requestedBy.displayName}`; + message += `${message ? '\n\n' : ''}**- Requested By:** ${this.escapeMarkdown(payload.request.requestedBy.displayName)}`; let status = ''; switch (type) { @@ -68,12 +72,12 @@ class NtfyAgent message = `**- Description:**\n${message}\n\n`; } message += `**- Comment:**\n${payload.comment.message}`; - message += `\n\n**- Comment from:** ${payload.comment.user.displayName}`; + message += `\n\n**- Comment from:** ${this.escapeMarkdown(payload.comment.user.displayName)}`; } else if (payload.issue) { if (message) { message = `**- Comment:**\n${message}`; } - message += `${message ? '\n\n' : ''}**- Reported By:** ${payload.issue.createdBy.displayName}`; + message += `${message ? '\n\n' : ''}**- Reported By:** ${this.escapeMarkdown(payload.issue.createdBy.displayName)}`; message += `\n**- Issue Type:** ${IssueTypeName[payload.issue.issueType]}`; message += `\n**- Issue Status:** ${ payload.issue.status === IssueStatus.OPEN ? 'Open' : 'Resolved' From 2306d0a12933eb39c60c9b9b4381e96ab8438d39 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:52:36 +0100 Subject: [PATCH 6/8] fix: also escape ~ and < --- server/lib/notifications/agents/ntfy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index 1021b97f9d..b204122b0e 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -22,7 +22,7 @@ class NtfyAgent } private escapeMarkdown(text: string): string { - return text.replace(/([\\`*_{}[\]()#+\-.!|>])/g, '\\$1'); + return text.replace(/([\\`*_{}[\]()#+\-.!|>~<])/g, '\\$1'); } private buildPayload(type: Notification, payload: NotificationPayload) { From 18e930ab2ebca8e493663eb1829705cb90001a29 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:00:34 +0100 Subject: [PATCH 7/8] fix: renamed payload.message label from "Comment" to "Description" --- server/lib/notifications/agents/ntfy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index 4e2447fc3f..09631caa54 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -75,7 +75,7 @@ class NtfyAgent message += `\n\n**- Comment from:** ${this.escapeMarkdown(payload.comment.user.displayName)}`; } else if (payload.issue) { if (message) { - message = `**- Comment:**\n${message}`; + message = `**- Description:**\n${message}`; } message += `${message ? '\n\n' : ''}**- Reported By:** ${this.escapeMarkdown(payload.issue.createdBy.displayName)}`; message += `\n**- Issue Type:** ${IssueTypeName[payload.issue.issueType]}`; From ec60fe89e0724ba2e0e628270b75405401bbb292 Mon Sep 17 00:00:00 2001 From: v3DJG6GL <72495210+v3DJG6GL@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:10:00 +0100 Subject: [PATCH 8/8] also escape [ --- server/lib/notifications/agents/ntfy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/notifications/agents/ntfy.ts b/server/lib/notifications/agents/ntfy.ts index 09631caa54..aef24e85a4 100644 --- a/server/lib/notifications/agents/ntfy.ts +++ b/server/lib/notifications/agents/ntfy.ts @@ -22,7 +22,7 @@ class NtfyAgent } private escapeMarkdown(text: string): string { - return text.replace(/([\\`*_{}[\]()#+\-.!|>~<])/g, '\\$1'); + return text.replace(/([\\`*_{}\[\]()#+\-.!|>~<])/g, '\\$1'); } private buildPayload(type: Notification, payload: NotificationPayload) {