Failing to send password reset emails while email column in database is encrypted (Laravel 8)

Viewed 345

I haven't found a solution for this problem yet: failing to send password reset emails while email column in database is encrypted (Laravel 8.57.0 with JetStream, Fortify, Livewire). I have browsed some other Q&A but they are mostly for Laravel 5 and I'm afraid they are not fully compatible.

Here we go:

Some columns in Users table are encrypted using betterapp/laravel-db-encrypter (https://github.com/betterapp/laravel-db-encrypter) - including email column. There's a separate username field for login (for safety reasons mostly).

Fortify routes are disabled and I maintain them on my routes/web.php.

config/auth.php file has

'username' => 'username',
'email' => 'email'

Reset password view leads to PasswordResetLinkController in Laravel\Fortify\Http\Controllers, which has function:

public function store(Request $request): Responsable
    {
        $request->validate([Fortify::email() => 'required|email']);

        // We will send the password reset link to this user. Once we have attempted
        // to send the link, we will examine the response then see the message we
        // need to show to the user. Finally, we'll send out a proper response.
        $status = $this->broker()->sendResetLink(
            $request->only(Fortify::email())
        );
        dd($status);  // -> "passwords.user"

        return $status == Password::RESET_LINK_SENT
                    ? app(SuccessfulPasswordResetLinkRequestResponse::class, ['status' => $status])
                    : app(FailedPasswordResetLinkRequestResponse::class, ['status' => $status]);
    }
/**
 * Get the broker to be used during password reset.
 *
 * @return \Illuminate\Contracts\Auth\PasswordBroker
 */
protected function broker(): PasswordBroker
{
    return Password::broker(config('fortify.passwords'));
}

(Fortify::email() fetches the setting in config/fortify -> 'email'.)

sendResetLink() function lives in an PasswordBroker-interface:

<?php

    namespace Illuminate\Contracts\Auth;

    use Closure;

    interface PasswordBroker
    {
/**
 * Constant representing a successfully sent reminder.
 *
 * @var string
 */
const RESET_LINK_SENT = 'passwords.sent';

/**
 * Constant representing a successfully reset password.
 *
 * @var string
 */
const PASSWORD_RESET = 'passwords.reset';

/**
 * Constant representing the user not found response.
 *
 * @var string
 */
const INVALID_USER = 'passwords.user';

/**
 * Constant representing an invalid token.
 *
 * @var string
 */
const INVALID_TOKEN = 'passwords.token';

/**
 * Constant representing a throttled reset attempt.
 *
 * @var string
 */
const RESET_THROTTLED = 'passwords.throttled';

/**
 * Send a password reset link to a user.
 *
 * @param  array  $credentials
 * @param  \Closure|null  $callback
 * @return string
 */
public function sendResetLink(array $credentials, Closure $callback = null);

/**
 * Reset the password for the given token.
 *
 * @param  array  $credentials
 * @param  \Closure  $callback
 * @return mixed
 */
public function reset(array $credentials, Closure $callback);

This one: public function sendResetLink(array $credentials, Closure $callback = null);

That function receives credentials *), but is unable to retrieve the correct email since it is encrypted in the database. That function gives me a result "passwords.user" [checked with dd($status);] which refers to translation file at resources/lang/en/passwords -> 'user' => "We can't find a user with that email address." and throws back at resetlinkpage with that error.

Password reset works great if I just drop the encryption from email column.

Thoughts and questions:

*) What credentials? The email in this case? Can I change it to something else, e.g. the username if I retrieved it first with the email address? Am I missing something?

How can I go around this or should I just drop this case and change my setup back to non-encrypted email column? Is there any use to create another column with hashed email and compare to that first?

I'm stuck. I need other pairs of eyes and more brains. Please, help!

0 Answers
Related