diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index dcc42a87fc..e8741c7c69 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -22,6 +22,7 @@ use Utopia\Database\Exception\Structure; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Domains\Domain; +use Utopia\Fetch\Client; use Utopia\Locale\Locale; use Utopia\Logger\Log; use Utopia\Platform\Action; @@ -48,6 +49,7 @@ class Certificates extends Action $this ->desc('Certificates worker') ->inject('message') + ->inject('project') ->inject('dbForConsole') ->inject('queueForMails') ->inject('queueForEvents') @@ -59,6 +61,7 @@ class Certificates extends Action /** * @param Message $message + * @param Document $project * @param Database $dbForConsole * @param Mail $queueForMails * @param Event $queueForEvents @@ -167,15 +170,26 @@ class Certificates extends Action // Prepare folder name for certbot. Using this helps prevent miss-match in LetsEncrypt configuration when renewing certificate $folder = ID::unique(); - // Generate certificate files using Let's Encrypt - $letsEncryptData = $this->issueCertificate($folder, $domain->get(), $email); + try { + // Generate certificate files using Let's Encrypt + $letsEncryptData = $this->issueCertificate($folder, $domain->get(), $email); + + // Give certificates to Traefik + $this->applyCertificateFiles($folder, $domain->get(), $letsEncryptData); + } catch (\Throwable $th) { + Console::error('Failed to generate Lets Encrypt certificate'); + } // Command succeeded, store all data into document $logs = 'Certificate successfully generated.'; $certificate->setAttribute('logs', \mb_strcut($logs, 0, 1000000));// Limit to 1MB - // Give certificates to Traefik - $this->applyCertificateFiles($folder, $domain->get(), $letsEncryptData); + try { + // TEMP: add custom hostnames to cloudflare + $this->addCustomHostnameToRegistrar($project, $domain->get()); + } catch (\Throwable $th) { + Console::error('Failed to add custom hostname to registrar: ' . $th->getMessage()); + } // Update certificate info stored in database $certificate->setAttribute('renewDate', $this->getRenewDate($domain->get())); @@ -208,6 +222,35 @@ class Certificates extends Action } } + /** + * Add custom hostname to Cloudflare registrar + * + * @param Document $project + * @param string $hostname + * @return void + * @throws Exception + */ + private function addCustomHostnameToRegistrar(Document $project, string $hostname): void + { + $client = new Client(); + $client + ->addHeader('content-type', Client::CONTENT_TYPE_APPLICATION_JSON) + ->addHeader('Authorization', 'Bearer ' . System::getEnv('_APP_SYSTEM_CLOUDFLARE_TOKEN')); + + $response = $client->fetch("https://api.cloudflare.com/client/v4/zones/b2d0e62383d3c0f6299efab107af2c7a/custom_hostnames", Client::METHOD_POST, [ + 'hostname' => $hostname, + 'ssl' => [ + "method" => "http", + "type" => "dv", + "wildcard" => false + ] + ]); + + if ($response->getStatusCode() !== 201) { + throw new Exception('Failed to add custom hostname to Cloudflare: ' . $response->getBody()); + } + } + /** * Save certificate data into database. *