Skip to content

Commit 0c4e54b

Browse files
committed
fix(webpush): set vapid sub in webpush payload
1 parent 58430ae commit 0c4e54b

File tree

4 files changed

+20
-6
lines changed

4 files changed

+20
-6
lines changed

cli/server.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,10 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
779779
// Manage push notifications.
780780
experiments := coderd.ReadExperiments(options.Logger, options.DeploymentValues.Experiments.Value())
781781
if experiments.Enabled(codersdk.ExperimentWebPush) {
782-
webpusher, err := webpush.New(ctx, &options.Logger, options.Database)
782+
if !strings.HasPrefix(options.AccessURL.String(), "https://") {
783+
options.Logger.Warn(ctx, "access URL is not HTTPS, so web push notifications may not work on some browsers", slog.F("access_url", options.AccessURL.String()))
784+
}
785+
webpusher, err := webpush.New(ctx, options.Logger.Named("webpush"), options.Database, options.AccessURL.String())
783786
if err != nil {
784787
options.Logger.Error(ctx, "failed to create web push dispatcher", slog.Error(err))
785788
options.Logger.Warn(ctx, "web push notifications will not work until the VAPID keys are regenerated")

coderd/coderdtest/coderdtest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
284284

285285
if options.WebpushDispatcher == nil {
286286
// nolint:gocritic // Gets/sets VAPID keys.
287-
pushNotifier, err := webpush.New(dbauthz.AsNotifier(context.Background()), options.Logger, options.Database)
287+
pushNotifier, err := webpush.New(dbauthz.AsNotifier(context.Background()), *options.Logger, options.Database, options.AccessURL.String())
288288
if err != nil {
289289
panic(xerrors.Errorf("failed to create web push notifier: %w", err))
290290
}

coderd/webpush/webpush.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ type Dispatcher interface {
4141
// for updates inside of a workspace, which we want to be immediate.
4242
//
4343
// See: https://github.com/coder/internal/issues/528
44-
func New(ctx context.Context, log *slog.Logger, db database.Store) (Dispatcher, error) {
44+
func New(ctx context.Context, log slog.Logger, db database.Store, vapidSub string) (Dispatcher, error) {
4545
keys, err := db.GetWebpushVAPIDKeys(ctx)
4646
if err != nil {
4747
if !errors.Is(err, sql.ErrNoRows) {
4848
return nil, xerrors.Errorf("get notification vapid keys: %w", err)
4949
}
5050
}
51+
5152
if keys.VapidPublicKey == "" || keys.VapidPrivateKey == "" {
5253
// Generate new VAPID keys. This also deletes all existing push
5354
// 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,
6263
}
6364

6465
return &Webpusher{
66+
vapidSub: vapidSub,
6567
store: db,
6668
log: log,
6769
VAPIDPublicKey: keys.VapidPublicKey,
@@ -71,8 +73,14 @@ func New(ctx context.Context, log *slog.Logger, db database.Store) (Dispatcher,
7173

7274
type Webpusher struct {
7375
store database.Store
74-
log *slog.Logger
75-
76+
log slog.Logger
77+
// VAPID allows us to identify the sender of the message.
78+
// This must be a https:// URL or an email address.
79+
// Some push services (such as Apple's) require this to be set.
80+
vapidSub string
81+
82+
// public and private keys for VAPID. These are used to sign and encrypt
83+
// the message payload.
7684
VAPIDPublicKey string
7785
VAPIDPrivateKey string
7886
}
@@ -148,10 +156,13 @@ func (n *Webpusher) webpushSend(ctx context.Context, msg []byte, endpoint string
148156
Endpoint: endpoint,
149157
Keys: keys,
150158
}, &webpush.Options{
159+
Subscriber: n.vapidSub,
151160
VAPIDPublicKey: n.VAPIDPublicKey,
152161
VAPIDPrivateKey: n.VAPIDPrivateKey,
153162
})
154163
if err != nil {
164+
n.log.Error(ctx, "failed to send webpush notification", slog.Error(err), slog.F("endpoint", endpoint))
165+
n.log.Debug(ctx, "webpush notification payload", slog.F("payload", string(cpy)))
155166
return -1, nil, xerrors.Errorf("send webpush notification: %w", err)
156167
}
157168
defer resp.Body.Close()

coderd/webpush/webpush_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func setupPushTest(ctx context.Context, t *testing.T, handlerFunc func(w http.Re
253253
server := httptest.NewServer(http.HandlerFunc(handlerFunc))
254254
t.Cleanup(server.Close)
255255

256-
manager, err := webpush.New(ctx, &logger, db)
256+
manager, err := webpush.New(ctx, logger, db, "http://example.com")
257257
require.NoError(t, err, "Failed to create webpush manager")
258258

259259
return manager, db, server.URL

0 commit comments

Comments
 (0)