Closed kaladivo closed 1 month ago
This is not a proposal to rewrite of chat microservice! This is just a way how to remove FCM tokens to inboxes table from the database.
It is possible to implemented and release this solution without breaking compatibility to previous versions!
FCM token will be encrypted and stored into offer's public payload using ECIES with server public key. To send chat message, 2 operations should be done - ideally separated so they can not be linked:
This needs o be done since chats are only "weakly" linked to offers. Offer for chat can already be removed.
Sender
Reciever
Client sender:
{"notificationPayload": cypherText, "fcmcipher": fcmTokenCypherText}
- Notification payload should be treated at potentially dangerous, there is no validation that the data are from verified authorServer:
Client receiver:
Sending / receiving messages is beyond scope of this change set. This is just a simplified description of how it it's currently done.
Client sender:
Server:
Client receiver:
See list of tickets in here: https://github.com/vexl-it/vexl/milestone/10
Current problem
We need to push messages to the device for core features to work. The most important features are:
Core of the problem
We use firebase messaging service (FCM) to issue push notifications (FCM is Android Native & uses APNs- Apple Push Notifications Service - for iOS). Notifications are issued from server. For server to issue push notification using FCM we need the following:
For each user, notification tokens need to be stored in database, in our model we store them in 2 places
users
table - this token is used for sending network updates to device (when new phone number loggs in)inbox
table - each inbox contains fcm token to send new messages notifications toOur aim is to make inboxes anonymous and make it impossible to link multiple inboxes to one user. Currently it is possible to do that using fcm token.
Main constraint in this regard is the sending of push notifications. Server needs to handle the notification payload - which is encrypted - and notification token to to FCM.
Currently there are following informations sent with a chat notification:
REQUEST_MESSAGING
,TEXT_MESSAGE
...Encrypting FCM - Possible solution that still utilises FCM (and APNS on iOS)
We need to find a way how to prevent linking multiple inboxes to one user. There are following constraints that the solution needs to meet:
The token in chat database can be Symmetrically encrypted with a secret. For every inbox, client will encrypt the fcm token with symmetric key and send it to the server. Server will store it with other inbox metadata. Created inbox should be stored as follows:
Client side (inbox owner):
Server side:
When another client wants to send notification to the client, he first needs have the cypher key. Which he will send to the server together with payload which will server use to decrypt the FCM token cypher and issue the notification. Cypher key can be included in public payload of the offer.
The problem here is, that eventually server needs to have plain FCM Token and target inbox public key to send the notification. This still makes it possible for server to group inboxes by fcm token (albeit it is more complicated since it can't be done from the database data).
The way how to solve this is removing public keys from notification payload.
Messaging connections not inboxes (PoW draft, this needs to be refined further)
Each connection represents open channel. There is no information about public keys associated with connection. This is rough connection shape stored in database (admin id can be replaced by mor sophisticated signature system):
Sending messages A -> B:
Opening connection A -> B: TODO
Alternate solution - ditching FCM messaging all together
Basically, instead of using APNS we can open a socket and have server push messages though. This is very straightforward to do on android using foreground services.
On iOs this is problematic.
It currently seems there is no way to keep socket connection active (or at least have the app react to incoming messages).
From old ios 4 documentation: