how to use async-await in custom validators

Issue

i have this array of validation rules for password changes, but there is an error says:

"’await’ expressions are only allowed within async functions and at the top levels of modules."

const validationRules = [
  body('current_password')
    .exists()
    .not()
    .isEmpty()
    .withMessage('current password is required')
    .custom((value, { req }) => {
      const { id } = req.user;
      const { current_password } = req.body;

      const detailUser = await User.where('id', id).fetch({
        withRelated: ['roles'],
      });

      if (!detailUser) {
        throw new Error('User not found');
      }

      if (
        !bcrypt.compareSync(current_password, detailUser.attributes.password)
      ) {
        const errorMessage =
          'Current password you entered did not match our records';
        Logger.error(errorMessage);
        throw new Error(errorMessage);
      }

      return true;
    }),
  body('new_password')
    .exists()
    .not()
    .isEmpty()
    .withMessage('New password is required'),
  body('confirm_password')
    .exists()
    .not()
    .isEmpty()
    .custom((value, { req }) => {
      if (value !== req.body.new_password) {
        throw new Error('Password confirmation does not match password');
      }
      return true;
    }),
];

where should i put async to fix this error, please help

Solution

Note: async functions must return a resolved or rejected Promise because truthy or falsy values won’t stop the chain (#1028).

Source: Custom validator chain

So, you need to reject to use error message and use async at the custom function(){}

Making those changes to your code,

const validationRules = [
  body('current_password')
    .exists()
    .not()
    .isEmpty()
    .withMessage('current password is required')
    .custom(async (value, { req }) => {
      const { id } = req.user;
      const { current_password } = req.body;

      const detailUser = await User.where('id', id).fetch({
        withRelated: ['roles'],
      });

      if (!detailUser) {
        return Promise.reject('User not found');
      }

      if (
        !bcrypt.compareSync(current_password, detailUser.attributes.password)
      ) {
        const errorMessage =
          'Current password you entered did not match our records';
        Logger.error(errorMessage);
        return Promise.reject(errorMessage);
      }

      return Promise.resolve();
    }),
  body('new_password')
    .exists()
    .not()
    .isEmpty()
    .withMessage('New password is required'),
  body('confirm_password')
    .exists()
    .not()
    .isEmpty()
    .custom(async (value, { req }) => {
      if (value !== req.body.new_password) {
        return Promise.reject('Password confirmation does not match password');
      }
      
      return Promise.resolve();
    }),
];

Answered By – Sridhar

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published