Persistence for user Multi-User Chat in Converse.js - ejabberd

I want to retrieve all chat conversations from ejabberd, even after I logout, close the browser and login again. Please suggest any way to do it. I am using converse.js. Should I add something in converse configuration to retrieve the chat conversation ?
Basically, I want Facebook kind of chat where we can retrieve chat conversation between each user after its logged in.
Here is my converse.js config:
converse.initialize({
websocket_url: webSocketUrl, // ConnectionUrl
keepalive: true,
message_carbons: true,
play_sounds: true,
auto_login: true,
jid: user,
password: password,
show_controlbox_by_default: false,
auto_list_rooms:true,
allow_logout: false,
allow_registration: false,
});

Converse.js supports the XMPP extension XEP-0313 Message Archive Management (MAM).
You need to make sure that your XMPP server supports MAM. Ejabberd 15.06 has support for it. You'll need to turn it on in Ejabberd's configuration file.
In converse.js, you want to pass in a value of roster or always to message_archiving when you call converse.initialize.
For example:
converse.initialize({
// Your other options go here...
message_archiving: 'always'
});
roster means that only message to and from contacts in your roster are archived. always of course means that messages are always archived.
There is also the related option archived_messages_page_size, which you can use to set how many messages are fetched at a time.

Related

how long a firebase cli token stays functional?

I have the following chunk as a part of a recursive delete cloud function , my question is I managed to store the cli token inside fb.token, but how long this token will last ? Is it forever or should have to update it frequently ? , is it even a thing for the user to be able to call this function ? , in my use case , I want to automate the process of deleting user account and his all related collections in one action, and this function really serves me well, not to mention I don’t have to get all docs … so if this stored token fails and deletes gets rejected due to token expiration during production for some reason it could cause big issues in my db structure..
await firebase_tools.firestore.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token,
force: true,
});
But how long this token will last ? Is it forever or should have to update it frequently ?
Tokens obtained by firebase login:ci doesn't have expiration, though it can be revoked manually. The token is tied to the access privileges of the user and you can check the tokens used in here.
If you want to use another method, I suggest that you use service account for authentication. Then, grant any necessary permissions to the service account in your project. These permissions depend on the actions that had to be performed by the CLI. You can refer to this documentation for further explanation that you must follow.

Keeping sync between two devices accessing the same account (different/same session)

