Philipp Heckel 4 лет назад
Родитель
Сommit
3bc8ff0104
8 измененных файлов с 148 добавлено и 51 удалено
  1. 2 0
      client/client_test.go
  2. 1 1
      cmd/serve.go
  3. 46 23
      docs/config.md
  4. 50 16
      docs/publish.md
  5. BIN
      docs/static/img/screenshot-email.png
  6. 27 10
      server/server.yml
  7. 1 1
      util/util.go
  8. 21 0
      util/util_test.go

+ 2 - 0
client/client_test.go

@@ -37,6 +37,8 @@ func TestClient_Publish_Subscribe(t *testing.T) {
 	require.Equal(t, "some delayed message", msg.Message)
 	require.Equal(t, "some delayed message", msg.Message)
 	require.True(t, time.Now().Add(24*time.Hour).Unix() < msg.Time)
 	require.True(t, time.Now().Add(24*time.Hour).Unix() < msg.Time)
 
 
+	time.Sleep(200 * time.Millisecond)
+
 	msg = nextMessage(c)
 	msg = nextMessage(c)
 	require.NotNil(t, msg)
 	require.NotNil(t, msg)
 	require.Equal(t, "some message", msg.Message)
 	require.Equal(t, "some message", msg.Message)

+ 1 - 1
cmd/serve.go

@@ -22,7 +22,7 @@ var flagsServe = []cli.Flag{
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: server.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: server.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: server.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: server.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: server.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: server.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
-	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-addr", EnvVars: []string{"NTFY_SMTP_ADDR"}, Usage: "SMTP address (host:port) to allow email sending"}),
+	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-addr", EnvVars: []string{"NTFY_SMTP_ADDR"}, Usage: "SMTP server address (host:port) to allow email sending"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-user", EnvVars: []string{"NTFY_SMTP_USER"}, Usage: "SMTP user (if e-mail sending is enabled)"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-user", EnvVars: []string{"NTFY_SMTP_USER"}, Usage: "SMTP user (if e-mail sending is enabled)"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-pass", EnvVars: []string{"NTFY_SMTP_PASS"}, Usage: "SMTP password (if e-mail sending is enabled)"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-pass", EnvVars: []string{"NTFY_SMTP_PASS"}, Usage: "SMTP password (if e-mail sending is enabled)"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-from", EnvVars: []string{"NTFY_SMTP_FROM"}, Usage: "SMTP sender address (if e-mail sending is enabled)"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-from", EnvVars: []string{"NTFY_SMTP_FROM"}, Usage: "SMTP sender address (if e-mail sending is enabled)"}),

+ 46 - 23
docs/config.md

@@ -300,6 +300,7 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
 
 
 | Config option | Env variable | Format | Default | Description |
 | Config option | Env variable | Format | Default | Description |
 |---|---|---|---|---|
 |---|---|---|---|---|
+| `base-url` | `NTFY_BASE_URL` | *URL* | - | Public facing base URL of the service (e.g. `https://ntfy.sh`) |
 | `listen-http` | `NTFY_LISTEN_HTTP` | `[host]:port` | `:80` | Listen address for the HTTP web server |
 | `listen-http` | `NTFY_LISTEN_HTTP` | `[host]:port` | `:80` | Listen address for the HTTP web server |
 | `listen-https` | `NTFY_LISTEN_HTTPS` | `[host]:port` | - | Listen address for the HTTPS web server. If set, you also need to set `key-file` and `cert-file`. |
 | `listen-https` | `NTFY_LISTEN_HTTPS` | `[host]:port` | - | Listen address for the HTTPS web server. If set, you also need to set `key-file` and `cert-file`. |
 | `key-file` | `NTFY_KEY_FILE` | *filename* | - | HTTPS/TLS private key file, only used if `listen-https` is set. |
 | `key-file` | `NTFY_KEY_FILE` | *filename* | - | HTTPS/TLS private key file, only used if `listen-https` is set. |
@@ -307,42 +308,64 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
 | `firebase-key-file` | `NTFY_FIREBASE_KEY_FILE` | *filename* | - | If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. See [Firebase (FCM](#firebase-fcm). |
 | `firebase-key-file` | `NTFY_FIREBASE_KEY_FILE` | *filename* | - | If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. See [Firebase (FCM](#firebase-fcm). |
 | `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. See [message cache](#message-cache). |
 | `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. See [message cache](#message-cache). |
 | `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. Set this to `0` to disable the cache entirely. |
 | `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. Set this to `0` to disable the cache entirely. |
+| `behind-proxy` | `NTFY_BEHIND_PROXY` | *bool* | false | If set, the X-Forwarded-For header is used to determine the visitor IP address instead of the remote address of the connection. |
+| `smtp-addr` | `NTFY_SMTP_ADDR` | `host:port` | - | SMTP server address to allow email sending |
+| `smtp-user` | `NTFY_SMTP_USER` | *string* | - | SMTP user; only used if e-mail sending is enabled |
+| `smtp-pass` | `NTFY_SMTP_PASS` | *string* | - | SMTP password; only used if e-mail sending is enabled |
+| `smtp-from` | `NTFY_SMTP_FROM` | *e-mail address* | - | SMTP sender e-mail address; only used if e-mail sending is enabled |
 | `keepalive-interval` | `NTFY_KEEPALIVE_INTERVAL` | *duration* | 30s | Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that. |
 | `keepalive-interval` | `NTFY_KEEPALIVE_INTERVAL` | *duration* | 30s | Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that. |
 | `manager-interval` | `$NTFY_MANAGER_INTERVAL` | *duration* | 1m | Interval in which the manager prunes old messages, deletes topics and prints the stats. |
 | `manager-interval` | `$NTFY_MANAGER_INTERVAL` | *duration* | 1m | Interval in which the manager prunes old messages, deletes topics and prints the stats. |
 | `global-topic-limit` | `NTFY_GLOBAL_TOPIC_LIMIT` | *number* | 5000 | Rate limiting: Total number of topics before the server rejects new topics. |
 | `global-topic-limit` | `NTFY_GLOBAL_TOPIC_LIMIT` | *number* | 5000 | Rate limiting: Total number of topics before the server rejects new topics. |
 | `visitor-subscription-limit` | `NTFY_VISITOR_SUBSCRIPTION_LIMIT` | *number* | 30 | Rate limiting: Number of subscriptions per visitor (IP address) |
 | `visitor-subscription-limit` | `NTFY_VISITOR_SUBSCRIPTION_LIMIT` | *number* | 30 | Rate limiting: Number of subscriptions per visitor (IP address) |
 | `visitor-request-limit-burst` | `NTFY_VISITOR_REQUEST_LIMIT_BURST` | *number* | 60 | Allowed GET/PUT/POST requests per second, per visitor. This setting is the initial bucket of requests each visitor has |
 | `visitor-request-limit-burst` | `NTFY_VISITOR_REQUEST_LIMIT_BURST` | *number* | 60 | Allowed GET/PUT/POST requests per second, per visitor. This setting is the initial bucket of requests each visitor has |
 | `visitor-request-limit-replenish` | `NTFY_VISITOR_REQUEST_LIMIT_REPLENISH` | *duration* | 10s | Strongly related to `visitor-request-limit-burst`: The rate at which the bucket is refilled |
 | `visitor-request-limit-replenish` | `NTFY_VISITOR_REQUEST_LIMIT_REPLENISH` | *duration* | 10s | Strongly related to `visitor-request-limit-burst`: The rate at which the bucket is refilled |
-| `behind-proxy` | `NTFY_BEHIND_PROXY` | *bool* | false | If set, the X-Forwarded-For header is used to determine the visitor IP address instead of the remote address of the connection. |
+| `visitor-email-limit-burst` | `NTFY_VISITOR_EMAIL_LIMIT_BURST` | *number* | 16 |Initial limit of e-mails per visitor |
+| `visitor-email-limit-replenish` | `NTFY_VISITOR_EMAIL_LIMIT_REPLENISH` | *duration* | 1h | Strongly related to `visitor-email-limit-burst`: The rate at which the bucket is refilled |
 
 
 The format for a *duration* is: `<number>(smh)`, e.g. 30s, 20m or 1h.
 The format for a *duration* is: `<number>(smh)`, e.g. 30s, 20m or 1h.
 
 
 ## Command line options
 ## Command line options
 ```
 ```
-$ ntfy --help
+$ ntfy serve --help
 NAME:
 NAME:
-   ntfy - Simple pub-sub notification service
+   main serve - Run the ntfy server
 
 
 USAGE:
 USAGE:
-   ntfy [OPTION..]
-
-GLOBAL OPTIONS:
-   --config value, -c value                           config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE]
-   --listen-http value, -l value                      ip:port used to as listen address (default: ":80") [$NTFY_LISTEN_HTTP]
-   --firebase-key-file value, -F value                Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
-   --cache-file value, -C value                       cache file used for message caching [$NTFY_CACHE_FILE]
-   --cache-duration since, -b since                   buffer messages for this time to allow since requests (default: 12h0m0s) [$NTFY_CACHE_DURATION]
-   --keepalive-interval value, -k value               interval of keepalive messages (default: 30s) [$NTFY_KEEPALIVE_INTERVAL]
-   --manager-interval value, -m value                 interval of for message pruning and stats printing (default: 1m0s) [$NTFY_MANAGER_INTERVAL]
-   --global-topic-limit value, -T value               total number of topics allowed (default: 5000) [$NTFY_GLOBAL_TOPIC_LIMIT]
-   --visitor-subscription-limit value, -V value       number of subscriptions per visitor (default: 30) [$NTFY_VISITOR_SUBSCRIPTION_LIMIT]
-   --visitor-request-limit-burst value, -B value      initial limit of requests per visitor (default: 60) [$NTFY_VISITOR_REQUEST_LIMIT_BURST]
-   --visitor-request-limit-replenish value, -R value  interval at which burst limit is replenished (one per x) (default: 10s) [$NTFY_VISITOR_REQUEST_LIMIT_REPLENISH]
-   --behind-proxy, -P                                 if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting) (default: false) [$NTFY_BEHIND_PROXY]
-
-Try 'ntfy COMMAND --help' for more information.
-
-ntfy v1.4.8 (7b8185c), runtime go1.17, built at 1637872539
-Copyright (C) 2021 Philipp C. Heckel, distributed under the Apache License 2.0
+   ntfy serve [OPTIONS..]
+
+DESCRIPTION:
+   Run the ntfy server and listen for incoming requests
+   
+   The command will load the configuration from /etc/ntfy/server.yml. Config options can 
+   be overridden using the command line options.
+   
+   Examples:
+     ntfy serve                      # Starts server in the foreground (on port 80)
+     ntfy serve --listen-http :8080  # Starts server with alternate port
+
+OPTIONS:
+   --config value, -c value                 config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE]
+   --base-url value, -B value               externally visible base URL for this host (e.g. https://ntfy.sh) [$NTFY_BASE_URL]
+   --listen-http value, -l value            ip:port used to as HTTP listen address (default: ":80") [$NTFY_LISTEN_HTTP]
+   --listen-https value, -L value           ip:port used to as HTTPS listen address [$NTFY_LISTEN_HTTPS]
+   --key-file value, -K value               private key file, if listen-https is set [$NTFY_KEY_FILE]
+   --cert-file value, -E value              certificate file, if listen-https is set [$NTFY_CERT_FILE]
+   --firebase-key-file value, -F value      Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
+   --cache-file value, -C value             cache file used for message caching [$NTFY_CACHE_FILE]
+   --cache-duration since, -b since         buffer messages for this time to allow since requests (default: 12h0m0s) [$NTFY_CACHE_DURATION]
+   --keepalive-interval value, -k value     interval of keepalive messages (default: 30s) [$NTFY_KEEPALIVE_INTERVAL]
+   --manager-interval value, -m value       interval of for message pruning and stats printing (default: 1m0s) [$NTFY_MANAGER_INTERVAL]
+   --smtp-addr value                        SMTP server address (host:port) to allow email sending [$NTFY_SMTP_ADDR]
+   --smtp-user value                        SMTP user (if e-mail sending is enabled) [$NTFY_SMTP_USER]
+   --smtp-pass value                        SMTP password (if e-mail sending is enabled) [$NTFY_SMTP_PASS]
+   --smtp-from value                        SMTP sender address (if e-mail sending is enabled) [$NTFY_SMTP_FROM]
+   --global-topic-limit value, -T value     total number of topics allowed (default: 5000) [$NTFY_GLOBAL_TOPIC_LIMIT]
+   --visitor-subscription-limit value       number of subscriptions per visitor (default: 30) [$NTFY_VISITOR_SUBSCRIPTION_LIMIT]
+   --visitor-request-limit-burst value      initial limit of requests per visitor (default: 60) [$NTFY_VISITOR_REQUEST_LIMIT_BURST]
+   --visitor-request-limit-replenish value  interval at which burst limit is replenished (one per x) (default: 10s) [$NTFY_VISITOR_REQUEST_LIMIT_REPLENISH]
+   --visitor-email-limit-burst value        initial limit of e-mails per visitor (default: 16) [$NTFY_VISITOR_EMAIL_LIMIT_BURST]
+   --visitor-email-limit-replenish value    interval at which burst limit is replenished (one per x) (default: 1h0m0s) [$NTFY_VISITOR_EMAIL_LIMIT_REPLENISH]
+   --behind-proxy, -P                       if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting) (default: false) [$NTFY_BEHIND_PROXY]
+   --help, -h                               show help (default: false)
 ```
 ```
 
 

+ 50 - 16
docs/publish.md

@@ -592,16 +592,26 @@ Here's an example with a custom message, tags and a priority:
     file_get_contents('https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull');
     file_get_contents('https://ntfy.sh/mywebhook/publish?message=Webhook+triggered&priority=high&tags=warning,skull');
     ```
     ```
 
 
-## Publish as e-mail
+## E-mail notifications
 You can forward messages to e-mail by specifying an address in the header. This can be useful for messages that 
 You can forward messages to e-mail by specifying an address in the header. This can be useful for messages that 
-you'd like to persist longer, or to blast-notify yourself on all possible channels. Since ntfy does not provide auth,
-the [rate limiting](#limitations) is pretty strict (see below). In the default configuration, you get 16 e-mails per 
-visitor (IP address) and then after that one per hour. On top of that, your IP address appears in the e-mail body. This 
-is to prevent abuse. 
+you'd like to persist longer, or to blast-notify yourself on all possible channels. 
+
+Usage is easy: Simply pass the `X-Email` header (or any of its aliases: `X-E-mail`, `Email`, `E-mail`, `Mail`, or `e`).
+Only one e-mail address is supported.
+
+Since ntfy does not provide auth (yet), the rate limiting is pretty strict (see [limitations](#limitations)). In the 
+default configuration, you get **16 e-mails per visitor** (IP address) and then after that one per hour. On top of 
+that, your IP address appears in the e-mail body. This is to prevent abuse.
 
 
 === "Command line (curl)"
 === "Command line (curl)"
     ```
     ```
-    curl -H "Email: phil@example.com" -d "You've Got Mail" ntfy.sh/alerts
+    curl \
+        -H "Email: phil@example.com" \
+        -H "Tags: warning,skull,backup-host,ssh-login" \
+        -H "Priority: high" \
+        -d "Unknown login from 5.31.23.83 to backups.example.com" \
+        ntfy.sh/alerts
+    curl -H "Email: phil@example.com" -d "You've Got Mail" 
     curl -d "You've Got Mail" "ntfy.sh/alerts?email=phil@example.com"
     curl -d "You've Got Mail" "ntfy.sh/alerts?email=phil@example.com"
     ```
     ```
 
 
@@ -609,7 +619,9 @@ is to prevent abuse.
     ```
     ```
     ntfy publish \
     ntfy publish \
         --email=phil@example.com \
         --email=phil@example.com \
-        alerts "You've Got Mail"
+        --tags=warning,skull,backup-host,ssh-login \
+        --priority=high \
+        alerts "Unknown login from 5.31.23.83 to backups.example.com"
     ```
     ```
 
 
 === "HTTP"
 === "HTTP"
@@ -617,31 +629,44 @@ is to prevent abuse.
     POST /alerts HTTP/1.1
     POST /alerts HTTP/1.1
     Host: ntfy.sh
     Host: ntfy.sh
     Email: phil@example.com
     Email: phil@example.com
+    Tags: warning,skull,backup-host,ssh-login
+    Priority: high
 
 
-    You've Got Mail
+    Unknown login from 5.31.23.83 to backups.example.com
     ```
     ```
 
 
 === "JavaScript"
 === "JavaScript"
     ``` javascript
     ``` javascript
     fetch('https://ntfy.sh/alerts', {
     fetch('https://ntfy.sh/alerts', {
         method: 'POST',
         method: 'POST',
-        body: "You've Got Mail",
-        headers: { 'Email': 'phil@example.com' }
+        body: "Unknown login from 5.31.23.83 to backups.example.com",
+        headers: { 
+            'Email': 'phil@example.com',
+            'Tags': 'warning,skull,backup-host,ssh-login',
+            'Priority': 'high'
+        }
     })
     })
     ```
     ```
 
 
 === "Go"
 === "Go"
     ``` go
     ``` go
-    req, _ := http.NewRequest("POST", "https://ntfy.sh/alerts", strings.NewReader("You've Got Mail"))
+    req, _ := http.NewRequest("POST", "https://ntfy.sh/alerts", 
+        strings.NewReader("Unknown login from 5.31.23.83 to backups.example.com"))
     req.Header.Set("Email", "phil@example.com")
     req.Header.Set("Email", "phil@example.com")
+    req.Header.Set("Tags", "warning,skull,backup-host,ssh-login")
+    req.Header.Set("Priority", "high")
     http.DefaultClient.Do(req)
     http.DefaultClient.Do(req)
     ```
     ```
 
 
 === "Python"
 === "Python"
     ``` python
     ``` python
     requests.post("https://ntfy.sh/alerts",
     requests.post("https://ntfy.sh/alerts",
-        data="You've Got Mail",
-        headers={ "Email": "phil@example.com" })
+        data="Unknown login from 5.31.23.83 to backups.example.com",
+        headers={ 
+            "Email": "phil@example.com",
+            "Tags": "warning,skull,backup-host,ssh-login",
+            "Priority": "high"
+        })
     ```
     ```
 
 
 === "PHP"
 === "PHP"
@@ -651,12 +676,21 @@ is to prevent abuse.
             'method' => 'POST',
             'method' => 'POST',
             'header' =>
             'header' =>
                 "Content-Type: text/plain\r\n" .
                 "Content-Type: text/plain\r\n" .
-                "Email: phil@example.com",
-            'content' => 'You've Got Mail'
+                "Email: phil@example.com\r\n" .
+                "Tags: warning,skull,backup-host,ssh-login\r\n" .
+                "Priority: high",
+            'content' => 'Unknown login from 5.31.23.83 to backups.example.com'
         ]
         ]
     ]));
     ]));
     ```
     ```
 
 
