$definition) { $formValues[$field] = field_value_from_request($field, $_POST + $_GET, $fieldDefs); } if ($formValues['target'] === '') { $formValues['target'] = default_target_for_profile($selectedProfile); } $message = ''; $messageType = 'ok'; $resultOutput = ''; $resultCode = null; $commandPreview = ''; if (isset($_GET['logout'])) { $_SESSION = []; session_destroy(); header('Location: index.php?lang=' . urlencode($lang)); exit; } if (($_POST['form'] ?? '') === 'login') { $postedLang = detect_lang(supported_languages()); $_SESSION['lang'] = $postedLang; $lang = $postedLang; $loginIp = client_ip_address(); $remainingLock = remaining_lock_seconds($config, $loginIp); if ($remainingLock > 0) { $minutes = (int)max(1, ceil($remainingLock / 60)); $message = str_replace('{minutes}', (string)$minutes, t($lang, 'login_locked')); $messageType = 'error'; append_auth_audit_log($config, $loginIp, 'login_blocked', 'remaining_seconds=' . $remainingLock); } elseif (!verify_csrf($_POST['csrf'] ?? null)) { $message = t($lang, 'csrf_error'); $messageType = 'error'; append_auth_audit_log($config, $loginIp, 'csrf_invalid', 'login-form'); } else { $password = (string)($_POST['password'] ?? ''); $expected = (string)($config['web_password'] ?? ''); if ($expected !== '' && hash_equals($expected, $password)) { register_login_attempt($config, $loginIp, true); append_auth_audit_log($config, $loginIp, 'login_success'); session_regenerate_id(true); $_SESSION['auth'] = true; header('Location: index.php?lang=' . urlencode($lang)); exit; } register_login_attempt($config, $loginIp, false); $remainingAfterFail = remaining_lock_seconds($config, $loginIp); if ($remainingAfterFail > 0) { $minutes = (int)max(1, ceil($remainingAfterFail / 60)); $message = str_replace('{minutes}', (string)$minutes, t($lang, 'login_locked')); append_auth_audit_log($config, $loginIp, 'login_failed_locked', 'remaining_seconds=' . $remainingAfterFail); } else { $message = t($lang, 'invalid_login'); append_auth_audit_log($config, $loginIp, 'login_failed_password'); } $messageType = 'error'; } } if (is_logged_in() && (($_POST['form'] ?? '') === 'run')) { $postedLang = detect_lang(supported_languages()); $_SESSION['lang'] = $postedLang; $lang = $postedLang; try { if (!verify_csrf($_POST['csrf'] ?? null)) { throw new RuntimeException(t($lang, 'csrf_error')); } $request = normalize_run_request($config, $_POST, $lang); $selectedModule = $request['module']; $selectedAction = $request['action']; $selectedProfile = $request['profile']; $workdir = $request['workdir']; foreach ($request['fields'] as $field => $value) { $formValues[$field] = $value; } $result = run_whitelisted_action($config, $request); $resultOutput = (string)($result['output'] ?? ''); $resultCode = (int)($result['exitCode'] ?? 1); $commandPreview = (string)($result['commandPreview'] ?? ''); if (($result['ok'] ?? false) === true) { $message = t($lang, 'status_ok') . ' (exit=' . $resultCode . ')'; $messageType = 'ok'; } else { $message = t($lang, 'status_error') . ' (exit=' . $resultCode . ')'; $messageType = 'error'; } push_execution_history([ 'time' => date('Y-m-d H:i:s'), 'module' => $selectedModule, 'action' => $selectedAction, 'profile' => $selectedProfile, 'exitCode' => $resultCode, 'ok' => $messageType === 'ok', ]); } catch (Throwable $exception) { $message = $exception->getMessage(); $messageType = 'error'; $resultCode = 1; } } $moduleCount = count($catalog); $actionCount = 0; foreach ($catalog as $moduleData) { $actionCount += count($moduleData['actions']); } $history = execution_history(); $activeAction = $catalog[$selectedModule]['actions'][$selectedAction]; $liveStatus = is_logged_in() ? collect_live_status($config, $selectedProfile, $workdir) : null; $clientCatalog = []; foreach ($catalog as $moduleKey => $moduleData) { $clientCatalog[$moduleKey] = [ 'label' => $moduleData['label'], 'description' => $moduleData['description'], 'actions' => [], ]; foreach ($moduleData['actions'] as $actionKey => $actionData) { $clientCatalog[$moduleKey]['actions'][$actionKey] = [ 'label' => $actionData['label'], 'description' => $actionData['description'], 'fields' => $actionData['fields'], 'profiles' => $actionData['profiles'], ]; } } $clientFields = []; foreach ($fieldDefs as $field => $definition) { $clientFields[$field] = [ 'type' => $definition['type'], 'options' => $definition['options'] ?? [], 'target_by_profile' => $definition['target_by_profile'] ?? [], ]; } function render_input(string $field, array $definition, string $value, string $lang, string $profile): string { $label = h(t($lang, $definition['label_key'])); $placeholder = h((string)($definition['placeholder'] ?? '')); $fieldEscaped = h($field); $valueEscaped = h($value); if (($definition['type'] ?? '') === 'select') { $options = $definition['options'] ?? []; if ($field === 'target') { $options = $definition['target_by_profile'][$profile] ?? []; } $html = ''; $html .= ''; return $html; } $type = ($definition['type'] ?? 'text') === 'password' ? 'password' : 'text'; return '' . ''; } ?> <?= h(t($lang, 'title')) ?>

s

'startstop', 'action' => 'start', 'label' => t($lang, 'action_start')], ['module' => 'startstop', 'action' => 'restart', 'label' => t($lang, 'action_restart')], ['module' => 'health', 'action' => 'run', 'label' => t($lang, 'health_run')], ['module' => 'report', 'action' => 'generate', 'label' => t($lang, 'report_generate')], ] as $quick): ?>

/
/

$definition): ?>

  • / / exit=