Release 1.0 #6
No files matched your search
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
{"Key":"unix:///var/run/docker.sock","Name":"","Global":false}
|
||||
@@ -1,4 +1,5 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -8,7 +9,7 @@ on:
|
||||
tag_name:
|
||||
description: "Custom tag name for the Docker image"
|
||||
required: false
|
||||
default: "development-latest"
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,49 +17,64 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
|
||||
- name: Install Dependencies and Build Frontend
|
||||
run: |
|
||||
cd frontend
|
||||
npm install
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Determine Docker image tag
|
||||
run: |
|
||||
echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
|
||||
if [ -n "${{ github.event.inputs.tag_name }}" ]; then
|
||||
IMAGE_TAG="${{ github.event.inputs.tag_name }}"
|
||||
if [ "${{ github.event.inputs.tag_name }}" == "" ]; then
|
||||
IMAGE_TAG="${{ github.ref_name }}-development-latest"
|
||||
else
|
||||
IMAGE_TAG="development-latest"
|
||||
IMAGE_TAG="${{ github.event.inputs.tag_name }}"
|
||||
fi
|
||||
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: Build and Push Docker Image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
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 }}
|
||||
|
||||
- name: Cleanup Docker Images
|
||||
run: docker image prune -af
|
||||
|
||||
- name: Notify via ntfy
|
||||
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
|
||||
@@ -133,6 +133,8 @@ yarn-error.log*
|
||||
.sudo_as_admin_successful
|
||||
.wget-hsts
|
||||
.git-credentials
|
||||
.docker/
|
||||
.bash_logout
|
||||
|
||||
# VSCode Files
|
||||
.vscode-server/
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
Termix
|
||||
@@ -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>
|
||||
@@ -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 |
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,467 @@
|
||||
<?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 timeout on close.">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/frontend/src/App.jsx" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/App.jsx" afterDir="false" />
|
||||
</list>
|
||||
<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">{
|
||||
"lastFilter": {}
|
||||
}</component>
|
||||
<component name="GithubPullRequestsUISettings">{
|
||||
"selectedUrlAndAccountId": {
|
||||
"url": "https://github.com/LukeGus/Termix",
|
||||
"accountId": "f107d505-1915-4c73-a3f4-e0440737e1dc"
|
||||
}
|
||||
}</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"customColor": "636378de",
|
||||
"associatedIndex": 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">{
|
||||
"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 "powershell" -ArgumentList "-NoProfile", "-Command npm run start-vite"; Start-Process "powershell" -ArgumentList "-NoProfile", "-Command npm run start-server" " />
|
||||
<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="Shell Script.run_backend_frontend" />
|
||||
<item itemvalue="npm.run_start_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="3958000" />
|
||||
<workItem from="1734052874393" duration="34000" />
|
||||
</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 & 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 & 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 & 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>
|
||||
<task id="LOCAL-00035" summary="Fix timeout on close.">
|
||||
<option name="closed" value="true" />
|
||||
<created>1733887980750</created>
|
||||
<option name="number" value="00035" />
|
||||
<option name="presentableId" value="LOCAL-00035" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1733887980750</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="36" />
|
||||
<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="Terminal size fix #18 (rows & cols fix)" />
|
||||
<MESSAGE value="Test ntfy build notification system" />
|
||||
<MESSAGE value="Silent resize cmds & Auto resize terminal #1" />
|
||||
<MESSAGE value="Silent resize cmds & 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." />
|
||||
<MESSAGE value="Fix timeout on close." />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Fix timeout on close." />
|
||||
</component>
|
||||
</project>
|
||||
@@ -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.
|
||||
@@ -1 +1,49 @@
|
||||
SSH is silly
|
||||
# Repo Stats
|
||||

|
||||

|
||||

|
||||
#### Top Technologies
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
|
||||
<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
|
||||
|
||||

|
||||
|
||||
# License
|
||||
Distributed under the MIT license. See LICENSE for more information.
|
||||
@@ -11,6 +11,8 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"express": "^4.21.1",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"http-proxy-middleware": "^3.0.3",
|
||||
@@ -1501,6 +1503,19 @@
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"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": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
|
||||
@@ -2288,10 +2303,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"license": "MIT",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
@@ -2312,7 +2326,7 @@
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
@@ -2327,6 +2341,10 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/debug": {
|
||||
@@ -3394,9 +3412,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3404,6 +3422,7 @@
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
@@ -3539,10 +3558,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
|
||||
"license": "MIT"
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
||||
},
|
||||
"node_modules/pathe": {
|
||||
"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": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
|
||||
@@ -6320,9 +6349,9 @@
|
||||
}
|
||||
},
|
||||
"express": {
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
@@ -6343,7 +6372,7 @@
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
@@ -7096,9 +7125,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true
|
||||
},
|
||||
"negotiator": {
|
||||
@@ -7185,9 +7214,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
||||
},
|
||||
"pathe": {
|
||||
"version": "1.1.1",
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"express": "^4.21.1",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"http-proxy-middleware": "^3.0.3",
|
||||
@@ -55,4 +57,4 @@
|
||||
"vite": "^4.5.5",
|
||||
"vitest": "^0.34.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,97 +2,104 @@ const WebSocket = require('ws');
|
||||
const ssh2 = require('ssh2');
|
||||
const http = require('http');
|
||||
|
||||
// Create an HTTP server to serve WebSocket connections
|
||||
const server = http.createServer((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('WebSocket server is running\n');
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('WebSocket server is running\n');
|
||||
});
|
||||
|
||||
// Create a WebSocket server attached to the HTTP server
|
||||
const wss = new WebSocket.Server({ server });
|
||||
|
||||
// WebSocket connection handling
|
||||
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;
|
||||
|
||||
ws.on('message', (message) => {
|
||||
try {
|
||||
const data = JSON.parse(message); // Try parsing the incoming message as JSON
|
||||
|
||||
// Check if message contains SSH connection details
|
||||
if (data.host && data.username && data.password) {
|
||||
if (conn) {
|
||||
conn.end(); // Close any previous connection before starting a new one
|
||||
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}`);
|
||||
}
|
||||
};
|
||||
|
||||
conn = new ssh2.Client(); // Create a new SSH connection instance
|
||||
ws.on('message', (message) => {
|
||||
const messageStr = message.toString();
|
||||
|
||||
// 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;
|
||||
let data;
|
||||
try {
|
||||
if (messageStr.trim().startsWith('{')) {
|
||||
data = JSON.parse(messageStr);
|
||||
} else if (stream && stream.writable) {
|
||||
stream.write(messageStr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle data from SSH session
|
||||
stream.on('data', (data) => {
|
||||
console.log(`SSH Output: ${data}`);
|
||||
ws.send(data.toString()); // Send the SSH output back to WebSocket client
|
||||
});
|
||||
|
||||
// Handle stream close event
|
||||
stream.on('close', () => {
|
||||
console.log('SSH stream closed');
|
||||
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) => {
|
||||
console.log('SSH Connection Error: ', err);
|
||||
ws.send(`SSH Error: ${err}`);
|
||||
}).connect({
|
||||
host: data.host, // Host provided from the client
|
||||
port: 22, // Default SSH port
|
||||
username: data.username, // Username provided from the client
|
||||
password: data.password, // Password provided from the client
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// If message is not valid JSON (i.e., terminal input), treat it as raw text and send it to SSH
|
||||
console.log('Received non-JSON message, sending to SSH session:', message);
|
||||
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
|
||||
} catch (error) {
|
||||
console.error('Failed to process message:', error);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.error('SSH connection is not established yet.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle WebSocket close event
|
||||
ws.on('close', () => {
|
||||
console.log('WebSocket closed');
|
||||
if (conn) {
|
||||
conn.end(); // Close SSH connection when WebSocket client disconnects
|
||||
}
|
||||
});
|
||||
if (data?.host && data.port && data.username && data.password) {
|
||||
conn.on('ready', () => {
|
||||
console.log('SSH Connection established');
|
||||
|
||||
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());
|
||||
});
|
||||
|
||||
stream.on('close', () => {
|
||||
console.log('SSH stream closed');
|
||||
conn.end();
|
||||
});
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
console.log('SSH Connection Error:', err);
|
||||
ws.send(`SSH Connection Error: ${err.message}`);
|
||||
}).connect({
|
||||
host: data.host,
|
||||
port: data.port,
|
||||
username: data.username,
|
||||
password: data.password,
|
||||
keepaliveInterval: 10000,
|
||||
keepaliveCountMax: 5,
|
||||
});
|
||||
} else if (data?.cols && data.rows) {
|
||||
currentCols = data.cols;
|
||||
currentRows = data.rows;
|
||||
resizeTerminal(currentCols, currentRows);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('WebSocket closed');
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
if (conn) {
|
||||
conn.end();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Start the WebSocket server on port 8081
|
||||
server.listen(8081, () => {
|
||||
console.log('WebSocket server is listening on ws://localhost:8081');
|
||||
console.log('WebSocket server is listening on ws://localhost:8081');
|
||||
});
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -2,12 +2,12 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using @vitejs/plugin-react"
|
||||
content="Sever management software for SSH!"
|
||||
/>
|
||||
<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/
|
||||
-->
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<title>React App</title>
|
||||
<title>Termix</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"express": "^4.21.1",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"http-proxy-middleware": "^3.0.3",
|
||||
@@ -1501,6 +1503,19 @@
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"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": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
|
||||
@@ -2288,10 +2303,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"license": "MIT",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
@@ -2312,7 +2326,7 @@
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
@@ -2327,6 +2341,10 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/express/node_modules/debug": {
|
||||
@@ -3394,9 +3412,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3404,6 +3422,7 @@
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
@@ -3539,10 +3558,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
|
||||
"license": "MIT"
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
||||
},
|
||||
"node_modules/pathe": {
|
||||
"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": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
|
||||
@@ -6319,9 +6348,9 @@
|
||||
}
|
||||
},
|
||||
"express": {
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
@@ -6342,7 +6371,7 @@
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
@@ -7095,9 +7124,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true
|
||||
},
|
||||
"negotiator": {
|
||||
@@ -7184,9 +7213,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
||||
},
|
||||
"pathe": {
|
||||
"version": "1.1.1",
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"express": "^4.21.1",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"http-proxy-middleware": "^3.0.3",
|
||||
@@ -24,7 +26,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"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",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -63,7 +62,7 @@
|
||||
.hide-sidebar-button {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
right: 23px;
|
||||
background-color: rgb(108, 108, 108);
|
||||
color: white;
|
||||
border: none;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Terminal } from 'xterm';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import 'xterm/css/xterm.css';
|
||||
import { FitAddon } from 'xterm-addon-fit';
|
||||
import { FitAddon } from '@xterm/addon-fit';
|
||||
import './App.css';
|
||||
|
||||
const App = () => {
|
||||
@@ -10,13 +10,13 @@ const App = () => {
|
||||
const fitAddon = useRef(null);
|
||||
const socket = useRef(null);
|
||||
const [host, setHost] = useState('');
|
||||
const [port, setPort] = useState('22');
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [isSideBarHidden, setIsSideBarHidden] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize the terminal and the fit addon
|
||||
terminal.current = new Terminal({
|
||||
cursorBlink: true,
|
||||
theme: {
|
||||
@@ -25,23 +25,37 @@ const App = () => {
|
||||
},
|
||||
macOptionIsMeta: 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();
|
||||
terminal.current.loadAddon(fitAddon.current);
|
||||
|
||||
terminal.current.open(terminalRef.current);
|
||||
|
||||
// Resize terminal to fit the container initially
|
||||
fitAddon.current.fit();
|
||||
|
||||
// Adjust terminal size on window resize
|
||||
const resizeListener = () => {
|
||||
// Fit the terminal and send the size when needed
|
||||
const fitAndNotifyResize = () => {
|
||||
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)
|
||||
terminal.current.onData((data) => {
|
||||
@@ -50,50 +64,54 @@ 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 () => {
|
||||
terminal.current.dispose();
|
||||
if (socket.current) {
|
||||
socket.current.close();
|
||||
}
|
||||
window.removeEventListener('resize', resizeListener);
|
||||
window.removeEventListener('resize', fitAndNotifyResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleConnect = () => {
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsUrl = `${protocol}//${window.location.host}/ws/`; // Use current host and "/ws/" endpoint
|
||||
|
||||
|
||||
if (!host || !username || !password) {
|
||||
terminal.current.writeln('Please fill in all fields.');
|
||||
return;
|
||||
}
|
||||
|
||||
socket.current = new WebSocket(wsUrl);
|
||||
|
||||
|
||||
socket.current.onopen = () => {
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
socket.current.onmessage = (event) => {
|
||||
terminal.current.write(event.data);
|
||||
};
|
||||
|
||||
|
||||
socket.current.onerror = (error) => {
|
||||
terminal.current.writeln(`WebSocket error: ${error.message}`);
|
||||
};
|
||||
|
||||
|
||||
socket.current.onclose = () => {
|
||||
terminal.current.writeln('Disconnected from WebSocket server.');
|
||||
setIsConnected(false);
|
||||
@@ -105,48 +123,80 @@ const App = () => {
|
||||
};
|
||||
|
||||
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 (
|
||||
<div className="app-container">
|
||||
<div className="main-content">
|
||||
<div className={`sidebar ${isSideBarHidden ? 'hidden' : ''}`}>
|
||||
<h2>Connection Details</h2>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Host"
|
||||
value={host}
|
||||
onChange={(e) => handleInputChange(e, setHost)}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChange={(e) => handleInputChange(e, setUsername)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChange={(e) => handleInputChange(e, setPassword)}
|
||||
/>
|
||||
<button onClick={handleConnect} disabled={isConnected}>
|
||||
{isConnected ? 'Connected' : 'Start Session'}
|
||||
</button>
|
||||
<div className="app-container">
|
||||
<div className="main-content">
|
||||
<div className={`sidebar ${isSideBarHidden ? 'hidden' : ''}`}>
|
||||
<h2>Connection Details</h2>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Host"
|
||||
value={host}
|
||||
onChange={(e) => handleInputChange(e, setHost)}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Port"
|
||||
value={port}
|
||||
onChange={(e) => handleInputChange(e, setPort)}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChange={(e) => handleInputChange(e, setUsername)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChange={(e) => handleInputChange(e, setPassword)}
|
||||
/>
|
||||
<button onClick={handleConnect} disabled={isConnected}>
|
||||
{isConnected ? 'Connected' : 'Start Session'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div ref={terminalRef} className="terminal-container"></div>
|
||||
</div>
|
||||
|
||||
<div ref={terminalRef} className="terminal-container"></div>
|
||||
{/* Hide button always positioned in the bottom-right corner */}
|
||||
<button
|
||||
className="hide-sidebar-button"
|
||||
onClick={handleSideBarHiding}
|
||||
>
|
||||
{isSideBarHidden ? '+' : '-'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Hide button always positioned in the bottom-right corner */}
|
||||
<button
|
||||
className="hide-sidebar-button"
|
||||
onClick={handleSideBarHiding}
|
||||
>
|
||||
{isSideBarHidden ? '+' : '-'}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ body {
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
overflow: hidden; /* Prevent scrolling */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
code {
|
||||
|
||||
@@ -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 |
@@ -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}`);
|
||||
});
|
||||
@@ -1,11 +1,2 @@
|
||||
Currently:
|
||||
Fix issue after nano where the input no longer goes down to the bottom.
|
||||
Fix issue where SSH randomly disconnects
|
||||
Post inital build.
|
||||
|
||||
Overall Features:
|
||||
SSH/RDP(?)/VNC(?)
|
||||
Split Screen & Tabs
|
||||
ChatGPT/Ollama Stuff
|
||||
SMTP(?)
|
||||
Login Page
|
||||
Done for release!
|
||||
@@ -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": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"xterm-addon-fit": "^0.8.0"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 39 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"short_name": "Termix",
|
||||
"name": "Termix",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
|
||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 19 KiB |