Terminal size fix #18 (rows & cols fix)

This commit is contained in:
LukeGus
2024-12-06 20:21:14 -06:00
parent fe09966196
commit bda3fe9b31
10 changed files with 149 additions and 59 deletions

22
.idea/workspace.xml generated
View File

@@ -4,10 +4,17 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="8497df64-d86b-4c98-ac58-c157d9d3fb1e" name="Changes" comment="Nano zoom fix #16 (ssh-2-promise)"> <list default="true" id="8497df64-d86b-4c98-ac58-c157d9d3fb1e" name="Changes" comment="Full return back to old code with minor fixes">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/backend/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/backend/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/backend/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/backend/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/backend/server.js" beforeDir="false" afterPath="$PROJECT_DIR$/backend/server.js" afterDir="false" /> <change beforePath="$PROJECT_DIR$/backend/server.js" beforeDir="false" afterPath="$PROJECT_DIR$/backend/server.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/src/App.css" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/App.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/src/App.jsx" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/App.jsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/frontend/src/App.jsx" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/App.jsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/src/index.css" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/info.txt" beforeDir="false" afterPath="$PROJECT_DIR$/info.txt" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -181,7 +188,15 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1733451925922</updated> <updated>1733451925922</updated>
</task> </task>
<option name="localTasksCounter" value="9" /> <task id="LOCAL-00009" summary="Full return back to old code with minor fixes">
<option name="closed" value="true" />
<created>1733532896448</created>
<option name="number" value="00009" />
<option name="presentableId" value="LOCAL-00009" />
<option name="project" value="LOCAL" />
<updated>1733532896448</updated>
</task>
<option name="localTasksCounter" value="10" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -194,6 +209,7 @@
<MESSAGE value="Nano zoom fix #14" /> <MESSAGE value="Nano zoom fix #14" />
<MESSAGE value="Nano zoom fix #15" /> <MESSAGE value="Nano zoom fix #15" />
<MESSAGE value="Nano zoom fix #16 (ssh-2-promise)" /> <MESSAGE value="Nano zoom fix #16 (ssh-2-promise)" />
<option name="LAST_COMMIT_MESSAGE" value="Nano zoom fix #16 (ssh-2-promise)" /> <MESSAGE value="Full return back to old code with minor fixes" />
<option name="LAST_COMMIT_MESSAGE" value="Full return back to old code with minor fixes" />
</component> </component>
</project> </project>

View File

@@ -11,6 +11,8 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3", "@testing-library/user-event": "^14.4.3",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"express": "^4.21.1", "express": "^4.21.1",
"guacamole-common-js": "^1.5.0", "guacamole-common-js": "^1.5.0",
"http-proxy-middleware": "^3.0.3", "http-proxy-middleware": "^3.0.3",
@@ -1501,6 +1503,19 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true "dev": true
}, },
"node_modules/@xterm/addon-fit": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz",
"integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==",
"peerDependencies": {
"@xterm/xterm": "^5.0.0"
}
},
"node_modules/@xterm/xterm": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A=="
},
"node_modules/abab": { "node_modules/abab": {
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -2288,10 +2303,9 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.21.1", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
@@ -2312,7 +2326,7 @@
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "2.4.1", "on-finished": "2.4.1",
"parseurl": "~1.3.3", "parseurl": "~1.3.3",
"path-to-regexp": "0.1.10", "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7", "proxy-addr": "~2.0.7",
"qs": "6.13.0", "qs": "6.13.0",
"range-parser": "~1.2.1", "range-parser": "~1.2.1",
@@ -2327,6 +2341,10 @@
}, },
"engines": { "engines": {
"node": ">= 0.10.0" "node": ">= 0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
} }
}, },
"node_modules/express/node_modules/debug": { "node_modules/express/node_modules/debug": {
@@ -3539,10 +3557,9 @@
} }
}, },
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
"version": "0.1.10", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
"license": "MIT"
}, },
"node_modules/pathe": { "node_modules/pathe": {
"version": "1.1.1", "version": "1.1.1",
@@ -5774,6 +5791,17 @@
} }
} }
}, },
"@xterm/addon-fit": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz",
"integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==",
"requires": {}
},
"@xterm/xterm": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A=="
},
"abab": { "abab": {
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -6320,9 +6348,9 @@
} }
}, },
"express": { "express": {
"version": "4.21.1", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"requires": { "requires": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
@@ -6343,7 +6371,7 @@
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "2.4.1", "on-finished": "2.4.1",
"parseurl": "~1.3.3", "parseurl": "~1.3.3",
"path-to-regexp": "0.1.10", "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7", "proxy-addr": "~2.0.7",
"qs": "6.13.0", "qs": "6.13.0",
"range-parser": "~1.2.1", "range-parser": "~1.2.1",
@@ -7185,9 +7213,9 @@
"dev": true "dev": true
}, },
"path-to-regexp": { "path-to-regexp": {
"version": "0.1.10", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
}, },
"pathe": { "pathe": {
"version": "1.1.1", "version": "1.1.1",

View File

@@ -6,6 +6,8 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3", "@testing-library/user-event": "^14.4.3",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"express": "^4.21.1", "express": "^4.21.1",
"guacamole-common-js": "^1.5.0", "guacamole-common-js": "^1.5.0",
"http-proxy-middleware": "^3.0.3", "http-proxy-middleware": "^3.0.3",

View File

@@ -22,13 +22,21 @@ wss.on('connection', (ws) => {
const data = JSON.parse(message); // Try parsing the incoming message as JSON const data = JSON.parse(message); // Try parsing the incoming message as JSON
// Check if message contains SSH connection details // Check if message contains SSH connection details
if (data.host && data.username && data.password) { if (data.host && data.port && data.username && data.password) {
if (conn) { if (conn) {
conn.end(); // Close any previous connection before starting a new one conn.end(); // Close any previous connection before starting a new one
} }
conn = new ssh2.Client(); // Create a new SSH connection instance conn = new ssh2.Client(); // Create a new SSH connection instance
const interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
} else {
clearInterval(interval);
}
}, 15000);
// When the SSH connection is ready // When the SSH connection is ready
conn.on('ready', () => { conn.on('ready', () => {
console.log('SSH Connection established'); console.log('SSH Connection established');
@@ -41,6 +49,10 @@ wss.on('connection', (ws) => {
return; return;
} }
// Set the terminal size dynamically based on the WebSocket message
const sttyCommand = `export TERM=xterm && stty rows ${data.rows} cols ${data.cols}`;
stream.write(sttyCommand + '\n'); // Send the stty command to set terminal size
// Handle data from SSH session // Handle data from SSH session
stream.on('data', (data) => { stream.on('data', (data) => {
console.log(`SSH Output: ${data}`); console.log(`SSH Output: ${data}`);
@@ -64,7 +76,7 @@ wss.on('connection', (ws) => {
ws.send(`SSH Error: ${err}`); ws.send(`SSH Error: ${err}`);
}).connect({ }).connect({
host: data.host, // Host provided from the client host: data.host, // Host provided from the client
port: 22, // Default SSH port port: data.port, // Default SSH port
username: data.username, // Username provided from the client username: data.username, // Username provided from the client
password: data.password, // Password provided from the client password: data.password, // Password provided from the client
keepaliveInterval: 10000, // Send a heartbeat every 10 seconds keepaliveInterval: 10000, // Send a heartbeat every 10 seconds
@@ -88,6 +100,7 @@ wss.on('connection', (ws) => {
// Handle WebSocket close event // Handle WebSocket close event
ws.on('close', () => { ws.on('close', () => {
console.log('WebSocket closed'); console.log('WebSocket closed');
clearInterval(interval);
if (conn) { if (conn) {
conn.end(); // Close SSH connection when WebSocket client disconnects conn.end(); // Close SSH connection when WebSocket client disconnects
} }

View File

@@ -11,6 +11,8 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3", "@testing-library/user-event": "^14.4.3",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"express": "^4.21.1", "express": "^4.21.1",
"guacamole-common-js": "^1.5.0", "guacamole-common-js": "^1.5.0",
"http-proxy-middleware": "^3.0.3", "http-proxy-middleware": "^3.0.3",
@@ -1501,6 +1503,19 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true "dev": true
}, },
"node_modules/@xterm/addon-fit": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz",
"integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==",
"peerDependencies": {
"@xterm/xterm": "^5.0.0"
}
},
"node_modules/@xterm/xterm": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A=="
},
"node_modules/abab": { "node_modules/abab": {
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -2288,10 +2303,9 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.21.1", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
@@ -2312,7 +2326,7 @@
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "2.4.1", "on-finished": "2.4.1",
"parseurl": "~1.3.3", "parseurl": "~1.3.3",
"path-to-regexp": "0.1.10", "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7", "proxy-addr": "~2.0.7",
"qs": "6.13.0", "qs": "6.13.0",
"range-parser": "~1.2.1", "range-parser": "~1.2.1",
@@ -2327,6 +2341,10 @@
}, },
"engines": { "engines": {
"node": ">= 0.10.0" "node": ">= 0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
} }
}, },
"node_modules/express/node_modules/debug": { "node_modules/express/node_modules/debug": {
@@ -3539,10 +3557,9 @@
} }
}, },
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
"version": "0.1.10", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
"license": "MIT"
}, },
"node_modules/pathe": { "node_modules/pathe": {
"version": "1.1.1", "version": "1.1.1",
@@ -5773,6 +5790,17 @@
} }
} }
}, },
"@xterm/addon-fit": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz",
"integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==",
"requires": {}
},
"@xterm/xterm": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A=="
},
"abab": { "abab": {
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -6319,9 +6347,9 @@
} }
}, },
"express": { "express": {
"version": "4.21.1", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"requires": { "requires": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
@@ -6342,7 +6370,7 @@
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "2.4.1", "on-finished": "2.4.1",
"parseurl": "~1.3.3", "parseurl": "~1.3.3",
"path-to-regexp": "0.1.10", "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7", "proxy-addr": "~2.0.7",
"qs": "6.13.0", "qs": "6.13.0",
"range-parser": "~1.2.1", "range-parser": "~1.2.1",
@@ -7184,9 +7212,9 @@
"dev": true "dev": true
}, },
"path-to-regexp": { "path-to-regexp": {
"version": "0.1.10", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
}, },
"pathe": { "pathe": {
"version": "1.1.1", "version": "1.1.1",

View File

@@ -6,6 +6,8 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3", "@testing-library/user-event": "^14.4.3",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"express": "^4.21.1", "express": "^4.21.1",
"guacamole-common-js": "^1.5.0", "guacamole-common-js": "^1.5.0",
"http-proxy-middleware": "^3.0.3", "http-proxy-middleware": "^3.0.3",

View File

@@ -22,7 +22,6 @@
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
justify-content: space-between; justify-content: space-between;
border-radius: 5px;
position: relative; position: relative;
} }
@@ -63,7 +62,7 @@
.hide-sidebar-button { .hide-sidebar-button {
position: fixed; position: fixed;
bottom: 10px; bottom: 10px;
right: 13px; right: 23px;
background-color: rgb(108, 108, 108); background-color: rgb(108, 108, 108);
color: white; color: white;
border: none; border: none;

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Terminal } from 'xterm'; import { Terminal } from '@xterm/xterm';
import 'xterm/css/xterm.css'; import 'xterm/css/xterm.css';
import { FitAddon } from 'xterm-addon-fit'; import { FitAddon } from '@xterm/addon-fit';
import './App.css'; import './App.css';
const App = () => { const App = () => {
@@ -10,6 +10,7 @@ const App = () => {
const fitAddon = useRef(null); const fitAddon = useRef(null);
const socket = useRef(null); const socket = useRef(null);
const [host, setHost] = useState(''); const [host, setHost] = useState('');
const [port, setPort] = useState('22');
const [username, setUsername] = useState(''); const [username, setUsername] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [isConnected, setIsConnected] = useState(false); const [isConnected, setIsConnected] = useState(false);
@@ -50,20 +51,6 @@ const App = () => {
} }
}); });
// Add specific resize call for certain programs like nano or vim
const resizeTerminalOnStart = () => {
// Resize immediately after starting vim/nano or other programs
fitAddon.current.fit();
terminal.current.clear();
};
terminal.current.onData((data) => {
if (data.includes('nano') || data.includes('vim')) {
// Trigger resize immediately when these programs start
resizeTerminalOnStart();
}
});
// Cleanup on component unmount // Cleanup on component unmount
return () => { return () => {
terminal.current.dispose(); terminal.current.dispose();
@@ -87,7 +74,16 @@ const App = () => {
socket.current.onopen = () => { socket.current.onopen = () => {
terminal.current.writeln(`Connected to WebSocket server at ${wsUrl}`); terminal.current.writeln(`Connected to WebSocket server at ${wsUrl}`);
socket.current.send(JSON.stringify({ host, username, password })); socket.current.send(
JSON.stringify({
host,
port,
username,
password,
rows: terminal.current.rows,
cols: terminal.current.cols
})
);
setIsConnected(true); setIsConnected(true);
}; };
@@ -124,6 +120,12 @@ const App = () => {
value={host} value={host}
onChange={(e) => handleInputChange(e, setHost)} onChange={(e) => handleInputChange(e, setHost)}
/> />
<input
type="text"
placeholder="Port"
value={port}
onChange={(e) => handleInputChange(e, setPort)}
/>
<input <input
type="text" type="text"
placeholder="Username" placeholder="Username"

View File

@@ -5,7 +5,7 @@ body {
sans-serif; sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
overflow: hidden; /* Prevent scrolling */ overflow: hidden;
} }
code { code {

View File

@@ -1,8 +1,8 @@
Currently: Currently:
Fix issue after nano where the input no longer goes down to the bottom. Fix issue after nano where the input no longer goes down to the bottom.
Fix issue where SSH randomly disconnects Fix issue where SSH randomly disconnects
lines do not go down a line when wrapping, they overwite previous text on that line
ntfy notifcation after build push ntfy notifcation after build push
numbers dont work in ssh
Overall Features: Overall Features:
SSH/RDP(?)/VNC(?) SSH/RDP(?)/VNC(?)