Merge branch 'main' into postgres-support

This commit is contained in:
binwiederhier
2026-02-21 09:59:55 -05:00
6 changed files with 73 additions and 6 deletions

View File

@@ -661,6 +661,8 @@ Add the following function and alias to your `.bashrc` or `.bash_profile`:
local token=$(< ~/.ntfy_token) # Securely read the token
local status_icon="$([ $exit_status -eq 0 ] && echo magic_wand || echo warning)"
local last_command=$(history | tail -n1 | sed -e 's/^[[:space:]]*[0-9]\{1,\}[[:space:]]*//' -e 's/[;&|][[:space:]]*alert$//')
# for zsh users, use the same sed pattern but get the history differently.
# local last_command=$(history "$HISTCMD" | sed -e 's/^[[:space:]]*[0-9]\{1,\}[[:space:]]*//' -e 's/[;&|][[:space:]]*alert$//')
curl -s -X POST "https://n.example.dev/alerts" \
-H "Authorization: Bearer $token" \
@@ -692,4 +694,4 @@ To test failure notifications:
false; alert # Always fails (exit 1)
ls --invalid; alert # Invalid option
cat nonexistent_file; alert # File not found
```
```

View File

@@ -185,6 +185,7 @@ I've added a ⭐ to projects or posts that have a significant following, or had
- [Uptime Monitor](https://uptime-monitor.org) - Self-hosted, enterprise-grade uptime monitoring and alerting system (TS)
- [send_to_ntfy_extension](https://github.com/TheDuffman85/send_to_ntfy_extension/) ⭐ - A browser extension to send the notifications to ntfy (JS)
- [SIA-Server](https://github.com/ZebMcKayhan/SIA-Server) - A light weight, self-hosted notification Server for Honywell Galaxy Flex alarm systems (Python)
- [zabbix-ntfy](https://github.com/torgrimt/zabbix-ntfy) - Zabbix server Mediatype to add support for ntfy.sh services
## Blog + forum posts

View File

@@ -1698,6 +1698,12 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
## Not released yet
### ntfy server v2.18.x (UNRELEASED)
**Bug fixes + maintenance:**
* Preserve `<br>` line breaks in HTML-only emails received via SMTP ([#690](https://github.com/binwiederhier/ntfy/issues/690), [#1620](https://github.com/binwiederhier/ntfy/pull/1620), thanks to [@uzkikh](https://github.com/uzkikh) for the fix and to [@teastrainer](https://github.com/teastrainer) for reporting)
### ntfy Android v1.23.x (UNRELEASED)
**Features:**

View File

@@ -34,6 +34,7 @@ var (
var (
onlySpacesRegex = regexp.MustCompile(`(?m)^\s+$`)
consecutiveNewLinesRegex = regexp.MustCompile(`\n{3,}`)
htmlLineBreakRegex = regexp.MustCompile(`(?i)<br\s*/?>`)
)
const (
@@ -328,6 +329,9 @@ func readHTMLMailBody(reader io.Reader, transferEncoding string) (string, error)
if err != nil {
return "", err
}
// Convert <br> tags to newlines before stripping HTML, so that line breaks
// in HTML emails (e.g. from Synology DSM, and other appliances) are preserved.
body = htmlLineBreakRegex.ReplaceAllString(body, "\n")
stripped := bluemonday.
StrictPolicy().
AddSpaceWhenStrippingTag(true).

View File

@@ -694,7 +694,8 @@ home automation setup
Now the light is on
If you don&#39;t want to receive this message anymore, stop the push
services in your FRITZ!Box .
services in your FRITZ!Box .
Here you can see the active push services: &#34;System &gt; Push Service&#34;.
This mail has ben sent by your FRITZ!Box automatically.`
@@ -1354,9 +1355,11 @@ Congratulations! You have successfully set up the email notification on Synology
s, c, conf, scanner := newTestSMTPServer(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/synology", r.URL.Path)
require.Equal(t, "[Synology NAS] Test Message from Litts_NAS", r.Header.Get("Title"))
actual := readAll(t, r.Body)
expected := `Congratulations! You have successfully set up the email notification on Synology_NAS. For further system configurations, please visit http://192.168.1.28:5000/, http://172.16.60.5:5000/. (If you cannot connect to the server, please contact the administrator.) From Synology_NAS`
require.Equal(t, expected, actual)
expected := "Congratulations! You have successfully set up the email notification on Synology_NAS.\n" +
"For further system configurations, please visit http://192.168.1.28:5000/, http://172.16.60.5:5000/.\n" +
"(If you cannot connect to the server, please contact the administrator.)\n\n" +
"From Synology_NAS"
require.Equal(t, expected, readAll(t, r.Body))
})
conf.SMTPServerDomain = "mydomain.me"
conf.SMTPServerAddrPrefix = ""
@@ -1365,6 +1368,36 @@ Congratulations! You have successfully set up the email notification on Synology
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
}
func TestSmtpBackend_HTMLEmail_BrTagsPreserved(t *testing.T) {
email := `EHLO example.com
MAIL FROM: nas@example.com
RCPT TO: ntfy-alerts@ntfy.sh
DATA
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit
Subject: Task Scheduler: daily-backup
Task Scheduler has completed a scheduled task.<BR><BR>Task: daily-backup<BR>Start time: Mon, 01 Jan 2026 02:00:00 +0000<BR>Stop time: Mon, 01 Jan 2024 02:03:00 +0000<BR>Current status: 0 (Normal)<BR>Standard output/error:<BR>OK<BR><BR>From MyNAS
.
`
s, c, _, scanner := newTestSMTPServer(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/alerts", r.URL.Path)
require.Equal(t, "Task Scheduler: daily-backup", r.Header.Get("Title"))
expected := "Task Scheduler has completed a scheduled task.\n\n" +
"Task: daily-backup\n" +
"Start time: Mon, 01 Jan 2026 02:00:00 +0000\n" +
"Stop time: Mon, 01 Jan 2024 02:03:00 +0000\n" +
"Current status: 0 (Normal)\n" +
"Standard output/error:\n" +
"OK\n\n" +
"From MyNAS"
require.Equal(t, expected, readAll(t, r.Body))
})
defer s.Close()
defer c.Close()
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
}
func TestSmtpBackend_PlaintextWithToken(t *testing.T) {
email := `EHLO example.com
MAIL FROM: phil@example.com

View File

@@ -48,5 +48,26 @@
"notifications_none_for_topic_title": "לא קיבלת התראות בנושא הזה עדיין.",
"notifications_none_for_topic_description": "כדי לשלוח התראות לנושא הזה, צריך לשלוח PUT או POST לכתובת הנושא הזה.",
"notifications_none_for_any_title": "לא קיבלת התראות כלל.",
"notifications_no_subscriptions_title": "נראה שלא נרשמת למינויים עדיין."
"notifications_no_subscriptions_title": "נראה שלא נרשמת למינויים עדיין.",
"action_bar_toggle_mute": "השתקת/הפעלת התראות",
"action_bar_toggle_action_menu": "פתיחת/סגירת תפריט הפעולות",
"action_bar_profile_title": "פרופיל",
"action_bar_profile_settings": "הגדרות",
"action_bar_profile_logout": "יציאה",
"action_bar_sign_in": "כניסה",
"action_bar_sign_up": "הרשמה",
"message_bar_type_message": "כאן ניתן להקליד הודעה",
"message_bar_error_publishing": "שגיאה בפרסום ההתראה",
"message_bar_show_dialog": "הצגת חלונית פרסום",
"message_bar_publish": "פרסום הודעה",
"nav_topics_title": "נושאים שנרשמת אליהם",
"nav_button_all_notifications": "כל ההתראות",
"nav_button_account": "חשבון",
"nav_button_settings": "הגדרות",
"nav_button_documentation": "תיעוד",
"nav_button_publish_message": "פרסום התראה",
"nav_button_subscribe": "הרשמה לנושא",
"nav_button_muted": "התראות הושתקו",
"nav_button_connecting": "מתחבר",
"nav_upgrade_banner_label": "שדרוג ל־ntfy Pro"
}