0

I am working on laravel5.2 project, i am using laravel's default auth module, which also provides us the reset password functionality.

I am facing issue in case if user is registered with

abcd@gmail.com

and if user enter email to reset password is

Abcd@gmail.com

In case of this it throws error account with this email doesn't exists.

As we can see both emails are same but just because of capitalization for first letter in second email it is throwing error.

How to make this functionality case insensitive?

Dovydas Šopa
  • 2,282
  • 8
  • 26
  • 34
Pankaj Sharma
  • 33
  • 2
  • 10

4 Answers4

3

Add this function in ForgotPasswordController.php to override the default functionality.

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Password;

    public function sendResetLinkEmail(Request $request)
    {
        $this->validateEmail($request);

        $data['email'] = strtolower($request->email);
        $response = $this->broker()->sendResetLink($data);

        return $response == Password::RESET_LINK_SENT
                ? $this->sendResetLinkResponse($response)
                : $this->sendResetLinkFailedResponse($request, $response);
    }
Ankit24007
  • 848
  • 9
  • 19
0

Path of the file where searching email is Illuminate\Foundation\Auth\ResetsPasswords. But you don't want to edit this file. This file contain a php trait that use in PasswordController class. So you can change the functionality of the trait methods by overriding it.

postEmail is the methods to be overwritten that find the user with given email and send reset link. Find the user by email case insensitively using ilike. Then overwrite request email variable by exact user email.

Following is to be the code in your PasswordController class (App\Http\Controllers\Auth\PasswordController)

public function postEmail(Request $request) {

    $this->validate($request, ['email' => 'required|email']);

    //Find the user by email case insensitively using ilike
    $user = User::where('email', 'ilike', $request->email)->first();

    // Overwrite request email variable by exact user email
    $request->email = $user->email;

    $response = Password::sendResetLink($request->only('email'), function (Message $message) {
                $message->subject($this->getEmailSubject());
            });

    switch ($response) {
        case Password::RESET_LINK_SENT:
            return redirect()->back()->with('status', trans($response));
        case Password::INVALID_USER:
            return redirect()->back()->withErrors(['email' => trans($response)]);
    }
}
Dinoop
  • 479
  • 4
  • 10
0

It all comes down to Collation.

I also ran in to this problem recently on an older site using Laravel 5.2. It turns out that changing the collation of the email column in the database from utf8mb4_bin to utf8mb4_unicode_ci solved it.

Apparently, the MySQL adapter does use LIKE when making the query, but that only returns the case-insensitive result if the column collation is allowing it to. Mine wasn't.

There is more discussion on the topic of MySQL collation and case sensitivity on this Stack Overflow question: MySQL case insensitive select as well as in the official MySQL documentation.

James Sheils
  • 276
  • 3
  • 7
0

In case you have stored your emails lowercased in the database, just redefine the credentials function in ForgotPasswordController.php:

protected function credentials(\Illuminate\Http\Request $request)
{
    $data = $request->only('email');
    $data['email'] = mb_strtolower($data['email']);
    return $data;
}
David Vielhuber
  • 3,253
  • 3
  • 29
  • 34