harden(auth): scope whitelist purge to active bans, cover unbanAll, hoist ip

feat/v1-foundation
boban 2026-06-20 18:20:19 +02:00
parent 7b4215d055
commit cabad0e770
3 changed files with 22 additions and 4 deletions

View File

@ -60,8 +60,8 @@ class LoginProtection extends Component
Setting::put('bruteforce_bantime', (string) $this->bantime);
Setting::put('bruteforce_whitelist', implode("\n", $lines));
// Widening the whitelist immediately clears any now-exempt bans.
foreach (BannedIp::all() as $ban) {
// Widening the whitelist immediately clears any now-exempt active bans.
foreach (BannedIp::active()->get() as $ban) {
if ($guard->isExempt($ban->ip)) {
$guard->unban($ban->ip);
}
@ -154,10 +154,12 @@ class LoginProtection extends Component
public function render(BruteforceGuard $guard)
{
$ip = (string) request()->ip();
return view('livewire.settings.login-protection', [
'bans' => BannedIp::query()->where('banned_until', '>', now())->orderByDesc('banned_until')->get(),
'currentIp' => (string) request()->ip(),
'currentIpExempt' => $guard->isExempt((string) request()->ip()),
'currentIp' => $ip,
'currentIpExempt' => $guard->isExempt($ip),
]);
}
}

View File

@ -58,6 +58,7 @@
@elseif ($tab === 'users') <livewire:settings.users />
@elseif ($tab === 'sessions') <livewire:settings.sessions />
@elseif ($tab === 'email') <livewire:settings.email />
{{-- Unknown ?tab= falls back to profile instead of rendering nothing. --}}
@else <livewire:settings.profile />
@endif
</div>

View File

@ -61,6 +61,21 @@ class LoginProtectionTabTest extends TestCase
$this->assertDatabaseHas('audit_events', ['action' => 'auth.ip_unbanned', 'target' => '203.0.113.5']);
}
public function test_unban_all_clears_every_ban(): void
{
$user = User::factory()->create();
BannedIp::create(['ip' => '203.0.113.5', 'banned_until' => now()->addHour(), 'attempts' => 10]);
BannedIp::create(['ip' => '203.0.113.6', 'banned_until' => now()->addHour(), 'attempts' => 10]);
$this->actingAs($user);
$token = ConfirmToken::issue('bansClearedAll');
ConfirmToken::confirm($token);
Livewire::actingAs($user)->test(LoginProtection::class)->call('unbanAll', $token);
$this->assertDatabaseCount('banned_ips', 0);
$this->assertDatabaseHas('audit_events', ['action' => 'auth.ip_unbanned', 'target' => 'all']);
}
public function test_widening_whitelist_clears_now_exempt_bans(): void
{
$user = User::factory()->create();