Hello, I hope you’re having a fantastic day. Is there any way to access the password field for custom validation purposes ?
Yes! You can pass in your own password field directly into your auth-enabled config, and whatever you define on it (including custom validate function) will be merged into the default password field
just make sure you have it named appropriately
hmm wait i may have spoken too soon. that works for any other field
besidespassword
it looks like right now this is not possible, but it would be a great feature to add
and a simple PR to make if you were interested in contributing
I could help document the work necessary to implement it and then you could make it happen if you were up for it. Otherwise we can get to it at some point - just not sure when
Thanks for the response, I really appreciate the work you guys are doing here. Whenever you have the time please do document the work necessary. I will be happy to help implement it.
Hi, is there any update on this topic?
Is it possible to enforce password strength without creating custom auth strategy?
I will add this as a feature request right now and tag it on the roadmap
https://github.com/payloadcms/payload/discussions/1713
Are there any news to this topic? I need to validate my password (min. length, has to include at least one number, one special character,...)
In the meantime you could validate the password field with a beforeValidate hook on the collection. Throw an error if it does not meet your requirements
How can one access password field of the document in the Collection hook?
If the operation is create or update it will live on
data
We created a workaround:
hooks: {
beforeOperation: [
({args, operation}) => {
if ((operation == 'update' || operation == 'create') && args?.data.password) {
const {password} = args?.data
const passwordLength = 18
// check if the password is at least X chars long and contains 3 of 4 conditions:
// lowercase / uppercase / digit / sepcial character
const regexString =
^((?=.
[a-z])(?=.[A-Z])(?=.
\d)|(?=.[a-z])(?=.
\d)(?=.[\W
])|(?=.[a-z])(?=.[A-Z])(?=.*[\W])|(?=.
[A-Z])(?=.\d)(?=.*[\W_])).{${passwordLength},}$
const regex = new RegExp(regexString)
const isValid = regex.test(password)
if (!isValid) {
throw new APIError('Error Message', httpStatus.BAD_REQUEST)
}
}
return args
},
],
},
Yes exactly ⬆️
For anyone else visiting this thread
I found that upon enacting the password validation -> previously "in-secure" password users could no longer log in so because we're unable to access the req.url within a
beforeOperation
hook I tested to see if the
req.user
is populated ( would be upon login )
export const checkPasswordStrength: BeforeOperationHook = ({ args, operation }) => {
if ((operation === 'update' || operation === 'create') && args?.data.password && args?.req.user !== undefined) {
const { password } = args?.data;
const errors: string[] = [];
if (password && password.length <= 15) {
errors.push('Password must be at least 15 characters long');
}
const upperCaseMatches = (password.match(/[A-Z]/g) || []).length;
const lowerCaseMatches = (password.match(/[a-z]/g) || []).length;
const hasNumber = /\d/.test(password);
const hasSymbols = /[$-/:-?{-~!"^_`\[\]]/.test(password);
if (upperCaseMatches < 2) {
errors.push('Password must have at least two uppercase letters');
}
if (lowerCaseMatches < 2) {
errors.push('Password must have at least two lowercase letters');
}
if (!hasNumber) {
errors.push('Password must include at least one number');
}
if (!hasSymbols) {
errors.push('Password must include at least one symbol');
}
if (errors.length > 1) {
const errorMessage = `Your password is not secure: ${errors.join(', ')}`;
throw Error(errorMessage);
} else if (errors.length === 1) {
throw Error(errors[0]);
}
return args;
}
};
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.