replace password reset mail template with custom template laravel 5.3 - laravel

I did the laravel command for authentication system , php artisan make:auth it made the authentication system for my app and almost everything is working.
Now when i use the forgot password and it sends me a token to my mail id , i see that the template contains laravel and some other things that i might wanna edit or ommit, to be precise , i want my custom template to be used there.
I looked up at the controllers and their source files but i can't find the template or the code that is displaying the html in the mail.
How do i do it ?
How do i change it?
This is the default template that comes from laravel to the mail.

Just a heads up: In addition to the previous answer, there are additional steps if you want to modify the notification lines like You are receiving this..., etc. Below is a step-by-step guide.
You'll need to override the default sendPasswordResetNotification method on your User model.
Why? Because the lines are pulled from Illuminate\Auth\Notifications\ResetPassword.php. Modifying it in the core will mean your changes are lost during an update of Laravel.
To do this, add the following to your your User model.
use App\Notifications\PasswordReset; // Or the location that you store your notifications (this is default).
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new PasswordReset($token));
}
Lastly, create that notification:
php artisan make:notification PasswordReset
And example of this notification's content:
/**
* The password reset token.
*
* #var string
*/
public $token;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('You are receiving this email because we received a password reset request for your account.') // Here are the lines you can safely override
->action('Reset Password', url('password/reset', $this->token))
->line('If you did not request a password reset, no further action is required.');
}

Run the following command in the terminal and the two email templates will be copied to your resources/vendor/notifications folder. Then you can modify the templates.
php artisan vendor:publish --tag=laravel-notifications
You can read more about Notifications in Laravel Docs.

If you wish to modify the mail template then check Laravel markdown, here you can change the default mail template:
if you do want to get HTML and be able to edit it, run this:
php artisan vendor:publish --tag=laravel-mail
This will happen:
Copied Directory
[/vendor/laravel/framework/src/Illuminate/Mail/resources/views] To
[/resources/views/vendor/mail]
Resource: https://laraveldaily.com/mail-notifications-customize-templates/

I ended up using Mail facade in User model..
public function sendPasswordResetNotification($token){
// $this->notify(new MyCustomResetPasswordNotification($token)); <--- remove this, use Mail instead like below
$data = [
$this->email
];
Mail::send('email.reset-password', [
'fullname' => $this->fullname,
'reset_url' => route('user.password.reset', ['token' => $token, 'email' => $this->email]),
], function($message) use($data){
$message->subject('Reset Password Request');
$message->to($data[0]);
});
}

in .env file or config/app.php file you have to change your app name and it's working fine.

You can also achieve this by building your own mail template and sending the Reset link yourself using the php mail() or or Laravel Mail Facade but first you will need to create the reset token
1) use Illuminate\Contracts\Auth\PasswordBroker;
$user = User::where('email', $email)->first();
if ($user) {
//so we can have dependency
$password_broker = app(PasswordBroker::class);
//create reset password token
$token = $password_broker->createToken($user);
DB::table('password_resets')->insert(['email' => $user->email, 'token' => $token, 'created_at' => new Carbon]);
//Send the reset token with your own template
//It can be like $link = url('/').'/password/reset/'.$token;
}

Related

Fortify - How to customise verification / password reset emails?

