Reputation: 37206
Okay, so for my senior design project I am working with a group on an Node.JS / Express application for an SGA student volunteer program. We are using MongoDB for persistence along with the session store in Express.
When a user signs in, their document is copied into their session storage.
Anytime user data is modified, it is written to the MongoDB database. If the database update is successful the user session is updated with the new document in the database resulting from the update.
Anytime user data is requested, it is read from the session store.
This works as long as the session stays updated every time user data is successfully modified in the database. It also lets us avoid having to read from the database every time we render a view with some user data.
We have different types of users. We have student volunteer
type users, different levels of staff
type users. I didn't think we would have a problem with the session/database combination until my partner implemented the functionality for the top-level staff
type users. They have the ability to modify the data of the student volunteer
users.
This is not a problem when it comes to writing to the database, we simply write the modified data to the volunteers document. The problem comes from the fact that, as far as I know, we have no way to update/invalidate/delete the volunteer
user's session in response to a request from a staff
type user to modify it.
Basically, if a staff
user modifies a volunteer
user's data and the volunteer
user is not signed then everything works fine, the modification will be made and the volunteer
document in the database will be modified. When the volunteer signs in this modified data will be read from the database and stored in the user's session.
However, if a staff
user modifies a volunteer
user's data and the volunteer
user is signed in then there could be problems. The volunteer
document in the database will be updated, but the volunteer
user's session will not be updated until either the session has ended and the user signs in again causing their document to be read into their new session from the database, or until the volunteer
user modifies their data causing their session to be updated with the new data from the database (this possibility may or may not overwrite the changes the staff
user made).
Needless to say this has the potential to cause inconsistencies if not addressed. Does anyone have any advice on how I can deal with this. Is it not possible to use the session store as planned if we are going to allow one user to update another's data?
Is it possible to invalidate/delete a particular user's session in response to a different particular user's request? Or possible to modify a particular user's session in response to a different particular user's request?
EDIT: Not sure how this is off-topic, perhaps a little too focused and possibly without 'minimal understanding', I'll attempt to rectify that by adding some more to clarify my question:
function updateUserDocument(req, res, id, callback) {
var data = req.body;
var query = { _id: id };
var cmd = {
$set: {
role: 'volunteer',
volunteer: data
}
};
var opt = { w: 1, new: true };
users.findAndModify(query, null, cmd, opt, function (err, updated) {
if (err || !updated) {
callback(err);
} else {
callback(null, updated);
}
});
}
This is what is used both when a volunteer
updates their own data, as well as when a staff
user updates the volunteer
user's data, the difference being that when the volunteer updates their data, the updated document passed back in the callback is used to update the session (I use the underscore merge method)
Example:
module.exports = {
volunteerUpdateVolunteer: function (req, res) {
updateUserData(req, res, req.session.user._id, function (err, doc) {
if (err) {
res.send(400);
} else {
// save user session with updated document send success response
_.merge(req.session.user, doc);
res.send(200);
}
});
},
staffUpdateVolunteer: function (req, res) {
updateUserData(req, res, req.params.id, function (err, doc) {
if (err) {
res.send(400);
} else {
// no way to update the volunteer user's session here?
// how can I handle possible inconsistencies?
res.send(200);
}
});
},
As our project is designed so far, this is my problem. I don't think that the session can be kept updated this way but I am not sure. Is there a way to keep the session updated? Or are we just using it all wrong?
Upvotes: 1
Views: 1170
Reputation: 2634
after looking into the code, I wrote below snippet, hope it could be helpful
var express = require('express');
var sesseionStore = new express.session.MemoryStore();
app.use(express.session({
secret: 'a4f8071f-c873-4447-8ee2',
cookie: { maxAge: 2628000000 },
store: sesseionStore
}));
var volunteerid2sessionid = {
};
express.use(function (req, res, next) {
volunteerid2sessionid[req.session.user._id] = req.sessionID;
next();
});
/// working with volunteer sesseion
// seems volunteerid is req.params.id in staffUpdateVolunteer
sessionid = volunteerid2sessionid[volunteerid];
sesseionStore.get(sessionid, function(err, sess){
});
Upvotes: 1