diff --git a/app/views/install/installer/js/modules/progress.js b/app/views/install/installer/js/modules/progress.js index 712cda052f..53d7f49a8b 100644 --- a/app/views/install/installer/js/modules/progress.js +++ b/app/views/install/installer/js/modules/progress.js @@ -283,10 +283,10 @@ return !isLocalHost?.(hostname) && !isIPAddress?.(hostname); }; - const pollCertificate = async (domain, maxAttempts, intervalMs) => { + const pollCertificate = async (domain, port, maxAttempts, intervalMs) => { for (let i = 0; i < maxAttempts; i++) { try { - const response = await fetch(`/install/certificate?domain=${encodeURIComponent(domain)}`); + const response = await fetch(`/install/certificate?domain=${encodeURIComponent(domain)}&port=${encodeURIComponent(port)}`); if (response.ok) { const data = await response.json(); if (data.ready) return true; @@ -428,6 +428,7 @@ const initStep5 = (root) => { if (!root) return; + let resolvedProtocol = 'http'; if (activeInstall?.controller) { activeInstall.controller.abort(); @@ -716,8 +717,9 @@ const dataset = getBodyDataset?.() ?? {}; const rawDomain = (formState?.appDomain || dataset.defaultAppDomain || '').trim(); + const httpsPort = (formState?.httpsPort || dataset.defaultHttpsPort || '443').trim(); const domain = extractHostname?.(rawDomain) || rawDomain; - pollCertificate(domain, 15, 2000).then((ready) => { + pollCertificate(domain, httpsPort, 15, 2000).then((ready) => { stopSyncedSpinnerRotation(); const certMessage = ready ? SSL_STEP.done : 'Certificate pending'; animatePanelHeight(() => { @@ -730,7 +732,8 @@ updateInstallRow(row, SSL_STEP, STATUS.COMPLETED, certMessage); } }); - showRedirectStep(sessionDetails, ready ? 'https' : 'http'); + resolvedProtocol = ready ? 'https' : 'http'; + showRedirectStep(sessionDetails, resolvedProtocol); }); }; @@ -943,7 +946,7 @@ const retryButton = event.target.closest('[data-install-retry]'); if (consoleButton) { - redirectToApp('http'); + redirectToApp(resolvedProtocol); return; } diff --git a/src/Appwrite/Platform/Installer/Http/Installer/Certificate/Get.php b/src/Appwrite/Platform/Installer/Http/Installer/Certificate/Get.php index eb18685683..ab0037f4b2 100644 --- a/src/Appwrite/Platform/Installer/Http/Installer/Certificate/Get.php +++ b/src/Appwrite/Platform/Installer/Http/Installer/Certificate/Get.php @@ -5,6 +5,7 @@ namespace Appwrite\Platform\Installer\Http\Installer\Certificate; use Appwrite\Platform\Installer\Validator\AppDomain; use Utopia\Http\Adapter\Swoole\Response; use Utopia\Platform\Action; +use Utopia\Validator\Range; class Get extends Action { @@ -22,11 +23,12 @@ class Get extends Action ->setHttpPath('/install/certificate') ->desc('Check if SSL certificate is ready for a domain') ->param('domain', '', new AppDomain(), 'Domain to check') + ->param('port', 443, new Range(1, 65535), 'HTTPS port to check', true) ->inject('response') ->callback($this->action(...)); } - public function action(string $domain, Response $response): void + public function action(string $domain, int $port, Response $response): void { $domain = trim($domain); if ($domain === '') { @@ -34,14 +36,13 @@ class Get extends Action return; } - $ready = $this->checkHttps($domain); + $ready = $this->checkHttps($domain, $port); $response->json(['ready' => $ready]); } - private function checkHttps(string $domain): bool + private function checkHttps(string $domain, int $port): bool { $gateway = $this->getDockerGateway(); - $port = 443; $ch = curl_init(); $options = [ @@ -77,6 +78,9 @@ class Get extends Action $fields = preg_split('/\s+/', trim($line)); if (isset($fields[1]) && $fields[1] === '00000000' && isset($fields[2])) { $hex = $fields[2]; + if (strlen($hex) !== 8) { + continue; + } $ip = long2ip((int) hexdec($hex[6] . $hex[7] . $hex[4] . $hex[5] . $hex[2] . $hex[3] . $hex[0] . $hex[1])); return $ip; }