diff --git a/public/assets/js/terminal.js b/public/assets/js/terminal.js index 8f3bfd2..bafc71a 100644 --- a/public/assets/js/terminal.js +++ b/public/assets/js/terminal.js @@ -12,6 +12,12 @@ terminalInput.addEventListener('keydown', function(e) { } }); +function escapeHtml(str) { + const d = document.createElement('div'); + d.textContent = str; + return d.innerHTML; +} + function executeCommand() { const command = terminalInput.value.trim(); if (!command) return; @@ -46,6 +52,9 @@ function executeCommand() { if (data.stderr) { appendTerminalLine(data.stderr, 'error'); } + if (data.history) { + appendHistoryRow(data.history); + } updateStatus('connected', 'Connected'); } else { appendTerminalLine(data.message || 'Command failed', 'error'); @@ -84,6 +93,23 @@ function clearTerminal() { terminalOutput.innerHTML = ''; } +function appendHistoryRow(h) { + const tbody = document.querySelector('.card-body .table tbody'); + if (!tbody) return; + const emptyState = tbody.closest('.card-body')?.querySelector('.empty-state'); + if (emptyState) emptyState.remove(); + const row = document.createElement('tr'); + const time = h.executed_at ? new Date(h.executed_at.replace(' ', 'T')).toLocaleTimeString('en-US', { hour12: false }) : ''; + row.innerHTML = + '' + time + '' + + '' + escapeHtml(h.command) + '' + + '' + (h.exit_status === 0 ? 'OK' : 'ERR') + '' + + '' + escapeHtml(h.username || 'System') + ''; + tbody.prepend(row); + const container = tbody.closest('.table-responsive'); + if (container) container.scrollTop = 0; +} + function clearHistory() { if (!confirm('Clear all command history for this server?')) return; diff --git a/src/Controllers/TerminalController.php b/src/Controllers/TerminalController.php index b20424f..8e22e0b 100755 --- a/src/Controllers/TerminalController.php +++ b/src/Controllers/TerminalController.php @@ -100,7 +100,7 @@ class TerminalController $ssh->disconnect(); $commandHistory = new CommandHistory(); - $commandHistory->log( + $historyId = $commandHistory->log( $id, Session::get('user_id'), $command, @@ -115,6 +115,13 @@ class TerminalController 'output' => $result['output'], 'exit_status' => $result['exit_status'], 'stderr' => $result['stderr'], + 'history' => [ + 'id' => $historyId, + 'command' => $command, + 'exit_status' => $result['exit_status'] ?? 0, + 'executed_at' => date('Y-m-d H:i:s'), + 'username' => Session::get('username'), + ], ]); } catch (\Throwable $e) { $this->view->json([