[Firebase](https://firebase.google.com/) for Android.
For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications.
Apple iOS devices restrict notifications to a few internal functions that every application can not use.
Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example,
it will not schedule any time if the application was closed with force quit.
Requesting execution time is not responsive enough to implement a push notification system.
Status provides a set of methods to acheive push notification services.
Since this can not be safely implemented in a privacy-preserving manner, clients need to be given an option to opt-in to receive and send push notifications.
They are disabled by default.
## Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in[2119](https://www.ietf.org/rfc/rfc2119.txt).
### Definitions
| Terminology | Description |
| --------------- | --------- |
| client | A node that implements the Status specifications. |
| user | The owner of a device that runs a client. |
| server | A service that performs push notifications. |
| Waku-Store | A Waku node that decides to provide functionality to store messages permanently and deliver the messages to requesting clients. As described in [13/WAKU-STORE](../../waku/standards/core/13/store.md) specification.|
### Server Components
| Components | Description |
| --------------- | --------- |
| gorush Instance | Only used by push notification servers and MUST be publicly available.|
| Push Notification Server | Used by clients to register for receiving and sending notifications. |
| Registering Client | A client that wants to receive push notifications. |
| Sending Client | A client that wants to send push notifications. |
### Requirements:
The party releasing the app MUST possess a certificate for the Apple Push Notification service and it MUST run a
[gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification.
The party releasing the app MUST run its own [gorush](https://github.com/appleboy/gorush).
Registering a client with a push notification service.
- A client MAY register with one or more push notification services in order to increase availability.
- A client SHOULD make sure that all the notification services they registered with have the same information about their tokens.
- A`PNR message`(Push Notification Registration) MUST be sent to the
[partitioned topic](../../waku/standards/application/54/x3dh-sessions.md)for the public key of the node, encrypted with this key.
- The message MUST be wrapped in a[`ApplicationMetadataMessage`](../62/payloads.md)with type set to`PUSH_NOTIFICATION_REGISTRATION`.
- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity.
This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
The content of the message MUST contain the following[protobuf record](https://developers.google.com/protocol-buffers/):
```protobuf
message PushNotificationRegistration {
enum TokenType {
UNKNOWN_TOKEN_TYPE = 0;
APN_TOKEN = 1;
FIREBASE_TOKEN = 2;
}
TokenType token_type = 1;
string device_token = 2;
string installation_id = 3;
string access_token = 4;
bool enabled = 5;
uint64 version = 6;
repeated bytes allowed_key_list = 7;
repeated bytes blocked_chat_list = 8;
bool unregister = 9;
bytes grant = 10;
bool allow_from_contacts_only = 11;
string apn_topic = 12;
bool block_mentions = 13;
repeated bytes allowed_mentions_chat_list = 14;
}
```
A push notification server will handle the message according to the following rules:
- it MUST extract the public key of the sender from the signature and verify that the payload can be decrypted successfully.
- it MUST verify that`token_type`is supported.
- it MUST verify that`device_token`is non empty.
- it MUST verify that`installation_id`is non empty.
- it MUST verify that`version`is non-zero and greater than the currently stored version for the public key and `installation_id` of the sender, if any.
- it MUST verify that`grant`is non empty and according to the Grant Serverspecs.
- it MUST verify that`access_token`is a validuuid.
- it MUST verify that`apn_topic`is set iftoken_typeisAPN_TOKEN.
- The message MUST be wrapped in a[`ApplicationMetadataMessage`](../62/payloads.md)with type set to`PUSH_NOTIFICATION_REGISTRATION_RESPONSE`.
The payload of the response is:
```protobuf
message PushNotificationRegistrationResponse {
bool success = 1;
ErrorType error = 2;
bytes request_id = 3;
enum ErrorType {
UNKNOWN_ERROR_TYPE = 0;
MALFORMED_MESSAGE = 1;
VERSION_MISMATCH = 2;
UNSUPPORTED_TOKEN_TYPE = 3;
INTERNAL_ERROR = 4;
}
}
```
A client SHOULD listen for a response sent on the [partitioned topic](../../waku/standards/application/54/x3dh-sessions.md) that the key used to register.
Ifsuccessistruethe client has registered successfully.
If`success`is`false`:
\> If`MALFORMED_MESSAGE`is returned, the request SHOULD NOT be retried without ensuring that it is correctly formed.
\> If`INTERNAL_ERROR`is returned, the request MAY be retried, but the client MUST backoff exponentially.
#### Handle Errors:
- If the message can’t be decrypted, the message MUST be discarded.
- If`token_type`is not supported, a response MUST be sent with`error`set to`UNSUPPORTED_TOKEN_TYPE`.
- If`token`, `installation_id`, `device_tokens`, `version`are empty, a response MUST be sent with`error`set to`MALFORMED_MESSAGE`.
- If the`version`is equal or less than the currently stored `version`, a response MUST be sent with`error`set to`VERSION_MISMATCH`.
- If any other error occurs the`error`SHOULD be set to`INTERNAL_ERROR`.
- If the response is successful`success`MUST be set to`true`otherwise a response MUST be sent with`success`set to`false`.
-`request_id`SHOULD be set to the[`SHAKE-256`](https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf)of the encrypted payload.
- The response MUST be sent on the [partitioned topic](../../waku/standards/application/54/x3dh-sessions.md) of the sender and
MUST not be encrypted using thesecure transportto facilitate the usage of ephemeral keys.
- If no response is returned, the request SHOULD be considered failed and
MAY be retried with the same server or a different one, but clients
MUST exponentially backoff after each trial.
## Push Notification Server
A node that handles receiving and sending push notifications for clients.
### Query Topic:
On successful registration the server MUST be listening to the topic derived from:
- The message MUST be wrapped in a[`ApplicationMetadataMessage`](../62/payloads.md)with type set to`PUSH_NOTIFICATION_QUERY_INFO`.
- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement.
Otherwise it SHOULD be left empty.
- This SHOULD be advertised on the[contact code topic](../../waku/standards/application/53/x3dh.md)and
SHOULD be coupled with normal contact-code advertisement.
- When a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
- Multiple servers MAY be advertised for the sameinstallation_idfor redundancy reasons.
#### Discovering a Server:
To discover a push notification service for a given user, their
[contact code topic](../../waku/standards/application/53/x3dh.md)SHOULD be listened to.
A Waku-Store node can be queried for the specific topic to retrieve the most up-to-date contact code.
#### Querying a Server:
If a token is not present in the latest advertisement for a user, the server SHOULD be queried directly.
To query a server a message:
```protobuf
message PushNotificationQuery {
repeated bytes public_keys = 1;
}
```
#### Handle Query Message:
- The message MUST be wrapped in a[`ApplicationMetadataMessage`](../62/payloads.md)with type set to`PUSH_NOTIFICATION_QUERY`.
- it MUST be sent to the server on the topic derived from the hashed public key of the key we are querying,
[asdescribed above](#query-topic).
- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the[secure transport](../../waku/standards/application/53/x3dh.md).
If the server has information about the client a response MUST be sent:
```protobuf
message PushNotificationQueryInfo {
string access_token = 1;
string installation_id = 2;
bytes public_key = 3;
repeated bytes allowed_user_list = 4;
bytes grant = 5;
uint64 version = 6;
bytes server_public_key = 7;
}
message PushNotificationQueryResponse {
repeated PushNotificationQueryInfo info = 1;
bytes message_id = 2;
bool success = 3;
}
```
#### Handle Query Response:
- A`PushNotificationQueryResponse`message MUST be wrapped in a
[`ApplicationMetadataMessage`](../62/payloads.md)with type set to`PUSH_NOTIFICATION_QUERY_RESPONSE`.
Otherwise a response MUST NOT be sent.
- If`allowed_key_list`is not set`access_token`MUST be set and`allowed_key_list`MUST NOT be set.
- If`allowed_key_list`is set`allowed_key_list`MUST be set and`access_token`MUST NOT be set.
- If`access_token`is returned, the`access_token`SHOULD be used to send push notifications.
- If`allowed_key_list`are returned, the client SHOULD decrypt each token by generating an`AES-GCM`symmetric key from the Diffie–Hellman between the target client and itself.
If AES decryption succeeds it will return a valid`uuid`which is what is used for access_token.
The token SHOULD be used to send push notifications.
- The response MUST be sent on the [partitioned topic](../../waku/standards/application/54/x3dh-sessions.md) of the sender and
MUST NOT be encrypted using the[secure transport](../../waku/standards/application/53/x3dh.md)to facilitate the usage of ephemeral keys.
- On receiving a response a client MUST verify`grant`to ensure that the server has been authorized to send push notification to a given client.
### Sending Client
Sending a push notification
- When sending a push notification, only the`installation_id`for the devices targeted by the message SHOULD be used.
- If a message is for all the user devices, all the`installation_id`known to the client MAY be used.
- The number of devices MAY be capped in order to reduce resource consumption.
- At least 3 devices SHOULD be targeted, ordered by last activity.
- For any device that a token is available, or that
a token is successfully queried,
a push notification message SHOULD be sent to the corresponding push notification server.
```protobuf
message PushNotification {
string access_token = 1;
string chat_id = 2;
bytes public_key = 3;
string installation_id = 4;
bytes message = 5;
PushNotificationType type = 6;
enum PushNotificationType {
UNKNOWN_PUSH_NOTIFICATION_TYPE = 0;
MESSAGE = 1;
MENTION = 2;
}
bytes author = 7;
}
message PushNotificationRequest {
repeated PushNotification requests = 1;
bytes message_id = 2;
}
```
#### Handle Notification Request:
- A`PushNotificationRequest`message MUST be wrapped in a
[`ApplicationMetadataMessage`](../62/payloads.md)with type set to`PUSH_NOTIFICATION_REQUEST`.
- Where`message`is the encrypted payload of the message and`chat_id`is the`SHAKE-256`of the`chat_id`.
`message_id`is the id of the message`author`is the`SHAKE-256`of the public key of the sender.
- If multiple server are available for a given push notification, only one notification MUST be sent.
- If no response is received a client SHOULD wait at least 3 seconds,
after which the request MAY be retried against a different server.
- This message SHOULD be sent using an ephemeral key.
On receiving the message, the push notification server MUST validate the access token.
If the access token is valid, a notification MUST be sent to the
[gorush](https://github.com/appleboy/gorush) instance with the following data:
- A`PushNotificationResponse`message MUST be wrapped in a[`ApplicationMetadataMessage`](../62/payloads.md)with type set to<74><6F>`PUSH_NOTIFICATION_RESPONSE`.
2. [Push Notification, Apple Developer](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1)