Push Notifications
Overview
Cloudillo implements Web Push notifications using the VAPID (Voluntary Application Server Identification) protocol. Push notifications are sent when users receive actions while offline or not connected via WebSocket.
Web Push Standards
The implementation follows these RFCs:
| RFC | Title | Purpose |
|---|---|---|
| RFC 8292 | VAPID for Web Push | Server identification |
| RFC 8188 | Encrypted Content-Encoding for HTTP | Payload encryption |
| RFC 8291 | Message Encryption for Web Push | End-to-end encryption |
VAPID Keys
Each tenant has a VAPID key pair for authenticating with push services. The private key is stored in the database; the public key is shared with clients. Keys are automatically generated on first request if they don’t exist.
Subscription Flow
sequenceDiagram
participant C as Client
participant SW as Service Worker
participant S as Cloudillo Server
participant PS as Push Service
C->>S: GET /api/auth/vapid
S-->>C: {vapidPublicKey: "BM5..."}
C->>SW: pushManager.subscribe({userVisibleOnly: true, applicationServerKey})
SW->>PS: Subscribe request
PS-->>SW: PushSubscription
SW-->>C: PushSubscription
C->>S: POST /api/notifications/subscription {subscription}
S-->>C: {id: 12345}
Push Delivery
When an action is received for an offline user:
sequenceDiagram
participant A as Action Sender
participant S as Cloudillo Server
participant PS as Push Service
participant B as User's Browser
A->>S: POST /api/inbox {action}
S->>S: Process action
S->>S: Check if recipient is online
alt User is online (WebSocket connected)
S->>B: WebSocket message
else User is offline
S->>S: Load push subscriptions
S->>S: Encrypt payload with user's public key
S->>PS: POST {encrypted payload}
PS->>B: Push notification
B->>B: Display notification
end
Notification Types
Users can configure which notification types they receive:
| Setting | Default | Description |
|---|---|---|
notify.push.message |
true | New direct messages |
notify.push.mention |
true | Mentioned in content |
notify.push.reaction |
false | Reactions to your content |
notify.push.connection |
true | Connection requests |
notify.push.follow |
true | New followers |
Settings are stored per-user and checked before sending notifications.
Encryption
Push notification payloads are encrypted end-to-end using the client’s P-256 key pair and a shared secret. The push service cannot read the encrypted data.
| Parameter | Description |
|---|---|
p256dh |
Client’s P-256 public key |
auth |
16-byte authentication secret |
content-encoding |
aes128gcm |
Payload Structure
{
"type": "action",
"actionType": "MSG",
"issuer": "alice@example.com",
"preview": "New message from Alice",
"actionId": "a1~xyz789..."
}| Field | Description |
|---|---|
type |
Notification type (action, system) |
actionType |
Action token type (MSG, CONN, FLLW) |
issuer |
Action issuer identity |
preview |
Short preview text |
actionId |
Action ID for deep linking |
Subscription Management
Users can have multiple push subscriptions (one per device/browser). Each subscription has a unique ID, and all active subscriptions receive notifications.
Push subscriptions can expire when the browser reports expiration, the push service responds with HTTP 410 Gone, or the user manually unsubscribes. Expired subscriptions are removed automatically.
Error Handling
| Push Service Response | Action |
|---|---|
| 201 Created | Success |
| 400 Bad Request | Log error, don’t retry |
| 410 Gone | Remove subscription |
| 429 Too Many Requests | Retry with backoff |
| 5xx Server Error | Retry with backoff |
See Also
- Push Notifications API - REST API endpoints
- Settings API - Notification preferences
- WebSocket API - Real-time notifications