diff --git a/README.md b/README.md index 8d98dd88..414aded4 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ account costs. Even small donations are very much appreciated. A big fat **Thank + I'd also like to thank JetBrains for providing their awesome [IntelliJ IDEA](https://www.jetbrains.com/idea/) to me for free, and [DigitalOcean](https://m.do.co/c/442b929528db) (*referral link*) for supporting the project: diff --git a/docs/integrations.md b/docs/integrations.md index 03c8229a..3eddb5e6 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -4,24 +4,6 @@ There are quite a few projects that work with ntfy, integrate ntfy, or have been I've added a โญ to projects or posts that have a significant following, or had a lot of interaction by the community. -## Public ntfy servers - -Here's a list of public ntfy servers. As of right now, there is only one official server. The others are provided by the -ntfy community. Thanks to everyone running a public server. **You guys rock!** - -| URL | Country | -|---------------------------------------------------|--------------------| -| [ntfy.sh](https://ntfy.sh/) (*Official*) | ๐Ÿ‡บ๐Ÿ‡ธ United States | -| [ntfy.tedomum.net](https://ntfy.tedomum.net/) | ๐Ÿ‡ซ๐Ÿ‡ท France | -| [ntfy.jae.fi](https://ntfy.jae.fi/) | ๐Ÿ‡ซ๐Ÿ‡ฎ Finland | -| [ntfy.adminforge.de](https://ntfy.adminforge.de/) | ๐Ÿ‡ฉ๐Ÿ‡ช Germany | -| [ntfy.envs.net](https://ntfy.envs.net) | ๐Ÿ‡ฉ๐Ÿ‡ช Germany | -| [ntfy.mzte.de](https://ntfy.mzte.de/) | ๐Ÿ‡ฉ๐Ÿ‡ช Germany | -| [ntfy.hostux.net](https://ntfy.hostux.net/) | ๐Ÿ‡ซ๐Ÿ‡ท France | - -Please be aware that **server operators can log your messages**. The project also cannot guarantee the reliability -and uptime of third party servers, so use of each server is **at your own discretion**. - ## Official integrations - [Healthchecks.io](https://healthchecks.io/) โญ - Online service for monitoring regularly running tasks such as cron jobs @@ -42,6 +24,14 @@ and uptime of third party servers, so use of each server is **at your own discre - [diun](https://crazymax.dev/diun/) - Docker Image Update Notifier - [Cloudron](https://www.cloudron.io/store/sh.ntfy.cloudronapp.html) - Platform that makes it easy to manage web apps on your server +## Integration via HTTP/SMTP/etc. + +- [Watchtower](https://containrrr.dev/watchtower/) โญ - Automating Docker container base image updates (see [integration example](examples.md#watchtower-shoutrrr)) +- [Jellyfin](https://jellyfin.org/) โญ - The Free Software Media System (see [integration example](examples.md#)) +- [Overseer](https://docs.overseerr.dev/using-overseerr/notifications/webhooks) โญ - a request management and media discovery tool for Plex (see [integration example](examples.md#jellyseerroverseerr-webhook)) +- [Tautulli](https://github.com/Tautulli/Tautulli) โญ - Monitoring and tracking tool for Plex (integration [via webhook](https://github.com/Tautulli/Tautulli/wiki/Notification-Agents-Guide#webhook)) +- [Mailrise](https://github.com/YoRyan/mailrise) - An SMTP gateway (integration via [Apprise](https://github.com/caronc/apprise/wiki/Notify_ntfy)) + ## [UnifiedPush](https://unifiedpush.org/users/apps/) integrations - [Element](https://f-droid.org/packages/im.vector.app/) โญ - Matrix client @@ -196,3 +186,22 @@ and uptime of third party servers, so use of each server is **at your own discre - [ntfy otro sistema de notificaciones pub-sub simple basado en HTTP](https://ugeek.github.io/blog/post/2021-11-05-ntfy-sh-otro-sistema-de-notificaciones-pub-sub-simple-basado-en-http.html) - ugeek.github.io - 11/2021 - [Show HN: A tool to send push notifications to your phone, written in Go](https://news.ycombinator.com/item?id=29715464) โญ - news.ycombinator.com - 12/2021 - [Reddit selfhostable post](https://www.reddit.com/r/selfhosted/comments/qxlsm9/my_open_source_notification_android_app_and/) โญ - reddit.com - 11/2021 + + +## Alternative ntfy servers + +Here's a list of public ntfy servers. As of right now, there is only one official server. The others are provided by the +ntfy community. Thanks to everyone running a public server. **You guys rock!** + +| URL | Country | +|---------------------------------------------------|--------------------| +| [ntfy.sh](https://ntfy.sh/) (*Official*) | ๐Ÿ‡บ๐Ÿ‡ธ United States | +| [ntfy.tedomum.net](https://ntfy.tedomum.net/) | ๐Ÿ‡ซ๐Ÿ‡ท France | +| [ntfy.jae.fi](https://ntfy.jae.fi/) | ๐Ÿ‡ซ๐Ÿ‡ฎ Finland | +| [ntfy.adminforge.de](https://ntfy.adminforge.de/) | ๐Ÿ‡ฉ๐Ÿ‡ช Germany | +| [ntfy.envs.net](https://ntfy.envs.net) | ๐Ÿ‡ฉ๐Ÿ‡ช Germany | +| [ntfy.mzte.de](https://ntfy.mzte.de/) | ๐Ÿ‡ฉ๐Ÿ‡ช Germany | +| [ntfy.hostux.net](https://ntfy.hostux.net/) | ๐Ÿ‡ซ๐Ÿ‡ท France | + +Please be aware that **server operators can log your messages**. The project also cannot guarantee the reliability +and uptime of third party servers, so use of each server is **at your own discretion**. diff --git a/docs/publish.md b/docs/publish.md index 1f52cf3a..1d1109e4 100644 --- a/docs/publish.md +++ b/docs/publish.md @@ -2939,7 +2939,7 @@ To publish/subscribe to protected topics, you can: When using Basic auth, base64 only encodes username and password. It **is not encrypting it**. For your self-hosted server, **be sure to use HTTPS to avoid eavesdropping** and exposing your password. -### Username & password +### Username + password The simplest way to authenticate against a ntfy server is to use [Basic auth](https://en.wikipedia.org/wiki/Basic_access_authentication). Here's an example with a user `testuser` and password `fakepassword`: @@ -3549,10 +3549,10 @@ but just in case, let's list them all: |---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Message length** | Each message can be up to 4,096 bytes long. Longer messages are treated as [attachments](#attachments). | | **Requests** | By default, the server is configured to allow 60 requests per visitor at once, and then refills the your allowed requests bucket at a rate of one request per 5 seconds. | -| **Daily messages** | By default, the number of messages is governed by the request limits. This can be overridden. On ntfy.sh, the daily message limit is 1,000. | -| **E-mails** | By default, the server is configured to allow sending 16 e-mails per visitor at once, and then refills the your allowed e-mail bucket at a rate of one per hour. On ntfy.sh, the daily limit is 10. | +| **Daily messages** | By default, the number of messages is governed by the request limits. This can be overridden. On ntfy.sh, the daily message limit is 250. | +| **E-mails** | By default, the server is configured to allow sending 16 e-mails per visitor at once, and then refills the your allowed e-mail bucket at a rate of one per hour. On ntfy.sh, the daily limit is 5. | | **Subscription limit** | By default, the server allows each visitor to keep 30 connections to the server open. | -| **Attachment size limit** | By default, the server allows attachments up to 15 MB in size, up to 100 MB in total per visitor and up to 5 GB across all visitors. On ntfy.sh, the attachment size limit is 5 MB, and the per-visitor total is 50 MB. | +| **Attachment size limit** | By default, the server allows attachments up to 15 MB in size, up to 100 MB in total per visitor and up to 5 GB across all visitors. On ntfy.sh, the attachment size limit is 2 MB, and the per-visitor total is 20 MB. | | **Attachment expiry** | By default, the server deletes attachments after 3 hours and thereby frees up space from the total visitor attachment limit. | | **Attachment bandwidth** | By default, the server allows 500 MB of GET/PUT/POST traffic for attachments per visitor in a 24 hour period. Traffic exceeding that is rejected. On ntfy.sh, the daily bandwidth limit is 200 MB. | | **Total number of topics** | By default, the server is configured to allow 15,000 topics. The ntfy.sh server has higher limits though. | diff --git a/docs/releases.md b/docs/releases.md index 72cc39e5..37ccd4bc 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -1178,7 +1178,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release ## Not released yet -## ntfy server v2.5.0 (UNRELEASED) +### ntfy server v2.5.0 (UNRELEASED) **Features:** @@ -1188,6 +1188,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release * Removed old ntfy website from ntfy entirely (no ticket) * Fix potential subscriber ID clash ([#712](https://github.com/binwiederhier/ntfy/issues/712), thanks to [@peterbourgon](https://github.com/peterbourgon) for reporting, and [@dropdevrahul](https://github.com/dropdevrahul) for fixing) +* Support for `quoted-printable` in incoming emails ([#719](https://github.com/binwiederhier/ntfy/pull/719), thanks to [@Aerion](https://github.com/Aerion)) ### ntfy Android app v1.16.1 (UNRELEASED) diff --git a/server/smtp_server.go b/server/smtp_server.go index 16d97328..b9fbe6ee 100644 --- a/server/smtp_server.go +++ b/server/smtp_server.go @@ -9,6 +9,7 @@ import ( "io" "mime" "mime/multipart" + "mime/quotedprintable" "net" "net/http" "net/http/httptest" @@ -265,6 +266,8 @@ func readMultipartMailBody(body io.Reader, params map[string]string, depth int) func readPlainTextMailBody(reader io.Reader, transferEncoding string) (string, error) { if strings.ToLower(transferEncoding) == "base64" { reader = base64.NewDecoder(base64.StdEncoding, reader) + } else if strings.ToLower(transferEncoding) == "quoted-printable" { + reader = quotedprintable.NewReader(reader) } body, err := io.ReadAll(reader) if err != nil { diff --git a/server/smtp_server_test.go b/server/smtp_server_test.go index 49085d79..7e1d29d9 100644 --- a/server/smtp_server_test.go +++ b/server/smtp_server_test.go @@ -303,6 +303,39 @@ BBBBBBBBBBBBBBBBBBBBBBBBB` writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued") } +func TestSmtpBackend_Plaintext_QuotedPrintable(t *testing.T) { + email := `EHLO example.com +MAIL FROM: phil@example.com +RCPT TO: mytopic@ntfy.sh +DATA +Date: Tue, 28 Dec 2021 00:30:10 +0100 +Message-ID: +Subject: and one more +From: Phil +To: mytopic@ntfy.sh +Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +what's +=C3=A0&=C3=A9"'(-=C3=A8_=C3=A7=C3=A0) +=3D=3D=3D=3D=3D +up +. +` + s, c, conf, scanner := newTestSMTPServer(t, func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "/mytopic", r.URL.Path) + require.Equal(t, "and one more", r.Header.Get("Title")) + require.Equal(t, `what's +ร &รฉ"'(-รจ_รงร ) +===== +up`, readAll(t, r.Body)) + }) + conf.SMTPServerAddrPrefix = "" + defer s.Close() + defer c.Close() + writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued") +} + func TestSmtpBackend_Unsupported(t *testing.T) { email := `EHLO example.com MAIL FROM: phil@example.com @@ -390,6 +423,49 @@ L0VOIj4KClRoaXMgaXMgYSB0ZXN0IG1lc3NhZ2UgZnJvbSBUcnVlTkFTIENPUkUuCg== writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued") } +func TestSmtpBackend_MultipartQuotedPrintable(t *testing.T) { + email := `EHLO example.com +MAIL FROM: phil@example.com +RCPT TO: ntfy-mytopic@ntfy.sh +DATA +MIME-Version: 1.0 +Date: Tue, 28 Dec 2021 00:30:10 +0100 +Message-ID: +Subject: and one more +From: Phil +To: ntfy-mytopic@ntfy.sh +Content-Type: multipart/alternative; boundary="000000000000f3320b05d42915c9" + +--000000000000f3320b05d42915c9 +Content-Type: text/html; charset="UTF-8" + +html, ignore me + +--000000000000f3320b05d42915c9 +Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +what's +=C3=A0&=C3=A9"'(-=C3=A8_=C3=A7=C3=A0) +=3D=3D=3D=3D=3D +up + +--000000000000f3320b05d42915c9-- +. +` + s, c, _, scanner := newTestSMTPServer(t, func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "/mytopic", r.URL.Path) + require.Equal(t, "and one more", r.Header.Get("Title")) + require.Equal(t, `what's +ร &รฉ"'(-รจ_รงร ) +===== +up`, readAll(t, r.Body)) + }) + defer s.Close() + defer c.Close() + writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued") +} + func TestSmtpBackend_NestedMultipartBase64(t *testing.T) { email := `EHLO example.com MAIL FROM: test@mydomain.me