diff options
Diffstat (limited to 'docs/api')
| -rw-r--r-- | docs/api/SUMMARY.md | 1 | ||||
| -rw-r--r-- | docs/api/authentication.md | 4 | ||||
| -rw-r--r-- | docs/api/basics.md | 2 | ||||
| -rw-r--r-- | docs/api/push.md | 124 |
4 files changed, 131 insertions, 0 deletions
diff --git a/docs/api/SUMMARY.md b/docs/api/SUMMARY.md index f51fbc7..5974ba7 100644 --- a/docs/api/SUMMARY.md +++ b/docs/api/SUMMARY.md @@ -7,3 +7,4 @@ - [Events](events.md) - [Invitations](invitations.md) - [Conversations and messages](conversations-messages.md) +- [Push notifications](push.md) diff --git a/docs/api/authentication.md b/docs/api/authentication.md index 189103e..801f0e7 100644 --- a/docs/api/authentication.md +++ b/docs/api/authentication.md @@ -85,6 +85,8 @@ This endpoint will respond with a status of `401 Unauthorized` if the login name Invalidates the identity token used to make the request, logging the caller out. +This terminates any [push subscriptions](push.md#receiving-web-push-messages) associated with the token. + ### Request ```json @@ -103,6 +105,8 @@ The response will include a `Set-Cookie` header that clears the `identity` cooki Changes the current user's password, and invalidates all outstanding identity tokens. +This terminates any [push subscriptions](push.md#receiving-web-push-messages) associated with existing tokens. + ### Authentication failure This endpoint will respond with a status of `401 Unauthorized` if the provided identity token is not valid. diff --git a/docs/api/basics.md b/docs/api/basics.md index ab39570..180880e 100644 --- a/docs/api/basics.md +++ b/docs/api/basics.md @@ -49,3 +49,5 @@ In addition to the documented status codes for each endpoint, any endpoint may r ## Errors When the server returns an error (any response whose status code is 400 or greater), the response body is freeform text (specifically, `text/plain`), which may be shown to the user, logged, or otherwise handled. Programmatic action should rely on the documented status codes, and not on the response body. + +A small number of endpoints deliver errors in other formats. These exceptions are documented with the endpoints they're relevant to. diff --git a/docs/api/push.md b/docs/api/push.md new file mode 100644 index 0000000..363bff3 --- /dev/null +++ b/docs/api/push.md @@ -0,0 +1,124 @@ +# Push Notifications + +```mermaid +--- +Push lifecycle +--- +sequenceDiagram + actor Andrea + participant API + participant Broker + + Note over Andrea, Broker : Creating a push subscription + + Andrea ->>+ API : Client Boot + API ->>- Andrea : Boot message with VAPID keys + + Andrea ->>+ API : Subscribe to events + + Andrea ->>+ Broker : New Push Subscription + Broker ->>- Andrea : Subscription URL + + Andrea ->>+ API : Subscribe + API ->>- Andrea : Created + + API ->>- Andrea : Disconnect + + Note over Andrea, Broker : Asynchronous notification + + API ->> Broker : Push Publication + Broker ->> Andrea : Push Delivery + + Andrea ->>+ API : Resume event subscription + API ->>- Andrea : Disconnect + + Note over Andrea, Broker : VAPID key rotation + + Andrea ->>+ API : Subscribe to events + API -) Andrea : VAPID key changed + + Andrea ->>+ Broker : Unsubscribe + Broker ->>- Andrea : Unsubscribed + Andrea ->>+ Broker : New Push Subscription + Broker ->>- Andrea : Subscription URL + + Andrea ->>+ API : Subscribe + API ->>- Andrea : Created + + API ->>- Andrea : Disconnect +``` + +Pilcrow uses [Web Push] to notify clients asynchronously of interesting events, to allow clients to disconnect from [the event stream](events.md) while keeping their users informed of updates to conversations. Clients are _not required_ to implement push subscriptions. Pilcrow's primarily channel for communicating real-time communications data to clients is the [event stream](events.md). + +[Web Push]: https://developer.mozilla.org/en-US/docs/Web/API/Push_API + +## VAPID keys + +Pilcrow uses a generated Voluntary Application Server Identification (VAPID) key to authenticate to push brokers. Clients do not generally need to handle VAPID authentication themselves, but, due to the design of the Web Push protocol, clients are responsible for providing Pilcrow's VAPID key to push brokers when subscribing to notifications. To make this possible, Pilcrow delivers its VAPID key to clients via the event stream. See the [VAPID key events](events.md#vapid-key-events) section for details of these events. + +Pilcrow rotates the VAPID key periodically, and sends all clients an event when this occurs. This immediately invalidates all existing subscriptions, as the previous VAPID key is destroyed. Clients that wish to continue receiving messages must re-subscribe using the new VAPID key when this happens, and will miss any Web Push messages sent during this interval. + +## Receiving Web Push messages + +Pilcrow sends web push messages to subscriptions. A Pilcrow user may have many subscriptions - in principle, generally one per client, but Pilcrow does not enforce any such limit. Clients create subscriptions as needed, and inform the Pilcrow server of those subscriptions to begin the flow of push messages. + +The specific taxonomy and structure of push messages is still under development. This API is even more experimental than the rest of Pilcrow. + +Pilcrow keeps track of the token used to create a web push subscription, and abandons subscriptions when that token is invalidated. This prevents the server from inadvertently sending information to a client after the user for which that information is intended has logged out, or after another user has taken over the client. Clients are responsible for re-establishing subscriptions on login if they wish to resume push messaging. + +## `POST /api/push/subscribe` + +Inform the Pilcrow server of a push subscription. + +### Request + +```json +{ + "subscription": { + "endpoint": "https://example.push.com/P1234", + "keys": { + "p256dh": "base64-encoded key", + "auth": "base64-encoded authentication secret" + } + } + "vapid": "BKILjh0SzTiHOZ5P_sfduv-iqtOg_S18nR7ePcjnDivJaOY6nOG1L3OmvjXjNnthlRDdVnawl1_owfdPCvmDt5U=" +} +``` + +The request must have the following fields: + +| Field | Type | Description | +| :------------- | :----- | :------------------------------------------------------ | +| `subscription` | object | The push subscription object created by the user agent. | +| `vapid` | string | The VAPID key used to create the subscription. | + +The `subscription` field should be the result of calling `toJSON()` on a `PushSubscription` object in the DOM API. For details, see [the WebPush specification](https://w3c.github.io/push-api/#dom-pushsubscription-tojson) or [MDN](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription/toJSON). + +The `vapid` field should be set to the key used when creating the subscription, which should in turn be obtained from the event stream. + +[wp-example]: https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription#sending_coding_information_to_the_server + +This request can be retried on any non-400 response, including any network-related errors. A duplicate subscription with the same endpoint, the same public key and the same authentication secret will be accepted by the server even if the subscription has already been created. + +### Success + +This endpoint will respond with a status of `201 Created` when successful. The response body is empty. + +### Duplicate endpoint + +If the push subscription's endpoint URL is already associated with a subscription with different keys, then Pilcrow will return a `409 Conflict` response. + +### Stale VAPID key + +If the provided `vapid` key is not the server's current VAPID key, then the client has created a subscription which is not usable. This may happen if Pilcrow rotates its key while a client is negotiating with a Web Push broker to set up a subscription using the old key. Pilcrow will respond a `400 Bad Request` response. + +**This response includes a JSON body**, unlike other errors, and will have a `content-type: application/json` header. + +The response will include the following fields: + +| Field | Type | Description | +| :-------- | :----- | :------------------------------ | +| `message` | string | A human-readable error message. | +| `key` | string | Pilcrow's new VAPID key. | + +Clients should immediately destroy the push subscription they were attempting to create, and may try again using the new VAPID key (either immediately, using the key from the response, or asynchronously, using the key when it is delivered via the event stream). |
