push

package
v1.19.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package push implements VAPID-encrypted Web Push delivery for v1.16 phase 4. The daemon generates a single VAPID keypair at first boot (persisted in app_kv), users opt in per device via the PushManager.subscribe() browser API, and the daemon fans critical-finding alerts out as encrypted push payloads.

No third-party push provider — Firebase / OneSignal would push payloads through their servers and need long-lived API keys. VAPID is the IETF-standard alternative: keys live in the daemon, pushes go directly to the browser push services (FCM, Mozilla, Apple). Honors the no-phone-home invariant (ADR-013 spirit).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Payload

type Payload struct {
	Title    string `json:"title"`
	Body     string `json:"body"`
	URL      string `json:"url,omitempty"`
	Severity string `json:"severity,omitempty"`
	Tag      string `json:"tag,omitempty"` // browser dedupe key
}

Payload is the message envelope delivered to the client's service worker push handler. The browser's notification UI renders Title + Body; URL routes the user when they click the notification.

type Sender

type Sender struct {
	// contains filtered or unexported fields
}

Sender owns the HTTP client + VAPID keys used to push to every subscriber. Reused across calls — webpush-go's send is per-request so the sender itself stays cheap to construct.

func NewSender

func NewSender(ctx context.Context, st *Store, contactEmail string) (*Sender, error)

NewSender returns a Sender that signs every push with the daemon's VAPID keys. contactEmail goes into the JWT `sub` claim browsers use to identify the sender to push services. Empty email falls back to the deploy-time admin email or a placeholder.

func (*Sender) PublicKey

func (s *Sender) PublicKey() string

PublicKey returns the VAPID public key in URL-safe base64. The browser needs this to call PushManager.subscribe(applicationServerKey).

func (*Sender) SendToUser

func (s *Sender) SendToUser(ctx context.Context, userID string, p Payload) (sent, failed int, err error)

SendToUser dispatches the payload to every subscription belonging to userID. Returns (sent, failed) counts; failed deliveries are logged but don't abort the loop. A 404/410 response from the push service means the subscription is stale and gets deleted.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store wraps the SQLite/Postgres push tables.

func NewStore

func NewStore(st *store.Store) *Store

func (*Store) DeleteByEndpoint

func (s *Store) DeleteByEndpoint(ctx context.Context, userID, endpoint string) (int64, error)

DeleteByEndpoint removes a subscription matching the user + endpoint. Returns the number of rows deleted (0 if the user didn't have a subscription with that endpoint).

func (*Store) EnsureVAPID

func (s *Store) EnsureVAPID(ctx context.Context) (publicKey, privateKey string, err error)

EnsureVAPID returns the daemon's VAPID keypair, generating + saving it on first call. Subsequent calls return the persisted pair. Returning the keys (rather than caching in memory) keeps the implementation stateless across daemon restarts + HA replicas.

func (*Store) ListForUser

func (s *Store) ListForUser(ctx context.Context, userID string) ([]Subscription, error)

ListForUser returns every subscription the user has registered, most-recent first. Used by the /settings/notifications UI to render the per-device list.

func (*Store) Save

func (s *Store) Save(ctx context.Context, sub Subscription) (Subscription, error)

Save upserts a Subscription by (user_id, endpoint). Idempotent; a refresh-token / reinstall returns the same id.

type Subscription

type Subscription struct {
	ID         string
	UserID     string
	Endpoint   string
	P256dhKey  string
	AuthKey    string
	DeviceLbl  string
	CreatedAt  time.Time
	LastUsedAt time.Time
}

Subscription is the server-side record of a single browser/ device push registration. Mirrors the wire shape browsers send when ServiceWorkerRegistration.pushManager.subscribe() returns.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL