I am beginner in Laravel. Currently I am learning this framework. My curent Laravel version is 5.3.
I am scaffolding my auth by using php artisan make:auth All are working fine. Also I configured gmail smtp in my .env file and mail.php in config directgory. All are perfectly working. But I saw by-default the forgot password email subject is going Reset Password. I want to change that.
I saw some blog. I found some blog. I have implement that in my site. But same output coming.
I followed these links -
https://laracasts.com/discuss/channels/general-discussion/laravel-5-password-reset-link-subject
https://laracasts.com/discuss/channels/general-discussion/reset-password-email-subject
https://laracasts.com/discuss/channels/laravel/how-to-override-message-in-sendresetlinkemail-in-forgotpasswordcontroller
You can change your password reset email subject, but it will need some extra work. First, you need to create your own implementation of ResetPassword notification.
Create a new notification class insideapp\Notifications directory, let's named it ResetPassword.php:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ResetPassword extends Notification
{
public $token;
public function __construct($token)
{
$this->token = $token;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Your Reset Password Subject Here')
->line('You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', url('password/reset', $this->token))
->line('If you did not request a password reset, no further action is required.');
}
}
You can also generate the notification template using artisan command:
php artisan make:notification ResetPassword
Or you can simply copy-paste the above code. As you may notice this notification class is pretty similar with the default Illuminate\Auth\Notifications\ResetPassword. You can actually just extend it from the default ResetPassword class.
The only difference is here, you add a new method call to define the email's subject:
return (new MailMessage)
->subject('Your Reset Password Subject Here')
You may read more about Mail Notifications here.
Secondly, on your app\User.php file, you need to override the default sendPasswordResetNotification() method defined by Illuminate\Auth\Passwords\CanResetPassword trait. Now you should use your own ResetPassword implementation:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\ResetPassword as ResetPasswordNotification;
class User extends Authenticatable
{
use Notifiable;
...
public function sendPasswordResetNotification($token)
{
// Your your own implementation.
$this->notify(new ResetPasswordNotification($token));
}
}
And now your reset password email subject should be updated!
Hope this help!
You may easily modify the notification class used to send the password reset link to the user. To get started, override the sendPasswordResetNotification method on your User model. Within this method, you may send the notification using any notification class you choose. The password reset $token is the first argument received by the method, See the Doc for Customization
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
Hope this helps!
In Laravel 5.7 the default implementation is similar to this:
return (new MailMessage)
->subject(Lang::getFromJson('Reset Password Notification'))
->line(Lang::getFromJson('You are receiving this email because we received a password reset request for your account.'))
->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', $this->token, false)))
->line(Lang::getFromJson('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.users.expire')]))
->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));
All you have to do is change your locale from config/app.php for example to ro, then in your resources/lang, create a file ro.json similar to this:
{
"Reset Password Notification": "Viața Medicală CMS :: Resetare parolă",
"Hello!": "Salut,",
"You are receiving this email because we received a password reset request for your account.": "Primești acest email deoarece am primit o solicitare de resetare a parolei pentru contul tău.",
"Reset Password": "Reseteză parola",
"This password reset link will expire in :count minutes.": "Acest link va expira în :count de minute.",
"If you did not request a password reset, no further action is required.": "Dacă nu ai solicitat resetarea parolei, nu este necesară nicio altă acțiune.",
"Regards": "Toate cele bune",
"Oh no": "O, nu",
"Whoops!": "Hopa!",
"If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser: [:actionURL](:actionURL)": "Dacă nu reușești să dai click pe butonul de \":actionText\", dă copy-paste la URL-ul de mai jos în browser:\n [:actionURL](:actionURL)"
}
It will translate both the subject (first key) and the mail body.
UPDATE for Laravel 6.*
This can be also used for VerifyEmail.php notification.
Laravel 8
In AuthServiceProvider.php
Add these code.
ResetPassword::toMailUsing(function ($notifiable, $url) {
return (new MailMessage)
->subject(Lang::get('Reset Password Notification'))
->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))
->action(Lang::get('Reset Password'), $url)
->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.' . config('auth.defaults.passwords') . '.expire')]))
->line(Lang::get('If you did not request a password reset, no further action is required.'));
});
To everyone asking how to update the Hello, Regards, and subcopy text:
php artisan vendor:publish (option 11)
then in views/vendor/notifications/email.blade.php
In this file there will be the text like Hello, wich you can change by changing:
for example:
line 9# #lang('Hallo!, Hei!, Bonjour!, Guten Tag!, Geia!')
You can create a custom function that will create the reset password token like this.
$user = User::where('email', 'example#name.com' )->first();
$password_broker = app(PasswordBroker::class); //so we can have dependency injection
$token = $password_broker->createToken($user); //create reset password token
$password_broker->emailResetLink($user, $token, function (Message $message) {
$message->subject('Custom Email title');
});//send email.
a note about this answer :
https://stackoverflow.com/a/40574428/9784378
you can copy vendor file functions and paste them into Resetpassword.php file
that you have created in notification folder .
Just add the line:
->subject('New Subjetc')
in the the method toMail of the file Illuminate\Auth\Notifications\ResetPassword
like this:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('New Subjetc')
->line('You are receiving this email because we received a password reset request for your account.')
->action('Restaurar Contraseña', url(config('app.url').route('password.reset', $this->token, false)))
->line('If you did not request a password reset, no further action is required.');
}
Related
In my AuthServiceProvider I was trying to add the users name to to email body. I tried the following method to accomplish that but it didn't work as expected.
When the page redirect to the verification page directly after registration it fails to get the auth user and results in an error. But when that page is closed and tried to login from the login page the it could get the auth()->user();
public function boot()
{
$this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) {
$user_name = Auth::user()->name;
return (new MailMessage)
->greeting("Hello {$user_name}!")
->subject('Verify Email Address')
->line('Please click the button below to verify your email address.')
->action('Verify Email Address', $url)
->line('If you did not create an account, no further action is required.');
});
}
Well, this can be achieved by using VerifyEmail::toMailUsing(). I used this function in my AuthServiceProvider. And the user's name can be accessed by using the $notifiable. This has all the information about the registered user.
public function boot()
{
$this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) {
return (new MailMessage)
->greeting("Hello {$notifiable->name}!")
->subject('Verify Email Address')
->line('Please click the button below to verify your email address.')
->action('Verify Email Address', $url)
->line('If you did not create an account, no further action is required.');
});
}
In my website firstly it was working and suddenly yesterday i got this bug where steps are as follows
request for reset password
when received mail click on reset password
I get following link to reset my password on reset password button http://sitename.com/password/reset/3f9674ddbe57a2f3f1b94495e9b1cc94593b7e0f861d92eb534739a47f2f2f34?email=vishal%40gmail.com
but clicking hitting that link used to get redirected to home page of the website with following url
https://sitename.com/index.php?email=vishal%40gamil.com
Resetpassword.php
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return (new MailMessage)
->subject(Lang::getFromJson('Password Password'))
->line(new HtmlString("<h1 style='text-align: center;'>Password Reset</h1>"))
->line(new HtmlString("<center>You have requestd a password reset <br /> Please click the button below to reset your password</center>"))
->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
->line(Lang::getFromJson('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));
}
reset_token_generator.php
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
why is this happening all of a sudden
i got the solution in .env file i just replace my website name with following
app_name= websitename.com to app_name= www.websitename.com
i didn't get what was the issue but this one worked for me
if someone knows the reason i will be glad to know that
The built-in controller for resetting the password Auth \ Reset Password Controller has the reset function
public function reset(Request $request)
{
$request->validate($this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
Well, here we are working with the user and their incoming data. However, I can't understand where the work with the password_resets table (built-in) is going? After all, after password recovery, entries are added/deleted there. I think (maybe incorrectly) that this is implemented in the broker () method, but I can't find it in the hierarchy of traits, interfaces, and other classes.
Checkout /vendor/laravel/framework/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php
This is the default class that implements the TokenRepositoryInterface and is used by the /vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.php.
Inside this class you can find all the actual functionality that handles the password resets including the table operations you mention. For example, one method you'll find is:
/**
* Create a new token record.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #return string
*/
public function create(CanResetPasswordContract $user)
{
$email = $user->getEmailForPasswordReset();
$this->deleteExisting($user);
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken();
$this->getTable()->insert($this->getPayload($email, $token));
return $token;
}
While doing a Password reset in laravel I have a need to also obtain the password the user enters on the password and confirm password fields , I need this because i have to post this to another api to update there password over there as well .
Can you please let me know how I can access this .
I have checked in controller's Auth ResetPasswordcontroller.php but i cannot figure out how to intercept and get the plain text password but still alow the normal password reset to occur.
You can simply override the reset() method from the ResetsPasswords trait within the controller.
ResetPasswordController.php
class ResetPasswordController extends Controller
{
use ResetsPasswords;
// ...
public function reset(Request $request)
{
// the code in this section is copied from ResetsPasswords#reset
$request->validate($this->rules(), $this->validationErrorMessages());
// --- put your custom code here ------------
$plaintext_password = $request->password;
// --- end custom code ----------------------
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
}
I generated a new email object through the artisan command to notify users about cumulative notifications. I succeeded using a custom template through the build method of the Email object:
public function build()
{
return $this->view('email.cumulative-notifications')
->with(['amount' => $this->amount])
->subject('You have some notifications!');
}
I want to use the template that is used for the reset password email which can be filled with lines and links like the ResetPassword does:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Reset Password')
->greeting('Hello!')
->line('...')
->action('Reset Password', url('password/reset', $this->token))
->line('...');
}
Should I use Notifications objects instead of Emails?