mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(site): add webpush notification serviceworker (#17123)
* Improves tests for webpush notifications
* Sets subscriber correctly in web push payload (without this,
notifications do not work in Safari)
* NOTE: for now, I'm using the Coder Access URL. Some push messaging
service don't like it when you use a non-HTTPS URL, so dropping a warn
log about this.
* Adds a service worker and context for push notifications
* Adds a button beside "Inbox" to enable / disable push notifications
Notes:
* ✅ Tested in in Firefox and Safari, and Chrome.
This commit is contained in:
@@ -41,13 +41,14 @@ type Dispatcher interface {
|
||||
// for updates inside of a workspace, which we want to be immediate.
|
||||
//
|
||||
// See: https://github.com/coder/internal/issues/528
|
||||
func New(ctx context.Context, log *slog.Logger, db database.Store) (Dispatcher, error) {
|
||||
func New(ctx context.Context, log *slog.Logger, db database.Store, vapidSub string) (Dispatcher, error) {
|
||||
keys, err := db.GetWebpushVAPIDKeys(ctx)
|
||||
if err != nil {
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, xerrors.Errorf("get notification vapid keys: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if keys.VapidPublicKey == "" || keys.VapidPrivateKey == "" {
|
||||
// Generate new VAPID keys. This also deletes all existing push
|
||||
// subscriptions as part of the transaction, as they are no longer
|
||||
@@ -62,6 +63,7 @@ func New(ctx context.Context, log *slog.Logger, db database.Store) (Dispatcher,
|
||||
}
|
||||
|
||||
return &Webpusher{
|
||||
vapidSub: vapidSub,
|
||||
store: db,
|
||||
log: log,
|
||||
VAPIDPublicKey: keys.VapidPublicKey,
|
||||
@@ -72,7 +74,13 @@ func New(ctx context.Context, log *slog.Logger, db database.Store) (Dispatcher,
|
||||
type Webpusher struct {
|
||||
store database.Store
|
||||
log *slog.Logger
|
||||
// VAPID allows us to identify the sender of the message.
|
||||
// This must be a https:// URL or an email address.
|
||||
// Some push services (such as Apple's) require this to be set.
|
||||
vapidSub string
|
||||
|
||||
// public and private keys for VAPID. These are used to sign and encrypt
|
||||
// the message payload.
|
||||
VAPIDPublicKey string
|
||||
VAPIDPrivateKey string
|
||||
}
|
||||
@@ -148,10 +156,12 @@ func (n *Webpusher) webpushSend(ctx context.Context, msg []byte, endpoint string
|
||||
Endpoint: endpoint,
|
||||
Keys: keys,
|
||||
}, &webpush.Options{
|
||||
Subscriber: n.vapidSub,
|
||||
VAPIDPublicKey: n.VAPIDPublicKey,
|
||||
VAPIDPrivateKey: n.VAPIDPrivateKey,
|
||||
})
|
||||
if err != nil {
|
||||
n.log.Error(ctx, "failed to send webpush notification", slog.Error(err), slog.F("endpoint", endpoint))
|
||||
return -1, nil, xerrors.Errorf("send webpush notification: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
Reference in New Issue
Block a user