mailwolt/app/Livewire/Ui/Security/SslCertificatesTable.php

97 lines
3.1 KiB
PHP

<?php
namespace App\Livewire\Ui\Security;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
#[Layout('layouts.dvx')]
#[Title('SSL/TLS · Mailwolt')]
class SslCertificatesTable extends Component
{
public array $certs = [];
public function mount(): void
{
$this->certs = $this->loadCertificates();
}
public function refresh(): void
{
$this->certs = $this->loadCertificates();
$this->dispatch('toast', type: 'done', badge: 'SSL', title: 'Aktualisiert',
text: 'Zertifikatsliste wurde neu geladen.', duration: 3000);
}
public function renew(string $name): void
{
$safe = preg_replace('/[^a-z0-9._-]/i', '', $name);
if ($safe === '') return;
$out = (string) @shell_exec(
"sudo -n /usr/bin/certbot renew --cert-name {$safe} --force-renewal 2>&1"
);
$this->certs = $this->loadCertificates();
if (str_contains($out, 'Successfully renewed') || str_contains($out, 'success')) {
$this->dispatch('toast', type: 'done', badge: 'SSL',
title: 'Zertifikat erneuert', text: "Zertifikat <b>{$safe}</b> wurde erfolgreich erneuert.", duration: 5000);
} else {
$this->dispatch('toast', type: 'error', badge: 'SSL',
title: 'Fehler', text: nl2br(htmlspecialchars(substr($out, 0, 300))), duration: 0);
}
}
private function loadCertificates(): array
{
$out = (string) @shell_exec('sudo -n /usr/bin/certbot certificates 2>&1');
if (empty(trim($out))) return [['_error' => 'unavailable']];
if (str_contains($out, 'No certificates found')) return [];
$certs = [];
$blocks = preg_split('/\n(?=Certificate Name:)/m', $out);
foreach ($blocks as $block) {
if (!preg_match('/Certificate Name:\s*(.+)/i', $block, $nameM)) continue;
preg_match('/Domains:\s*(.+)/i', $block, $domainsM);
preg_match('/Expiry Date:\s*(.+)/i', $block, $expiryM);
preg_match('/Certificate Path:\s*(.+)/i', $block, $certM);
$expiryRaw = trim($expiryM[1] ?? '');
$daysLeft = null;
$expired = false;
if (preg_match('/VALID: (\d+) days/i', $expiryRaw, $dM)) {
$daysLeft = (int) $dM[1];
} elseif (preg_match('/INVALID/i', $expiryRaw)) {
$expired = true;
$daysLeft = 0;
}
$domainsRaw = trim($domainsM[1] ?? '');
$domains = $domainsRaw !== '' ? array_values(array_filter(explode(' ', $domainsRaw))) : [];
$certs[] = [
'name' => trim($nameM[1]),
'domains' => $domains,
'expiry' => $expiryRaw,
'days_left' => $daysLeft,
'expired' => $expired,
'cert_path' => trim($certM[1] ?? ''),
];
}
usort($certs, fn($a, $b) => ($a['days_left'] ?? 999) <=> ($b['days_left'] ?? 999));
return $certs;
}
public function render()
{
return view('livewire.ui.security.ssl-certificates-table');
}
}