feat(notify): web push as a notification channel
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m15s

- VAPID keys from VAPID_* or generated once (push_keys, migration 9);
  devices in push_subscriptions, forgotten on 404/410 from the push service
- push column for every event (also due tasks) and the daily summary,
  bundles as one notification; /push/key, /devices, /subscribe,
  /unsubscribe, /test
- settings: switch push on per device, test it, see the devices; the
  service worker shows notifications and focuses MindSift on click
- tests decrypt a sent push like a browser (RFC 8291) and check VAPID

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-30 21:21:55 +01:00
1 parent 1a49e6b304
commit 38b8c92899
27 files changed
+918 -27

No files matched your search

+3 -1
View File
@@ -158,10 +158,11 @@ type ChannelChoice struct {
Email bool `json:"email"`
Discord bool `json:"discord"`
Webhook bool `json:"webhook"` // own webhook (customWebhookUrl), JSON payload
Push bool `json:"push"` // web push to the user's browsers and phones
}
// Any reports whether at least one channel is chosen.
func (c ChannelChoice) Any() bool { return c.Email || c.Discord || c.Webhook }
func (c ChannelChoice) Any() bool { return c.Email || c.Discord || c.Webhook || c.Push }
type DailySummary struct {
Enabled bool `json:"enabled"`
@@ -169,6 +170,7 @@ type DailySummary struct {
Email bool `json:"email"`
Discord bool `json:"discord"`
Webhook bool `json:"webhook"`
Push bool `json:"push"`
}
// DefaultNotificationSettings for users who never saved any; task alarms follow the old alarm channels.