From 51f9c2ee15011e0b38f35df5a98f71a28938fc23 Mon Sep 17 00:00:00 2001 From: Alex Popa Date: Tue, 3 Dec 2024 02:15:40 +0200 Subject: [PATCH] Reset password action --- .../UserResource/Actions/ResetPassword.php | 57 ------------- .../Actions/ResetPasswordAction.php | 79 +++++++++++++++++++ .../UserResource/Pages/CreateUser.php | 6 ++ .../Resources/UserResource/Pages/ViewUser.php | 3 +- app/Models/User.php | 5 -- lang/ro/user.php | 9 +++ 6 files changed, 96 insertions(+), 63 deletions(-) delete mode 100644 app/Filament/Organizations/Resources/UserResource/Actions/ResetPassword.php create mode 100644 app/Filament/Organizations/Resources/UserResource/Actions/ResetPasswordAction.php diff --git a/app/Filament/Organizations/Resources/UserResource/Actions/ResetPassword.php b/app/Filament/Organizations/Resources/UserResource/Actions/ResetPassword.php deleted file mode 100644 index 7eb55ce8..00000000 --- a/app/Filament/Organizations/Resources/UserResource/Actions/ResetPassword.php +++ /dev/null @@ -1,57 +0,0 @@ -visible(fn (User $record) => $record->isActive()); - - $this->label(__('user.actions.reset_password')); - - $this->icon('heroicon-o-lock-open'); - - $this->modalHeading(__('user.action_reset_password_confirm.title')); - - $this->modalWidth('md'); - - $this->action(function (User $record) { - $key = $this->getRateLimiterKey($record); - $maxAttempts = 1; - - if (RateLimiter::tooManyAttempts($key, $maxAttempts)) { - return $this->failure(); - } - - RateLimiter::increment($key, HOUR_IN_SECONDS); - - $record->resetPassword(); -// $record->sendWelcomeNotification(); -// $this->success(); - }); - - $this->successNotificationTitle(__('user.action_reset_password_confirm.success')); - - $this->failureNotification( - fn (Notification $notification) => $notification - ->danger() - ->title(__('user.action_reset_password_confirm.failure_title')) - ->body(__('user.action_reset_password_confirm.failure_body')) - ); - } - - private function getRateLimiterKey(User $user): string - { - return 'reset-password:' . $user->id; - } -} diff --git a/app/Filament/Organizations/Resources/UserResource/Actions/ResetPasswordAction.php b/app/Filament/Organizations/Resources/UserResource/Actions/ResetPasswordAction.php new file mode 100644 index 00000000..10fab1af --- /dev/null +++ b/app/Filament/Organizations/Resources/UserResource/Actions/ResetPasswordAction.php @@ -0,0 +1,79 @@ +visible(fn (User $record) => $record->userStatus->isActive() && ! Filament::auth()->user()->is($record)); + + $this->label(__('user.actions.reset_password')); + + $this->icon('heroicon-o-lock-open'); + + $this->outlined(); + + $this->modalHeading(__('user.action_reset_password_confirm.title')); + + $this->modalSubmitActionLabel(__('user.action_reset_password_confirm.title')); + + $this->modalWidth('md'); + + $this->action(function (User $record) { + $status = Password::broker(Filament::getAuthPasswordBroker()) + ->sendResetLink( + ['email' => $record->email], + function (CanResetPassword $user, string $token): void { + if (! method_exists($user, 'notify')) { + $userClass = $user::class; + + throw new Exception("Model [{$userClass}] does not have a [notify()] method."); + } + + $notification = new ResetPasswordNotification($token); + $notification->url = Filament::getResetPasswordUrl($token, $user); + + $user->notify($notification); + } + ); + + if ($status !== Password::RESET_LINK_SENT) { + $this->failureNotificationTitle(__($status)); + $this->failure(); + + return; + } + + $this->successNotificationTitle(__($status)); + $this->success(); + }); + + $this->successNotificationTitle(__('user.action_reset_password_confirm.success')); + + $this->failureNotification( + fn (Notification $notification) => $notification + ->danger() + ->title(__('user.action_reset_password_confirm.failure_title')) + ->body(__('user.action_reset_password_confirm.failure_body')) + ); + } +} diff --git a/app/Filament/Organizations/Resources/UserResource/Pages/CreateUser.php b/app/Filament/Organizations/Resources/UserResource/Pages/CreateUser.php index e3f8652e..5359bb30 100644 --- a/app/Filament/Organizations/Resources/UserResource/Pages/CreateUser.php +++ b/app/Filament/Organizations/Resources/UserResource/Pages/CreateUser.php @@ -9,6 +9,7 @@ use App\Models\User; use Filament\Facades\Filament; use Filament\Resources\Pages\CreateRecord; +use Illuminate\Contracts\Support\Htmlable; use Illuminate\Database\Eloquent\Model; class CreateUser extends CreateRecord @@ -19,6 +20,11 @@ class CreateUser extends CreateRecord protected static bool $canCreateAnother = false; + public function getTitle(): string|Htmlable + { + return __('user.titles.create_specialist'); + } + protected function afterSave(): void { /** @var User $user */ diff --git a/app/Filament/Organizations/Resources/UserResource/Pages/ViewUser.php b/app/Filament/Organizations/Resources/UserResource/Pages/ViewUser.php index 34593ce7..38cfb053 100644 --- a/app/Filament/Organizations/Resources/UserResource/Pages/ViewUser.php +++ b/app/Filament/Organizations/Resources/UserResource/Pages/ViewUser.php @@ -11,6 +11,7 @@ use App\Filament\Organizations\Resources\UserResource\Actions\DeactivateUserAction; use App\Filament\Organizations\Resources\UserResource\Actions\ReactivateUserAction; use App\Filament\Organizations\Resources\UserResource\Actions\ResendInvitationAction; +use App\Filament\Organizations\Resources\UserResource\Actions\ResetPasswordAction; use App\Infolists\Components\SectionHeader; use App\Models\User; use Filament\Infolists\Components\Actions\Action; @@ -112,7 +113,7 @@ protected function getHeaderActions(): array return [ DeactivateUserAction::make(), - // UserResource\Actions\ResetPassword::make('reset-password'), + ResetPasswordAction::make(), ResendInvitationAction::make(), diff --git a/app/Models/User.php b/app/Models/User.php index 2fb0b6b9..96d6804d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -227,11 +227,6 @@ public function scopeWithLastLoginAt(Builder $query): Builder ->withCasts(['last_login_at' => 'datetime']); } - // TODO create notifications - public function resetPassword(): void - { - } - public function getFullNameAttribute(): string { return $this->first_name . ' ' . $this->last_name; diff --git a/lang/ro/user.php b/lang/ro/user.php index 7115f7cb..af88a650 100644 --- a/lang/ro/user.php +++ b/lang/ro/user.php @@ -14,6 +14,10 @@ 'plural' => 'Specialiști', ], + 'titles' => [ + 'create_specialist' => 'Adaugă specialist', + ], + 'labels' => [ 'first_name' => 'Nume', 'last_name' => 'Prenume', @@ -77,6 +81,11 @@ 'success' => 'Cont reactivat cu succes', ], + 'action_reset_password_confirm' => [ + 'title' => 'Resetează parola', + 'success' => 'Email-ul a fost trimis cu succes', + ], + 'status' => [ 'active' => 'Activ', 'inactive' => 'Inactiv',