diff --git a/files/en-us/web/api/pushmanager/supportedcontentencodings_static/index.md b/files/en-us/web/api/pushmanager/supportedcontentencodings_static/index.md index 54682ee6596fe0b..d9e7acaa86be818 100644 --- a/files/en-us/web/api/pushmanager/supportedcontentencodings_static/index.md +++ b/files/en-us/web/api/pushmanager/supportedcontentencodings_static/index.md @@ -10,20 +10,60 @@ browser-compat: api.PushManager.supportedContentEncodings_static The **`supportedContentEncodings`** read-only static property of the {{domxref("PushManager")}} interface returns an array of supported content codings that can be used to encrypt the payload of a push message. - - User agents must support the `aes128gcm` content coding defined in {{rfc("8291")}}, and may also support content codings defined from previous versions of the specification. +The returned array is frozen, and may not be modified by the recipient. + +The application server requires this coding in order to encrypt push messages for sending to the push server. +The coding used for encryption is also included by the app server in the {{httpheader("Content-Encoding")}} HTTP header field of each push message. -Note that the returned array is frozen, and may not be modified by the recipient. +The specification does not define how the client code should send the application server the supported codings, or the information in the {{domxref("PushSubscription")}} that it also needs in order to encrypt and send a push message. +One approach is shown in the examples section below. ## Value An array of strings. +This usually contains just one value: `"aes128gcm"`. ## Exceptions - `TypeError` - - This is thrown when attempting to set a value in the returned array. + - : This is thrown when attempting to set a value in the returned array. + +## Examples + +### Sending coding information to the server + +Push messages are encrypted on the application server for sending to the push server, and decrypted by the browser before being passed to the application service worker. +The public and private keys used are generated by the browser, and only the public key and an associated secret are shared with the web app, and hence the application server. +This ensures that push messages remain private as they pass through the push server infrastructure. + +The [`p256dh`](/en-US/docs/Web/API/PushSubscription/getKey#p256dh) public key and [`auth`](/en-US/docs/Web/API/PushSubscription/getKey#auth) secret used for encrypting the message are provided to the service worker via its push subscription, using the {{domxref("PushSubscription.getKey()")}} method, along with the target endpoint for sending push messages in {{domxref("PushSubscription.endpoint")}}. +The coding that should be used for encryption is provided by `supportedContentEncodings`. + +This information may be sent to the application server using any mechanism. +One approach is to put the needed information from {{domxref("PushSubscription")}} and `supportedContentEncodings` into a JSON object, serialize it using [`JSON.stringify()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) and post the result to the application server. + +```js +// Get a PushSubscription object +const pushSubscription = await serviceWorkerRegistration.pushManager.subscribe(); + +// Create an object containing the information needed by the app server +const subscriptionObject = { + endpoint: pushSubscription.endpoint, + keys: { + p256dh: pushSubscription.getKeys('p256dh'), + auth: pushSubscription.getKeys('auth'), + }, + encoding: PushManager.supportedContentEncodings, + /* other app-specific data, such as user identity */ +}; + +// Stringify the object an post to the app server +fetch(`https://example.com/push/`, { + method: "post", + body: JSON.stringify(pushSubscription); +}); +``` ## Specifications diff --git a/files/en-us/web/api/pushsubscription/index.md b/files/en-us/web/api/pushsubscription/index.md index ddd64ed5fdf7c3d..7c1a2e486b64c94 100644 --- a/files/en-us/web/api/pushsubscription/index.md +++ b/files/en-us/web/api/pushsubscription/index.md @@ -7,9 +7,10 @@ browser-compat: api.PushSubscription {{ApiRef("Push API")}}{{SecureContext_Header}}{{AvailableInWorkers}} -The `PushSubscription` interface of the [Push API](/en-US/docs/Web/API/Push_API) provides a subscription's URL endpoint and allows unsubscribing from a push service. +The `PushSubscription` interface of the [Push API](/en-US/docs/Web/API/Push_API) provides a subscription's URL endpoint along with the public key and secrets that should be used for encrypting push messages to this subscription. +This information must be passed to the application server, using any desired application-specific method. -An instance of this interface can be serialized. +The interface also provides information about when the subscription will expire, and a method to unsubscribe from the subscription. ## Instance properties @@ -31,8 +32,51 @@ An instance of this interface can be serialized. - {{domxref("PushSubscription.unsubscribe()")}} - : Starts the asynchronous process of unsubscribing from the push service, returning a {{jsxref("Promise")}} that resolves to a boolean value when the current subscription is successfully unregistered. +## Description + +Each browser uses a particular push service. +A service worker can use {{domxref("PushManager.subscribe()")}} to subscribe to the supported service, and use the returned `PushSubscription` to discover the endpoint where push messages should be sent. + +The `PushSubscription` is also used to get the public key and secret that the application server must use to encrypt the messages that it sends to the push service. +Note that the private keys used to decrypt push messages are not shared by the browser, and are used to decrypt messages before they are passed to the service worker. +This ensures that push messages remain private as they pass through the push server infrastructure. + +The service worker doesn't need to know anything about the endpoints or encryption, other than to pass the relevant information onto the application server. +Any mechanism may be used to share the information with the application server. + ## Example +### Sending coding information to the server + +The [`p256dh`](/en-US/docs/Web/API/PushSubscription/getKey#p256dh) public key and [`auth`](/en-US/docs/Web/API/PushSubscription/getKey#auth) secret used for encrypting the message are provided to the service worker via its push subscription, using the {{domxref("PushSubscription.getKey()")}} method, along with the target endpoint for sending push messages in {{domxref("PushSubscription.endpoint")}}. +The coding that should be used for encryption is provided by the {{domxref("PushManager.supportedContentEncodings")}} static property. + +This example shows how you might put the needed information from `PushSubscription` and `supportedContentEncodings` into a JSON object, serialize it using [`JSON.stringify()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify), and post the result to the application server. + +```js +// Get a PushSubscription object +const pushSubscription = await serviceWorkerRegistration.pushManager.subscribe(); + +// Create an object containing the information needed by the app server +const subscriptionObject = { + endpoint: pushSubscription.endpoint, + keys: { + p256dh: pushSubscription.getKeys('p256dh'), + auth: pushSubscription.getKeys('auth'), + }, + encoding: PushManager.supportedContentEncodings, + /* other app-specific data, such as user identity */ +}; + +// Stringify the object an post to the app server +fetch(`https://example.com/push/`, { + method: "post", + body: JSON.stringify(pushSubscription); +}); +``` + +### Unsubscribing from a push manager + ```js navigator.serviceWorker.ready.then((reg) => { reg.pushManager.getSubscription().then((subscription) => {