Release 1.0 (#3)

* Nano and timeout error fix #1

* Nano and timeout error fix #2

* Nano and timeout error fix #3

* Nano and timeout error fix #4

* Nano and timeout error fix #5

* Nano and timeout error fix #6

* Nano and timeout error fix #7 (plus css changes for hide buttons)

* Nano and timeout error fix #8 (zoom method)

* Nano zoom fix #9

* Nano zoom fix #10

* Nano zoom fix #11

* Nano zoom fix #12

* Nano zoom fix #13

* Nano zoom fix #14

* Nano zoom fix #15

* Nano zoom fix #16 (ssh-2-promise)

* Nano zoom fix #17 (ssh-2-promise port  fix)

* Full return back to old code with minor fixes

* Terminal size fix #18 (rows & cols fix)

* Test ntfy build notification system

* Silent resize cmds & Auto resize terminal #1

* Silent resize cmds & Auto resize terminal #2

* Docker build update

* Docker build update #2

* Docker build update #3

* Docker build update #4 (cache and cleanup)

* Docker build update #5 (cache and cleanup)

* Docker build update #6 (cache and cleanup)

* Docker build update #7 (final)

* Docker build update #8 (nevermind not finanl)

* Docker build update #9 (nevermind not finanl)

* Docker build update #10

* Docker build update #10 (I hope final)

* Docker build update #10 (actual final)

* Release 1.0!!!!

* Repo clean-up

* Remove files ignored by .gitignore

* Change project name, create logo, change README.md to be soon updated.

* Update README.md #1 (also added MIT License)

* Update README.md #2

* Update README.md #3

* Update README.md #4

* Update README.md #5

* Update README.md #6

* Update README.md #7

* Update README.md

* Add images

* Update image name

* Update README.md

* Final changes to release-1.0

* Update README.md

* Update name (need to fix logo)

* Final updates (I hope for real this time)

* Fix web-socket timeout.

* Fix timeout on close.
This commit was merged in pull request #3.
This commit is contained in:
Karmaa authored and GitHub committed 2024-12-12 18:46:43 -06:00
1 parent b6a3f881a8
commit 15e1fd215e
37 files changed
+855 -207

No files matched your search

-7
View File
@@ -1,7 +0,0 @@
# ~/.bash_logout: executed by bash(1) when login shell exits.
# when leaving the console clear the screen to increase privacy
if [ "$SHLVL" = 1 ]; then
[ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
fi
View File
Whitespace-only changes.
-1
View File
@@ -1 +0,0 @@
{"Key":"unix:///var/run/docker.sock","Name":"","Global":false}
+24 -8
View File
@@ -1,4 +1,5 @@
name: Build and Push Docker Image name: Build and Push Docker Image
on: on:
push: push:
branches: branches:
@@ -8,7 +9,7 @@ on:
tag_name: tag_name:
description: "Custom tag name for the Docker image" description: "Custom tag name for the Docker image"
required: false required: false
default: "development-latest" default: ""
jobs: jobs:
build: build:
@@ -25,7 +26,7 @@ jobs:
- name: Install Dependencies and Build Frontend - name: Install Dependencies and Build Frontend
run: | run: |
cd frontend cd frontend
npm install npm ci
npm run build npm run build
- name: Setup Docker Buildx - name: Setup Docker Buildx
@@ -44,10 +45,10 @@ jobs:
- name: Determine Docker image tag - name: Determine Docker image tag
run: | run: |
echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
if [ -n "${{ github.event.inputs.tag_name }}" ]; then if [ "${{ github.event.inputs.tag_name }}" == "" ]; then
IMAGE_TAG="${{ github.event.inputs.tag_name }}" IMAGE_TAG="${{ github.ref_name }}-development-latest"
else else
IMAGE_TAG="development-latest" IMAGE_TAG="${{ github.event.inputs.tag_name }}"
fi fi
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
@@ -57,8 +58,23 @@ jobs:
context: . context: .
file: ./docker/Dockerfile file: ./docker/Dockerfile
push: true push: true
tags: ghcr.io/${{ env.REPO_OWNER }}/ssh-project:${{ env.IMAGE_TAG }} tags: ghcr.io/${{ env.REPO_OWNER }}/termix:${{ env.IMAGE_TAG }}
labels: org.opencontainers.image.source=https://github.com/${{ github.repository }} labels: org.opencontainers.image.source=https://github.com/${{ github.repository }}
- name: Cleanup Docker Images - name: Notify via ntfy
run: docker image prune -af run: |
curl -d "Docker image build and push completed successfully for tag: ${{ env.IMAGE_TAG }}" \
https://ntfy.karmaashomepage.online/termix-build
- name: Delete all untagged image versions
uses: quartx-analytics/ghcr-cleaner@v1
with:
owner-type: user
token: ${{ secrets.GHCR_TOKEN }}
repository-owner: ${{ github.repository_owner }}
delete-untagged: true
- name: Cleanup Docker Images Locally
run: |
docker image prune -af
docker system prune -af --volumes
+2
View File
@@ -133,6 +133,8 @@ yarn-error.log*
.sudo_as_admin_successful .sudo_as_admin_successful
.wget-hsts .wget-hsts
.git-credentials .git-credentials
.docker/
.bash_logout
# VSCode Files # VSCode Files
.vscode-server/ .vscode-server/
+8
View File
@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
Generated
+1
View File
@@ -0,0 +1 @@
Termix
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+1
View File
@@ -0,0 +1 @@
<svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0, 0, 400,400"><g id="svgg"><path id="path0" d="M108.560 88.160 L 107.200 89.520 107.201 119.660 C 107.203 148.684,107.231 149.847,107.972 151.060 C 109.081 152.881,111.184 153.202,121.920 153.190 C 135.693 153.176,135.650 153.198,136.013 146.043 C 136.374 138.941,137.344 138.000,144.307 138.000 C 151.310 138.000,151.195 138.326,151.198 118.589 C 151.200 102.368,151.159 102.662,153.604 101.398 C 155.225 100.559,162.787 100.566,164.413 101.407 C 166.995 102.742,166.800 93.928,166.800 209.193 C 166.800 322.394,166.676 315.827,168.847 317.348 C 170.271 318.345,229.729 318.345,231.153 317.348 C 233.324 315.827,233.200 322.394,233.200 209.193 C 233.200 93.928,233.005 102.742,235.587 101.407 C 237.475 100.431,245.006 100.562,246.710 101.602 C 248.732 102.834,248.799 103.372,248.817 118.526 C 248.842 138.302,248.736 138.000,255.662 138.000 C 262.571 138.000,263.622 139.047,263.990 146.298 C 264.338 153.153,264.385 153.176,278.080 153.190 C 288.816 153.202,290.919 152.881,292.028 151.060 C 292.769 149.847,292.797 148.684,292.799 119.660 L 292.800 89.520 291.440 88.160 L 290.080 86.800 200.000 86.800 L 109.920 86.800 108.560 88.160 " stroke="none" fill="#dbdbdb" fill-rule="evenodd"></path><path id="path1" d="M187.600 5.600 C 187.600 5.841,185.941 6.000,183.424 6.000 C 181.071 6.000,179.139 6.175,179.000 6.400 C 178.864 6.620,177.334 6.800,175.600 6.800 C 173.866 6.800,172.336 6.980,172.200 7.200 C 172.064 7.420,170.894 7.600,169.600 7.600 C 168.306 7.600,167.136 7.780,167.000 8.000 C 166.864 8.220,165.874 8.400,164.800 8.400 C 163.726 8.400,162.736 8.580,162.600 8.800 C 162.464 9.020,161.553 9.200,160.576 9.200 C 159.599 9.200,158.800 9.380,158.800 9.600 C 158.800 9.820,158.001 10.000,157.024 10.000 C 156.047 10.000,155.148 10.161,155.026 10.358 C 154.818 10.695,154.258 10.817,150.100 11.432 C 149.165 11.571,148.400 11.845,148.400 12.042 C 148.400 12.239,147.860 12.400,147.200 12.400 C 146.540 12.400,146.000 12.580,146.000 12.800 C 146.000 13.020,145.280 13.200,144.400 13.200 C 143.520 13.200,142.800 13.380,142.800 13.600 C 142.800 13.820,142.361 14.000,141.824 14.000 C 141.287 14.000,140.736 14.180,140.600 14.400 C 140.464 14.620,139.924 14.800,139.400 14.800 C 138.876 14.800,138.336 14.980,138.200 15.200 C 138.064 15.420,137.423 15.600,136.776 15.600 C 136.129 15.600,135.600 15.780,135.600 16.000 C 135.600 16.220,135.060 16.400,134.400 16.400 C 133.740 16.400,133.200 16.580,133.200 16.800 C 133.200 17.020,132.840 17.200,132.400 17.200 C 131.960 17.200,131.600 17.380,131.600 17.600 C 131.600 17.820,131.060 18.000,130.400 18.000 C 129.740 18.000,129.200 18.180,129.200 18.400 C 129.200 18.620,128.761 18.800,128.224 18.800 C 127.687 18.800,127.136 18.980,127.000 19.200 C 126.864 19.420,126.403 19.600,125.976 19.600 C 125.549 19.600,125.200 19.780,125.200 20.000 C 125.200 20.220,124.858 20.400,124.441 20.400 C 124.023 20.400,122.655 20.940,121.400 21.600 C 120.145 22.260,118.867 22.800,118.559 22.800 C 118.252 22.800,118.000 22.980,118.000 23.200 C 118.000 23.420,117.671 23.600,117.268 23.600 C 116.238 23.600,112.755 25.421,113.108 25.775 C 113.269 25.935,113.220 26.030,113.000 25.986 C 112.070 25.798,111.299 26.049,110.492 26.800 C 110.020 27.240,109.482 27.600,109.296 27.600 C 108.703 27.600,106.806 28.589,106.803 28.900 C 106.801 29.065,106.440 29.200,106.000 29.200 C 105.560 29.200,105.200 29.380,105.200 29.600 C 105.200 29.820,104.840 30.000,104.400 30.000 C 103.960 30.000,103.600 30.180,103.600 30.400 C 103.600 30.620,103.364 30.800,103.075 30.800 C 102.787 30.800,102.164 31.160,101.692 31.600 C 101.220 32.040,100.638 32.400,100.400 32.400 C 100.162 32.400,99.580 32.760,99.108 33.200 C 98.636 33.640,98.013 34.000,97.725 34.000 C 97.436 34.000,97.200 34.180,97.200 34.400 C 97.200 34.620,97.010 34.800,96.778 34.800 C 96.546 34.800,95.296 35.520,94.000 36.400 C 92.704 37.280,91.454 38.000,91.222 38.000 C 90.990 38.000,90.800 38.180,90.800 38.400 C 90.800 38.620,90.557 38.800,90.259 38.800 C 89.962 38.800,89.154 39.340,88.463 40.000 C 87.772 40.660,86.975 41.200,86.692 41.200 C 86.409 41.200,85.917 41.560,85.600 42.000 C 85.283 42.440,84.831 42.800,84.596 42.800 C 84.360 42.800,83.372 43.520,82.400 44.400 C 81.428 45.280,80.472 46.000,80.276 46.000 C 80.081 46.000,79.417 46.540,78.800 47.200 C 78.183 47.860,77.526 48.401,77.340 48.402 C 77.153 48.403,75.871 49.483,74.492 50.802 C 73.113 52.121,71.805 53.200,71.587 53.200 C 71.077 53.200,54.000 70.348,54.000 70.860 C 54.000 71.071,52.920 72.304,51.600 73.600 C 50.280 74.896,49.200 76.145,49.200 76.377 C 49.200 76.609,48.480 77.541,47.600 78.448 C 46.720 79.355,46.000 80.273,46.000 80.488 C 46.000 80.703,45.505 81.356,44.900 81.940 C 44.295 82.523,43.545 83.495,43.232 84.100 C 42.920 84.705,42.515 85.200,42.332 85.200 C 42.150 85.200,42.000 85.443,42.000 85.741 C 42.000 86.038,41.460 86.846,40.800 87.537 C 40.140 88.228,39.600 88.Line truncated

After

Width:  |  Height:  |  Size: 47 KiB

+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Termix.iml" filepath="$PROJECT_DIR$/.idea/Termix.iml" />
</modules>
</component>
</project>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
+455
View File
@@ -0,0 +1,455 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="8497df64-d86b-4c98-ac58-c157d9d3fb1e" name="Changes" comment="Fix web-socket timeout." />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="release-1.0" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GitHubPullRequestSearchHistory">{
&quot;lastFilter&quot;: {}
}</component>
<component name="GithubPullRequestsUISettings"><![CDATA[{
"selectedUrlAndAccountId": {
"url": "https://github.com/LukeGus/Termix",
"accountId": "f107d505-1915-4c73-a3f4-e0440737e1dc"
}
}]]></component>
<component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;636378de&quot;,
&quot;associatedIndex&quot;: 8
}</component>
<component name="ProjectId" id="2pojjnjB8kTL4lo1P2No1yvZp4c" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="1" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"Shell Script.Node Server.js Start.executor": "Run",
"Shell Script.Run backend and frontend.executor": "Run",
"Shell Script.run_backend_frontend.executor": "Run",
"git-widget-placeholder": "release-1.0",
"ignore.virus.scanning.warn.message": "true",
"last_opened_file_path": "C:/Users/Luke/Documents/Personal Projects/Termix/frontend",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"npm.run_start.executor": "Run",
"npm.run_start_frontend.executor": "Run",
"npm.run_start_node_backend.executor": "Run",
"npm.run_start_vite.executor": "Run",
"npm.start.executor": "Run",
"settings.editor.selected.configurable": "ml.llm.LLMConfigurable",
"ts.external.directory.path": "D:\\Program Files (x86)\\Applications\\Jetbrains Webstorm\\WebStorm 2024.3.1\\plugins\\javascript-plugin\\jsLanguageServicesImpl\\external",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="C:\Users\Luke\Documents\Personal Projects\Termix\frontend" />
<recent name="C:\Users\Luke\Documents\Personal Projects\Termix" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="C:\Users\Luke\Documents\Personal Projects\Termix\frontend\src" />
<recent name="D:\Programming Projects\Termix\repo-images" />
<recent name="D:\Programming Projects\SSH-Project-JB\public" />
</key>
</component>
<component name="RunManager" selected="Shell Script.run_backend_frontend">
<configuration name="run_backend_frontend" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="Start-Process &quot;powershell&quot; -ArgumentList &quot;-NoProfile&quot;, &quot;-Command npm run start-vite&quot;; Start-Process &quot;powershell&quot; -ArgumentList &quot;-NoProfile&quot;, &quot;-Command npm run start-server&quot; " />
<option name="INDEPENDENT_SCRIPT_PATH" value="false" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/../../../../../Windows/System32/WindowsPowerShell/v1.0/powershell.exe" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="false" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/frontend" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="false" />
<option name="INTERPRETER_PATH" value="$PROJECT_DIR$/../../../../../Windows/System32/WindowsPowerShell/v1.0/powershell.exe" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="false" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
</configuration>
<configuration name="run_start_frontend" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/frontend/package.json" />
<command value="start" />
<node-interpreter value="project" />
<envs />
<EXTENSION ID="com.intellij.lang.javascript.buildTools.npm.rc.StartBrowserRunConfigurationExtension">
<browser name="a7bb68e0-33c0-4d6f-a81a-aac1fdb870c8" start="true" url="http://localhost:8080" />
</EXTENSION>
<method v="2" />
</configuration>
<list>
<item itemvalue="npm.run_start_frontend" />
<item itemvalue="Shell Script.run_backend_frontend" />
</list>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-d6986cc7102b-deb605915726-JavaScript-WS-243.22562.112" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="8497df64-d86b-4c98-ac58-c157d9d3fb1e" name="Changes" comment="" />
<created>1733439468142</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1733439468142</updated>
<workItem from="1733439479708" duration="5489000" />
<workItem from="1733448523969" duration="3535000" />
<workItem from="1733549186397" duration="8748000" />
<workItem from="1733599078854" duration="1895000" />
<workItem from="1733601633451" duration="10190000" />
<workItem from="1733644355292" duration="59000" />
<workItem from="1733644430242" duration="42000" />
<workItem from="1733688686708" duration="3433000" />
<workItem from="1733804654516" duration="339000" />
<workItem from="1733805003742" duration="9000" />
<workItem from="1733883751079" duration="757000" />
<workItem from="1733884522510" duration="2933000" />
</task>
<task id="LOCAL-00001" summary="Nano zoom fix #11">
<option name="closed" value="true" />
<created>1733447944692</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1733447944692</updated>
</task>
<task id="LOCAL-00002" summary="Nano zoom fix #11">
<option name="closed" value="true" />
<created>1733448864234</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1733448864234</updated>
</task>
<task id="LOCAL-00003" summary="Nano zoom fix #11">
<option name="closed" value="true" />
<created>1733449234908</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1733449234908</updated>
</task>
<task id="LOCAL-00004" summary="Nano zoom fix #12">
<option name="closed" value="true" />
<created>1733449331913</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1733449331913</updated>
</task>
<task id="LOCAL-00005" summary="Nano zoom fix #13">
<option name="closed" value="true" />
<created>1733449760767</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1733449760767</updated>
</task>
<task id="LOCAL-00006" summary="Nano zoom fix #14">
<option name="closed" value="true" />
<created>1733450304640</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1733450304640</updated>
</task>
<task id="LOCAL-00007" summary="Nano zoom fix #15">
<option name="closed" value="true" />
<created>1733450681262</created>
<option name="number" value="00007" />
<option name="presentableId" value="LOCAL-00007" />
<option name="project" value="LOCAL" />
<updated>1733450681262</updated>
</task>
<task id="LOCAL-00008" summary="Nano zoom fix #16 (ssh-2-promise)">
<option name="closed" value="true" />
<created>1733451925922</created>
<option name="number" value="00008" />
<option name="presentableId" value="LOCAL-00008" />
<option name="project" value="LOCAL" />
<updated>1733451925922</updated>
</task>
<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>
<task id="LOCAL-00010" summary="Terminal size fix #18 (rows &amp; cols fix)">
<option name="closed" value="true" />
<created>1733538097802</created>
<option name="number" value="00010" />
<option name="presentableId" value="LOCAL-00010" />
<option name="project" value="LOCAL" />
<updated>1733538097802</updated>
</task>
<task id="LOCAL-00011" summary="Test ntfy build notification system">
<option name="closed" value="true" />
<created>1733539381433</created>
<option name="number" value="00011" />
<option name="presentableId" value="LOCAL-00011" />
<option name="project" value="LOCAL" />
<updated>1733539381433</updated>
</task>
<task id="LOCAL-00012" summary="Silent resize cmds &amp; Auto resize terminal #1">
<option name="closed" value="true" />
<created>1733553128900</created>
<option name="number" value="00012" />
<option name="presentableId" value="LOCAL-00012" />
<option name="project" value="LOCAL" />
<updated>1733553128900</updated>
</task>
<task id="LOCAL-00013" summary="Silent resize cmds &amp; Auto resize terminal #2">
<option name="closed" value="true" />
<created>1733553902375</created>
<option name="number" value="00013" />
<option name="presentableId" value="LOCAL-00013" />
<option name="project" value="LOCAL" />
<updated>1733553902375</updated>
</task>
<task id="LOCAL-00014" summary="Docker build update">
<option name="closed" value="true" />
<created>1733555933987</created>
<option name="number" value="00014" />
<option name="presentableId" value="LOCAL-00014" />
<option name="project" value="LOCAL" />
<updated>1733555933987</updated>
</task>
<task id="LOCAL-00015" summary="Docker build update #2">
<option name="closed" value="true" />
<created>1733556269270</created>
<option name="number" value="00015" />
<option name="presentableId" value="LOCAL-00015" />
<option name="project" value="LOCAL" />
<updated>1733556269270</updated>
</task>
<task id="LOCAL-00016" summary="Docker build update #3">
<option name="closed" value="true" />
<created>1733556428424</created>
<option name="number" value="00016" />
<option name="presentableId" value="LOCAL-00016" />
<option name="project" value="LOCAL" />
<updated>1733556428424</updated>
</task>
<task id="LOCAL-00017" summary="Docker build update #4 (cache and cleanup)">
<option name="closed" value="true" />
<created>1733556699034</created>
<option name="number" value="00017" />
<option name="presentableId" value="LOCAL-00017" />
<option name="project" value="LOCAL" />
<updated>1733556699034</updated>
</task>
<task id="LOCAL-00018" summary="Docker build update #5 (cache and cleanup)">
<option name="closed" value="true" />
<created>1733556917800</created>
<option name="number" value="00018" />
<option name="presentableId" value="LOCAL-00018" />
<option name="project" value="LOCAL" />
<updated>1733556917800</updated>
</task>
<task id="LOCAL-00019" summary="Docker build update #5 (cache and cleanup)">
<option name="closed" value="true" />
<created>1733557286584</created>
<option name="number" value="00019" />
<option name="presentableId" value="LOCAL-00019" />
<option name="project" value="LOCAL" />
<updated>1733557286584</updated>
</task>
<task id="LOCAL-00020" summary="Docker build update #6 (cache and cleanup)">
<option name="closed" value="true" />
<created>1733557337662</created>
<option name="number" value="00020" />
<option name="presentableId" value="LOCAL-00020" />
<option name="project" value="LOCAL" />
<updated>1733557337662</updated>
</task>
<task id="LOCAL-00021" summary="Docker build update #7 (final)">
<option name="closed" value="true" />
<created>1733557558085</created>
<option name="number" value="00021" />
<option name="presentableId" value="LOCAL-00021" />
<option name="project" value="LOCAL" />
<updated>1733557558085</updated>
</task>
<task id="LOCAL-00022" summary="Docker build update #8 (nevermind not finanl)">
<option name="closed" value="true" />
<created>1733557773727</created>
<option name="number" value="00022" />
<option name="presentableId" value="LOCAL-00022" />
<option name="project" value="LOCAL" />
<updated>1733557773727</updated>
</task>
<task id="LOCAL-00023" summary="Docker build update #9 (nevermind not finanl)">
<option name="closed" value="true" />
<created>1733558138278</created>
<option name="number" value="00023" />
<option name="presentableId" value="LOCAL-00023" />
<option name="project" value="LOCAL" />
<updated>1733558138278</updated>
</task>
<task id="LOCAL-00024" summary="Docker build update #10">
<option name="closed" value="true" />
<created>1733558347319</created>
<option name="number" value="00024" />
<option name="presentableId" value="LOCAL-00024" />
<option name="project" value="LOCAL" />
<updated>1733558347319</updated>
</task>
<task id="LOCAL-00025" summary="Docker build update #10 (I hope final)">
<option name="closed" value="true" />
<created>1733558781194</created>
<option name="number" value="00025" />
<option name="presentableId" value="LOCAL-00025" />
<option name="project" value="LOCAL" />
<updated>1733558781194</updated>
</task>
<task id="LOCAL-00026" summary="Docker build update #10 (actual final)">
<option name="closed" value="true" />
<created>1733558952696</created>
<option name="number" value="00026" />
<option name="presentableId" value="LOCAL-00026" />
<option name="project" value="LOCAL" />
<updated>1733558952696</updated>
</task>
<task id="LOCAL-00027" summary="Release 1.0!!!!">
<option name="closed" value="true" />
<created>1733603759658</created>
<option name="number" value="00027" />
<option name="presentableId" value="LOCAL-00027" />
<option name="project" value="LOCAL" />
<updated>1733603759658</updated>
</task>
<task id="LOCAL-00028" summary="Update README.md #4">
<option name="closed" value="true" />
<created>1733688870582</created>
<option name="number" value="00028" />
<option name="presentableId" value="LOCAL-00028" />
<option name="project" value="LOCAL" />
<updated>1733688870582</updated>
</task>
<task id="LOCAL-00029" summary="Add images">
<option name="closed" value="true" />
<created>1733691729582</created>
<option name="number" value="00029" />
<option name="presentableId" value="LOCAL-00029" />
<option name="project" value="LOCAL" />
<updated>1733691729582</updated>
</task>
<task id="LOCAL-00030" summary="Update image name">
<option name="closed" value="true" />
<created>1733691982293</created>
<option name="number" value="00030" />
<option name="presentableId" value="LOCAL-00030" />
<option name="project" value="LOCAL" />
<updated>1733691982293</updated>
</task>
<task id="LOCAL-00031" summary="Final changes to release-1.0">
<option name="closed" value="true" />
<created>1733692181011</created>
<option name="number" value="00031" />
<option name="presentableId" value="LOCAL-00031" />
<option name="project" value="LOCAL" />
<updated>1733692181011</updated>
</task>
<task id="LOCAL-00032" summary="Update name (need to fix logo)">
<option name="closed" value="true" />
<created>1733692962039</created>
<option name="number" value="00032" />
<option name="presentableId" value="LOCAL-00032" />
<option name="project" value="LOCAL" />
<updated>1733692962039</updated>
</task>
<task id="LOCAL-00033" summary="Final updates (I hope for real this time)">
<option name="closed" value="true" />
<created>1733886236040</created>
<option name="number" value="00033" />
<option name="presentableId" value="LOCAL-00033" />
<option name="project" value="LOCAL" />
<updated>1733886236040</updated>
</task>
<task id="LOCAL-00034" summary="Fix web-socket timeout.">
<option name="closed" value="true" />
<created>1733887722496</created>
<option name="number" value="00034" />
<option name="presentableId" value="LOCAL-00034" />
<option name="project" value="LOCAL" />
<updated>1733887722496</updated>
</task>
<option name="localTasksCounter" value="35" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="Full return back to old code with minor fixes" />
<MESSAGE value="Terminal size fix #18 (rows &amp; cols fix)" />
<MESSAGE value="Test ntfy build notification system" />
<MESSAGE value="Silent resize cmds &amp; Auto resize terminal #1" />
<MESSAGE value="Silent resize cmds &amp; Auto resize terminal #2" />
<MESSAGE value="Docker build update" />
<MESSAGE value="Docker build update #2" />
<MESSAGE value="Docker build update #3" />
<MESSAGE value="Docker build update #4 (cache and cleanup)" />
<MESSAGE value="Docker build update #5 (cache and cleanup)" />
<MESSAGE value="Docker build update #6 (cache and cleanup)" />
<MESSAGE value="Docker build update #7 (final)" />
<MESSAGE value="Docker build update #8 (nevermind not finanl)" />
<MESSAGE value="Docker build update #9 (nevermind not finanl)" />
<MESSAGE value="Docker build update #10" />
<MESSAGE value="Docker build update #10 (I hope final)" />
<MESSAGE value="Docker build update #10 (actual final)" />
<MESSAGE value="Release 1.0!!!!" />
<MESSAGE value="Update README.md #4" />
<MESSAGE value="Add images" />
<MESSAGE value="Update image name" />
<MESSAGE value="Final changes to release-1.0" />
<MESSAGE value="Update name (need to fix logo)" />
<MESSAGE value="Final updates (I hope for real this time)" />
<MESSAGE value="Fix web-socket timeout." />
<option name="LAST_COMMIT_MESSAGE" value="Fix web-socket timeout." />
</component>
</project>
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Luke Gustafson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+49 -1
View File
@@ -1 +1,49 @@
SSH is silly # Repo Stats
![GitHub Repo stars](https://img.shields.io/github/stars/LukeGus/Termix?style=flat&label=Stars)
![GitHub forks](https://img.shields.io/github/forks/LukeGus/Termix?style=flat&label=Forks)
![GitHub Release](https://img.shields.io/github/v/release/LukeGus/Termix?style=flat&label=Release)
#### Top Technologies
[![React Badge](https://img.shields.io/badge/-React-61DBFB?style=flat-square&labelColor=black&logo=react&logoColor=61DBFB)](#)
[![Javascript Badge](https://img.shields.io/badge/-Javascript-F0DB4F?style=flat-square&labelColor=black&logo=javascript&logoColor=F0DB4F)](#)
[![Nodejs Badge](https://img.shields.io/badge/-Nodejs-3C873A?style=flat-square&labelColor=black&logo=node.js&logoColor=3C873A)](#)
[![HTML Badge](https://img.shields.io/badge/-HTML-E34F26?style=flat-square&labelColor=black&logo=html5&logoColor=E34F26)](#)
[![CSS Badge](https://img.shields.io/badge/-CSS-1572B6?style=flat-square&labelColor=black&logo=css3&logoColor=1572B6)](#)
[![Docker Badge](https://img.shields.io/badge/-Docker-2496ED?style=flat-square&labelColor=black&logo=docker&logoColor=2496ED)](#)
<br />
<p align="center">
<a href="https://github.com/LukeGus/Termix">
<img alt="Termimx Banner" src=./repo-images/TermixLogo.png style="width: 125px; height: auto;"> </a>
</p>
# Description
Termix is an open-source forever free self-hosted SSH (other protocols planned, see [Planned Features](#planned-features)) management panel inspired by [Nexterm](https://github.com/gnmyt/Nexterm). Its purpose is to provide an all-in-one docker-hosted web solution to manage your servers in one easy place. I'm using this project to help me learn [React](https://github.com/facebook/react), [Vite](https://github.com/vitejs/vite-plugin-react), and [Docker](https://www.docker.com) but also because I could never settle on a server management software that I enjoyed to use.
> [!WARNING]
> This app is in the VERY early stages of development. Expect bugs, data loss, and possibly even security issues!
# Planned Features
- [x] SSH
- [ ] VNC
- [ ] RDP
- [ ] SMTP (build in file transfer)
- [ ] Split Screen & Tabs
- [ ] ChatGPT/Ollama Integration (for commands)
- [ ] Login Screen
# How Termix is Different
Before developing Termix, I faced the issue of a server management panel that did not have every feature I liked. [Guacamole](https://guacamole.apache.org/) had poor copy/paste abilities and a poor UI. [Shellngn](https://shellngn.com/) was too expensive and all other alternatives had one major problem with them. I plan to develop the management panel of my dreams with even an AI integration for those pesky commands I always forget the syntax of.
# Installation
View the Termix [Wiki](https://github.com/LukeGus/Termix/wiki) for information on how to install Termix. You can also use these links to go directly to guide. [Docker](https://github.com/LukeGus/Termix/wiki/Docker) or [Manual](https://github.com/LukeGus/Termix/wiki/Manual).
# Known Bugs
### Please create an [Issue](https://github.com/LukeGus/Termix/issues) if you find any problems!
Start session button stays connected even if SSH fails to connect.
# Show-off
![Demo Image](repo-images/DemoImage1.png)
# License
Distributed under the MIT license. See LICENSE for more information.
+51 -22
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": {
@@ -3394,9 +3412,9 @@
"optional": true "optional": true
}, },
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.6", "version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -3404,6 +3422,7 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "MIT",
"bin": { "bin": {
"nanoid": "bin/nanoid.cjs" "nanoid": "bin/nanoid.cjs"
}, },
@@ -3539,10 +3558,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 +5792,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 +6349,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 +6372,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",
@@ -7096,9 +7125,9 @@
"optional": true "optional": true
}, },
"nanoid": { "nanoid": {
"version": "3.3.6", "version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true "dev": true
}, },
"negotiator": { "negotiator": {
@@ -7185,9 +7214,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",
+2
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",
+61 -54
View File
@@ -2,97 +2,104 @@ const WebSocket = require('ws');
const ssh2 = require('ssh2'); const ssh2 = require('ssh2');
const http = require('http'); const http = require('http');
// Create an HTTP server to serve WebSocket connections
const server = http.createServer((req, res) => { const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' }); res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('WebSocket server is running\n'); res.end('WebSocket server is running\n');
}); });
// Create a WebSocket server attached to the HTTP server
const wss = new WebSocket.Server({ server }); const wss = new WebSocket.Server({ server });
// WebSocket connection handling
wss.on('connection', (ws) => { wss.on('connection', (ws) => {
console.log('WebSocket connection established'); console.log('WebSocket connection established');
let conn = null; // Declare SSH client outside to manage lifecycle let conn = new ssh2.Client();
let stream = null;
let currentCols = 80;
let currentRows = 24;
let interval = null;
const resizeTerminal = (cols, rows) => {
if (stream && stream.setWindow) {
stream.setWindow(rows, cols, rows * 100, cols * 100); // Adjust terminal size
console.log(`Terminal resized successfully: cols=${cols}, rows=${rows}`);
}
};
ws.on('message', (message) => { ws.on('message', (message) => {
const messageStr = message.toString();
let data;
try { try {
const data = JSON.parse(message); // Try parsing the incoming message as JSON if (messageStr.trim().startsWith('{')) {
data = JSON.parse(messageStr);
// Check if message contains SSH connection details } else if (stream && stream.writable) {
if (data.host && data.username && data.password) { stream.write(messageStr);
if (conn) { return;
conn.end(); // Close any previous connection before starting a new one
} }
} catch (error) {
conn = new ssh2.Client(); // Create a new SSH connection instance console.error('Failed to process message:', error);
// When the SSH connection is ready
conn.on('ready', () => {
console.log('SSH Connection established');
// Start an interactive shell session
conn.shell((err, stream) => {
if (err) {
console.log(`SSH Error: ${err}`);
ws.send(`Error: ${err}`);
return; return;
} }
// Handle data from SSH session if (data?.host && data.port && data.username && data.password) {
stream.on('data', (data) => { conn.on('ready', () => {
console.log(`SSH Output: ${data}`); console.log('SSH Connection established');
ws.send(data.toString()); // Send the SSH output back to WebSocket client
interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
} else {
clearInterval(interval);
}
}, 15000);
conn.shell({ term: 'xterm', cols: currentCols, rows: currentRows }, (error, newStream) => {
if (error) {
console.error(`SSH Shell Error: ${error}`);
ws.send(`Error: Could not establish a shell: ${error.message}`);
return;
}
stream = newStream;
stream.on('data', (chunk) => {
ws.send(chunk.toString());
}); });
// Handle stream close event
stream.on('close', () => { stream.on('close', () => {
console.log('SSH stream closed'); console.log('SSH stream closed');
conn.end(); conn.end();
}); });
// When the WebSocket client sends a message (from terminal input), forward it to the SSH stream
ws.on('message', (message) => {
console.log(`Received message from WebSocket: ${message}`);
stream.write(message); // Write the message (input) to the SSH shell
});
}); });
}).on('error', (err) => { }).on('error', (err) => {
console.log('SSH Connection Error: ', err); console.log('SSH Connection Error:', err);
ws.send(`SSH Error: ${err}`); ws.send(`SSH Connection Error: ${err.message}`);
}).connect({ }).connect({
host: data.host, // Host provided from the client host: data.host,
port: 22, // Default SSH port port: data.port,
username: data.username, // Username provided from the client username: data.username,
password: data.password, // Password provided from the client password: data.password,
keepaliveInterval: 10000,
keepaliveCountMax: 5,
}); });
} } else if (data?.cols && data.rows) {
} catch (error) { currentCols = data.cols;
// If message is not valid JSON (i.e., terminal input), treat it as raw text and send it to SSH currentRows = data.rows;
console.log('Received non-JSON message, sending to SSH session:', message); resizeTerminal(currentCols, currentRows);
if (conn) {
const stream = conn._stream; // Access the SSH stream directly
if (stream && stream.writable) {
stream.write(message); // Write raw input message to SSH stream
}
} else {
console.error('SSH connection is not established yet.');
}
} }
}); });
// Handle WebSocket close event
ws.on('close', () => { ws.on('close', () => {
console.log('WebSocket closed'); console.log('WebSocket closed');
if (interval) {
clearInterval(interval);
}
if (conn) { if (conn) {
conn.end(); // Close SSH connection when WebSocket client disconnects conn.end();
} }
}); });
}); });
// Start the WebSocket server on port 8081
server.listen(8081, () => { server.listen(8081, () => {
console.log('WebSocket server is listening on ws://localhost:8081'); console.log('WebSocket server is listening on ws://localhost:8081');
}); });
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

+3 -3
View File
@@ -2,12 +2,12 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico?v=2" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta
name="description" name="description"
content="Web site created using @vitejs/plugin-react" content="Sever management software for SSH!"
/> />
<link rel="apple-touch-icon" href="/logo192.png" /> <link rel="apple-touch-icon" href="/logo192.png" />
<!-- <!--
@@ -15,7 +15,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
--> -->
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<title>React App</title> <title>Termix</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
+51 -22
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": {
@@ -3394,9 +3412,9 @@
"optional": true "optional": true
}, },
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.6", "version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -3404,6 +3422,7 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "MIT",
"bin": { "bin": {
"nanoid": "bin/nanoid.cjs" "nanoid": "bin/nanoid.cjs"
}, },
@@ -3539,10 +3558,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 +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",
@@ -6319,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",
@@ -6342,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",
@@ -7095,9 +7124,9 @@
"optional": true "optional": true
}, },
"nanoid": { "nanoid": {
"version": "3.3.6", "version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true "dev": true
}, },
"negotiator": { "negotiator": {
@@ -7184,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",
+3 -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",
@@ -24,7 +26,7 @@
}, },
"scripts": { "scripts": {
"start-vite": "cross-env BROWSER=none WDS_SOCKET_PORT=0 vite --port 8080", "start-vite": "cross-env BROWSER=none WDS_SOCKET_PORT=0 vite --port 8080",
"start-server": "node 'D:/Programming Projects/SSH-Project/ssh-project/backend/server.js'", "start-server": "node ./start.js",
"start": "npm run start-vite && npm run start-server", "start": "npm run start-vite && npm run start-server",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
+1 -2
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: 10px; right: 23px;
background-color: rgb(108, 108, 108); background-color: rgb(108, 108, 108);
color: white; color: white;
border: none; border: none;
+79 -29
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,13 +10,13 @@ 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);
const [isSideBarHidden, setIsSideBarHidden] = useState(false); const [isSideBarHidden, setIsSideBarHidden] = useState(false);
useEffect(() => { useEffect(() => {
// Initialize the terminal and the fit addon
terminal.current = new Terminal({ terminal.current = new Terminal({
cursorBlink: true, cursorBlink: true,
theme: { theme: {
@@ -25,23 +25,37 @@ const App = () => {
}, },
macOptionIsMeta: true, macOptionIsMeta: true,
allowProposedApi: true, allowProposedApi: true,
scrollback: 1000, // Allow scrollback so the terminal doesn't lose state scrollback: 5000,
}); });
// Initialize and attach the fit addon to the terminal
fitAddon.current = new FitAddon(); fitAddon.current = new FitAddon();
terminal.current.loadAddon(fitAddon.current); terminal.current.loadAddon(fitAddon.current);
terminal.current.open(terminalRef.current); terminal.current.open(terminalRef.current);
// Resize terminal to fit the container initially
fitAddon.current.fit(); fitAddon.current.fit();
// Adjust terminal size on window resize // Fit the terminal and send the size when needed
const resizeListener = () => { const fitAndNotifyResize = () => {
fitAddon.current.fit(); fitAddon.current.fit();
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
socket.current.send(JSON.stringify({
cols: terminal.current.cols,
rows: terminal.current.rows,
}));
}
}; };
window.addEventListener('resize', resizeListener); window.addEventListener('resize', fitAndNotifyResize);
terminal.current.onResize(({ cols, rows }) => {
console.log(`Terminal resized to cols:${cols}, rows:${rows}`);
fitAndNotifyResize();
});
const handleConnectionEstablished = () => {
fitAndNotifyResize();
};
window.addEventListener('connection-established', handleConnectionEstablished);
// Monitor terminal data (activity) // Monitor terminal data (activity)
terminal.current.onData((data) => { terminal.current.onData((data) => {
@@ -50,27 +64,12 @@ 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
return () => { return () => {
terminal.current.dispose(); terminal.current.dispose();
if (socket.current) { if (socket.current) {
socket.current.close(); socket.current.close();
} }
window.removeEventListener('resize', resizeListener); window.removeEventListener('resize', fitAndNotifyResize);
}; };
}, []); }, []);
@@ -78,11 +77,30 @@ const App = () => {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.host}/ws/`; // Use current host and "/ws/" endpoint const wsUrl = `${protocol}//${window.location.host}/ws/`; // Use current host and "/ws/" endpoint
socket.current = new WebSocket(wsUrl); if (!host || !username || !password) {
terminal.current.writeln('Please fill in all fields.');
return;
}
socket.current = new WebSocket("ws://localhost:8081");
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
})
);
// Dispatch a custom event when connection is open
const event = new Event('connection-established');
window.dispatchEvent(event);
setIsConnected(true); setIsConnected(true);
}; };
@@ -105,7 +123,33 @@ const App = () => {
}; };
const handleSideBarHiding = () => { const handleSideBarHiding = () => {
setIsSideBarHidden((prevState) => !prevState); setIsSideBarHidden((prevState) => {
const newState = !prevState;
if (newState) {
setTimeout(() => {
// Add a delay to ensure layout settles before resize action
fitAddon.current.fit();
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
socket.current.send(JSON.stringify({
cols: terminal.current.cols,
rows: terminal.current.rows,
}));
}
}, 100); // Delay of 100 milliseconds
} else {
setTimeout(() => {
// Refit terminal when showing sidebar as well
fitAddon.current.fit();
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
socket.current.send(JSON.stringify({
cols: terminal.current.cols,
rows: terminal.current.rows,
}));
}
}, 100); // Delay of 100 milliseconds
}
return newState;
});
}; };
return ( return (
@@ -119,6 +163,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"
+1 -1
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 {
+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg> <svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0, 0, 400,400"><g id="svgg"><path id="path0" d="M109.557 87.399 C 107.077 88.747,107.200 87.048,107.200 120.026 L 107.200 150.080 108.577 151.457 L 109.954 152.834 121.966 152.717 C 136.715 152.573,135.661 153.055,136.022 146.298 C 136.411 139.003,137.406 138.000,144.254 138.000 C 148.371 138.000,148.487 137.975,149.631 136.831 L 150.800 135.662 150.800 120.418 C 150.800 100.465,150.659 100.802,159.000 100.804 C 163.752 100.805,165.152 101.282,166.259 103.276 C 166.672 104.021,166.774 124.554,166.786 209.113 C 166.801 322.394,166.676 315.827,168.847 317.348 C 169.688 317.937,172.713 318.000,200.083 318.000 L 230.387 318.000 231.694 316.833 L 233.000 315.666 233.200 209.733 C 233.371 119.206,233.482 103.676,233.967 102.947 C 235.128 101.200,236.451 100.800,241.062 100.801 C 249.331 100.804,249.200 100.488,249.200 120.418 L 249.200 135.662 250.369 136.831 C 251.517 137.979,251.617 138.000,255.869 138.003 C 262.683 138.007,263.626 138.945,263.988 146.077 C 264.344 153.080,263.293 152.571,277.711 152.726 C 290.473 152.864,291.356 152.732,292.353 150.544 C 292.670 149.849,292.800 140.844,292.800 119.670 C 292.800 86.839,292.940 88.713,290.396 87.398 C 288.694 86.518,111.176 86.519,109.557 87.399 " stroke="none" fill="#dbdbdb" fill-rule="evenodd"></path><path id="path1" d="M188.000 5.600 C 188.000 5.840,186.408 6.000,184.024 6.000 C 181.804 6.000,179.938 6.177,179.800 6.400 C 179.664 6.620,177.943 6.800,175.976 6.800 C 173.859 6.800,172.400 6.963,172.400 7.200 C 172.400 7.420,171.421 7.600,170.224 7.600 C 169.027 7.600,167.936 7.780,167.800 8.000 C 167.664 8.220,166.674 8.400,165.600 8.400 C 164.526 8.400,163.524 8.599,163.374 8.843 C 163.183 9.151,162.996 9.121,162.756 8.743 C 162.567 8.444,162.409 8.389,162.406 8.621 C 162.403 8.852,161.746 9.060,160.947 9.083 C 160.148 9.105,159.383 9.293,159.247 9.499 C 159.111 9.705,158.371 9.827,157.601 9.770 C 156.832 9.713,155.957 9.870,155.656 10.119 C 155.356 10.368,154.505 10.520,153.765 10.456 C 153.025 10.393,152.190 10.488,151.910 10.668 C 151.208 11.118,147.996 11.961,146.900 11.982 C 146.405 11.992,146.000 12.180,146.000 12.400 C 146.000 12.620,145.608 12.800,145.128 12.800 C 144.256 12.800,141.577 13.617,141.200 13.998 C 140.966 14.234,140.013 14.495,139.300 14.518 C 139.025 14.526,138.800 14.694,138.800 14.890 C 138.800 15.087,138.665 15.168,138.500 15.071 C 138.335 14.973,137.750 15.080,137.200 15.306 C 136.650 15.533,135.961 15.768,135.669 15.829 C 135.377 15.889,134.837 16.070,134.469 16.231 C 134.101 16.391,133.350 16.596,132.800 16.686 C 132.250 16.776,131.740 17.018,131.667 17.225 C 131.593 17.431,131.188 17.600,130.767 17.600 C 130.345 17.600,130.000 17.780,130.000 18.000 C 130.000 18.220,129.550 18.400,129.000 18.400 C 128.450 18.400,128.000 18.547,128.000 18.728 C 128.000 18.908,127.100 19.300,126.000 19.600 C 124.900 19.900,124.000 20.292,124.000 20.472 C 124.000 20.653,123.651 20.800,123.224 20.800 C 122.797 20.800,122.336 20.980,122.200 21.200 C 122.064 21.420,121.503 21.600,120.953 21.600 C 120.388 21.600,120.060 21.774,120.200 22.000 C 120.348 22.240,119.836 22.402,118.924 22.406 C 117.793 22.411,117.555 22.512,118.000 22.800 C 118.468 23.102,118.357 23.189,117.500 23.194 C 116.895 23.197,116.400 23.380,116.400 23.600 C 116.400 23.820,116.122 24.000,115.783 24.000 C 115.444 24.000,114.780 24.360,114.308 24.800 C 113.836 25.240,113.134 25.600,112.748 25.600 C 112.363 25.600,111.936 25.780,111.800 26.000 C 111.664 26.220,111.203 26.400,110.776 26.400 C 110.349 26.400,110.000 26.591,110.000 26.824 C 110.000 27.057,109.820 27.136,109.600 27.000 C 109.380 26.864,109.200 27.011,109.200 27.326 C 109.200 27.644,108.620 28.036,107.900 28.206 C 107.185 28.374,106.510 28.541,106.400 28.577 C 105.688 28.808,102.081 31.186,101.056 32.100 C 100.377 32.705,99.504 33.200,99.115 33.200 C 98.470 33.200,97.574 33.780,96.184 35.100 C 95.894 35.375,95.483 35.600,95.271 35.600 C 95.058 35.600,94.307 36.140,93.600 36.800 C 92.893 37.460,91.968 38.000,91.544 38.000 C 91.120 38.000,90.139 38.634,89.364 39.409 C 88.589 40.185,87.785 40.714,87.577 40.586 C 87.370 40.458,87.200 40.543,87.200 40.776 C 87.200 41.009,86.942 41.200,86.627 41.200 C 86.312 41.200,85.939 41.563,85.798 42.006 C 85.657 42.449,85.390 42.717,85.203 42.602 C 85.017 42.487,84.601 42.656,84.280 42.977 C 83.958 43.299,83.605 43.472,83.495 43.361 C 83.384 43.251,82.452 43.890,81.423 44.780 C 80.393 45.671,79.388 46.400,79.188 46.400 C 78.989 46.400,78.940 46.700,79.081 47.066 C 79.252 47.513,79.183 47.636,78.868 47.442 C 78.611 47.283,78.400 47.343,78.400 47.576 C 78.400 47.809,78.170 48.000,77.888 48.000 C 77.607 48.000,77.117 48.360,76.800 48.800 C 76.483 49.240,75.983 49.600,75.688 49.600 C 75.394 49.600,75.251 49.759,75.371 49.954 C 75.491 50.148,75.054 50.529,74.400 50.800 C 73.746 51.071,73.309 51.452,73.429 51.646 C 73.549 51.841,73.470 52.000,73.254 52.000 C 73.Line truncated

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 49 KiB

+12
View File
@@ -0,0 +1,12 @@
// start.js
const { spawn } = require('child_process');
const child = spawn('node', ["\"D:/Programming Projects/Termix/backend/server.js\""], {
stdio: 'inherit', // this is key for interactivity
shell: true, // use system shell
});
child.on('exit', function (code, signal) {
console.log('child process exited with ' +
`code ${code} and signal ${signal}`);
});
Executable → Regular
View File
File mode changed.
+1 -10
View File
@@ -1,11 +1,2 @@
Currently: Currently:
Fix issue after nano where the input no longer goes down to the bottom. Done for release!
Fix issue where SSH randomly disconnects
Post inital build.
Overall Features:
SSH/RDP(?)/VNC(?)
Split Screen & Tabs
ChatGPT/Ollama Stuff
SMTP(?)
Login Page
-38
View File
@@ -1,38 +0,0 @@
{
"name": "ssh-project",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"xterm-addon-fit": "^0.8.0"
}
},
"node_modules/xterm": {
"version": "5.3.0",
"license": "MIT",
"peer": true
},
"node_modules/xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"deprecated": "This package is now deprecated. Move to @xterm/addon-fit instead.",
"peerDependencies": {
"xterm": "^5.0.0"
}
}
},
"dependencies": {
"xterm": {
"version": "5.3.0",
"peer": true
},
"xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"requires": {}
}
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"dependencies": {
"xterm-addon-fit": "^0.8.0"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 39 KiB

+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"short_name": "React App", "short_name": "Termix",
"name": "Create React App Sample", "name": "Termix",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "favicon.ico",
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB