peardock/libs/dockerTerminal.js

112 lines
3.8 KiB
JavaScript
Raw Normal View History

2024-12-01 22:01:07 -05:00
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
// DOM Elements
const dockerTerminalModal = document.getElementById('docker-terminal-modal');
const dockerTerminalTitle = document.getElementById('docker-terminal-title');
const dockerTerminalContainer = document.getElementById('docker-terminal-container');
const dockerKillTerminalBtn = document.getElementById('docker-kill-terminal-btn');
// Terminal variables
let dockerTerminalSession = null;
function startDockerTerminal(connectionId, peer) {
2024-12-01 22:14:26 -05:00
if (!peer) {
console.error('[ERROR] No active peer for Docker CLI terminal.');
return;
2024-12-01 22:01:07 -05:00
}
2024-12-01 22:14:26 -05:00
if (dockerTerminalSession) {
console.log('[INFO] Docker CLI terminal session already exists.');
return;
2024-12-01 22:01:07 -05:00
}
2024-12-01 22:14:26 -05:00
const xterm = new Terminal({
cursorBlink: true,
theme: { background: '#000000', foreground: '#ffffff' },
});
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
dockerTerminalContainer.innerHTML = ''; // Clear previous content
xterm.open(dockerTerminalContainer);
fitAddon.fit();
dockerTerminalSession = { xterm, fitAddon, connectionId, peer };
let inputBuffer = ''; // Buffer for user input
xterm.onData((input) => {
if (input === '\r') { // User pressed Enter
const sanitizedInput = sanitizeDockerCommand(inputBuffer.trim());
if (sanitizedInput) {
console.log(`[DEBUG] Sending Docker CLI command: ${sanitizedInput}`);
peer.write(
JSON.stringify({
type: 'dockerCommand',
connectionId,
data: sanitizedInput,
})
);
xterm.write('\r\n'); // Move to the next line in the terminal
} else {
xterm.write('\r\n[ERROR] Invalid command. Only Docker CLI commands are allowed.\r\n');
}
inputBuffer = ''; // Clear the buffer after processing
} else if (input === '\u007F') { // Handle backspace
if (inputBuffer.length > 0) {
inputBuffer = inputBuffer.slice(0, -1); // Remove the last character from the buffer
xterm.write('\b \b'); // Erase the character from the terminal display
}
} else {
inputBuffer += input; // Append input to the buffer
xterm.write(input); // Display input in the terminal
}
});
peer.on('data', (data) => {
try {
const response = JSON.parse(data.toString());
if (response.type === 'dockerOutput' && response.connectionId === connectionId) {
xterm.write(`${response.data}\r\n`);
}
} catch (error) {
console.error(`[ERROR] Failed to parse response from peer: ${error.message}`);
}
});
dockerTerminalTitle.textContent = `Docker CLI Terminal: ${connectionId}`;
dockerTerminalModal.style.display = 'flex';
dockerKillTerminalBtn.onclick = () => {
cleanUpDockerTerminal();
};
}
2024-12-01 22:01:07 -05:00
// Sanitize input to ensure only Docker CLI commands are allowed
function sanitizeDockerCommand(command) {
2024-12-01 22:14:26 -05:00
// Allow commands starting with "docker" and disallow dangerous operators
const isValid = /^docker(\s+[\w.-]+)*$/i.test(command);
return isValid ? command : null;
2024-12-01 22:01:07 -05:00
}
// Clean up Docker CLI terminal session
function cleanUpDockerTerminal() {
2024-12-01 22:14:26 -05:00
if (dockerTerminalSession) {
dockerTerminalSession.xterm.dispose();
dockerTerminalSession = null;
dockerTerminalContainer.innerHTML = ''; // Clear terminal content
dockerTerminalModal.style.display = 'none'; // Hide the modal
dockerTerminalModal.classList.add('hidden');
console.log('[INFO] Docker CLI terminal session cleaned up.');
}
2024-12-01 22:01:07 -05:00
}
2024-12-01 22:14:26 -05:00
2024-12-01 22:01:07 -05:00
// Handle Kill Terminal button
dockerKillTerminalBtn.onclick = () => {
cleanUpDockerTerminal();
};
// Export functions
export { startDockerTerminal, cleanUpDockerTerminal };