Domain Create Modal anpassen Fehler auf Null
parent
47cf6e95ae
commit
890184d985
|
|
@ -4,9 +4,8 @@ namespace App\Livewire\Ui\Domain;
|
||||||
|
|
||||||
use App\Models\Domain;
|
use App\Models\Domain;
|
||||||
use App\Services\DkimService;
|
use App\Services\DkimService;
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Facades\Process;
|
use Illuminate\Support\Facades\Process;
|
||||||
|
use Illuminate\View\View;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class DkimStatus extends Component
|
class DkimStatus extends Component
|
||||||
|
|
@ -16,44 +15,46 @@ class DkimStatus extends Component
|
||||||
|
|
||||||
public function mount(Domain $domain, ?string $selector = null): void
|
public function mount(Domain $domain, ?string $selector = null): void
|
||||||
{
|
{
|
||||||
$this->domain = $domain;
|
$this->domain = $domain;
|
||||||
|
|
||||||
|
// aktiven Selector aus DB, sonst Default aus Config
|
||||||
$this->selector = $selector
|
$this->selector = $selector
|
||||||
?: optional($domain->dkimKeys()->where('is_active', true)->latest()->first())->selector
|
?: optional(
|
||||||
|
$domain->dkimKeys()->where('is_active', true)->latest()->first()
|
||||||
|
)->selector
|
||||||
?: (string) config('mailpool.defaults.dkim_selector', 'mwl1');
|
?: (string) config('mailpool.defaults.dkim_selector', 'mwl1');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** interne Normalisierung nur fürs Dateisystem */
|
/** Prüft nur lokale Voraussetzungen (Keyfile + KeyTable + SigningTable) */
|
||||||
protected function safeKey(string|Domain $value, int $len = 64): string
|
|
||||||
{
|
|
||||||
$val = $value instanceof Domain ? $value->domain : (string) $value;
|
|
||||||
return preg_replace('/[^a-zA-Z0-9_.-]+/', '_', substr($val, 0, $len));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Minimalcheck: existiert .private + steht’s in KeyTable & SigningTable? */
|
|
||||||
protected function isDkimReady(string $domain, string $selector): bool
|
protected function isDkimReady(string $domain, string $selector): bool
|
||||||
{
|
{
|
||||||
$hasFile = is_readable("/etc/opendkim/keys/{$domain}/{$selector}.private");
|
$d = preg_quote($domain, '/');
|
||||||
|
$s = preg_quote($selector, '/');
|
||||||
|
|
||||||
$keyTab = is_readable('/etc/opendkim/KeyTable')
|
// 1) Key-Datei unter /etc/opendkim/keys/<domain>/<selector>.private
|
||||||
? (@file_get_contents('/etc/opendkim/KeyTable') ?: '')
|
$keyFile = "/etc/opendkim/keys/{$domain}/{$selector}.private";
|
||||||
: '';
|
$hasFile = is_readable($keyFile) && filesize($keyFile) > 0;
|
||||||
$signTab = is_readable('/etc/opendkim/SigningTable')
|
|
||||||
? (@file_get_contents('/etc/opendkim/SigningTable') ?: '')
|
|
||||||
: '';
|
|
||||||
|
|
||||||
$inKey = (bool) preg_match(
|
// 2) Einträge in KeyTable + SigningTable
|
||||||
"/^{$selector}\._domainkey\.{$domain}\s+{$domain}:{$selector}:/m",
|
$keyTab = is_readable('/etc/opendkim/KeyTable') ? (string) @file_get_contents('/etc/opendkim/KeyTable') : '';
|
||||||
|
$signTab = is_readable('/etc/opendkim/SigningTable') ? (string) @file_get_contents('/etc/opendkim/SigningTable') : '';
|
||||||
|
|
||||||
|
// Beispiele:
|
||||||
|
// KeyTable: mwl1._domainkey.sysmail.toastra.com sysmail.toastra.com:mwl1:/etc/opendkim/keys/sysmail.toastra.com/mwl1.private
|
||||||
|
// SigningTable:*@sysmail.toastra.com mwl1._domainkey.sysmail.toastra.com
|
||||||
|
$inKey = (bool) preg_match(
|
||||||
|
"/^{$s}\._domainkey\.{$d}\s+{$d}:{$s}:/m",
|
||||||
$keyTab
|
$keyTab
|
||||||
);
|
);
|
||||||
$inSign = (bool) preg_match(
|
$inSign = (bool) preg_match(
|
||||||
"/^\*\@{$domain}\s+{$selector}\._domainkey\.{$domain}\s*$/m",
|
"/^\*\@{$d}\s+{$s}\._domainkey\.{$d}\s*$/m",
|
||||||
$signTab
|
$signTab
|
||||||
);
|
);
|
||||||
|
|
||||||
return $hasFile && $inKey && $inSign;
|
return $hasFile && $inKey && $inSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Button: (re)generieren + Helper einhängen + OpenDKIM reload */
|
/** Reparieren/Neu erzeugen */
|
||||||
public function regenerate(?string $selector = null): void
|
public function regenerate(?string $selector = null): void
|
||||||
{
|
{
|
||||||
$selector = $selector ?: ($this->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1'));
|
$selector = $selector ?: ($this->selector ?: (string) config('mailpool.defaults.dkim_selector', 'mwl1'));
|
||||||
|
|
@ -62,27 +63,22 @@ class DkimStatus extends Component
|
||||||
/** @var DkimService $svc */
|
/** @var DkimService $svc */
|
||||||
$svc = app(DkimService::class);
|
$svc = app(DkimService::class);
|
||||||
|
|
||||||
// 1) Key erzeugen/auffrischen – deine Funktion macht bereits alles Nötige:
|
// erzeugt/aktualisiert Keys in storage, pflegt DB, ruft Helper auf (falls vorhanden)
|
||||||
// - schreibt .pem/.pub/.private/.txt in storage
|
$svc->generateForDomain($this->domain, 2048, $selector);
|
||||||
// - pflegt DB (DkimKey)
|
|
||||||
// - ruft /usr/local/sbin/mailwolt-install-dkim auf
|
|
||||||
// - reloadet opendkim
|
|
||||||
$res = $svc->generateForDomain($this->domain, 2048, $selector);
|
|
||||||
|
|
||||||
// 2) Sicherstellen, dass der Helper wirklich geladen hat (idempotent):
|
// OpenDKIM neu laden (idempotent)
|
||||||
Process::run(['systemctl', 'reload', 'opendkim']);
|
Process::run(['systemctl', 'reload', 'opendkim']);
|
||||||
|
|
||||||
// 3) Status checken & Feedback
|
// Status neu prüfen
|
||||||
$ok = $this->isDkimReady($this->domain->domain, $selector);
|
$ok = $this->isDkimReady($this->domain->domain, $selector);
|
||||||
$this->dispatch('toast',
|
$this->dispatch('toast', type: $ok ? 'success' : 'warning',
|
||||||
type: $ok ? 'success' : 'warning',
|
message: $ok ? 'DKIM ist aktiv.' : 'DKIM generiert – OpenDKIM prüfen.');
|
||||||
message: $ok ? 'DKIM ist aktiv.' : 'DKIM generiert – OpenDKIM/Tabellen prüfen.');
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->dispatch('toast', type: 'error', message: 'DKIM Fehler: '.$e->getMessage());
|
$this->dispatch('toast', type: 'error', message: 'DKIM Fehler: '.$e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ggf. Selector für UI festhalten
|
$this->selector = $selector; // für Folge-Checks
|
||||||
$this->selector = $selector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(): View
|
public function render(): View
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
<div class="flex items-center gap-4 text-sm">
|
<div class="flex items-center gap-3 text-xs">
|
||||||
<div class="flex items-center gap-2">
|
<div class="inline-flex items-center gap-2 px-1.5 py-0.5 rounded-full
|
||||||
<i class="ph-bold {{ $dkimOk ? 'ph-shield-check text-emerald-400' : 'ph-warning-octagon text-rose-400' }} text-[18px]"></i>
|
{{ $dkimOk ? 'bg-green-500/10 text-green-500 ring-1 ring-green-500/30' : 'bg-red-500/10 text-red-500 ring-1 ring-red-500/30' }}">
|
||||||
<span class="{{ $dkimOk ? 'text-emerald-400' : 'text-rose-400' }}">
|
<i class="ph-bold {{ $dkimOk ? 'ph-shield-check' : 'ph-shield-warning' }} text-base"></i>
|
||||||
{{ $dkimOk ? 'DKIM aktiv' : 'DKIM fehlt' }}
|
<span class="font-xs">{{ $dkimOk ? 'DKIM aktiv' : 'DKIM fehlt' }}</span>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
@if(!$dkimOk)
|
||||||
wire:click="regenerate"
|
<button wire:click="regenerate"
|
||||||
wire:loading.attr="disabled"
|
wire:loading.attr="disabled"
|
||||||
class="inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs font-medium
|
class="inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs font-medium
|
||||||
border border-slate-600/40 bg-slate-800/40 hover:bg-slate-800
|
border border-slate-600/40 bg-slate-800/40 hover:bg-slate-800
|
||||||
disabled:opacity-50">
|
disabled:opacity-50">
|
||||||
<i class="ph-bold ph-arrows-counter-clockwise"></i>
|
<i class="ph-bold ph-arrow-clockwise text-base"
|
||||||
<span wire:loading.remove>DKIM reparieren</span>
|
wire:loading.class="animate-spin"></i>
|
||||||
<span wire:loading>Erzeuge…</span>
|
<span wire:loading.remove>DKIM reparieren</span>
|
||||||
</button>
|
<span wire:loading>Repariere…</span>
|
||||||
|
</button>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue