Status Message After Password Reset - laravel

All this code works just fine except when the password is updated. I am not getting the status message that password is updated once Auth::logout() is fired and returned to the login screen. It does change the password but no message. If there is an error, it returns back and displays a sweetalert message that passwords do not match.
Controller
public function UserUpdatePassword(Request $request)
{
$validateData = $request->validate([
'oldpassword' => 'required',
'password' => 'required|confirmed',
]);
$hashedPassword = Auth::user()->password;
if(Hash::check($request->oldpassword,$hashedPassword)){
$user = User::find(Auth::id());
$user->password = Hash::make($request->password);
$user->save();
Auth::logout();
return redirect()->route('user.logout')->with('status','Password Updated Successfully');
} else{
Alert::warning('Password Mismatch','Current Password Error or Password Confirm Do Not Match');
return redirect()->back();
}
}
on login screen
#if (session('status'))
<div class="alert" role="alert" style="background-color:#C5ECEB;">
{{ session('status') }}
</div>
#endif

Your
Auth::logout();
is before showing the status;
So If you want to show the status message, just comment logout line as follows:
$user = User::find(Auth::id());
$user->password = Hash::make($request->password);
$user->save();
return redirect()->route('user.logout')->with('status','Password Updated Successfully');

Put \Session::put('status','Password Updated Successfully');
before Auth::logout();

Related

Store the login details in session in laravel

I have a function in controller checklogin() which checks the user details. I want to store into session. So I can get the name of the user and display in blade view
Controller
public function checklogin(Request $request)
{
$req=$request->validate([
'name'=>'required',
'email'=>'required|email',
'password'=>'required|regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[#_!]){8,}/'
]);
$userdata = array(
'name' => $request->input('name') ,
'email'=>$request->input('email'),
'password' => $request->input('password')
);
if (Auth::attempt($userdata))
{
$data = $request->session()->put('user',$userdata['name']);
dd($data) ; //returning null
return redirect('/home');
}
else
{
return back()->with('error', 'Wrong Login Details');
}
}
No need to store logged in user detail in session.You can call auth helper function which will return auth instance.
{{auth()->user()->name}}
if you have both logged in or guest page same then you can do null check
{{ auth()->user()!=null?auth()->user()->name:null }}

How To Display Laravel Breeze Status Message

