diff --git a/docs/config.md b/docs/config.md index 9af79992..bb7f7e1b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -44,6 +44,14 @@ Here are a few working sample configs: attachment-cache-dir: "/var/cache/ntfy/attachments" ``` +=== "server.yml (behind proxy, with cache + attachments)" + ``` yaml + base-url: "http://ntfy.example.com" + listen-http: ":2586" + cache-file: "/var/cache/ntfy/cache.db" + attachment-cache-dir: "/var/cache/ntfy/attachments" + ``` + === "server.yml (ntfy.sh config)" ``` yaml # All the things: Behind a proxy, Firebase, cache, attachments, @@ -649,8 +657,8 @@ or the root domain: ServerName ntfy.sh - # Proxy connections to ntfy (requires "a2enmod proxy") - ProxyPass / http://127.0.0.1:2586/ + # Proxy connections to ntfy (requires "a2enmod proxy proxy_http") + ProxyPass / http://127.0.0.1:2586/ upgrade=websocket ProxyPassReverse / http://127.0.0.1:2586/ SetEnv proxy-nokeepalive 1 @@ -658,19 +666,13 @@ or the root domain: # Higher than the max message size of 4096 bytes LimitRequestBody 102400 - - # Enable mod_rewrite (requires "a2enmod rewrite") - RewriteEngine on - - # WebSockets support (requires "a2enmod rewrite proxy_wstunnel") - RewriteCond %{HTTP:Upgrade} websocket [NC] - RewriteCond %{HTTP:Connection} upgrade [NC] - RewriteRule ^/?(.*) "ws://127.0.0.1:2586/$1" [P,L] # Redirect HTTP to HTTPS, but only for GET topic addresses, since we want - # it to work with curl without the annoying https:// prefix - RewriteCond %{REQUEST_METHOD} GET - RewriteRule ^/([-_A-Za-z0-9]{0,64})$ https://%{SERVER_NAME}/$1 [R,L] + # it to work with curl without the annoying https:// prefix (requires "a2enmod alias") + + RedirectMatch permanent "^/([-_A-Za-z0-9]{0,64})$" "https://%{SERVER_NAME}/$1" + + @@ -681,8 +683,8 @@ or the root domain: SSLCertificateKeyFile /etc/letsencrypt/live/ntfy.sh/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf - # Proxy connections to ntfy (requires "a2enmod proxy") - ProxyPass / http://127.0.0.1:2586/ + # Proxy connections to ntfy (requires "a2enmod proxy proxy_http") + ProxyPass / http://127.0.0.1:2586/ upgrade=websocket ProxyPassReverse / http://127.0.0.1:2586/ SetEnv proxy-nokeepalive 1 @@ -690,14 +692,7 @@ or the root domain: # Higher than the max message size of 4096 bytes LimitRequestBody 102400 - - # Enable mod_rewrite (requires "a2enmod rewrite") - RewriteEngine on - - # WebSockets support (requires "a2enmod rewrite proxy_wstunnel") - RewriteCond %{HTTP:Upgrade} websocket [NC] - RewriteCond %{HTTP:Connection} upgrade [NC] - RewriteRule ^/?(.*) "ws://127.0.0.1:2586/$1" [P,L] + ``` diff --git a/server/server.yml b/server/server.yml index 6b2fc989..b044a914 100644 --- a/server/server.yml +++ b/server/server.yml @@ -342,6 +342,10 @@ # - "field -> level" to match any value, e.g. "time_taken_ms -> debug" # Warning: Using log-level-overrides has a performance penalty. Only use it for temporary debugging. # +# Check your permissions: +# If you are running ntfy with systemd, make sure this log file is owned by the +# ntfy user and group by running: chown ntfy.ntfy . +# # Example (good for production): # log-level: info # log-format: json diff --git a/web/src/app/notificationUtils.js b/web/src/app/notificationUtils.js index 35c85ce6..0bd5136d 100644 --- a/web/src/app/notificationUtils.js +++ b/web/src/app/notificationUtils.js @@ -35,7 +35,7 @@ export const formatMessage = (m) => { }; const imageRegex = /\.(png|jpe?g|gif|webp)$/i; -const isImage = (attachment) => { +export const isImage = (attachment) => { if (!attachment) return false; // if there's a type, only take that into account diff --git a/web/src/components/Notifications.jsx b/web/src/components/Notifications.jsx index d1cce0e8..0b8b2e7d 100644 --- a/web/src/components/Notifications.jsx +++ b/web/src/components/Notifications.jsx @@ -27,7 +27,7 @@ import { useOutletContext } from "react-router-dom"; import { useRemark } from "react-remark"; import styled from "@emotion/styled"; import { formatBytes, formatShortDateTime, maybeActionErrors, openUrl, shortUrl, topicShortUrl, unmatchedTags } from "../app/utils"; -import { formatMessage, formatTitle } from "../app/notificationUtils"; +import { formatMessage, formatTitle, isImage } from "../app/notificationUtils"; import { LightboxBackdrop, Paragraph, VerticallyCenteredContainer } from "./styles"; import subscriptionManager from "../app/SubscriptionManager"; import priority1 from "../img/priority-1.svg"; @@ -346,7 +346,7 @@ const Attachment = (props) => { const { attachment } = props; const expired = attachment.expires && attachment.expires < Date.now() / 1000; const expires = attachment.expires && attachment.expires > Date.now() / 1000; - const displayableImage = !expired && attachment.type && attachment.type.startsWith("image/"); + const displayableImage = !expired && isImage(attachment); // Unexpired image if (displayableImage) {