chovy
chovy

Reputation: 75774

validate a password with express-validator

I'm using express-validator for express 3.x -- when the user changes their password or signs up for an new account, they have to enter their password twice.

How would I write a custom validator that will push an error to the error stack in express-validator if the two passwords (two strings) do not match?

Something like this:

req.assert('password1', 'Passwords do not match').isIdentical(password1, password2);
var mappedErrors = req.validationErrors(true);

Upvotes: 13

Views: 17934

Answers (8)

Antti A
Antti A

Reputation: 500

I found the previous answers not complete or hard to understand so here is my version without anything extra:

app.post('/registrate', 
    body('password1'),
    body('password2')
    .custom( function(password2, { req }) {
            if (req.body.password === password2) {
              return true;
            } else {
              return false;
            }
          })
    .withMessage("Password mitchmatch."),
    function (req, res, next){
    ....

Upvotes: 0

Stanley Umeanozie
Stanley Umeanozie

Reputation: 467

One liner:

check('confirmPassword', 'Passwords do not match').custom((value, { req }) => (value === req.body.password))

Change confirmPassword to the "name" of your confirm password field.

Change password to the "name" of your password field.

Upvotes: 1

Reinier Garcia
Reinier Garcia

Reputation: 1760

Here is a cleaner & more complete solution:

File: routes/auth.route.js

const express = require('express');
const controller = require('../controllers/auth.controller');
const isAuth = require('../middleware/isAuth');
const {body} = require('express-validator');

const router = express.Router();

// Validators Definition:
.
.
.
const registerValidators = [
    .
    .
    .
    body('password')
        .exists({checkFalsy: true}).withMessage('You must type a password'),
    body('confirmedPassword')
        .exists({checkFalsy: true}).withMessage('You must type a confirmation password')
        .custom((value, {req}) => value === req.body.password).withMessage("The passwords do not match"),
];

// Routes Definition:
.
.
.
router.post('/register', ...registerValidators, controller.register);

module.exports.routes = router;

Note:

The name of the received parameter, inside the anonymous function passed into the custom validator, MUST be req. Not "request" nor anything else. Otherwise it won't work.

Upvotes: 2

P R 3 A C H 3 R
P R 3 A C H 3 R

Reputation: 55

Proper way : express-validator doc:checking if password confirmation matches password

const RegistrationRules = [
  check("password")
    .notEmpty().withMessage("Password should not be empty"),
  check("confirmPassword")
    .notEmpty().withMessage("Confirm Password should not be empty")
    .custom((value,{req}) =>{
        if(value !== req.body.password){
            throw new Error('Password confirmation does not match with 
            password')
        }
        return true;
    }),]

Upvotes: 1

Dejan Markovic
Dejan Markovic

Reputation: 59

I make it with custom method:

.custom(() => {
      if (req.body.password === req.body.confirmPassword) {
        return true;
      } else {
        return false;
      }
    })

This is full code for password validator:

exports.userRegisterValidator = (req, res, next) => {

//
  // ─── CHECK FOR PASSWORD ─────────────────────────────────────────────────────────
  //
  req
    .check("password", "Password is required")
    .notEmpty()
    .isLength({
      min: 6
    })
    .withMessage("Password must contain at least 6 characters")
    .isLength({
      max: 20
    })
    .withMessage("Password can contain max 20 characters")
    .custom(() => {
      if (req.body.password === req.body.confirmPassword) {
        return true;
      } else {
        return false;
      }
    })
    .withMessage("Passwords don't match.");

  //
  // ─── CHECK FOR ERRORS ───────────────────────────────────────────────────────────
  //
  const errors = req.validationErrors();

  // if error show the first one as they happen
  if (errors) {
    const firstError = errors.map(error => error.msg)[0];
    return res.status(400).json({ error: firstError });
  }

  // proceed to next middleware
  next();
};

Upvotes: 0

Suchfish Huang
Suchfish Huang

Reputation: 81

This is the answer I found

const { body } = require('express-validator/check');
app.post('/user', body('passwordConfirmation').custom((value, { req }) => {
if (value !== req.body.password) {
    throw new Error('Password confirmation does not match password');
    }
  }), (req, res) => {
// Handle the request
});`

check this document https://express-validator.github.io/docs/custom-validators-sanitizers.html

Upvotes: 8

Edwin O.
Edwin O.

Reputation: 5276

This one works!

req.checkBody('password2','Passwords do not match.').equals(req.body.password1);
var errors = req.validationErrors();

notice the use of checkBody() in this case

Upvotes: 5

chovy
chovy

Reputation: 75774

I found the answer

req.assert('password2', 'Passwords do not match').equals(req.body.password1);
var mappedErrors = req.validationErrors(true);

Upvotes: 20

Related Questions