+Here's what that looks like in Google Mail:
+
+<figure markdown>
+  ![e-mail notification](static/img/screenshot-email.png){ width=600 }
+  <figcaption>E-mail notification</figcaption>
+</figure>
+
 ## Advanced features
 ## Advanced features
 
 
 ### Message caching
 ### Message caching
@@ -827,6 +861,6 @@ and can be passed as **HTTP headers** or **query parameters in the URL**. They a
 | `X-Priority` | `Priority`, `prio`, `p` | [Message priority](#message-priority) |
 | `X-Priority` | `Priority`, `prio`, `p` | [Message priority](#message-priority) |
 | `X-Tags` | `Tags`, `Tag`, `ta` | [Tags and emojis](#tags-emojis) |
 | `X-Tags` | `Tags`, `Tag`, `ta` | [Tags and emojis](#tags-emojis) |
 | `X-Delay` | `Delay`, `X-At`, `At`, `X-In`, `In` | Timestamp or duration for [delayed delivery](#scheduled-delivery) |
 | `X-Delay` | `Delay`, `X-At`, `At`, `X-In`, `In` | Timestamp or duration for [delayed delivery](#scheduled-delivery) |
-| `X-Email` | `X-E-Mail`, `Email`, `E-Mail`, `mail`, `e` | E-mail address for [e-mail delivery](#publish-as-e-mail) |
+| `X-Email` | `X-E-Mail`, `Email`, `E-Mail`, `mail`, `e` | E-mail address for [e-mail notifications](#e-mail-notifications) |
 | `X-Cache` | `Cache` | Allows disabling [message caching](#message-caching) |
 | `X-Cache` | `Cache` | Allows disabling [message caching](#message-caching) |
 | `X-Firebase` | `Firebase` | Allows disabling [sending to Firebase](#disable-firebase) |
 | `X-Firebase` | `Firebase` | Allows disabling [sending to Firebase](#disable-firebase) |

BIN
docs/static/img/screenshot-email.png


+ 27 - 10
server/server.yml

@@ -1,8 +1,12 @@
 # ntfy server config file
 # ntfy server config file
 
 
+# Public facing base URL of the service (e.g. https://ntfy.sh or https://ntfy.example.com)
+# This setting is currently only used by the e-mail feature.
+#
+# base-url:
+
 # Listen address for the HTTP & HTTPS web server. If "listen-https" is set, you must also
 # Listen address for the HTTP & HTTPS web server. If "listen-https" is set, you must also
-# set "key-file" and "cert-file".
-# Format: <hostname>:<port>
+# set "key-file" and "cert-file". Format: <hostname>:<port>
 #
 #
 # listen-http: ":80"
 # listen-http: ":80"
 # listen-https:
 # listen-https:
@@ -34,6 +38,27 @@
 #
 #
 # cache-duration: 12h
 # cache-duration: 12h
 
 
+# If set, the X-Forwarded-For header is used to determine the visitor IP address
+# instead of the remote address of the connection.
+#
+# WARNING: If you are behind a proxy, you must set this, otherwise all visitors are rate limited
+#          as if they are one.
+#
+# behind-proxy: false
+
+# If enabled, allow e-mail notifications via the 'X-Email' header. As of today, only SMTP servers
+# with plain text auth and STARTLS are supported. Please also refer to the rate limiting settings
+# below (visitor-email-limit-burst & visitor-email-limit-burst).
+#
+# - smtp-addr is the hostname:port of the SMTP server
+# - smtp-user/smtp-pass are the username and password of the SMTP user
+# - smtp-from is the e-mail address of the sender
+#
+# smtp-addr:
+# smtp-user:
+# smtp-pass:
+# smtp-from:
+
 # Interval in which keepalive messages are sent to the client. This is to prevent
 # Interval in which keepalive messages are sent to the client. This is to prevent
 # intermediaries closing the connection for inactivity.
 # intermediaries closing the connection for inactivity.
 #
 #
@@ -67,11 +92,3 @@
 #
 #
 # visitor-email-limit-burst: 16
 # visitor-email-limit-burst: 16
 # visitor-email-limit-replenish: 1h
 # visitor-email-limit-replenish: 1h
-
-# If set, the X-Forwarded-For header is used to determine the visitor IP address
-# instead of the remote address of the connection.
-#
-# WARNING: If you are behind a proxy, you must set this, otherwise all visitors are rate limited
-#          as if they are one.
-#
-# behind-proxy: false

+ 1 - 1
util/util.go

@@ -148,7 +148,7 @@ func PriorityString(priority int) (string, error) {
 	case 4:
 	case 4:
 		return "high", nil
 		return "high", nil
 	case 5:
 	case 5:
-		return "urgent", nil
+		return "max", nil
 	default:
 	default:
 		return "", errInvalidPriority
 		return "", errInvalidPriority
 	}
 	}

+ 21 - 0
util/util_test.go

@@ -100,3 +100,24 @@ func TestParsePriority_Invalid(t *testing.T) {
 		require.Equal(t, errInvalidPriority, err)
 		require.Equal(t, errInvalidPriority, err)
 	}
 	}
 }
 }
+
+func TestPriorityString(t *testing.T) {
+	priorities := []int{0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 5}
+	expected := []string{"default", "min", "low", "default", "high", "max"}
+	for i, priority := range priorities {
+		actual, err := PriorityString(priority)
+		require.Nil(t, err)
+		require.Equal(t, expected[i], actual)
+	}
+}
+
+func TestPriorityString_Invalid(t *testing.T) {
+	_, err := PriorityString(99)
+	require.Equal(t, err, errInvalidPriority)
+}
+
+func TestShortTopicURL(t *testing.T) {
+	require.Equal(t, "ntfy.sh/mytopic", ShortTopicURL("https://ntfy.sh/mytopic"))
+	require.Equal(t, "ntfy.sh/mytopic", ShortTopicURL("http://ntfy.sh/mytopic"))
+	require.Equal(t, "lalala", ShortTopicURL("lalala"))
+}