envExists()) { render_page('Already installed', '
Cypht is already configured. Delete .env first if you really want to run the installer again.
', 'locked'); exit; } $web_installer = new Hm_Web_Installer($installer, APP_PATH.'.install_token'); session_set_cookie_params(['httponly' => true, 'samesite' => 'Lax', 'secure' => Hm_Web_Installer::isHttps($_SERVER)]); session_start(); if (!$web_installer->tokenExists()) { $web_installer->generateToken(); } $given_token = $_GET['token'] ?? ($_POST['token'] ?? ''); if (!$web_installer->tokenMatches($given_token)) { render_page('Installer locked', 'Missing or invalid access token.
'. 'Retrieve it from .install_token next to this script (over FTP, SSH, or your host\'s file manager; enable "show hidden files" if needed), then reopen this page with ?token= appended.
The server is missing: '.htmlspecialchars(implode(', ', $missing)).'
', 'error'); exit; } if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(24)); } $csrf_token = $_SESSION['csrf_token']; $ajax_action = $_POST['ajax_action'] ?? ''; if ($_SERVER['REQUEST_METHOD'] === 'POST' && in_array($ajax_action, ['test_auth_connection', 'test_storage_dirs'], true)) { header('Content-Type: application/json'); if (!Hm_Web_Installer::secretMatches($csrf_token, $_POST['csrf_token'] ?? '')) { echo json_encode(['success' => false, 'error' => 'Invalid session, reload the form and try again.']); exit; } $values = Hm_Web_Installer::collectFormValues($_POST); if ($ajax_action === 'test_auth_connection') { $errors = Hm_Web_Installer::validate($values, APP_PATH, ['AUTH']); if (!empty($errors)) { echo json_encode(['success' => false, 'error' => implode(' ', $errors)]); exit; } $result = $web_installer->testAuthConnection($values); echo json_encode(['success' => $result['success'], 'error' => $result['error']]); exit; } $errors = Hm_Web_Installer::validate($values, APP_PATH, ['DIRS']); if (!empty($errors)) { echo json_encode(['success' => false, 'error' => implode(' ', $errors)]); exit; } $result = Hm_Web_Installer::checkStorageWritable($values); echo json_encode(['success' => $result['success'], 'error' => $result['error']]); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!Hm_Web_Installer::secretMatches($csrf_token, $_POST['csrf_token'] ?? '')) { render_page('Installer locked', 'Invalid session, reload the form and try again.
', 'locked'); exit; } $values = Hm_Web_Installer::collectFormValues($_POST); $errors = Hm_Web_Installer::validate($values, APP_PATH); if (!empty($errors)) { render_page('Installation failed', ''.htmlspecialchars($result['output']).''; if ($result['success']) { $web_installer->consumeToken(); render_page('Installation complete', $body.'
Delete or rename install.php now.
', 'success'); } else { $hint = $result['env_written'] ? '.env was written before this step failed. If you retry, delete .env first or the installer will report itself as already configured.
' : ''; render_page('Installation failed', $body.$hint, 'error'); } } catch (Throwable $e) { error_log('Cypht installer error: '.$e->getMessage()); render_page('Installation failed', 'An unexpected error occurred. Check the server error log.
', 'error'); } exit; } render_form($csrf_token, $given_token); function field($name, $label, $type = 'text', $hint = '', $required = false) { $hint_html = $hint ? ''.htmlspecialchars($hint).'' : ''; $input = ''; if ($type === 'checkbox') { return ''; } return ''; } function driver_select() { $opts = ''; foreach (['mysql', 'pgsql', 'sqlite'] as $driver) { $opts .= ''; } return ''; } function auth_type_select() { $opts = ''; foreach (['DB' => 'Database', 'IMAP' => 'IMAP server', 'LDAP' => 'LDAP server'] as $value => $label) { $opts .= ''; } return ''; } function auth_fields_group($auth_type, $fields, $visible_by_default = false) { return '