Framework: How to override message in SendResetLinkEmail in ForgotPasswordController?

Created on 26 Jul 2016  路  2Comments  路  Source: laravel/framework

I am running a Dual Auth:Guard application.

in the frontend routes i use the standard auth() scaffold and install.

// routes/web.php
// using default middleware and guard
Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index');

The backend route has the following;

//  middleware 'web, auth:admin'

// Authentication Routes...
Route::group(['namespace' => 'Admin\Auth'], function (\Illuminate\Routing\Router $router) {

    // Login...
    $router->get('login', ['as'=>'admin.login', 'uses'=>'LoginController@showLoginForm']);
    $router->post('login', 'LoginController@login')->name('admin.login');
    $router->get('logout', ['as'=>'admin.logout', 'uses'=>'LoginController@logout']);

    // Registration Routes...
    if (config('cms.app.allow_admin_user_registration')) {
        $router->get('register', 'RegisterController@showRegistrationForm')->name('admin.register');
        $router->post('register', 'RegisterController@register');
    }

    // Password Reset Routes...
    $router->get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('admin.password.reset');
    $router->post('password/email', 'ForgotPasswordController@sendResetLinkEmail');
    $router->get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('admin.password.token');
    $router->post('password/reset', 'ResetPasswordController@reset');
});

I copied all App\Http\Controllers\Auth* into App\Http\Controllers\Admin\Auth\ and customized guards and brokers as per the documentation. Additionally i created all customized views inside its own backendauth path.... and... made all of the other configurations to support multiple auth guards.

Everything works! ..... Almost!

The password reset email link that is sent by the system only directs the user to the '/password/reset' path. which uses the default guard and default redirects. In order for admins to succefully reset their password the path needs to change to '/admin/password/reset' so that the link can use the correct auth guard and redirects as customized on those controllers.

There is a resetNotifier() method in the SendsPasswordResetEmails trait but there is no documentation as to how to use it. I understand that it can be overwritten in ForgotPasswordController.php but exactly what you do inside of resetNotifier() escapes me. Or, perhaps its not even related..

The actual email message is embedded in the following Notifications class which i think is pretty darn cool...

namespace Illuminate\Auth\Notifications;

use Illuminate\Notifications\Notification;

class ResetPassword extends Notification
{
    /**
     * The password reset token.
     *
     * @var string
     */
    public $token;

    /**
     * Create a notification instance.
     *
     * @param  string  $token
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the notification message.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\MessageBuilder
     */
    public function message($notifiable)
    {
        return $this->line('You are receiving this email because we received a password reset request for your account. Click the button below to reset your password:')
                    ->action('Reset Password', url('password/reset', $this->token).'?email='.urlencode($notifiable->email))
                    ->line('If you did not request a password reset, no further action is required.');
    }
}

I am looking for some guidance on this issue.

Thanks
Victor

Most helpful comment

Hi!

We have created a CRM package that implements password reset, the problem is that the notification of the project changes depending on where it is installed, and being a package, you can not overwrite the method:

public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}

It would not be much more versatile, if we had the possibility of sobrescrivir notification from ForgotPasswordController?

for example:

public function sendResetLinkEmail(Request $request)
{
    $this->validate($request, ['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.
    $response = $this->broker()->sendResetLink(
        $request->only('email'), $this->resetNotifier() 
    );

    switch ($response) {
        case Password::RESET_LINK_SENT:
            return response()->json([
                'success' => true
            ]);

        case Password::INVALID_USER:
        default:
            return response()->json([
                'success' => false,
                'message' => 'Invalid user'
            ]);
    }
}

// overwritte function resetNotifier() on trait SendsPasswordResetEmails
protected function resetNotifier()
{
    return function($token)
    {
        return new ResetPasswordNotification($token)
    }
}

Regards!

All 2 comments

Thanks for getting in touch. Feel free to discuss application specific questions on the forums, and I'm sure someone can help you there.

Hi!

We have created a CRM package that implements password reset, the problem is that the notification of the project changes depending on where it is installed, and being a package, you can not overwrite the method:

public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}

It would not be much more versatile, if we had the possibility of sobrescrivir notification from ForgotPasswordController?

for example:

public function sendResetLinkEmail(Request $request)
{
    $this->validate($request, ['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.
    $response = $this->broker()->sendResetLink(
        $request->only('email'), $this->resetNotifier() 
    );

    switch ($response) {
        case Password::RESET_LINK_SENT:
            return response()->json([
                'success' => true
            ]);

        case Password::INVALID_USER:
        default:
            return response()->json([
                'success' => false,
                'message' => 'Invalid user'
            ]);
    }
}

// overwritte function resetNotifier() on trait SendsPasswordResetEmails
protected function resetNotifier()
{
    return function($token)
    {
        return new ResetPasswordNotification($token)
    }
}

Regards!

Was this page helpful?
0 / 5 - 0 ratings