mirror of
https://github.com/binwiederhier/ntfy.git
synced 2025-06-12 23:53:19 +02:00
Simplify web push UX and updates
- Use a single endpoint - Use a declarative web push sync hook. This thus handles all edge cases that had to be manually handled before: logout, login, account sync, etc. - Simplify UX: browser notifications are always enabled (unless denied), web push toggle only shows up if permissions are already granted.
This commit is contained in:
parent
4944e3ae4b
commit
47ad024ec7
20 changed files with 294 additions and 427 deletions
server
|
@ -3,40 +3,36 @@ package server
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/SherClockHolmes/webpush-go"
|
||||
"heckel.io/ntfy/log"
|
||||
"net/http"
|
||||
"heckel.io/ntfy/user"
|
||||
)
|
||||
|
||||
func (s *Server) handleTopicWebPushSubscribe(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||
sub, err := readJSONWithLimit[webPushSubscribePayload](r.Body, jsonBodyBytesLimit, false)
|
||||
if err != nil || sub.BrowserSubscription.Endpoint == "" || sub.BrowserSubscription.Keys.P256dh == "" || sub.BrowserSubscription.Keys.Auth == "" {
|
||||
func (s *Server) handleWebPushUpdate(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||
payload, err := readJSONWithLimit[webPushSubscriptionPayload](r.Body, jsonBodyBytesLimit, false)
|
||||
if err != nil || payload.BrowserSubscription.Endpoint == "" || payload.BrowserSubscription.Keys.P256dh == "" || payload.BrowserSubscription.Keys.Auth == "" {
|
||||
return errHTTPBadRequestWebPushSubscriptionInvalid
|
||||
}
|
||||
|
||||
topic, err := fromContext[*topic](r, contextTopic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = s.webPush.AddSubscription(topic.ID, v.MaybeUserID(), *sub); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.writeJSON(w, newSuccessResponse())
|
||||
}
|
||||
u := v.User()
|
||||
|
||||
func (s *Server) handleTopicWebPushUnsubscribe(w http.ResponseWriter, r *http.Request, _ *visitor) error {
|
||||
payload, err := readJSONWithLimit[webPushUnsubscribePayload](r.Body, jsonBodyBytesLimit, false)
|
||||
if err != nil {
|
||||
return errHTTPBadRequestWebPushSubscriptionInvalid
|
||||
}
|
||||
|
||||
topic, err := fromContext[*topic](r, contextTopic)
|
||||
topics, err := s.topicsFromIDs(payload.Topics...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.webPush.RemoveSubscription(topic.ID, payload.Endpoint)
|
||||
if err != nil {
|
||||
if s.userManager != nil {
|
||||
for _, t := range topics {
|
||||
if err := s.userManager.Authorize(u, t.ID, user.PermissionRead); err != nil {
|
||||
logvr(v, r).With(t).Err(err).Debug("Access to topic %s not authorized", t.ID)
|
||||
return errHTTPForbidden.With(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.webPush.UpdateSubscriptions(payload.Topics, v.MaybeUserID(), payload.BrowserSubscription); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue