Reputation: 1253
import * as Yup from 'yup';
import User from '../models/User';
class UserController {
async store(req, res) {
const schema = Yup.object().shape({
name: Yup.string().required(),
email: Yup.string()
.email()
.required(),
password: Yup.string()
.required()
.min(6),
});
if (!(await schema.isValid(req.body))) {
return res.status(400).json({ error: 'Validation fails' });
}
const userExists = await User.findOne({ where: { email: req.body.email } });
if (userExists) {
return res.status(400).json({ error: 'User already exists.' });
}
const { id, name, email, provider } = await User.create(req.body);
return res.json({ id, name, email, provider });
}
async update(req, res) {
const schema = Yup.object().shape({
name: Yup.string(),
email: Yup.string().email(),
oldPassword: Yup.string().min(6),
password: Yup.string()
.min(6)
.when('oldPassword', (oldPassword, field) =>
oldPassword ? field.required() : field
),
confirmPassword: Yup.string().when('password', (password, field) =>
password ? field.required().oneOf([Yup.ref('password')]) : field
),
});
if (!(await schema.isValid(req.body))) {
return res.status(400).json({ error: 'Validation fails' });
}
const { email, oldPassword } = req.body;
const user = await User.findByPk(req.userId);
if (user.email !== email) {
const userExists = await User.findOne({
where: { email },
});
if (userExists) {
return res.status(400).json({ error: 'User already exists.' });
}
}
if (oldPassword && !(await user.checkPassword(oldPassword))) {
return res.status(401).json({ error: 'Password does not match.' });
}
const { id, name, provider } = await user.update(req.body);
return res.json({ id, name, email, provider });
}
}
export default new UserController();
Here it creates a normal user with the password 123456:
Here it should work, since the old password is the same as the password of the created user, and it should update the new password:
I want to try to understand how to make him understand the current password as oldpassword and update the password.
Upvotes: 114
Views: 129948
Reputation: 183
Yup.object({
password: Yup.string().required('Password is required'),
passwordConfirmation: Yup.string()
yup.string().when('password', ([password], schema, options) => {
if (password!= '') {
// if the password filled but passwordConfirmation not then return
required message
if (options.value == '') {
return schema.required();
} else {
// if the password filled and passwordConfirmation then return mismatch
message
return schema.oneOf([password], 'validations.mismatch');
}
} else {
return schema;
}
})
})
Upvotes: 0
Reputation: 420
Based on Harshal's answer above, but the API is a little different.
import * as Yup from 'yup';
validationSchema: Yup.object({
password: Yup.string().required('Password is required'),
passwordConfirmation: Yup.string()
.oneOf([Yup.ref('password'), undefined], 'Passwords must match')
});
Notice it's undefined
instead of null
.
Alternatively you can skip the undefined
all together:
import * as Yup from 'yup';
validationSchema: Yup.object({
password: Yup.string().required('Password is required'),
passwordConfirmation: Yup.string()
.oneOf([Yup.ref('password')], 'Passwords must match')
});
Upvotes: 1
Reputation: 59
It seems in the latest version of Yup. Yup ^1.0.0
You no longer need to pass null
as the second argument to yup.ref
where the options arguments go: docs.
Here's how I would test the confirm password:
import * as Yup from 'yup';
validationSchema: Yup.object({
password: Yup.string().required('Password is required').matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*[\]{}()?"\\,><':;|_~`=+-])[a-zA-Z\d!@#$%^&*[\]{}()?"\\,><':;|_~`=+-]{12,99}$/,
'Must contain at least 12 Characters, 1 Uppercase, 1 Lowercase, 1 Special Character, and 1 Number'
),
passwordConfirmation: Yup.string()
.oneOf([Yup.ref('password')], 'Passwords must match')
});
Note: I have added an extra .matches()
regex in to the solution as for security most sites use some form of password validation.
Upvotes: 0
Reputation: 1274
This is how I did it.
yup.object({
password: yup
.string()
.required('Please enter your password.')
.min(8, 'Your password is too short.'),
retypePassword: yup
.string()
.required('Please retype your password.')
.oneOf([yup.ref('password')], 'Your passwords do not match.')
});
Upvotes: 39
Reputation: 1225
Based on @anoNewb answer and the request made by @Renan,
Yup.object({
password: Yup.string().required('Password is required'),
passwordConfirmation: Yup.string()
.test('passwords-match', 'Passwords must match', function(value){
return this.parent.password === value
})
})
Upvotes: 89
Reputation: 8308
Try this out:
import * as Yup from 'yup';
validationSchema: Yup.object({
password: Yup.string().required('Password is required'),
passwordConfirmation: Yup.string()
.oneOf([Yup.ref('password'), null], 'Passwords must match')
});
Upvotes: 282