diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 9f9ce33dbd..1df77f9827 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -98,6 +98,25 @@ class CertificatesV1 extends Worker && isset($certificate['issueDate']) && (($certificate['issueDate'] + ($expiry)) > \time()) ) { // Check last issue time + + // Update document anyway, if needed. + // This occurs when a cert is already generated because a different project is using the domain. + // By updating here we ensure all domains has certificateId assigned (share same certificate document) + if(!isset($document['certificateId'])) { + $certificate = new Document($certificate); + + $domain = new Document(\array_merge($document, [ + 'updated' => \time(), + 'certificateId' => $certificate->getId(), + ])); + + $domain = $dbForConsole->updateDocument('domains', $domain->getId(), $domain); + + if(!$certificate) { + throw new Exception('Failed saving domain to DB'); + } + } + throw new Exception('Renew isn\'t required'); } diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 0beb7d01a8..29b9bc5c49 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -41,6 +41,7 @@ class DeletesV1 extends Worker public function run(): void { + $projectId = $this->args['projectId'] ?? ''; $type = $this->args['type'] ?? ''; @@ -530,11 +531,40 @@ class DeletesV1 extends Worker */ protected function deleteCertificates(Document $document): void { + $consoleDB = $this->getConsoleDB(); + + // If domain has certificate generated + if(isset($document['certificateId'])) { + $domainUsingCertificate = $consoleDB->findOne('domains', [ + new Query('certificateId', Query::TYPE_EQUAL, [$document['certificateId']]) + ]); + + if(!$domainUsingCertificate) { + $mainDomain = App::getEnv('_APP_DOMAIN_TARGET', ''); + if($mainDomain === $document->getAttribute('domain')) { + $domainUsingCertificate = $mainDomain; + } + } + + // If certificate is still used by some domain, mark we can't delete. + // Current domain should not be found, because we only have copy. Original domain is already deleted from database. + if($domainUsingCertificate) { + Console::warning("Skipping certificate deletion, because a domain is still using it."); + return; + } + } + $domain = $document->getAttribute('domain'); $directory = APP_STORAGE_CERTIFICATES . '/' . $domain; $checkTraversal = realpath($directory) === $directory; if ($domain && $checkTraversal && is_dir($directory)) { + // Delete certificate document, so Appwrite is aware of change + if(isset($document['certificateId'])) { + $consoleDB->deleteDocument('certificates', $document['certificateId']); + } + + // Delete files, so Traefik is aware of change array_map('unlink', glob($directory . '/*.*')); rmdir($directory); Console::info("Deleted certificate files for {$domain}");