Philipp Heckel 3 лет назад
Родитель
Сommit
6122cf20aa
5 измененных файлов с 84 добавлено и 10 удалено
  1. 7 0
      docs/faq.md
  2. 9 9
      docs/releases.md
  3. 1 0
      server/errors.go
  4. 4 1
      server/server_matrix.go
  5. 63 0
      server/server_matrix_test.go

+ 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
 server and listens for incoming notifications. This consumes additional battery (see above),
 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)
 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)
 
 **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)
 
 
-<!--
-
-## 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)
 
 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"}
 	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"}
+	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"}
 	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"}

+ 4 - 1
server/server_matrix.go

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

+ 63 - 0
server/server_matrix_test.go

@@ -3,6 +3,7 @@ package server
 import (
 	"github.com/stretchr/testify/require"
 	"net/http"
+	"net/http/httptest"
 	"strings"
 	"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, 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())
+}