webpush

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: AGPL-3.0 Imports: 26 Imported by: 0

Documentation

Overview

Package webpush sends reminders as Web Push notifications to the browsers and installed apps (PWA) where a member turned them on (ADR 0026).

Each device is one destination: a channel link whose external id is the push endpoint, next to the browser's keys. Messages are encrypted for the browser (RFC 8291) and signed with the instance's VAPID key (RFC 8292), both written on the standard library.

A notification can carry up to two action buttons taken from the message's own buttons (actions.PushButtons). Each carries a signed token for that device, charge and verb, so the service worker can run it with no tab open and no session.

Index

Constants

View Source
const ActionTTL = 72 * time.Hour

ActionTTL is how long a notification's buttons keep working. After that the service worker opens the charge in the web instead.

View Source
const MaxPlaintext = recordSize - headerLen - 16 - 1

MaxPlaintext is the longest message that still fits in one record: the record holds the plaintext, the padding delimiter and the 16-octet tag, and push services limit the body (header included) to 4096 octets.

View Source
const Name = "webpush"

Name is the channel name in channel_links.

View Source
const TTL = 72 * time.Hour

TTL is how long a push service keeps a message for a device that is offline.

Variables

View Source
var ErrBadToken = errors.New("this button has expired")

ErrBadToken means the token is not one of ours, or has expired.

View Source
var ErrNoDevice = errors.New("no such device")

ErrNoDevice is returned by a Lookup that does not know the endpoint.

View Source
var ErrTooLarge = errors.New("push message too large")

ErrTooLarge is returned for a message longer than MaxPlaintext.

Functions

func Audience

func Audience(endpoint string) (string, error)

Audience is the origin of a push endpoint, the aud claim.

func Encrypt

func Encrypt(plaintext []byte, keys Keys) ([]byte, error)

Encrypt encrypts plaintext for a browser with a fresh key pair and salt.

func SignAction

func SignAction(key []byte, a Action) string

SignAction returns a token for a, signed with key.

Types

type Action

type Action struct {
	LinkID   string // the device (channel_links.id) the notification went to
	MemberID string
	ChargeID string
	Verb     string // button verb of the action layer, e.g. "paid"
	Expires  time.Time
}

Action is what a token allows.

func VerifyAction

func VerifyAction(key []byte, token string, now time.Time) (Action, error)

VerifyAction checks a token and returns what it allows.

type ActionButton

type ActionButton struct {
	Action string `json:"action"`
	Title  string `json:"title"`
	Token  string `json:"token"`
}

ActionButton is a button of a notification.

type Channel

type Channel struct {
	notify.OneWay
	// Lookup returns the device of an endpoint.
	Lookup func(ctx context.Context, endpoint string) (Device, error)
	// Gone forgets a device the push service says no longer exists.
	Gone func(ctx context.Context, endpoint string)
	// Keys returns the instance's VAPID key pair and the key that signs
	// action tokens.
	Keys func(ctx context.Context) (VAPID, []byte, error)
	// Subject is the contact in the VAPID claims (mailto: or https:).
	Subject string
	// Client must come from a netguard.Guard: endpoints are sent by
	// browsers, so anyone signed in can choose one.
	Client *http.Client
	// Now defaults to time.Now.
	Now func() time.Time
}

Channel is the Web Push channel. Its chat id is the push endpoint.

func (*Channel) Name

func (c *Channel) Name() string

func (*Channel) Push

func (c *Channel) Push(ctx context.Context, endpoint string, keys Keys, vapid VAPID, p Payload, urgency string) error

Push delivers one payload to an endpoint.

func (*Channel) Send

func (c *Channel) Send(ctx context.Context, endpoint string, m actions.Message) (string, error)

Send encrypts the message for the device and posts it to its push service. A device the push service no longer knows (404, 410) is removed and reported as actions.ErrGone, which is not retried.

type Device

type Device struct {
	LinkID   string
	MemberID string
	Keys     Keys
}

Device is one browser subscription.

type Keys

type Keys struct {
	P256dh []byte // uncompressed P-256 point, 65 octets
	Auth   []byte // authentication secret, 16 octets
}

Keys are a browser's keys from its PushSubscription.

type Payload

type Payload struct {
	Title   string         `json:"title"`
	Body    string         `json:"body,omitempty"`
	Tag     string         `json:"tag,omitempty"`
	URL     string         `json:"url"`
	Actions []ActionButton `json:"actions,omitempty"`
}

Payload is what the service worker receives (web/public/sw.js).

func BuildPayload

func BuildPayload(m actions.Message, dev Device, key []byte, now time.Time) Payload

BuildPayload turns a message into the notification for one device.

type VAPID

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

VAPID is the instance's key pair. Generate it once and keep it: changing it invalidates every browser subscription.

func GenerateVAPID

func GenerateVAPID() (VAPID, error)

GenerateVAPID makes a new key pair.

func ParseVAPID

func ParseVAPID(private string) (VAPID, error)

ParseVAPID reads a private key saved with PrivateKey.

func (VAPID) Header

func (v VAPID) Header(endpoint, subject string, now time.Time) (string, error)

Header returns the Authorization header for a request to endpoint: `vapid t=<JWT>, k=<public key>`. subject is a mailto: or https: contact for the push service's operators.

func (VAPID) PrivateKey

func (v VAPID) PrivateKey() string

PrivateKey is the private scalar, base64url, for saving.

func (VAPID) PublicKey

func (v VAPID) PublicKey() string

PublicKey is the uncompressed public point, base64url: the applicationServerKey browsers subscribe with, and the k= of the header.

Directories

Path Synopsis
Package pushtest is a fake Web Push service and a fake browser for tests.
Package pushtest is a fake Web Push service and a fake browser for tests.

Jump to

Keyboard shortcuts

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