I'm in the process of implementing fortify into my app. I'm really confused about customising the default emails that are produced when you hit the password-reset / verifty-email routes?
I could edit them in vendor but that going to cause me an issue every time I update.
There must be a hook to provide an alternative email template.
Unfortnatly I cant find any documentation that explains how its done.
Do I need to add:
public function sendEmailVerificationNotification()
{
}
To my user model? If so how to I generate the return verificaiton URL as its not being held in the database?
Any help would be great.
Thanks!
Here is the solution in Laravel 8.
1.) Create a Notification by command
php artisan make:notification ResetPasswordNotification
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
class ResetPasswordNotification extends ResetPassword
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public $token;
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
$url = url(config('app.url') . route('password.reset', [
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
return (new MailMessage)
->view(
'emails.reset_password', ['name'=>$notifiable->name,'url' => $url]
)
->subject(Lang::get('Reset Password'));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
2.) In the app/Models/User.php Model. Add below method.
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
3.) Now create an email template in views/emails/reset_password.blade.php
Hi {{ $name }}, Please reset your password here. Click on the below link to reset the password.
RESET
You can customize the password reset email by adding the following in FortifyServiceProvider
ResetPassword::toMailUsing(function($user, string $token) {
return (new MailMessage)
->subject('Reset Password')
->view('emails.password_reset', [
'user' => $user,
'url' => sprintf('%s/users/password_reset/%s', config('app.url'), $token)
]);
});
Create a file named resources/views/emails/password_reset.blade.php, in this file you can use $user and $url
You can enter the directory when you use fortify vendor\laravel\framework\src\Illuminate\ Notifications\resources\views\email.blade.php and overwrite the content and style of the email.
Notifications are by default in the directory vendor\laravel\framework\src\Illuminate\Auth\Notifications\VerifyEmail.php
You can change the email text lines there. Similarly reset password in ResetPassword.php

SMTP: Change Message-ID domain in sending emails from Laravel 5.7 (Swift Mailer)

Laravel 5.7 sends emails using Swift Mailer.
By default, all sent emails will have the Message-ID header with the domain swift.generated (eg. Message-ID: <90b9835f38bb441bea134d3ac815dd6f#swift.generated>).
I would like to change the domain swift.generated to for example my-domain.com.
How can I change this for all emails?
Edit the file config/mail.php and define your domain near the end:
'domain' => 'yourdomain.com',
In the command line, create a new listener:
php artisan make:listener -e 'Illuminate\Mail\Events\MessageSending' MessageSendingListener
Edit the newly created listener and make it look as follows (do NOT implement ShouldQueue):
<?php
/**
* Set the domain part in the message-id generated by Swift Mailer
*/
namespace App\Listeners;
use Illuminate\Mail\Events\MessageSending;
use Swift_Mime_IdGenerator;
class MessageSendingListener
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param MessageSending $event
* #return void
*/
public function handle(MessageSending $event)
{
$event->message->setId((new Swift_Mime_IdGenerator(config('mail.domain')))->generateId());
}
}
Register the listener in app/Providers/EventServiceProvider:
protected $listen = [
// [...]
\Illuminate\Mail\Events\MessageSending::class => [
\App\Listeners\MessageSendingListener::class,
],
];
That's it, enjoy! :)
Just found a correct way to change #swift.generated in message ID.
Add this code to your AppServiceProvider->boot() method:
\Swift_DependencyContainer::getInstance()
->register('mime.idgenerator.idright')
->asValue(config('mail.domain'));
config('mail.domain') is a custom config entry so you can change it to whatever you want.
Tested in Laravel 6, maybe will work with 5.* versions too.
Also you can find many interesting configs in this file:
vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php

How to customize the email verification email from Laravel 5.7?

I just upgraded to Laravel 5.7 and now I am using the built in Email Verification. However there is 2 things I have not been able to figure out and the primary issue is how can I customize the email that is being sent to the user for verifying their email? I also can't figure out how to initiate sending that email if the users changes their email but I can save that for another thread.
When you want to add Email Verification in Laravel 5.7 the suggested method is to implement Illuminate\Contracts\Auth\MustVerifyEmail and use the Illuminate\Auth\MustVerifyEmail trait on the App\User Model.
To make some custom behaviour you can override the method sendEmailVerificationNotification which is the method that notifies the created user by calling the method notify, and passes as a parameter a new instance of the Notifications\MustVerifyEmail class.
You can create a custom Notification which will be passed as a parameter to the $this->notify() within the sendEmailVerificationNotification method in your User Model:
public function sendEmailVerificationNotification()
{
$this->notify(new App\Notifications\CustomVerifyEmail);
}
...then in your CustomVerifyEmail Notification you can define the way the verification will be handled. You can notify created user by sending an email with a custom verification.route which will take any parameters that you want.
Email verification notification process
When a new user signs-up an Illuminate\Auth\Events\Registered Event is emitted in the App\Http\Controllers\Auth\RegisterController and that Registered event has a listener called Illuminate\Auth\Listeners\SendEmailVerificationNotification which is registered in the App\Providers\EventServiceProvider:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
]
];
The SendEmailVerificationNotification listener checks if the $user – which is passed as a parameter to new Registered($user = $this->create($request->all())) in the Laravel default authentication App\Http\Controllers\Auth\RegisterController – is an instance of Illuminate\Contracts\Auth\MustVerifyEmail which is the name of the trait that Laravel suggests is used in the App\User Model when you want to provide default email verification and also check that $user is not already verified. If all that passes, the sendEmailVerificationNotification method is called on that user:
if ($event->user instanceof MustVerifyEmail && !$event->user->hasVerifiedEmail()) {
$event->user->sendEmailVerificationNotification();
}
I think the simple way to do this is to make a new notification using the docs here: https://laravel.com/docs/5.7/notifications#creating-notifications
Then override the function:
public function sendEmailVerificationNotification()
{
$this->notify(new App\Notifications\CustomEmailNotification);
}
In the users model.
Or you can
php artisan vendor:publish --tag=laravel-notifications
This will copy the templates to the resources/views/vendor/notifications directory and you can modify them there
Unfortunately this email that is sent out is not from a "view", it is a Notification that is built inline actually. This is where it is currently built when needing to be sent off: Illuminate\Auth\Notifications\VerifyEmail#toMail. This particular class has a static callback that can be set to build this email instead of letting it do it.
In a Service Provider in the boot method you will need to assign a callback for this class:
Something "like" this might work:
public function boot()
{
\Illuminate\Auth\Notifications\VerifyEmail::toMailUsing(function ($notifiable) {
// this is what is currently being done
// adjust for your needs
return (new \Illuminate\Notifications\Messages\MailMessage)
->subject(\Lang::getFromJson('Verify Email Address'))
->line(\Lang::getFromJson('Please click the button below to verify your email address.'))
->action(
\Lang::getFromJson('Verify Email Address'),
$this->verificationUrl($notifiable)
)
->line(\Lang::getFromJson('If you did not create an account, no further action is required.'));
});
}
As this is a notification you should have more options on customizing it.
If you want to use your own Notification class you can override the sendEmailVerificationNotification method on the User (Authenticatable) model (this is from the MustVerifyEmail trait).
Second Question:
The VerificationController (App\Http\Controllers\Auth\VerificationController) that you should have has a method named resend (from the trait VerifiesEmails) that looks like a good candidate for this purpose.
You should have routes setup for these verification routes via Auth::routes(['verify' => true]);
Note:
The verification system uses a field on the users table email_verified_at in 5.7 to mark this. You would want to make sure you have this field. When the user changes email address I suppose you could make this null then redirect them to the resend route, to send off the new verification. This will put them into an "unverified" state though until they reverify, if that is what you intend to happen.
Update:
Seems we were going down the right track. I found this SO answer that goes over similar things:
Changing the default “subject” field for the verification email in laravel 5.7
For quick and easy way:
php artisan vendor:publish --tag=laravel-notifications
It's creating a new file in:
\resources\views\vendor\notifications
This is Laravel's email themplate. You can change and customize it.
I'll show you how to customize User verification email using custom view from scratch without using any vendor publish
Step: 1
Create a new notification UserVerifyNotification class. It should extend the VerifyEmail class from the library Illuminate\Auth\Notifications\VerifyEmail;
Code :
use Illuminate\Auth\Notifications\VerifyEmail;
...
class UserVerifyNotification extends VerifyEmail implements ShouldQueue
{
use Queueable;
public $user; //you'll need this to address the user
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($user='')
{
$this->user = $user ?: Auth::user(); //if user is not supplied, get from session
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$actionUrl = $this->verificationUrl($notifiable); //verificationUrl required for the verification link
$actionText = 'Click here to verify your email';
return (new MailMessage)->subject('Verify your account')->view(
'emails.user-verify',
[
'user'=> $this->user,
'actionText' => $actionText,
'actionUrl' => $actionUrl,
]);
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
Step:2
Create the blade view for the email (user-verify.blade.php) inside resources\views\emails
<DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
</head>
<body>
<p>Dear {{$user->name}},</p>
<p>
Please click the button below to verify your email address.
</p>
{{$actionText}}
<p>If you did not create an account, no further action is required.</p>
<p>
Best regards, <br>
{{ config('app.name')}}
</p>
<p>
<hr>
<span class="break-all">
<strong>If you’re having trouble clicking the link, copy and paste the URL below into your web browser:</strong><br/>
<em>{{$actionUrl}}</em>
</p>
</body>
</html>
Step:3
Add the following method inside the User model
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable;
...
...
...
public function sendEmailVerificationNotification()
{
$this->notify(new \App\Notifications\UserVerifyNotification(Auth::user())); //pass the currently logged in user to the notification class
}
}
Explanation
When a new user is registered, the Registered event (Illuminate\Auth\Events) is called.
There is a listener inside EventServiceProvider (App\Providers\EventServiceProvider) that listens to the Registered event. 1. Once registration is completed, it calls SendEmailVerificationNotification method (Illuminate\Auth\Listeners\SendEmailVerificationNotification).
The listener (step-2) calls the sendEmailVerificationNotification() method from the library Illuminate\Auth\Listeners\SendEmailVerificationNotification
We now override the sendEmailVerificationNotification() function in Step: 3 and indicate that we would like to use our own notification class which we made earlier in Step: 1
The notification class gets the 'verification link' and calls the 'user-verify' blade to send email with the necessary link as defined in Step: 2
You'll need to add routes required for verification. Just add the following route in the web.php file
Auth::routes([
'verify' => true,
'register' => true,
]);
Building slightly on the answer by Andrew Earls, you can also publish all the markdown mail components used by the application with this command:
php artisan vendor:publish --tag=laravel-mail
Once that's done you'll have a series of html and markdown files to modify in resources/views/vendor/mail. This will allow you to modify the overall email layout and also 'theme' the CSS. I'd highly recommend having a good read of the Mail docs - Customizing The Components.
CSS theming
As a general email theming quick-start (Laravel 5.7), you can:
Publish the theme with php artisan vendor:publish --tag=laravel-mail .
Copy resources/views/vendor/mail/html/themes/default.css to your own file. e.g resources/views/vendor/mail/html/themes/wayne.css
Edit config/mail.php and where you see 'theme' => 'default' change it to 'theme' => 'wayne'
Edit wayne.css to restyle your emails.
Hope that helps someone.
To send verification email you can just use the next code:
// send new verification email to user
$user->sendEmailVerificationNotification();
In Route File
Auth::routes(['verify' => true]);
In AppServiceProvider.php File
namespace App\Providers;
use App\Mail\EmailVerification;
use Illuminate\Support\ServiceProvider;
use View;
use URL;
use Carbon\Carbon;
use Config;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
// Override the email notification for verifying email
VerifyEmail::toMailUsing(function ($notifiable){
$verifyUrl = URL::temporarySignedRoute('verification.verify',
\Illuminate\Support\Carbon::now()->addMinutes(\Illuminate\Support\Facades
\Config::get('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
]
);
return new EmailVerification($verifyUrl, $notifiable);
});
}
}
Now Create EmailVerification With Markdown
php artisan make:mail EmailVerification --markdown=emails.verify-email
Edit The EmailVerrification as you want and the blade file
class EmailVerification extends Mailable
{
use Queueable, SerializesModels;
public $verifyUrl;
protected $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($url,$user)
{
$this->verifyUrl = $url;
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$address = 'mymail#gmail.com';
$name = 'Name';
$subject = 'verify Email';
return $this->to($this->user)->subject($subject)->from($address, $name)->
markdown('emails.verify',['url' => $this->verifyUrl,'user' => $this->user]);
}
}
in the blade file change the design as you want and use verifyUrl to display the verification link and $user to display user information
thanks, happy coding :)
Navigate to these files
vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php
vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php
and then customize it.
you can even introduce a constructor in
vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php
and pass value through vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php
eg:

Laravel 5.3 Auth block user

I have a question, I'm currently developing a little site with Laravel 5.3 and I'm using the Basic Auth from them for users to register and login.
Now I want the following: Everybody can register and login, but if I click on a button (as an admin), I can "block" one specific user (for example if he did something not allowed), I don't completely delete the row in the database, but somehow make sure that if the user tries to login he get's a message saying something like "you can't login any more, your account is blocked, contact admin for more info" or something similar. The question is: Whats the best way to do this? I didn't find something built in, correct me if I'm wrong...
Ofcourse, I could just alter the users table and add a column called "blocked", set to false normally, then with the button, set it to true and then when logging in somehow checking for this value and (if it's true) showing this message and not allowing log in. Is this the best way to do this? If yes, where would I have to check for this value and how can I show the message then? If not, whats the better way?
I would do what you're suggesting - use a blocked or active column to indicate if the user should be able to log in. When I've done something similar in the past, to check this value upon login, I moved the out-of-the-box login function into my LoginController and added to it a bit. My login method now looks like this:
/**
* Handle a login request to the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
$user = User::where('email', $request->email)->firstOrFail();
if ( $user && !$user->active ) {
return $this->sendLockedAccountResponse($request);
}
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
I also added these functions to handle users who weren't active:
/**
* Get the locked account response instance.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
protected function sendLockedAccountResponse(Request $request)
{
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getLockedAccountMessage(),
]);
}
/**
* Get the locked account message.
*
* #return string
*/
protected function getLockedAccountMessage()
{
return Lang::has('auth.locked')
? Lang::get('auth.locked')
: 'Your account is inactive. Please contact the Support Desk for help.';
}
You can use soft deleting feature.
In addition to actually removing records from your database, Eloquent can also "soft delete" models. When models are soft deleted, they are not actually removed from your database. Instead, a deleted_at attribute is set on the model and inserted into the database. If a model has a non-null deleted_at value, the model has been soft deleted.
step1:
add new field to the User table called ‘status’ (1:enabled, 0:disabed)
step2:
to block the web login , in app/Http/Controllers/Auth/LoginController.php add the follwoing function:
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
$credentials = $request->only($this->username(), ‘password’);
return array_add($credentials, ‘status’, ‘1’);
}
Step3:
to block the user when using passport authentication ( token ) , in the User.php model add the following function :
public function findForPassport($identifier) {
return User::orWhere(‘email’, $identifier)->where(‘status’, 1)->first();
}
refer to this link ( tutorial) will help you : https://medium.com/#mshanak/solved-tutorial-laravel-5-3-disable-enable-block-user-login-web-passport-oauth-4bfb74b0c810
There is a package which not only blocks users but also lets you to monitor them before making a decision to block them or not.
Laravel Surveillance : https://github.com/neelkanthk/laravel-surveillance
Solved: this link ( tutorial) will help you : https://medium.com/#mshanak/solved-tutorial-laravel-5-3-disable-enable-block-user-login-web-passport-oauth-4bfb74b0c810
step1:
add new field to the User table called ‘status’ (1:enabled, 0:disabed)
step2:
to block the web login , in app/Http/Controllers/Auth/LoginController.php add the follwoing function:
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
$credentials = $request->only($this->username(), ‘password’);
return array_add($credentials, ‘status’, ‘1’);
}
Step3:
to block the user when using passport authentication ( token ) , in the User.php model add the following function :
public function findForPassport($identifier) {
return User::orWhere(‘email’, $identifier)->where(‘status’, 1)->first();
}
Done :)

