Domain Create Modal anpassen Fehler auf Null
parent
33abdc7c7f
commit
0730f53a72
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Domain;
|
||||
use App\Models\DkimKey;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InstallDkimKey implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public function __construct(
|
||||
public int $domainId,
|
||||
public int $dkimKeyId,
|
||||
public string $privPath,
|
||||
public string $dnsTxtContent,
|
||||
) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$domain = Domain::findOrFail($this->domainId);
|
||||
$dk = DkimKey::findOrFail($this->dkimKeyId);
|
||||
|
||||
$domainName = $domain->domain; // z.B. example.com
|
||||
$selector = $dk->selector; // z.B. mwl1
|
||||
|
||||
// TXT temporär für Helper speichern (optional, damit /etc/mailwolt/dns gefüllt wird)
|
||||
$tmpTxt = tempnam(sys_get_temp_dir(), 'dkim_txt_');
|
||||
file_put_contents($tmpTxt, $this->dnsTxtContent);
|
||||
|
||||
// Root-Helper aufrufen (sudoers hast du im Installer angelegt)
|
||||
$cmd = sprintf(
|
||||
'sudo /usr/local/sbin/mailwolt-install-dkim %s %s %s %s',
|
||||
escapeshellarg($domainName),
|
||||
escapeshellarg($selector),
|
||||
escapeshellarg($this->privPath),
|
||||
escapeshellarg($tmpTxt)
|
||||
);
|
||||
|
||||
exec($cmd, $out, $rc);
|
||||
@unlink($tmpTxt);
|
||||
|
||||
if ($rc !== 0) {
|
||||
throw new \RuntimeException("mailwolt-install-dkim failed (rc={$rc})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Domain;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class RemoveDkimKey implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public function __construct(
|
||||
public int $domainId,
|
||||
public string $selector
|
||||
) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$domain = Domain::withTrashed()->findOrFail($this->domainId);
|
||||
|
||||
$cmd = sprintf(
|
||||
'sudo /usr/local/sbin/mailwolt-remove-dkim %s %s',
|
||||
escapeshellarg($domain->domain),
|
||||
escapeshellarg($this->selector)
|
||||
);
|
||||
|
||||
exec($cmd, $out, $rc);
|
||||
if ($rc !== 0) {
|
||||
throw new \RuntimeException("mailwolt-remove-dkim failed (rc={$rc})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
namespace App\Livewire\Ui\Domain\Modal;
|
||||
|
||||
use App\Jobs\InstallDkimKey;
|
||||
use App\Models\DkimKey;
|
||||
use App\Models\Domain;
|
||||
use App\Models\Setting;
|
||||
|
|
@ -271,7 +272,7 @@ class DomainCreateModal extends ModalComponent
|
|||
// DKIM + DNS
|
||||
$dkim = app(DkimService::class)->generateForDomain($domain, $this->dkim_bits, $this->dkim_selector);
|
||||
|
||||
DkimKey::create([
|
||||
$dk = DkimKey::create([
|
||||
'domain_id' => $domain->id,
|
||||
'selector' => $dkim['selector'],
|
||||
'private_key_pem' => $dkim['private_pem'],
|
||||
|
|
@ -279,6 +280,13 @@ class DomainCreateModal extends ModalComponent
|
|||
'is_active' => true,
|
||||
]);
|
||||
|
||||
dispatch(new InstallDkimKey(
|
||||
domainId: $domain->id,
|
||||
dkimKeyId: $dk->id,
|
||||
privPath: $dkim['priv_path'],
|
||||
dnsTxtContent: $dkim['dns_txt']
|
||||
));
|
||||
|
||||
app(DnsRecordService::class)->provision(
|
||||
$domain,
|
||||
$dkim['selector'] ?? null,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Jobs\InstallDkimKey;
|
||||
use App\Jobs\RemoveDkimKey;
|
||||
use App\Models\DkimKey;
|
||||
use App\Models\Domain;
|
||||
use App\Services\DkimService;
|
||||
|
||||
class DomainObserver
|
||||
{
|
||||
/**
|
||||
* DKIM bei neuen Domains erzeugen + in OpenDKIM installieren.
|
||||
* Läuft NUR, wenn die Domain aktiv ist (anpassbar).
|
||||
*/
|
||||
public function created(Domain $domain): void
|
||||
{
|
||||
// Standardwerte aus Config oder .env
|
||||
$selector = config('mailwolt.dkim.selector', 'mwl1');
|
||||
$bits = (int) config('mailwolt.dkim.bits', 2048);
|
||||
|
||||
// Keypair erzeugen
|
||||
$res = app(DkimService::class)->generateForDomain(
|
||||
domainId: $domain,
|
||||
bits: $bits,
|
||||
selector: $selector
|
||||
);
|
||||
|
||||
// In dkim_keys speichern
|
||||
$dk = DkimKey::create([
|
||||
'domain_id' => $domain->id,
|
||||
'selector' => $res['selector'],
|
||||
'private_key_pem' => $res['private_pem'],
|
||||
'public_key_txt' => preg_replace('/^v=DKIM1; k=rsa; p=/', '', $res['dns_txt']),
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
// Helper-Job zum Installieren starten
|
||||
InstallDkimKey::dispatch(
|
||||
domainId: $domain->id,
|
||||
dkimKeyId: $dk->id,
|
||||
privPath: $res['priv_path'],
|
||||
dnsTxtContent: $res['dns_txt']
|
||||
)->afterCommit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Beim Löschen alle DKIM-Selector dieser Domain aus OpenDKIM entfernen.
|
||||
*/
|
||||
public function deleted(Domain $domain): void
|
||||
{
|
||||
// Falls SoftDeletes im Spiel, willst du evtl. forceDeleted spiegeln (s.u.)
|
||||
foreach ($domain->dkimKeys()->get() as $dk) {
|
||||
RemoveDkimKey::dispatch(
|
||||
domainId: $domain->id,
|
||||
selector: $dk->selector
|
||||
)->afterCommit();
|
||||
}
|
||||
}
|
||||
|
||||
public function forceDeleted(Domain $domain): void
|
||||
{
|
||||
$this->deleted($domain);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Domain;
|
||||
use App\Observers\DomainObserver;
|
||||
use App\Support\SettingsRepository;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
|
@ -21,6 +23,9 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot(\App\Support\SettingsRepository $settings): void
|
||||
{
|
||||
|
||||
Domain::observe(DomainObserver::class);
|
||||
|
||||
try {
|
||||
$S = app(\App\Support\SettingsRepository::class);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,9 +54,6 @@ class DkimService
|
|||
throw new \RuntimeException("DKIM: Public-Key schreiben fehlgeschlagen: {$pubRel}");
|
||||
}
|
||||
|
||||
// 4) DNS-Record bauen
|
||||
// $p = preg_replace('/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\s+/', '', $publicKeyPem);
|
||||
// $dnsTxt = "v=DKIM1; k=rsa; p={$p}";
|
||||
|
||||
$publicKeyBase64 = self::extractPublicKeyBase64($publicKeyPem);
|
||||
Log::debug('dkim.p.len', ['len' => strlen($publicKeyBase64)]);
|
||||
|
|
|
|||
|
|
@ -4,4 +4,10 @@ return [
|
|||
'base_domain' => env('BASE_DOMAIN', 'example.com'),
|
||||
'sysmail_sub' => env('SYSMAIL_SUB', 'sysmail'),
|
||||
'dkim_selector' => env('DKIM_SELECTOR', 'mwl1'),
|
||||
|
||||
'dkim' => [
|
||||
'selector' => env('DKIM_SELECTOR', 'mwl1'),
|
||||
'bits' => (int) env('DKIM_BITS', 2048),
|
||||
],
|
||||
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in New Issue