Password validation

default discord avatar
julesdj
11 months ago
11

Hello, I hope you’re having a fantastic day. Is there any way to access the password field for custom validation purposes ?

  • discord user avatar
    jmikrut
    Payload Team
    11 months ago

    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

    besides

    password



    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

  • default discord avatar
    julesdj
    11 months ago

    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.

  • default discord avatar
    kaspartr
    9 months ago

    Hi, is there any update on this topic?


    Is it possible to enforce password strength without creating custom auth strategy?

  • discord user avatar
    jmikrut
    Payload Team
    9 months ago

    I will add this as a feature request right now and tag it on the roadmap



    https://github.com/payloadcms/payload/discussions/1713
  • default discord avatar
    DU DA
    6 months ago

    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,...)

  • discord user avatar
    jarrod_not_jared
    Payload Team
    6 months ago

    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

  • default discord avatar
    kaspartr
    6 months ago

    How can one access password field of the document in the Collection hook?

  • discord user avatar
    jarrod_not_jared
    Payload Team
    6 months ago

    If the operation is create or update it will live on

    data
  • default discord avatar
    DU DA
    6 months ago

    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 }, ], },
  • discord user avatar
    jarrod_not_jared
    Payload Team
    6 months ago

    Yes exactly ⬆️

  • default discord avatar
    jamesryan
    2 months ago

    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;
        }
    };
Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.