1
0
Philipp Heckel 3 жил өмнө
parent
commit
6122cf20aa

+ 7 - 0
docs/faq.md

@@ -42,3 +42,10 @@ decent now.
 [Instant delivery](subscribe/phone.md#instant-delivery) is a feature in the Android app. If turned on, the app maintains a constant connection to the
 [Instant delivery](subscribe/phone.md#instant-delivery) is a feature in the Android app. If turned on, the app maintains a constant connection to the
 server and listens for incoming notifications. This consumes additional battery (see above),
 server and listens for incoming notifications. This consumes additional battery (see above),
 but delivers notifications instantly.
 but delivers notifications instantly.
+
+## Where can I donate?
+Many people have asked (thanks for that!), but I am currently not accepting any donations. The cost is manageable 
+($25/month for hosting, and $99/year for the Apple cert) right now, and I don't want to have to feel obligated to 
+anyone by accepting their money.
+
+I may ask for donations in the future, though. After all, $400 per year isn't nothing... 

+ 9 - 9
docs/releases.md

@@ -2,6 +2,15 @@
 Binaries for all releases can be found on the GitHub releases pages for the [ntfy server](https://github.com/binwiederhier/ntfy/releases)
 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).
 and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/releases).
 
 
+<!--
+
+## ntfy Android app v1.14.0 (UNRELEASED)
+
+**Additional translations:**
+
+* Italian (thanks to [@Genio2003](https://hosted.weblate.org/user/Genio2003/))
+
+
 ## ntfy server v1.26.0 (UNRELEASED)
 ## ntfy server v1.26.0 (UNRELEASED)
 
 
 **Features:**
 **Features:**
@@ -23,15 +32,6 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
 * Update FAQ for iOS app ([#321](https://github.com/binwiederhier/ntfy/issues/321), thanks to [@milksteakjellybeans](https://github.com/milksteakjellybeans) for reporting)
 * Update FAQ for iOS app ([#321](https://github.com/binwiederhier/ntfy/issues/321), thanks to [@milksteakjellybeans](https://github.com/milksteakjellybeans) for reporting)
 
 
 
 
-<!--
-
-## ntfy Android app v1.14.0 (UNRELEASED)
-
-**Additional translations:**
-
-* Italian (thanks to [@Genio2003](https://hosted.weblate.org/user/Genio2003/))
-
-
 ## ntfy iOS app v1.2 (UNRELEASED)
 ## ntfy iOS app v1.2 (UNRELEASED)
 
 
 This release adds support for authentication/authorization for self-hosted servers. It also allows you to
 This release adds support for authentication/authorization for self-hosted servers. It also allows you to

+ 1 - 0
server/errors.go

@@ -56,6 +56,7 @@ var (
 	errHTTPUnauthorized                              = &errHTTP{40101, http.StatusUnauthorized, "unauthorized", "https://ntfy.sh/docs/publish/#authentication"}
 	errHTTPUnauthorized                              = &errHTTP{40101, http.StatusUnauthorized, "unauthorized", "https://ntfy.sh/docs/publish/#authentication"}
 	errHTTPForbidden                                 = &errHTTP{40301, http.StatusForbidden, "forbidden", "https://ntfy.sh/docs/publish/#authentication"}
 	errHTTPForbidden                                 = &errHTTP{40301, http.StatusForbidden, "forbidden", "https://ntfy.sh/docs/publish/#authentication"}
 	errHTTPEntityTooLargeAttachmentTooLarge          = &errHTTP{41301, http.StatusRequestEntityTooLarge, "attachment too large, or bandwidth limit reached", "https://ntfy.sh/docs/publish/#limitations"}
 	errHTTPEntityTooLargeAttachmentTooLarge          = &errHTTP{41301, http.StatusRequestEntityTooLarge, "attachment too large, or bandwidth limit reached", "https://ntfy.sh/docs/publish/#limitations"}
+	errHTTPEntityTooLargeMatrixRequestTooLarge       = &errHTTP{41302, http.StatusRequestEntityTooLarge, "Matrix request is larger than the max allowed length", ""}
 	errHTTPTooManyRequestsLimitRequests              = &errHTTP{42901, http.StatusTooManyRequests, "limit reached: too many requests, please be nice", "https://ntfy.sh/docs/publish/#limitations"}
 	errHTTPTooManyRequestsLimitRequests              = &errHTTP{42901, http.StatusTooManyRequests, "limit reached: too many requests, please be nice", "https://ntfy.sh/docs/publish/#limitations"}
 	errHTTPTooManyRequestsLimitEmails                = &errHTTP{42902, http.StatusTooManyRequests, "limit reached: too many emails, please be nice", "https://ntfy.sh/docs/publish/#limitations"}
 	errHTTPTooManyRequestsLimitEmails                = &errHTTP{42902, http.StatusTooManyRequests, "limit reached: too many emails, please be nice", "https://ntfy.sh/docs/publish/#limitations"}
 	errHTTPTooManyRequestsLimitSubscriptions         = &errHTTP{42903, http.StatusTooManyRequests, "limit reached: too many active subscriptions, please be nice", "https://ntfy.sh/docs/publish/#limitations"}
 	errHTTPTooManyRequestsLimitSubscriptions         = &errHTTP{42903, http.StatusTooManyRequests, "limit reached: too many active subscriptions, please be nice", "https://ntfy.sh/docs/publish/#limitations"}

+ 4 - 1
server/server_matrix.go

@@ -113,8 +113,11 @@ func newRequestFromMatrixJSON(r *http.Request, baseURL string, messageLimit int)
 		return nil, err
 		return nil, err
 	}
 	}
 	defer r.Body.Close()
 	defer r.Body.Close()
+	if body.LimitReached {
+		return nil, errHTTPEntityTooLargeMatrixRequestTooLarge
+	}
 	var m matrixRequest
 	var m matrixRequest
-	if err := json.NewDecoder(body).Decode(&m); err != nil {
+	if err := json.Unmarshal(body.PeekedBytes, &m); err != nil {
 		return nil, errHTTPBadRequestMatrixMessageInvalid
 		return nil, errHTTPBadRequestMatrixMessageInvalid
 	} else if m.Notification == nil || len(m.Notification.Devices) == 0 || m.Notification.Devices[0].PushKey == "" {
 	} else if m.Notification == nil || len(m.Notification.Devices) == 0 || m.Notification.Devices[0].PushKey == "" {
 		return nil, errHTTPBadRequestMatrixMessageInvalid
 		return nil, errHTTPBadRequestMatrixMessageInvalid

+ 63 - 0
server/server_matrix_test.go

@@ -3,6 +3,7 @@ package server
 import (
 import (
 	"github.com/stretchr/testify/require"
 	"github.com/stretchr/testify/require"
 	"net/http"
 	"net/http"
+	"net/http/httptest"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 )
 )
@@ -19,3 +20,65 @@ func TestMatrix_NewRequestFromMatrixJSON_Success(t *testing.T) {
 	require.Equal(t, "https://ntfy.sh/upABCDEFGHI?up=1", newRequest.Header.Get("X-Matrix-Pushkey"))
 	require.Equal(t, "https://ntfy.sh/upABCDEFGHI?up=1", newRequest.Header.Get("X-Matrix-Pushkey"))
 	require.Equal(t, body, readAll(t, newRequest.Body))
 	require.Equal(t, body, readAll(t, newRequest.Body))
 }
 }
+
+func TestMatrix_NewRequestFromMatrixJSON_TooLarge(t *testing.T) {
+	baseURL := "https://ntfy.sh"
+	maxLength := 10 // Small
+	body := `{"notification":{"content":{"body":"I'm floating in a most peculiar way.","msgtype":"m.text"},"counts":{"missed_calls":1,"unread":2},"devices":[{"app_id":"org.matrix.matrixConsole.ios","data":{},"pushkey":"https://ntfy.sh/upABCDEFGHI?up=1","pushkey_ts":12345678,"tweaks":{"sound":"bing"}}],"event_id":"$3957tyerfgewrf384","prio":"high","room_alias":"#exampleroom:matrix.org","room_id":"!slw48wfj34rtnrf:example.com","room_name":"Mission Control","sender":"@exampleuser:matrix.org","sender_display_name":"Major Tom","type":"m.room.message"}}`
+	r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body))
+	_, err := newRequestFromMatrixJSON(r, baseURL, maxLength)
+	require.Equal(t, errHTTPEntityTooLargeMatrixRequestTooLarge, err)
+}
+
+func TestMatrix_NewRequestFromMatrixJSON_InvalidJSON(t *testing.T) {
+	baseURL := "https://ntfy.sh"
+	maxLength := 4096
+	body := `this is not json`
+	r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body))
+	_, err := newRequestFromMatrixJSON(r, baseURL, maxLength)
+	require.Equal(t, errHTTPBadRequestMatrixMessageInvalid, err)
+}
+
+func TestMatrix_NewRequestFromMatrixJSON_NotAMatrixMessage(t *testing.T) {
+	baseURL := "https://ntfy.sh"
+	maxLength := 4096
+	body := `{"message":"this is not a matrix message, but valid json"}`
+	r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body))
+	_, err := newRequestFromMatrixJSON(r, baseURL, maxLength)
+	require.Equal(t, errHTTPBadRequestMatrixMessageInvalid, err)
+}
+
+func TestMatrix_NewRequestFromMatrixJSON_MismatchingPushKey(t *testing.T) {
+	baseURL := "https://ntfy.sh" // Mismatch!
+	maxLength := 4096
+	body := `{"notification":{"content":{"body":"I'm floating in a most peculiar way.","msgtype":"m.text"},"counts":{"missed_calls":1,"unread":2},"devices":[{"app_id":"org.matrix.matrixConsole.ios","data":{},"pushkey":"https://ntfy.example.com/upABCDEFGHI?up=1","pushkey_ts":12345678,"tweaks":{"sound":"bing"}}],"event_id":"$3957tyerfgewrf384","prio":"high","room_alias":"#exampleroom:matrix.org","room_id":"!slw48wfj34rtnrf:example.com","room_name":"Mission Control","sender":"@exampleuser:matrix.org","sender_display_name":"Major Tom","type":"m.room.message"}}`
+	r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body))
+	_, err := newRequestFromMatrixJSON(r, baseURL, maxLength)
+	matrixErr, ok := err.(*errMatrix)
+	require.True(t, ok)
+	require.Equal(t, errHTTPBadRequestMatrixPushkeyBaseURLMismatch, matrixErr.err)
+	require.Equal(t, "https://ntfy.example.com/upABCDEFGHI?up=1", matrixErr.pushKey)
+}
+
+func TestMatrix_WriteMatrixDiscoveryResponse(t *testing.T) {
+	w := httptest.NewRecorder()
+	require.Nil(t, writeMatrixDiscoveryResponse(w))
+	require.Equal(t, 200, w.Result().StatusCode)
+	require.Equal(t, `{"unifiedpush":{"gateway":"matrix"}}`+"\n", w.Body.String())
+}
+
+func TestMatrix_WriteMatrixError(t *testing.T) {
+	w := httptest.NewRecorder()
+	r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", nil)
+	v := newVisitor(newTestConfig(t), nil, "1.2.3.4")
+	require.Nil(t, writeMatrixError(w, r, v, &errMatrix{"https://ntfy.example.com/upABCDEFGHI?up=1", errHTTPBadRequestMatrixPushkeyBaseURLMismatch}))
+	require.Equal(t, 200, w.Result().StatusCode)
+	require.Equal(t, `{"rejected":["https://ntfy.example.com/upABCDEFGHI?up=1"]}`+"\n", w.Body.String())
+}
+
+func TestMatrix_WriteMatrixSuccess(t *testing.T) {
+	w := httptest.NewRecorder()
+	require.Nil(t, writeMatrixSuccess(w))
+	require.Equal(t, 200, w.Result().StatusCode)
+	require.Equal(t, `{"rejected":[]}`+"\n", w.Body.String())
+}