Merge branch 'main' into vrate

pull/637/head
binwiederhier 2023-02-23 14:03:11 -05:00
commit ede957973b
4 changed files with 63 additions and 3 deletions

View File

@ -572,4 +572,27 @@ Example `template.html`:
Add notification on Rundeck (attachment type must be: `Attached as file to email`):
![Rundeck](static/img/rundeck.png)
## Traccar
This will only work on selfhosted [traccar](https://www.traccar.org/) ([Github](https://github.com/traccar/traccar)) instances, as you need to be able to set `sms.http.*` keys, which is not possible through the UI attributes
The easiest way to integrate traccar with ntfy, is to configure ntfy as the SMS provider for your instance. You then can set your ntfy topic as your account's phone number in traccar. Sending the email notifications to ntfy will not work, as ntfy does not support HTML emails.
**Caution:** JSON publishing is only possible, when POST-ing to the root URL of the ntfy instance. (see [documentation](publish.md#publish-as-json))
```xml
<entry key='sms.http.url'>https://ntfy.sh</entry>
<entry key='sms.http.template'>
{
"topic": "{phone}",
"message": "{message}"
}
</entry>
```
If [access control](config.md#access-control) is enabled, and the target topic does not support anonymous writes, you'll also have to provide an authorization header, for example in form of a privileged token
```xml
<entry key='sms.http.authorization'>Bearer tk_JhbsnoMrgy2FcfHeofv97Pi5uXaZZ</entry>
```
or by simply providing traccar with a valid username/password combination.
```xml
<entry key='sms.http.user'>phil</entry>
<entry key='sms.http.password'>mypass</entry>
```

View File

@ -2,7 +2,11 @@
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.2 (UNRELEASED)
## ntfy server v2.1.0 (UNRELEASED)
This release now supports sending emails to protected topics, and it ships code to support annual billing cycles (not live yet).
Most importantly, it fixes an issue with UnifiedPush (mostly Mastodon servers) that send an `Authorization` header, which ntfy
rejects with an HTTP 401.
**Features:**
@ -13,6 +17,11 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
**Bug fixes + maintenance:**
* Web: Do not disable "Reserve topic" checkbox for admins (no ticket, thanks to @xenrox for reporting)
* UnifiedPush: Treat non-Basic/Bearer `Authorization` header like header was not sent ([#629](https://github.com/binwiederhier/ntfy/issues/629), thanks to [@Boebbele](https://github.com/Boebbele) and [@S1m](https://github.com/S1m) for reporting)
**Documentation:**
* Added example for [Traccar](https://ntfy.sh/docs/examples/#traccar) ([#631](https://github.com/binwiederhier/ntfy/pull/631), thanks to [tamcore](https://github.com/tamcore))
**Additional languages:**

View File

@ -1528,7 +1528,8 @@ func (s *Server) autorizeTopic(next handleFunc, perm user.Permission) handleFunc
// maybeAuthenticate reads the "Authorization" header and will try to authenticate the user
// if it is set.
//
// - If the header is not set, an IP-based visitor is returned
// - If the header is not set or not supported (anything non-Basic and non-Bearer),
// an IP-based visitor is returned
// - If the header is set, authenticate will be called to check the username/password (Basic auth),
// or the token (Bearer auth), and read the user from the database
//
@ -1541,7 +1542,7 @@ func (s *Server) maybeAuthenticate(r *http.Request) (*visitor, error) {
header, err := readAuthHeader(r)
if err != nil {
return vip, err
} else if header == "" {
} else if !supportedAuthHeader(header) {
return vip, nil
} else if s.userManager == nil {
return vip, errHTTPUnauthorized
@ -1586,6 +1587,14 @@ func readAuthHeader(r *http.Request) (string, error) {
return value, nil
}
// supportedAuthHeader returns true only if the Authorization header value starts
// with "Basic" or "Bearer". In particular, an empty value is not supported, and neither
// are things like "WebPush", or "vapid" (see #629).
func supportedAuthHeader(value string) bool {
value = strings.ToLower(value)
return strings.HasPrefix(value, "basic ") || strings.HasPrefix(value, "bearer ")
}
func (s *Server) authenticateBasicAuth(r *http.Request, value string) (user *user.User, err error) {
r.Header.Set("Authorization", value)
username, password, ok := r.BasicAuth()

View File

@ -796,6 +796,25 @@ func TestServer_Auth_ViaQuery(t *testing.T) {
require.Equal(t, 401, response.Code)
}
func TestServer_Auth_NonBasicHeader(t *testing.T) {
s := newTestServer(t, newTestConfigWithAuthFile(t))
response := request(t, s, "PUT", "/mytopic", "test", map[string]string{
"Authorization": "WebPush not-supported",
})
require.Equal(t, 200, response.Code)
response = request(t, s, "PUT", "/mytopic", "test", map[string]string{
"Authorization": "Bearer supported",
})
require.Equal(t, 401, response.Code)
response = request(t, s, "PUT", "/mytopic", "test", map[string]string{
"Authorization": "basic supported",
})
require.Equal(t, 401, response.Code)
}
func TestServer_StatsResetter(t *testing.T) {
// This tests the stats resetter for
// - an anonymous user