I have a very simple site that is using Passport JS to create local login strategy to hit a local postgres database using the Sequelize ORM.
The user model looks something like this:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('user', {
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
email: DataTypes.STRING,
password: DataTypes.STRING,
}, {
classMethods: {
generateHash: function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
},
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
}
},
getterMethods: {
someValue: function() {
return this.someValue;
}
},
setterMethods: {
someValue: function(value) {
this.someValue = value;
}
}
});
}
Everything seems to work just fine. I can sign up using this strategy, log in, and see data.
I also am using Express and have various routes set. The req.user
appears to be set correctly, as I can interact with all the fields of this object.
Consider the sample route which works correctly:
app.get('/profile', isLoggedIn, function(req, res) {
res.render('profile.ejs', {
user : req.user
});
});
My serialization / deserialization methods:
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id).then(function(user) {
done(null, user);
}).catch(function(e) {
done(e, false);
});
});
So, as per the Passport JS documentation, the user session seems to be correctly set and hooked into Express.
The trouble is that I cannot update any of the fields in the user object.
If I have the following route:
app.get('/change-email', function(req, res) {
req.user.email = req.body.email;
res.status(200).end();
});
Nothing happens in the database.
This is very similar to this question except it appears with Sequalize, the user object never persists, even after logging out and back in again.
I have also tried: req.session.passport.user.email = req.body.email
Although I didn't think this would fix the problem, I also tried to call login
with the new user object, but this generated 500 errors. Which such a limited number of functions that can be called, according to the Passport JS documentation, I'm starting to question if this functionality is even possible.
I'm not sure what to try from here. How can I update my user
object using Sequelize?
Any help would be greatly appreciated! Thanks!
// Edit: Rewriting first paragraph to be clearer
When you change any column values in an Instance object you also need to explicitly save the changes to the database to persist them. Since you are already storing the user Instance in req.user via passport.deserializeUser you only need to make a small change to your routing code to do this.
Instead of your current route for /change-email
, I suggest:
app.get('/change-email', function(req, res) {
req.user.email = req.body.email;
req.user.save()
.then(function() {
res.status(200).end();
});
});
For more information on how to persist changes to an instance, see this part of the Sequelize documentation.