In this case, the emails were being sent and reported being delivered but the user kept claiming they didn’t receive it, the obvious culprit of it going to spam/bulk mail. In the research process, it was discovered that we only sent an HTML password reset without any text fallback. Maybe that was the reason?
This seemed like a simple improvement and could at least rule out that as a possibility. However, now all the mail is handled inside the Illuminate components and I couldn’t find any documentation on how to send both.
At this point, I started digging to try and see how Laravel is sending the email. Inside PasswordBroker I found an emailResetLink method which is how it is actually sent:
$view <strong class="markup--strong markup--pre-strong">= </strong>$this<strong class="markup--strong markup--pre-strong">-></strong>emailView;
return $this->mailer->send($view,
Now it’s just a matter of figuring out where “$view” came from and I didn’t have to look far. Inside the constructor it is injected:
public function __construct(TokenRepositoryInterface $tokens,
UserProvider $users,
MailerContract $mailer,
$emailView)
Next question is, where is the instantiated? Doing a project search for the class name lead me to the registerPasswordBroker in the PasswordResetServiceProvider. This pulls in from the config file:
$view = $app[‘config’][‘auth.password.email’];
Opening config/auth.php shows how it’s defined by default:
'password' => [
'email' => 'emails.password',
Almost there. Going back to the mail documentation it shows you can send both with this call:
send(['html.view', 'text.view'], $data, $callback);
That means it’s just a matter of adjust the auth.password.email to be an array instead of the string:
'password' => [
'email' => ['emails.password', 'emails.text-password]',