webpush

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package webpush is the Web Push (RFC 8030 + VAPID) usernotify.Sink: it delivers a Notification to every browser PushSubscription registered by each recipient, via the browsers' push services.

Index

Constants

View Source
const SubscriptionsCollectionName = "push_subscriptions"

SubscriptionsCollectionName backs the cloud-mode SubscriptionStore.

Variables

This section is empty.

Functions

func GenerateVAPIDKeys

func GenerateVAPIDKeys() (privateKey, publicKey string, err error)

GenerateVAPIDKeys mints a fresh VAPID keypair (private, public) for the `iterion server webpush-keys` helper.

Types

type MemSubscriptionStore

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

MemSubscriptionStore is the in-memory SubscriptionStore for tests and local mode.

func NewMemSubscriptionStore

func NewMemSubscriptionStore() *MemSubscriptionStore

func (*MemSubscriptionStore) DeleteByEndpoint

func (m *MemSubscriptionStore) DeleteByEndpoint(_ context.Context, userID, endpoint string) error

func (*MemSubscriptionStore) ListForUsers

func (m *MemSubscriptionStore) ListForUsers(_ context.Context, userIDs []string) ([]*Subscription, error)

func (*MemSubscriptionStore) Prune

func (m *MemSubscriptionStore) Prune(_ context.Context, endpoint string) error

func (*MemSubscriptionStore) Touch

func (m *MemSubscriptionStore) Touch(_ context.Context, endpoint string, at time.Time) error

func (*MemSubscriptionStore) Upsert

type MongoSubscriptionStore

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

MongoSubscriptionStore is the cloud-mode SubscriptionStore.

func NewMongoSubscriptionStore

func NewMongoSubscriptionStore(db *mongo.Database) *MongoSubscriptionStore

func (*MongoSubscriptionStore) DeleteByEndpoint

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

func (*MongoSubscriptionStore) EnsureSchema

func (s *MongoSubscriptionStore) EnsureSchema(ctx context.Context) error

func (*MongoSubscriptionStore) ListForUsers

func (s *MongoSubscriptionStore) ListForUsers(ctx context.Context, userIDs []string) ([]*Subscription, error)

func (*MongoSubscriptionStore) Prune

func (s *MongoSubscriptionStore) Prune(ctx context.Context, endpoint string) error

func (*MongoSubscriptionStore) Touch

func (s *MongoSubscriptionStore) Touch(ctx context.Context, endpoint string, at time.Time) error

func (*MongoSubscriptionStore) Upsert

type Sink

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

Sink implements usernotify.Sink over Web Push.

func NewSink

func NewSink(store SubscriptionStore, opts SinkOptions, logger *iterlog.Logger) *Sink

func (*Sink) Deliver

func (s *Sink) Deliver(ctx context.Context, n usernotify.Notification) error

Deliver pushes n to every registered browser of every recipient — one subscription query, then bounded-parallel HTTP sends (each is a blocking call to an external push service; serialized they can outlast the deliver budget). A push endpoint the service reports dead (404/410 Gone) is pruned. Deliver only errors when nothing could be delivered despite at least one live subscription — a recipient with no subscriptions is not a failure.

func (*Sink) Name

func (s *Sink) Name() string

type SinkOptions

type SinkOptions struct {
	VAPIDPublicKey  string
	VAPIDPrivateKey string
	// Subscriber is the VAPID contact (mailto: or https: URL) push services
	// may use to reach the operator.
	Subscriber string
	// HTTPClient overrides the client used to reach push services (tests).
	HTTPClient *http.Client
}

SinkOptions configures the web-push sink. The VAPID keypair must be shared by every server replica (it is the sender identity browsers pin at subscribe time).

type Subscription

type Subscription struct {
	ID         string    `json:"id" bson:"_id"`
	TenantID   string    `json:"tenant_id" bson:"tenant_id"`
	UserID     string    `json:"user_id" bson:"user_id"`
	Endpoint   string    `json:"endpoint" bson:"endpoint"`
	P256dh     string    `json:"p256dh" bson:"p256dh"`
	Auth       string    `json:"auth" bson:"auth"`
	UserAgent  string    `json:"user_agent,omitempty" bson:"user_agent,omitempty"`
	CreatedAt  time.Time `json:"created_at" bson:"created_at"`
	LastUsedAt time.Time `json:"last_used_at,omitempty" bson:"last_used_at,omitempty"`
}

Subscription is one browser push registration (one user × one browser profile × one device). The endpoint is the push service's capability URL and is globally unique. A subscription belongs to the USER, not a team: TenantID records where it was enrolled (provenance) but delivery must not filter on it — a multi-team user enrolls once and receives notifications for runs of every team that resolves them as a recipient (recipient resolution is already tenant-scoped upstream).

type SubscriptionStore

type SubscriptionStore interface {
	// Upsert registers (or refreshes) a subscription, keyed on its endpoint.
	Upsert(ctx context.Context, s *Subscription) error
	// ListForUsers returns every subscription of the given users in one
	// query (a notification fans out to all recipients at once). Not
	// tenant-filtered — see the Subscription doc.
	ListForUsers(ctx context.Context, userIDs []string) ([]*Subscription, error)
	// DeleteByEndpoint removes the caller's own subscription (unsubscribe).
	DeleteByEndpoint(ctx context.Context, userID, endpoint string) error
	// Prune removes a subscription the push service reported dead (404/410).
	Prune(ctx context.Context, endpoint string) error
	// Touch refreshes last_used_at after a successful delivery. Best-effort.
	Touch(ctx context.Context, endpoint string, at time.Time) error
}

SubscriptionStore persists browser push registrations.

Jump to

Keyboard shortcuts

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