joi icon indicating copy to clipboard operation
joi copied to clipboard

Live password_confirmation validation not working

Open stesvis opened this issue 2 years ago • 1 comments

Support plan

  • is this issue currently blocking your project? (yes/no): no
  • is this issue affecting a production system? (yes/no): yes

Context

  • node version: 16.5.0
  • module version with issue: 17.4.2
  • last module version without issue: Never used it before, i don't know
  • environment (e.g. node, browser, native): browser
  • used with (e.g. hapi application, another framework, standalone, ...): react 17.0.2
  • any other relevant information:

What are you trying to achieve or the steps to reproduce?

I have a password and a password_confirmation fields that I want to validate as the user is typing, and this is the schema:

const schema = Joi.object({
// ...
password: Joi.string()
  .min(6)
  .max(15)
  .required()
  .label("Password")
  .messages({
	"string.base": "Invalid password",
	"string.min": "Password is too short (min {{#limit}})",
	"string.max": "Password is too long (max {{#limit}})",
	"string.empty": "Password is required",
	"any.required": "Password is required",
  }),
password_confirmation: Joi.string()
  .required()
  .equal(Joi.ref("password"))
  .label("Confirm password")
  .messages({
	"any.required": "Password confirmation is required",
	"string.empty": "Password confirmation is required",
	"any.only": "Password does not match",
  }),
});

const validationValues = {
	full_name: name,
	email: email,
	password: password,
	password_confirmation: passwordConfirmation,
};

Then for each field I do live validation such as:

<form onSubmit={handleSubmit}>

	// ...
	
	<input
		name="password"
		type="password"
		className="form-control form-control-lg"
		onChange={(event) => {
			// ...
			validateField(event.target);
		}}
	/>

	// ...

	<input
		name="password_confirmation"
		type="password"
		className="form-control form-control-lg"
		onChange={(event) => {
			//...
			validateField(event.target);
		}}
	/>

	// ...

	<button type="submit" className="btn btn-primary mt-2 mb-2">Register</button>
	
</form>

The password_confirmation should display an error if the two passwords don't match, and it works perfectly when I click the button to submit the entire form.

Here's the validation functions:

const validateForm = () => {
	const { error } = schema.validate(validationValues, schemaOptions);

	// ...
};

const validateField = ({ name, value }) => {
    const fieldValue = { [name]: value };
    const fieldSchema = Joi.object({ [name]: schema.extract(name) });
    const { error } = fieldSchema.validate(fieldValue);

    // ...
};

What was the result you got?

The problem is that it does not validate the field password_confirmation while i am typing. Even when I match the password field, the validation still returns a mismatch error.

What result did you expect?

When I type the same value in password_confirmation, this error should be null:

const { error } = fieldSchema.validate(fieldValue);

###Demo

  1. Go here: https://portaldev.northstarsystems.ca/register
  2. Enter aaaaaa in the password field
  3. Start typing a in password_confirmation
  4. The live validation starts working (it says "Password does not match")
  5. Enter the the same value aaaaaa
  6. The live validation stops working (still says "Password does not match" even if they do)
  7. Press the Register button
  8. The validation worked now, the error is gone

stesvis avatar Oct 29 '21 15:10 stesvis

If you are validating the field in complete isolation (your validateField function), it is indeed normal that it won't work, it cannot compare a field to another one that doesn't exist. Validating the whole form with abortEarly: false and only retaining the errors interesting to you is probably a better strategy.

Marsup avatar Oct 30 '21 14:10 Marsup

No activity, closing, feel free to reopen if there is more to discuss.

Marsup avatar Sep 12 '22 22:09 Marsup