When updating a User profile, password is being reset even though a new password is not being entered. Existing password should be retained if no new one is entered.
livewire/user/edit.blade.php
...
<div >
<div >
<label for="new_password" >
New Password
</label>
<div >
<input wire:model="new_password" type="password" name="new_password" id="new_password"
autocomplete="new-password"
>
</div>
@error('new_password')<span
>{{ $message }}</span>
@enderror
</div>
<div >
<label for="new_password_confirmation" >
Confirm Password
</label>
<div >
<input wire:model="new_password_confirmation" type="password" name="new_password_confirmation" id="new_confirmation"
>
</div>
</div>
</div>
...
Livewire/User/edit.php
...
class Edit extends Component
{
public $first_name;
public $last_name;
public $email;
public $password;
public $new_password = '';
public $new_password_confirmation = '';
public $role;
public function mount(User $user)
{
$this->user = $user;
$this->first_name = $user->first_name;
$this->last_name = $user->last_name;
$this->email = $user->email;
$this->password = $user->password;
$this->role = $user->role;
}
public function updateUser($id)
{
$record = User::find($id);
$this->validate([
'new_password' => ['confirmed'],
]);
$record->update([
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'email' => $this->email,
'role' => $this->role,
'password' => bcrypt($this->new_password) ? : $record->password,
]);
session()->flash('success', 'User Successfully Updated');
return redirect()->route('user.edit', $record->id);
}
public function render()
{
return view('livewire.user.edit');
}
}
CodePudding user response:
Your setting $new_password to an empty string.
public $new_password = '';
But you evaluate whether it’s null in your updateUser method.
I would start by setting public $new_password = null;
Then in updateUser update your new_password check to:
'password' => $this->new_password ? bcrypt($this->new_password) : bcrypt($record->password),
You could also leave the property set as empty string and check for empty($this->new_password)
but I prefer the null route.
CodePudding user response:
A few notes first,
- Livewire has a
$rules
property that you should use, and declare the rules separately - see https://laravel-livewire.com/docs/2.x/input-validation - Instead of doing
updateUser($id)
and then$record = User::find($id);
, you can just doupdateUser(User $user)
through "model route binding" - You may want to update the current user instead, so update
$this->user
instead of fetching it again through the parameter
Your actual issue though, instead of updating all properties at once, move the array to a variable, and then push the password only if it was changed.
$userData = [
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'email' => $this->email,
'role' => $this->role,
];
if (filled($this->new_password)) {
$this->validate([
'new_password' => ['confirmed'],
]);
$userData['password'] = bcrypt($this->new_password);
}
$record->update($userData);
CodePudding user response:
I would have a simple if
there to be more explicit, but if you prefer a quick, inline solution to your problem then this should do:
'password' => bcrypt($this->new_password ?: $record->password),