mirror of
https://github.com/deployflare/ssh.git
synced 2026-01-13 16:18:02 +00:00
68 lines
3.6 KiB
HTML
68 lines
3.6 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Browser SSH</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<style>
|
|
body, html { margin: 0; padding: 0; height: 100%; width: 100%; overflow: hidden; font-family: sans-serif; background: #1e1e1e; color: #ccc; }
|
|
#terminal-container { width: 100%; height: 100%; }
|
|
#connect-form { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 2em; background: #2a2a2a; border-radius: 8px; box-shadow: 0 0 20px rgba(0,0,0,0.5); z-index: 10; display: flex; flex-direction: column; gap: 1em; min-width: 300px; }
|
|
input, button, textarea { font-size: 1em; padding: 0.5em; border-radius: 4px; border: 1px solid #555; background: #333; color: #eee; }
|
|
button { cursor: pointer; background: #007acc; border-color: #007acc; font-weight: bold; }
|
|
.form-row { display: grid; grid-template-columns: 80px 1fr; gap: 1em; align-items: center; }
|
|
</style>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.min.css" />
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="connect-form">
|
|
<h2>Connect via Worker</h2>
|
|
<div class="form-row"><label for="host">Host:</label><input id="host" type="text" placeholder="ssh.example.com" required></div>
|
|
<div class="form-row"><label for="port">Port:</label><input id="port" type="number" value="22" required></div>
|
|
<div class="form-row"><label for="username">User:</label><input id="username" type="text" placeholder="root" required></div>
|
|
<div class="form-row"><label for="password">Password:</label><input id="password" type="password"></div>
|
|
<div class="form-row"><label for="privateKey">Pvt. Key:</label><textarea id="privateKey" rows="3" placeholder="... or paste RSA/ED25519 key"></textarea></div>
|
|
<button id="connect-btn">Connect</button>
|
|
</div>
|
|
|
|
<div id="terminal-container"></div>
|
|
|
|
<script>
|
|
const term = new Terminal({ convertEol: true, cursorBlink: true, theme: { background: '#1e1e1e' } });
|
|
const fitAddon = new FitAddon.FitAddon();
|
|
term.loadAddon(fitAddon);
|
|
|
|
const connectForm = document.getElementById('connect-form');
|
|
const terminalContainer = document.getElementById('terminal-container');
|
|
|
|
function startSession(params) {
|
|
connectForm.style.display = 'none';
|
|
term.open(terminalContainer);
|
|
fitAddon.fit();
|
|
|
|
const ws = new WebSocket(new URL('/ws', window.location.href).toString().replace(/^http/, 'ws'));
|
|
term.onResize((d) => ws.readyState === 1 && ws.send(JSON.stringify({ resize: d })));
|
|
term.onData((d) => ws.readyState === 1 && ws.send(d));
|
|
ws.onmessage = (e) => term.write(e.data instanceof Blob ? e.data.arrayBuffer().then(b=>new Uint8Array(b)) : e.data);
|
|
ws.onopen = () => ws.send(JSON.stringify(params));
|
|
ws.onclose = (e) => term.writeln(`\r\n\x1b[31m[Connection Closed: ${e.reason || 'Normal'}]\x1b[0m`);
|
|
ws.onerror = () => term.writeln("\r\n\x1b[31m[Connection Error]\x1b[0m");
|
|
|
|
window.addEventListener('resize', () => fitAddon.fit());
|
|
}
|
|
|
|
document.getElementById('connect-btn').addEventListener('click', () => {
|
|
const params = Object.fromEntries(new FormData(connectForm).entries());
|
|
Object.keys(params).forEach(k => !params[k] && delete params[k]);
|
|
startSession({
|
|
host: document.getElementById('host').value, port: document.getElementById('port').value,
|
|
username: document.getElementById('username').value, password: document.getElementById('password').value,
|
|
privateKey: document.getElementById('privateKey').value,
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|