Run a function once per user for any endpoint in nodejs - node.js

My backend is written in NodeJS. I would like to push some real time data for my firestore database. My question how can i run a function once when a user is connected to my server. Also, this function will extract info from a cookie stored in the browser. I tried the singleton design pattern, but it is totally wrong because it runs for one user only.

This will involve storing some state per user (presumably you could do this in Firestore). As each user request comes in, you just need to check for said state and if it's not been set yet, invoke the function and set the state.
For example, here's how it might look if you were using Express:
app.use((req, res, next) => {
// assume user is deserialized with state from store
if (!req.user.hasRunFunc) {
// run some function
// update store setting 'hasRunFunc' state
}
})
As long as the state is set, then subsequent requests from the same user would be skipped.

Related

Getting the 'current user' in an emit listener in nestjs app

My nestjs + React app has a Google oauth flow loosely based on this process. One thing that the Google library tries to help with is to take a refresh_token (that you've likely stored in your app's db) and use it to automatically retrieve a new access_token if the old one is expired. When it does this refresh, it emits a 'tokens' signal, and in my code I need something like
oauth2Client.on('tokens', async (tokens) => {
if (tokens.refresh_token) {
// store the refresh_token in your secure persistent database
console.log(tokens.refresh_token);
}
console.log(tokens.access_token);
});
It appears that the Google library intentionally does not let you proactively make a call to do the token refresh. The refresh happens automatically when you've set a refresh_token on the oauth2 client object and use that client object to next make any Google API call where the previous access_token has expired.
What I'm finding tricky is that when the above listener runs, I ideally would be able to get the 'current user' whose initial client session is what led to this server code path running. I can certainly create a chain of events like
User is logged into my app on the client
User does something on the frontend
A call to the server is made that has #UseGuards(AuthGuard()) and where I can get the user from the #Req
The above controller calls some additional functions, one of which can use the oauth2 client to make any random Google API call
If the random Google API call caused a token refresh, it would run the listener quoted above.
...but then, when #5 happens, is there any way to get the user detected in #3? Perhaps put another way, is there any way to 'inject' more info when the certain signal is emitted (but it's emitted in the Google library, not my code), or is there a way for the listener to pull the user from some kind of context?
(In case it matters, the emitter looks like this)

How to handle parallel requests from same user in nodejs

For example:
app.post('/login', (req, res) => {
// I want to check.
// If we are already authenticating this user from the given IP.
// then res.send('Authentication already in progress');
});
I'm interested in how to correctly process a request in such moments.
I'm just reading "secure-your-node-js-web-application" of Karl Duuna. And he shows how to stop attackers from running parallel checks about a user’s account. But he mentions that examples have been simplified and are not directly usable in a production environment. So I want to know how to do that in real project. If I don't need to do anything why he wrote that.
You can use a lock based on the identifying feature of the user. Such a lock can persist in Redis as explained in this question.

How to create multiple instances of nodejs server

I am building a notification application in which every time an event is triggered the associated user gets a notification. I am using localstorage of NodeJs to store the information of the logged in user. The problem is that when two users are logged in,the localstorage values are overridden by the new users value.
I need to create multiple instances of NodeJS server so that every user has its own localStorage.
For example
If two users log in with credentials
{
userName:name1
}
and
{
userName:name2
}
then two separate localStorage should be created one having userName:name1 and one having userName:name2.
I have tried all the solutions available online but I am unable to create multiple states of NodeJS server.
Thanks in advance
You do not have to create a new server for each user. Take the IP address and port instead. This means that each user can be uniquely identified. You can simply name the files of the users after the variable client.
Here an example code
net.createServer((netSocket : net.Socket) => {
netSocket.on('data', (data) => {
var client = netSocket.remoteAddress + ':' + netSocket.remotePort;
})
})
I wasn't able to create multiple nodejs instances hence I stored the user data in session storage and passed it to nodejs server every time I triggered a request.

How does NodeJS process multiple GET requests from different users/browsers?

I'd like to know how does NodeJS process multiple GET requests from different users/browsers which have event emitted to return the results? I'd like to think of it as each time a user executes the GET request, it's as if a new session is started for that user.
For example if I have this GET request
var tester = require('./tester-class');
app.get('/triggerEv', async function(req, res, next) {
// Start the data processing
tester.startProcessing('some-data');
// tester has event emitters that are triggered when processing is complete (success or fail)
tester.on('success', function(data) {
return res.send('success');
}
tester.on('fail', function(data) {
return res.send('fail');
}
}
What I'm thinking is that if I open a browser and run this GET request by passing some-data and start processing. Then open another browser to execute this GET request with different data (to simulate multiple users accessing it at the same time), it will overwrite the previous startProcessing function and rerun it again with the new data.
So if multiple users execute this GET request at the same time, would it handle it separately for each user as if it was different and independent sessions then return when there's a response for each user's sessions? Or will it do as I mentioned above (this case I will have to somehow manage different sessions for each user that triggers this GET request)?
I want to make it so that each user that executes this GET request doesn't interfere with other users that also execute this GET request at the same time and the correct response is returned for each user based on their own data sent to the startProcessing function.
Thanks, I hope I'm making sense. Will clarify if not.
If you're sharing the global tester object among different requests, then the 2nd request will interfere with the first request. Since all incoming requests use the same global environment in node.js, the usual model is that any request that may be "in-flight" for awhile needs to create its own resources and keep them for itself. Then, if some other request arrives while the first one is still waiting for something to complete, then it will also create its own resources and the two will not conflict.
The server environment does not have a concept of "sessions" in the way you're using the term. There is no separate server-session or server state that each request lives in other than the request and response objects that are created for each incoming request. This is not like PHP - there is not a whole new interpreter state for each request.
I want to make it so that each user that executes this GET request doesn't interfere with other users that also execute this GET request at the same time and the correct response is returned for each user based on their own data sent to the startProcessing function.
Then, don't share any resources between requests and don't use any objects that have global state. I don't know what your tester is, but one way to keep multiple requests separate from each other is to just make a new tester object for each request so they can each use it to their heart's content without any conflict.

In New Relic Agent for Node.js, how to show the trace for every transaction?

In my expressjs app, each time there is a request, a transaction will be recorded on New Relic. However, as each transaction comes from a different user, I want to add a custom attribute (userId) to the transaction so that I know from which user the request comes from.
The only way to show that custom attribute is from the transaction trace > transaction details.
However, it appears that ONLY long transactions have a trace. So, I can't track the userId for each transaction.
What's wrong am I doing? Is it a good practice to add custom attribute to each transaction?
Here is the important lines in my node.js code:
// beginning of the file
const newrelic = require('newrelic');
...
app.get('/blah', function(req, res, next) {
newrelic.addCustomAttribute('test', 28);
...
});
For NodeJs that would be the best route. because of the way Node breaks out data (express, middleware, etc) the transactions can get a bit...weird.
What you can do (and I have done) is find specific transactions your concerned with (slow timing, etc) and instrument those out with the above code. Then add a newrelic.addCustomAttribute('ObjectName', Name);
to start calling the userId.
I believe "startWebTransaction" is the correct method to break out the functions call. But check the documents (goooooooogle) and you'll find examples.

Resources