Express-session: first user session overwritten by second user session - javascript

This is a get request where the user is passed to the view
app.get('/blog/:id', function(req, res) {
// Define which page
res.render('blog', {
user: req.user,
});
});
This is a textarea where all of the users on this page should have their names stored.
<textarea readonly id="usersInRoom" placeholder="<%= user.username %>"></textarea>
This successfully sets the correct username as the placeholder. If a second user renders the same view and visits this page at the same time as the first user, the second user's username will be the only placeholder. How would one store the first username so that when the second user opens the page, the placeholder can be a concatenation of the first username + the second username? The data stored in any embedded javascript arrays etc. by the first user are not available to the second user.

If you are using SignalR, then you could broadcast the current list of users to each connection and update the view like in the sample chat application.
If you are using regular ajax server polling, set a client method on an interval that gets a list of current page users from a database store. Because of http's lack of state, you would have to 'retire' users from the list if they haven't posted in awhile.
Client code:
setInterval(checkServer,5000);
function checkServer(){
//some ajax call to the server here
//that returns your user list
...
success:function(result){
$('#usersInRoom').val(result);
}
}
Server code (assuming you are saving all your current page users in a table
with a field called LastModified):
CurrentPageUser class (store this in your DbContext as the CurrentPageUsers table):
public class CurrentPageUser{
public int Id {get;set;}
public DateTime LastModified {get;set;}
public string Name {get;set;}
}
Controller method:
public string GetCurrentUsers(int selfid){
using (var db=new DbContext()){
var now=DateTime.Now;
//update your requesting user so other users can see him/her
db.CurrentPageUsers.Find(selfid).LastModified=now;
db.SaveChanges();
DateTime timelimit = now.AddMinutes-5);
return string.Join(", ",
db.CurrentPageUsers.Where(u=>
u.LastModified<timelimit).Select(u=>u.Name).ToList());
}
}
Note that the SignalR implementation has much better performance and is less clumsy to implement on the server side with no need for a database table to store the current page users. It was made for this type of scenario.

I found a solution. I did in fact have express-sessions persisting my login sessions. The first session was overwritten by a second user who logged in while the first user was online, which replaced the first user's credentials with the second users, and now I had user 2 online in two different browsers.
Although I tried this on different browsers, from different devices, the problem was that the node app was hosted locally at localhost. When I uploaded the app to heroku and accessed it from there, the user session was not overwritten.

Related

parse server add current user to relation in users class (javascript SDK)

i want to do something like who visit your profile function in my ionic application, simply this function take the current user parse object and insert it in a relation column present in users class called who visited
so what i would like to do first is to query the relation to see if the current user already there and if not insert it in the relation
tried the following code:
var currentUser = Parse.User.current(); //current user object
var user = this.navParams.get('user'); // parse user object passed through navparams
var relation = user.relation("whoVisited");
relation.add(currentUser)
user.save()
but it gives me POST error 400 Bad Request
After searching for 6 hours i found the following
User class is protected and no user can modify other user data thats why i was getting the error
I managed to do the same function using cloud code and the power of master key

Best approach/design to web application?

I have been taking a Node.js course on Udemy and would like to apply some of the knowledge I have gained to create a simple web application. I would like to have a user register, which leads him to an admin panel, this part I already have.
This user (requester) can then refer users (invitees) to this website using a unique link. For example he would click a button to generate a unique hyperlink (my idea for this link was to be the http://websiteurl/userid of the requester who is sending the link).
The requester can then send this link through email to their friends to invite them to the website, once they click the link they are taken to a sign up form and when they fill in the form they are linked (added to an array under the original user).
How would I go about setting up this "session", as in make sure that the form that the invitees fill out is linked to the original requester? How can those forms be generated dynamically on the requester's hyperlink?
I'm not looking for the exact code to do this, but rather validation if my idea for the url is a good approach or if there are other approaches I should consider.
Thanks in advance!
Well, this would require you changing the schema for your database. A user will need to have a property like:
{
referred: []
}
The referred array should contain ids or some sort of reference to a user's referred users.
On the "/:userid" route, the form should submit to the route where a new user is created and have a parameter with the user ID. In this case, I am using query parameters.
So if a person were to visit /foo, they would get a form that would post to a URL like /new?userid=foo.
In that route, you can do something like this (assuming Express):
app.post("/new", (req, res) => {
const userID = req.query.userid;
const newUser = // create user normally
if(userID) {
// `userID` referred this user
const referrer = getUser(userID);
referrer.referred.push(newUser);
save(referrer);
}
});
The getUser function should returning the current user, and you should modify the referred property with the new user. This code was merely an outline and you should update the user in your database.
In a nutshell, a form should post to /new?userid=foo, and when creating a new user, if this parameter is present, you can update the database entry for the user id in the parameter with the id of the new user.

Multi-Page Order Form with sessions

For my web dev class we have to create a login page, verify it against encrypted records (Id, password) that we have to enter, then step through an order form (while being able to step forward and backward throughout).. so sessions and all that.. I have no idea where to even start aside from coding the html which I've already done.. Any pushes in the right direction would be helpful.. my instructor is abrasive and refuses to help most people without degrading them first.
This is kinda like a longer question.
First at login form you need to check with MYSQL / SQL / DB / etc if the username and password matches.
It's basically like this:
SELECT * from users WHERE username = 'username' AND pass = 'sha1(password)'
Or use the encryption method which you use (md5,sha1,any other for password)
Then you check out if it's returning a row. IF it's return 1 row,then everything is correct.
Then you put all this data to session. I don't know how much you need,but you can put the whole sql result to data. IT doesn't matter here as you said it's a dev class work.
So basically at every of your php you have to start with
session_start();
Then when you verified the user you put the sql result into SESSION like this:
$_SESSION['userdata'] = $sql_row_array;
With this data you can read the current loggedin user's informations. So it's like:
Get username: $_SESSION['userdata']['username']
So you can use this to identify whom bought / ordered the products and insert it into the database.

Navigation properties do not get refreshed

I have a Home entity that I send from my server down to my clients.
public Home {
public HomeId {get;set;}
public String Address {get; set;}
public ICollection<Room> Rooms{ get; set;}
}
All data management on the client side is handled by BreezeJs.
My web application is multiuser. Whenever a user updates a Home entity, the server notifies all interested clients using SignalR.
When a client is notified, it runs the following query to refresh its cache:
function refresh(homeId) {
var query = entityQuery.from('Homes')
.withParameters({ homeId: homeId });
return manager.executeQuery(query)
.fail(queryfailed);
function queryfailed(data) {
// error
}
}
The server side controller:
[HttpGet]
public Home Homes(int homeId)
{
var home = _context.Context.Homes
.Include(t => t.Rooms)
.FirstOrDefault(t => t.HomeId == homeId);
return home;
}
Problem
When a Home entity is refreshed, all properties get the new values from the server but not the navigation properties. If a user adds/removes a Room to/from a given House then the related Rooms entities in cache don't get refreshed although the json data looks fine and contains the added/removed Room entities.
Questions
Is there a simple way to tell Breeze to update the Home and all its navigation properties?
Ideally, I would like to do this without clearing the cache as explained here to avoid some flickering on my UI.
Update I
I tried expanding my query to include Rooms by
var query = entityQuery.from('Homes')
.withParameters({ homeId: homeId })
.expand("Rooms");
Still the same issue, the json data contains the changes made by other clients but are not reflected on the local entities
Update II
I managed to get the changes to propagate to clients using expand. However, changes get propagated only when Rooms are added but not when they are removed.
Just to clarify, my guess is that you are dealing with "rooms' being added and removed from one "house" by one client and these updates not being correctly refreshed on another client with the same "house".
If this is the case, the reason is that the breeze client is able to determine which "rooms" have been added to a house by the other client but it can't determine which rooms have been moved or removed unless you also requery the rooms.
To clarify, imagine if Room 1 is moved from House 1 to House 2 by Client A. Client B still has House 1 containing Room 1. When Client B requeries House 1 (with an Include) it will return no rooms, but breeze will NOT remove Room1 from House 1 because it doesn't know where it moved to. If you were to requery either Room1 or House 2 with an "Rooms" include, then breeze would have sufficient information to "move" the room.
So one approach you could follow would be to simply detach "all" rooms associated with a specific house before "refreshing" the house. You would "lose" any houses that had been moved to another house but these would presumably be refetched by a refresh of that house.
Not sure how clear this is, but...

Redirect from JavaScript

I'm working on an internal web app and we are using secure query string keys generated server side for some simple security to prevent users from accessing pages they haven't been given access to. The page I am currently working on grabs data via AJAX calls and renders it in a table on the page. Each row has an edit button that will take the user to an edit page with more information, with the id of the row kept in the query string. Since every row id is unique, the key for every edit page will be unique to that row-user combination.
My problem is that I need to be able to get these secure query string keys from the server in some way that allows the JavaScript to redirect the user. I can't move the key generator client side because that opens up the possibility of users generating their own keys for pages they don't have permission to visit. And similarly I can't expose the generator in a web service.
Basically what this boils down to is I am stumped in finding a way to send data from the client to the server in order to generate a secure key and then redirect the user to the new page.
Not exactly sure if I am being 100% clear but I'll edit this as questions come in.
Your question is a little unclear, but PageMethods might work for this:
[WebMethod]
public static string GetSecureID()
{
return "Secure";
}
clientRedirectSecure = function() {
PageMethods.GetSecureID(onSuccess, onFailure);
}
onSuccess = function(result) {
window.location.href = "somepage.aspx?id=" + result;
}
onFailure = function(error) {
alert(error);
}
Here's an article that discusses PageMethods:
http://blogs.microsoft.co.il/blogs/gilf/archive/2008/10/04/asp-net-ajax-pagemethods.aspx

Categories