Bots often send commands via `ssh user@host <command>` (exec request) rather than requesting an interactive shell. These were previously rejected silently. Now exec commands are captured, stored on the session record, and displayed in the web UI session detail page. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
3.0 KiB
HTML
82 lines
3.0 KiB
HTML
{{define "content"}}
|
|
<section>
|
|
<h3>Session {{.Session.ID}}</h3>
|
|
<div class="top-grid">
|
|
<article>
|
|
<header>Session Info</header>
|
|
<table>
|
|
<tbody>
|
|
<tr><td><strong>IP</strong></td><td>{{.Session.IP}}</td></tr>
|
|
<tr><td><strong>Country</strong></td><td>{{.Session.Country}}</td></tr>
|
|
<tr><td><strong>Username</strong></td><td>{{.Session.Username}}</td></tr>
|
|
<tr><td><strong>Shell</strong></td><td>{{.Session.ShellName}}</td></tr>
|
|
{{if .Session.ExecCommand}}<tr><td><strong>Exec Command</strong></td><td><code>{{derefString .Session.ExecCommand}}</code></td></tr>{{end}}
|
|
<tr><td><strong>Score</strong></td><td>{{formatScore .Session.HumanScore}}</td></tr>
|
|
<tr><td><strong>Connected</strong></td><td>{{formatTime .Session.ConnectedAt}}</td></tr>
|
|
<tr>
|
|
<td><strong>Disconnected</strong></td>
|
|
<td>{{if .Session.DisconnectedAt}}{{formatTime (derefTime .Session.DisconnectedAt)}}{{else}}<mark>active</mark>{{end}}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</article>
|
|
</div>
|
|
</section>
|
|
|
|
{{if gt .EventCount 0}}
|
|
<section>
|
|
<h3>Session Replay</h3>
|
|
<div style="margin-bottom: 1rem;">
|
|
<button id="btn-play" onclick="replayPlayer.play()">Play</button>
|
|
<button id="btn-pause" onclick="replayPlayer.pause()">Pause</button>
|
|
<button id="btn-reset" onclick="replayPlayer.reset()">Reset</button>
|
|
<label for="speed-select" style="margin-left: 1rem;">Speed:</label>
|
|
<select id="speed-select" onchange="replayPlayer.setSpeed(parseFloat(this.value))">
|
|
<option value="0.5">0.5x</option>
|
|
<option value="1" selected>1x</option>
|
|
<option value="2">2x</option>
|
|
<option value="5">5x</option>
|
|
<option value="10">10x</option>
|
|
</select>
|
|
</div>
|
|
<div id="terminal" style="background: #000; padding: 4px; border-radius: 4px;"></div>
|
|
</section>
|
|
<link rel="stylesheet" href="/static/xterm.css">
|
|
<script src="/static/xterm.min.js"></script>
|
|
<script src="/static/replay.js"></script>
|
|
<script>
|
|
var replayPlayer = new ReplayPlayer("terminal", "{{.Session.ID}}");
|
|
</script>
|
|
{{else}}
|
|
<section>
|
|
<p>No recorded events for this session.</p>
|
|
</section>
|
|
{{end}}
|
|
|
|
{{if .Logs}}
|
|
<section>
|
|
<h3>Command Log</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>Input</th>
|
|
<th>Output</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Logs}}
|
|
<tr>
|
|
<td>{{formatTime .Timestamp}}</td>
|
|
<td><code>{{.Input}}</code></td>
|
|
<td><pre style="margin:0; white-space:pre-wrap;">{{.Output}}</pre></td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
{{end}}
|
|
|
|
<p><a href="/">← Back to dashboard</a></p>
|
|
{{end}}
|