I have a register user form built in react and nextjs. I have applied regex patterns to the password field and set up custom validation using bootstrap. The confirm password pattern is simply set to the value coming from the password field which is updated onChange.
For the most part it works as intended. When the passwords match, it validates correctly. When they don't match, it gives appropriate feedback to the user. However, when there is any of the following symbols...
?*(){}[]/
...in the password entered, the confirm password will validate before I have even entered the entire password. For example:
PASSWORD: Password123*
CONFIRM: Password12
Below is the code for the form:
const Register = () => {
const [validated, setValidated] = useState(false);
const [values, setValues] = useState({
username:"",
email:"",
password:"",
confirmPassword:"",
});
const inputs = [
{
id: 1,
name:"username",
type:"text",
errorMessage:"Username should be 3-16 characters long, and should not include special characters.",
label:"Username",
pattern:"^[A-Za-z0-9]{3,16}$",
required: true,
},
{
id: 2,
name:"email",
type:"email",
errorMessage:"Please use a valid email address.",
label:"Email",
required: true,
},
{
id: 3,
name:"password",
type:"password",
errorMessage:"Password should be minimum 8 characters comprised of upper-case, lower-case, and numerals.",
label:"Password",
pattern:"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$",
required: true,
},
{
id: 4,
name:"confirmPassword",
type:"password",
errorMessage:"Passwords do not match.",
label:"Confirm Password",
pattern: values.password,
required: true,
},
];
const handleSubmit = (event) => {
const form = event.currentTarget;
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
setValidated(true);
};
const onChange = (e)=>{
setValues({...values, [e.target.name]: e.target.value });
};
return (
<Form noValidate validated={validated} onSubmit={handleSubmit} className="needs-validation">
{inputs.map((input) => (
<FormInput key={input.id} {...input} value={values[input.name]} onChange={onChange} />
))}
<div className="d-grid"><hr/>
<Button className="btn-custom" type="submit">
Register
</Button>
</div>
</Form>
)
};
export default Register;
... and in case its relevant, here is the FormInput component:
export default function FormInput(props) {
const { label, errorMessage, onChange, id, ...inputProps } = props;
return (
<Form.Group className="mb-3">
<FloatingLabel label={label} className="mb-3">
<Form.Control {...inputProps} onChange={onChange} className="form-input" />
<Form.Control.Feedback type="invalid">
{errorMessage}
</Form.Control.Feedback>
</FloatingLabel>
</Form.Group>
)
}
Is there something I am missing that would explain why this is happening? Or is there a fix I can apply? My guess is that these symbols are escaping the input in some way but I have no idea how to ensure they remain superficial only. I really do not want to simply bar the user from using certain symbols in their password. React and js beginner here.