I'm using Laravel Breeze for authentication, and I'm facing a problem:
When user request a password reset link, I like to show him/her a success message, if we send email successfully. PasswordResetLinkController returns this:
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
When it goes back, it goes, for example, to home route. HomeController returns home.blade.php. When I try to display $status, which should be passed by PasswordResetLinkController, I got undefiened variable error. How can I get that message?
EDIT
PasswordResetLinkController.php
// This is the original store function came with Breeze.
// I did touch neither code nor the comments.
public function store(Request $request)
{
$request->validate([
'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 = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
HomeController.php
public function index()
{
$baseData = $this->baseData();
$asset = $this->pickAssetRandom();
$publishings = $this->paginate($this->getPublishings, 12);
return view('pages.home', compact('publishings', 'baseData', 'asset'));
}
The $status is being set in the PasswordResetLinkController.
Specifically:
back()->with('status', __($status))
So, as you can see, it is returning the previous page and passing in status.
However, if $status == Password::RESET_LINK_SENT is false, then $status is not set, but the $errors['email'] is. You can see this on the ternary condition in your code.
Try:
dd($status == Password::REST_LINK_SENT);
before the return statement on the controller, if you get false then there will be no $status, and you will get the undefiened variable error.
You can account for this in your view:
#if ($status)
{{ $status }} // A link was sent
#endif
// no link sent and here are the errors.
#if ($errors->any())
#foreach ($errors->all() as $error)
{{ $error }}
#endforeach
#endif
Laravel docs on this: https://laravel.com/docs/8.x/passwords#resetting-the-password
Treat that status as a session and it will work
#if (session('status'))
<span class="alert alert-success">{{ session('status') ?? ''}} </span>
#endif

Route for resetting password in Laravel 7

I am using the custom password reset option in Laravel 7. When the user clicks the reset password button (in the inbox of her/his email), the user is redirected to the password reset link. Here is my link
http://localhost/LaraTest/public/reset/5199667639cfc4f5ea624f4c18dbf7e8-vJcnLSH92vAj1IlnV3j7phT8zBtcbX0gSDbjXX37oFsuEM560oAiehZ4oVd0?email=basish%40gmail.com
Here is the code which generates the link
$token1= md5($fp_email);
$token2 = Str::random(60);
$fp_token = $token1."-".$token2;
//some more codes here
$link = 'localhost/LaraTest/public/reset/' . $fp_token . '?email=' . urlencode($fp_email);
//$link is sent to user as email
Route (after some research)
Route::get('reset/{tokenname}{email}','LoginController#resetpassword');
Controller
public function resetpassword(Request $request){
return view('resetpassword');
}
How would I define my route? I am a bit confused as my link contains
both the password reset token and the email id.
How will I retrieve the password reset token and the email id from the link above,after being redirected to the new password form?
Your route should be:
Route::get('reset/{tokenname}','LoginController#resetpassword');
In then the actual handler:
public function resetpassword(Request $request, $token){
$email = $request->email;
return view('resetpassword', compact('token', 'email');
}
Then in your view you can have:
<input type="hidden" name="email" value="{{$email}}" />
<input type="hidden" name="token" value="{{$token}}" />
and your actual password reset handler this would probably be defined in a route like:
Route::post('reset', 'LoginController#doPasswordReset');
and the method body would be (code borrowed in some part from the laravel source):
public function doPasswordReset(Request $request){
$validatedRequest = $request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed|min:8',
]);
$email = $request->email;
$token = $request->token;
$broker = app(PasswordBrokerManager::class);
$response = $broker()->reset(
$validatedRequest, function ($user, $password) {
// save new password here
}
);
return $response == Password::PASSWORD_RESET
? // Reset response?
: // Reset failed response?
}
This will ensure Laravel can verify the user by the provided email and password before doing the actual password reset.

Authorise a user with Laravel Passport when testing RESTful controllers update method

Every time I run the test, I'm getting a 403 response status, what am I doing wrong in here?
I have tried to remove Passport authorization from the test, but then I'm getting a redirect to a login page, 302 status response.
//PostTest:
public function test_can_update_post()
{
//creating a user
$user = factory(User::class)->create();
//creating an author for post
$author = factory(Author::class)->create([
'user_id' => $user->id,
]);
//creating a post
$post = factory(Post::class)->create([
'author_id' => $author->id,
]);
$data = [
'title' => $this->faker->title,
'content' => $this->faker->paragraph,
];
//authorizing user
//I have tried to remove this line, then I'm gettig a redirect to login page 302
$user = Passport::actingAs($user);
$this->actingAs($user)
->patch(route('posts.update', $post->id), $data)
->assertStatus(200);// why I'm getting 403???
}
//API route:
Route::patch('posts/{post}')
->uses('PostController#update')
->middleware('auth:api')
->name('posts.update');
//PostController update method:
public function update(PostUpdateRequest $request, Post $post)
{
$this->authorize('update', $post);
$post->title = $request->input('title');
$post->content = $request->input('content');
$post->save();
return new PostResource($post);
}
//PostPolocy
public function update(User $user, Post $post)
{
return Author::where('user_id', $user->id)->first()->id === $post->author_id;
}
I expect response status 200
I have changed the line in PostPolicy update method to:
if(!$user->author) {
return false;
}
return $user->author->id == $post->author_id;
This worked for me.

How to change password in laravel-4 with auth

I am using laravel-4 auth component . I want to make a function which will change user password . I have my view as follows :
password - Text-box ;
new_password - Text-box;
confirm_new_password - Text-box
I also have checked manual for password reset , but in that doc(http://laravel.com/docs/security#password-reminders-and-reset) they are sending mail for password reset .
View is as follows :
#extends('layouts.main')
#section('title') Change Password
#stop
#section('content')
{{ Form::open(array('url'=>'users/user-password-change', 'class'=>'block small center login')) }}
<h3 class="">Change Password</h3>
<h6>Please change your password below.</h6>
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
{{ Form::password('password', array('class'=>'input-block-level', 'placeholder'=>'Old Password')) }}
{{ Form::password('new_password', array('class'=>'input-block-level', 'placeholder'=>'New Password')) }}
{{ Form::password('confirm_new_password', array('class'=>'input-block-level', 'placeholder'=>'Confirm New Password')) }}
{{ Form::submit('Register', array('class'=>'k-button'))}}
{{ Form::close() }}
#stop
Controller code is as follows :
public function postUserPasswordChange(){
$validator = Validator::make(Input::all(), User::$change_password_rules);
if($validator->passes()){
$user=new UserEventbot;
$user->password=Hash::make(Input::get('new_password'));
$user->save();
return Redirect::to('users/change-password');
}else {
return Redirect::to('users/change-password')->with('message', 'The following errors occurred')->withErrors($validator)->withInput();
}
}
Please help me on this , how to first match this password with database table users , and then the whole process .
Thank you .
To match current user password with password in database you can do something like this,
// retrieve the authenticated user
$user = Auth::user();
Retrieve the current password specified by the user inside the form,
$current_password = Input::get('current_password');
We can see if the current password has bee specified and check against the hashed password as follows,
if (strlen($current_password) > 0 && !Hash::check($current_password, $user->password)) {
return Redirect::to('/user/edit-profile')->withErrors('Please specify the good current password');
}
Important thing to note here is the function
Hash::check(CURRENT_PASSWORD_ENTERED_IN_FORM, HASHED_VERSION_OF_PASSWORD_STORED_IN_AUTH_USER)
Finally, if it's all good you can update the current user password inside Auth and in database as follows,
// authenticated user
$user = Auth::user();
$user->password = Hash::make($new_password);
// finally we save the authenticated user
$user->save();
Try the following:
public function postUserPasswordChange(){
$validator = Validator::make(Input::all(), User::$change_password_rules);
if($validator->passes()){
$user = UserEventbot::findOrFail(Auth::user()->id);
$user->password = Hash::make(Input::get('new_password'));
$user->save();
return Redirect::to('users/change-password');
}else {
return Redirect::to('users/change-password')->with('message', 'The following errors occurred')->withErrors($validator)->withInput();
}
}
this is my own solution, I have 3 inputs = old_password, password, password_confirmation, form with action=post.
Validator check requirements, hash checks if Old password matches
public function changePassword()
{
$user = Auth::user();
$rules = array(
'old_password' => 'required|alphaNum|between:6,16',
'password' => 'required|alphaNum|between:6,16|confirmed'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
return Redirect::action('UserController#show',$user->id)->withErrors($validator);
}
else
{
if (!Hash::check(Input::get('old_password'), $user->password))
{
return Redirect::action('UserController#show',$user->id)->withErrors('Your old password does not match');
}
else
{
$user->password = Hash::make(Input::get('password'));
$user->save();
return Redirect::action('UserController#show',$user->id)->withMessage("Password have been changed");
}
}
}
Please try the following changed
public function postUserPasswordChange(){
$validator = Validator::make(Input::all(), User::$change_password_rules);
if($validator->passes()){
$user = UserEventbot::findOrFail(Auth::user()->id);
if(Hash::check(Input::get('password'), $user->getAuthPassword())) {
$user->password = Hash::make(Input::get('new_password'));
$user->save();
return Redirect::to('users/change-password')->with('message','Your password has been changed');
}
}
return Redirect::to('users/change-password')->with('message', 'The following errors occurred')->withErrors($validator);
}
You should exclude withInput() in term of password.Hope this help

Resources