mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-01-19 00:27:25 +01:00
Compare commits
12 Commits
v2.0.0
...
http-respo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db1a1fec0c | ||
|
|
7fb6f794e5 | ||
|
|
df68b0cb43 | ||
|
|
ca49fd1161 | ||
|
|
bb3f17ada2 | ||
|
|
d18c61f0da | ||
|
|
92cfc04024 | ||
|
|
2d0ce79011 | ||
|
|
c6e091a754 | ||
|
|
c8c16eb8e6 | ||
|
|
c815b183d4 | ||
|
|
6451762508 |
@@ -1179,9 +1179,9 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||
| `visitor-request-limit-exempt-hosts` | `NTFY_VISITOR_REQUEST_LIMIT_EXEMPT_HOSTS` | *comma-separated host/IP list* | - | Rate limiting: List of hostnames and IPs to be exempt from request rate limiting |
|
||||
| `visitor-subscription-limit` | `NTFY_VISITOR_SUBSCRIPTION_LIMIT` | *number* | 30 | Rate limiting: Number of subscriptions per visitor (IP address) |
|
||||
| `web-root` | `NTFY_WEB_ROOT` | `app`, `home` or `disable` | `app` | Sets web root to landing page (home), web app (app) or disables the web app entirely (disable) |
|
||||
| `enable-signup` | `NTFY_SIGNUP` | *boolean* (`true` or `false`) | `false` | Allows users to sign up via the web app, or API |
|
||||
| `enable-login` | `NTFY_LOGIN` | *boolean* (`true` or `false`) | `false` | Allows users to log in via the web app, or API |
|
||||
| `enable-reservations` | `NTFY_RESERVATIONS` | *boolean* (`true` or `false`) | `false` | Allows users to reserve topics (if their tier allows it) |
|
||||
| `enable-signup` | `NTFY_ENABLE_SIGNUP` | *boolean* (`true` or `false`) | `false` | Allows users to sign up via the web app, or API |
|
||||
| `enable-login` | `NTFY_ENABLE_LOGIN` | *boolean* (`true` or `false`) | `false` | Allows users to log in via the web app, or API |
|
||||
| `enable-reservations` | `NTFY_ENABLE_RESERVATIONS` | *boolean* (`true` or `false`) | `false` | Allows users to reserve topics (if their tier allows it) |
|
||||
| `stripe-secret-key` | `NTFY_STRIPE_SECRET_KEY` | *string* | - | Payments: Key used for the Stripe API communication, this enables payments |
|
||||
| `stripe-webhook-key` | `NTFY_STRIPE_WEBHOOK_KEY` | *string* | - | Payments: Key required to validate the authenticity of incoming webhooks from Stripe |
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ and uptime of third party servers, so use of each server is **at your own discre
|
||||
## Projects + scripts
|
||||
|
||||
- [Grafana-to-ntfy](https://github.com/kittyandrew/grafana-to-ntfy) - Grafana-to-ntfy alerts channel (Rust)
|
||||
- [Grafana-ntfy-webhook-integration](https://github.com/academo/grafana-alerting-ntfy-webhook-integration) - Integrates Grafana alerts webhooks (Go)
|
||||
- [ntfy-long-zsh-command](https://github.com/robfox92/ntfy-long-zsh-command) - Notifies you once a long-running command completes (zsh)
|
||||
- [ntfy-shellscripts](https://github.com/nickexyz/ntfy-shellscripts) - A few scripts for the ntfy project (Shell)
|
||||
- [QuickStatus](https://github.com/corneliusroot/QuickStatus) - A shell script to alert to any immediate problems upon login (Shell)
|
||||
@@ -114,6 +115,7 @@ and uptime of third party servers, so use of each server is **at your own discre
|
||||
## Blog + forum posts
|
||||
|
||||
- [Video: Simple Push Notifications ntfy](https://www.youtube.com/watch?v=u9EcWrsjE20) ⭐ - youtube.com - 2/2023
|
||||
- [Use ntfy.sh with Home Assistant](https://diecknet.de/en/2023/02/12/ntfy-sh-with-homeassistant/) - diecknet.de - 2/2023
|
||||
- [On installe Ntfy sur Synology Docker](https://www.maison-et-domotique.com/140356-serveur-notification-jeedom-ntfy-synology-docker/) - maison-et-domotique.co - 1/2023
|
||||
- [January 2023 Developer Update](https://community.nodebb.org/topic/16908/january-2023-developer-update) - nodebb.org - 1/2023
|
||||
- [Comment envoyer des notifications push sur votre téléphone facilement et gratuitement?](https://korben.info/notifications-push-telephone.html) - 1/2023
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Binaries for all releases can be found on the GitHub releases pages for the [ntfy server](https://github.com/binwiederhier/ntfy/releases)
|
||||
and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/releases).
|
||||
|
||||
## ntfy server v2.0.0 (UNRELEASED)
|
||||
## ntfy server v2.0.0
|
||||
Released February 16, 2023
|
||||
|
||||
This is the biggest ntfy server release I've ever done 🥳 . Lots of new and exciting features.
|
||||
|
||||
@@ -291,6 +291,7 @@ func (s *Server) closeDatabases() {
|
||||
|
||||
// handle is the main entry point for all HTTP requests
|
||||
func (s *Server) handle(w http.ResponseWriter, r *http.Request) {
|
||||
w = newHTTPResponseWriter(w) // Avoid logging "superfluous response.WriteHeader call" warning
|
||||
v, err := s.maybeAuthenticate(r) // Note: Always returns v, even when error is returned
|
||||
if err != nil {
|
||||
s.handleError(w, r, v, err)
|
||||
|
||||
@@ -1498,7 +1498,7 @@ func TestServer_PublishAttachmentTooLargeBodyVisitorAttachmentTotalSizeLimit(t *
|
||||
c.VisitorAttachmentTotalSizeLimit = 10000
|
||||
s := newTestServer(t, c)
|
||||
|
||||
response := request(t, s, "PUT", "/mytopic", util.RandomString(5000), nil)
|
||||
response := request(t, s, "PUT", "/mytopic", "text file!"+util.RandomString(4990), nil)
|
||||
msg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, 200, response.Code)
|
||||
require.Equal(t, "You received a file: attachment.txt", msg.Message)
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"heckel.io/ntfy/util"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func readBoolParam(r *http.Request, defaultValue bool, names ...string) bool {
|
||||
@@ -85,3 +88,57 @@ func readJSONWithLimit[T any](r io.ReadCloser, limit int, allowEmpty bool) (*T,
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
type httpResponseWriter struct {
|
||||
w http.ResponseWriter
|
||||
headerWritten bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type httpResponseWriterWithHijacker struct {
|
||||
httpResponseWriter
|
||||
}
|
||||
|
||||
var _ http.ResponseWriter = (*httpResponseWriter)(nil)
|
||||
var _ http.Flusher = (*httpResponseWriter)(nil)
|
||||
var _ http.Hijacker = (*httpResponseWriterWithHijacker)(nil)
|
||||
|
||||
func newHTTPResponseWriter(w http.ResponseWriter) http.ResponseWriter {
|
||||
if _, ok := w.(http.Hijacker); ok {
|
||||
return &httpResponseWriterWithHijacker{httpResponseWriter: httpResponseWriter{w: w}}
|
||||
}
|
||||
return &httpResponseWriter{w: w}
|
||||
}
|
||||
|
||||
func (w *httpResponseWriter) Header() http.Header {
|
||||
return w.w.Header()
|
||||
}
|
||||
|
||||
func (w *httpResponseWriter) Write(bytes []byte) (int, error) {
|
||||
w.mu.Lock()
|
||||
w.headerWritten = true
|
||||
w.mu.Unlock()
|
||||
return w.w.Write(bytes)
|
||||
}
|
||||
|
||||
func (w *httpResponseWriter) WriteHeader(statusCode int) {
|
||||
w.mu.Lock()
|
||||
if w.headerWritten {
|
||||
w.mu.Unlock()
|
||||
return
|
||||
}
|
||||
w.headerWritten = true
|
||||
w.mu.Unlock()
|
||||
w.w.WriteHeader(statusCode)
|
||||
}
|
||||
|
||||
func (w *httpResponseWriter) Flush() {
|
||||
if f, ok := w.w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *httpResponseWriterWithHijacker) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
h, _ := w.w.(http.Hijacker)
|
||||
return h.Hijack()
|
||||
}
|
||||
|
||||
45
web/public/static/langs/ar.json
Normal file
45
web/public/static/langs/ar.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"action_bar_logo_alt": "شعار ntfy",
|
||||
"action_bar_settings": "اﻹعدادات",
|
||||
"action_bar_clear_notifications": "محو كافة الإشعارات",
|
||||
"action_bar_unsubscribe": "إلغاء الاشتراك",
|
||||
"message_bar_show_dialog": "إظهار مربع حوار النشر",
|
||||
"message_bar_publish": "نشر الرسالة",
|
||||
"nav_topics_title": "المواضيع التي تم الاشتراك فيها",
|
||||
"nav_button_all_notifications": "كافة الإشعارات",
|
||||
"nav_button_settings": "اﻹعدادات",
|
||||
"nav_button_documentation": "الدليل",
|
||||
"nav_button_publish_message": "نشر الإشعار",
|
||||
"nav_button_subscribe": "اشترك في الموضوع",
|
||||
"nav_button_connecting": "جارٍ الاتصال",
|
||||
"alert_grant_title": "تم تعطيل الإشعارات",
|
||||
"alert_grant_description": "امنح متصفحك الإذن لعرض إشعارات سطح المكتب.",
|
||||
"notifications_list": "قائمة الإشعارات",
|
||||
"notifications_list_item": "إشعار",
|
||||
"notifications_mark_read": "وضع علامة كمقروء",
|
||||
"notifications_tags": "الوسوم",
|
||||
"notifications_priority_x": "الأولوية {{priority}}",
|
||||
"notifications_new_indicator": "إشعار جديد",
|
||||
"notifications_attachment_image": "صورة مرفقة",
|
||||
"notifications_attachment_copy_url_button": "نسخ عنوان URL",
|
||||
"notifications_attachment_open_title": "انتقل إلى {{url}}",
|
||||
"notifications_attachment_link_expires": "تنتهي صلاحية الرابط {{date}}",
|
||||
"notifications_attachment_link_expired": "انتهت صلاحية رابط التنزيل",
|
||||
"notifications_attachment_file_image": "ملف الصورة",
|
||||
"notifications_attachment_file_video": "ملف فيديو",
|
||||
"notifications_attachment_file_audio": "ملف صوتي",
|
||||
"notifications_attachment_file_app": "ملف تطبيق Android",
|
||||
"notifications_attachment_file_document": "وثيقة أخرى",
|
||||
"notifications_click_copy_url_button": "نسخ الرابط",
|
||||
"notifications_click_open_button": "فتح الرابط",
|
||||
"notifications_actions_open_url_title": "انتقل إلى {{url}}",
|
||||
"notifications_actions_not_supported": "هذا الإجراء غير مدعوم في تطبيق الويب",
|
||||
"action_bar_send_test_notification": "إرسال إشعار للاختبار",
|
||||
"action_bar_show_menu": "عرض القائمة",
|
||||
"message_bar_type_message": "اكتب رسالة هنا",
|
||||
"alert_not_supported_title": "الإشعارات غير مدعومة",
|
||||
"alert_not_supported_description": "الإشعارات غير مدعومة في متصفحك.",
|
||||
"message_bar_error_publishing": "خطأ أثناء نشر الإشعار",
|
||||
"notifications_delete": "حذف",
|
||||
"notifications_copied_to_clipboard": "تم نسخه إلى الحافظة"
|
||||
}
|
||||
Reference in New Issue
Block a user