- About
- Services
- Experiences
- Blog
- Portfolio
- Contact
Filament - How to force renew password on first user login
This article uses the Filament Renew Password Plugin.
- Start by installing and registering the plugin on panel.
composer require yebor974/filament-renew-password
We publish default plugin migration that will add two columns to users table : last_password_renew_at
and force_renew_password
php artisan vendor:publish --tag="filament-renew-password-migrations"
php artisan migrate
We register the plugin to panel and add force renewal process and timestamp management.
use Yebor974\Filament\RenewPassword\RenewPasswordPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(
(new RenewPasswordPlugin())
->forceRenewPassword() // activate the force renewal process
->timestampColumn() // activate last_password_renew_at column, updating it with each password renewal.
)
);
}
We implement RenewPasswordContract
on User Model, add default RenewPassword
trait and declare fillable
attributes.
We will just declare a name and email attributes for user.
use Illuminate\Foundation\Auth\User as Authenticatable;
use Yebor974\Filament\RenewPassword\Contracts\RenewPasswordContract;
use Yebor974\Filament\RenewPassword\Traits\RenewPassword;
//...
class User extends Authenticatable implements RenewPasswordContract
{
use RenewPassword;
protected $fillable = [
'name',
'email',
'force_renew_password'
];
//...
}
If we set true to
force_renew_password
attribute,the user will be automatically redirect to the renewal password process.
- Create User Resource
php artisan make:filament-resource User
class UserResource extends Resource
{
protected static ?string $model = User::class;
protected static ?string $navigationIcon = 'heroicon-o-users';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Section::make()
->schema([
TextInput::make('name')
->required(),
TextInput::make('email')
->required()
->unique(ignoreRecord: true)
])->columns(2)
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->searchable(),
Tables\Columns\TextColumn::make('email')
->searchable(),
Tables\Columns\IconColumn::make('force_renew_password')
->boolean()
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
//...
}
Now, we need to generate default password and invite user to connect and renew password.
On CreateUser.php
page we have to override the mutateFormDataBeforeCreate
and handleRecordCreation
functions like that:
class CreateUser extends CreateRecord
{
protected static string $resource = UserResource::class;
protected string $password;
protected function mutateFormDataBeforeCreate(array $data): array
{
$this->password = Str::password(12); // generate a default password with length of 12 caracters
$data['password'] = bcrypt($this->password);
$data['force_renew_password'] = true; // to force user to renew password on next login
return $data;
}
protected function handleRecordCreation(array $data): Model
{
/** @var User $user */
$user = parent::handleRecordCreation($data); // handle the creation of the new user
$user->notify(new NewAccount($this->password)); // notify the new user with account details
return $user;
}
}
The NewAccount
notification class is:
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\HtmlString;
class NewAccount extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*/
public function __construct(protected string $password, protected ?Model $tenant = null)
{
$this->afterCommit();
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
$appName = config('app.name');
return (new MailMessage)
->subject("Your account has been created on $appName")
->line("Here are your login details:")
->line(new HtmlString("<strong>Email</strong> : {$notifiable->email}"))
->line(new HtmlString("<strong>Temporary password</strong> : {$this->password}"))
->line("You will be prompted to change this temporary password at your next login.")
->action('Go to app', filament()->getUrl($this->tenant));
}
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
//
];
}
}
That's all!
- We can test our code
- Create user
- Receive notification (with smtp mailpit mailer)
- Login and renew passord
Other posts
Plugins
To contact me
If you have an idea to bring to life, a problem to solve, or a significant technical challenge to tackle, don't waste any more time. Contact me now and let me help you turn your ambitions into reality. My expertise is at your disposal to successfully materialize your projects.
My mail
Geographic location
Paris & Reunion Island (France - UTC+4)