Feat/push notifications#211
Merged
jeroenrinzema merged 29 commits intomainfrom Apr 11, 2026
Merged
Conversation
… in GettingStarted component
…he error it was causing in GettingStarted.tsx was bothering me
…ting device retrieval methods
- Created a new Web Push provider with full implementation in `main.go`. - Added configuration schema for VAPID keys in the provider manifest. - Implemented sending notifications to web browsers using the Web Push Protocol. - Included a Makefile for building the WASM module. - Added Quick Start guide and detailed README documentation for usage and testing. - Updated payload structures to support Web Push targets. - Introduced error handling for various HTTP response codes from push services.
fix(store): update VapidKeysStore to select specific columns feat(devices): implement Scan and Value methods for DeviceCredentials; add UpsertDevice method feat(migrations): create unique index for active devices fix(wasm): update provider.wasm binary feat(webpush): enhance Web Push provider to support FCM; add necessary configuration fields and logic
…ions - Moved provider manifest and related types to a new `types` package for better organization. - Updated the `Manifest` function to use the new types. - Refactored the `Send` function to utilize the new `SendRequest` and `SendResponse` types. - Enhanced Web Push notification handling with manual VAPID JWT generation and AES-128-GCM encryption. - Improved error handling and logging throughout the code. - Removed unused imports and redundant code for clarity and maintainability.
… up notification headers
…ptional push subscription
…M, APNs, and Web Push
- Removed the device registration endpoint from the management API. - Added a new device registration endpoint to the client API. - Implemented the RegisterDevice function in the client controller. - Updated OpenAPI specifications for the new device registration endpoint. - Removed deprecated device registration models and methods from the management API. - Added new methods in the UsersStore for fetching users by anonymous ID. - Updated the WASM provider binary.
|
All contributors have signed the CLA ✍️ ✅ |
42311e2 to
685abd7
Compare
API Unifies push registration and VAPID retrieval under the client API, removes legacy management device handlers, and tightens device validation by enforcing OS-to-push config consistency. Updates related store queries/migrations to rely on push_config and active-device semantics, with matching docs/console cleanup.
# Conflicts: # internal/pubsub/consumer/campaigns.go # internal/store/management/store.go # internal/store/subjects/devices.go # internal/wasm/test/provider.wasm
- Rename `devices` table to `user_devices` and `push_config` column to `config` - Add `data` JSONB column for custom device metadata - Update code and migrations to use new schema - Remove duplicated provider types, use shared pkg/modules/providers - Update provider modules to use shared types and Go 1.25 - Update API and OAPI to reflect new device config structure
There was a problem hiding this comment.
Pull request overview
This PR introduces multi-platform push notification support (FCM, APNs, Web Push) with per-project default push-provider mappings, adds device registration/management APIs, and updates the console and data model to support the new push workflow.
Changes:
- Expanded push payloads and provider manifests to support iOS/Android/Web targets and platform metadata.
- Reworked device persistence from legacy
devices.tokentouser_devices.config(JSONB) +data, including migrations and new device endpoints. - Added project-level push provider defaults (per platform), VAPID key storage/bootstrap, and corresponding management + console UI.
Reviewed changes
Copilot reviewed 104 out of 111 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/modules/providers/payload.go | Adds APNs/webpush fields to push payloads and defines WebPushTarget. |
| pkg/modules/providers/manifest.go | Adds provider spec Platforms for push provider capability metadata. |
| pkg/modules/providers/channel.go | Introduces Platform enum (ios/android/web) with validation. |
| pkg/modules/manifest.go | Extends JSONSchema with FileUpload, FileAccept, Hidden. |
| modules/providers/webpush/Makefile | Adds TinyGo WASM build for webpush provider. |
| modules/providers/webpush/go.mod | New Go module definition for webpush provider. |
| modules/providers/webpush/go.sum | Dependencies for webpush provider module. |
| modules/providers/fcm/Makefile | Adds TinyGo WASM build for fcm provider. |
| modules/providers/fcm/go.mod | New Go module definition for fcm provider. |
| modules/providers/fcm/go.sum | Dependencies for fcm provider module. |
| modules/providers/apns/Makefile | Adds TinyGo WASM build for apns provider. |
| modules/providers/apns/go.mod | New Go module definition for apns provider. |
| modules/providers/apns/go.sum | Dependencies for apns provider module. |
| modules/providers/logger/main.go | Advertises supported push platforms in logger provider manifest. |
| internal/wasm/test/provider/main.go | Updates test WASM provider manifest to include platforms. |
| internal/wasm/module.go | Enables WASI wall time for Extism plugins via wazero module config. |
| internal/store/subjects/users.go | Updates has_push_device checks to use user_devices.config and adds anonymous-id lookup. |
| internal/store/subjects/users_test.go | Updates device fixtures to use new PushConfig JSON config structure. |
| internal/store/subjects/organizations.go | Updates has_push_device checks to use user_devices. |
| internal/store/subjects/lists.go | Updates has_push_device checks to use user_devices. |
| internal/store/subjects/devices.go | Adds push config types, device/public device models, and new device CRUD queries on user_devices. |
| internal/store/subjects/migrations/1784300000_user_devices_config_data.up.sql | Renames devices→user_devices, push_config→config, adds data JSONB. |
| internal/store/subjects/migrations/1784300000_user_devices_config_data.down.sql | Reverts user_devices rename and drops data. |
| internal/store/subjects/migrations/1784200000_push_config.up.sql | Migrates legacy tokens to JSONB push_config, adjusts unique indexes, drops old columns. |
| internal/store/subjects/migrations/1784200000_push_config.down.sql | Restores legacy token/device_credentials and drops push_config. |
| internal/store/subjects/migrations/1784106036_device_unique_index.up.sql | Updates unique index for active device rows to account for soft delete. |
| internal/store/subjects/migrations/1784106036_device_unique_index.down.sql | Reverts device unique index change. |
| internal/store/subjects/migrations/1772900001_devices_schema_device_credentials.up.sql | Adds legacy device_credentials JSONB column (compat migration). |
| internal/store/subjects/migrations/1772900001_devices_schema_device_credentials.down.sql | Drops legacy device_credentials JSONB column. |
| internal/store/management/vapid_key.go | Adds VAPID key storage and generation in management store. |
| internal/store/management/store.go | Wires ProjectPushProvidersStore + VapidKeysStore into management state. |
| internal/store/management/providers.go | Adds provider listing by channel helper. |
| internal/store/management/project_push_providers.go | Adds store/model for per-project per-platform default push providers. |
| internal/store/management/project_push_providers_test.go | Adds tests for project push provider upsert/get/list/delete behavior. |
| internal/store/management/migrations/1764116035_vapid_keys_schema.up.sql | Creates vapid_keys table and unique active-name index. |
| internal/store/management/migrations/1764116035_vapid_keys_schema.down.sql | Drops vapid_keys table and index. |
| internal/store/management/migrations/1764106044_drop_campaign_provider_id.up.sql | Removes campaigns.provider_id (provider derived elsewhere now). |
| internal/store/management/migrations/1764106044_drop_campaign_provider_id.down.sql | Re-adds campaigns.provider_id. |
| internal/store/management/migrations/1764106043_project_push_providers.up.sql | Creates project_push_providers mapping table + trigger. |
| internal/store/management/migrations/1764106043_project_push_providers.down.sql | Drops project_push_providers. |
| internal/store/management/campaigns.go | Removes campaign-provider coupling; provider is resolved during send. |
| internal/rbac/model.go | Adds RBAC resources for push_providers and devices. |
| internal/pubsub/schemas/events.go | Removes embedded rate limit from SendCampaign/broadcast batch events. |
| internal/pubsub/consumer/campaigns.go | Resolves provider at send-time, adds project push provider routing and device loading. |
| internal/pubsub/consumer/broadcasts_enterprise.go | Removes rate-limit propagation in broadcast batch chain. |
| internal/providers/channels/push.go | Composes push payload with FCM/APNs/WebPush targets from device configs. |
| internal/journeys/campaign.go | Removes pre-resolved rate limiting; defers to send-time provider resolution. |
| internal/http/controllers/v1/management/users.go | Adds admin endpoint to upsert a user device with new config schema. |
| internal/http/controllers/v1/management/users_test.go | Adds tests for create-device, user-not-found, token conflict, and token non-exposure. |
| internal/http/controllers/v1/management/templates.go | Updates test-send flow: push provider resolution via device + project push providers; sender identity resolution for email/sms. |
| internal/http/controllers/v1/management/templates_test.go | Updates controller construction for templates (adds subjects DB). |
| internal/http/controllers/v1/management/push_providers.go | Adds management endpoints to list/upsert/delete project push providers. |
| internal/http/controllers/v1/management/providers.go | Adds VAPID injection for webpush configs, rate limit validation helper, auto-assign default push provider by supported platforms. |
| internal/http/controllers/v1/management/oapi/resources.yml | Adds push provider endpoints, create-user-device endpoint, and updates schemas (removes campaign provider_id, updates device schema). |
| internal/http/controllers/v1/management/controller.go | Wires PushProvidersController; updates templates controller constructor args. |
| internal/http/controllers/v1/management/campaigns.go | Removes provider_id handling from create/update/duplicate campaign endpoints. |
| internal/http/controllers/v1/management/broadcasts_enterprise.go | Removes “campaign must have provider” validation (provider derived later). |
| internal/http/controllers/v1/client/users.go | Adds client endpoints for identify/delete user. |
| internal/http/controllers/v1/client/subscriptions.go | Refactors to embed shared ClientController and simplify constructor. |
| internal/http/controllers/v1/client/subscriptions_test.go | Updates test setup to use new client controller wiring. |
| internal/http/controllers/v1/client/scheduled.go | Adds client endpoints for user/org scheduled operations. |
| internal/http/controllers/v1/client/organizations.go | Adds client endpoints for upsert/delete orgs and org membership ops. |
| internal/http/controllers/v1/client/oapi/resources.yml | Adds device registration endpoint and VAPID public key endpoint to client OAPI. |
| internal/http/controllers/v1/client/events.go | Adds client endpoints for posting user/org events. |
| internal/http/controllers/v1/client/devices.go | Adds device registration handler and VAPID public key retrieval handler. |
| internal/http/controllers/v1/client/controller.go | Refactors client controller composition; wires new client controllers. |
| internal/http/controllers/v1/client/client_test.go | Updates client controller tests to use new composed controller. |
| internal/http/console/dist/index.html | Updates built console HTML output (doctype/meta/assets/icon tags). |
| internal/cluster/leader/leader.go | Bootstraps VAPID keys on leader start. |
| cmd/lunogram/main.go | Passes management store + logger into leader handler for VAPID bootstrap. |
| go.mod | Adds webpush-go, moves cors/x/net to direct deps. |
| docs/content/docs/api/client.mdx | Updates device registration endpoint path in docs. |
| console/src/views/users/rules/WrapperRuleEdit.tsx | Updates select trigger to support “flat” elevation styling. |
| console/src/views/users/rules/OrganizationRuleEdit.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/users/rules/OrganizationEventRuleEdit.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/users/rules/MemberConditionsBuilder.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/users/rules/MemberConditionEdit.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/users/rules/JourneyRuleEdit.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/users/rules/FilterRuleEdit.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/users/rules/EventRuleEdit.tsx | Updates select trigger styling and elevation usage. |
| console/src/views/settings/Settings.tsx | Adds “Push” settings nav item. |
| console/src/views/settings/PushProviders.tsx | Adds UI to assign default push provider per platform. |
| console/src/views/router.tsx | Adds push providers route; removes campaign setup route. |
| console/src/views/campaign/template/text/Setup.tsx | Removes provider default-from fallback behavior; updates sender identity selection flow. |
| console/src/views/campaign/template/Review.tsx | Removes provider display and broadcast “requires provider” gating. |
| console/src/views/campaign/template/push/useSendTestPush.ts | Adds hook to save template then send a test push using device_id targeting. |
| console/src/views/campaign/template/push/Setup.tsx | Adds device selection and “send test” button for push templates. |
| console/src/views/campaign/template/mail/Setup.tsx | Removes provider default-from fallback behavior; updates sender identity selection flow. |
| console/src/views/campaign/setup/Setup.tsx | Removes campaign provider-setup screen (deleted). |
| console/src/views/campaign/Provider.tsx | Removes placeholder campaign provider screen (deleted). |
| console/src/views/campaign/CreateCampaign.tsx | Auto-creates a default template and navigates directly to template editor. |
| console/src/views/campaign/CampaignDetails.tsx | Removes provider selection UI and broadcast gating by provider. |
| console/src/views/broadcast/BroadcastMessagePreview.tsx | Removes dependency on provider default-from in email preview. |
| console/src/types.ts | Updates types for device data and removes campaign provider fields. |
| console/src/oapi/management.generated.ts | Regenerates management client types for new endpoints/schemas. |
| console/src/components/ui/select.tsx | Adds elevation prop (default/flat) to SelectTrigger and adjusts styling. |
| console/src/components/ui/multi-select.tsx | Adds elevation prop and adjusts styling. |
| console/src/components/ui/attribute-editor.tsx | Uses flat elevation selects to match updated styling. |
| console/src/components/sender-identity-combobox.tsx | Removes provider filter; adds provider selection when creating sender identities. |
| console/src/components/schema-fields.tsx | Adds file upload support for schema-driven config fields (base64). |
| console/public/sw.js | Adds a service worker for handling web push notifications. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d484dd2 to
1d3a423
Compare
Switch provider exports to TinyGo reactor mode and remove the temporary wasmcrypto shim, relying on standard library crypto paths again.
- Move node and leader resource cleanup to a dedicated method - Ensure cleanup runs on context close - Improve error and context cancellation handling in cluster watch and heartbeat routines - Add timeout handling and logging for resource release
jeroenrinzema
previously approved these changes
Apr 11, 2026
# Conflicts: # console/src/views/campaign/CampaignDetails.tsx # console/src/views/campaign/setup/Setup.tsx # console/src/views/users/rules/OrganizationEventRuleEdit.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.