132 lines
4.6 KiB
PHP
132 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Ui\Nx\Mail;
|
|
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\On;
|
|
use Livewire\Attributes\Title;
|
|
use Livewire\Attributes\Url;
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
|
|
#[Layout('layouts.dvx')]
|
|
#[Title('Quarantäne · Mailwolt')]
|
|
class QuarantineList extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
#[Url(as: 'filter', keep: true)]
|
|
public string $filter = 'suspicious';
|
|
|
|
#[Url(as: 'q', keep: true)]
|
|
public string $search = '';
|
|
|
|
#[Url(as: 'limit', keep: true)]
|
|
public int $perPage = 25;
|
|
public int $rows = 500;
|
|
|
|
#[On('quarantine:updated')]
|
|
public function refresh(): void {}
|
|
|
|
public function updatedFilter(): void { $this->resetPage(); }
|
|
public function updatedSearch(): void { $this->resetPage(); }
|
|
public function updatedPerPage(): void { $this->resetPage(); }
|
|
|
|
public function openMessage(string $msgId): void
|
|
{
|
|
$this->dispatch('openModal',
|
|
component: 'ui.nx.mail.modal.quarantine-message-modal',
|
|
arguments: ['msgId' => $msgId]
|
|
);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$all = $this->fetchHistory();
|
|
|
|
$suspicious = array_values(array_filter($all, fn($m) => $m['action'] !== 'no action'));
|
|
|
|
$counts = [
|
|
'all' => count($all),
|
|
'suspicious' => count($suspicious),
|
|
'reject' => count(array_filter($all, fn($m) => $m['action'] === 'reject')),
|
|
'add header' => count(array_filter($all, fn($m) => $m['action'] === 'add header')),
|
|
'greylist' => count(array_filter($all, fn($m) => $m['action'] === 'greylist')),
|
|
];
|
|
|
|
$messages = match($this->filter) {
|
|
'suspicious' => $suspicious,
|
|
'all' => $all,
|
|
default => array_values(array_filter($all, fn($m) => $m['action'] === $this->filter)),
|
|
};
|
|
|
|
if ($this->search !== '') {
|
|
$s = strtolower($this->search);
|
|
$messages = array_values(array_filter($messages, fn($m) =>
|
|
str_contains(strtolower($m['from'] ?? ''), $s) ||
|
|
str_contains(strtolower($m['rcpt'] ?? ''), $s) ||
|
|
str_contains(strtolower($m['subject'] ?? ''), $s)
|
|
));
|
|
}
|
|
|
|
$total = count($messages);
|
|
$currentPage = LengthAwarePaginator::resolveCurrentPage();
|
|
$paged = new LengthAwarePaginator(
|
|
array_slice($messages, ($currentPage - 1) * $this->perPage, $this->perPage),
|
|
$total,
|
|
$this->perPage,
|
|
$currentPage,
|
|
['path' => request()->url()]
|
|
);
|
|
|
|
return view('livewire.ui.nx.mail.quarantine-list', [
|
|
'messages' => $paged,
|
|
'counts' => $counts,
|
|
]);
|
|
}
|
|
|
|
// ── helpers ──────────────────────────────────────────────────────────────
|
|
|
|
public function fetchHistory(): array
|
|
{
|
|
$password = env('RSPAMD_PASSWORD', '');
|
|
$opts = [
|
|
'http' => [
|
|
'timeout' => 3,
|
|
'ignore_errors' => true,
|
|
'header' => $password !== '' ? "Password: {$password}\r\n" : '',
|
|
],
|
|
];
|
|
$ctx = stream_context_create($opts);
|
|
$raw = @file_get_contents("http://127.0.0.1:11334/history?rows={$this->rows}", false, $ctx);
|
|
|
|
if (!$raw) return [];
|
|
|
|
$data = json_decode($raw, true);
|
|
if (!is_array($data)) return [];
|
|
|
|
$items = $data['rows'] ?? (isset($data[0]) ? $data : []);
|
|
|
|
return array_map(function ($r) {
|
|
$rcpt = $r['rcpt'] ?? [];
|
|
if (is_array($rcpt)) $rcpt = implode(', ', $rcpt);
|
|
|
|
return [
|
|
'id' => $r['scan_id'] ?? ($r['id'] ?? uniqid('q_')),
|
|
'msg_id' => $r['message-id'] ?? '—',
|
|
'from' => $r['from'] ?? $r['sender'] ?? '—',
|
|
'rcpt' => $rcpt ?: '—',
|
|
'subject' => $r['subject'] ?? '(kein Betreff)',
|
|
'score' => round((float)($r['score'] ?? 0), 2),
|
|
'required' => round((float)($r['required_score'] ?? 15), 2),
|
|
'action' => $r['action'] ?? 'unknown',
|
|
'time' => (int)($r['unix_time'] ?? $r['time'] ?? 0),
|
|
'size' => (int)($r['size'] ?? 0),
|
|
'symbols' => array_keys($r['symbols'] ?? []),
|
|
'ip' => $r['ip'] ?? '—',
|
|
];
|
|
}, $items);
|
|
}
|
|
}
|