How to check if user with email already exists?

22,177

Solution 1

The best way to check if the e-mail id already exists in the database or not is by using express-validator. Since, there upgrade to version 4, the API has changed. Now, instead of using:-

const expressValidator = require('express-validator');

..in your app.js file, and then calling the middleware. Instead, just do this in your users route file:-

const { check, validationResult } = require('express-validator/check');

Now, to check if the e-mail id already exists in the database, you will have to use Promise. Here's a working code:-

      router.post('/register', [
          check('name')
          .not()
          .isEmpty()
          .withMessage('Name is required'),
          check('email')
          .not()
          .isEmpty()
          .withMessage('Email is required')
          .isEmail()
          .withMessage('Invalid Email')
          .custom((value, {req}) => {
            return new Promise((resolve, reject) => {
              User.findOne({email:req.body.email}, function(err, user){
                if(err) {
                  reject(new Error('Server Error'))
                }
                if(Boolean(user)) {
                  reject(new Error('E-mail already in use'))
                }
                resolve(true)
              });
            });
          }),
          // Check Password
          check('password')
          .not()
          .isEmpty()
          .withMessage('Password is required'),
          // Check Password Confirmation
          check('confirmedPassword', 'Passwords do not match')
          .exists()
          .custom((value, { req }) => value === req.body.password)
        ], function(req, res) {
          var name = req.body.name;
          var email = req.body.email;
          var password = req.body.password;
          var confirmedPassword = req.body.confirmedPassword;

          // Check for Errors
          const validationErrors = validationResult(req);
          let errors = [];
          if(!validationErrors.isEmpty()) {
            Object.keys(validationErrors.mapped()).forEach(field => {
              errors.push(validationErrors.mapped()[field]['msg']);
            });
          }

          if(errors.length){
            res.render('register',{
              errors:errors
            });
          }  else {
            var newUser = new User({
              name: name,
              email: email,
              password: password,
              admin: false,
              active: false
            });

            User.createUser(newUser, function (err, user) {
              if (err) {
                throw err;
              }
            });

            req.flash('success_msg', 'You are registerd and can now login');
            res.redirect('/users/login');
          }

You can similarly do this to check for the username also. Here is the link to the official GitHub page of express-validator

Solution 2

You can use Monsgoose's Model.findOne()=> https://mongoosejs.com/docs/api.html#model_Model.findOne:

router.post('/register',(req,res)=>{
    // Object destructuring
    const {username,password,email,...rest} =req.body;
    // Error's Array
    let errors = [];
    // Mongoose Model.findOne()
    User.findOne({email:email}).then(user=>{
        if(user){
            errors.push({msg: 'Email already exists'});
            res.render('register',{errors})
        }
    })
})
Share:
22,177
Anthony Ashpen
Author by

Anthony Ashpen

Updated on August 08, 2020

Comments

  • Anthony Ashpen
    Anthony Ashpen almost 4 years

    I'm trying to prevent registration with a previously registered email. I tried to create a custom validation in mongoose schema. but it gave me an error ValidationError: User validation failed at MongooseError.ValidationError. The code is down bellow. Can some one tell me where is the error or a better way to check if the user email exists in db.

    // user schema 
    var UserSchema = mongoose.Schema({
        username: {
            type: String,
            index: true,
            require: true
        },
        password: {
            type: String,
            require: true
        },
        email: {
            type: String,
            lowercase: true,
            trim: true,
            index: {
                unique: true,
            },
            validate: {
                validator : isEmailExists, msg: 'Email already exists'
            }
        },
        name: {
            type: String
        },
        admin: Boolean,
        active: Boolean,
    });
    
    // validation
    function isEmailExists(email, callback) {
        if (email) {
            mongoose.models['User'].count({ _id: { '$ne': this._id }, email: email }, function (err, result) {
                if (err) {
                    return callback(err);
                }
                callback(!result);
            })
        }
    }
    // createUser function
    module.exports.createUser = function(newUser, callback){
        bcrypt.genSalt(10, function(err, salt) {
            bcrypt.hash(newUser.password, salt, function(err, hash) {
                newUser.password = hash;
                newUser.save(callback);
            });
        });
    }
    

    Router

    router.post('/register', function(req, res, next) {
        var name = req.body.name;
        var email = req.body.email;
        var password = req.body.password;
        var confirmedPassword = req.body.confirmedPassword;
    
        // Validation
        req.checkBody('name', 'Name is required').notEmpty();
        req.checkBody('email', 'Email is required').notEmpty();
        req.checkBody('email', 'Email is not valid').isEmail();
        req.checkBody('password', 'Password is required').notEmpty();
        req.checkBody('confirmedPassword', 'Passwords do not match').equals(req.body.password);
    
        var errors = req.validationErrors();
    
        if (errors) {
            res.render('register', {
                errors: errors
            });
        } else {
            var newUser = new User({
                name: name,
                email: email,
                password: password,
                admin: false,
                active: false
            });
    
            User.createUser(newUser, function (err, user) {
                if (err) {
                    throw err;
                }
            });
    
            req.flash('success_msg', 'You are registerd and can now login');
            res.redirect('/users/login');
        }