Trying to reset Passwords in Lumen

I am trying to implement password reset feature in Lumen but could not succeed.
Lumen has access to things like Laravel's PasswordBroker and PasswordManager but I am not able to use this and succeed. Is there any solution for this.
I literally just figured this out last night and wrote a blog about it:
http://www.imjohnbon.com/password-resets-in-lumen/
Hopefully it can at least get you on the right track.
Ok, so I just got this working myself, with Lumen 5.6. (I've upgraded to 5.8, still works, no changes made).
These are the changes I had to make to my code. I had to tweak a few things to suit my system, but this might help someone else.
Routes
I wanted two routes.
Send reset password email
GET auth/resetpassword?email=fred#example.com
Reset Password
PUT auth/resetpassword?token=281...b&username=fred&password=banana&password_confirmation=banana
Composer
To send the user an email, the following Laravel packages are needed:
composer require illuminate/mail "^5.6"
composer require illuminate/notifications "^5.6"
Config files
Some extra config file are needed:
config/auth.php
config/mail.php
I just copied these over from Laravel 5.6, no changes made. I also added the mail variables into my .env file.
bootstrap/app.php
These new files need to be registered in the app:
$app->configure('auth');
$app->configure('mail');
$app->register(Illuminate\Notifications\NotificationServiceProvider::class);
$app->register(\Illuminate\Mail\MailServiceProvider::class);
$app->alias('mailer', \Illuminate\Contracts\Mail\Mailer::class);
$app->withFacades();
Database
I used the default Laravel password_resets table:
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
Now the real changes to the code.
Based on the code from Illuminate\Foundation\Auth\SendsPasswordResetEmails and Illuminate\Foundation\Auth\ResetsPasswords.
AuthController
use Illuminate\Auth\Passwords\PasswordBrokerManager;
use Illuminate\Support\Facades\Password;
use Laravel\Lumen\Routing\Controller;
use Illuminate\Http\Request;
class AuthController extends Controller
{
// 1. Send reset password email
public function generateResetToken(Request $request)
{
// Check email address is valid
$this->validate($request, ['email' => 'required|email']);
// Send password reset to the user with this email address
$response = $this->broker()->sendResetLink(
$request->only('email')
);
return $response == Password::RESET_LINK_SENT
? response()->json(true)
: response()->json(false);
}
// 2. Reset Password
public function resetPassword(Request $request)
{
// Check input is valid
$rules = [
'token' => 'required',
'username' => 'required|string',
'password' => 'required|confirmed|min:6',
];
$this->validate($request, $rules);
// Reset the password
$response = $this->broker()->reset(
$this->credentials($request),
function ($user, $password) {
$user->password = app('hash')->make($password);
$user->save();
}
);
return $response == Password::PASSWORD_RESET
? response()->json(true)
: response()->json(false);
}
/**
* Get the password reset credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(Request $request)
{
return $request->only('username', 'password', 'password_confirmation', 'token');
}
/**
* Get the broker to be used during password reset.
*
* #return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
$passwordBrokerManager = new PasswordBrokerManager(app());
return $passwordBrokerManager->broker();
}
}
User model
use Illuminate\Auth\Passwords\CanResetPassword as CanResetPasswordTrait;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordInterface;
use Illuminate\Notifications\Notifiable;
class User extends Model implements CanResetPasswordInterface
{
use CanResetPasswordTrait;
use Notifiable;
...
}

Resources