Search code examples
javascriptreactjsvalidationfrontendyup

Can you validate a property based on another property using Yup?



What I am trying to do is to validate that the password added by the user does not contain the username the they chose. On the frontend I do the validation with Yup and right know I have something like this:

export const schema = Yup.object({
  username: Yup.string()
    .required("Username is required")
    .matches(
      /^[a-zA-Z0-9_-]+$/,
      "The username should contain only alphanumeric characters, underscores and hyphens"
    ),
  password: Yup.string()
    .required("Password is required")
    .matches(
      /^(?=.*?[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W).{8,}$/,
      "The password should contain upper and lowercase letters, numbers and special characters"
    )
    // Here I should somehow check if the username value is used (maybe like this?)
    .matches(
      /^(?=.*?[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W)(?!.*[{username}]).{1,}$/,
      "The password should not contain the username"
    )
});

I probably already do this wrong (with the username check part at least) so any other idea or suggestion on how to do this would be appreciated. Thanks!!


Solution

  • You can use Yup ref and notOneOf to achieve this

    import * as Yup from "yup";
    
    const schema = Yup.object({
      username: Yup.string()
        .required("Username is required")
        .matches(
          /^[a-zA-Z0-9_-]+$/,
          "The username should contain only alphanumeric characters, underscores and hyphens"
        ),
      password: Yup.string()
        .required("Password is required")
        .matches(
          /^(?=.*?[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W).{8,}$/,
          "The password should contain upper and lowercase letters, numbers and special characters"
        )
        // Here I should somehow check if the username value is used (maybe like this?)
        .notOneOf([Yup.ref('username'), null], "The password should not contain the username")
     
        
    });
    
     const obj = {
      username: 'abc',
      password: 'assscdF3$'
    }
    
    console.log(schema.validateSync(obj, {returnError: true}))
    
    const obj2 = {
          username: 'assscdF3$',
          password: 'assscdF3$'
        }
        
        console.log(schema.validateSync(obj2, {returnError: true}))