Reputation: 2989
I'm using Postman to test the routes and this route returns the err message after user.save((err)=>{})
saying that the password is too long. It uses a passwordValidator
I created but I obviously didn't call it for this route neither in Schema.
What am I doing wrong?
The user schema in mongoose:
const userSchema=new Schema({
email: { type: String, required: true, unique: true, lowercase: true, validate: emailValidators},
username: { type: String, required: true, unique: true, lowercase: true, validate: usernameValidators},
bio: { type:String,default:null,validate:bioValidators},
location: {type:String, default:null},
gender: {type:String,default:null,validate:genderValidators},
birthday: { type:String,default:null},
password: { type: String, required: true,validate: passwordValidators}
});
The route:
router.put('/editProfile',(req,res)=>{
if(!req.body.bio){
res.json({success:false,message:"No bio provided"});
}
else{
if(!req.body.location){
res.json({success:false,message:"No location provided"});
}
else{
if(!req.body.gender){
res.json({success:false,message:"No gender provided"});
}
else{
if (!req.body.birthday) {
res.json({success:false,message:"No birthday provided"});
}
else{
User.findOne({_id:req.decoded.userId},(err,user)=>{
if(err){
res.json({success:false,message:"Something went wrong: "+err});
}
else{
if(!user){
res.json({success:false,message:"User not found"});
}
else{
user.bio=req.body.bio;
user.location=req.body.location;
user.gender=req.body.gender;
user.birthday=req.body.birthday;
user.save((err)=>{
if(err){
res.json({success:false,message:'Something went wrong: '+ err}); //returns this
}
else{
res.json({success:true,message:"Account updated !"});
}
});
}
}
});
}
}
}
}
});
EDIT
Here's the password validator array
const passwordValidators = [
{
validator: passwordLengthChecker,
message: 'Password must be at least 5 characters but no more than 40'
},
{
validator:validPassword,
message: 'Must have at least one uppercase, lowercase, special character, and number'
}
];
and the checkers
let passwordLengthChecker = (password)=>{
if (!password) {
return false;
}
else{
if(password.length<5 || password.length>40){
return false;
}
else{
return true;
}
}
};
let validPassword = (password)=>{
if (!password) {
return false;
}
else{
const regExp = new RegExp(/^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\d])(?=.*?[\W]).{8,35}$/);
return regExp.test(password);
}
};
As you can see it's using the passwordLengthChecker though it shouldn't
EDIT N°2
I just realized i have this middleware just below the schema
userSchema.pre('save', function(next){
if(!this.isModified('password'))
return next();
bcrypt.hash(this.password, null, null, (err,hash)=>{
if(err) return next(err);
this.password=hash;
next();
});
});
does it mean this function is gonna run everytime I use save() ?
Upvotes: 1
Views: 86
Reputation:
Down here is the problem, you providing bio
, location
, gender
, birthday
but not password. When you do not declare a password its length
will be equal to 0
. That's why you get error back. Length can be from 5
to 40
.
else{
user.password=req.body.password;
//I added user.password here, this is what you should do
user.bio=req.body.bio;
user.location=req.body.location;
user.gender=req.body.gender;
user.birthday=req.body.birthday;
user.save((err)=>{
if(err){
res.json({success:false,message:'Something went wrong: '+ err}); //returns this
}
else{
res.json({success:true,message:"Account updated !"});
}
});
}
UPDATE HERE
If you are only going to update bio
,location
,gender
and birthday
then using save()
function is wrong. You need to use findOneAndUpdate()
function.
User.findOneAndUpdate({_id:req.decoded.userId}, { $rename : {gender: 'male' , bio : 'somethingElse'}}, {new: true}, function(err, user){
if(err) throw err;
else{
console.log("done : " + user.gender);
}
});
Also please see findOneAndUpdate and its operators to be used
Upvotes: 1
Reputation: 2989
So i think the bcrypt function compromised the Mongoose save() function, i found an other solution for now in Mongoose doc.
User.findByIdAndUpdate(req.decoded.userId,{$set:{bio:req.body.bio, location:req.body.location, gender:req.body.gender, birthday:req.body.birthday}},{new:true},function(err,user){
if(err){
res.json({success:false,message:"Something went wrong: "+err});
}
else{
if(!user){
res.json({success:false,message:"User not found"});
}
else{
res.json({success:true,user:user});
}
}
});
Upvotes: 0