Kind of curious as I'm aiming for a stateless setup, how some people go about coding/setting up their session handling when many devices accessing a single account occurs.
I work with Node.JS currently but the pseudo is appreciated,
This is how my sessions look currently, ID is a unique value. (Redis stored JSON by KEY)
{"cookie": {
"originalMaxAge": null,
"expires": null,
"secure": true,
"httpOnly": true,
"domain": "",
"path": "/",
"sameSite": "strict"
},
"SameSite": "7e5b3108-2939-4b4b-afdc-39ed5dbd00d0",
"loggedin": 1,
"validated": 1,
"username": "Tester12345",
"displayself": 1,
"avatar": "{ \"folder\": \"ad566c0b-aeac-4db8-9f54-36529c99ef15/\", \"filetype\": \".png\" }",
"admin": 0,
"backgroundcolor": "#ffffff",
"namebackgroundcolor": "#000000",
"messagetextcolor": "#5d1414"}
I have no issues with this setup until I have a user logged in twice different devices and one decides to adjust their colors or avatar; one session is up to date and the other is completely lost.
I do my best when possibly to call out to database to ensure the information is up to date when it's most important but curious for this small slip up what I should be doing? I'd hate to call for database each request to get this information but think most do this any-how?
I could set up in my mind a hundred different ways to go about this but was hoping maybe someone who has dealt with this has some excellent ideas about this. I'd like to just be efficient and not make my databases work as hard if they don't need to, but I know session handling makes the call each request so trying to determine a final thought.
Open to all ideas, and my example above is a JSON insert into Redis; I'm open to changing to MySQL or another store.
One way to notify devices and keep them up-to-date about changes made elsewhere is with a webSocket or socket.io connection from device to the server. When the device logs in as a particular user and then makes a corresponding webSocket or socket.io connection to the server, the server keeps track of what user that connection belongs to. The connection stays connected for the duration of the user's presence.
Then, if a client changes something (let's use a background color as an example), and tells the server to update its state to that new color, the server can look in its list of connections to see if there are any other connections for this same account. If so, the server sends that other connection a message indicating what change has been made. That client will then receive that notification and can update their view immediately. This whole thing can happen in milliseconds without any polling by the client.
If you aren't familiar with socket.io, it is a layer on top of webSocket that offers some additional features.
In socket.io, you can add each device that connects on behalf of a specific account to a socket.io room that has a unique name derived from the account (often an email address or username). Upon login:
// join this newly connected socket to a room with the name
// of the account it belongs to
socket.join(accountName);
Then, you can easily broadcast to all devices connected to that room with one simple socket.io API call:
// send a message to all currently connected devices using this account
io.emit(accountName, msg);
When socket.io connections are disconnected, they are automatically removed from any rooms that they have been placed in.
A room is a lightweight collection of currently connected sockets so it works quite well for a use like this.

Html - single page - staying logged in

I have an Html page with a load of javascript that changes between views.
Some views require the person to be logged in, and consequently prompt for it.
How can I note the person has successfully logged in, using the javascript, that will not be a security issue, but will mean the person does not have to repeatedly log in for each view. I do not want to keep on going back to the server each time.
Edit:::
To explain more. Here are the problems I see.
Lets say I have the following in my javascript:
var isLoggedIn = true;
var userEmail = "myemail#mysite.com";
Anyone can hack my code to change these values and then get another person's info. That is not good. So instead of isLoggedIn do I need something like a hashed password stored in the javascript:
var userHashedPassword = "shfasjfhajshfalshfla";
But every where I read, they say you should not keep any password stuff in memory for any length of time.
So what variables do I keep and where? The user will be constantly flicking between non-user specific divs and user-based divs, and I do not want them to have to constantly log in each time.
****Edit 2:*****
This is what I am presently doing, but am not happy with.
There is a page/div with 3 radio buttons. Vacant games (does not require user information), My Game (requires knowledge of user and must be signed in), My Old Games (also requires logged in status).
When first going on the page it defaults on vacant games, and gets the info from the server, which does not require login.
In two variables in the javascript I have
var g_Email = "";
var g_PasswordEncrypted = "";
Note these are both 0 length strings.
If the user wants to view their games, they click the My Games radio button. The code checks to see if the g_Email and PasswordEncrypted are 0 length strings, if they are it goes to a div where they need to login.
When the user submits their loging info, it goes to the server, checks their details, and sends back an ok message, and all the info (My Games) that the user was requesting.
So if the login was a success, then
g_Email = "myemail#mysite.com";
g_PasswordEncrypted = "this is and encrypted version of the password";
If there is any failure in login, these two are instead set to "".
Then when the user navigates to any page that requires login, it checks to see if these two strings are filled. If they are, it will not go to a login page when you request information like My Games.
Instead it just sends the info in these strings to the server, along with the My Games request. The server still checks these Email and encrypted password are valid before sending back the info, but at the client side, the user has not had to repeatedly input this info each time.
If there is any failure in the server request, it just sends back an error message (I am using ajax) in the callback function, which knows to set the g_Email and g_PasswordEncrypted to "" if there is anything wrong. (In the latter case, the client side knows it has to re-request the login details because these two strings are "").
The thing I do not like is I am keeping the Encryted password on the person's client machine. If they walk away from their machine, someone can open up the debugger in something like chrome and extract these details, and then hack it into their machine some time later.
If javascript loads content for each view from the server then it is for server to know if a current session belongs to logged user or not. In case the user is not logged, the server responses with prompt to login, otherwise it sends content of the view.
If javascript bulds content for the views deriving it from the data that was already received from the server then it should use some variable keeping state of the user (logged/not_logged). And depending on that value javascript will either show a prompt to login or display required content of the view.

Problems with WebSession when executing a WebService (GeneXus)

Here is the problem: I have a KB Called APP1 that will execute an WebService of an Identity Provider (centralizes all the logins/sessions for different applications) that will return true if there is a logged user in current WebSession that has been granted to access the Application or false otherwise. When I create an web panel at the same KB as the Identity Provider, it works just fine, I get TRUE when there's a logged user, and FALSE when there's not. But when I call it from APP1 it always returns false, I believe that the problem is because the WebSession won't work properly when called through an WS. Any ideas of how to solve it?
My first advice is to try using GAM Single Sign on (X Evolution 3)
WebServices should be Stateless. I think that using the Database instead of WebSession could do the job.
Nonetheless, in order to call a restful WebService you will have to do something more complex as dealing with CookieContainers as stated in the following link.
Consider this solution:
User tries to access App1
There's no web session (App1 doesn't know who is connecting)
App1 redirects User to an IdentityProvider's special login page
If User is not logged, it provides credentials and logs in
IdentityProvider has a session for the user (it knows who is connecting), then it redirects to the referer, appending to the url an encrypted userid parameter.
App1 decodes the parameter, now it knows who is connecting.
App1 saves the userid to the web session, now the user is authenticated
App1 and IdentityProvider must share an encryption key.
Consider that if the encryption key gets compromised or cracked anyone can impersonate another user.
Depending in how secure you want your system to be, you should study other security issues:
every time the user connects it's encrypted login is the same an it shows in the url, it can be easily solved adding a nonce or salt.
The system could be abused generating multiple requests until it gets a valid encrypted userid. It can be mitigated using a large Salt and/or blocking multiple attempts from the same source.
Note that this isn't a tested protocol and I didn't study the security in depth. I got some inspiration from OpenId, but this is a simplified protocol and I could be missing security holes.

Is it possible CookieStore config not working correctly?

Even if I configure CookieStore with:
MyApp::Application.config.session_store :cookie_store, {
key: '_myapp_session',
cookie_only: false,
httponly: false
}
and I make a POST request with
_myapp_session = #SOME_SESSION_ID
and authenticity_token = #AUTH_TOKEN
and http-header[X-CSRF-Token] set to #AUTH_TOKEN
finally the user is not authenticated, and new session is created with new AUTH_TOKEN and session id.
Can anybody give me some suggestions ?
Unfortunately there is NO SUPPORT for this option in current 4.0 branch. Although this option is forced to TRUE and I didn't find any code in rails sources using this option.
The way to make isolated POST's requests working is to create dedicated middleware, which will add appropriate session cookie. It must be inserted in the apropriate place, because middleware's order is significant.
Because it is very dangerous in CSRF security aspect, we must add to our middleware same verification, which will limit potential risk to minimum.