diff --git a/src/lib/dyn_dns/MailinaboxProvider.php b/src/lib/dyn_dns/MailinaboxProvider.php new file mode 100644 index 0000000..8ee92cc --- /dev/null +++ b/src/lib/dyn_dns/MailinaboxProvider.php @@ -0,0 +1,46 @@ +credentials['mabEmail'] ?? null; + $apiKey = $this->credentials['mabApiKey'] ?? null; + $force = !empty($this->credentials['mabForce']) && $this->credentials['mabForce'] == '1'; + + if (!$email || !$apiKey) { + $this->logger->error("Missing credentials for Mail‑in‑a‑Box DDNS: {$this->domain}"); + return false; + } + + $url = "https://{$this->credentials['mabHost']}/admin/dns/update"; + $postFields = http_build_query([ + 'force' => $force ? 1 : 0, + ]); + + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_USERPWD => "$email:$apiKey", + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $postFields, + CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"], + ]); + + $resp = curl_exec($ch); + if ($resp === false) { + $this->logger->error("Mail‑in‑a‑Box /dns/update request failed: {$this->domain}"); + return false; + } + curl_close($ch); + + if (strpos($resp, 'updated DNS:') !== false) { + $this->logger->info("Mail‑in‑a‑Box DDNS updated for {$this->domain}: $resp"); + return true; + } else { + $this->logger->error("Mail‑in‑a‑Box DDNS update failed for {$this->domain}: $resp"); + return false; + } + } +} diff --git a/src/lib/dyn_dns_update.php b/src/lib/dyn_dns_update.php index 862c770..5db1ea1 100644 --- a/src/lib/dyn_dns_update.php +++ b/src/lib/dyn_dns_update.php @@ -7,6 +7,7 @@ require_once __DIR__ . '/dyn_dns/StratoProvider.php'; require_once __DIR__ . '/dyn_dns/NamecheapProvider.php'; require_once __DIR__ . '/dyn_dns/CloudflareProvider.php'; +require_once __DIR__ . '/dyn_dns/MailinaboxProvider.php'; require_once __DIR__ . '/dyn_dns/HetznerProvider.php'; $domainManager = new PersistentEntityManager(Domain::class, $logger, DB, 'domains'); @@ -34,6 +35,7 @@ 'strato' => StratoProvider::class, 'namecheap' => NamecheapProvider::class, 'cloudflare' => CloudflareProvider::class, + 'mailinabox' => MailinaboxProvider::class, 'hetzner' => HetznerProvider::class, default => null, }; diff --git a/src/public/domains.php b/src/public/domains.php index ebcac4c..4288572 100644 --- a/src/public/domains.php +++ b/src/public/domains.php @@ -219,6 +219,7 @@ + @@ -350,6 +351,12 @@ { label: 'API Token', id: 'cfApiToken', type: 'text' }, { label: 'Zone ID', id: 'cfZoneId', type: 'text' } ], + mailinabox: [ + { label: 'Host (box.example.com)', id: 'mabHost', type: 'text' }, + { label: 'Email (admin user)', id: 'mabEmail', type: 'text' }, + { label: 'API Key', id: 'mabApiKey', type: 'password' }, + { label: 'Force Update (0 or 1)', id: 'mabForce', type: 'text' } + ], hetzner: [ { label: 'API Token', id: 'hetznerApiToken', type: 'text' }, { label: 'Zone ID', id: 'hetznerZoneId', type: 'text' }