7.8 KiB
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",
"object-data"
]
}
}
}
}
}
Subscribing at the Nextcloud server
-
Only on first registration on the server The device generates a
rsa2048
key pair (devicePrivateKey
anddevicePublicKey
). -
The device generates the
PushToken
for Apple Push Notification Service (iOS) or Firebase Cloud Messaging (Android) -
The device generates a
sha512
hash of thePushToken
(PushTokenHash
) -
The device then sends the
devicePublicKey
,PushTokenHash
andproxyServerUrl
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 thePushToken
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. The sample content of a Nextcloud push notification looks like the following:
{
"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. |
Encrypted subject data
If you are missing any information necessary to parse the notification in a more usable way, use the nid
to get the full notification information via OCS API
{
"app" : "spreed",
"subject" : "Test mentioned you in a private conversation",
"type" : "chat",
"id" : "t0k3n",
"nid" : 1337
}
}
Attribute | Meaning | Capability |
---|---|---|
app |
The nextcloud app sending the notification | - |
subject |
The subject of the actual notification | - |
type |
Type of the object this notification is about | object-data |
id |
Identifier of the object this notification is about | object-data |
nid |
Numeric identifier of the notification in order to get more information via the OCS API | object-data |
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.