yebor974/filament-renew-password
Installation:
composer require yebor974/filament-renew-password
(Use ^2.0 for Filament v3, ^3.0 for Filament v4/v5).
Publish Migrations:
php artisan vendor:publish --tag="filament-renew-password-migrations"
php artisan migrate
Skippable if you manually add last_renew_password_at (timestamp) and force_renew_password (boolean) to your users table.
Register Plugin:
Add to app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\Yebor974\FilamentRenewPassword\FilamentRenewPasswordPlugin::make(),
]);
}
First Use Case:
force_renew_password = true will be prompted to reset their password on next login.config/filament-renew-password.php (default: 90 days).Recurring Renewal:
RenewPasswordMiddleware) or manually in controllers.app/Http/Middleware/CheckPasswordRenewal.php:
use Yebor974\FilamentRenewPassword\Facades\RenewPassword;
public function handle(Request $request, Closure $next)
{
if (RenewPassword::shouldRenew($request->user())) {
return redirect()->route('filament.pages.auth.login');
}
return $next($request);
}
Force Renewal:
force_renew_password = true via:
$user->force_renew_password = true;
$user->save();
Custom Criteria:
Yebor974\FilamentRenewPassword\Contracts\RenewPasswordCriteria:
class CustomCriteria implements RenewPasswordCriteria
{
public function shouldRenew(User $user): bool
{
return $user->role === 'admin' && $user->last_login_at->diffInDays() > 30;
}
}
config/filament-renew-password.php:
'criteria' => [
\App\CustomCriteria::class,
],
Integration with Filament Pages:
RenewPasswordPage:
use Yebor974\FilamentRenewPassword\Pages\RenewPasswordPage;
RenewPasswordPage::make()->navigationIcon('heroicon-o-key');
Bulk Actions: Update multiple users via a Filament resource action:
use Yebor974\FilamentRenewPassword\Facades\RenewPassword;
public static function getBulkActions(): array
{
return [
BulkAction::make('forceRenew')
->action(function (Collection $records) {
RenewPassword::forceRenew($records);
})
->label('Force Renew Password'),
];
}
Conditional Logic: Combine with Filament’s policy system:
public function canAccess(Page $page): bool
{
return parent::canAccess($page) &&
!RenewPassword::shouldRenew(auth()->user());
}
Migration Conflicts:
users table already has last_renew_password_at, skip publishing migrations to avoid errors.--force with migrations.Caching Issues:
php artisan cache:clear
Middleware Order:
RenewPasswordMiddleware before Authenticate middleware to avoid redirect loops.app/Http/Kernel.php):
'web' => [
\Yebor974\FilamentRenewPassword\Http\Middleware\RenewPasswordMiddleware::class,
\App\Http\Middleware\Authenticate::class,
// ...
],
Timezone Mismatches:
last_renew_password_at uses the same timezone as your app (configured in .env).\Log::debug('Renewal diff:', [
'days' => now()->diffInDays($user->last_renew_password_at),
'tz' => now()->timezone,
]);
\Yebor974\FilamentRenewPassword\Facades\RenewPassword::shouldRenew($user);
config/filament-renew-password.php:
'debug' => env('FILAMENT_RENEW_PASSWORD_DEBUG', false),
Outputs criteria evaluation to Laravel logs.Custom Renewal Page:
Extend RenewPasswordPage:
namespace App\Filament\Pages;
use Yebor974\FilamentRenewPassword\Pages\RenewPasswordPage as BasePage;
class CustomRenewPasswordPage extends BasePage
{
protected static string $view = 'filament-renew-password::pages.custom-renew';
}
Email Notifications: Override the mailer service in config:
'mailer' => \App\Services\CustomRenewPasswordMailer::class,
Implement Yebor974\FilamentRenewPassword\Contracts\RenewPasswordMailer.
Database Columns: Customize columns via service provider:
public function boot()
{
$this->app->bind(
\Yebor974\FilamentRenewPassword\Contracts\RenewPasswordModel::class,
function () {
return new class extends \Yebor974\FilamentRenewPassword\Models\RenewPasswordModel {
protected $table = 'custom_users';
public $timestamps = false;
};
}
);
}
User::chunk(100, function ($users) {
RenewPassword::forceRenew($users);
});
canAccess):
if (RenewPassword::shouldRenew(auth()->user())) {
return redirect()->route('filament.pages.renew-password');
}
How can I help you explore Laravel packages today?