diff options
author | Joas Schilling <coding@schilljs.com> | 2017-04-24 16:07:34 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-24 16:07:34 +0300 |
commit | af90c155980a4b51ce16c3ffadc48dced85ca115 (patch) | |
tree | 0421bc0fd0df3dfaddb4078d1a9439732a0d6a35 /docs | |
parent | 6982181dc3583ef8843fd1fa8ddfc35a03978358 (diff) | |
parent | edbb99192eba9fe8d4630214b7aff1d35a3066a0 (diff) |
Merge pull request #59 from nextcloud/push-notification
Allow devices to register for push notifications
Diffstat (limited to 'docs')
-rw-r--r-- | docs/push-v2.md | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/docs/push-v2.md b/docs/push-v2.md new file mode 100644 index 0000000..84aed3e --- /dev/null +++ b/docs/push-v2.md @@ -0,0 +1,213 @@ +# Push notifications as a Nextcloud client device + + + +## Checking the capabilities of the Nextcloud server + +In order to find out if notifications support push on the server you can run a request against the capabilities endpoint: `/ocs/v2.php/cloud/capabilities` + +``` +{ + "ocs": { + ... + "data": { + ... + "capabilities": { + ... + "notifications": { + "push": [ + ... + "devices" + ] + } + } + } + } +} +``` + + + +## Subscribing at the Nextcloud server + +1. **Only on first registration on the server** The device generates a `rsa2048` key pair (`devicePrivateKey` and `devicePublicKey`). + +2. The device generates the `PushToken` for *Apple Push Notification Service* (iOS) or *Firebase Cloud Messaging* (Android) + +3. The device generates a `sha512` hash of the `PushToken` (`PushTokenHash`) + +4. The device then sends the `devicePublicKey`, `PushTokenHash` and `proxyServerUrl` to the Nextcloud server: + + ``` + POST /ocs/v2.php/apps/notifications/api/v2/push + + { + "pushTokenHash": "{{PushTokenHash}}", + "devicePublicKey": "{{devicePublicKey}}", + "proxyServer": "{{proxyServerUrl}}" + } + ``` + + + +### Response + +The server replies with the following status codes: + +| Status code | Meaning | +| ----------- | ---------------------------------------- | +| 200 | No further action by the device required | +| 201 | Push token was created/updated and **needs to be sent to the `Proxy`** | +| 400 | Invalid device public key; device does not use a token to authenticate; the push token hash is invalid formatted; the proxy server URL is invalid; | +| 401 | Device is not logged in | + + + +#### Body in case of success + +In case of `200` and `201` the reply has more information in the body: + +| Key | Type | | +| ---------------- | ------------ | ---------------------------------------- | +| publicKey | string (512) | rsa2048 public key of the user account on the instance | +| deviceIdentifier | string (128) | unique identifier encrypted with the users private key | +| signature | string (512) | base64 encoded signature of the deviceIdentifier | + + + +#### Body in case of an error + +In case of `400` the following `message` can appear in the body: + +| Error | Description | +| ------------------------ | ---------------------------------------- | +| `INVALID_PUSHTOKEN_HASH` | The hash of the push token was not a valid `sha512` hash. | +| `INVALID_SESSION_TOKEN` | The authentication token of the request could not be identified. Check whether a password was used to login. | +| `INVALID_DEVICE_KEY` | The device key does not match the one registered to the provided session token. | +| `INVALID_PROXY_SERVER` | The proxy server was not a valid https URL. | + + + +## Unsubcribing at the Nextcloud server + +When an account is removed from a device, the device should unregister on the server. Otherwise the server sends unnecessary push notifications and might be blocked because of spam. + + + +The device should then send a `DELETE` request to the Nextcloud server: + +``` +DELETE /ocs/v2.php/apps/notifications/api/v2/push +``` + + + +### Response + +The server replies with the following status codes: + +| Status code | Meaning | +| ----------- | ---------------------------------------- | +| 200 | Push token was not registered on the server | +| 202 | Push token was deleted and **needs to be deleted from the `Proxy`** | +| 400 | Device does not use a token to authenticate | +| 401 | Device is not logged in | + + + +#### Body in case of an error + +In case of `400` the following `message` can appear in the body: + +| Error | Description | +| ----------------------- | ---------------------------------------- | +| `INVALID_SESSION_TOKEN` | The authentication token of the request could not be identified. | + + + +## Subscribing at the Push Proxy + +The device sends the`PushToken` as well as the `deviceIdentifier`, `signature` and the user´s `publicKey` (from the server´s response) to the Push Proxy: + +``` +POST /devices + +{ + "pushToken": "{{PushToken}}", + "deviceIdentifier": "{{deviceIdentifier}}", + "deviceIdentifierSignature": "{{signature}}", + "userPublicKey": "{{userPublicKey}}" +} +``` + + + +### Response + +The server replies with the following status codes: + +| Status code | Meaning | +| ----------- | ---------------------------------------- | +| 200 | Push token was written to the databse | +| 400 | Push token, public key or device identifier is malformed, the signature does not match | +| 403 | Device is not allowed to write the push token of the device identifier | +| 409 | In case of a conflict the device can retry with the additional field `cloudId` with the value `{{userid}}@{{serverurl}}` which allows the proxy to verify the public key and device identifier belongs to the given user on the instance | + + + +## Unsubscribing at the Push Proxy + +The device sends the `deviceIdentifier`, `deviceIdentifierSignature` and the user´s `publicKey` (from the server´s response) to the Push Proxy: + +``` +DELETE /devices + +{ + "deviceIdentifier": "{{deviceIdentifier}}", + "deviceIdentifierSignature": "{{signature}}", + "userPublicKey": "{{userPublicKey}}" +} +``` + + + +### Response + +The server replies with the following status codes: + +| Status code | Meaning | +| ----------- | ---------------------------------------- | +| 200 | Push token was deleted from the database | +| 400 | Public key or device identifier is malformed | +| 403 | Device identifier and device public key didn't match or could not be found | + + + +## Pushed notifications + +The pushed notifications is defined by the [Firebase Cloud Messaging HTTP Protocol](https://firebase.google.com/docs/cloud-messaging/http-server-ref#send-downstream). The sample content of a Nextcloud push notification looks like the following: + +```json +{ + "to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...", + "notification" : { + "body" : "NEW_NOTIFICATION", + "body_loc_key" : "NEW_NOTIFICATION", + "title" : "NEW_NOTIFICATION", + "title_loc_key" : "NEW_NOTIFICATION" + }, + "data" : { + "subject" : "*Encrypted subject*", + "signature" : "*Signature*" + } +} +``` + +| Attribute | Meaning | +| ----------- | ---------------------------------------- | +| `subject` | The subject is encrypted with the device´s *public key*. | +| `signature` | The signature is a sha512 signature over the encrypted subject using the user´s private key. | + +### Verification +So a device should verify the signature using the user´s public key. +If the signature is okay, the subject can be decrypted using the device´s private key. |