47 lines
1.4 KiB
PHP
47 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Security;
|
|
|
|
use App\Models\IpAttempt;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
|
|
class IpBanQueryService
|
|
{
|
|
public function paginate(array $filters, int $page = 1, int $perPage = 20): LengthAwarePaginator
|
|
{
|
|
$query = IpAttempt::query()->orderBy('updated_at', 'desc');
|
|
|
|
$status = strtolower(trim((string) ($filters['status'] ?? 'all')));
|
|
if ($status === 'active') {
|
|
$query->where('blocked_until', '>', $this->utcNow());
|
|
}
|
|
|
|
if (!empty($filters['search'])) {
|
|
$term = '%' . trim((string) $filters['search']) . '%';
|
|
$query->where('ip_address', 'like', $term);
|
|
}
|
|
|
|
$sortBy = (string) ($filters['sort_by'] ?? 'updated_at');
|
|
$sortDir = strtolower((string) ($filters['sort_dir'] ?? 'desc')) === 'asc' ? 'asc' : 'desc';
|
|
$allowedSorts = ['updated_at', 'blocked_until', 'attempts', 'ip_address', 'last_attempt_at'];
|
|
if (in_array($sortBy, $allowedSorts, true)) {
|
|
$query->orderBy($sortBy, $sortDir);
|
|
}
|
|
|
|
return $query->paginate($perPage, ['*'], 'page', $page);
|
|
}
|
|
|
|
public function find(int $id): ?IpAttempt
|
|
{
|
|
return IpAttempt::query()->find($id);
|
|
}
|
|
|
|
private function utcNow(): string
|
|
{
|
|
if (function_exists('utc_now')) {
|
|
return (string) utc_now();
|
|
}
|
|
return now('UTC')->toDateTimeString();
|
|
}
|
|
}
|