wallacemartinss/filament-security
Installation:
composer require wallacemartinss/filament-security
Publish the config and migrations:
php artisan vendor:publish --provider="WallaceMartinss\FilamentSecurity\FilamentSecurityServiceProvider" --tag="filament-security-config"
php artisan vendor:publish --provider="WallaceMartinss\FilamentSecurity\FilamentSecurityServiceProvider" --tag="filament-security-migrations"
php artisan migrate
Register Plugin:
Add to app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\WallaceMartinss\FilamentSecurity\FilamentSecurityPlugin::make(),
]);
}
First Use Case:
Enable honeypot in config/filament-security.php:
'honeypot' => [
'enabled' => true,
'field_name' => 'fake_field',
],
Add a hidden field with name="fake_field" to your Filament form. Bots filling this will be blocked.
Email Validation:
Filament\Forms\Components\TextInput:
TextInput::make('email')
->rules([
function ($livewire) {
return \WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::isDisposableEmail($livewire->email);
},
])
->afterStateUpdated(function ($state, $set) {
if (\WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::isDisposableEmail($state)) {
$set('email', null);
$this->addError('email', 'Disposable emails are not allowed.');
}
}),
if (!\WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::validateEmailDomain($email)) {
throw ValidationException::withMessages(['email' => 'Domain does not exist.']);
}
Cloudflare IP Blocking:
config/filament-security.php:
'cloudflare' => [
'enabled' => true,
'whitelisted_ips' => ['192.168.1.1', '10.0.0.1'],
],
use WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity;
public function handle(Request $request, Closure $next)
{
if (FilamentSecurity::isCloudflareIpBlocked($request->ip())) {
abort(403, 'Access denied.');
}
return $next($request);
}
Single Session Enforcement:
public function handle(Request $request, Closure $next)
{
if (\WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::hasMultipleSessions($request->user())) {
auth()->logoutOtherDevices($request->user()->id);
}
return $next($request);
}
Security Dashboard:
/admin/security (auto-registered). Monitor blocked IPs, disposable emails, and honeypot triggers in real-time.rules.php config file:
'email' => [
'disposable_providers' => [
'temp-mail.org',
'guerrillamail.com',
],
],
DisposableEmailBlocked) to log or notify admins:
\WallaceMartinss\FilamentSecurity\Events\DisposableEmailBlocked::class => [
\App\Listeners\LogSecurityEvent::class,
],
'rdap' => [
'enabled' => true,
'min_domain_age_days' => 30,
],
if (!\WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::isDomainOldEnough($domain)) {
throw ValidationException::withMessages(['email' => 'Domain too new.']);
}
DNS/MX Validation Latency:
config/filament-security.php:
'dns' => [
'cache_ttl_minutes' => 60,
],
dns_get_record) for offline testing.Cloudflare IP Blocking:
CF-Connecting-IP header is passed if behind Cloudflare. Configure middleware to parse it:
$ip = $request->header('CF-Connecting-IP') ?? $request->ip();
FilamentSecurity::isCloudflareIpBlocked($ip) before deploying.Honeypot False Positives:
honeypot_ or fake_ in other forms to prevent accidental triggers.'honeypot' => [
'excluded_routes' => ['admin.pages.*'],
],
RDAP API Limits:
try {
$isValid = FilamentSecurity::isDomainOldEnough($domain);
} catch (\Exception $e) {
$isValid = true; // Fallback
}
Session Enforcement Conflicts:
if (FilamentSecurity::hasMultipleSessions($user)) {
$user->notify(new OtherDevicesActive($user->otherDevices()));
}
Log Security Events:
Enable logging in config/filament-security.php:
'logging' => [
'enabled' => true,
'channel' => 'security',
],
Check logs for blocked requests or validation failures.
Test Disposable Email List:
Use the FilamentSecurity::isDisposableEmail() method to test emails:
\WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::isDisposableEmail('test@temp-mail.org'); // Returns true
Dashboard Debugging: The dashboard shows blocked IPs, disposable emails, and honeypot triggers. Use it to verify configurations:
honeypot_triggered).Custom Security Layers:
FilamentSecurity facade or creating a decorator:
\WallaceMartinss\FilamentSecurity\Facades\FilamentSecurity::extend(function ($security) {
$security->addRule('custom_rule', function ($value) {
return str_contains($value, 'malicious');
});
});
Override Default Policies:
SecurityPolicy by binding your own in AppServiceProvider:
$this->app->bind(
\WallaceMartinss\FilamentSecurity\Contracts\SecurityPolicy::class,
\App\Policies\CustomSecurityPolicy::class
);
Custom Event Handlers:
SecurityEvent class to add custom data:
class CustomSecurityEvent extends \WallaceMartinss\FilamentSecurity\Events\SecurityEvent
{
public function __construct(
public string $customData,
array $extra = []
) {
parent::__construct($extra);
}
}
Modify Dashboard Widgets:
FilamentSecurityPlugin:
\WallaceMartinss\FilamentSecurity\FilamentSecurityPlugin::make()
->modifyQueryUsing(fn (Builder $query) => $query->where('created_at', '>', now()->subDays(7)))
How can I help you explore Laravel packages today?