laravelpasswordsuser-experiencelaravel-breeze

How do I customize Laravel Breeze's message about a password being compromised?


Edit: This issue should be solved in Laravel 10.33 and up. Refer to the comment below for more information.

I'm working on an app using Laravel Breeze. When I try to create an unsafe password (something that has been leaked/pwned such as Password1!), I receive this validation error message:

The given password has appeared in a data leak. Please choose a different password.

From my standpoint, the message is pretty straightforward, but from an end-user standpoint, I'm afraid it is not so clear. Indeed, the end-user reading this message might wonder if the data was leaked on the site I'm working on and feel like the site being visited isn't safe when this actually is extra safety being provided. This is why I want to customize my message for something like this:

The given password was part of a leak at some point on the Web. As a security measure, we have blocked its use on this site.

Technologies:

What I have tried so far in my RegisteredUserController

    public function store(Request $request): RedirectResponse
    {
        $rules = [
            [other rules],
            'password'      => ['required', 'confirmed', Password::min(8)->mixedCase()->letters()->numbers()->symbols()->uncompromised()],
        ];

        $messages = [
            'password.uncompromised' => 'The given password was part of a leak at some point on the Web. As a security measure, we have blocked its use on this site.',
        ];

        $this->validate($request, $rules, $messages);

        Auth::login($user = User::create([
            [other stuff]
            'password'      => Hash::make($request->password),
        ]));

        event(new Registered($user));

        Auth::login($user);

        (new MyController)->store($request);

        return redirect()->route('register_step_2');
    }

What happens when I use the code above

When I use the code provided above, the default error message is what gets passed to the user interface, not my custom message.


Solution

  • This is seems to be the case for not only uncompromised() but all the remaining built-in methods of the custom rules object (used in Password.php) and the documentation does not cover this case at all.

    The only workaround I found so far for these built-in methods is to run php artisan lang:publish. You will then see a lang/ directory added to the root of your application where you can locate the key in the associative array of the validation.php file and change its value to whatever you want:

    enter image description here

    And here a short piece of code I used in RegisteredUserController.php:

    public function store(Request $request): RedirectResponse
        {
            $messages = [
                // For non built-in methods, this works as mentioned in the documentation
                'name.required' => 'We need your name',
            ];
            $rules = [
                'name' => ['required', 'string'],
                'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
                'password' => ['required', 'confirmed', Password::min(5)->uncompromised()]
            ];
            $request->validate($rules, $messages);
            // The rest of code      
        }
    

    And here is the result of the above code and changes:

    enter image description here