Users chat using Rails + Nodejs (Redis, Socket.io, Mysql) - mysql

I want to implement chat between users (like live Personal Messages) into my RoR application. So, after reading a lot of manuals and recommendations, i've decided to use nodejs + socket.io to handle socket connections and send\receive messages. How i imagine it:
After user successfully signed in, rails adding session key to the redis db with associated user id. When user is opend PM's page, starts new connection through socket. When user presses button "Send", all data including receiver id and message sent to the server (nodejs). After that, nodejs extracting session key from cookie and checking redis db for existance. If exists -> check if user is subscribed to the specific channel ("channel-id1-id2" for example, where id1 and id2 - sender and recepient id), if true -> save message to db and send this message to channel subscribers (redis?), else -> create channel, save message to db and send this message to channel subscribers.
So, from what i have written, we use rails only for user authentication (if to take only PM module of my site). Questions:
Is logic of my application ok?
Is it safe to use channels for
private messages? I mean if i be able to create channels and
subscribe\unsubscribe users from it ONLY by nodejs server?
Any suggestions\corrections and etc. are Welcomed!
Thank you and remember that before posting this i have read different tutorials\manuals on this topic.

Related

Firebase Chat Application with Social Media on Flutter

I have a social media app written in Flutter. Users can see the profiles each other and block/unblock them. I'm using MySQL to keep that data. Now I want to implement chat feature using Firebase Firestore (or maybe MongoDB). When a user sends a message to another user, should I check if user blocked another user from MySQL every time, so user can't send new message. Is this a good practice in chat application, or should I store the "blocked" data at Firebase also.
I researched this subject deeply but didn't find any solution.
Like when user is trying to send a message to another user so in the list of the recipients you are also retrieving the value for (is particular user is blocked by the current user), if it's so you are checking this on that time.
Secondly, if you want this to check when sending to server. So, you can manage this using firestore transaction in which you might get the object of the sender and check to whom the sender has blocked and you may throw an exception. The other thing you might manage it using Firestore Security Rules as well.
So you can code like most of the current social media works.
Simply let the user send a message but put a condition on the receiver
user side so if the user is blocked by the receiver then it should not show
the chat in the user chat list also should not send a notification if the user
is blocked by the receiver.

React/Javascript/MySQL App - Authenticated User Data from DB?

I have a simple ToDo app written in ReactJS with Express backend and MySQL. I've recently implemented Auth0 authentication, and the app successfully requires authentication before allowing a user to view or add tasks. Any user can see all the tasks (stored in DB), but at least authentication is required first.
Next, I want ensure that users can see only their OWN tasks. Can anyone either describe how this works, or share any decent resources on the subject? Any examples I can review somewhere? I imagine there is probably an ID value I can fetch from Auth0 user DB and silently include that as a column in the DB, then allow users to only fetch tasks matching their own ID.
Any resources appreciated.

How to store and send one to one messages data from database to users

I am building a chat app with private messages that are saved in a database so when a user is offline he still can receive messages and they are sent to him when he logs in.
I am using MySQL, React, Node.js, and socket io for signaling.
What I did is:
When a user types a message and clicks send, the message is sent through socket io and stored in the database in a messages table with columns (id, sender, receiver, message_content).
When the receiver logs in, a get request is made to get the latest 50 messages, saved in an array state and displayed with Array.map() and more are requested on scrolling up in the chat section.
On every new message added, a new set of 50 messages is sent to both users and replaces the current messages array to keep them updated.
This way is working and everything but it really bad way to do it because of all the unnecessary data being transferred and all extra bandwidth.
I need to know if there is a better approach to this?
Thank you in advance.

Can eJabberd call an API if a roster contact does not exist?

Ejabberd newbie here. I hope this question makes sense.
We had a need to setup our own XMPP server so that customers on web and a Bria client can utilize it. I was able to get the basics up and running using ejabberd.
All users will be in the 'xmpp.exampledomain.com'
We also have a custom SMS gateway we built (which is really a server which can accept json APIs).
So what I am trying to accomplish:
Our platform would create a 'normal' xmpp user so the user can login to ejabberd.
This user can add roster contacts of other 'normal' xmpp users.
If this user wants to send messages via SMS, we would instruct them to add roster contacts (i assume) with the format 12125551234#sms.exampledomain.com. (adding the contact works currently)
If a user sends a message to this "SMS" contact, have ejabberd call our custom SMS gateway via a json API instead of attempting to deliver via normal xmpp.
Is this even possible?
For inbound from the SMS Gateway server, can call the ejabberd API send message function, so inbound is fairly easy.
I appreciate any suggestions
thanks
What you want was called a "transport" in the old days of IRC, ICQ, AIM and MSN. They were programs that you installed next to ejabberd (or other Jabber servers). Example usage:
you download a transport for ICQ
configure it to have access to ICQ,
and then configure ejabberd to connect to that transport, and allow users to contact it at address icq.example.com.
There are very old tutorials for your curiosity:
https://www.ejabberd.im/tutorials-transports/index.html
I don't know if the old "SMS-Jabber transports" will work nowadays. Searching revelaed few results:
https://www.jethrocarr.com/2013/06/03/smstoxmpp/
https://sourceforge.net/projects/jabbersms/
https://www.jabber.cz/wiki/SMS_transport
Alternatively, as you mentioned you already have a SMS program, if you can get your hands on Erlang or Elixir, you can write an ejabberd module that registers at sms.example.com, and forwards XMPP messages as json API...

Secure iOS to online database connection

I have an iPhone application that needs to collect data from an online MySQL database. I've written a PHP web service so I collect the data with JSON. The problem is that everyone can see the data if they go to the URL now. How do i secure the data transfer properly?
Thanks for your suggestions.
Typically, if you are showing data private to a particular user, then each user will generally have an account (user id and password). The app will pass the user's credentials to the server before the server will provide the user's data.
You can also do something similar using SSO integration, or OAuth (ala Facebook).
In some cases, your app may only pass the username/password on the initial call and receive a session ID, which the app passes on remaining calls. This allows the server to store session data.
Even if the data isn't private to a particular user, you can use accounts to restrict access and privileges for a publicly reachable web API.
In all of the above cases encryption such as SSL (HTTPS) must be used to protect the authentication mechanisms and data transfer.
I'm assuming your data is public for all users of your app, in other words, you don't want to implement a login mechanism for your users. If you just want to make sure you return the data only to users of your app and not to anyone who happens to enter the right URL in their browser, you will need to sign your requests, so that only requests from your app are accepted by your server.
I use a secret key that my app uses to create a hash/digest of the request which the server verifies (it knows the secret key as well). Also I make sure requests cannot be replayed if they are intercepted by adding a timestamp and a nonce. The timestamp is checked to be within 10 minutes of the server's timestamp (relaxed sync) and the nonce must be unique (server keeps the last 10 minutes of nonces). This way no-one can copy the same request, the server will just serve an error if they try.
This post explains how to sign your requests in a bit more detail:
http://www.naildrivin5.com/blog/2008/04/21/rest-security-signing-requests-with-secret-key-but-does-it-work.html