63 lines
1.8 KiB
JavaScript
63 lines
1.8 KiB
JavaScript
'use strict';
|
|
const express = require('express');
|
|
const { WebSocketServer } = require('ws');
|
|
const pty = require('node-pty');
|
|
const http = require('http');
|
|
const https = require('https');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3333;
|
|
|
|
app.use(express.static(path.join(__dirname)));
|
|
|
|
// ホームディレクトリのTailscale証明書を自動検出
|
|
function findCert() {
|
|
const home = os.homedir();
|
|
const crt = fs.readdirSync(home).find((f) => f.endsWith('.crt'));
|
|
if (!crt) return null;
|
|
const key = crt.replace('.crt', '.key');
|
|
if (!fs.existsSync(path.join(home, key))) return null;
|
|
return { cert: fs.readFileSync(path.join(home, crt)), key: fs.readFileSync(path.join(home, key)) };
|
|
}
|
|
|
|
const tlsOpts = findCert();
|
|
const server = tlsOpts ? https.createServer(tlsOpts, app) : http.createServer(app);
|
|
const proto = tlsOpts ? 'https' : 'http';
|
|
|
|
const wss = new WebSocketServer({ server, path: '/terminal' });
|
|
|
|
wss.on('connection', (ws) => {
|
|
const shell = process.env.SHELL || '/bin/bash';
|
|
const ptyProc = pty.spawn(shell, [], {
|
|
name: 'xterm-256color',
|
|
cols: 80,
|
|
rows: 24,
|
|
cwd: process.env.HOME || '/home/ubuntu-pc',
|
|
env: process.env
|
|
});
|
|
|
|
ptyProc.onData((data) => {
|
|
if (ws.readyState === 1) {
|
|
ws.send(JSON.stringify({ type: 'output', data }));
|
|
}
|
|
});
|
|
|
|
ws.on('message', (raw) => {
|
|
try {
|
|
const msg = JSON.parse(raw.toString());
|
|
if (msg.type === 'input') ptyProc.write(msg.data);
|
|
if (msg.type === 'resize') ptyProc.resize(Number(msg.cols), Number(msg.rows));
|
|
} catch {}
|
|
});
|
|
|
|
ws.on('close', () => { try { ptyProc.kill(); } catch {} });
|
|
ptyProc.onExit(() => { try { ws.close(); } catch {} });
|
|
});
|
|
|
|
server.listen(PORT, '0.0.0.0', () => {
|
|
console.log(`posimai-dev running on ${proto}://0.0.0.0:${PORT}`);
|
|
});
|