Secure messaging system with chat history - node.js

I would like to create a messaging app that will be available both on website and mobile ie users can access there messages with their account both on the website and the app.
Now, the issue is that in order to keep the history of the messages I must save them somehow in the database. I do not want to save them in plain text to avoid any data stealing (the app might go in production someday). But, I do not see any way to save the messages encrypted in the database and decrypt them for both the sender and receiver.
What I thought about doing is to create two instances of each message sent in the db. One being encrypted with the sender's public key and the other one being encrypted with the receiver's public key. This way both sender and receiver will be able to decrypt every single message saved in the discussion with their private key.
However, I do not if this is the best way of doing it, what do you think about? Also, I guess the private key will be stored on the user's device but what would happen if the user deletes the app or changes device. Furthemore what about the website? How will it access the private key if it is on the user's mobile device?
Fyi I am using NodeJS, MongoDB, React, React Native and Socket.io

Related

rocket.chat uploading to inaccessible room

I am writing a slashcommand with the Rocket.Chat.Apps-engine for my Rocket.Chat Server which exports the chat in the current room, creates a pdf and uploads this back into the room. I am using an own node server for the generation and upload. However, my bot-user does not have access to lets say direct chats, private rooms also not. One could invite the bot into every new private room, but the direct chat problem stays. Is there a ways to somehow use the Rest Api to write a message to such rooms? I am using access tokens for authorization.
So far I can read all the chats with the /api/v1/im.messages.others endpoint (also those my bot cannot access), now I need to have some endpoint or similar to write something to the rooms which my bot cannot see.

What is the most secure way to invite an unregistered user to my app?

I'm working on a React app with an Express backend, with Passport for authentication via JWTs. A registered user needs to be able to send an invitation to someone else who is unregistered, to come use the application. The unregistered user should not be required to register in order to see a subset of our content. THIS IS IMPORTANT - the unregistered user needs to be able to have access to some data that belongs to the registered user and would otherwise be unviewable without being authenticated. I built an invitation model to track these invites, who sent them, who they're being sent to, etc.
What is the best/most secure way to identify this user?
My current guess is to create a unique string and store that in the invitation object and pass that to the unregistered user via email. So they will have a link to our app with ?invite_id=SOME_ID_HERE appended at the end. When they reach our app we will verify that the string matches an invite in our DB.
Is this the best approach? Should I be doing something more secure, maybe a pair of public and private keys? Any advice would be greatly appreciated, thanks!
I think it's best to keep this as a random ID in your database. That way, the users can be removed later. And, if you do associate this new user with that random ID later, you can use an existing profile that you're already storing rather than having them start from scratch.
In other words, create a new ID for this user but set it up so that they can only access things via this URL until they create an account.

Sending Firebase Notification with nodejs

I have an android app on which I want to send notification via my web app.
How do I send Firebase Cloud Messaging notification with nodejs? I have found a lot of examples and posts on this subject, but in all of them you are supposed to just paste device Token and send notification to that device. If I wanted to use it that way, I would be able to simply implement this from official documentation.
The thing is, I need to receive user id from database so I know which user I want to send notification. After I have user id I can then retrieve device Token from the same database. I get both user id and device token on client side. And documentation refers to server side.
This all happen after button click. So, I don't understand how to send notification on server side, meaning, I don't have there all those informations I need - user id, device token and message info that contain some other database info. Do I pass those arguments from client side to server side somehow, or is there a way of using modules like "require()" on client side?
What is the best approach here?
You will need to implement a device token registry to fit with your use case. So if you want to send messages to users, then you will need a registry (really just a fancy word for a database) of the token(s) for each user. Then when you want to send a specific user a message, you look up their token(s) in the registry, and call the FCM API to send messages to them. Since you mention Node.js, you can likely do this using the Firebase Admin SDK: https://firebase.google.com/docs/cloud-messaging/admin/send-messages#send_to_individual_devices.
An alternative I have once written article about using a topic for each user, which saves having to have a registry of their tokens. While this is less secure (since anyone who knows a topic, can subscribe to it), it is definitely easier to implement.

End-to-End Encryption & Syncing

Our iOS app stores messages that users send each other in a PostgreSQL database on our server. Therefore, our users can access their entire message history on any device (iPhone, iPad, iPod Touch) just by logging in.
We'd like to implement end-to-end encryption while still allowing our users to access their message history from any device.
Is this possible?
For example, if Apple's Messages app is end-to-end encrypted, then how is it able to sync across all of my devices?
Of course: you can go two ways (well, at least two ways): let the users register their devices and list all the devices public keys. Then encrypt for all the devices using a single data key and encrypting using the various public keys. Disadvantage: adding a device means re-encrypting for the device.
You could also distribute a single private key encrypted by the password of a user to each device. Now the user has to enter a password to access the private key and the messages encrypted for it.
These are two ways of doing this; there will be more. I don't know how Apple does perform end-to-end encryption though.

J2ME High Secured app for m-commerce

I am creating a j2me application for mcommerce, which uses mobile internet(gprs). I wanted make it more secured by binding the application to the SIM card and the device. That is a user should be able to login to the system, only using his/her SIM card or from the registered mobile number.
To achieve this I need to fetch the mobile number.
So, on login i thought of Triggering an SMS from the server with a key, which the application reads and uses the key for the entire session. Here the challenge is, that sms should not go to the inbox.
Any suggestions pls?
Yes it can be achieved using the Wireless Messaging API. Have the MIDlet set up a server connection on a chosen port number, then send the SMS to that port number. It will go straight to your app, bypassing the inbox. If you use the Push Registry, you can even make the SMS start your app if it is not running.
It doesn't matter if the user sees the number in his/her inbox.
As long as the key is only used that session, it is her/his responsibility to not share the key with others.
The one thing you make sure is that ONLY the person who owns the SMS phonenumber gets the key and is able to log on.
This doesn't take care of the phone being stolen though.

Resources