Ad

How To Make Password Validation In NodeJS With Mongoose

- 1 answer

I have registration form with username, mail, password and password2. I want to verify passwords that they actually match. I verify practically everything in Mongoose Scheme but I cannot find any useful information in documentation how to grab password2 without actually saving it to database. (I have function to crypt password which runs only before saving)

    const userSchema = new mongoose.Schema({
    username: {
        type: String,
        unique: true,
        required: true,
        trim: true,
        validate(value) {
            if (!validator.isAlphanumeric(value , 'pl-PL')) {
                throw new Error('Name cannot contain special characters.')
            }
        }
    },
    email: {
        type: String,
        unique: true,
        required: true,
        trim: true,
        lowercase: true,
        validate(value) {
            if (!validator.isEmail(value)) {
                throw new Error('Email is invalid')
            }
        }
    },
    password: {
        type: String,
        required: true, 
        validate(value) {
            console.log(value)
            if(value !== this.password2) {
                throw new Error("Passwords don't match. Try again.")
            }

            if(value.length < 8) {
                throw new Error("Passwords is too short. At least 8 characters.")
            }
        }
    },
    tokens: [{
        token: {
            type: String,
            required: true
        }
    }]
    })
Ad

Answer

You don't need to make password2 a part of userSchema. The better way is to make a compare password function like this:

UserSchema.methods.comparePassword = function(plaintext, callback) {
    return callback(null, Bcrypt.compareSync(plaintext, this.password));
};

also you can make a use of Schema.pre:

UserSchema.pre("save", function(next) {
    if(!this.isModified("password")) {
        return next();
    }
    this.password = Bcrypt.hashSync(this.password, 10);
    next();
});

After this, you need to call the compare function from user controller. Something like this (depending on your logic):

        var user = await UserModel.findOne({ username: request.body.username }).exec();
        if(!user) {
            return response.status(400).send({ message: "The username does not exist" });
        }
        user.comparePassword(request.body.password, (error, match) => {
            if(!match) {
                return response.status(400).send({ message: "The password is invalid" });
            }
        });

For details you can read this excellent article.

Ad
source: stackoverflow.com
Ad