Compare commits

..

12 Commits

Author SHA1 Message Date
Luke Gustafson d7450d5867 New Crowdin updates (#622)
* Update source file en.json

* New translations en.json (Russian)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Korean)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Afrikaans)

* New translations en.json (Arabic)

* New translations en.json (Bulgarian)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Serbian (Cyrillic))

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Vietnamese)

* New translations en.json (Indonesian)

* New translations en.json (Bengali)

* New translations en.json (Thai)

* New translations en.json (Hindi)
2026-03-14 20:07:53 -05:00
Luke Gustafson e9e30cd318 v2.0.0 (#621)
* Guacd, Docker-Compose, RDP (#475)

* fix select edit host but not update view (#438)

* fix: Checksum issue with chocolatey

* fix: Remove homebrew old stuff

* Add Korean translation (#439)

Co-authored-by: 송준우 <2484@coreit.co.kr>

* feat: Automate flatpak

* fix: Add imagemagik to electron builder to resolve build error

* fix: Build error with runtime repo flag

* fix: Flatpak runtime error and install freedesktop ver warning

* fix: Flatpak runtime error and install freedesktop ver warning

* feat: Re-add homebrew cask and move scripts to backend

* fix: No sandbox flag issue

* fix: Change name for electron macos cask output

* fix: Sandbox error with Linux

* fix: Remove comming soon for app stores in readme

* Adding Comment at the end of the public_key on the host on deploy (#440)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* -Add New Interface for Credential DB
-Add Credential Name as a comment into the server authorized_key file

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Sudo auto fill password (#441)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Feature Sudo password auto-fill;

* Fix locale json shema;

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Added Italian Language; (#445)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Added Italian Language;

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Auto collapse snippet folders (#448)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* feat: Add collapsable snippets (customizable in user profile)

* Translations (#447)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Added Italian Language;

* Fix translations;

Removed duplicate keys, synchronised other languages using English as the source, translated added keys, fixed inaccurate translations.

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Remove PTY-level keepalive (#449)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Remove PTY-level keepalive to prevent unwanted terminal output; use SSH-level keepalive instead

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* feat: add Guacamole support for RDP, VNC, and Telnet connections

- Implemented WebSocket support for Guacamole in Nginx configuration.
- Added REST API endpoints for generating connection tokens and checking guacd status.
- Created Guacamole server using guacamole-lite for handling connections.
- Developed frontend components for testing RDP/VNC connections and displaying the remote session.
- Updated package dependencies to include guacamole-common-js and guacamole-lite.
- Enhanced logging for Guacamole operations.

* feat: enhance Guacamole support with RDP and VNC connection settings and UI updates

* feat: Seperate server stats and tunnel management (improved both UI's) then started initial docker implementation

* fix: finalize adding docker to db

* fix: merge syntax errors

* feat: implement mouse coordinate adjustment based on scale factor in GuacamoleDisplay

* feat: add TypeScript definitions for guacamole-common-js module

* feat: enhance Mouse.State constructor to accept optional parameters and object destructuring

* feat: Add support for RDP and VNC connections in SSH host management

- Introduced connectionType field to differentiate between SSH, RDP, VNC, and Telnet in host data structures.
- Updated backend routes to handle RDP/VNC specific fields: domain, security, and ignoreCert.
- Enhanced the HostManagerEditor to include RDP/VNC specific settings and authentication options.
- Implemented token retrieval for RDP/VNC connections using Guacamole API.
- Updated UI components to reflect connection type changes and provide appropriate connection buttons.
- Removed the GuacamoleTestDialog component as its functionality is integrated into the HostManagerEditor.
- Adjusted the TopNavbar and Host components to accommodate new connection types and their respective actions.

* feat: Enhance Guacamole integration with extended configuration options

- Added detailed Guacamole configuration interface for RDP/VNC/Telnet connections, including display, audio, performance, and session settings.
- Implemented logging for token requests and received options for better debugging.
- Updated HostManagerEditor to support new Guacamole configuration fields with validation and default values.
- Integrated Guacamole configuration parsing in HostManagerViewer and Host components.
- Enhanced API requests to include extended Guacamole configuration parameters in the token request.
- Refactored code to convert camelCase configuration keys to kebab-case for compatibility with Guacamole API.

* feat: merge guacd into 2.0.0 and improve UI for host manager and made general bug fixes

---------

Co-authored-by: Tran Trung Kien <kientt13.7@gmail.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: junu <bigdwarf_@naver.com>
Co-authored-by: 송준우 <2484@coreit.co.kr>
Co-authored-by: SlimGary <trash.slim@gmail.com>
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Nunzio Marfè <nunzio.marfe@protonmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: rename api routes and files

* feat: improve guacd ui/backend

* feat: improve guacd ui/backend

* fix: state persistance issues causing refresh

* feat: improge guacd connections, fixed telnet not opening, and improved general guacd integration

* feat: continue improving integration also with bug fixes

* Merge 2.0.0 with 2.0.0 that includes bug fixes (#620)

* Guacd, Docker-Compose, RDP (#475)

* fix select edit host but not update view (#438)

* fix: Checksum issue with chocolatey

* fix: Remove homebrew old stuff

* Add Korean translation (#439)

Co-authored-by: 송준우 <2484@coreit.co.kr>

* feat: Automate flatpak

* fix: Add imagemagik to electron builder to resolve build error

* fix: Build error with runtime repo flag

* fix: Flatpak runtime error and install freedesktop ver warning

* fix: Flatpak runtime error and install freedesktop ver warning

* feat: Re-add homebrew cask and move scripts to backend

* fix: No sandbox flag issue

* fix: Change name for electron macos cask output

* fix: Sandbox error with Linux

* fix: Remove comming soon for app stores in readme

* Adding Comment at the end of the public_key on the host on deploy (#440)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* -Add New Interface for Credential DB
-Add Credential Name as a comment into the server authorized_key file

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Sudo auto fill password (#441)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Feature Sudo password auto-fill;

* Fix locale json shema;

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Added Italian Language; (#445)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Added Italian Language;

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Auto collapse snippet folders (#448)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* feat: Add collapsable snippets (customizable in user profile)

* Translations (#447)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Added Italian Language;

* Fix translations;

Removed duplicate keys, synchronised other languages using English as the source, translated added keys, fixed inaccurate translations.

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* Remove PTY-level keepalive (#449)

* Add termix.rb Cask file

* Update Termix to version 1.9.0 with new checksum

* Update README to remove 'coming soon' notes

* Remove PTY-level keepalive to prevent unwanted terminal output; use SSH-level keepalive instead

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* feat: add Guacamole support for RDP, VNC, and Telnet connections

- Implemented WebSocket support for Guacamole in Nginx configuration.
- Added REST API endpoints for generating connection tokens and checking guacd status.
- Created Guacamole server using guacamole-lite for handling connections.
- Developed frontend components for testing RDP/VNC connections and displaying the remote session.
- Updated package dependencies to include guacamole-common-js and guacamole-lite.
- Enhanced logging for Guacamole operations.

* feat: enhance Guacamole support with RDP and VNC connection settings and UI updates

* feat: Seperate server stats and tunnel management (improved both UI's) then started initial docker implementation

* fix: finalize adding docker to db

* fix: merge syntax errors

* feat: implement mouse coordinate adjustment based on scale factor in GuacamoleDisplay

* feat: add TypeScript definitions for guacamole-common-js module

* feat: enhance Mouse.State constructor to accept optional parameters and object destructuring

* feat: Add support for RDP and VNC connections in SSH host management

- Introduced connectionType field to differentiate between SSH, RDP, VNC, and Telnet in host data structures.
- Updated backend routes to handle RDP/VNC specific fields: domain, security, and ignoreCert.
- Enhanced the HostManagerEditor to include RDP/VNC specific settings and authentication options.
- Implemented token retrieval for RDP/VNC connections using Guacamole API.
- Updated UI components to reflect connection type changes and provide appropriate connection buttons.
- Removed the GuacamoleTestDialog component as its functionality is integrated into the HostManagerEditor.
- Adjusted the TopNavbar and Host components to accommodate new connection types and their respective actions.

* feat: Enhance Guacamole integration with extended configuration options

- Added detailed Guacamole configuration interface for RDP/VNC/Telnet connections, including display, audio, performance, and session settings.
- Implemented logging for token requests and received options for better debugging.
- Updated HostManagerEditor to support new Guacamole configuration fields with validation and default values.
- Integrated Guacamole configuration parsing in HostManagerViewer and Host components.
- Enhanced API requests to include extended Guacamole configuration parameters in the token request.
- Refactored code to convert camelCase configuration keys to kebab-case for compatibility with Guacamole API.

* feat: merge guacd into 2.0.0 and improve UI for host manager and made general bug fixes

---------

Co-authored-by: Tran Trung Kien <kientt13.7@gmail.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: junu <bigdwarf_@naver.com>
Co-authored-by: 송준우 <2484@coreit.co.kr>
Co-authored-by: SlimGary <trash.slim@gmail.com>
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Nunzio Marfè <nunzio.marfe@protonmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: rename api routes and files

* feat: improve guacd ui/backend

* feat: improve guacd ui/backend

* fix: state persistance issues causing refresh

* feat: improge guacd connections, fixed telnet not opening, and improved general guacd integration

* feat: continue improving integration also with bug fixes

---------

Co-authored-by: Wesley Reid <starhound@lostsouls.org>
Co-authored-by: Tran Trung Kien <kientt13.7@gmail.com>
Co-authored-by: junu <bigdwarf_@naver.com>
Co-authored-by: 송준우 <2484@coreit.co.kr>
Co-authored-by: SlimGary <trash.slim@gmail.com>
Co-authored-by: Nunzio Marfè <nunzio.marfe@protonmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: allow customizing guacd backened url

* fix: ssh route mistmatching and guacamole url not changing

* chore: increment ver

* feat: change default to work with default compose, added splits creen support, updated readmes

* fix: linux app not starting due to better sqlite isuses, improved copy/paste system so no context menu, added oidc remember me toggle, improved OS detection for sessions, flatpak invalid key, and sharing hosts with other users errors

* fix: global settings not setting

* chore: update compose

* feat: improve the global status input

* chore: cleanup files

* chore: update export/improt with new host fields

* fix: file manager and docker not loading properly

---------

Co-authored-by: Wesley Reid <starhound@lostsouls.org>
Co-authored-by: Tran Trung Kien <kientt13.7@gmail.com>
Co-authored-by: junu <bigdwarf_@naver.com>
Co-authored-by: 송준우 <2484@coreit.co.kr>
Co-authored-by: SlimGary <trash.slim@gmail.com>
Co-authored-by: Nunzio Marfè <nunzio.marfe@protonmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-14 20:05:05 -05:00
LukeGus a255a08903 fix: oidc, global default, and remember me issues 2026-03-10 23:32:43 -05:00
LukeGus ea2e59abd8 fix: monitoring defaults not saving and OIDC redirect issues 2026-03-10 00:09:58 -05:00
LukeGus 5caadf1d5d fix: macOS submit error due to icon 2026-03-08 23:03:14 -05:00
LukeGus 98d3c86cc7 chore: update cask 2026-03-08 22:27:07 -05:00
LukeGus ee9824d47f fix: macos build error 2026-03-08 21:07:56 -05:00
LukeGus effe419d97 fix: macos build error 2026-03-08 20:21:20 -05:00
LukeGus bb5d104b52 fix: macos build error 2026-03-08 19:57:23 -05:00
LukeGus e4361b9bd1 fix: macos build error 2026-03-08 19:46:29 -05:00
LukeGus 1b8f6b54b4 fix: macos build error 2026-03-08 19:25:54 -05:00
LukeGus a0237dc155 fix: macos build error 2026-03-08 18:44:39 -05:00
122 changed files with 11346 additions and 2573 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
cask "termix" do
version "1.11.1"
sha256 "0551e2bd7a3a030ffb967627d04320c1456259dd26b7a992fc02ea0fd9940315"
version "1.11.2"
sha256 "92eb67e25a302474084aeee92071561b037aff9b2d5d6fdafe33f8aeb18cb05d"
url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_dmg.dmg"
name "Termix"
+21 -3
View File
@@ -46,12 +46,13 @@ If you would like, you can support the project here!\
Termix is an open-source, forever-free, self-hosted all-in-one server management platform. It provides a multi-platform
solution for managing your servers and infrastructure through a single, intuitive interface. Termix offers SSH terminal
access, SSH tunneling capabilities, remote file management, and many other tools. Termix is the perfect
access, remote desktop control (RDP, VNC, Telnet), SSH tunneling capabilities, remote SSH file management, and many other tools. Termix is the perfect
free and self-hosted alternative to Termius available for all platforms.
# Features
- **SSH Terminal Access** - Full-featured terminal with split-screen support (up to 4 panels) with a browser-like tab system. Includes support for customizing the terminal including common terminal themes, fonts, and other components.
- **Remote Desktop Access** - RDP, VNC, and Telnet support over the browser with complete customization and split screening
- **SSH Tunnel Management** - Create and manage SSH tunnels with automatic reconnection and health monitoring and support for -l or -r connections
- **Remote File Manager** - Manage files directly on remote servers with support for viewing and editing code, images, audio, and video. Upload, download, rename, delete, and move files seamlessly with sudo support.
- **Docker Management** - Start, stop, pause, remove containers. View container stats. Control container using docker exec terminal. It was not made to replace Portainer or Dockge but rather to simply manage your containers compared to creating them.
@@ -105,7 +106,7 @@ Supported Devices:
- APK
Visit the Termix [Docs](https://docs.termix.site/install) for more information on how to install Termix on all platforms. Otherwise, view
a sample Docker Compose file here:
a sample Docker Compose file here (you can omit guacd and the network if you don't plan on using remote desktop features):
```yaml
services:
@@ -119,10 +120,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Sponsors
@@ -153,7 +171,7 @@ channel, however, response times may be longer.
# Screenshots
[![YouTube](./repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](./repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="./repo-images/Image 1.png" width="400" alt="Termix Demo 1"/>
+32
View File
@@ -0,0 +1,32 @@
services:
termix:
image: ghcr.io/lukegus/termix:latest
container_name: termix
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
+111 -43
View File
@@ -38,7 +38,7 @@ http {
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
'' '';
}
ssl_protocols TLSv1.2 TLSv1.3;
@@ -87,7 +87,7 @@ http {
location ~ ^/users/sessions(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
@@ -96,16 +96,18 @@ http {
location ~ ^/users(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
}
location ~ ^/version(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -114,7 +116,7 @@ http {
location ~ ^/releases(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -123,7 +125,7 @@ http {
location ~ ^/alerts(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -132,7 +134,7 @@ http {
location ~ ^/rbac(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -141,7 +143,7 @@ http {
location ~ ^/credentials(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -154,7 +156,7 @@ http {
location ~ ^/snippets(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -163,7 +165,7 @@ http {
location ~ ^/terminal(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -175,7 +177,7 @@ http {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -194,7 +196,7 @@ http {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -210,26 +212,26 @@ http {
location ~ ^/encryption(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/quick-connect {
location /host/quick-connect {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/ssh/opkssh-chooser(/.*)?$ {
proxy_pass http://127.0.0.1:30001/ssh/opkssh-chooser$1$is_args$args;
location ~ ^/host/opkssh-chooser(/.*)?$ {
proxy_pass http://127.0.0.1:30001/host/opkssh-chooser$1$is_args$args;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
@@ -243,8 +245,8 @@ http {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
location ~ ^/ssh/opkssh-callback(/.*)?$ {
proxy_pass http://127.0.0.1:30001/ssh/opkssh-callback$1$is_args$args;
location ~ ^/host/opkssh-callback(/.*)?$ {
proxy_pass http://127.0.0.1:30001/host/opkssh-callback$1$is_args$args;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
@@ -258,10 +260,10 @@ http {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
location /ssh/ {
location /host/ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -292,52 +294,86 @@ http {
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
location /ssh/tunnel/ {
location ^~ /guacamole/websocket/ {
proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $http_host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 10s;
proxy_buffering off;
proxy_request_buffering off;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
location ~ ^/guacamole(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /host/tunnel/ {
proxy_pass http://127.0.0.1:30003;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/recent {
location /host/file_manager/recent {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/pinned {
location /host/file_manager/pinned {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/shortcuts {
location /host/file_manager/shortcuts {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/sudo-password {
location /host/file_manager/sudo-password {
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/ssh/ {
location /ssh/file_manager/ {
client_max_body_size 5G;
client_body_timeout 300s;
@@ -345,7 +381,28 @@ http {
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_request_buffering off;
proxy_buffering off;
}
location /host/file_manager/ssh/ {
client_max_body_size 5G;
client_body_timeout 300s;
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -361,7 +418,7 @@ http {
location ~ ^/network-topology(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -370,7 +427,7 @@ http {
location /health {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -379,7 +436,7 @@ http {
location ~ ^/status(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -388,7 +445,7 @@ http {
location ~ ^/metrics(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -398,10 +455,19 @@ http {
proxy_read_timeout 60s;
}
location ~ ^/global-settings(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/uptime(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -410,7 +476,7 @@ http {
location ~ ^/activity(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -419,24 +485,26 @@ http {
location ~ ^/dashboard/preferences(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/;
proxy_pass http://127.0.0.1:30009/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $http_host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
@@ -451,7 +519,7 @@ http {
location ~ ^/docker(/.*)?$ {
proxy_pass http://127.0.0.1:30007;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
+111 -43
View File
@@ -38,7 +38,7 @@ http {
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
'' '';
}
ssl_protocols TLSv1.2 TLSv1.3;
@@ -76,7 +76,7 @@ http {
location ~ ^/users/sessions(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
@@ -85,16 +85,18 @@ http {
location ~ ^/users(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
}
location ~ ^/version(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -103,7 +105,7 @@ http {
location ~ ^/releases(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -112,7 +114,7 @@ http {
location ~ ^/alerts(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -121,7 +123,7 @@ http {
location ~ ^/rbac(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -130,7 +132,7 @@ http {
location ~ ^/credentials(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -143,7 +145,7 @@ http {
location ~ ^/snippets(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -152,7 +154,7 @@ http {
location ~ ^/terminal(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -164,7 +166,7 @@ http {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -183,7 +185,7 @@ http {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -199,26 +201,26 @@ http {
location ~ ^/encryption(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/quick-connect {
location /host/quick-connect {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/ssh/opkssh-chooser(/.*)?$ {
proxy_pass http://127.0.0.1:30001/ssh/opkssh-chooser$1$is_args$args;
location ~ ^/host/opkssh-chooser(/.*)?$ {
proxy_pass http://127.0.0.1:30001/host/opkssh-chooser$1$is_args$args;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
@@ -232,8 +234,8 @@ http {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
location ~ ^/ssh/opkssh-callback(/.*)?$ {
proxy_pass http://127.0.0.1:30001/ssh/opkssh-callback$1$is_args$args;
location ~ ^/host/opkssh-callback(/.*)?$ {
proxy_pass http://127.0.0.1:30001/host/opkssh-callback$1$is_args$args;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
@@ -247,10 +249,10 @@ http {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
location /ssh/ {
location /host/ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -281,52 +283,86 @@ http {
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
location /ssh/tunnel/ {
location ^~ /guacamole/websocket/ {
proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $http_host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 10s;
proxy_buffering off;
proxy_request_buffering off;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
location ~ ^/guacamole(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /host/tunnel/ {
proxy_pass http://127.0.0.1:30003;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/recent {
location /host/file_manager/recent {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/pinned {
location /host/file_manager/pinned {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/shortcuts {
location /host/file_manager/shortcuts {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/sudo-password {
location /host/file_manager/sudo-password {
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/file_manager/ssh/ {
location /ssh/file_manager/ {
client_max_body_size 5G;
client_body_timeout 300s;
@@ -334,7 +370,28 @@ http {
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_request_buffering off;
proxy_buffering off;
}
location /host/file_manager/ssh/ {
client_max_body_size 5G;
client_body_timeout 300s;
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -350,7 +407,7 @@ http {
location ~ ^/network-topology(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -359,7 +416,7 @@ http {
location /health {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -368,7 +425,7 @@ http {
location ~ ^/status(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -377,7 +434,7 @@ http {
location ~ ^/metrics(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -387,10 +444,19 @@ http {
proxy_read_timeout 60s;
}
location ~ ^/global-settings(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/uptime(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -399,7 +465,7 @@ http {
location ~ ^/activity(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@@ -408,24 +474,26 @@ http {
location ~ ^/dashboard/preferences(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/;
proxy_pass http://127.0.0.1:30009/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $http_host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
@@ -440,7 +508,7 @@ http {
location ~ ^/docker(/.*)?$ {
proxy_pass http://127.0.0.1:30007;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
+12 -3
View File
@@ -18,14 +18,22 @@
"!node_modules/@napi-rs/canvas*/**/*",
"!node_modules/@rollup/rollup-darwin-*/**/*",
"!node_modules/@rollup/rollup-linux-*/**/*",
"!node_modules/@rollup/rollup-win32-*/**/*"
"!node_modules/@rollup/rollup-win32-*/**/*",
"!dist/icon-mac.png",
"!public/icon-mac.png",
"!dist/icon.ico",
"!public/icon.ico",
"!dist/icon.icns",
"!public/icon.icns",
"!dist/icons/**/*",
"!public/icons/**/*"
],
"extraMetadata": {
"main": "electron/main.cjs"
},
"buildDependenciesFromSource": false,
"nodeGypRebuild": false,
"npmRebuild": false,
"npmRebuild": true,
"win": {
"target": [
{
@@ -108,7 +116,8 @@
"type": "distribution",
"minimumSystemVersion": "10.15",
"mergeASARs": false,
"singleArchFiles": "node_modules/@tailwindcss/oxide-*/**/*"
"singleArchFiles": "**/*.node",
"x64ArchFiles": "**/*.node"
},
"dmg": {
"artifactName": "termix_macos_${arch}_dmg.${ext}",
-9
View File
@@ -99,8 +99,6 @@ function getBackendEntryPath() {
if (isDev) {
return path.join(appRoot, "dist", "backend", "backend", "starter.js");
}
// In production, asar is disabled (asar: false in electron-builder.json)
// so backend is directly in appRoot/dist
return path.join(appRoot, "dist", "backend", "backend", "starter.js");
}
@@ -133,13 +131,11 @@ function startBackendServer() {
logToFile("Data directory:", dataDir);
logToFile("Backend cwd:", appRoot);
// Verify all required paths exist
logToFile("Checking paths...");
logToFile(" entryPath exists:", fs.existsSync(entryPath));
logToFile(" dataDir exists:", fs.existsSync(dataDir));
logToFile(" appRoot exists:", fs.existsSync(appRoot));
// List contents of dist directory
const distPath = path.join(appRoot, "dist");
if (fs.existsSync(distPath)) {
logToFile(" dist directory contents:", fs.readdirSync(distPath));
@@ -214,7 +210,6 @@ function stopBackendServer() {
console.log("Stopping embedded backend server...");
// Use IPC for graceful shutdown (SIGTERM doesn't work on Windows)
try {
backendProcess.send({ type: "shutdown" });
} catch {
@@ -256,7 +251,6 @@ function createTray() {
let trayIcon;
if (process.platform === "darwin") {
// macOS: use 16x16 Template image for menu bar
const iconPath = path.join(appRoot, "public", "icons", "16x16.png");
trayIcon = nativeImage.createFromPath(iconPath);
trayIcon.setTemplateImage(true);
@@ -304,7 +298,6 @@ function createTray() {
console.log("System tray created successfully");
} catch (err) {
console.error("Failed to create system tray:", err);
// Tray is non-critical; app still works without it
}
}
@@ -871,7 +864,6 @@ app.whenReady().then(async () => {
);
createMenu();
// Start embedded backend server (skip in dev mode, backend runs separately via npm run dev:backend)
if (!isDev) {
const result = await startBackendServer();
logToFile("startBackendServer result:", result);
@@ -887,7 +879,6 @@ app.whenReady().then(async () => {
});
app.on("window-all-closed", () => {
// If tray exists, keep backend alive; otherwise quit normally
if (!tray || tray.isDestroyed()) {
app.quit();
}
-1
View File
@@ -4,7 +4,6 @@ Branch=stable
Title=Termix - SSH Server Management Platform
IsRuntime=false
Url=https://github.com/Termix-SSH/Termix/releases/download/VERSION_PLACEHOLDER/termix_linux_flatpak.flatpak
GPGKey=
RuntimeRepo=https://flathub.org/repo/flathub.flatpakrepo
Comment=Web-based server management platform with SSH terminal, tunneling, and file editing
Description=Termix is an open-source, forever-free, self-hosted all-in-one server management platform. It provides SSH terminal access, tunneling capabilities, and remote file management.
+30 -2
View File
@@ -1,12 +1,12 @@
{
"name": "termix",
"version": "1.11.2",
"version": "2.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "termix",
"version": "1.11.2",
"version": "2.0.0",
"dependencies": {
"@codemirror/autocomplete": "^6.18.7",
"@codemirror/commands": "^6.3.3",
@@ -35,6 +35,7 @@
"@types/bcryptjs": "^2.4.6",
"@types/cookie-parser": "^1.4.9",
"@types/cytoscape": "^3.21.9",
"@types/guacamole-common-js": "^1.5.5",
"@types/jszip": "^3.4.0",
"@types/multer": "^2.0.0",
"@types/qrcode": "^1.5.5",
@@ -62,6 +63,8 @@
"dotenv": "^17.2.0",
"drizzle-orm": "^0.44.3",
"express": "^5.1.0",
"guacamole-common-js": "^1.5.0",
"guacamole-lite": "^1.2.0",
"https-proxy-agent": "^7.0.6",
"i18n-auto-translation": "^2.2.3",
"i18next": "^25.4.2",
@@ -5417,6 +5420,12 @@
"@types/node": "*"
}
},
"node_modules/@types/guacamole-common-js": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/guacamole-common-js/-/guacamole-common-js-1.5.5.tgz",
"integrity": "sha512-dqDYo/PhbOXFGSph23rFDRZRzXdKPXy/nsTkovFMb6P3iGrd0qGB5r5BXHmX5Cr/LK7L1TK9nYrTMbtPkhdXyg==",
"license": "MIT"
},
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
@@ -10582,6 +10591,25 @@
"safe-buffer": "^5.0.1"
}
},
"node_modules/guacamole-common-js": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/guacamole-common-js/-/guacamole-common-js-1.5.0.tgz",
"integrity": "sha512-zxztif3GGhKbg1RgOqwmqot8kXgv2HmHFg1EvWwd4q7UfEKvBcYZ0f+7G8HzvU+FUxF0Psqm9Kl5vCbgfrRgJg==",
"license": "Apache 2.0"
},
"node_modules/guacamole-lite": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/guacamole-lite/-/guacamole-lite-1.2.0.tgz",
"integrity": "sha512-NeSYgbT5s5rxF0SE/kzJsV5Gg0IvnqoTOCbNIUMl23z1+SshaVfLExpxrEXSGTG0cdvY5lfZC1fOAepYriaXGg==",
"license": "Apache-2.0",
"dependencies": {
"deep-extend": "^0.6.0",
"ws": "^8.15.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+4 -1
View File
@@ -1,7 +1,7 @@
{
"name": "termix",
"private": true,
"version": "1.11.2",
"version": "2.0.0",
"description": "A web-based server management platform with SSH terminal, tunneling, and file editing capabilities",
"author": "Karmaa",
"main": "electron/main.cjs",
@@ -58,6 +58,7 @@
"@types/bcryptjs": "^2.4.6",
"@types/cookie-parser": "^1.4.9",
"@types/cytoscape": "^3.21.9",
"@types/guacamole-common-js": "^1.5.5",
"@types/jszip": "^3.4.0",
"@types/multer": "^2.0.0",
"@types/qrcode": "^1.5.5",
@@ -85,6 +86,8 @@
"dotenv": "^17.2.0",
"drizzle-orm": "^0.44.3",
"express": "^5.1.0",
"guacamole-common-js": "^1.5.0",
"guacamole-lite": "^1.2.0",
"https-proxy-agent": "^7.0.6",
"i18n-auto-translation": "^2.2.3",
"i18next": "^25.4.2",
+20 -2
View File
@@ -49,6 +49,7 @@ Termix هي منصة مفتوحة المصدر ومجانية للأبد وذا
# الميزات
- **الوصول إلى طرفية SSH** - طرفية كاملة الميزات مع دعم تقسيم الشاشة (حتى 4 لوحات) مع نظام علامات تبويب شبيه بالمتصفح. يتضمن دعم تخصيص الطرفية بما في ذلك السمات الشائعة والخطوط والمكونات الأخرى
- **الوصول إلى سطح المكتب البعيد** - دعم RDP و VNC و Telnet عبر المتصفح مع تخصيص كامل وتقسيم الشاشة
- **إدارة أنفاق SSH** - إنشاء وإدارة أنفاق SSH مع إعادة الاتصال التلقائي ومراقبة الحالة ودعم اتصالات -l أو -r
- **مدير الملفات عن بُعد** - إدارة الملفات مباشرة على الخوادم البعيدة مع دعم عرض وتحرير الكود والصور والصوت والفيديو. رفع وتنزيل وإعادة تسمية وحذف ونقل الملفات بسلاسة مع دعم sudo
- **إدارة Docker** - تشغيل وإيقاف وتعليق وحذف الحاويات. عرض إحصائيات الحاويات. التحكم في الحاوية باستخدام طرفية docker exec. لم يُصمم ليحل محل Portainer أو Dockge بل لإدارة حاوياتك ببساطة مقارنة بإنشائها
@@ -69,7 +70,7 @@ Termix هي منصة مفتوحة المصدر ومجانية للأبد وذا
- **لوحة الأوامر** - اضغط مرتين على Shift الأيسر للوصول السريع إلى اتصالات SSH باستخدام لوحة المفاتيح
- **ميزات SSH الغنية** - دعم مضيفات القفز، Warpgate، الاتصالات المبنية على TOTP، SOCKS5، التحقق من مفتاح المضيف، الملء التلقائي لكلمة المرور، [OPKSSH](https://github.com/openpubkey/opkssh)، وغيرها
- **الرسم البياني للشبكة** - تخصيص لوحة التحكم لتصور مختبرك المنزلي بناءً على اتصالات SSH مع دعم الحالة
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **علامات التبويب الدائمة** - تبقى جلسات SSH وعلامات التبويب مفتوحة عبر الأجهزة/التحديثات إذا تم تفعيلها في ملف تعريف المستخدم
# الميزات المخططة
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# الرعاة
@@ -148,7 +166,7 @@ volumes:
# لقطات الشاشة
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+97 -79
View File
@@ -1,97 +1,98 @@
# 仓库统计
<p align="IPAenter">
<a href="../README.md"><img srIPA="https://flagIPAdn.IPAom/us.svg" alt="English" width="24" height="16"> English</a> ·
<img srIPA="https://flagIPAdn.IPAom/IPAn.svg" alt="中文" width="24" height="16"> 中文 ·
<a href="README-JA.md"><img srIPA="https://flagIPAdn.IPAom/jp.svg" alt="日本語" width="24" height="16"> 日本語</a> ·
<a href="README-KO.md"><img srIPA="https://flagIPAdn.IPAom/kr.svg" alt="한국어" width="24" height="16"> 한국어</a> ·
<a href="README-FR.md"><img srIPA="https://flagIPAdn.IPAom/fr.svg" alt="Français" width="24" height="16"> Français</a> ·
<a href="README-DE.md"><img srIPA="https://flagIPAdn.IPAom/de.svg" alt="DeutsIPAh" width="24" height="16"> DeutsIPAh</a> ·
<a href="README-ES.md"><img srIPA="https://flagIPAdn.IPAom/es.svg" alt="Español" width="24" height="16"> Español</a> ·
<a href="README-PT.md"><img srIPA="https://flagIPAdn.IPAom/br.svg" alt="Português" width="24" height="16"> Português</a> ·
<a href="README-RU.md"><img srIPA="https://flagIPAdn.IPAom/ru.svg" alt="Русский" width="24" height="16"> Русский</a> ·
<a href="README-AR.md"><img srIPA="https://flagIPAdn.IPAom/sa.svg" alt="العربية" width="24" height="16"> العربية</a> ·
<a href="README-HI.md"><img srIPA="https://flagIPAdn.IPAom/in.svg" alt="हिन्दी" width="24" height="16"> हिन्दी</a> ·
<a href="README-TR.md"><img srIPA="https://flagIPAdn.IPAom/tr.svg" alt="Türkçe" width="24" height="16"> Türkçe</a> ·
<a href="README-VI.md"><img srIPA="https://flagIPAdn.IPAom/vn.svg" alt="Tiếng Việt" width="24" height="16"> Tiếng Việt</a> ·
<a href="README-IT.md"><img srIPA="https://flagIPAdn.IPAom/it.svg" alt="Italiano" width="24" height="16"> Italiano</a>
<p align="center">
<a href="../README.md"><img src="https://flagcdn.com/us.svg" alt="English" width="24" height="16"> English</a> ·
<img src="https://flagcdn.com/cn.svg" alt="中文" width="24" height="16"> 中文 ·
<a href="README-JA.md"><img src="https://flagcdn.com/jp.svg" alt="日本語" width="24" height="16"> 日本語</a> ·
<a href="README-KO.md"><img src="https://flagcdn.com/kr.svg" alt="한국어" width="24" height="16"> 한국어</a> ·
<a href="README-FR.md"><img src="https://flagcdn.com/fr.svg" alt="Français" width="24" height="16"> Français</a> ·
<a href="README-DE.md"><img src="https://flagcdn.com/de.svg" alt="Deutsch" width="24" height="16"> Deutsch</a> ·
<a href="README-ES.md"><img src="https://flagcdn.com/es.svg" alt="Español" width="24" height="16"> Español</a> ·
<a href="README-PT.md"><img src="https://flagcdn.com/br.svg" alt="Português" width="24" height="16"> Português</a> ·
<a href="README-RU.md"><img src="https://flagcdn.com/ru.svg" alt="Русский" width="24" height="16"> Русский</a> ·
<a href="README-AR.md"><img src="https://flagcdn.com/sa.svg" alt="العربية" width="24" height="16"> العربية</a> ·
<a href="README-HI.md"><img src="https://flagcdn.com/in.svg" alt="हिन्दी" width="24" height="16"> हिन्दी</a> ·
<a href="README-TR.md"><img src="https://flagcdn.com/tr.svg" alt="Türkçe" width="24" height="16"> Türkçe</a> ·
<a href="README-VI.md"><img src="https://flagcdn.com/vn.svg" alt="Tiếng Việt" width="24" height="16"> Tiếng Việt</a> ·
<a href="README-IT.md"><img src="https://flagcdn.com/it.svg" alt="Italiano" width="24" height="16"> Italiano</a>
</p>
![GitHub Repo stars](https://img.shields.io/github/stars/Termix-SSH/Termix?style=flat&label=Stars)
![GitHub forks](https://img.shields.io/github/forks/Termix-SSH/Termix?style=flat&label=Forks)
![GitHub Release](https://img.shields.io/github/v/release/Termix-SSH/Termix?style=flat&label=Release)
<a href="https://disIPAord.gg/jVQGdvHDrf"><img alt="DisIPAord" srIPA="https://img.shields.io/disIPAord/1347374268253470720"></a>
<a href="https://discord.gg/jVQGdvHDrf"><img alt="Discord" src="https://img.shields.io/discord/1347374268253470720"></a>
<p align="IPAenter">
<img srIPA="../repo-images/RepoOfTheDay.png" alt="Repo of the Day AIPAhievement" style="width: 300px; height: auto;">
<p align="center">
<img src="../repo-images/RepoOfTheDay.png" alt="Repo of the Day Achievement" style="width: 300px; height: auto;">
<br>
<small style="IPAolor: #666;">2025年9月1日获得</small>
<small style="color: #666;">2025年9月1日获得</small>
</p>
<br />
<p align="IPAenter">
<a href="https://github.IPAom/Termix-SSH/Termix">
<img alt="Termix Banner" srIPA=../repo-images/HeaderImage.png style="width: auto; height: auto;"> </a>
<p align="center">
<a href="https://github.com/Termix-SSH/Termix">
<img alt="Termix Banner" src=../repo-images/HeaderImage.png style="width: auto; height: auto;"> </a>
</p>
如果你愿意,可以在这里支持这个项目!\
[![GitHub Sponsor](https://img.shields.io/badge/Sponsor-LukeGus-181717?style=for-the-badge&logo=github&logoIPAolor=white)](https://github.IPAom/sponsors/LukeGus)
[![GitHub Sponsor](https://img.shields.io/badge/Sponsor-LukeGus-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/sponsors/LukeGus)
# 概览
<p align="IPAenter">
<a href="https://github.IPAom/Termix-SSH/Termix">
<img alt="Termix Banner" srIPA=../publiIPA/iIPAon.svg style="width: 250px; height: 250px;"> </a>
<p align="center">
<a href="https://github.com/Termix-SSH/Termix">
<img alt="Termix Banner" src=../public/icon.svg style="width: 250px; height: 250px;"> </a>
</p>
Termix 是一个开源、永久免费、自托管的一体化服务器管理平台。它提供了一个基于网页的解决方案,通过一个直观的界面管理你的服务器和基础设施。Termix
提供 SSH 终端访问、SSH 隧道功能以及远程文件管理,还会陆续添加更多工具。Termix 是适用于所有平台的完美免费自托管 Termius 替代品。
Termix 是一个开源、永久免费、自托管的一体化服务器管理平台。它提供了一个多平台解决方案,通过一个直观的界面管理你的服务器和基础设施。Termix
提供 SSH 终端访问、远程桌面控制(RDP、VNC、Telnet)、SSH 隧道功能以及远程文件管理,还会陆续添加更多工具。Termix 是适用于所有平台的完美免费自托管 Termius 替代品。
# 功能
- **SSH 终端访问** - 功能齐全的终端,具有分屏支持(最多 4 个面板)和类似浏览器的选项卡系统。包括对自定义终端的支持,包括常见终端主题、字体和其他组件
- **SSH 隧道管理** - 创建和管理 SSH 隧道,具有自动重新连接和健康监控功能
- **远程文件管理** - 直接在远程服务器上管理文件,支持查看和编辑代码、图像、音频和视频。无缝上传、下载、重命名、删除和移动文件
- **DoIPAker 管理** - 启动、停止、暂停、删除容器。查看容器统计信息。使用 doIPAker exeIPA 终端控制容器。它不是用来替代 Portainer 或 DoIPAkge,而是用于简单管理你的容器而不是创建它们。
- **远程桌面访问** - 通过浏览器支持 RDP、VNC 和 Telnet,具有完整的自定义和分屏功能
- **SSH 隧道管理** - 创建和管理 SSH 隧道,具有自动重新连接和健康监控功能,支持 -l 或 -r 连接
- **远程文件管理** - 直接在远程服务器上管理文件,支持查看和编辑代码、图像、音频和视频。无缝上传、下载、重命名、删除和移动文件,支持 sudo
- **Docker 管理** - 启动、停止、暂停、删除容器。查看容器统计信息。使用 docker exec 终端控制容器。它不是用来替代 Portainer 或 Dockge,而是用于简单管理你的容器而不是创建它们
- **SSH 主机管理器** - 保存、组织和管理您的 SSH 连接,支持标签和文件夹,并轻松保存可重用的登录信息,同时能够自动部署 SSH 密钥
- **服务器统计** - 在任何 SSH 服务器上查看 IPAPU、内存和磁盘使用情况以及网络、正常运行时间系统信息
- **服务器统计** - 在大多数 Linux 服务器上查看 CPU、内存和磁盘使用情况以及网络、正常运行时间系统信息、防火墙、端口监控
- **仪表板** - 在仪表板上一目了然地查看服务器信息
- **RBAIPA** - 创建角色并在用户/角色之间共享主机
- **用户认证** - 安全的用户管理,具有管理员控制以及 OIDIPA 和 2FA (TOTP) 支持。查看所有平台上的活动用户会话并撤销权限。将您的 OIDIPA/本地帐户链接在一起
- **数据库加密** - 后端存储为加密的 SQLite 数据库文件。查看[文档](https://doIPAs.termix.site/seIPAurity)了解更多信息
- **RBAC** - 创建角色并在用户/角色之间共享主机
- **用户认证** - 安全的用户管理,具有管理员控制以及 OIDC 和 2FA (TOTP) 支持。查看所有平台上的活动用户会话并撤销权限。将您的 OIDC/本地帐户链接在一起
- **数据库加密** - 后端存储为加密的 SQLite 数据库文件。查看[文档](https://docs.termix.site/security)了解更多信息
- **数据导出/导入** - 导出和导入 SSH 主机、凭据和文件管理器数据
- **自动 SSL 设置** - 内置 SSL 证书生成和管理,支持 HTTPS 重定向
- **现代用户界面** - 使用 ReaIPAt、Tailwind IPASS 和 ShadIPAn 构建的简洁的桌面/移动设备友好界面。可选择基于深色或浅色模式的用户界面。
- **语言** - 内置支持约 30 种语言(由 [IPArowdin](https://doIPAs.termix.site/translations) 管理)
- **平台支持** - 可作为 Web 应用程序、桌面应用程序(Windows、Linux 和 maIPAOS)、PWA 以及适用于 iOS 和 Android 的专用移动/平板电脑应用程序
- **SSH 工具** - 创建可重用的命令片段,单击即可执行。在多个打开的终端上同时运行一个命令
- **现代用户界面** - 使用 React、Tailwind CSS 和 Shadcn 构建的简洁的桌面/移动设备友好界面。可选择基于深色或浅色模式的用户界面。使用 URL 路由以全屏方式打开任何连接
- **语言** - 内置支持约 30 种语言(由 [Crowdin](https://docs.termix.site/translations) 管理)
- **平台支持** - 可作为 Web 应用程序、桌面应用程序(Windows、Linux 和 macOS)、PWA 以及适用于 iOS 和 Android 的专用移动/平板电脑应用程序
- **SSH 工具** - 创建可重用的命令片段,单击即可执行。在多个打开的终端上同时运行一个命令
- **命令历史** - 自动完成并查看以前运行的 SSH 命令
- **快速连接** - 无需保存连接数据即可连接到服务器
- **命令面板** - 双击左 Shift 键可快速使用键盘访问 SSH 连接
- **SSH 功能丰富** - 支持跳板机、Warpgate、基于 TOTP 的连接、SOIPAKS5、主机密钥验证、密码自动填充、[OPKSSH](https://github.IPAom/openpubkey/opkssh)等
- **SSH 功能丰富** - 支持跳板机、Warpgate、基于 TOTP 的连接、SOCKS5、主机密钥验证、密码自动填充、[OPKSSH](https://github.com/openpubkey/opkssh)等
- **网络图** - 自定义您的仪表板,根据您的 SSH 连接可视化您的家庭实验室,支持状态显示
- **持久标签页** - 如果在用户配置文件中启用,SSH 会话和标签页在设备/刷新后保持打开状态
# 计划功能
查看 [项目](https://github.IPAom/orgs/Termix-SSH/projeIPAts/2) 了解所有计划功能。如果你想贡献代码,请参阅 [贡献指南](https://github.IPAom/Termix-SSH/Termix/blob/main/IPAONTRIBUTING.md)。
查看 [项目](https://github.com/orgs/Termix-SSH/projects/2) 了解所有计划功能。如果你想贡献代码,请参阅 [贡献指南](https://github.com/Termix-SSH/Termix/blob/main/CONTRIBUTING.md)。
# 安装
支持的设备:
- 网站(任何平台上的任何现代浏览器,如 IPAhrome、Safari 和 Firefox)(包括 PWA 支持)
- 网站(任何平台上的任何现代浏览器,如 Chrome、Safari 和 Firefox)(包括 PWA 支持)
- Windowsx64/ia32
- 便携版
- MSI 安装程序
- IPAhoIPAolatey 软件包管理器
- Chocolatey 软件包管理器
- Linuxx64/ia32
- 便携版
- AUR
- AppImage
- Deb
- Flatpak
- maIPAOSx64/ia32 on v12.0+
- macOSx64/ia32 on v12.0+
- Apple App Store
- DMG
- Homebrew
@@ -102,13 +103,13 @@ Termix 是一个开源、永久免费、自托管的一体化服务器管理平
- Google Play 商店
- APK
访问 Termix [文档](https://doIPAs.termix.site/install) 了解有关如何在所有平台上安装 Termix 的更多信息。或者,在此处查看示例 DoIPAker IPAompose 文件:
访问 Termix [文档](https://docs.termix.site/install) 了解有关如何在所有平台上安装 Termix 的更多信息。或者,在此处查看示例 Docker Compose 文件(如果不打算使用远程桌面功能,可以省略 guacd 和 network
```yaml
serviIPAes:
services:
termix:
image: ghIPAr.io/lukegus/termix:latest
IPAontainer_name: termix
image: ghcr.io/lukegus/termix:latest
container_name: termix
restart: unless-stopped
ports:
- "8080:8080"
@@ -116,74 +117,91 @@ serviIPAes:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: loIPAal
driver: local
networks:
termix-net:
driver: bridge
```
# 赞助商
<p align="left">
<a href="https://www.digitaloIPAean.IPAom/">
<img srIPA="https://opensourIPAe.nyIPA3.IPAdn.digitaloIPAeanspaIPAes.IPAom/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="50" alt="DigitalOIPAean">
<a href="https://www.digitalocean.com/">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="50" alt="DigitalOcean">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://IPArowdin.IPAom/">
<img srIPA="https://support.IPArowdin.IPAom/assets/logos/IPAore-logo/svg/IPArowdin-IPAore-logo-IPADark.svg" height="50" alt="IPArowdin">
<a href="https://crowdin.com/">
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="50" alt="Crowdin">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://www.blaIPAksmith.sh/">
<img srIPA="https://IPAdn.prod.website-files.IPAom/681bfb0IPA9a4601bIPA6e288eIPA4/683IPAa9e2IPA5186757092611b8_e8IPAb22127df4da0811IPA4120a523722d2_logo-baIPAksmith-wordmark-light.svg" height="50" alt="IPArowdin">
<a href="https://www.blacksmith.sh/">
<img src="https://cdn.prod.website-files.com/681bfb0c9a4601bc6e288ec4/683ca9e2c5186757092611b8_e8cb22127df4da0811c4120a523722d2_logo-backsmith-wordmark-light.svg" height="50" alt="Blacksmith">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://www.IPAloudflare.IPAom/">
<img srIPA="https://sirv.sirv.IPAom/website/sIPAreenshots/IPAloudflare/IPAloudflare-logo.png?w=300" height="50" alt="IPArowdin">
<a href="https://www.cloudflare.com/">
<img src="https://sirv.sirv.com/website/screenshots/cloudflare/cloudflare-logo.png?w=300" height="50" alt="Cloudflare">
</a>
</p>
# 支持
如果你需要 Termix 的帮助或想要请求功能,请访问 [Issues](https://github.IPAom/Termix-SSH/Support/issues) 页面,登录并点击 `New Issue`
请尽可能详细地描述你的问题,最好使用英语。你也可以加入 [DisIPAord](https://disIPAord.gg/jVQGdvHDrf) 服务器并访问支持
如果你需要 Termix 的帮助或想要请求功能,请访问 [Issues](https://github.com/Termix-SSH/Support/issues) 页面,登录并点击 `New Issue`
请尽可能详细地描述你的问题,最好使用英语。你也可以加入 [Discord](https://discord.gg/jVQGdvHDrf) 服务器并访问支持
频道,但响应时间可能较长。
# 展示
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfIPAK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="IPAenter">
<img srIPA="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
<img srIPA="../repo-images/Image%202.png" width="400" alt="Termix Demo 2"/>
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
<img src="../repo-images/Image%202.png" width="400" alt="Termix Demo 2"/>
</p>
<p align="IPAenter">
<img srIPA="../repo-images/Image%203.png" width="400" alt="Termix Demo 3"/>
<img srIPA="../repo-images/Image%204.png" width="400" alt="Termix Demo 4"/>
<p align="center">
<img src="../repo-images/Image%203.png" width="400" alt="Termix Demo 3"/>
<img src="../repo-images/Image%204.png" width="400" alt="Termix Demo 4"/>
</p>
<p align="IPAenter">
<img srIPA="../repo-images/Image%205.png" width="400" alt="Termix Demo 5"/>
<img srIPA="../repo-images/Image%206.png" width="400" alt="Termix Demo 6"/>
<p align="center">
<img src="../repo-images/Image%205.png" width="400" alt="Termix Demo 5"/>
<img src="../repo-images/Image%206.png" width="400" alt="Termix Demo 6"/>
</p>
<p align="IPAenter">
<img srIPA="../repo-images/Image%207.png" width="400" alt="Termix Demo 7"/>
<img srIPA="../repo-images/Image%208.png" width="400" alt="Termix Demo 8"/>
<p align="center">
<img src="../repo-images/Image%207.png" width="400" alt="Termix Demo 7"/>
<img src="../repo-images/Image%208.png" width="400" alt="Termix Demo 8"/>
</p>
<p align="IPAenter">
<img srIPA="../repo-images/Image%209.png" width="400" alt="Termix Demo 9"/>
<img srIPA="../repo-images/Image%2010.png" width="400" alt="Termix Demo 10"/>
<p align="center">
<img src="../repo-images/Image%209.png" width="400" alt="Termix Demo 9"/>
<img src="../repo-images/Image%2010.png" width="400" alt="Termix Demo 10"/>
</p>
<p align="IPAenter">
<img srIPA="../repo-images/Image%2011.png" width="400" alt="Termix Demo 11"/>
<img srIPA="../repo-images/Image%2012.png" width="400" alt="Termix Demo 12"/>
<p align="center">
<img src="../repo-images/Image%2011.png" width="400" alt="Termix Demo 11"/>
<img src="../repo-images/Image%2012.png" width="400" alt="Termix Demo 12"/>
</p>
某些视频和图像可能已过时或可能无法完美展示功能。
# 许可证
根据 ApaIPAhe LiIPAense Version 2.0 发布。更多信息请参见 LIIPAENSE。
根据 Apache License Version 2.0 发布。更多信息请参见 LICENSE。
+20 -2
View File
@@ -49,6 +49,7 @@ Termix ist eine quelloffene, dauerhaft kostenlose, selbst gehostete All-in-One-S
# Funktionen
- **SSH-Terminalzugriff** - Voll ausgestattetes Terminal mit Split-Screen-Unterstützung (bis zu 4 Panels) mit einem browserähnlichen Tab-System. Enthält Unterstützung für die Anpassung des Terminals einschließlich gängiger Terminal-Themes, Schriftarten und anderer Komponenten
- **Remote-Desktop-Zugriff** - RDP-, VNC- und Telnet-Unterstützung über den Browser mit vollständiger Anpassung und Split-Screen
- **SSH-Tunnelverwaltung** - Erstellen und verwalten Sie SSH-Tunnel mit automatischer Wiederverbindung und Gesundheitsüberwachung sowie Unterstützung für -l oder -r Verbindungen
- **Remote-Dateimanager** - Verwalten Sie Dateien direkt auf Remote-Servern mit Unterstützung für das Anzeigen und Bearbeiten von Code, Bildern, Audio und Video. Laden Sie Dateien hoch, herunter, benennen Sie sie um, löschen oder verschieben Sie sie nahtlos mit Sudo-Unterstützung.
- **Docker-Verwaltung** - Container starten, stoppen, pausieren, entfernen. Container-Statistiken anzeigen. Container über Docker-Exec-Terminal steuern. Es wurde nicht entwickelt, um Portainer oder Dockge zu ersetzen, sondern um Ihre Container einfach zu verwalten, anstatt sie zu erstellen.
@@ -69,7 +70,7 @@ Termix ist eine quelloffene, dauerhaft kostenlose, selbst gehostete All-in-One-S
- **Befehlspalette** - Doppeltippen Sie die linke Umschalttaste, um schnell auf SSH-Verbindungen mit Ihrer Tastatur zuzugreifen
- **SSH-Funktionsreich** - Unterstützt Jump-Hosts, Warpgate, TOTP-basierte Verbindungen, SOCKS5, Host-Key-Verifizierung, automatisches Ausfüllen von Passwörtern, [OPKSSH](https://github.com/openpubkey/opkssh) usw.
- **Netzwerkgraph** - Passen Sie Ihr Dashboard an, um Ihr Homelab basierend auf Ihren SSH-Verbindungen mit Statusunterstützung zu visualisieren
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Persistente Tabs** - SSH-Sitzungen und Tabs bleiben über Geräte/Aktualisierungen hinweg offen, wenn im Benutzerprofil aktiviert
# Geplante Funktionen
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Sponsoren
@@ -148,7 +166,7 @@ Bitte beschreiben Sie Ihr Anliegen so detailliert wie möglich, vorzugsweise auf
# Screenshots
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix es una plataforma de gestión de servidores todo en uno, de código abier
# Características
- **Acceso a Terminal SSH** - Terminal completo con soporte de pantalla dividida (hasta 4 paneles) con un sistema de pestañas similar al navegador. Incluye soporte para personalizar el terminal incluyendo temas comunes de terminal, fuentes y otros componentes
- **Acceso a Escritorio Remoto** - Soporte RDP, VNC y Telnet a través del navegador con personalización completa y pantalla dividida
- **Gestión de Túneles SSH** - Cree y gestione túneles SSH con reconexión automática y monitoreo de estado, con soporte para conexiones -l o -r
- **Gestor Remoto de Archivos** - Gestione archivos directamente en servidores remotos con soporte para visualizar y editar código, imágenes, audio y video. Suba, descargue, renombre, elimine y mueva archivos sin problemas con soporte sudo.
- **Gestión de Docker** - Inicie, detenga, pause, elimine contenedores. Vea estadísticas de contenedores. Controle contenedores usando el terminal Docker Exec. No fue creado para reemplazar Portainer o Dockge, sino para simplemente gestionar sus contenedores en lugar de crearlos.
@@ -69,7 +70,7 @@ Termix es una plataforma de gestión de servidores todo en uno, de código abier
- **Paleta de Comandos** - Pulse dos veces la tecla Shift izquierda para acceder rápidamente a las conexiones SSH con su teclado
- **SSH Rico en Funciones** - Soporta jump hosts, Warpgate, conexiones basadas en TOTP, SOCKS5, verificación de clave de host, autocompletado de contraseñas, [OPKSSH](https://github.com/openpubkey/opkssh), etc.
- **Gráfico de Red** - Personalice su Dashboard para visualizar su homelab basado en sus conexiones SSH con soporte de estado
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Pestañas Persistentes** - Las sesiones SSH y pestañas permanecen abiertas entre dispositivos/actualizaciones si está habilitado en el perfil de usuario
# Características Planeadas
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Patrocinadores
@@ -148,7 +166,7 @@ Por favor, sea lo más detallado posible en su reporte, preferiblemente escrito
# Capturas de Pantalla
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix est une plateforme de gestion de serveurs tout-en-un, open source, à jam
# Fonctionnalités
- **Accès terminal SSH** - Terminal complet avec support d'écran partagé (jusqu'à 4 panneaux) et un système d'onglets inspiré des navigateurs. Inclut la personnalisation du terminal avec des thèmes courants, des polices et d'autres composants
- **Accès Bureau à Distance** - Support RDP, VNC et Telnet via navigateur avec personnalisation complète et écran partagé
- **Gestion des tunnels SSH** - Créez et gérez des tunnels SSH avec reconnexion automatique et surveillance de l'état, avec support des connexions -l ou -r
- **Gestionnaire de fichiers distant** - Gérez les fichiers directement sur les serveurs distants avec support de la visualisation et de l'édition de code, images, audio et vidéo. Téléversez, téléchargez, renommez, supprimez et déplacez des fichiers de manière fluide avec support sudo
- **Gestion Docker** - Démarrez, arrêtez, mettez en pause, supprimez des conteneurs. Consultez les statistiques des conteneurs. Contrôlez les conteneurs via le terminal docker exec. Non conçu pour remplacer Portainer ou Dockge, mais plutôt pour gérer simplement vos conteneurs plutôt que de les créer
@@ -69,7 +70,7 @@ Termix est une plateforme de gestion de serveurs tout-en-un, open source, à jam
- **Palette de commandes** - Appuyez deux fois sur Shift gauche pour accéder rapidement aux connexions SSH avec votre clavier
- **SSH riche en fonctionnalités** - Support des hôtes de rebond, Warpgate, connexions basées sur TOTP, SOCKS5, vérification des clés d'hôte, remplissage automatique des mots de passe, [OPKSSH](https://github.com/openpubkey/opkssh), etc.
- **Graphe réseau** - Personnalisez votre tableau de bord pour visualiser votre homelab basé sur vos connexions SSH avec support des statuts
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Onglets Persistants** - Les sessions SSH et les onglets restent ouverts sur tous les appareils/actualisations si activé dans le profil utilisateur
# Fonctionnalités prévues
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Sponsors
@@ -147,7 +165,7 @@ Si vous avez besoin d'aide ou souhaitez demander une fonctionnalité pour Termix
# Captures d'écran
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix एक ओपन-सोर्स, हमेशा के लिए मु
# विशेषताएँ
- **SSH टर्मिनल एक्सेस** - ब्राउज़र जैसी टैब प्रणाली के साथ स्प्लिट-स्क्रीन सपोर्ट (4 पैनल तक) वाला पूर्ण-विशेषता वाला टर्मिनल। इसमें लोकप्रिय टर्मिनल थीम, फ़ॉन्ट और अन्य कंपोनेंट सहित टर्मिनल को कस्टमाइज़ करने का सपोर्ट शामिल है
- **रिमोट डेस्कटॉप एक्सेस** - ब्राउज़र पर RDP, VNC और Telnet सपोर्ट, पूर्ण कस्टमाइज़ेशन और स्प्लिट स्क्रीन के साथ
- **SSH टनल प्रबंधन** - ऑटोमैटिक रीकनेक्शन और हेल्थ मॉनिटरिंग के साथ SSH टनल बनाएँ और प्रबंधित करें, -l या -r कनेक्शन के सपोर्ट के साथ
- **रिमोट फ़ाइल मैनेजर** - कोड, इमेज, ऑडियो और वीडियो देखने और संपादित करने के सपोर्ट के साथ रिमोट सर्वर पर सीधे फ़ाइलें प्रबंधित करें। sudo सपोर्ट के साथ फ़ाइलें अपलोड, डाउनलोड, रीनेम, डिलीट और मूव करें
- **Docker प्रबंधन** - कंटेनर शुरू, बंद, पॉज़, हटाएँ। कंटेनर स्टैट्स देखें। docker exec टर्मिनल का उपयोग करके कंटेनर को नियंत्रित करें। इसे Portainer या Dockge की जगह लेने के लिए नहीं बनाया गया बल्कि कंटेनर बनाने की तुलना में उन्हें सरलता से प्रबंधित करने के लिए बनाया गया है
@@ -69,7 +70,7 @@ Termix एक ओपन-सोर्स, हमेशा के लिए मु
- **कमांड पैलेट** - अपने कीबोर्ड से SSH कनेक्शन तक त्वरित पहुँच के लिए बाएँ Shift को दो बार टैप करें
- **SSH सुविधाओं से भरपूर** - जम्प होस्ट, Warpgate, TOTP आधारित कनेक्शन, SOCKS5, होस्ट की वेरिफ़िकेशन, पासवर्ड ऑटोफ़िल, [OPKSSH](https://github.com/openpubkey/opkssh) आदि का सपोर्ट
- **नेटवर्क ग्राफ़** - स्थिति सपोर्ट के साथ अपने SSH कनेक्शन के आधार पर अपने होमलैब को विज़ुअलाइज़ करने के लिए अपना डैशबोर्ड कस्टमाइज़ करें
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **परसिस्टेंट टैब** - उपयोगकर्ता प्रोफ़ाइल में सक्षम होने पर SSH सेशन और टैब डिवाइस/रीफ्रेश के पार खुले रहते हैं
# नियोजित विशेषताएँ
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# प्रायोजक
@@ -148,7 +166,7 @@ volumes:
# स्क्रीनशॉट
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+21 -3
View File
@@ -48,7 +48,8 @@ Termix è una piattaforma di gestione server tutto-in-uno, open-source, per semp
# Funzionalità
- **Accesso Terminale SSH** - Terminale completo con supporto schermo divIPA (fino a 4 pannelli) con un sistema di schede in stile browser. Include il supporto per la personalizzazione del terminale, inclusi temi, font e altri componenti comuni
- **Accesso Terminale SSH** - Terminale completo con supporto schermo diviso (fino a 4 pannelli) con un sistema di schede in stile browser. Include il supporto per la personalizzazione del terminale, inclusi temi, font e altri componenti comuni
- **Accesso Desktop Remoto** - Supporto RDP, VNC e Telnet tramite browser con personalizzazione completa e schermo diviso
- **Gestione Tunnel SSH** - Crea e gestisci tunnel SSH con riconnessione automatica e monitoraggio dello stato, con supporto per connessioni -l o -r
- **Gestore File Remoto** - Gestisci i file direttamente sui server remoti con supporto per la visualizzazione e la modifica di codice, immagini, audio e video. Carica, scarica, rinomina, elimina e sposta file senza problemi con supporto sudo.
- **Gestione Docker** - Avvia, ferma, metti in pausa, rimuovi container. Visualizza le statistiche dei container. Controlla i container tramite terminale docker exec. Non è stato creato per sostituire Portainer o Dockge, ma piuttosto per gestire semplicemente i tuoi container rispetto alla loro creazione.
@@ -69,7 +70,7 @@ Termix è una piattaforma di gestione server tutto-in-uno, open-source, per semp
- **Palette Comandi** - Premi due volte shift sinistro per accedere rapidamente alle connessioni SSH con la tastiera
- **SSH Ricco di Funzionalità** - Supporta jump host, Warpgate, connessioni basate su TOTP, SOCKS5, verifica chiave host, compilazione automatica password, [OPKSSH](https://github.com/openpubkey/opkssh), ecc.
- **Grafico di Rete** - Personalizza la tua Dashboard per visualizzare il tuo homelab basato sulle connessioni SSH con supporto dello stato
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Schede Persistenti** - Le sessioni SSH e le schede rimangono aperte tra dispositivi/aggiornamenti se abilitato nel profilo utente
# Funzionalità Pianificate
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Sponsor
@@ -148,7 +166,7 @@ Per favore, sii il più dettagliato possibile nella tua segnalazione, preferibil
# Screenshot
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termixは、オープンソースで永久無料のセルフホスト型オー
# 機能
- **SSHターミナルアクセス** - ブラウザ風タブシステムによる分割画面対応(最大4パネル)のフル機能ターミナル。一般的なターミナルテーマ、フォント、その他のコンポーネントを含むターミナルカスタマイズに対応
- **リモートデスクトップアクセス** - ブラウザ上でRDP、VNC、Telnetをサポート、完全なカスタマイズと分割画面に対応
- **SSHトンネル管理** - 自動再接続とヘルスモニタリング機能を備えたSSHトンネルの作成・管理、-l または -r 接続に対応
- **リモートファイルマネージャー** - コード、画像、音声、動画の表示・編集に対応し、リモートサーバー上のファイルを直接管理。sudo対応でファイルのアップロード、ダウンロード、名前変更、削除、移動をシームレスに実行
- **Docker管理** - コンテナの起動、停止、一時停止、削除。コンテナの統計情報を表示。docker execターミナルでコンテナを操作。PortainerやDockgeの代替ではなく、コンテナの作成よりも簡易管理を目的としています
@@ -69,7 +70,7 @@ Termixは、オープンソースで永久無料のセルフホスト型オー
- **コマンドパレット** - 左Shiftキーを2回押すことで、キーボードからSSH接続に素早くアクセス
- **SSH機能充実** - ジャンプホスト、Warpgate、TOTPベースの接続、SOCKS5、ホストキー検証、パスワード自動入力、[OPKSSH](https://github.com/openpubkey/opkssh)などに対応
- **ネットワークグラフ** - ダッシュボードをカスタマイズして、SSH接続に基づくホームラボのネットワークをステータス表示付きで可視化
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **永続タブ** - ユーザープロフィールで有効にすると、SSHセッションとタブがデバイス/更新をまたいで開いたまま保持されます
# 予定されている機能
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# スポンサー
@@ -147,7 +165,7 @@ Termixに関するヘルプや機能リクエストが必要な場合は、[Issu
# スクリーンショット
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix는 오픈 소스이며 영구 무료인 셀프 호스팅 올인원 서버
# 기능
- **SSH 터미널 접속** - 브라우저 스타일 탭 시스템과 분할 화면 지원(최대 4개 패널)을 갖춘 완전한 기능의 터미널. 일반 터미널 테마, 글꼴 및 기타 구성 요소를 포함한 터미널 사용자 정의 지원
- **원격 데스크톱 접속** - 완전한 사용자 정의와 분할 화면을 지원하는 브라우저 기반 RDP, VNC, Telnet 지원
- **SSH 터널 관리** - 자동 재연결 및 상태 모니터링 기능을 갖춘 SSH 터널 생성 및 관리, -l 또는 -r 연결 지원
- **원격 파일 관리자** - 코드, 이미지, 오디오, 비디오의 보기 및 편집을 지원하여 원격 서버에서 파일을 직접 관리. sudo 지원으로 파일 업로드, 다운로드, 이름 변경, 삭제, 이동을 원활하게 수행
- **Docker 관리** - 컨테이너 시작, 중지, 일시 정지, 제거. 컨테이너 통계 보기. docker exec 터미널로 컨테이너 제어. Portainer나 Dockge를 대체하기 위한 것이 아니라 컨테이너 생성보다는 간편한 관리를 목적으로 합니다
@@ -69,7 +70,7 @@ Termix는 오픈 소스이며 영구 무료인 셀프 호스팅 올인원 서버
- **명령어 팔레트** - 왼쪽 Shift 키를 두 번 눌러 키보드로 SSH 연결에 빠르게 접근
- **풍부한 SSH 기능** - 점프 호스트, Warpgate, TOTP 기반 연결, SOCKS5, 호스트 키 검증, 비밀번호 자동 입력, [OPKSSH](https://github.com/openpubkey/opkssh) 등 지원
- **네트워크 그래프** - 대시보드를 사용자 정의하여 SSH 연결 기반의 홈랩 네트워크를 상태 표시와 함께 시각화
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **지속 탭** - 사용자 프로필에서 활성화된 경우 SSH 세션 및 탭이 기기/새로 고침 간에 열린 상태 유지
# 계획된 기능
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# 스폰서
@@ -147,7 +165,7 @@ Termix에 대한 도움이 필요하거나 기능을 요청하려면 [Issues](ht
# 스크린샷
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix é uma plataforma de gerenciamento de servidores tudo-em-um, de código a
# Funcionalidades
- **Acesso ao Terminal SSH** - Terminal completo com suporte a tela dividida (até 4 painéis) com um sistema de abas similar ao navegador. Inclui suporte para personalização do terminal incluindo temas comuns de terminal, fontes e outros componentes
- **Acesso à Área de Trabalho Remota** - Suporte a RDP, VNC e Telnet pelo navegador com personalização completa e tela dividida
- **Gerenciamento de Túneis SSH** - Crie e gerencie túneis SSH com reconexão automática e monitoramento de saúde, com suporte para conexões -l ou -r
- **Gerenciador Remoto de Arquivos** - Gerencie arquivos diretamente em servidores remotos com suporte para visualizar e editar código, imagens, áudio e vídeo. Faça upload, download, renomeie, exclua e mova arquivos facilmente com suporte sudo.
- **Gerenciamento de Docker** - Inicie, pare, pause, remova contêineres. Visualize estatísticas de contêineres. Controle contêineres usando o terminal Docker Exec. Não foi feito para substituir Portainer ou Dockge, mas sim para simplesmente gerenciar seus contêineres em vez de criá-los.
@@ -69,7 +70,7 @@ Termix é uma plataforma de gerenciamento de servidores tudo-em-um, de código a
- **Paleta de Comandos** - Pressione duas vezes a tecla Shift esquerda para acessar rapidamente as conexões SSH com seu teclado
- **SSH Rico em Funcionalidades** - Suporta jump hosts, Warpgate, conexões baseadas em TOTP, SOCKS5, verificação de chave do host, preenchimento automático de senhas, [OPKSSH](https://github.com/openpubkey/opkssh), etc.
- **Gráfico de Rede** - Personalize seu Dashboard para visualizar seu homelab baseado nas suas conexões SSH com suporte de status
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Abas Persistentes** - Sessões SSH e abas permanecem abertas entre dispositivos/atualizações se habilitado no perfil do usuário
# Funcionalidades Planejadas
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Patrocinadores
@@ -148,7 +166,7 @@ Por favor, seja o mais detalhado possível no seu relato, preferencialmente escr
# Capturas de Tela
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix — это платформа для управления сервера
# Возможности
- **Доступ к SSH-терминалу** — Полнофункциональный терминал с поддержкой разделения экрана (до 4 панелей) и системой вкладок, как в браузере. Включает поддержку настройки терминала, включая популярные темы, шрифты и другие компоненты
- **Доступ к удалённому рабочему столу** — Поддержка RDP, VNC и Telnet через браузер с полной настройкой и разделением экрана
- **Управление SSH-туннелями** — Создание и управление SSH-туннелями с автоматическим переподключением и мониторингом состояния, с поддержкой соединений -l и -r
- **Удалённый файловый менеджер** — Управление файлами непосредственно на удалённых серверах с поддержкой просмотра и редактирования кода, изображений, аудио и видео. Загрузка, скачивание, переименование, удаление и перемещение файлов с поддержкой sudo
- **Управление Docker** — Запуск, остановка, приостановка, удаление контейнеров. Просмотр статистики контейнеров. Управление контейнером через терминал docker exec. Не предназначен для замены Portainer или Dockge, а скорее для простого управления контейнерами по сравнению с их созданием
@@ -69,7 +70,7 @@ Termix — это платформа для управления сервера
- **Командная палитра** — Двойное нажатие левого Shift для быстрого доступа к SSH-подключениям с клавиатуры
- **Богатый функционал SSH** — Поддержка jump-хостов, Warpgate, подключений на основе TOTP, SOCKS5, верификации ключей хоста, автозаполнения паролей, [OPKSSH](https://github.com/openpubkey/opkssh) и др.
- **Сетевой граф** — Настройте панель управления для визуализации вашей домашней лаборатории на основе SSH-подключений с поддержкой статусов
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Постоянные вкладки** SSH-сессии и вкладки остаются открытыми на всех устройствах/при обновлении страницы, если включено в профиле пользователя
# Запланированные функции
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Спонсоры
@@ -148,7 +166,7 @@ volumes:
# Скриншоты
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix, açık kaynaklı, sonsuza kadar ücretsiz, kendi sunucunuzda barındıra
# Özellikler
- **SSH Terminal Erişimi** - Tarayıcı benzeri sekme sistemiyle bölünmüş ekran desteğine sahip (4 panele kadar) tam özellikli terminal. Yaygın terminal temaları, yazı tipleri ve diğer bileşenler dahil olmak üzere terminal özelleştirme desteği içerir
- **Uzak Masaüstü Erişimi** - Tam özelleştirme ve bölünmüş ekran ile tarayıcı üzerinden RDP, VNC ve Telnet desteği
- **SSH Tünel Yönetimi** - Otomatik yeniden bağlanma ve sağlık izleme ile SSH tünelleri oluşturun ve yönetin, -l veya -r bağlantıları desteğiyle
- **Uzak Dosya Yöneticisi** - Uzak sunuculardaki dosyaları doğrudan yönetin; kod, görüntü, ses ve video görüntüleme ve düzenleme desteğiyle. Sudo desteğiyle dosyaları sorunsuzca yükleyin, indirin, yeniden adlandırın, silin ve taşıyın.
- **Docker Yönetimi** - Konteynerleri başlatın, durdurun, duraklatın, kaldırın. Konteyner istatistiklerini görüntüleyin. Docker exec terminali kullanarak konteyneri kontrol edin. Portainer veya Dockge'nin yerini almak için değil, konteynerlerinizi oluşturmak yerine basitçe yönetmek için tasarlanmıştır.
@@ -69,7 +70,7 @@ Termix, açık kaynaklı, sonsuza kadar ücretsiz, kendi sunucunuzda barındıra
- **Komut Paleti** - Sol shift tuşuna iki kez basarak SSH bağlantılarına klavyenizle hızlıca erişin
- **SSH Zengin Özellikler** - Atlama ana bilgisayarları, Warpgate, TOTP tabanlı bağlantılar, SOCKS5, ana bilgisayar anahtar doğrulama, otomatik şifre doldurma, [OPKSSH](https://github.com/openpubkey/opkssh) vb. destekler.
- **Ağ Grafiği** - Kontrol panelinizi, SSH bağlantılarınıza dayalı olarak ev laboratuvarınızı durum desteğiyle görselleştirmek için özelleştirin
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Kalıcı Sekmeler** - Kullanıcı profilinde etkinleştirilmişse SSH oturumları ve sekmeler cihazlar/yenilemeler arasında açık kalır
# Planlanan Özellikler
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Sponsorlar
@@ -148,7 +166,7 @@ Lütfen sorununuzu mümkün olduğunca ayrıntılı yazın, tercihen İngilizce
# Ekran Görüntüleri
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+20 -2
View File
@@ -49,6 +49,7 @@ Termix là nền tảng quản lý máy chủ tất cả trong một, mã nguồ
# Tính Năng
- **Truy Cập Terminal SSH** - Terminal đầy đủ tính năng với hỗ trợ chia màn hình (lên đến 4 bảng) với hệ thống tab kiểu trình duyệt. Bao gồm hỗ trợ tùy chỉnh terminal bao gồm các chủ đề terminal phổ biến, phông chữ và các thành phần khác
- **Truy Cập Màn Hình Từ Xa** - Hỗ trợ RDP, VNC và Telnet qua trình duyệt với đầy đủ tùy chỉnh và chia màn hình
- **Quản Lý Đường Hầm SSH** - Tạo và quản lý đường hầm SSH với tự động kết nối lại và giám sát sức khỏe, hỗ trợ kết nối -l hoặc -r
- **Trình Quản Lý Tệp Từ Xa** - Quản lý tệp trực tiếp trên máy chủ từ xa với hỗ trợ xem và chỉnh sửa mã, hình ảnh, âm thanh và video. Tải lên, tải xuống, đổi tên, xóa và di chuyển tệp liền mạch với hỗ trợ sudo.
- **Quản Lý Docker** - Khởi động, dừng, tạm dừng, xóa container. Xem thống kê container. Điều khiển container bằng terminal docker exec. Không được tạo ra để thay thế Portainer hay Dockge mà đơn giản là để quản lý container của bạn thay vì tạo mới chúng.
@@ -69,7 +70,7 @@ Termix là nền tảng quản lý máy chủ tất cả trong một, mã nguồ
- **Bảng Lệnh** - Nhấn đúp phím shift trái để truy cập nhanh các kết nối SSH bằng bàn phím
- **SSH Giàu Tính Năng** - Hỗ trợ jump host, Warpgate, kết nối dựa trên TOTP, SOCKS5, xác minh khóa máy chủ, tự động điền mật khẩu, [OPKSSH](https://github.com/openpubkey/opkssh), v.v.
- **Biểu Đồ Mạng** - Tùy chỉnh Bảng Điều Khiển để trực quan hóa homelab của bạn dựa trên các kết nối SSH với hỗ trợ trạng thái
- **Persistent Tabs** - SSH sessions and tabs stay open across devices/refreshes if enabled in user profile
- **Tab Liên Tục** - Các phiên SSH và tab vẫn mở trên các thiết bị/lần làm mới nếu được bật trong hồ sơ người dùng
# Tính Năng Dự Kiến
@@ -115,10 +116,27 @@ services:
- termix-data:/app/data
environment:
PORT: "8080"
depends_on:
- guacd
networks:
- termix-net
guacd:
image: guacamole/guacd:latest
container_name: guacd
restart: unless-stopped
ports:
- "4822:4822"
networks:
- termix-net
volumes:
termix-data:
driver: local
networks:
termix-net:
driver: bridge
```
# Nhà Tài Trợ
@@ -148,7 +166,7 @@ Vui lòng mô tả vấn đề càng chi tiết càng tốt, ưu tiên viết b
# Ảnh Chụp Màn Hình
[![YouTube](../repo-images/YouTube.jpg)](https://youtu.be/sjKIqfCK0NY)
[![YouTube](../repo-images/YouTube.jpg)](https://www.youtube.com/@TermixSSH/videos)
<p align="center">
<img src="../repo-images/Image%201.png" width="400" alt="Termix Demo 1"/>
+8 -5
View File
@@ -4,7 +4,7 @@ import cookieParser from "cookie-parser";
import { getDb, DatabaseSaveTrigger } from "./database/db/index.js";
import {
recentActivity,
sshData,
hosts,
hostAccess,
dashboardPreferences,
} from "./database/db/schema.js";
@@ -176,7 +176,7 @@ app.get("/activity/recent", async (req, res) => {
* properties:
* type:
* type: string
* enum: [terminal, file_manager, server_stats, tunnel, docker]
* enum: [terminal, file_manager, server_stats, tunnel, docker, telnet, vnc, rdp]
* hostId:
* type: integer
* hostName:
@@ -219,11 +219,14 @@ app.post("/activity/log", async (req, res) => {
"server_stats",
"tunnel",
"docker",
"telnet",
"vnc",
"rdp",
].includes(type)
) {
return res.status(400).json({
error:
"Invalid activity type. Must be 'terminal', 'file_manager', 'server_stats', 'tunnel', or 'docker'",
"Invalid activity type. Must be 'terminal', 'file_manager', 'server_stats', 'tunnel', 'docker', 'telnet', 'vnc', or 'rdp'",
});
}
@@ -252,8 +255,8 @@ app.post("/activity/log", async (req, res) => {
const ownedHosts = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
+13 -11
View File
@@ -3,11 +3,12 @@ import bodyParser from "body-parser";
import multer from "multer";
import cookieParser from "cookie-parser";
import userRoutes from "./routes/users.js";
import sshRoutes from "./routes/ssh.js";
import hostRoutes from "./routes/host.js";
import alertRoutes from "./routes/alerts.js";
import credentialsRoutes from "./routes/credentials.js";
import snippetsRoutes from "./routes/snippets.js";
import terminalRoutes from "./routes/terminal.js";
import guacamoleRoutes from "../guacamole/routes.js";
import networkTopologyRoutes from "./routes/network-topology.js";
import rbacRoutes from "./routes/rbac.js";
import cors from "cors";
@@ -28,7 +29,7 @@ import { parseUserAgent } from "../utils/user-agent-parser.js";
import { getProxyAgent } from "../utils/proxy-agent.js";
import {
users,
sshData,
hosts,
sshCredentials,
fileManagerRecent,
fileManagerPinned,
@@ -846,8 +847,8 @@ app.post("/database/export", authenticateJWT, async (req, res) => {
const sshHosts = await getDb()
.select()
.from(sshData)
.where(eq(sshData.userId, userId));
.from(hosts)
.where(eq(hosts.userId, userId));
const insertHost = exportDb.prepare(`
INSERT INTO ssh_data (id, user_id, name, ip, port, username, folder, tags, pin, auth_type, force_keyboard_interactive, password, key, key_password, key_type, sudo_password, autostart_password, autostart_key, autostart_key_password, credential_id, override_credential_username, enable_terminal, enable_tunnel, tunnel_connections, jump_hosts, enable_file_manager, enable_docker, show_terminal_in_sidebar, show_file_manager_in_sidebar, show_tunnel_in_sidebar, show_docker_in_sidebar, show_server_stats_in_sidebar, default_path, stats_config, terminal_config, quick_actions, notes, use_socks5, socks5_host, socks5_port, socks5_username, socks5_password, socks5_proxy_chain, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -1267,13 +1268,13 @@ app.post(
try {
const existing = await mainDb
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.userId, userId),
eq(sshData.ip, host.ip),
eq(sshData.port, host.port),
eq(sshData.username, host.username),
eq(hosts.userId, userId),
eq(hosts.ip, host.ip),
eq(hosts.port, host.port),
eq(hosts.username, host.username),
),
);
@@ -1341,7 +1342,7 @@ app.post(
userId,
userDataKey,
);
await mainDb.insert(sshData).values(encrypted);
await mainDb.insert(hosts).values(encrypted);
result.summary.sshHostsImported++;
} catch (hostError) {
result.summary.errors.push(
@@ -1759,11 +1760,12 @@ app.post("/database/restore", requireAdmin, async (req, res) => {
});
app.use("/users", userRoutes);
app.use("/ssh", sshRoutes);
app.use("/host", hostRoutes);
app.use("/alerts", alertRoutes);
app.use("/credentials", credentialsRoutes);
app.use("/snippets", snippetsRoutes);
app.use("/terminal", terminalRoutes);
app.use("/guacamole", guacamoleRoutes);
app.use("/network-topology", networkTopologyRoutes);
app.use("/rbac", rbacRoutes);
+42 -3
View File
@@ -427,9 +427,7 @@ async function initializeCompleteDatabase(): Promise<void> {
`);
try {
sqlite
.prepare("DELETE FROM sessions WHERE expires_at < datetime('now')")
.run();
sqlite.prepare("DELETE FROM sessions").run();
} catch (e) {
databaseLogger.warn("Could not clear expired sessions on startup", {
operation: "db_init_session_cleanup_failed",
@@ -474,6 +472,42 @@ async function initializeCompleteDatabase(): Promise<void> {
error: e,
});
}
try {
const row = sqlite
.prepare("SELECT value FROM settings WHERE key = 'guac_enabled'")
.get();
if (!row) {
sqlite
.prepare(
"INSERT INTO settings (key, value) VALUES ('guac_enabled', 'true')",
)
.run();
}
} catch (e) {
databaseLogger.warn("Could not initialize guac_enabled setting", {
operation: "db_init",
error: e,
});
}
try {
const row = sqlite
.prepare("SELECT value FROM settings WHERE key = 'guac_url'")
.get();
if (!row) {
sqlite
.prepare(
"INSERT INTO settings (key, value) VALUES ('guac_url', 'guacd:4822')",
)
.run();
}
} catch (e) {
databaseLogger.warn("Could not initialize guac_url setting", {
operation: "db_init",
error: e,
});
}
}
const addColumnIfNotExists = (
@@ -591,6 +625,11 @@ const migrateSchema = () => {
);
addColumnIfNotExists("ssh_data", "docker_config", "TEXT");
addColumnIfNotExists("ssh_data", "connection_type", 'TEXT NOT NULL DEFAULT "ssh"');
addColumnIfNotExists("ssh_data", "domain", "TEXT");
addColumnIfNotExists("ssh_data", "security", "TEXT");
addColumnIfNotExists("ssh_data", "ignore_cert", "INTEGER NOT NULL DEFAULT 0");
addColumnIfNotExists("ssh_data", "guacamole_config", "TEXT");
addColumnIfNotExists("ssh_data", "notes", "TEXT");
addColumnIfNotExists("ssh_data", "use_socks5", "INTEGER");
+16 -10
View File
@@ -64,11 +64,12 @@ export const trustedDevices = sqliteTable("trusted_devices", {
.default(sql`CURRENT_TIMESTAMP`),
});
export const sshData = sqliteTable("ssh_data", {
export const hosts = sqliteTable("ssh_data", {
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
connectionType: text("connection_type").notNull().default("ssh"),
name: text("name"),
ip: text("ip").notNull(),
port: integer("port").notNull(),
@@ -124,9 +125,14 @@ export const sshData = sqliteTable("ssh_data", {
.default(false),
defaultPath: text("default_path"),
statsConfig: text("stats_config"),
dockerConfig: text("docker_config"),
terminalConfig: text("terminal_config"),
quickActions: text("quick_actions"),
notes: text("notes"),
domain: text("domain"),
security: text("security"),
ignoreCert: integer("ignore_cert", { mode: "boolean" }).default(false),
guacamoleConfig: text("guacamole_config"),
useSocks5: integer("use_socks5", { mode: "boolean" }),
socks5Host: text("socks5_host"),
@@ -157,7 +163,7 @@ export const fileManagerRecent = sqliteTable("file_manager_recent", {
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
name: text("name").notNull(),
path: text("path").notNull(),
lastOpened: text("last_opened")
@@ -172,7 +178,7 @@ export const fileManagerPinned = sqliteTable("file_manager_pinned", {
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
name: text("name").notNull(),
path: text("path").notNull(),
pinnedAt: text("pinned_at")
@@ -187,7 +193,7 @@ export const fileManagerShortcuts = sqliteTable("file_manager_shortcuts", {
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
name: text("name").notNull(),
path: text("path").notNull(),
createdAt: text("created_at")
@@ -246,7 +252,7 @@ export const sshCredentialUsage = sqliteTable("ssh_credential_usage", {
.references(() => sshCredentials.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
@@ -313,7 +319,7 @@ export const recentActivity = sqliteTable("recent_activity", {
type: text("type").notNull(),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
hostName: text("host_name"),
timestamp: text("timestamp")
.notNull()
@@ -327,7 +333,7 @@ export const commandHistory = sqliteTable("command_history", {
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
command: text("command").notNull(),
executedAt: text("executed_at")
.notNull()
@@ -367,7 +373,7 @@ export const hostAccess = sqliteTable("host_access", {
id: integer("id").primaryKey({ autoIncrement: true }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
userId: text("user_id")
.references(() => users.id, { onDelete: "cascade" }),
@@ -492,7 +498,7 @@ export const sessionRecordings = sqliteTable("session_recordings", {
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
@@ -523,7 +529,7 @@ export const opksshTokens = sqliteTable("opkssh_tokens", {
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => sshData.id, { onDelete: "cascade" }),
.references(() => hosts.id, { onDelete: "cascade" }),
sshCert: text("ssh_cert", { length: 8192 }).notNull(),
privateKey: text("private_key", { length: 8192 }).notNull(),
+17 -27
View File
@@ -7,7 +7,7 @@ import { db } from "../db/index.js";
import {
sshCredentials,
sshCredentialUsage,
sshData,
hosts,
hostAccess,
} from "../db/schema.js";
import { eq, and, desc, sql } from "drizzle-orm";
@@ -606,9 +606,8 @@ router.put(
userId,
);
const { SharedCredentialManager } = await import(
"../../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
await sharedCredManager.updateSharedCredentialsForOriginal(
parseInt(id),
@@ -691,17 +690,14 @@ router.delete(
const hostsUsingCredential = await db
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.credentialId, parseInt(id)),
eq(sshData.userId, userId),
),
and(eq(hosts.credentialId, parseInt(id)), eq(hosts.userId, userId)),
);
if (hostsUsingCredential.length > 0) {
await db
.update(sshData)
.update(hosts)
.set({
credentialId: null,
password: null,
@@ -710,10 +706,7 @@ router.delete(
authType: "password",
})
.where(
and(
eq(sshData.credentialId, parseInt(id)),
eq(sshData.userId, userId),
),
and(eq(hosts.credentialId, parseInt(id)), eq(hosts.userId, userId)),
);
for (const host of hostsUsingCredential) {
@@ -737,9 +730,8 @@ router.delete(
}
}
const { SharedCredentialManager } = await import(
"../../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
await sharedCredManager.deleteSharedCredentialsForOriginal(parseInt(id));
@@ -837,7 +829,7 @@ router.post(
const credential = credentials[0];
await db
.update(sshData)
.update(hosts)
.set({
credentialId: parseInt(credentialId),
username: (credential.username as string) || "",
@@ -848,9 +840,7 @@ router.post(
keyType: null,
updatedAt: new Date().toISOString(),
})
.where(
and(eq(sshData.id, parseInt(hostId)), eq(sshData.userId, userId)),
);
.where(and(eq(hosts.id, parseInt(hostId)), eq(hosts.userId, userId)));
await db.insert(sshCredentialUsage).values({
credentialId: parseInt(credentialId),
@@ -917,17 +907,17 @@ router.get(
}
try {
const hosts = await db
const hostsUsingCredential = await db
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.credentialId, parseInt(credentialId)),
eq(sshData.userId, userId),
eq(hosts.credentialId, parseInt(credentialId)),
eq(hosts.userId, userId),
),
);
res.json(hosts.map((host) => formatSSHHostOutput(host)));
res.json(hostsUsingCredential.map((host) => formatSSHHostOutput(host)));
} catch (err) {
authLogger.error("Failed to fetch hosts using credential", err);
res.status(500).json({
@@ -1942,7 +1932,7 @@ router.post(
});
}
const targetHost = await SimpleDBOps.select(
db.select().from(sshData).where(eq(sshData.id, targetHostId)).limit(1),
db.select().from(hosts).where(eq(hosts.id, targetHostId)).limit(1),
"ssh_data",
userId,
);
@@ -2,7 +2,7 @@ import type { AuthenticatedRequest } from "../../../types/index.js";
import express from "express";
import { db } from "../db/index.js";
import {
sshData,
hosts,
sshCredentials,
sshCredentialUsage,
fileManagerRecent,
@@ -90,6 +90,12 @@ function transformHostResponse(
socks5ProxyChain: host.socks5ProxyChain
? JSON.parse(host.socks5ProxyChain as string)
: [],
domain: host.domain || undefined,
security: host.security || undefined,
ignoreCert: !!host.ignoreCert,
guacamoleConfig: host.guacamoleConfig
? JSON.parse(host.guacamoleConfig as string)
: undefined,
};
}
@@ -139,12 +145,9 @@ router.get("/db/host/internal", async (req: Request, res: Response) => {
try {
const autostartHosts = await db
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.enableTunnel, true),
isNotNull(sshData.tunnelConnections),
),
and(eq(hosts.enableTunnel, true), isNotNull(hosts.tunnelConnections)),
);
const result = autostartHosts
@@ -235,7 +238,7 @@ router.get("/db/host/internal/all", async (req: Request, res: Response) => {
.json({ error: "Invalid internal authentication token" });
}
const allHosts = await db.select().from(sshData);
const allHosts = await db.select().from(hosts);
const result = allHosts.map((host) => {
const tunnelConnections = host.tunnelConnections
@@ -334,6 +337,7 @@ router.post(
}
const {
connectionType,
name,
folder,
tags,
@@ -363,8 +367,13 @@ router.post(
jumpHosts,
quickActions,
statsConfig,
dockerConfig,
terminalConfig,
forceKeyboardInteractive,
domain,
security,
ignoreCert,
guacamoleConfig,
notes,
useSocks5,
socks5Host,
@@ -397,8 +406,10 @@ router.post(
}
const effectiveAuthType = authType || authMethod;
const effectiveConnectionType = connectionType || "ssh";
const sshDataObj: Record<string, unknown> = {
userId: userId,
connectionType: effectiveConnectionType,
name,
folder: folder || null,
tags: Array.isArray(tags) ? tags.join(",") : tags || "",
@@ -431,12 +442,21 @@ router.post(
? statsConfig
: JSON.stringify(statsConfig)
: null,
dockerConfig: dockerConfig
? typeof dockerConfig === "string"
? dockerConfig
: JSON.stringify(dockerConfig)
: null,
terminalConfig: terminalConfig
? typeof terminalConfig === "string"
? terminalConfig
: JSON.stringify(terminalConfig)
: null,
forceKeyboardInteractive: forceKeyboardInteractive ? "true" : "false",
domain: domain || null,
security: security || null,
ignoreCert: ignoreCert ? 1 : 0,
guacamoleConfig: guacamoleConfig ? JSON.stringify(guacamoleConfig) : null,
notes: notes || null,
sudoPassword: sudoPassword || null,
useSocks5: useSocks5 ? 1 : 0,
@@ -449,7 +469,13 @@ router.post(
: null,
};
if (effectiveAuthType === "password") {
// For non-SSH hosts (RDP, VNC, Telnet), always save password if provided
if (effectiveConnectionType !== "ssh") {
sshDataObj.password = password || null;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
} else if (effectiveAuthType === "password") {
sshDataObj.password = password || null;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
@@ -501,7 +527,7 @@ router.post(
try {
const result = await SimpleDBOps.insert(
sshData,
hosts,
"ssh_data",
sshDataObj,
userId,
@@ -532,7 +558,7 @@ router.post(
try {
const axios = (await import("axios")).default;
const statsPort = process.env.STATS_PORT || 30005;
const statsPort = 30005;
await axios.post(
`http://localhost:${statsPort}/host-updated`,
{ hostId: createdHost.id },
@@ -818,6 +844,7 @@ router.put(
}
const {
connectionType,
name,
folder,
tags,
@@ -847,8 +874,13 @@ router.put(
jumpHosts,
quickActions,
statsConfig,
dockerConfig,
terminalConfig,
forceKeyboardInteractive,
domain,
security,
ignoreCert,
guacamoleConfig,
notes,
useSocks5,
socks5Host,
@@ -884,6 +916,7 @@ router.put(
const effectiveAuthType = authType || authMethod;
const sshDataObj: Record<string, unknown> = {
connectionType: connectionType || "ssh",
name,
folder,
tags: Array.isArray(tags) ? tags.join(",") : tags || "",
@@ -916,12 +949,21 @@ router.put(
? statsConfig
: JSON.stringify(statsConfig)
: null,
dockerConfig: dockerConfig
? typeof dockerConfig === "string"
? dockerConfig
: JSON.stringify(dockerConfig)
: null,
terminalConfig: terminalConfig
? typeof terminalConfig === "string"
? terminalConfig
: JSON.stringify(terminalConfig)
: null,
forceKeyboardInteractive: forceKeyboardInteractive ? "true" : "false",
domain: domain || null,
security: security || null,
ignoreCert: ignoreCert ? 1 : 0,
guacamoleConfig: guacamoleConfig ? JSON.stringify(guacamoleConfig) : null,
notes: notes || null,
sudoPassword: sudoPassword || null,
useSocks5: useSocks5 ? 1 : 0,
@@ -934,7 +976,15 @@ router.put(
: null,
};
if (effectiveAuthType === "password") {
// For non-SSH hosts (RDP, VNC, Telnet), always save password if provided
if ((connectionType || "ssh") !== "ssh") {
if (password) {
sshDataObj.password = password;
}
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
} else if (effectiveAuthType === "password") {
if (password) {
sshDataObj.password = password;
}
@@ -1021,12 +1071,12 @@ router.put(
const hostRecord = await db
.select({
userId: sshData.userId,
credentialId: sshData.credentialId,
authType: sshData.authType,
userId: hosts.userId,
credentialId: hosts.credentialId,
authType: hosts.authType,
})
.from(sshData)
.where(eq(sshData.id, Number(hostId)))
.from(hosts)
.where(eq(hosts.id, Number(hostId)))
.limit(1);
if (hostRecord.length === 0) {
@@ -1072,9 +1122,9 @@ router.put(
}
await SimpleDBOps.update(
sshData,
hosts,
"ssh_data",
eq(sshData.id, Number(hostId)),
eq(hosts.id, Number(hostId)),
sshDataObj,
ownerId,
);
@@ -1082,8 +1132,8 @@ router.put(
const updatedHosts = await SimpleDBOps.select(
db
.select()
.from(sshData)
.where(eq(sshData.id, Number(hostId))),
.from(hosts)
.where(eq(hosts.id, Number(hostId))),
"ssh_data",
ownerId,
);
@@ -1110,7 +1160,7 @@ router.put(
try {
const axios = (await import("axios")).default;
const statsPort = process.env.STATS_PORT || 30005;
const statsPort = 30005;
await axios.post(
`http://localhost:${statsPort}/host-updated`,
{ hostId: parseInt(hostId) },
@@ -1186,62 +1236,67 @@ router.get(
const rawData = await db
.select({
id: sshData.id,
userId: sshData.userId,
name: sshData.name,
ip: sshData.ip,
port: sshData.port,
username: sshData.username,
folder: sshData.folder,
tags: sshData.tags,
pin: sshData.pin,
authType: sshData.authType,
password: sshData.password,
key: sshData.key,
keyPassword: sshData.keyPassword,
keyType: sshData.keyType,
enableTerminal: sshData.enableTerminal,
enableTunnel: sshData.enableTunnel,
tunnelConnections: sshData.tunnelConnections,
jumpHosts: sshData.jumpHosts,
enableFileManager: sshData.enableFileManager,
defaultPath: sshData.defaultPath,
autostartPassword: sshData.autostartPassword,
autostartKey: sshData.autostartKey,
autostartKeyPassword: sshData.autostartKeyPassword,
forceKeyboardInteractive: sshData.forceKeyboardInteractive,
statsConfig: sshData.statsConfig,
terminalConfig: sshData.terminalConfig,
sudoPassword: sshData.sudoPassword,
createdAt: sshData.createdAt,
updatedAt: sshData.updatedAt,
credentialId: sshData.credentialId,
overrideCredentialUsername: sshData.overrideCredentialUsername,
quickActions: sshData.quickActions,
notes: sshData.notes,
enableDocker: sshData.enableDocker,
showTerminalInSidebar: sshData.showTerminalInSidebar,
showFileManagerInSidebar: sshData.showFileManagerInSidebar,
showTunnelInSidebar: sshData.showTunnelInSidebar,
showDockerInSidebar: sshData.showDockerInSidebar,
showServerStatsInSidebar: sshData.showServerStatsInSidebar,
useSocks5: sshData.useSocks5,
socks5Host: sshData.socks5Host,
socks5Port: sshData.socks5Port,
socks5Username: sshData.socks5Username,
socks5Password: sshData.socks5Password,
socks5ProxyChain: sshData.socks5ProxyChain,
id: hosts.id,
userId: hosts.userId,
connectionType: hosts.connectionType,
name: hosts.name,
ip: hosts.ip,
port: hosts.port,
username: hosts.username,
folder: hosts.folder,
tags: hosts.tags,
pin: hosts.pin,
authType: hosts.authType,
password: hosts.password,
key: hosts.key,
keyPassword: hosts.keyPassword,
keyType: hosts.keyType,
enableTerminal: hosts.enableTerminal,
enableTunnel: hosts.enableTunnel,
tunnelConnections: hosts.tunnelConnections,
jumpHosts: hosts.jumpHosts,
enableFileManager: hosts.enableFileManager,
defaultPath: hosts.defaultPath,
autostartPassword: hosts.autostartPassword,
autostartKey: hosts.autostartKey,
autostartKeyPassword: hosts.autostartKeyPassword,
forceKeyboardInteractive: hosts.forceKeyboardInteractive,
statsConfig: hosts.statsConfig,
terminalConfig: hosts.terminalConfig,
sudoPassword: hosts.sudoPassword,
createdAt: hosts.createdAt,
updatedAt: hosts.updatedAt,
credentialId: hosts.credentialId,
overrideCredentialUsername: hosts.overrideCredentialUsername,
quickActions: hosts.quickActions,
notes: hosts.notes,
enableDocker: hosts.enableDocker,
showTerminalInSidebar: hosts.showTerminalInSidebar,
showFileManagerInSidebar: hosts.showFileManagerInSidebar,
showTunnelInSidebar: hosts.showTunnelInSidebar,
showDockerInSidebar: hosts.showDockerInSidebar,
showServerStatsInSidebar: hosts.showServerStatsInSidebar,
useSocks5: hosts.useSocks5,
socks5Host: hosts.socks5Host,
socks5Port: hosts.socks5Port,
socks5Username: hosts.socks5Username,
socks5Password: hosts.socks5Password,
socks5ProxyChain: hosts.socks5ProxyChain,
domain: hosts.domain,
security: hosts.security,
ignoreCert: hosts.ignoreCert,
guacamoleConfig: hosts.guacamoleConfig,
ownerId: sshData.userId,
isShared: sql<boolean>`${hostAccess.id} IS NOT NULL AND ${sshData.userId} != ${userId}`,
ownerId: hosts.userId,
isShared: sql<boolean>`${hostAccess.id} IS NOT NULL AND ${hosts.userId} != ${userId}`,
permissionLevel: hostAccess.permissionLevel,
expiresAt: hostAccess.expiresAt,
})
.from(sshData)
.from(hosts)
.leftJoin(
hostAccess,
and(
eq(hostAccess.hostId, sshData.id),
eq(hostAccess.hostId, hosts.id),
or(
eq(hostAccess.userId, userId),
roleIds.length > 0
@@ -1253,7 +1308,7 @@ router.get(
)
.where(
or(
eq(sshData.userId, userId),
eq(hosts.userId, userId),
and(
eq(hostAccess.userId, userId),
or(isNull(hostAccess.expiresAt), gte(hostAccess.expiresAt, now)),
@@ -1361,10 +1416,14 @@ router.get(
return res.status(400).json({ error: "Invalid userId or hostId" });
}
try {
const data = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, Number(hostId)), eq(sshData.userId, userId)));
const data = await SimpleDBOps.select(
db
.select()
.from(hosts)
.where(and(eq(hosts.id, Number(hostId)), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
if (data.length === 0) {
sshLogger.warn("SSH host not found", {
@@ -1429,37 +1488,36 @@ router.get(
}
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
db
.select()
.from(sshData)
.where(
and(eq(sshData.id, Number(hostId)), eq(sshData.userId, userId)),
),
.from(hosts)
.where(and(eq(hosts.id, Number(hostId)), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
return res.status(404).json({ error: "SSH host not found" });
}
const host = hosts[0];
const host = hostResults[0];
const resolvedHost = (await resolveHostCredentials(host, userId)) || host;
const exportData = {
const exportedConnectionType =
(resolvedHost.connectionType as string) || "ssh";
const isRemoteDesktop = ["rdp", "vnc", "telnet"].includes(
exportedConnectionType,
);
const baseExportData = {
connectionType: exportedConnectionType,
name: resolvedHost.name,
ip: resolvedHost.ip,
port: resolvedHost.port,
username: resolvedHost.username,
authType: resolvedHost.authType,
password: resolvedHost.password || null,
key: resolvedHost.key || null,
keyPassword: resolvedHost.keyPassword || null,
keyType: resolvedHost.keyType || null,
credentialId: resolvedHost.credentialId || null,
overrideCredentialUsername: !!resolvedHost.overrideCredentialUsername,
folder: resolvedHost.folder,
tags:
typeof resolvedHost.tags === "string"
@@ -1467,44 +1525,68 @@ router.get(
: resolvedHost.tags || [],
pin: !!resolvedHost.pin,
notes: resolvedHost.notes || null,
enableTerminal: !!resolvedHost.enableTerminal,
enableTunnel: !!resolvedHost.enableTunnel,
enableFileManager: !!resolvedHost.enableFileManager,
enableDocker: !!resolvedHost.enableDocker,
showTerminalInSidebar: !!resolvedHost.showTerminalInSidebar,
showFileManagerInSidebar: !!resolvedHost.showFileManagerInSidebar,
showTunnelInSidebar: !!resolvedHost.showTunnelInSidebar,
showDockerInSidebar: !!resolvedHost.showDockerInSidebar,
showServerStatsInSidebar: !!resolvedHost.showServerStatsInSidebar,
defaultPath: resolvedHost.defaultPath,
sudoPassword: resolvedHost.sudoPassword || null,
tunnelConnections: resolvedHost.tunnelConnections
? JSON.parse(resolvedHost.tunnelConnections as string)
: [],
jumpHosts: resolvedHost.jumpHosts
? JSON.parse(resolvedHost.jumpHosts as string)
: null,
quickActions: resolvedHost.quickActions
? JSON.parse(resolvedHost.quickActions as string)
: null,
statsConfig: resolvedHost.statsConfig
? JSON.parse(resolvedHost.statsConfig as string)
: null,
terminalConfig: resolvedHost.terminalConfig
? JSON.parse(resolvedHost.terminalConfig as string)
: null,
forceKeyboardInteractive:
resolvedHost.forceKeyboardInteractive === "true",
useSocks5: !!resolvedHost.useSocks5,
socks5Host: resolvedHost.socks5Host || null,
socks5Port: resolvedHost.socks5Port || null,
socks5Username: resolvedHost.socks5Username || null,
socks5Password: resolvedHost.socks5Password || null,
socks5ProxyChain: resolvedHost.socks5ProxyChain
? JSON.parse(resolvedHost.socks5ProxyChain as string)
: null,
};
const exportData = isRemoteDesktop
? {
...baseExportData,
domain: resolvedHost.domain || null,
security: resolvedHost.security || null,
ignoreCert: !!resolvedHost.ignoreCert,
guacamoleConfig: resolvedHost.guacamoleConfig
? JSON.parse(resolvedHost.guacamoleConfig as string)
: null,
}
: {
...baseExportData,
authType: resolvedHost.authType,
key: resolvedHost.key || null,
keyPassword: resolvedHost.keyPassword || null,
keyType: resolvedHost.keyType || null,
credentialId: resolvedHost.credentialId || null,
overrideCredentialUsername:
!!resolvedHost.overrideCredentialUsername,
enableTerminal: !!resolvedHost.enableTerminal,
enableTunnel: !!resolvedHost.enableTunnel,
enableFileManager: !!resolvedHost.enableFileManager,
enableDocker: !!resolvedHost.enableDocker,
showTerminalInSidebar: !!resolvedHost.showTerminalInSidebar,
showFileManagerInSidebar: !!resolvedHost.showFileManagerInSidebar,
showTunnelInSidebar: !!resolvedHost.showTunnelInSidebar,
showDockerInSidebar: !!resolvedHost.showDockerInSidebar,
showServerStatsInSidebar: !!resolvedHost.showServerStatsInSidebar,
defaultPath: resolvedHost.defaultPath,
sudoPassword: resolvedHost.sudoPassword || null,
tunnelConnections: resolvedHost.tunnelConnections
? JSON.parse(resolvedHost.tunnelConnections as string)
: [],
jumpHosts: resolvedHost.jumpHosts
? JSON.parse(resolvedHost.jumpHosts as string)
: null,
quickActions: resolvedHost.quickActions
? JSON.parse(resolvedHost.quickActions as string)
: null,
statsConfig: resolvedHost.statsConfig
? JSON.parse(resolvedHost.statsConfig as string)
: null,
dockerConfig: resolvedHost.dockerConfig
? JSON.parse(resolvedHost.dockerConfig as string)
: null,
terminalConfig: resolvedHost.terminalConfig
? JSON.parse(resolvedHost.terminalConfig as string)
: null,
forceKeyboardInteractive:
resolvedHost.forceKeyboardInteractive === "true",
useSocks5: !!resolvedHost.useSocks5,
socks5Host: resolvedHost.socks5Host || null,
socks5Port: resolvedHost.socks5Port || null,
socks5Username: resolvedHost.socks5Username || null,
socks5Password: resolvedHost.socks5Password || null,
socks5ProxyChain: resolvedHost.socks5ProxyChain
? JSON.parse(resolvedHost.socks5ProxyChain as string)
: null,
};
sshLogger.success("Host exported with decrypted credentials", {
operation: "host_export",
hostId: parseInt(hostId),
@@ -1573,8 +1655,8 @@ router.delete(
try {
const hostToDelete = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, Number(hostId)), eq(sshData.userId, userId)));
.from(hosts)
.where(and(eq(hosts.id, Number(hostId)), eq(hosts.userId, userId)));
if (hostToDelete.length === 0) {
sshLogger.warn("SSH host not found for deletion", {
@@ -1618,8 +1700,8 @@ router.delete(
.where(eq(sessionRecordings.hostId, numericHostId));
await db
.delete(sshData)
.where(and(eq(sshData.id, numericHostId), eq(sshData.userId, userId)));
.delete(hosts)
.where(and(eq(hosts.id, numericHostId), eq(hosts.userId, userId)));
databaseLogger.success("SSH host deleted", {
operation: "host_delete_success",
@@ -1629,7 +1711,7 @@ router.delete(
try {
const axios = (await import("axios")).default;
const statsPort = process.env.STATS_PORT || 30005;
const statsPort = 30005;
await axios.post(
`http://localhost:${statsPort}/host-deleted`,
{ hostId: numericHostId },
@@ -2522,9 +2604,9 @@ router.put(
try {
const updatedHosts = await SimpleDBOps.update(
sshData,
hosts,
"ssh_data",
and(eq(sshData.userId, userId), eq(sshData.folder, oldName)),
and(eq(hosts.userId, userId), eq(hosts.folder, oldName)),
{
folder: newName,
updatedAt: new Date().toISOString(),
@@ -2748,8 +2830,8 @@ router.delete(
try {
const hostsToDelete = await db
.select()
.from(sshData)
.where(and(eq(sshData.userId, userId), eq(sshData.folder, folderName)));
.from(hosts)
.where(and(eq(hosts.userId, userId), eq(hosts.folder, folderName)));
if (hostsToDelete.length === 0) {
return res.json({
@@ -2793,8 +2875,8 @@ router.delete(
}
await db
.delete(sshData)
.where(and(eq(sshData.userId, userId), eq(sshData.folder, folderName)));
.delete(hosts)
.where(and(eq(hosts.userId, userId), eq(hosts.folder, folderName)));
await db
.delete(sshFolders)
@@ -2806,7 +2888,7 @@ router.delete(
try {
const axios = (await import("axios")).default;
const statsPort = process.env.STATS_PORT || 30005;
const statsPort = 30005;
for (const host of hostsToDelete) {
try {
await axios.post(
@@ -2935,9 +3017,9 @@ router.patch(
try {
const ownedHosts = await db
.select({ id: sshData.id, statsConfig: sshData.statsConfig })
.from(sshData)
.where(and(inArray(sshData.id, hostIds), eq(sshData.userId, userId)));
.select({ id: hosts.id, statsConfig: hosts.statsConfig })
.from(hosts)
.where(and(inArray(hosts.id, hostIds), eq(hosts.userId, userId)));
const ownedIds = ownedHosts.map((h) => h.id);
const unauthorizedIds = hostIds.filter(
@@ -2968,11 +3050,9 @@ router.patch(
if (Object.keys(simpleUpdates).length > 0) {
await db
.update(sshData)
.update(hosts)
.set(simpleUpdates)
.where(
and(inArray(sshData.id, ownedIds), eq(sshData.userId, userId)),
);
.where(and(inArray(hosts.id, ownedIds), eq(hosts.userId, userId)));
}
if (updates.statsConfig && typeof updates.statsConfig === "object") {
@@ -2983,9 +3063,9 @@ router.patch(
: {};
const merged = { ...existing, ...updates.statsConfig };
await db
.update(sshData)
.update(hosts)
.set({ statsConfig: JSON.stringify(merged) })
.where(and(eq(sshData.id, host.id), eq(sshData.userId, userId)));
.where(and(eq(hosts.id, host.id), eq(hosts.userId, userId)));
} catch (e) {
errors.push(`Failed to update statsConfig for host ${host.id}`);
}
@@ -3011,15 +3091,15 @@ router.post(
authenticateJWT,
async (req: Request, res: Response) => {
const userId = (req as AuthenticatedRequest).userId;
const { hosts, overwrite } = req.body;
const { hosts: hostsToImport, overwrite } = req.body;
if (!Array.isArray(hosts) || hosts.length === 0) {
if (!Array.isArray(hostsToImport) || hostsToImport.length === 0) {
return res
.status(400)
.json({ error: "Hosts array is required and must not be empty" });
}
if (hosts.length > 100) {
if (hostsToImport.length > 100) {
return res
.status(400)
.json({ error: "Maximum 100 hosts allowed per import" });
@@ -3037,7 +3117,7 @@ router.post(
if (overwrite) {
try {
const allHosts = await SimpleDBOps.select<Record<string, unknown>>(
db.select().from(sshData).where(eq(sshData.userId, userId)),
db.select().from(hosts).where(eq(hosts.userId, userId)),
"ssh_data",
userId,
);
@@ -3051,23 +3131,34 @@ router.post(
}
}
for (let i = 0; i < hosts.length; i++) {
const hostData = hosts[i];
for (let i = 0; i < hostsToImport.length; i++) {
const hostData = hostsToImport[i];
try {
if (
!isNonEmptyString(hostData.ip) ||
!isValidPort(hostData.port) ||
!isNonEmptyString(hostData.username)
) {
const effectiveConnectionType = hostData.connectionType || "ssh";
if (!isNonEmptyString(hostData.ip) || !isValidPort(hostData.port)) {
results.failed++;
results.errors.push(
`Host ${i + 1}: Missing required fields (ip, port, username)`,
`Host ${i + 1}: Missing required fields (ip, port)`,
);
continue;
}
if (
effectiveConnectionType === "ssh" &&
!isNonEmptyString(hostData.username)
) {
results.failed++;
results.errors.push(
`Host ${i + 1}: Username required for SSH connections`,
);
continue;
}
if (
effectiveConnectionType === "ssh" &&
hostData.authType &&
!["password", "key", "credential", "none", "opkssh"].includes(
hostData.authType,
)
@@ -3080,6 +3171,7 @@ router.post(
}
if (
effectiveConnectionType === "ssh" &&
hostData.authType === "password" &&
!isNonEmptyString(hostData.password)
) {
@@ -3090,7 +3182,11 @@ router.post(
continue;
}
if (hostData.authType === "key" && !isNonEmptyString(hostData.key)) {
if (
effectiveConnectionType === "ssh" &&
hostData.authType === "key" &&
!isNonEmptyString(hostData.key)
) {
results.failed++;
results.errors.push(
`Host ${i + 1}: Key required for key authentication`,
@@ -3098,7 +3194,11 @@ router.post(
continue;
}
if (hostData.authType === "credential" && !hostData.credentialId) {
if (
effectiveConnectionType === "ssh" &&
hostData.authType === "credential" &&
!hostData.credentialId
) {
results.failed++;
results.errors.push(
`Host ${i + 1}: credentialId required for credential authentication`,
@@ -3108,21 +3208,13 @@ router.post(
const sshDataObj: Record<string, unknown> = {
userId: userId,
name: hostData.name || `${hostData.username}@${hostData.ip}`,
connectionType: effectiveConnectionType,
name: hostData.name || `${hostData.username || ""}@${hostData.ip}`,
folder: hostData.folder || "Default",
tags: Array.isArray(hostData.tags) ? hostData.tags.join(",") : "",
ip: hostData.ip,
port: hostData.port,
username: hostData.username,
password: hostData.authType === "password" ? hostData.password : null,
authType: hostData.authType,
credentialId:
hostData.authType === "credential" ? hostData.credentialId : null,
key: hostData.authType === "key" ? hostData.key : null,
keyPassword:
hostData.authType === "key" ? hostData.keyPassword || null : null,
keyType:
hostData.authType === "key" ? hostData.keyType || "auto" : null,
username: hostData.username || null,
pin: hostData.pin || false,
enableTerminal: hostData.enableTerminal !== false,
enableTunnel: hostData.enableTunnel !== false,
@@ -3147,6 +3239,9 @@ router.post(
statsConfig: hostData.statsConfig
? JSON.stringify(hostData.statsConfig)
: null,
dockerConfig: hostData.dockerConfig
? JSON.stringify(hostData.dockerConfig)
: null,
terminalConfig: hostData.terminalConfig
? JSON.stringify(hostData.terminalConfig)
: null,
@@ -3168,21 +3263,51 @@ router.post(
updatedAt: new Date().toISOString(),
};
if (effectiveConnectionType !== "ssh") {
sshDataObj.password = hostData.password || null;
sshDataObj.authType = "password";
sshDataObj.credentialId = null;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
sshDataObj.domain = hostData.domain || null;
sshDataObj.security = hostData.security || null;
sshDataObj.ignoreCert = hostData.ignoreCert ? 1 : 0;
sshDataObj.guacamoleConfig = hostData.guacamoleConfig
? JSON.stringify(hostData.guacamoleConfig)
: null;
} else {
sshDataObj.password =
hostData.authType === "password" ? hostData.password : null;
sshDataObj.authType = hostData.authType || "password";
sshDataObj.credentialId =
hostData.authType === "credential" ? hostData.credentialId : null;
sshDataObj.key = hostData.authType === "key" ? hostData.key : null;
sshDataObj.keyPassword =
hostData.authType === "key" ? hostData.keyPassword || null : null;
sshDataObj.keyType =
hostData.authType === "key" ? hostData.keyType || "auto" : null;
sshDataObj.domain = null;
sshDataObj.security = null;
sshDataObj.ignoreCert = 0;
sshDataObj.guacamoleConfig = null;
}
const lookupKey = `${hostData.ip}:${hostData.port}:${hostData.username}`;
const existing = existingHostMap?.get(lookupKey);
if (existing) {
await SimpleDBOps.update(
sshData,
hosts,
"ssh_data",
eq(sshData.id, existing.id),
eq(hosts.id, existing.id),
sshDataObj,
userId,
);
results.updated++;
} else {
sshDataObj.createdAt = new Date().toISOString();
await SimpleDBOps.insert(sshData, "ssh_data", sshDataObj, userId);
await SimpleDBOps.insert(hosts, "ssh_data", sshDataObj, userId);
results.success++;
}
} catch (error) {
@@ -3204,6 +3329,104 @@ router.post(
},
);
/**
* @openapi
* /ssh/folders/{folderName}/hosts:
* delete:
* summary: Delete all hosts in a folder
* description: Deletes all hosts within a specific folder.
* tags:
* - SSH
* parameters:
* - in: path
* name: folderName
* required: true
* schema:
* type: string
* responses:
* 200:
* description: All hosts deleted successfully.
* 400:
* description: Invalid folder name.
* 500:
* description: Failed to delete hosts.
*/
router.delete(
"/folders/:folderName/hosts",
authenticateJWT,
requireDataAccess,
async (req: Request, res: Response) => {
const userId = (req as AuthenticatedRequest).userId;
const folderName = decodeURIComponent(
Array.isArray(req.params.folderName)
? req.params.folderName[0]
: req.params.folderName,
);
if (!folderName) {
return res.status(400).json({ error: "Folder name is required" });
}
try {
const hostsToDelete = await db
.select({ id: hosts.id })
.from(hosts)
.where(and(eq(hosts.userId, userId), eq(hosts.folder, folderName)));
if (hostsToDelete.length === 0) {
return res.json({ deletedCount: 0 });
}
const hostIds = hostsToDelete.map((h) => h.id);
for (const hostId of hostIds) {
await db
.delete(fileManagerRecent)
.where(eq(fileManagerRecent.hostId, hostId));
await db
.delete(fileManagerPinned)
.where(eq(fileManagerPinned.hostId, hostId));
await db
.delete(fileManagerShortcuts)
.where(eq(fileManagerShortcuts.hostId, hostId));
await db
.delete(commandHistory)
.where(eq(commandHistory.hostId, hostId));
await db
.delete(sshCredentialUsage)
.where(eq(sshCredentialUsage.hostId, hostId));
await db
.delete(recentActivity)
.where(eq(recentActivity.hostId, hostId));
await db.delete(hostAccess).where(eq(hostAccess.hostId, hostId));
await db
.delete(sessionRecordings)
.where(eq(sessionRecordings.hostId, hostId));
}
await db
.delete(hosts)
.where(and(eq(hosts.userId, userId), eq(hosts.folder, folderName)));
databaseLogger.success("All hosts in folder deleted", {
operation: "delete_folder_hosts",
userId,
folderName,
deletedCount: hostsToDelete.length,
});
res.json({ deletedCount: hostsToDelete.length });
} catch (error) {
sshLogger.error("Failed to delete hosts in folder", error, {
operation: "delete_folder_hosts",
userId,
folderName,
});
res.status(500).json({ error: "Failed to delete hosts in folder" });
}
},
);
/**
* @openapi
* /ssh/autostart/enable:
@@ -3270,8 +3493,8 @@ router.post(
const sshConfig = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, sshConfigId), eq(sshData.userId, userId)));
.from(hosts)
.where(and(eq(hosts.id, sshConfigId), eq(hosts.userId, userId)));
if (sshConfig.length === 0) {
sshLogger.warn("SSH config not found for autostart enable", {
@@ -3309,8 +3532,8 @@ router.post(
) {
const endpointHosts = await db
.select()
.from(sshData)
.where(eq(sshData.userId, userId));
.from(hosts)
.where(eq(hosts.userId, userId));
const endpointHost = endpointHosts.find(
(h) =>
@@ -3349,14 +3572,14 @@ router.post(
}
await db
.update(sshData)
.update(hosts)
.set({
autostartPassword: decryptedConfig.password || null,
autostartKey: decryptedConfig.key || null,
autostartKeyPassword: decryptedConfig.keyPassword || null,
tunnelConnections: updatedTunnelConnections,
})
.where(eq(sshData.id, sshConfigId));
.where(eq(hosts.id, sshConfigId));
try {
await DatabaseSaveTrigger.triggerSave();
@@ -3429,13 +3652,13 @@ router.delete(
try {
await db
.update(sshData)
.update(hosts)
.set({
autostartPassword: null,
autostartKey: null,
autostartKeyPassword: null,
})
.where(and(eq(sshData.id, sshConfigId), eq(sshData.userId, userId)));
.where(and(eq(hosts.id, sshConfigId), eq(hosts.userId, userId)));
res.json({
message: "AutoStart disabled successfully",
@@ -3475,13 +3698,13 @@ router.get(
try {
const autostartConfigs = await db
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.userId, userId),
eq(hosts.userId, userId),
or(
isNotNull(sshData.autostartPassword),
isNotNull(sshData.autostartKey),
isNotNull(hosts.autostartPassword),
isNotNull(hosts.autostartKey),
),
),
);
+23 -26
View File
@@ -3,7 +3,7 @@ import express from "express";
import { db } from "../db/index.js";
import {
hostAccess,
sshData,
hosts,
users,
roles,
userRoles,
@@ -111,8 +111,8 @@ router.post(
const host = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId)))
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId)))
.limit(1);
if (host.length === 0) {
@@ -201,9 +201,8 @@ router.post(
.delete(sharedCredentials)
.where(eq(sharedCredentials.hostAccessId, existing[0].id));
const { SharedCredentialManager } = await import(
"../../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
if (targetType === "user") {
await sharedCredManager.createSharedCredentialForUser(
@@ -244,9 +243,8 @@ router.post(
expiresAt,
});
const { SharedCredentialManager } = await import(
"../../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
if (targetType === "user") {
@@ -336,8 +334,8 @@ router.delete(
try {
const host = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId)))
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId)))
.limit(1);
if (host.length === 0) {
@@ -404,8 +402,8 @@ router.get(
try {
const host = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId)))
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId)))
.limit(1);
if (host.length === 0) {
@@ -484,21 +482,21 @@ router.get(
const sharedHosts = await db
.select({
id: sshData.id,
name: sshData.name,
ip: sshData.ip,
port: sshData.port,
username: sshData.username,
folder: sshData.folder,
tags: sshData.tags,
id: hosts.id,
name: hosts.name,
ip: hosts.ip,
port: hosts.port,
username: hosts.username,
folder: hosts.folder,
tags: hosts.tags,
permissionLevel: hostAccess.permissionLevel,
expiresAt: hostAccess.expiresAt,
grantedBy: hostAccess.grantedBy,
ownerUsername: users.username,
})
.from(hostAccess)
.innerJoin(sshData, eq(hostAccess.hostId, sshData.id))
.innerJoin(users, eq(sshData.userId, users.id))
.innerJoin(hosts, eq(hostAccess.hostId, hosts.id))
.innerJoin(users, eq(hosts.userId, users.id))
.where(
and(
eq(hostAccess.userId, userId),
@@ -978,12 +976,11 @@ router.post(
const hostsSharedWithRole = await db
.select()
.from(hostAccess)
.innerJoin(sshData, eq(hostAccess.hostId, sshData.id))
.innerJoin(hosts, eq(hostAccess.hostId, hosts.id))
.where(eq(hostAccess.roleId, roleId));
const { SharedCredentialManager } = await import(
"../../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
for (const { host_access, ssh_data } of hostsSharedWithRole) {
+3 -5
View File
@@ -632,17 +632,15 @@ router.post(
const snippet = snippetResult[0];
const { Client } = await import("ssh2");
const { sshData, sshCredentials } = await import("../db/schema.js");
const { hosts, sshCredentials } = await import("../db/schema.js");
const { SimpleDBOps } = await import("../../utils/simple-db-ops.js");
const hostResult = await SimpleDBOps.select(
db
.select()
.from(sshData)
.where(
and(eq(sshData.id, parseInt(hostId)), eq(sshData.userId, userId)),
),
.from(hosts)
.where(and(eq(hosts.id, parseInt(hostId)), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
+147 -42
View File
@@ -1,11 +1,12 @@
import type { AuthenticatedRequest } from "../../../types/index.js";
import express from "express";
import { restartGuacServer } from "../../guacamole/guacamole-server.js";
import crypto from "crypto";
import { db } from "../db/index.js";
import {
users,
sessions,
sshData,
hosts,
sshCredentials,
fileManagerRecent,
fileManagerPinned,
@@ -43,6 +44,7 @@ import {
generateDeviceFingerprint,
} from "../../utils/user-agent-parser.js";
import { loginRateLimiter } from "../../utils/login-rate-limiter.js";
import { getRequestOriginWithForceHTTPS } from "../../utils/request-origin.js";
const authManager = AuthManager.getInstance();
@@ -264,7 +266,7 @@ async function deleteUserAndRelatedData(userId: string): Promise<void> {
await db.delete(commandHistory).where(eq(commandHistory.userId, userId));
await db.delete(sshData).where(eq(sshData.userId, userId));
await db.delete(hosts).where(eq(hosts.userId, userId));
await db.delete(sshCredentials).where(eq(sshCredentials.userId, userId));
await db.delete(networkTopology).where(eq(networkTopology.userId, userId));
@@ -788,6 +790,12 @@ router.get("/oidc-config/admin", requireAdmin, async (req, res) => {
* description: Returns the OIDC authorization URL.
* tags:
* - Users
* parameters:
* - in: query
* name: rememberMe
* schema:
* type: boolean
* description: Whether to extend the session to 30 days instead of 2 hours.
* responses:
* 200:
* description: OIDC authorization URL.
@@ -798,16 +806,9 @@ router.get("/oidc-config/admin", requireAdmin, async (req, res) => {
*/
router.get("/oidc/authorize", async (req, res) => {
try {
authLogger.info("OIDC authorize request headers", {
protocol: req.protocol,
host: req.get("Host"),
origin: req.get("Origin"),
referer: req.get("Referer"),
"x-forwarded-proto": req.get("X-Forwarded-Proto"),
"x-forwarded-host": req.get("X-Forwarded-Host"),
"x-forwarded-port": req.get("X-Forwarded-Port"),
secure: req.secure,
});
const { rememberMe } = req.query;
const origin = getRequestOriginWithForceHTTPS(req);
const backendCallbackUri = `${origin}/users/oidc/callback`;
const envConfig = getOIDCConfigFromEnv();
let config;
@@ -826,15 +827,6 @@ router.get("/oidc/authorize", async (req, res) => {
const state = nanoid();
const nonce = nanoid();
const protocol =
process.env.OIDC_FORCE_HTTPS === "true"
? "https"
: req.get("X-Forwarded-Proto") || req.protocol;
const host = req.get("Host");
const origin = `${protocol}://${host}`;
const backendCallbackUri = `${origin}/users/oidc/callback`;
const referer = req.get("Referer");
let frontendOrigin;
if (referer) {
@@ -856,12 +848,12 @@ router.get("/oidc/authorize", async (req, res) => {
.prepare("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)")
.run(`oidc_frontend_origin_${state}`, frontendOrigin);
authLogger.info("OIDC authorization initiated", {
operation: "oidc_authorize",
backendCallbackUri,
frontendOrigin,
referer,
});
db.$client
.prepare("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)")
.run(
`oidc_remember_me_${state}`,
rememberMe === "true" ? "true" : "false",
);
const authUrl = new URL(config.authorization_url);
authUrl.searchParams.set("client_id", config.client_id);
@@ -894,10 +886,6 @@ router.get("/oidc/authorize", async (req, res) => {
*/
router.get("/oidc/callback", async (req, res) => {
const { code, state } = req.query;
authLogger.info("OIDC login callback received", {
operation: "oidc_login_request",
state,
});
if (!isNonEmptyString(code) || !isNonEmptyString(state)) {
return res.status(400).json({ error: "Code and state are required" });
@@ -909,6 +897,9 @@ router.get("/oidc/callback", async (req, res) => {
const storedFrontendOriginRow = db.$client
.prepare("SELECT value FROM settings WHERE key = ?")
.get(`oidc_frontend_origin_${state}`);
const storedRememberMeRow = db.$client
.prepare("SELECT value FROM settings WHERE key = ?")
.get(`oidc_remember_me_${state}`);
if (!storedBackendCallbackRow || !storedFrontendOriginRow) {
return res
@@ -921,6 +912,8 @@ router.get("/oidc/callback", async (req, res) => {
).value as string;
const frontendOrigin = (storedFrontendOriginRow as Record<string, unknown>)
.value as string;
const storedRememberMe =
(storedRememberMeRow as Record<string, unknown> | null)?.value === "true";
try {
const storedNonce = db.$client
@@ -947,12 +940,6 @@ router.get("/oidc/callback", async (req, res) => {
);
}
authLogger.info("OIDC token exchange attempt", {
operation: "oidc_token_exchange",
backendCallbackUri,
frontendOrigin,
});
const tokenResponse = await fetch(config.token_url, {
method: "POST",
headers: {
@@ -994,6 +981,9 @@ router.get("/oidc/callback", async (req, res) => {
db.$client
.prepare("DELETE FROM settings WHERE key = ?")
.run(`oidc_frontend_origin_${state}`);
db.$client
.prepare("DELETE FROM settings WHERE key = ?")
.run(`oidc_remember_me_${state}`);
let userInfo: Record<string, unknown> = null;
const userInfoUrls: string[] = [];
@@ -1316,6 +1306,7 @@ router.get("/oidc/callback", async (req, res) => {
const token = await authManager.generateJWTToken(userRecord.id, {
deviceType: deviceInfo.type,
deviceInfo: deviceInfo.deviceInfo,
rememberMe: storedRememberMe,
});
authLogger.success("OIDC login successful", {
@@ -1330,7 +1321,9 @@ router.get("/oidc/callback", async (req, res) => {
const maxAge =
deviceInfo.type === "desktop" || deviceInfo.type === "mobile"
? 30 * 24 * 60 * 60 * 1000
: 2 * 60 * 60 * 1000;
: storedRememberMe
? 30 * 24 * 60 * 60 * 1000
: 2 * 60 * 60 * 1000;
res.clearCookie("jwt", authManager.getClearCookieOptions(req));
@@ -1529,9 +1522,10 @@ router.post("/login", async (req, res) => {
if (userRecord.totpEnabled) {
const deviceFingerprint = generateDeviceFingerprint(deviceInfo);
const isTrusted = rememberMe
? await authManager.isTrustedDevice(userRecord.id, deviceFingerprint)
: false;
const isTrusted = await authManager.isTrustedDevice(
userRecord.id,
deviceFingerprint,
);
if (isTrusted) {
authLogger.info("TOTP bypassed for trusted device", {
@@ -2483,7 +2477,7 @@ router.post("/complete-reset", async (req, res) => {
.delete(dismissedAlerts)
.where(eq(dismissedAlerts.userId, userId));
await db.delete(snippets).where(eq(snippets.userId, userId));
await db.delete(sshData).where(eq(sshData.userId, userId));
await db.delete(hosts).where(eq(hosts.userId, userId));
await db
.delete(sshCredentials)
.where(eq(sshCredentials.userId, userId));
@@ -4121,4 +4115,115 @@ router.post("/unlink-oidc-from-password", authenticateJWT, async (req, res) => {
}
});
/**
* @openapi
* /users/guacamole-settings:
* get:
* summary: Get Guacamole settings
* description: Returns current guacd enabled status and host:port URL. No authentication required.
* tags:
* - Users
* responses:
* 200:
* description: Guacamole settings.
* content:
* application/json:
* schema:
* type: object
* properties:
* enabled:
* type: boolean
* url:
* type: string
* 500:
* description: Failed to get guacamole settings.
*/
router.get("/guacamole-settings", async (req, res) => {
try {
const enabledRow = db.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_enabled'")
.get() as { value: string } | undefined;
const urlRow = db.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_url'")
.get() as { value: string } | undefined;
res.json({
enabled: enabledRow ? enabledRow.value !== "false" : true,
url: urlRow ? urlRow.value : "guacd:4822",
});
} catch (err) {
authLogger.error("Failed to get guacamole settings", err);
res.status(500).json({ error: "Failed to get guacamole settings" });
}
});
/**
* @openapi
* /users/guacamole-settings:
* patch:
* summary: Update Guacamole settings
* description: Admin-only. Updates guacd enabled status and/or host:port URL.
* tags:
* - Users
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* enabled:
* type: boolean
* url:
* type: string
* responses:
* 200:
* description: Guacamole settings updated.
* 403:
* description: Not authorized.
* 500:
* description: Failed to update guacamole settings.
*/
router.patch("/guacamole-settings", authenticateJWT, async (req, res) => {
const userId = (req as AuthenticatedRequest).userId;
try {
const user = await db.select().from(users).where(eq(users.id, userId));
if (!user || user.length === 0 || !user[0].isAdmin) {
return res.status(403).json({ error: "Not authorized" });
}
const { enabled, url } = req.body;
if (typeof enabled === "boolean") {
db.$client
.prepare(
"INSERT OR REPLACE INTO settings (key, value) VALUES ('guac_enabled', ?)",
)
.run(enabled ? "true" : "false");
}
if (typeof url === "string") {
db.$client
.prepare(
"INSERT OR REPLACE INTO settings (key, value) VALUES ('guac_url', ?)",
)
.run(url);
try {
await restartGuacServer();
} catch (err) {
authLogger.error("Failed to restart guac server after URL update", err);
}
}
const enabledRow = db.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_enabled'")
.get() as { value: string } | undefined;
const urlRow = db.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_url'")
.get() as { value: string } | undefined;
res.json({
enabled: enabledRow ? enabledRow.value !== "false" : true,
url: urlRow ? urlRow.value : "guacd:4822",
});
} catch (err) {
authLogger.error("Failed to update guacamole settings", err);
res.status(500).json({ error: "Failed to update guacamole settings" });
}
});
export default router;
+153
View File
@@ -0,0 +1,153 @@
import GuacamoleLite from "guacamole-lite";
import { parse as parseUrl } from "url";
import { guacLogger } from "../utils/logger.js";
import { AuthManager } from "../utils/auth-manager.js";
import { GuacamoleTokenService } from "./token-service.js";
import { getDb } from "../database/db/index.js";
import type { IncomingMessage } from "http";
const authManager = AuthManager.getInstance();
const tokenService = GuacamoleTokenService.getInstance();
function parseGuacUrl(url: string): { host: string; port: number } {
const parts = url.split(":");
return {
host: parts[0] || "localhost",
port: parseInt(parts[1] || "4822", 10),
};
}
function readGuacdOptions(): { host: string; port: number } {
let host = process.env.GUACD_HOST || "localhost";
let port = parseInt(process.env.GUACD_PORT || "4822", 10);
try {
const db = getDb();
const urlRow = db.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_url'")
.get() as { value: string } | undefined;
if (urlRow?.value) {
const parsed = parseGuacUrl(urlRow.value);
host = parsed.host;
port = parsed.port;
}
} catch {
// DB not available yet, use env var defaults
}
return { host, port };
}
const GUAC_WS_PORT = 30008;
const websocketOptions = {
port: GUAC_WS_PORT,
};
const clientOptions = {
crypt: {
cypher: "AES-256-CBC",
key: tokenService.getEncryptionKey(),
},
log: {
level: "ERRORS",
stdLog: (...args: unknown[]) => {
guacLogger.info(args.join(" "));
},
errorLog: (...args: unknown[]) => {
guacLogger.error(args.join(" "));
},
},
allowedUnencryptedConnectionSettings: {
rdp: ["width", "height", "dpi"],
vnc: ["width", "height", "dpi"],
telnet: ["width", "height"],
},
connectionDefaultSettings: {
rdp: {
security: "any",
"ignore-cert": true,
"enable-wallpaper": false,
"enable-font-smoothing": true,
"enable-desktop-composition": false,
"disable-audio": false,
"enable-drive": false,
"resize-method": "display-update",
width: 1280,
height: 720,
dpi: 96,
},
vnc: {
"swap-red-blue": false,
cursor: "remote",
width: 1280,
height: 720,
},
telnet: {
"terminal-type": "xterm-256color",
},
},
};
const _origConsoleLog = console.log;
console.log = (...args: unknown[]) => {
const msg = args[0];
if (typeof msg === "string" && msg.startsWith("New client connection"))
return;
_origConsoleLog(...args);
};
function createGuacServer(): GuacamoleLite {
const guacdOptions = readGuacdOptions();
const server = new GuacamoleLite(
websocketOptions,
guacdOptions,
clientOptions,
);
server.on(
"open",
(clientConnection: { connectionSettings?: Record<string, unknown> }) => {
guacLogger.info("Guacamole connection opened", {
operation: "guac_connection_open",
type: clientConnection.connectionSettings?.type,
});
},
);
server.on(
"close",
(clientConnection: { connectionSettings?: Record<string, unknown> }) => {
guacLogger.info("Guacamole connection closed", {
operation: "guac_connection_close",
type: clientConnection.connectionSettings?.type,
});
},
);
server.on(
"error",
(
clientConnection: { connectionSettings?: Record<string, unknown> },
error: Error,
) => {
guacLogger.error("Guacamole connection error", error, {
operation: "guac_connection_error",
type: clientConnection.connectionSettings?.type,
});
},
);
return server;
}
let guacServer = createGuacServer();
export async function restartGuacServer(): Promise<void> {
try {
guacServer.close();
} catch (err) {
guacLogger.error("Error closing guac server during restart", err as Error);
}
guacServer = createGuacServer();
}
export { guacServer, tokenService };
+303
View File
@@ -0,0 +1,303 @@
import express from "express";
import { GuacamoleTokenService } from "./token-service.js";
import { guacLogger } from "../utils/logger.js";
import { AuthManager } from "../utils/auth-manager.js";
import { PermissionManager } from "../utils/permission-manager.js";
import { SimpleDBOps } from "../utils/simple-db-ops.js";
import { getDb } from "../database/db/index.js";
import { hosts } from "../database/db/schema.js";
import { eq, and } from "drizzle-orm";
import type { AuthenticatedRequest } from "../../types/index.js";
const router = express.Router();
const tokenService = GuacamoleTokenService.getInstance();
const authManager = AuthManager.getInstance();
router.use(authManager.createAuthMiddleware());
/**
* POST /guacamole/token
* Generate an encrypted connection token for guacamole-lite
*
* Body: {
* type: "rdp" | "vnc" | "telnet",
* hostname: string,
* port?: number,
* username?: string,
* password?: string,
* domain?: string,
* // Additional protocol-specific options
* }
*/
router.post("/token", async (req, res) => {
try {
const userId = (req as AuthenticatedRequest).userId;
const { type, hostname, port, username, password, domain, ...options } =
req.body;
if (!type || !hostname) {
return res
.status(400)
.json({ error: "Missing required fields: type and hostname" });
}
if (!["rdp", "vnc", "telnet"].includes(type)) {
return res.status(400).json({
error: "Invalid connection type. Must be rdp, vnc, or telnet",
});
}
let token: string;
switch (type) {
case "rdp":
token = tokenService.createRdpToken(
hostname,
username || "",
password || "",
{
port: port || 3389,
domain,
...options,
},
);
break;
case "vnc":
token = tokenService.createVncToken(hostname, password, {
port: port || 5900,
...options,
});
break;
case "telnet":
token = tokenService.createTelnetToken(hostname, username, password, {
port: port || 23,
...options,
});
break;
default:
return res.status(400).json({ error: "Invalid connection type" });
}
res.json({ token });
} catch (error) {
guacLogger.error("Failed to generate guacamole token", error, {
operation: "guac_token_error",
});
res.status(500).json({ error: "Failed to generate connection token" });
}
});
/**
* @openapi
* /guacamole/connect-host/{hostId}:
* post:
* summary: Generate Guacamole connection token from host configuration
* description: Fetches host configuration from database and generates a connection token for RDP/VNC/Telnet
* tags:
* - Guacamole
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: hostId
* required: true
* schema:
* type: integer
* description: Host ID to connect to
* responses:
* 200:
* description: Connection token generated successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* description: Encrypted connection token
* 400:
* description: Invalid request or unsupported connection type
* 403:
* description: Access denied to host
* 404:
* description: Host not found
* 500:
* description: Server error
*/
router.post(
"/connect-host/:hostId",
async (req: express.Request, res: express.Response) => {
try {
const userId = (req as AuthenticatedRequest).userId!;
const hostId = parseInt(req.params.hostId, 10);
if (!hostId || isNaN(hostId)) {
return res.status(400).json({ error: "Invalid host ID" });
}
const hostResults = await SimpleDBOps.select(
getDb().select().from(hosts).where(eq(hosts.id, hostId)),
"ssh_data",
userId,
);
if (hostResults.length === 0) {
return res.status(404).json({ error: "Host not found" });
}
const host = hostResults[0];
if (host.userId !== userId) {
const permissionManager = PermissionManager.getInstance();
const accessInfo = await permissionManager.canAccessHost(
userId,
hostId,
"read",
);
if (!accessInfo.hasAccess) {
guacLogger.warn("User attempted to access host without permission", {
operation: "guac_access_denied",
userId,
hostId,
});
return res.status(403).json({ error: "Access denied to this host" });
}
}
const connectionType = (host.connectionType as string) || "ssh";
if (!["rdp", "vnc", "telnet"].includes(connectionType)) {
return res.status(400).json({
error: `Connection type '${connectionType}' is not supported for remote desktop. Only RDP, VNC, and Telnet are supported.`,
});
}
let guacConfig: Record<string, unknown> = {};
if (host.guacamoleConfig) {
try {
guacConfig =
typeof host.guacamoleConfig === "string"
? JSON.parse(host.guacamoleConfig as string)
: (host.guacamoleConfig as Record<string, unknown>);
} catch (error) {
guacLogger.warn("Failed to parse guacamole config", {
operation: "guac_config_parse_error",
hostId,
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
let token: string;
const hostname = host.ip as string;
const port = host.port as number;
const username = (host.username as string) || "";
const password = (host.password as string) || "";
const domain = (host.domain as string) || "";
switch (connectionType) {
case "rdp":
token = tokenService.createRdpToken(hostname, username, password, {
port: port || 3389,
domain,
security: (host.security as string) || undefined,
"ignore-cert": (host.ignoreCert as boolean) || false,
...guacConfig,
});
break;
case "vnc":
token = tokenService.createVncToken(hostname, password, {
port: port || 5900,
...guacConfig,
});
break;
case "telnet":
token = tokenService.createTelnetToken(hostname, username, password, {
port: port || 23,
...guacConfig,
});
break;
default:
return res.status(400).json({ error: "Invalid connection type" });
}
res.json({ token });
} catch (error) {
guacLogger.error("Failed to generate guacamole token for host", error, {
operation: "guac_host_token_error",
});
res.status(500).json({ error: "Failed to generate connection token" });
}
},
);
/**
* GET /guacamole/status
* Check if guacd is reachable
*/
router.get("/status", async (req, res) => {
try {
let guacdHost = process.env.GUACD_HOST || "localhost";
let guacdPort = parseInt(process.env.GUACD_PORT || "4822", 10);
try {
const db = getDb();
const urlRow = db.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_url'")
.get() as { value: string } | undefined;
if (urlRow?.value) {
const parts = urlRow.value.split(":");
guacdHost = parts[0] || guacdHost;
guacdPort = parseInt(parts[1] || String(guacdPort), 10);
}
} catch {
// Fall back to env vars
}
const net = await import("net");
const checkConnection = (): Promise<boolean> => {
return new Promise((resolve) => {
const socket = new net.Socket();
socket.setTimeout(3000);
socket.on("connect", () => {
socket.destroy();
resolve(true);
});
socket.on("timeout", () => {
socket.destroy();
resolve(false);
});
socket.on("error", () => {
socket.destroy();
resolve(false);
});
socket.connect(guacdPort, guacdHost);
});
};
const isConnected = await checkConnection();
res.json({
guacd: {
host: guacdHost,
port: guacdPort,
status: isConnected ? "connected" : "disconnected",
},
websocket: {
port: 30008,
status: "running",
},
});
} catch (error) {
guacLogger.error("Failed to check guacamole status", error, {
operation: "guac_status_error",
});
res.status(500).json({ error: "Failed to check status" });
}
});
export default router;
+181
View File
@@ -0,0 +1,181 @@
import crypto from "crypto";
import { guacLogger } from "../utils/logger.js";
export interface GuacamoleConnectionSettings {
type: "rdp" | "vnc" | "telnet";
settings: {
hostname: string;
port?: number;
username?: string;
password?: string;
domain?: string;
width?: number;
height?: number;
dpi?: number;
security?: string;
"ignore-cert"?: boolean;
"enable-wallpaper"?: boolean;
"enable-drive"?: boolean;
"drive-path"?: string;
"create-drive-path"?: boolean;
"swap-red-blue"?: boolean;
cursor?: string;
"terminal-type"?: string;
[key: string]: unknown;
};
}
export interface GuacamoleToken {
connection: GuacamoleConnectionSettings;
}
const CIPHER = "aes-256-cbc";
const KEY_LENGTH = 32;
export class GuacamoleTokenService {
private static instance: GuacamoleTokenService;
private encryptionKey: Buffer;
private constructor() {
this.encryptionKey = this.initializeKey();
}
static getInstance(): GuacamoleTokenService {
if (!GuacamoleTokenService.instance) {
GuacamoleTokenService.instance = new GuacamoleTokenService();
}
return GuacamoleTokenService.instance;
}
private initializeKey(): Buffer {
const existingKey = process.env.GUACAMOLE_ENCRYPTION_KEY;
if (existingKey) {
if (existingKey.length === 64 && /^[0-9a-fA-F]+$/.test(existingKey)) {
return Buffer.from(existingKey, "hex");
}
if (existingKey.length === KEY_LENGTH) {
return Buffer.from(existingKey, "utf8");
}
}
const jwtSecret = process.env.JWT_SECRET;
if (jwtSecret) {
return crypto
.createHash("sha256")
.update(jwtSecret + "_guacamole")
.digest();
}
guacLogger.warn(
"No persistent encryption key found, generating random key",
{
operation: "guac_key_generation",
},
);
return crypto.randomBytes(KEY_LENGTH);
}
getEncryptionKey(): Buffer {
return this.encryptionKey;
}
encryptToken(tokenObject: GuacamoleToken): string {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(CIPHER, this.encryptionKey, iv);
let encrypted = cipher.update(
JSON.stringify(tokenObject),
"utf8",
"base64",
);
encrypted += cipher.final("base64");
const data = {
iv: iv.toString("base64"),
value: encrypted,
};
return Buffer.from(JSON.stringify(data)).toString("base64");
}
decryptToken(token: string): GuacamoleToken | null {
try {
const data = JSON.parse(Buffer.from(token, "base64").toString("utf8"));
const iv = Buffer.from(data.iv, "base64");
const decipher = crypto.createDecipheriv(CIPHER, this.encryptionKey, iv);
let decrypted = decipher.update(data.value, "base64", "utf8");
decrypted += decipher.final("utf8");
return JSON.parse(decrypted) as GuacamoleToken;
} catch (error) {
guacLogger.error("Failed to decrypt guacamole token", error, {
operation: "guac_token_decrypt_error",
});
return null;
}
}
createRdpToken(
hostname: string,
username: string,
password: string,
options: Partial<GuacamoleConnectionSettings["settings"]> = {},
): string {
const token: GuacamoleToken = {
connection: {
type: "rdp",
settings: {
hostname,
username,
password,
port: 3389,
security: "nla",
"ignore-cert": true,
...options,
},
},
};
return this.encryptToken(token);
}
createVncToken(
hostname: string,
password?: string,
options: Partial<GuacamoleConnectionSettings["settings"]> = {},
): string {
const token: GuacamoleToken = {
connection: {
type: "vnc",
settings: {
hostname,
password,
port: 5900,
...options,
},
},
};
return this.encryptToken(token);
}
createTelnetToken(
hostname: string,
username?: string,
password?: string,
options: Partial<GuacamoleConnectionSettings["settings"]> = {},
): string {
const token: GuacamoleToken = {
connection: {
type: "telnet",
settings: {
hostname,
username,
password,
port: 23,
...options,
},
},
};
return this.encryptToken(token);
}
}
+4 -4
View File
@@ -2,7 +2,7 @@ import { Client as SSHClient } from "ssh2";
import { WebSocketServer, WebSocket } from "ws";
import { parse as parseUrl } from "url";
import { AuthManager } from "../utils/auth-manager.js";
import { sshData, sshCredentials } from "../database/db/schema.js";
import { hosts, sshCredentials } from "../database/db/schema.js";
import { and, eq } from "drizzle-orm";
import { getDb } from "../database/db/index.js";
import { SimpleDBOps } from "../utils/simple-db-ops.js";
@@ -24,7 +24,7 @@ const activeSessions = new Map<string, SSHSession>();
const wss = new WebSocketServer({
host: "0.0.0.0",
port: 30008,
port: 30009,
verifyClient: async (info) => {
try {
const url = parseUrl(info.req.url || "", true);
@@ -107,8 +107,8 @@ async function createJumpHostChain(
const jumpHostData = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, jumpHostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, jumpHostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
+26 -28
View File
@@ -4,7 +4,7 @@ import cookieParser from "cookie-parser";
import axios from "axios";
import { Client as SSHClient } from "ssh2";
import { getDb } from "../database/db/index.js";
import { sshData, sshCredentials } from "../database/db/schema.js";
import { hosts, sshCredentials } from "../database/db/schema.js";
import { eq, and } from "drizzle-orm";
import { logger } from "../utils/logger.js";
import { SimpleDBOps } from "../utils/simple-db-ops.js";
@@ -136,20 +136,20 @@ async function resolveJumpHost(
userId: string,
): Promise<JumpHostConfig | null> {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
return null;
}
const host = hosts[0];
const host = hostResults[0];
if (host.credentialId) {
const credentials = await SimpleDBOps.select(
@@ -570,25 +570,24 @@ app.post("/docker/ssh/connect", async (req, res) => {
);
try {
const hosts = await SimpleDBOps.select(
getDb().select().from(sshData).where(eq(sshData.id, hostId)),
const hostResults = await SimpleDBOps.select(
getDb().select().from(hosts).where(eq(hosts.id, hostId)),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
connectionLogs.push(
createConnectionLog("error", "docker_connecting", "Host not found"),
);
return res.status(404).json({ error: "Host not found", connectionLogs });
}
const host = hosts[0] as unknown as SSHHost;
const host = hostResults[0] as unknown as SSHHost;
if (host.userId !== userId) {
const { PermissionManager } = await import(
"../utils/permission-manager.js"
);
const { PermissionManager } =
await import("../utils/permission-manager.js");
const permissionManager = PermissionManager.getInstance();
const accessInfo = await permissionManager.canAccessHost(
userId,
@@ -693,9 +692,8 @@ app.post("/docker/ssh/connect", async (req, res) => {
if (userId !== ownerId) {
try {
const { SharedCredentialManager } = await import(
"../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
const sharedCred = await sharedCredManager.getSharedCredentialForUser(
host.id,
@@ -1678,14 +1676,14 @@ app.post("/docker/ssh/connect-totp", async (req, res) => {
if (session.hostId && session.userId) {
(async () => {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.id, session.hostId!),
eq(sshData.userId, session.userId!),
eq(hosts.id, session.hostId!),
eq(hosts.userId, session.userId!),
),
),
"ssh_data",
@@ -1693,8 +1691,8 @@ app.post("/docker/ssh/connect-totp", async (req, res) => {
);
const hostName =
hosts.length > 0 && hosts[0].name
? hosts[0].name
hostResults.length > 0 && hostResults[0].name
? hostResults[0].name
: `${session.username}@${session.ip}:${session.port}`;
await axios.post(
@@ -1863,14 +1861,14 @@ app.post("/docker/ssh/connect-warpgate", async (req, res) => {
if (session.hostId && session.userId) {
(async () => {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.id, session.hostId!),
eq(sshData.userId, session.userId!),
eq(hosts.id, session.hostId!),
eq(hosts.userId, session.userId!),
),
),
"ssh_data",
@@ -1878,8 +1876,8 @@ app.post("/docker/ssh/connect-warpgate", async (req, res) => {
);
const hostName =
hosts.length > 0 && hosts[0].name
? hosts[0].name
hostResults.length > 0 && hostResults[0].name
? hostResults[0].name
: `${session.username}@${session.ip}:${session.port}`;
await axios.post(
+137 -64
View File
@@ -4,7 +4,7 @@ import cookieParser from "cookie-parser";
import axios from "axios";
import { Client as SSHClient } from "ssh2";
import { getDb } from "../database/db/index.js";
import { sshCredentials, sshData } from "../database/db/schema.js";
import { sshCredentials, hosts } from "../database/db/schema.js";
import { eq, and } from "drizzle-orm";
import { fileLogger } from "../utils/logger.js";
import { SimpleDBOps } from "../utils/simple-db-ops.js";
@@ -179,20 +179,20 @@ async function resolveJumpHost(
userId: string,
): Promise<JumpHostConfig | null> {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
return null;
}
const host = hosts[0];
const host = hostResults[0];
if (host.credentialId) {
const credentials = await SimpleDBOps.select(
@@ -803,64 +803,137 @@ app.post("/ssh/file_manager/ssh/connect", async (req, res) => {
let resolvedCredentials = { password, sshKey, keyPassword, authType };
if (credentialId && hostId && userId) {
try {
const credentials = await SimpleDBOps.select(
getDb()
.select()
.from(sshCredentials)
.where(
and(
eq(sshCredentials.id, credentialId),
eq(sshCredentials.userId, userId),
),
),
"ssh_credentials",
userId,
);
const hostRow = await getDb()
.select({ userId: hosts.userId })
.from(hosts)
.where(eq(hosts.id, hostId))
.limit(1);
const ownerId = hostRow[0]?.userId ?? null;
if (credentials.length > 0) {
const credential = credentials[0];
resolvedCredentials = {
password: credential.password,
sshKey: credential.privateKey,
keyPassword: credential.keyPassword,
authType: credential.authType,
};
if (ownerId && userId !== ownerId) {
try {
const { SharedCredentialManager } =
await import("../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
const sharedCred = await sharedCredManager.getSharedCredentialForUser(
hostId,
userId,
);
if (sharedCred) {
resolvedCredentials = {
password: sharedCred.password,
sshKey: sharedCred.key,
keyPassword: sharedCred.keyPassword,
authType: sharedCred.authType,
};
connectionLogs.push(
createConnectionLog(
"info",
"sftp_auth",
"Credentials resolved from shared credential store",
),
);
} else {
fileLogger.warn(`No shared credentials found for host ${hostId}`, {
operation: "ssh_credentials",
hostId,
userId,
});
connectionLogs.push(
createConnectionLog(
"warning",
"sftp_auth",
"No shared credentials found, using provided credentials",
),
);
}
} catch (error) {
fileLogger.warn(
`Failed to resolve shared credential for host ${hostId}`,
{
operation: "ssh_credentials",
hostId,
error: error instanceof Error ? error.message : "Unknown error",
},
);
connectionLogs.push(
createConnectionLog(
"info",
"warning",
"sftp_auth",
"Credentials resolved from credential store",
`Failed to resolve shared credentials: ${error instanceof Error ? error.message : "Unknown error"}`,
),
);
} else {
fileLogger.warn(`No credentials found for host ${hostId}`, {
}
} else if (ownerId) {
try {
const credentials = await SimpleDBOps.select(
getDb()
.select()
.from(sshCredentials)
.where(
and(
eq(sshCredentials.id, credentialId),
eq(sshCredentials.userId, ownerId),
),
),
"ssh_credentials",
ownerId,
);
if (credentials.length > 0) {
const credential = credentials[0];
resolvedCredentials = {
password: credential.password,
sshKey: credential.privateKey,
keyPassword: credential.keyPassword,
authType: credential.authType,
};
connectionLogs.push(
createConnectionLog(
"info",
"sftp_auth",
"Credentials resolved from credential store",
),
);
} else {
fileLogger.warn(`No credentials found for host ${hostId}`, {
operation: "ssh_credentials",
hostId,
credentialId,
userId: ownerId,
});
connectionLogs.push(
createConnectionLog(
"warning",
"sftp_auth",
"No stored credentials found, using provided credentials",
),
);
}
} catch (error) {
fileLogger.warn(`Failed to resolve credentials for host ${hostId}`, {
operation: "ssh_credentials",
hostId,
credentialId,
userId,
error: error instanceof Error ? error.message : "Unknown error",
});
connectionLogs.push(
createConnectionLog(
"warning",
"sftp_auth",
"No stored credentials found, using provided credentials",
`Failed to resolve credentials: ${error instanceof Error ? error.message : "Unknown error"}`,
),
);
}
} catch (error) {
fileLogger.warn(`Failed to resolve credentials for host ${hostId}`, {
operation: "ssh_credentials",
hostId,
credentialId,
error: error instanceof Error ? error.message : "Unknown error",
});
connectionLogs.push(
createConnectionLog(
"warning",
"sftp_auth",
`Failed to resolve credentials: ${error instanceof Error ? error.message : "Unknown error"}`,
),
} else {
fileLogger.warn(
"Missing userId for credential resolution in file manager",
{
operation: "ssh_credentials",
hostId,
credentialId,
},
);
}
} else if (credentialId && hostId) {
@@ -1201,18 +1274,18 @@ app.post("/ssh/file_manager/ssh/connect", async (req, res) => {
if (hostId && userId) {
(async () => {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
const hostName =
hosts.length > 0 && hosts[0].name
? hosts[0].name
hostResults.length > 0 && hostResults[0].name
? hostResults[0].name
: `${username}@${ip}:${port}`;
const authManager = AuthManager.getInstance();
@@ -1844,14 +1917,14 @@ app.post("/ssh/file_manager/ssh/connect-totp", async (req, res) => {
if (session.hostId && session.userId) {
(async () => {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.id, session.hostId!),
eq(sshData.userId, session.userId!),
eq(hosts.id, session.hostId!),
eq(hosts.userId, session.userId!),
),
),
"ssh_data",
@@ -1859,8 +1932,8 @@ app.post("/ssh/file_manager/ssh/connect-totp", async (req, res) => {
);
const hostName =
hosts.length > 0 && hosts[0].name
? hosts[0].name
hostResults.length > 0 && hostResults[0].name
? hostResults[0].name
: `${session.username}@${session.ip}:${session.port}`;
const authManager = AuthManager.getInstance();
@@ -2045,14 +2118,14 @@ app.post("/ssh/file_manager/ssh/connect-warpgate", async (req, res) => {
if (session.hostId && session.userId) {
(async () => {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.id, session.hostId!),
eq(sshData.userId, session.userId!),
eq(hosts.id, session.hostId!),
eq(hosts.userId, session.userId!),
),
),
"ssh_data",
@@ -2060,8 +2133,8 @@ app.post("/ssh/file_manager/ssh/connect-warpgate", async (req, res) => {
);
const hostName =
hosts.length > 0 && hosts[0].name
? hosts[0].name
hostResults.length > 0 && hostResults[0].name
? hostResults[0].name
: `${session.username}@${session.ip}:${session.port}`;
await axios.post(
+9 -20
View File
@@ -1,6 +1,6 @@
import type { WebSocket } from "ws";
import { db } from "../database/db/index.js";
import { sshData } from "../database/db/schema.js";
import { hosts } from "../database/db/schema.js";
import { eq } from "drizzle-orm";
import { sshLogger } from "../utils/logger.js";
@@ -21,17 +21,6 @@ interface VerificationResponse {
}
export class SSHHostKeyVerifier {
/**
* Creates a hostVerifier callback for ssh2 Client.connect()
*
* @param hostId - Database ID of the host (null for quick connect)
* @param ip - IP address or hostname
* @param port - SSH port
* @param ws - WebSocket for user prompts (null for non-interactive connections)
* @param userId - User ID for logging
* @param isJumpHost - If true, auto-accepts without prompting
* @returns async hostVerifier callback
*/
static async createHostVerifier(
hostId: number | null,
ip: string,
@@ -63,8 +52,8 @@ export class SSHHostKeyVerifier {
return;
}
const host = await db.query.sshData.findFirst({
where: eq(sshData.id, hostId),
const host = await db.query.hosts.findFirst({
where: eq(hosts.id, hostId),
});
if (!host) {
@@ -153,11 +142,11 @@ export class SSHHostKeyVerifier {
if (host.hostKeyFingerprint === fingerprint) {
await db
.update(sshData)
.update(hosts)
.set({
hostKeyLastVerified: new Date().toISOString(),
})
.where(eq(sshData.id, hostId));
.where(eq(hosts.id, hostId));
sshLogger.info("Host key verified successfully", {
operation: "host_key_verified",
@@ -287,7 +276,7 @@ export class SSHHostKeyVerifier {
algorithm: string,
): Promise<void> {
await db
.update(sshData)
.update(hosts)
.set({
hostKeyFingerprint: fingerprint,
hostKeyType: keyType,
@@ -295,7 +284,7 @@ export class SSHHostKeyVerifier {
hostKeyFirstSeen: new Date().toISOString(),
hostKeyLastVerified: new Date().toISOString(),
})
.where(eq(sshData.id, hostId));
.where(eq(hosts.id, hostId));
}
private static async updateHostKey(
@@ -306,7 +295,7 @@ export class SSHHostKeyVerifier {
currentChangeCount: number,
): Promise<void> {
await db
.update(sshData)
.update(hosts)
.set({
hostKeyFingerprint: fingerprint,
hostKeyType: keyType,
@@ -314,7 +303,7 @@ export class SSHHostKeyVerifier {
hostKeyLastVerified: new Date().toISOString(),
hostKeyChangedCount: currentChangeCount + 1,
})
.where(eq(sshData.id, hostId));
.where(eq(hosts.id, hostId));
}
private static async promptUserForNewKey(
+4 -40
View File
@@ -12,6 +12,7 @@ import { FieldCrypto } from "../utils/field-crypto.js";
import { promises as fs } from "fs";
import path from "path";
import axios from "axios";
import { getRequestOrigin } from "../utils/request-origin.js";
const AUTH_TIMEOUT = 60 * 1000;
@@ -48,43 +49,6 @@ interface OPKSSHAuthSession {
const activeAuthSessions = new Map<string, OPKSSHAuthSession>();
const cleanupInProgress = new Set<string>();
export function getRequestOrigin(req: IncomingMessage): string {
const protoHeader =
req.headers["x-forwarded-proto"] ||
((req.socket as unknown as { encrypted?: boolean }).encrypted
? "https"
: "http");
const proto =
typeof protoHeader === "string"
? protoHeader.split(",")[0].trim()
: String(protoHeader);
const portHeader = req.headers["x-forwarded-port"];
const port =
typeof portHeader === "string"
? portHeader.split(",")[0].trim()
: undefined;
const hostHeaderRaw =
req.headers["x-forwarded-host"] || req.headers.host || "localhost";
const hostHeader =
typeof hostHeaderRaw === "string"
? hostHeaderRaw.split(",")[0].trim()
: String(hostHeaderRaw);
if (port) {
const hostWithoutPort = hostHeader.split(":")[0];
const isDefaultPort =
(proto === "http" && port === "80") ||
(proto === "https" && port === "443");
return isDefaultPort
? `${proto}://${hostWithoutPort}`
: `${proto}://${hostWithoutPort}:${port}`;
}
return `${proto}://${hostHeader}`;
}
function getOPKConfigPath(): string {
const dataDir =
process.env.DATA_DIR || path.join(process.cwd(), "db", "data");
@@ -159,7 +123,7 @@ async function checkOPKConfigExists(): Promise<{
return {
exists: false,
configPath,
error: `OPKSSH configuration is missing 'redirect_uris' field. This field must contain the Termix callback URL that you registered with your OAuth provider (e.g., http://localhost:8080/ssh/opkssh-callback for Docker). The static callback route will internally redirect to the dynamic route for proper URL rewriting.`,
error: `OPKSSH configuration is missing 'redirect_uris' field. This field must contain the Termix callback URL that you registered with your OAuth provider (e.g., http://localhost:8080/host/opkssh-callback for Docker). The static callback route will internally redirect to the dynamic route for proper URL rewriting.`,
};
}
@@ -215,7 +179,7 @@ export async function startOPKSSHAuth(
}
const requestId = randomUUID();
const remoteRedirectUri = `${requestOrigin}/ssh/opkssh-callback`;
const remoteRedirectUri = `${requestOrigin}/host/opkssh-callback`;
const session: Partial<OPKSSHAuthSession> = {
requestId,
@@ -388,7 +352,7 @@ function handleOPKSSHOutput(requestId: string, output: string): void {
/\/ssh\/opkssh-callback$/,
"",
);
const proxiedChooserUrl = `${baseUrl}/ssh/opkssh-chooser/${requestId}`;
const proxiedChooserUrl = `${baseUrl}/host/opkssh-chooser/${requestId}`;
session.status = "waiting_for_auth";
session.ws.send(
+94 -26
View File
@@ -4,7 +4,7 @@ import cors from "cors";
import cookieParser from "cookie-parser";
import { Client, type ConnectConfig } from "ssh2";
import { getDb } from "../database/db/index.js";
import { sshData, sshCredentials } from "../database/db/schema.js";
import { hosts, sshCredentials } from "../database/db/schema.js";
import { eq, and } from "drizzle-orm";
import { statsLogger } from "../utils/logger.js";
import { SimpleDBOps } from "../utils/simple-db-ops.js";
@@ -29,6 +29,15 @@ import {
import { SSHHostKeyVerifier } from "./host-key-verifier.js";
import { connectionPool, withConnection } from "./ssh-connection-pool.js";
function supportsMetrics(host: SSHHostWithCredentials): boolean {
const connectionType = host.connectionType || "ssh";
return connectionType === "ssh";
}
function isTcpPingEnabled(statsConfig: StatsConfig): boolean {
return statsConfig.statusCheckEnabled && !statsConfig.disableTcpPing;
}
function createConnectionLog(
type: "info" | "success" | "warning" | "error",
stage: ConnectionStage,
@@ -62,20 +71,20 @@ async function resolveJumpHost(
userId: string,
): Promise<JumpHostConfig | null> {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
return null;
}
const host = hosts[0];
const host = hostResults[0];
if (host.credentialId) {
const credentials = await SimpleDBOps.select(
@@ -644,6 +653,7 @@ interface SSHHostWithCredentials {
socks5Username?: string;
socks5Password?: string;
socks5ProxyChain?: ProxyNode[];
connectionType?: "ssh" | "rdp" | "vnc" | "telnet";
}
type StatusEntry = {
@@ -659,6 +669,7 @@ interface StatsConfig {
metricsEnabled: boolean;
metricsInterval: number;
useGlobalMetricsInterval?: boolean;
disableTcpPing?: boolean;
}
const DEFAULT_STATS_CONFIG: StatsConfig = {
@@ -783,9 +794,13 @@ class PollingManager {
const statusOnly = options?.statusOnly ?? false;
const viewerUserId = options?.viewerUserId;
const canCollectMetrics = supportsMetrics(host);
const enabledCollectors: string[] = [];
if (statsConfig.statusCheckEnabled) enabledCollectors.push("status");
if (!statusOnly && statsConfig.metricsEnabled) {
if (isTcpPingEnabled(statsConfig)) {
enabledCollectors.push("status");
}
if (!statusOnly && statsConfig.metricsEnabled && canCollectMetrics) {
enabledCollectors.push(
"cpu",
"memory",
@@ -810,7 +825,7 @@ class PollingManager {
}
}
if (!statsConfig.statusCheckEnabled && !statsConfig.metricsEnabled) {
if (!isTcpPingEnabled(statsConfig) && !statsConfig.metricsEnabled) {
this.pollingConfigs.delete(host.id);
this.statusStore.delete(host.id);
this.metricsStore.delete(host.id);
@@ -823,14 +838,14 @@ class PollingManager {
viewerUserId,
};
if (statsConfig.statusCheckEnabled) {
if (isTcpPingEnabled(statsConfig)) {
const intervalMs = statsConfig.statusCheckInterval * 1000;
this.pollHostStatus(host, viewerUserId);
config.statusTimer = setInterval(() => {
const latestConfig = this.pollingConfigs.get(host.id);
if (latestConfig && latestConfig.statsConfig.statusCheckEnabled) {
if (latestConfig && isTcpPingEnabled(latestConfig.statsConfig)) {
this.pollHostStatus(latestConfig.host, latestConfig.viewerUserId);
}
}, intervalMs);
@@ -838,14 +853,18 @@ class PollingManager {
this.statusStore.delete(host.id);
}
if (!statusOnly && statsConfig.metricsEnabled) {
if (!statusOnly && statsConfig.metricsEnabled && canCollectMetrics) {
const intervalMs = statsConfig.metricsInterval * 1000;
await this.pollHostMetrics(host, viewerUserId);
config.metricsTimer = setInterval(() => {
const latestConfig = this.pollingConfigs.get(host.id);
if (latestConfig && latestConfig.statsConfig.metricsEnabled) {
if (
latestConfig &&
latestConfig.statsConfig.metricsEnabled &&
supportsMetrics(latestConfig.host)
) {
this.pollHostMetrics(latestConfig.host, latestConfig.viewerUserId);
}
}, intervalMs);
@@ -896,6 +915,15 @@ class PollingManager {
return;
}
if (!supportsMetrics(refreshedHost)) {
statsLogger.debug("Skipping metrics collection for non-SSH host", {
operation: "poll_host_metrics_skipped",
hostId: refreshedHost.id,
connectionType: refreshedHost.connectionType || "ssh",
});
return;
}
const config = this.pollingConfigs.get(refreshedHost.id);
if (!config || !config.statsConfig.metricsEnabled) {
return;
@@ -1001,6 +1029,34 @@ class PollingManager {
}
}
async refreshAllPolling(): Promise<void> {
const hostsToRefresh: Array<{
host: SSHHostWithCredentials;
viewerUserId?: string;
}> = [];
for (const [hostId, config] of this.pollingConfigs.entries()) {
const status = this.statusStore.get(hostId);
if (!status || status.status === "online") {
hostsToRefresh.push({
host: config.host,
viewerUserId: config.viewerUserId,
});
}
}
for (const hostId of this.pollingConfigs.keys()) {
this.stopPollingForHost(hostId, false);
}
for (const { host, viewerUserId } of hostsToRefresh) {
await this.startPollingForHost(host, { statusOnly: true, viewerUserId });
}
const skipped = this.pollingConfigs.size - hostsToRefresh.length;
}
registerViewer(hostId: number, sessionId: string, userId: string): void {
if (!this.activeViewers.has(hostId)) {
this.activeViewers.set(hostId, new Set());
@@ -1142,14 +1198,14 @@ async function fetchAllHosts(
userId: string,
): Promise<SSHHostWithCredentials[]> {
try {
const hosts = await SimpleDBOps.select(
getDb().select().from(sshData).where(eq(sshData.userId, userId)),
const hostResults = await SimpleDBOps.select(
getDb().select().from(hosts).where(eq(hosts.userId, userId)),
"ssh_data",
userId,
);
const hostsWithCredentials: SSHHostWithCredentials[] = [];
for (const host of hosts) {
for (const host of hostResults) {
try {
const hostWithCreds = await resolveHostCredentials(host, userId);
if (hostWithCreds) {
@@ -1193,17 +1249,17 @@ async function fetchHostById(
return undefined;
}
const hosts = await SimpleDBOps.select(
getDb().select().from(sshData).where(eq(sshData.id, id)),
const hostResults = await SimpleDBOps.select(
getDb().select().from(hosts).where(eq(hosts.id, id)),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
return undefined;
}
const host = hosts[0];
const host = hostResults[0];
return await resolveHostCredentials(host, userId);
} catch (err) {
statsLogger.error(`Failed to fetch host ${id}`, err);
@@ -1259,9 +1315,8 @@ async function resolveHostCredentials(
const isSharedHost = userId !== ownerId;
if (isSharedHost) {
const { SharedCredentialManager } = await import(
"../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
const sharedCred = await sharedCredManager.getSharedCredentialForUser(
host.id as number,
@@ -1730,6 +1785,10 @@ async function collectMetrics(host: SSHHostWithCredentials): Promise<{
os: string | null;
};
}> {
if (!supportsMetrics(host)) {
throw new Error("Metrics collection only supported for SSH hosts");
}
if (authFailureTracker.shouldSkip(host.id)) {
const reason = authFailureTracker.getSkipReason(host.id);
throw new Error(reason || "Authentication failed");
@@ -1908,7 +1967,8 @@ function tcpPing(
socket.once("data", (data) => {
clearTimeout(dataTimeout);
if (data.toString().startsWith("SSH-")) {
const dataStr = data.toString("utf8");
if (dataStr.startsWith("SSH-")) {
try {
socket.end("SSH-2.0-TermixHealthCheck\r\n");
} catch {
@@ -3185,13 +3245,21 @@ app.post("/global-settings", requireAdmin, async (req, res) => {
.run(String(metricsInterval));
}
res.json({ success: true });
await pollingManager.refreshAllPolling();
res.json({
success: true,
message: "Settings updated and polling refreshed",
});
} catch (error) {
statsLogger.error("Failed to save global settings", {
operation: "global_settings_save_error",
error: error instanceof Error ? error.message : String(error),
});
res.status(500).json({ error: "Failed to save global settings" });
res.status(500).json({
error: "Failed to save global settings",
details: error instanceof Error ? error.message : String(error),
});
}
});
+96 -55
View File
@@ -3,7 +3,7 @@ import { Client, type ClientChannel, type PseudoTtyOptions } from "ssh2";
import { parse as parseUrl } from "url";
import axios from "axios";
import { getDb } from "../database/db/index.js";
import { sshCredentials, sshData } from "../database/db/schema.js";
import { sshCredentials, hosts } from "../database/db/schema.js";
import { eq, and } from "drizzle-orm";
import { sshLogger, authLogger } from "../utils/logger.js";
import { SimpleDBOps } from "../utils/simple-db-ops.js";
@@ -97,20 +97,20 @@ async function resolveJumpHost(
hostId,
});
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId))),
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId))),
"ssh_data",
userId,
);
if (hosts.length === 0) {
if (hostResults.length === 0) {
return null;
}
const host = hosts[0];
const host = hostResults[0];
if (host.credentialId) {
const credentials = await SimpleDBOps.select(
@@ -808,14 +808,14 @@ wss.on("connection", async (ws: WebSocket, req) => {
case "opkssh_start_auth": {
const opksshData = data as { hostId: number };
try {
const { startOPKSSHAuth, getRequestOrigin } = await import(
"./opkssh-auth.js"
);
const { startOPKSSHAuth } = await import("./opkssh-auth.js");
const { getRequestOrigin } =
await import("../utils/request-origin.js");
const db = getDb();
const hostRow = await db
.select()
.from(sshData)
.where(eq(sshData.id, opksshData.hostId))
.from(hosts)
.where(eq(hosts.id, opksshData.hostId))
.limit(1);
if (!hostRow || hostRow.length === 0) {
sshLogger.error(
@@ -1057,55 +1057,96 @@ wss.on("connection", async (ws: WebSocket, req) => {
authType,
};
const authMethodNotAvailable = false;
if (credentialId && id && hostConfig.userId) {
try {
const credentials = await SimpleDBOps.select(
getDb()
.select()
.from(sshCredentials)
.where(
and(
eq(sshCredentials.id, credentialId),
eq(sshCredentials.userId, hostConfig.userId),
),
),
"ssh_credentials",
hostConfig.userId,
);
if (credentialId && id) {
const hostRow = await getDb()
.select({ userId: hosts.userId })
.from(hosts)
.where(eq(hosts.id, id))
.limit(1);
const ownerId = hostRow[0]?.userId ?? null;
if (credentials.length > 0) {
const credential = credentials[0];
resolvedCredentials = {
username: (credential.username as string | undefined) || username,
password: credential.password as string | undefined,
key: credential.privateKey as string | undefined,
keyPassword: credential.keyPassword as string | undefined,
keyType: credential.keyType as string | undefined,
authType: credential.authType as string | undefined,
};
} else {
sshLogger.warn(`No credentials found for host ${id}`, {
if (ownerId && userId !== ownerId) {
try {
const { SharedCredentialManager } =
await import("../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
const sharedCred = await sharedCredManager.getSharedCredentialForUser(
id,
userId,
);
if (sharedCred) {
resolvedCredentials = {
username: sharedCred.username || username,
password: sharedCred.password,
key: sharedCred.key,
keyPassword: sharedCred.keyPassword,
keyType: sharedCred.keyType,
authType: sharedCred.authType,
};
} else {
sshLogger.warn(`No shared credentials found for host ${id}`, {
operation: "ssh_credentials",
userId,
hostId: id,
});
}
} catch (error) {
sshLogger.warn(`Failed to resolve shared credential for host ${id}`, {
operation: "ssh_credentials",
hostId: id,
error: error instanceof Error ? error.message : "Unknown error",
});
}
} else if (ownerId) {
try {
const credentials = await SimpleDBOps.select(
getDb()
.select()
.from(sshCredentials)
.where(
and(
eq(sshCredentials.id, credentialId),
eq(sshCredentials.userId, ownerId),
),
),
"ssh_credentials",
ownerId,
);
if (credentials.length > 0) {
const credential = credentials[0];
resolvedCredentials = {
username: (credential.username as string | undefined) || username,
password: credential.password as string | undefined,
key: credential.privateKey as string | undefined,
keyPassword: credential.keyPassword as string | undefined,
keyType: credential.keyType as string | undefined,
authType: credential.authType as string | undefined,
};
} else {
sshLogger.warn(`No credentials found for host ${id}`, {
operation: "ssh_credentials",
hostId: id,
credentialId,
userId: ownerId,
});
}
} catch (error) {
sshLogger.warn(`Failed to resolve credentials for host ${id}`, {
operation: "ssh_credentials",
hostId: id,
credentialId,
userId: hostConfig.userId,
error: error instanceof Error ? error.message : "Unknown error",
});
}
} catch (error) {
sshLogger.warn(`Failed to resolve credentials for host ${id}`, {
} else {
sshLogger.warn("Missing userId for credential resolution in terminal", {
operation: "ssh_credentials",
hostId: id,
credentialId,
error: error instanceof Error ? error.message : "Unknown error",
});
}
} else if (credentialId && id) {
sshLogger.warn("Missing userId for credential resolution in terminal", {
operation: "ssh_credentials",
hostId: id,
credentialId,
hasUserId: !!hostConfig.userId,
});
}
sshConn.on("ready", () => {
@@ -1400,14 +1441,14 @@ wss.on("connection", async (ws: WebSocket, req) => {
if (id && hostConfig.userId) {
(async () => {
try {
const hosts = await SimpleDBOps.select(
const hostResults = await SimpleDBOps.select(
getDb()
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.id, id),
eq(sshData.userId, hostConfig.userId!),
eq(hosts.id, id),
eq(hosts.userId, hostConfig.userId!),
),
),
"ssh_data",
@@ -1415,8 +1456,8 @@ wss.on("connection", async (ws: WebSocket, req) => {
);
const hostName =
hosts.length > 0 && hosts[0].name
? hosts[0].name
hostResults.length > 0 && hostResults[0].name
? hostResults[0].name
: `${username}@${ip}:${port}`;
await axios.post(
+5 -7
View File
@@ -608,9 +608,8 @@ async function connectSSHTunnel(
tunnelConfig.requestingUserId &&
tunnelConfig.requestingUserId !== tunnelConfig.sourceUserId
) {
const { SharedCredentialManager } = await import(
"../utils/shared-credential-manager.js"
);
const { SharedCredentialManager } =
await import("../utils/shared-credential-manager.js");
const sharedCredManager = SharedCredentialManager.getInstance();
if (tunnelConfig.sourceHostId) {
@@ -1750,7 +1749,7 @@ app.post(
const internalAuthToken = await systemCrypto.getInternalAuthToken();
const allHostsResponse = await axios.get(
"http://localhost:30001/ssh/db/host/internal/all",
"http://localhost:30001/host/db/host/internal/all",
{
headers: {
"Content-Type": "application/json",
@@ -2028,7 +2027,7 @@ async function initializeAutoStartTunnels(): Promise<void> {
const internalAuthToken = await systemCrypto.getInternalAuthToken();
const autostartResponse = await axios.get(
"http://localhost:30001/ssh/db/host/internal",
"http://localhost:30001/host/db/host/internal",
{
headers: {
"Content-Type": "application/json",
@@ -2038,7 +2037,7 @@ async function initializeAutoStartTunnels(): Promise<void> {
);
const allHostsResponse = await axios.get(
"http://localhost:30001/ssh/db/host/internal/all",
"http://localhost:30001/host/db/host/internal/all",
{
headers: {
"Content-Type": "application/json",
@@ -2050,7 +2049,6 @@ async function initializeAutoStartTunnels(): Promise<void> {
const autostartHosts: SSHHost[] = autostartResponse.data || [];
const allHosts: SSHHost[] = allHostsResponse.data || [];
const autoStartTunnels: TunnelConfig[] = [];
tunnelLogger.info(
`Found ${autostartHosts.length} autostart hosts and ${allHosts.length} total hosts for endpointHost resolution`,
);
+29 -3
View File
@@ -112,9 +112,8 @@ import { systemLogger, versionLogger } from "./utils/logger.js";
await authManager.initialize();
DataCrypto.initialize();
const { OPKSSHBinaryManager } = await import(
"./utils/opkssh-binary-manager.js"
);
const { OPKSSHBinaryManager } =
await import("./utils/opkssh-binary-manager.js");
try {
await OPKSSHBinaryManager.ensureBinary();
} catch (error) {
@@ -143,6 +142,33 @@ import { systemLogger, versionLogger } from "./utils/logger.js";
await import("./ssh/docker-console.js");
await import("./dashboard.js");
// Initialize Guacamole server for RDP/VNC/Telnet support
const { getDb: getDbForGuac } = await import("./database/db/index.js");
const guacDb = getDbForGuac();
const guacEnabledRow = guacDb.$client
.prepare("SELECT value FROM settings WHERE key = 'guac_enabled'")
.get() as { value: string } | undefined;
const guacEnabled = guacEnabledRow
? guacEnabledRow.value !== "false"
: true;
if (process.env.ENABLE_GUACAMOLE !== "false" && guacEnabled) {
try {
await import("./guacamole/guacamole-server.js");
systemLogger.info("Guacamole server initialized", {
operation: "guac_init",
});
} catch (error) {
systemLogger.warn(
"Failed to initialize Guacamole server (guacd may not be available)",
{
operation: "guac_init_skip",
error: error instanceof Error ? error.message : "Unknown error",
},
);
}
}
systemLogger.success("Termix backend started successfully", {
operation: "backend_init_complete",
port: process.env.PORT || 4090,
+23 -40
View File
@@ -99,7 +99,7 @@ class AuthManager {
const sessionDurationMs =
deviceType === "desktop" || deviceType === "mobile"
? 30 * 24 * 60 * 60 * 1000
: 2 * 60 * 60 * 1000;
: 24 * 60 * 60 * 1000;
const authenticated = await this.userCrypto.authenticateOIDCUser(
userId,
@@ -121,7 +121,7 @@ class AuthManager {
const sessionDurationMs =
deviceType === "desktop" || deviceType === "mobile"
? 30 * 24 * 60 * 60 * 1000
: 2 * 60 * 60 * 1000;
: 24 * 60 * 60 * 1000;
const authenticated = await this.userCrypto.authenticateUser(
userId,
@@ -154,9 +154,8 @@ class AuthManager {
return;
}
const { getSqlite, saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { getSqlite, saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
const sqlite = getSqlite();
@@ -171,9 +170,8 @@ class AuthManager {
}
try {
const { CredentialSystemEncryptionMigration } = await import(
"./credential-system-encryption-migration.js"
);
const { CredentialSystemEncryptionMigration } =
await import("./credential-system-encryption-migration.js");
const credMigration = new CredentialSystemEncryptionMigration();
const credResult = await credMigration.migrateUserCredentials(userId);
@@ -213,10 +211,10 @@ class AuthManager {
if (options.rememberMe) {
expiresIn = "30d";
} else {
expiresIn = "2h";
expiresIn = "24h";
}
} else if (!expiresIn) {
expiresIn = "2h";
expiresIn = "24h";
}
const payload: JWTPayload = { userId };
@@ -250,9 +248,8 @@ class AuthManager {
});
try {
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
} catch (saveError) {
databaseLogger.error(
@@ -280,7 +277,7 @@ class AuthManager {
private parseExpiresIn(expiresIn: string): number {
const match = expiresIn.match(/^(\d+)([smhd])$/);
if (!match) return 2 * 60 * 60 * 1000;
if (!match) return 24 * 60 * 60 * 1000;
const value = parseInt(match[1]);
const unit = match[2];
@@ -295,7 +292,7 @@ class AuthManager {
case "d":
return value * 24 * 60 * 60 * 1000;
default:
return 2 * 60 * 60 * 1000;
return 24 * 60 * 60 * 1000;
}
}
@@ -364,9 +361,8 @@ class AuthManager {
await db.delete(sessions).where(eq(sessions.id, sessionId));
try {
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
} catch (saveError) {
databaseLogger.error(
@@ -423,9 +419,8 @@ class AuthManager {
}
try {
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
} catch (saveError) {
databaseLogger.error(
@@ -466,9 +461,8 @@ class AuthManager {
.where(sql`${sessions.expiresAt} < datetime('now')`);
try {
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
} catch (saveError) {
databaseLogger.error(
@@ -531,7 +525,7 @@ class AuthManager {
getSecureCookieOptions(
req: RequestWithHeaders,
maxAge: number = 2 * 60 * 60 * 1000,
maxAge: number = 24 * 60 * 60 * 1000,
) {
return {
httpOnly: false,
@@ -613,9 +607,8 @@ class AuthManager {
.where(eq(sessions.id, payload.sessionId))
.then(async () => {
try {
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
const remainingSessions = await db
@@ -759,9 +752,8 @@ class AuthManager {
await db.delete(sessions).where(eq(sessions.id, sessionId));
try {
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
} catch (saveError) {
databaseLogger.error(
@@ -827,9 +819,6 @@ class AuthManager {
);
}
/**
* Check if device is trusted for TOTP bypass
*/
async isTrustedDevice(
userId: string,
deviceFingerprint: string,
@@ -875,9 +864,6 @@ class AuthManager {
}
}
/**
* Add device to trusted list for TOTP bypass
*/
async addTrustedDevice(
userId: string,
deviceFingerprint: string,
@@ -925,9 +911,6 @@ class AuthManager {
}
}
/**
* Remove trusted device
*/
async removeTrustedDevice(
userId: string,
deviceFingerprint: string,
+1
View File
@@ -254,5 +254,6 @@ export const authLogger = new Logger("AUTH", "🔐", "#ef4444");
export const systemLogger = new Logger("SYSTEM", "🚀", "#14b8a6");
export const versionLogger = new Logger("VERSION", "📦", "#8b5cf6");
export const dashboardLogger = new Logger("DASHBOARD", "📊", "#ec4899");
export const guacLogger = new Logger("GUACAMOLE", "🖼️", "#ff6b6b");
export const logger = systemLogger;
+6 -6
View File
@@ -4,7 +4,7 @@ import {
hostAccess,
roles,
userRoles,
sshData,
hosts,
users,
} from "../database/db/schema.js";
import { eq, and, or, isNull, gte, sql } from "drizzle-orm";
@@ -167,8 +167,8 @@ class PermissionManager {
try {
const host = await db
.select()
.from(sshData)
.where(and(eq(sshData.id, hostId), eq(sshData.userId, userId)))
.from(hosts)
.where(and(eq(hosts.id, hostId), eq(hosts.userId, userId)))
.limit(1);
if (host.length > 0) {
@@ -210,9 +210,9 @@ class PermissionManager {
const access = sharedAccess[0];
const hostOwnerCheck = await db
.select({ ownerId: sshData.userId })
.from(sshData)
.where(eq(sshData.id, hostId))
.select({ ownerId: hosts.userId })
.from(hosts)
.where(eq(hosts.id, hostId))
.limit(1);
if (hostOwnerCheck.length > 0 && hostOwnerCheck[0].ownerId === userId) {
+63
View File
@@ -0,0 +1,63 @@
import type { Request } from "express";
import type { IncomingMessage } from "http";
export function getRequestOrigin(req: Request | IncomingMessage): string {
let protocol: string;
const protoHeader = req.headers["x-forwarded-proto"];
if (protoHeader) {
protocol =
typeof protoHeader === "string"
? protoHeader.split(",")[0].trim()
: protoHeader[0];
} else if ("protocol" in req && req.protocol) {
protocol = req.protocol;
} else {
protocol = (req.socket as unknown as { encrypted?: boolean }).encrypted
? "https"
: "http";
}
const portHeader = req.headers["x-forwarded-port"];
let port: string | undefined =
typeof portHeader === "string"
? portHeader.split(",")[0].trim()
: undefined;
const hostHeaderRaw =
req.headers["x-forwarded-host"] || req.headers.host || "localhost";
const hostHeader =
typeof hostHeaderRaw === "string"
? hostHeaderRaw.split(",")[0].trim()
: String(hostHeaderRaw);
if (!port && hostHeader.includes(":")) {
const parts = hostHeader.split(":");
if (parts.length === 2 && !parts[0].includes("[")) {
port = parts[1];
}
}
const hostWithoutPort = hostHeader.split(":")[0];
if (port) {
const isDefaultPort =
(protocol === "http" && port === "80") ||
(protocol === "https" && port === "443");
return isDefaultPort
? `${protocol}://${hostWithoutPort}`
: `${protocol}://${hostWithoutPort}:${port}`;
}
return `${protocol}://${hostWithoutPort}`;
}
export function getRequestOriginWithForceHTTPS(
req: Request | IncomingMessage,
): string {
if (process.env.OIDC_FORCE_HTTPS === "true") {
const origin = getRequestOrigin(req);
return origin.replace(/^http:/, "https:");
}
return getRequestOrigin(req);
}
+23 -11
View File
@@ -4,7 +4,7 @@ import {
sshCredentials,
hostAccess,
userRoles,
sshData,
hosts,
} from "../database/db/schema.js";
import { eq, and } from "drizzle-orm";
import { DataCrypto } from "./data-crypto.js";
@@ -190,15 +190,27 @@ class SharedCredentialManager {
const cred = sharedCred[0].shared_credentials;
if (cred.needsReEncryption) {
databaseLogger.warn(
"Shared credential needs re-encryption but cannot be accessed yet",
{
operation: "get_shared_credential_pending",
hostId,
userId,
},
);
return null;
await this.reEncryptSharedCredential(cred.id, userId);
const refreshed = await db
.select()
.from(sharedCredentials)
.where(eq(sharedCredentials.id, cred.id))
.limit(1);
if (refreshed.length === 0 || refreshed[0].needsReEncryption) {
databaseLogger.warn(
"Shared credential needs re-encryption but cannot be accessed yet",
{
operation: "get_shared_credential_pending",
hostId,
userId,
},
);
return null;
}
return this.decryptSharedCredential(refreshed[0], userDEK);
}
return this.decryptSharedCredential(cred, userDEK);
@@ -587,7 +599,7 @@ class SharedCredentialManager {
const access = await db
.select()
.from(hostAccess)
.innerJoin(sshData, eq(hostAccess.hostId, sshData.id))
.innerJoin(hosts, eq(hostAccess.hostId, hosts.id))
.where(eq(hostAccess.id, cred.hostAccessId))
.limit(1);
+12 -1
View File
@@ -23,7 +23,18 @@ export function detectPlatform(req: Request): DeviceType {
return "mobile";
}
if (userAgent.includes("Android")) {
const isDesktopOS =
userAgent.includes("Windows") ||
userAgent.includes("Macintosh") ||
userAgent.includes("Mac OS X") ||
userAgent.includes("X11") ||
userAgent.includes("Linux x86_64");
if (
(userAgent.includes("Android") && !isDesktopOS) ||
userAgent.includes("iPhone") ||
userAgent.includes("iPad")
) {
return "mobile";
}
+6 -9
View File
@@ -303,9 +303,8 @@ class UserCrypto {
await this.storeKEKSalt(userId, newKekSalt);
await this.storeEncryptedDEK(userId, newEncryptedDEK);
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
oldKEK.fill(0);
@@ -341,9 +340,8 @@ class UserCrypto {
await this.storeKEKSalt(userId, newKekSalt);
await this.storeEncryptedDEK(userId, newEncryptedDEK);
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
newKEK.fill(0);
@@ -418,9 +416,8 @@ class UserCrypto {
},
);
const { saveMemoryDatabaseToFile } = await import(
"../database/db/index.js"
);
const { saveMemoryDatabaseToFile } =
await import("../database/db/index.js");
await saveMemoryDatabaseToFile();
} catch (error) {
databaseLogger.error("Failed to convert to OIDC encryption", error, {
+3 -3
View File
@@ -1,7 +1,7 @@
import { getDb } from "../database/db/index.js";
import {
users,
sshData,
hosts,
sshCredentials,
fileManagerRecent,
fileManagerPinned,
@@ -74,8 +74,8 @@ class UserDataExport {
const sshHosts = await getDb()
.select()
.from(sshData)
.where(eq(sshData.userId, userId));
.from(hosts)
.where(eq(hosts.userId, userId));
const processedSshHosts =
format === "plaintext" && userDataKey
? sshHosts.map((host) =>
+11 -13
View File
@@ -1,7 +1,7 @@
import { getDb } from "../database/db/index.js";
import {
users,
sshData,
hosts,
sshCredentials,
fileManagerRecent,
fileManagerPinned,
@@ -179,13 +179,13 @@ class UserDataImport {
const existing = await getDb()
.select()
.from(sshData)
.from(hosts)
.where(
and(
eq(sshData.userId, targetUserId),
eq(sshData.ip, host.ip as string),
eq(sshData.port, host.port as number),
eq(sshData.username, host.username as string),
eq(hosts.userId, targetUserId),
eq(hosts.ip, host.ip as string),
eq(hosts.port, host.port as number),
eq(hosts.username, host.username as string),
),
);
@@ -218,15 +218,13 @@ class UserDataImport {
if (existing.length > 0 && options.replaceExisting) {
await getDb()
.update(sshData)
.set(processedHostData as unknown as typeof sshData.$inferInsert)
.where(eq(sshData.id, existing[0].id));
.update(hosts)
.set(processedHostData as unknown as typeof hosts.$inferInsert)
.where(eq(hosts.id, existing[0].id));
} else {
await getDb()
.insert(sshData)
.values(
processedHostData as unknown as typeof sshData.$inferInsert,
);
.insert(hosts)
.values(processedHostData as unknown as typeof hosts.$inferInsert);
}
imported++;
} catch (error) {
+1 -2
View File
@@ -37,8 +37,7 @@ const buttonVariants = cva(
);
export interface ButtonProps
extends React.ComponentProps<"button">,
VariantProps<typeof buttonVariants> {
extends React.ComponentProps<"button">, VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
+1
View File
@@ -810,6 +810,7 @@
"globalSettingsSaved": "Global monitoring settings saved",
"failedToSaveGlobalSettings": "Failed to save global monitoring settings",
"failedToLoadGlobalSettings": "Failed to load global monitoring settings",
"clampedToValidRange": "was adjusted to valid range",
"sessionManagement": "Session Management",
"loadingSessions": "Loading sessions...",
"noActiveSessions": "No active sessions found.",
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globale moniteringsinstellings gestoor",
"failedToSaveGlobalSettings": "Kon nie globale moniteringsinstellings stoor nie",
"failedToLoadGlobalSettings": "Kon nie globale moniteringsinstellings laai nie",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Laai sessies...",
"noActiveSessions": "Geen aktiewe sessies gevind nie.",
"device": "Toestel",
@@ -866,11 +876,21 @@
"importError": "Invoerfout",
"failedToImportJson": "Kon nie JSON-lêer invoer nie",
"connectionDetails": "Verbindingsbesonderhede",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisasie",
"ipAddress": "IP-adres of gasheernaam",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Hawe",
"name": "Naam",
"username": "Gebruikersnaam",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Vouer",
"tags": "Etikette",
"pin": "Speld vas",
@@ -979,6 +999,8 @@
"tunnel": "Tonnel",
"fileManager": "Lêerbestuurder",
"serverStats": "Bedienerstatistieke",
"status": "Status",
"statistics": "Statistiek",
"hostViewer": "Gasheerkyker",
"enableServerStats": "Aktiveer bedienerstatistieke",
"enableServerStatsDesc": "Aktiveer/deaktiveer bedienerstatistiekversameling vir hierdie gasheer",
@@ -1028,7 +1050,6 @@
"openFileManager": "Maak Lêerbestuurder oop",
"openTunnels": "Oop Tonnels",
"openServerDetails": "Maak bedienerbesonderhede oop",
"statistics": "Statistiek",
"enabledWidgets": "Geaktiveerde Widgets",
"openServerStats": "Maak bedienerstatistieke oop",
"enabledWidgetsDesc": "Kies watter statistiek-widgets vir hierdie gasheer vertoon moet word",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Kontroleer of die bediener aanlyn of vanlyn is",
"statusCheckInterval": "Statuskontrole-interval",
"statusCheckIntervalDesc": "Hoe gereeld om te kyk of die gasheer aanlyn is (5s - 1u)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Gebruik globale verstekwaarde",
"useGlobalMetricsInterval": "Gebruik globale verstekwaarde",
"usingGlobalDefault": "Gebruik globale verstekwaarde ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Aktiveer Metrieke Monitering",
"metricsEnabledDesc": "Versamel SVE-, RAM-, skyf- en ander stelselstatistieke",
"metricsInterval": "Metrieke-insamelingsinterval",
"metricsIntervalDesc": "Hoe gereeld om bedienerstatistieke in te samel (5s - 1u)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekondes",
"intervalMinutes": "minute",
"intervalValidation": "Moniteringsintervalle moet tussen 5 sekondes en 1 uur (3600 sekondes) wees.",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopieer Tonnel URL",
"copyServerStatsUrl": "Kopieer bedienerstatistieke-URL",
"copyDockerUrl": "Kopieer Docker URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Kopieer URL om hierdie program in volskermmodus oop te maak",
"notEnabled": "Docker is nie vir hierdie gasheer geaktiveer nie. Aktiveer dit in Gasheerinstellings om Docker-funksies te gebruik.",
"validating": "Valideer Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Kies alles",
"deselectAll": "Deselekteer alles",
"useGlobalStatusDefault": "Gebruik globale verstekwaarde (status)",
"useGlobalMetricsDefault": "Gebruik globale verstekwaarde (metrieke)"
"useGlobalMetricsDefault": "Gebruik globale verstekwaarde (metrieke)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminaal",
@@ -1372,6 +1489,7 @@
"connected": "Verbonde",
"clipboardWriteFailed": "Kon nie na knipbord kopieer nie. Maak seker dat die bladsy oor HTTPS of localhost bedien word.",
"clipboardReadFailed": "Kon nie vanaf knipbord lees nie. Maak seker dat knipbordtoestemmings toegestaan is.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-verbinding gevestig",
"authError": "Verifikasie het misluk: {{message}}",
"unknownError": "Onbekende fout het voorgekom",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Merk outomaties opdragte, paaie, IP's en logvlakke in terminaaluitvoer",
"enableCommandPaletteShortcut": "Aktiveer die opdragpalet-kortpad",
"enableCommandPaletteShortcutDesc": "Dubbeltik links Shift om die opdragpalet oop te maak vir vinnige toegang tot gashere",
"enableTerminalSessionPersistence": "Aanhoudende terminale sessies",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Handhaaf SSH-verbindings wanneer jy oortjies wissel of die blaaier toemaak (dit kan onstabiel wees)."
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "تم حفظ إعدادات المراقبة العالمية",
"failedToSaveGlobalSettings": "فشل في حفظ إعدادات المراقبة العالمية",
"failedToLoadGlobalSettings": "فشل تحميل إعدادات المراقبة العالمية",
"guacamoleIntegration": "تكامل سطح المكتب عن بعد (غواكامول)",
"guacamoleIntegrationDesc": "تمكين اتصالات RDP و VNC و Telnet عبر guacd. يتطلب مثيل Gacd ليتم تشغيله.",
"enableGuacamole": "تمكين دعم RDP/VNC/Telnet",
"guacdUrl": "رابط guacd (المضيف:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "تتطلب التغييرات على مضيف/منفذ guacd إعادة تشغيل الخادم لتفعيلها.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "تم تعديله إلى نطاق صحيح",
"loadingSessions": "جاري تحميل الجلسات...",
"noActiveSessions": "لم يتم العثور على جلسات نشطة.",
"device": "الجهاز",
@@ -866,11 +876,21 @@
"importError": "خطأ في الاستيراد",
"failedToImportJson": "فشل استيراد ملف JSON",
"connectionDetails": "تفاصيل الاتصال",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "المنظمة",
"ipAddress": "عنوان IP أو اسم المضيف",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "المنفذ",
"name": "الاسم",
"username": "اسم المستخدم",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "مجلد",
"tags": "الوسوم",
"pin": "تثبيت",
@@ -979,6 +999,8 @@
"tunnel": "نفق",
"fileManager": "مدير الملفات",
"serverStats": "إحصائيات الخادم",
"status": "Status",
"statistics": "الإحصائيات",
"hostViewer": "عارض المضيف",
"enableServerStats": "تمكين إحصائيات الخادم",
"enableServerStatsDesc": "تمكين/تعطيل مجموعة إحصائيات الخادم لهذا المضيف",
@@ -1028,7 +1050,6 @@
"openFileManager": "فتح مدير الملفات",
"openTunnels": "فتح الأنفاق",
"openServerDetails": "فتح تفاصيل الخادم",
"statistics": "الإحصائيات",
"enabledWidgets": "تمكين الودجت",
"openServerStats": "فتح إحصائيات الخادم",
"enabledWidgetsDesc": "حدد الاحصائيات التي سيتم عرضها لهذا المضيف",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "تحقق مما إذا كان الخادم متصلاً أو غير متصل",
"statusCheckInterval": "فترة التحقق من الحالة",
"statusCheckIntervalDesc": "كم عدد المرات للتحقق مما إذا كان المضيف متصل بالإنترنت (5s - 1ساعة)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "استخدام الافتراضي العام",
"useGlobalMetricsInterval": "استخدام الافتراضي العام",
"usingGlobalDefault": "استخدام الافتراضي العالمي ({{value}})",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "تمكين مراقبة القياسات",
"metricsEnabledDesc": "جمع إحصائيات المعالجة، ذاكرة الوصول العشوائي، القرص وغيرها من إحصائيات النظام",
"metricsInterval": "الفاصل الزمني لمجموعة القياسات",
"metricsIntervalDesc": "كم عدد المرات لجمع إحصائيات الخادم (5s - 1ساعة)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "ثواني",
"intervalMinutes": "دقائق",
"intervalValidation": "يجب أن تكون فترات الرصد بين 5 ثوان وساعة واحدة (3600 ثانية)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "نسخ رابط النفق",
"copyServerStatsUrl": "نسخ رابط إحصائيات الخادم",
"copyDockerUrl": "نسخ رابط Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "نسخ عنوان URL لفتح هذا التطبيق في وضع ملء الشاشة",
"notEnabled": "Docker غير مفعل لهذا المضيف. قم بتمكينه في إعدادات المضيف لاستخدام ميزات Docker.",
"validating": "التحقق من دوكر...",
@@ -1348,7 +1375,97 @@
"selectAll": "حدد الكل",
"deselectAll": "إلغاء تحديد الكل",
"useGlobalStatusDefault": "استخدام الافتراضي العام (الحالة)",
"useGlobalMetricsDefault": "استخدام الافتراضي العام (القياسات)"
"useGlobalMetricsDefault": "استخدام الافتراضي العام (القياسات)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "المحطة",
@@ -1372,6 +1489,7 @@
"connected": "متصل",
"clipboardWriteFailed": "فشل النسخ إلى الحافظة. تأكد من خدمة الصفحة عبر HTTPS أو localhost.",
"clipboardReadFailed": "فشل في القراءة من الحافظة. تأكد من منح أذونات الحافظة.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "تم إنشاء اتصال SSH",
"authError": "فشل المصادقة: {{message}}",
"unknownError": "حدث خطأ غير معروف",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "تسليط الضوء تلقائياً على الأوامر والمسارات وIP ومستويات السجل في المخرجات الطرفية",
"enableCommandPaletteShortcut": "تمكين اختصار قفل لوحة الأوامر",
"enableCommandPaletteShortcutDesc": "انقر نقرًا مزدوجًا على نوبات اليسار لفتح لوحة القيادة للوصول السريع إلى المضيفين",
"enableTerminalSessionPersistence": "الدورات الطرفية المستمرة",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "الحفاظ على اتصالات SSH عند تبديل علامات التبويب أو إغلاق المتصفح (قد يكون غير مستقر)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Глобалните настройки за наблюдение са запазени",
"failedToSaveGlobalSettings": "Запазването на настройките за глобално наблюдение не бе успешно",
"failedToLoadGlobalSettings": "Зареждането на настройките за глобално наблюдение не бе успешно",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Зареждане на сесиите...",
"noActiveSessions": "Няма намерени активни сесии.",
"device": "Устройство",
@@ -866,11 +876,21 @@
"importError": "Грешка при импортиране",
"failedToImportJson": "Импортирането на JSON файл не бе успешно",
"connectionDetails": "Детайли за връзката",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Организация",
"ipAddress": "IP адрес или име на хост",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Порт",
"name": "Име",
"username": "Потребителско име",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Папка",
"tags": "Етикети",
"pin": "Закачи",
@@ -979,6 +999,8 @@
"tunnel": "Тунел",
"fileManager": "Файлов мениджър",
"serverStats": "Статистика на сървъра",
"status": "Status",
"statistics": "Статистика",
"hostViewer": "Преглед на хоста",
"enableServerStats": "Активиране на статистиката на сървъра",
"enableServerStatsDesc": "Активиране/деактивиране на събирането на статистика за сървъра за този хост",
@@ -1028,7 +1050,6 @@
"openFileManager": "Отворете файловия мениджър",
"openTunnels": "Отворени тунели",
"openServerDetails": "Отворете подробности за сървъра",
"statistics": "Статистика",
"enabledWidgets": "Активирани джаджи",
"openServerStats": "Отворете статистиката на сървъра",
"enabledWidgetsDesc": "Изберете кои статистически уиджети да се показват за този хост",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Проверете дали сървърът е онлайн или офлайн",
"statusCheckInterval": "Интервал за проверка на състоянието",
"statusCheckIntervalDesc": "Колко често да проверявам дали хостът е онлайн (5 секунди - 1 час)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Използване на глобално по подразбиране",
"useGlobalMetricsInterval": "Използване на глобално по подразбиране",
"usingGlobalDefault": "Използване на глобалното по подразбиране ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Активиране на мониторинг на показатели",
"metricsEnabledDesc": "Събиране на статистически данни за процесора, RAM, диска и други системни данни",
"metricsInterval": "Интервал на събиране на показатели",
"metricsIntervalDesc": "Колко често да се събира статистика за сървъра (5 секунди - 1 час)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "секунди",
"intervalMinutes": "минути",
"intervalValidation": "Интервалите за наблюдение трябва да бъдат между 5 секунди и 1 час (3600 секунди)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Копиране на URL адреса на тунела",
"copyServerStatsUrl": "Копиране на URL адреса за статистика на сървъра",
"copyDockerUrl": "Копиране на URL адреса на Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Копирайте URL адреса, за да отворите това приложение в режим на цял екран",
"notEnabled": "Docker не е активиран за този хост. Активирайте го в настройките на хоста, за да използвате функциите на Docker.",
"validating": "Валидиране на Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Избери всички",
"deselectAll": "Премахване на избора от всички",
"useGlobalStatusDefault": "Използване на глобално по подразбиране (състояние)",
"useGlobalMetricsDefault": "Използване на глобални настройки по подразбиране (метрики)"
"useGlobalMetricsDefault": "Използване на глобални настройки по подразбиране (метрики)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Терминал",
@@ -1372,6 +1489,7 @@
"connected": "Свързан",
"clipboardWriteFailed": "Копирането в клипборда не бе успешно. Уверете се, че страницата се предоставя през HTTPS или localhost.",
"clipboardReadFailed": "Четенето от клипборда не бе успешно. Уверете се, че са предоставени разрешения за достъп до клипборда.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH връзка е установена",
"authError": "Удостоверяването не бе успешно: {{message}}",
"unknownError": "Възникна неизвестна грешка",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Автоматично маркиране на команди, пътища, IP адреси и нива на лог файлове в изхода на терминала",
"enableCommandPaletteShortcut": "Активиране на пряк път за палитра с команди",
"enableCommandPaletteShortcutDesc": "Докоснете двукратно левия Shift, за да отворите палитрата с команди за бърз достъп до хостове",
"enableTerminalSessionPersistence": "Постоянни терминални сесии",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Поддържане на SSH връзки при превключване на раздели или затваряне на браузъра (може да е нестабилно)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "বিশ্বব্যাপী পর্যবেক্ষণ সেটিংস সংরক্ষণ করা হয়েছে",
"failedToSaveGlobalSettings": "বিশ্বব্যাপী পর্যবেক্ষণ সেটিংস সংরক্ষণ করতে ব্যর্থ হয়েছে",
"failedToLoadGlobalSettings": "বিশ্বব্যাপী পর্যবেক্ষণ সেটিংস লোড করা যায়নি",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "সেশন লোড হচ্ছে...",
"noActiveSessions": "কোন সক্রিয় সেশন পাওয়া যায়নি।",
"device": "যন্ত্র",
@@ -866,11 +876,21 @@
"importError": "আমদানি ত্রুটি",
"failedToImportJson": "JSON ফাইল আমদানি করা যায়নি",
"connectionDetails": "সংযোগের বিবরণ",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "সংগঠন",
"ipAddress": "আইপি ঠিকানা অথবা হোস্টনেম",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "বন্দর",
"name": "নাম",
"username": "ব্যবহারকারীর নাম",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "ফোল্ডার",
"tags": "ট্যাগ",
"pin": "পিন",
@@ -979,6 +999,8 @@
"tunnel": "টানেল",
"fileManager": "ফাইল ম্যানেজার",
"serverStats": "সার্ভার পরিসংখ্যান",
"status": "Status",
"statistics": "পরিসংখ্যান",
"hostViewer": "হোস্ট ভিউয়ার",
"enableServerStats": "সার্ভার পরিসংখ্যান সক্ষম করুন",
"enableServerStatsDesc": "এই হোস্টের জন্য সার্ভার পরিসংখ্যান সংগ্রহ সক্ষম/অক্ষম করুন",
@@ -1028,7 +1050,6 @@
"openFileManager": "ফাইল ম্যানেজার খুলুন",
"openTunnels": "খোলা টানেল",
"openServerDetails": "সার্ভারের বিবরণ খুলুন",
"statistics": "পরিসংখ্যান",
"enabledWidgets": "সক্রিয় উইজেট",
"openServerStats": "ওপেন সার্ভার পরিসংখ্যান",
"enabledWidgetsDesc": "এই হোস্টের জন্য কোন পরিসংখ্যান উইজেটগুলি প্রদর্শন করা হবে তা নির্বাচন করুন।",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "সার্ভারটি অনলাইন নাকি অফলাইন তা পরীক্ষা করুন।",
"statusCheckInterval": "স্থিতি পরীক্ষা ব্যবধান",
"statusCheckIntervalDesc": "হোস্ট অনলাইন আছে কিনা তা কতবার পরীক্ষা করতে হবে (৫ সেকেন্ড - ১ ঘন্টা)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "গ্লোবাল ডিফল্ট ব্যবহার করুন",
"useGlobalMetricsInterval": "গ্লোবাল ডিফল্ট ব্যবহার করুন",
"usingGlobalDefault": "গ্লোবাল ডিফল্ট ব্যবহার করে ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "মেট্রিক্স মনিটরিং সক্ষম করুন",
"metricsEnabledDesc": "CPU, RAM, ডিস্ক এবং অন্যান্য সিস্টেম পরিসংখ্যান সংগ্রহ করুন",
"metricsInterval": "মেট্রিক্স সংগ্রহের ব্যবধান",
"metricsIntervalDesc": "সার্ভারের পরিসংখ্যান কত ঘন ঘন সংগ্রহ করতে হবে (৫ সেকেন্ড - ১ ঘন্টা)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "সেকেন্ড",
"intervalMinutes": "মিনিট",
"intervalValidation": "পর্যবেক্ষণের ব্যবধান ৫ সেকেন্ড থেকে ১ ঘন্টা (৩৬০০ সেকেন্ড) এর মধ্যে হতে হবে।",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "টানেলের URL কপি করুন",
"copyServerStatsUrl": "সার্ভার পরিসংখ্যান URL কপি করুন",
"copyDockerUrl": "ডকার ইউআরএল কপি করুন",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "এই অ্যাপটি পূর্ণ-স্ক্রিন মোডে খুলতে URL কপি করুন",
"notEnabled": "এই হোস্টের জন্য ডকার সক্ষম করা নেই। ডকার বৈশিষ্ট্যগুলি ব্যবহার করতে হোস্ট সেটিংসে এটি সক্ষম করুন।",
"validating": "ডকার যাচাই করা হচ্ছে...",
@@ -1348,7 +1375,97 @@
"selectAll": "সবগুলো নির্বাচন করুন",
"deselectAll": "সবগুলো অনির্বাচন করুন",
"useGlobalStatusDefault": "গ্লোবাল ডিফল্ট (স্থিতি) ব্যবহার করুন",
"useGlobalMetricsDefault": "গ্লোবাল ডিফল্ট (মেট্রিক্স) ব্যবহার করুন"
"useGlobalMetricsDefault": "গ্লোবাল ডিফল্ট (মেট্রিক্স) ব্যবহার করুন",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "টার্মিনাল",
@@ -1372,6 +1489,7 @@
"connected": "সংযুক্ত",
"clipboardWriteFailed": "ক্লিপবোর্ডে কপি করা যায়নি। নিশ্চিত করুন যে পৃষ্ঠাটি HTTPS অথবা localhost এর মাধ্যমে পরিবেশিত হচ্ছে।",
"clipboardReadFailed": "ক্লিপবোর্ড থেকে পড়া যায়নি। ক্লিপবোর্ডের অনুমতি মঞ্জুর করা হয়েছে কিনা তা নিশ্চিত করুন।",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH সংযোগ স্থাপন করা হয়েছে",
"authError": "প্রমাণীকরণ ব্যর্থ হয়েছে: {{message}}",
"unknownError": "অজানা ত্রুটি ঘটেছে",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "টার্মিনাল আউটপুটে স্বয়ংক্রিয়ভাবে কমান্ড, পাথ, আইপি এবং লগ লেভেল হাইলাইট করুন",
"enableCommandPaletteShortcut": "কমান্ড প্যালেট শর্টকাট সক্ষম করুন",
"enableCommandPaletteShortcutDesc": "হোস্টগুলিতে দ্রুত অ্যাক্সেসের জন্য কমান্ড প্যালেট খুলতে বাম দিকে Shift-এ দুবার ট্যাপ করুন।",
"enableTerminalSessionPersistence": "স্থায়ী টার্মিনাল সেশন",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "ট্যাব স্যুইচ করার সময় বা ব্রাউজার বন্ধ করার সময় SSH সংযোগ বজায় রাখুন (অস্থির হতে পারে)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "S'ha desat la configuració de monitorització global",
"failedToSaveGlobalSettings": "No s'ha pogut desar la configuració de monitorització global",
"failedToLoadGlobalSettings": "No s'ha pogut carregar la configuració de monitorització global",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "S'estan carregant les sessions...",
"noActiveSessions": "No s'han trobat sessions actives.",
"device": "Dispositiu",
@@ -866,11 +876,21 @@
"importError": "Error d'importació",
"failedToImportJson": "No s'ha pogut importar el fitxer JSON",
"connectionDetails": "Detalls de la connexió",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organització",
"ipAddress": "Adreça IP o nom d'amfitrió",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Nom",
"username": "Nom d'usuari",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Carpeta",
"tags": "Etiquetes",
"pin": "Fixar",
@@ -979,6 +999,8 @@
"tunnel": "Túnel",
"fileManager": "Gestor de fitxers",
"serverStats": "Estadístiques del servidor",
"status": "Status",
"statistics": "Estadístiques",
"hostViewer": "Visualitzador de l'amfitrió",
"enableServerStats": "Habilita les estadístiques del servidor",
"enableServerStatsDesc": "Activa/desactiva la recopilació d'estadístiques del servidor per a aquest amfitrió",
@@ -1028,7 +1050,6 @@
"openFileManager": "Obre el gestor de fitxers",
"openTunnels": "Túnels oberts",
"openServerDetails": "Obre els detalls del servidor",
"statistics": "Estadístiques",
"enabledWidgets": "Widgets activats",
"openServerStats": "Estadístiques del servidor obert",
"enabledWidgetsDesc": "Seleccioneu els widgets d'estadístiques que voleu mostrar per a aquest amfitrió",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Comprova si el servidor està en línia o fora de línia",
"statusCheckInterval": "Interval de comprovació d'estat",
"statusCheckIntervalDesc": "Amb quina freqüència cal comprovar si l'amfitrió està en línia (5 segons - 1 hora)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Utilitza el valor predeterminat global",
"useGlobalMetricsInterval": "Utilitza el valor predeterminat global",
"usingGlobalDefault": "Utilitzant el valor per defecte global ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Activa la supervisió de mètriques",
"metricsEnabledDesc": "Recopila estadístiques de CPU, RAM, disc i altres estadístiques del sistema",
"metricsInterval": "Interval de recopilació de mètriques",
"metricsIntervalDesc": "Amb quina freqüència s'han de recopilar estadístiques del servidor (5 segons - 1 hora)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "segons",
"intervalMinutes": "minuts",
"intervalValidation": "Els intervals de monitorització han d'estar entre 5 segons i 1 hora (3600 segons)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copia l'URL del túnel",
"copyServerStatsUrl": "Copia l'URL de les estadístiques del servidor",
"copyDockerUrl": "Copia l'URL de Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copia l'URL per obrir aquesta aplicació en mode de pantalla completa",
"notEnabled": "Docker no està habilitat per a aquest amfitrió. Activeu-lo a la configuració de l'amfitrió per utilitzar les funcions de Docker.",
"validating": "Validant Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Selecciona-ho tot",
"deselectAll": "Desselecciona-ho tot",
"useGlobalStatusDefault": "Utilitza el valor per defecte global (estat)",
"useGlobalMetricsDefault": "Utilitza el valor predeterminat global (mètriques)"
"useGlobalMetricsDefault": "Utilitza el valor predeterminat global (mètriques)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Connectat",
"clipboardWriteFailed": "No s'ha pogut copiar al porta-retalls. Assegureu-vos que la pàgina es serveix per HTTPS o localhost.",
"clipboardReadFailed": "No s'ha pogut llegir del porta-retalls. Assegureu-vos que els permisos del porta-retalls estiguin concedits.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Connexió SSH establerta",
"authError": "L'autenticació ha fallat: {{message}}",
"unknownError": "S'ha produït un error desconegut",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Ressaltar automàticament les ordres, les rutes, les IP i els nivells de registre a la sortida del terminal",
"enableCommandPaletteShortcut": "Activa la drecera de la paleta d'ordres",
"enableCommandPaletteShortcutDesc": "Toqueu dues vegades la tecla Majúscules esquerra per obrir la paleta d'ordres i accedir ràpidament als amfitrions.",
"enableTerminalSessionPersistence": "Sessions terminals persistents",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Mantingueu les connexions SSH en canviar de pestanya o tancar el navegador (pot ser inestable)"
},
"user": {
+158 -40
View File
@@ -244,14 +244,14 @@
}
},
"snippets": {
"title": "Výstřižky bloků",
"new": "Nový snippet",
"create": "Vytvořit snippet",
"edit": "Upravit snippet",
"title": "Úryvky",
"new": "Nový úryvek",
"create": "Vytvořit úryvek",
"edit": "Upravit úryvek",
"run": "Spustit",
"empty": "Zatím žádné textové bloky",
"emptyHint": "Vytvořit snippet pro uložení běžně používaných příkazů",
"searchSnippets": "Hledat snippety...",
"empty": "Zatím žádné úryvky",
"emptyHint": "Vytvořit úryvek pro uložení běžně používaných příkazů",
"searchSnippets": "Hledat úryvky...",
"name": "Název",
"description": "L 343, 22.12.2009, s. 1).",
"content": "Příkaz",
@@ -260,29 +260,29 @@
"contentPlaceholder": "Např. sudo systemctl restart nginx",
"nameRequired": "Název je povinný",
"contentRequired": "Příkaz je povinný",
"createDescription": "Vytvořit nový snippet příkazu pro rychlé spuštění",
"editDescription": "Upravit tento snippet příkazu",
"deleteConfirmTitle": "Odstranit snippet",
"createDescription": "Vytvořit nový úryvek příkazu pro rychlé spuštění",
"editDescription": "Upravit tento úryvek příkazu",
"deleteConfirmTitle": "Odstranit úryvek",
"deleteConfirmDescription": "Jste si jisti, že chcete odstranit \"{{name}}\"?",
"createSuccess": "Výstřižek byl úspěšně vytvořen",
"createSuccess": "Úryvek byl úspěšně vytvořen",
"updateSuccess": "Úryvek byl úspěšně aktualizován",
"deleteSuccess": "Textový blok byl úspěšně odstraněn",
"createFailed": "Nepodařilo se vytvořit snippet",
"updateFailed": "Nepodařilo se aktualizovat snippet",
"deleteFailed": "Nepodařilo se odstranit snippet",
"failedToFetch": "Nepodařilo se načíst snippety",
"deleteSuccess": "Úryvek byl úspěšně odstraněn",
"createFailed": "Nepodařilo se vytvořit úryvek",
"updateFailed": "Nepodařilo se aktualizovat úryvek",
"deleteFailed": "Nepodařilo se odstranit úryvek",
"failedToFetch": "Nepodařilo se načíst úryvky",
"executeSuccess": "Probíhá: {{name}}",
"copySuccess": "Zkopírováno \"{{name}}\" do schránky",
"runTooltip": "Spustit tento snippet v terminálu",
"copyTooltip": "Zkopírovat snippet do schránky",
"runTooltip": "Spustit tento úryvek v terminálu",
"copyTooltip": "Zkopírovat úryvek do schránky",
"editTooltip": "Upravit tento úryvek",
"deleteTooltip": "Odstranit tento úryvek",
"newFolder": "Nová složka",
"reorderSameFolder": "Lze změnit pořadí snippetů ve stejné složce",
"reorderSuccess": "Úryvky úspěšně seřazeny",
"reorderFailed": "Nepodařilo se změnit pořadí snippetů",
"deleteFolderConfirm": "Odstranit složku \"{{name}}\"? Všechny textové bloky budou přesunuty do nekategorizované.",
"deleteFolderSuccess": "Složka byla úspěšně smazána",
"reorderSameFolder": "Lze změnit pořadí úryvků pouze ve stejné složce",
"reorderSuccess": "Pořadí úryvků bylo úspěšně změněno",
"reorderFailed": "Nepodařilo se změnit pořadí úryvků",
"deleteFolderConfirm": "Odstranit složku \"{{name}}\"? Všechny úryvky budou přesunuty do Nezařazené.",
"deleteFolderSuccess": "Složka byla úspěšně odstraněna",
"deleteFolderFailed": "Nepodařilo se odstranit složku",
"updateFolderSuccess": "Složka byla úspěšně aktualizována",
"createFolderSuccess": "Složka byla úspěšně vytvořena",
@@ -293,7 +293,7 @@
"executeOnCurrent": "Spustit na aktuálním terminálu (klepnutím vyberte více možností)",
"folder": "Složka",
"selectFolder": "Vyberte složku nebo ponechte prázdné",
"noFolder": "Žádná složka (nekategorizovaná)",
"noFolder": "Žádná složka (Nezařazené)",
"folderName": "Název složky",
"folderNameRequired": "Název složky je povinný",
"folderColor": "Barva složky",
@@ -302,10 +302,10 @@
"updateFolder": "Aktualizovat složku",
"createFolder": "Vytvořit složku",
"editFolder": "Upravit složku",
"editFolderDescription": "Přizpůsobit složku snippetu",
"editFolderDescription": "Přizpůsobit složku úryvku",
"createFolderDescription": "Uspořádat úryvky do složek",
"confirmExecution": "Spustit \"{{name}}\"?",
"confirmExecutionDesc": "Jste si jisti, že chcete spustit tento snippet?"
"confirmExecutionDesc": "Opravdu chcete spustit tento úryvek?"
},
"commandHistory": {
"title": "Historie",
@@ -528,7 +528,7 @@
"admin": "Admin",
"userProfile": "Profil uživatele",
"tools": "Nástroje",
"snippets": "Výstřižky bloků",
"snippets": "Úryvky",
"newTab": "New Tab",
"splitScreen": "Rozdělit obrazovku",
"closeTab": "Zavřít kartu",
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globální nastavení monitorování uloženo",
"failedToSaveGlobalSettings": "Nepodařilo se uložit globální nastavení monitorování",
"failedToLoadGlobalSettings": "Nepodařilo se načíst globální nastavení monitorování",
"guacamoleIntegration": "Integrace vzdálené plochy (Guacamole)",
"guacamoleIntegrationDesc": "Povolit připojení RDP, VNC a Telnet pomocí guacdu. Vyžaduje spuštění instance guacd.",
"enableGuacamole": "Povolit podporu RDP/VNC/Telnet",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guakd:4822",
"guacdUrlNote": "Změny hostitele/portu guacd vyžadují restartování serveru.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "byl upraven na platný rozsah",
"loadingSessions": "Načítání relací...",
"noActiveSessions": "Nebyly nalezeny žádné aktivní relace.",
"device": "Zařízení",
@@ -866,11 +876,21 @@
"importError": "Chyba importu",
"failedToImportJson": "Nepodařilo se importovat soubor JSON",
"connectionDetails": "Detaily připojení",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organizace",
"ipAddress": "IP adresa nebo název hostitele",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Název",
"username": "Uživatelské jméno",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Složka",
"tags": "Štítky",
"pin": "Připnout",
@@ -979,6 +999,8 @@
"tunnel": "Tunel",
"fileManager": "Správce souborů",
"serverStats": "Statistiky serveru",
"status": "Status",
"statistics": "Statistiky",
"hostViewer": "Prohlížeč hostitelů",
"enableServerStats": "Povolit statistiky serveru",
"enableServerStatsDesc": "Povolit/zakázat sběr statistik serveru pro tohoto hostitele",
@@ -1028,7 +1050,6 @@
"openFileManager": "Otevřít správce souborů",
"openTunnels": "Otevřené tunely",
"openServerDetails": "Detaily otevřeného serveru",
"statistics": "Statistiky",
"enabledWidgets": "Povolené widgety",
"openServerStats": "Otevřené statistiky serveru",
"enabledWidgetsDesc": "Vyberte, které widgety statistiky se zobrazí pro tohoto hostitele",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Zkontrolujte, zda je server online nebo offline",
"statusCheckInterval": "Interval kontroly stavu",
"statusCheckIntervalDesc": "Jak často kontrolovat, zda je hostitel online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Použít globální výchozí nastavení",
"useGlobalMetricsInterval": "Použít globální výchozí nastavení",
"usingGlobalDefault": "Použití globálního výchozího ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Povolit sledování metriky",
"metricsEnabledDesc": "Sbírat CPU, RAM, disky a další systémové statistiky",
"metricsInterval": "Interval sběru metrik",
"metricsIntervalDesc": "Jak často shromažďovat statistiky serveru (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekundy",
"intervalMinutes": "minuty",
"intervalValidation": "Monitorovací intervaly musí být mezi 5 sekundami a 1 hodinou (3600 sekund)",
@@ -1112,9 +1138,9 @@
"backspaceModeNormal": "Normální (DEL)",
"backspaceModeControlH": "Ovládání H (^H)",
"backspaceModeDesc": "Chování tlačítka Backspace pro kompatibilitu",
"startupSnippet": "Spustit snippet",
"startupSnippet": "Spustit úryvek",
"selectSnippet": "Vybrat úryvek",
"searchSnippets": "Hledat snippety...",
"searchSnippets": "Hledat úryvky...",
"snippetNone": "Nic",
"noneAuthTitle": "Klávesnice interaktivní ověření",
"noneAuthDescription": "Tato metoda ověřování bude při připojování k serveru SSH používat klávesnice-interaktivní ověřování.",
@@ -1174,11 +1200,11 @@
"proxyNode": "Proxy uzel",
"proxyType": "Typ proxy",
"quickActions": "Rychlé akce",
"quickActionsDescription": "Rychlé akce vám umožní vytvořit vlastní tlačítka, která na tomto serveru spustí snippety SSH. Tato tlačítka se zobrazí v horní části statistiky serveru pro rychlý přístup.",
"quickActionsDescription": "Rychlé akce vám umožní vytvořit vlastní tlačítka, která na tomto serveru spustí úryvky SSH. Tato tlačítka se zobrazí v horní části statistiky serveru pro rychlý přístup.",
"quickActionsList": "Seznam rychlých akcí",
"addQuickAction": "Přidat rychlou akci",
"quickActionName": "Název akce",
"noSnippetFound": "Úryvek nenalezen",
"noSnippetFound": "Nebyl nalezen žádný úryvek",
"quickActionsOrder": "Tlačítka pro rychlé akce se zobrazí v pořadí uvedeném výše na stránce Statistiky serveru",
"sidebarCustomization": "Přizpůsobení postranního panelu",
"sidebarCustomizationDesc": "Vyberte, které akce se zobrazí jako rychlá tlačítka v postranním panelu. Akce nezobrazené jako tlačítka se zobrazí v rozbalovacím menu.",
@@ -1212,7 +1238,7 @@
"proxyTestSuccess": "Proxy připojení úspěšné ({{latency}}ms)",
"proxyTestFailed": "Proxy test selhal: {{error}}",
"connectionPath": "Cesta k připojení",
"executeSnippetOnConnect": "Spustit snippet, když se terminál připojí",
"executeSnippetOnConnect": "Spustit úryvek, když se terminál připojí",
"autoMosh": "Automatické MOSH",
"autoMoshDesc": "Automaticky spustit MOSH příkaz při připojení",
"moshCommand": "Příkaz MOSH",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopírovat URL tunelu",
"copyServerStatsUrl": "Kopírovat URL statistiky serveru",
"copyDockerUrl": "Kopírovat URL Dockeru",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Kopírovat URL pro otevření této aplikace v režimu celé obrazovky",
"notEnabled": "Docker není pro tohoto hostitele povolen. Povolte jej v nastavení hostitele pro použití funkcí Dockeru.",
"validating": "Ověřování Dockeru...",
@@ -1348,7 +1375,97 @@
"selectAll": "Vybrat vše",
"deselectAll": "Zrušit výběr všech",
"useGlobalStatusDefault": "Použít globální výchozí (stav)",
"useGlobalMetricsDefault": "Použít globální výchozí (Metrics)"
"useGlobalMetricsDefault": "Použít globální výchozí (Metrics)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminál",
@@ -1372,6 +1489,7 @@
"connected": "Připojeno",
"clipboardWriteFailed": "Kopírování do schránky se nezdařilo. Ujistěte se, že stránka je vedena přes HTTPS nebo localhost.",
"clipboardReadFailed": "Nepodařilo se přečíst ze schránky. Ujistěte se, že máte oprávnění na schránku.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH připojení navázáno",
"authError": "Ověření se nezdařilo: {{message}}",
"unknownError": "Došlo k neznámé chybě",
@@ -2126,8 +2244,8 @@
"fileColorCodingDesc": "Barevné soubory podle typu: složky (červené), soubory (modrá), symbolické odkazy (zelené)",
"commandAutocomplete": "Automatické dokončování příkazu",
"commandAutocompleteDesc": "Povolit návrhy automatického dokončování tlačítek záložek pro terminálové příkazy na základě vaší historie příkazů",
"defaultSnippetFoldersCollapsed": "Sbalit složky snippet ve výchozím nastavení",
"defaultSnippetFoldersCollapsedDesc": "Pokud je povoleno, všechny složky snippetů se sbalí, když otevřete záložku snippetů",
"defaultSnippetFoldersCollapsed": "Sbalit složky úryvků ve výchozím nastavení",
"defaultSnippetFoldersCollapsedDesc": "Když je povoleno, všechny složky úryvků se sbalí, když otevřete záložku úryvků",
"terminalSyntaxHighlighting": "Zvýraznění syntaxe terminálu",
"showHostTags": "Zobrazit štítky hostitele",
"showHostTagsDesc": "Zobrazit štítky pod každým hostitelem v postranním panelu. Zakažte pro skrytí všech štítků.",
@@ -2137,9 +2255,9 @@
"fileManagerSettings": "Správce souborů",
"terminalSettings": "Terminál",
"hostSidebarSettings": "Hostitel & postranní panel",
"snippetsSettings": "Výstřižky bloků",
"confirmSnippetExecution": "Potvrdit spuštění snippetu",
"confirmSnippetExecutionDesc": "Zobrazit potvrzovací dialog před spuštěním snippetů",
"snippetsSettings": "Úryvky",
"confirmSnippetExecution": "Potvrdit spuštění úryvku",
"confirmSnippetExecutionDesc": "Zobrazit potvrzovací dialogové okno před spuštěním úryvků",
"updateSettings": "Aktualizace",
"disableUpdateCheck": "Zakázat kontrolu aktualizací",
"disableUpdateCheckDesc": "Zastavit kontrolu nových verzí na startu a řídicím panelu. Sníží síťové požadavky.",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Automaticky zvýraznit příkazy, cesty, IP a logovací úrovně v terminálu",
"enableCommandPaletteShortcut": "Povolit zástupce pro Palety",
"enableCommandPaletteShortcutDesc": "Dvojitým poklepáním vlevo otevřít Příkazovou paletu pro rychlý přístup k hostům",
"enableTerminalSessionPersistence": "Trvalé relace terminálů",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Udržovat SSH připojení při přepínání karet nebo zavření prohlížeče (může být nestabilní)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globale overvågningsindstillinger gemt",
"failedToSaveGlobalSettings": "Kunne ikke gemme globale overvågningsindstillinger",
"failedToLoadGlobalSettings": "Kunne ikke indlæse globale overvågningsindstillinger",
"guacamoleIntegration": "Remote Desktop Integration (Guacamol)",
"guacamoleIntegrationDesc": "Aktivér RDP, VNC og Telnet forbindelser via guacd. Kræver en guacd instans for at køre.",
"enableGuacamole": "Aktiver RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (vært: port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Ændringer af guacd værten / port kræver en server genstart til at træde i kraft.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "blev justeret til gyldigt interval",
"loadingSessions": "Indlæser sessioner...",
"noActiveSessions": "Ingen aktive sessioner fundet.",
"device": "Enhed",
@@ -866,11 +876,21 @@
"importError": "Import fejl",
"failedToImportJson": "Kunne ikke importere JSON- fil",
"connectionDetails": "Forbindelse Detaljer",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisation",
"ipAddress": "Ip adresse eller værtsnavn",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Navn",
"username": "Brugernavn",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Mappe",
"tags": "Mærker",
"pin": "Fastgør",
@@ -979,6 +999,8 @@
"tunnel": "Tunnel",
"fileManager": "Filhåndtering",
"serverStats": "Server Statistik",
"status": "Status",
"statistics": "Statistik",
"hostViewer": "Vært Fremviser",
"enableServerStats": "Aktiver Serverstatistik",
"enableServerStatsDesc": "Aktiver/deaktiver server statistik samling for denne vært",
@@ -1028,7 +1050,6 @@
"openFileManager": "Åbn Filhåndtering",
"openTunnels": "Åbne Tunneler",
"openServerDetails": "Åbn Serverdetaljer",
"statistics": "Statistik",
"enabledWidgets": "Aktiverede Widgets",
"openServerStats": "Åbn Serverstatistik",
"enabledWidgetsDesc": "Vælg hvilke statistikwidgets der skal vises for denne vært",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Tjek om serveren er online eller offline",
"statusCheckInterval": "Status Tjek Interval",
"statusCheckIntervalDesc": "Hvor ofte til at kontrollere, om værten er online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Brug global standard",
"useGlobalMetricsInterval": "Brug global standard",
"usingGlobalDefault": "Bruger global standard ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Aktiver Måleovervågning",
"metricsEnabledDesc": "Indsaml CPU, RAM, disk, og andre systemstatistikker",
"metricsInterval": "Interval For Metrikelsamling",
"metricsIntervalDesc": "Hvor ofte at indsamle server statistik (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekunder",
"intervalMinutes": "minutter",
"intervalValidation": "Overvågningsintervallerne skal være mellem 5 sekunder og 1 time (3600 sekunder)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopier Tunnel URL",
"copyServerStatsUrl": "Kopier Server Statistik URL",
"copyDockerUrl": "Kopier Docker-URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Kopier URL for at åbne denne app i fuld skærm",
"notEnabled": "Docker er ikke aktiveret for denne vært. Aktivér den i værtsindstillinger for at bruge Docker-funktioner.",
"validating": "Validerer Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Vælg alle",
"deselectAll": "Fravælg alle",
"useGlobalStatusDefault": "Brug Global Standard (Status)",
"useGlobalMetricsDefault": "Brug Global Standard (Metrics)"
"useGlobalMetricsDefault": "Brug Global Standard (Metrics)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Forbundet",
"clipboardWriteFailed": "Kunne ikke kopiere til udklipsholderen. Sørg for, at siden er serveret over HTTPS eller localhost.",
"clipboardReadFailed": "Kunne ikke læse fra udklipsholderen. Sørg for, at udklipsholdertilladelser er tildelt.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-forbindelse oprettet",
"authError": "Godkendelse mislykkedes: {{message}}",
"unknownError": "Ukendt fejl opstod",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Fremhæv automatisk kommandoer, stier, IP'er og logniveauer i terminaloutput",
"enableCommandPaletteShortcut": "Aktivér Kommandopalettegenvej",
"enableCommandPaletteShortcutDesc": "Dobbelttryk på venstre Skift for at åbne kommandopaletten for hurtig adgang til værter",
"enableTerminalSessionPersistence": "Vedvarende Terminalsessioner",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Oprethold SSH-forbindelser, når du skifter faner eller lukker browseren (kan være ustabil)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globale Überwachungseinstellungen gespeichert",
"failedToSaveGlobalSettings": "Fehler beim Speichern der globalen Überwachungseinstellungen",
"failedToLoadGlobalSettings": "Fehler beim Laden der globalen Überwachungseinstellungen",
"guacamoleIntegration": "Remote-Desktop-Integration (Guacamole)",
"guacamoleIntegrationDesc": "Aktiviere RDP, VNC und Telnet-Verbindungen via Guacd. Erfordert eine Guacd-Instanz zum Laufen.",
"enableGuacamole": "RDP/VNC/Telnet-Support aktivieren",
"guacdUrl": "guacd-URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Änderungen am Guacd-Host/Port erfordern einen Neustart des Servers.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "wurde an gültigen Bereich angepasst",
"loadingSessions": "Lade Sitzungen...",
"noActiveSessions": "Keine aktiven Sitzungen gefunden.",
"device": "Gerät",
@@ -866,11 +876,21 @@
"importError": "Importfehler",
"failedToImportJson": "Import der JSON-Datei fehlgeschlagen",
"connectionDetails": "Verbindungsdetails",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisation",
"ipAddress": "IP-Adresse oder Hostname",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Name",
"username": "Benutzername",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Ordner",
"tags": "Tags",
"pin": "Pin",
@@ -979,6 +999,8 @@
"tunnel": "Tunnel",
"fileManager": "Datei-Manager",
"serverStats": "Serverstatistik",
"status": "Status",
"statistics": "Statistiken",
"hostViewer": "Hostbetrachter",
"enableServerStats": "Serverstatistik aktivieren",
"enableServerStatsDesc": "Server-Statistiksammlung für diesen Host aktivieren/deaktivieren",
@@ -1028,7 +1050,6 @@
"openFileManager": "Dateimanager öffnen",
"openTunnels": "Tunnel öffnen",
"openServerDetails": "Öffne Server-Details",
"statistics": "Statistiken",
"enabledWidgets": "Aktivierte Widgets",
"openServerStats": "Serverstatistik öffnen",
"enabledWidgetsDesc": "Auswählen, welche Statistik-Widgets für diesen Host angezeigt werden sollen",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Prüfen, ob der Server online oder offline ist",
"statusCheckInterval": "Statusüberprüfungsintervall",
"statusCheckIntervalDesc": "Wie oft wird überprüft, ob der Host online ist (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Globale Standard verwenden",
"useGlobalMetricsInterval": "Globale Standard verwenden",
"usingGlobalDefault": "Globale Standardeinstellung verwenden ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Metrik-Überwachung aktivieren",
"metricsEnabledDesc": "Erfassen Sie CPU, RAM, Festplatte und andere Systemstatistiken",
"metricsInterval": "Metrik-Sammlungsintervall",
"metricsIntervalDesc": "Wie oft Serverstatistiken gesammelt werden (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "Sekunden",
"intervalMinutes": "minuten",
"intervalValidation": "Überwachungsintervalle müssen zwischen 5 Sekunden und 1 Stunde (3600 Sekunden) betragen",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Tunnel-URL kopieren",
"copyServerStatsUrl": "Server-Statistik-URL kopieren",
"copyDockerUrl": "Docker URL kopieren",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "URL kopieren, um diese App im Vollbildmodus zu öffnen",
"notEnabled": "Docker ist für diesen Host nicht aktiviert. Aktivieren Sie ihn in den Host-Einstellungen, um Docker Features zu verwenden.",
"validating": "Docker wird überprüft...",
@@ -1348,7 +1375,97 @@
"selectAll": "Alles auswählen",
"deselectAll": "Alle abwählen",
"useGlobalStatusDefault": "Globale Standardeinstellung verwenden (Status)",
"useGlobalMetricsDefault": "Globale Standardeinstellung (Metriks) verwenden"
"useGlobalMetricsDefault": "Globale Standardeinstellung (Metriks) verwenden",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Verbunden",
"clipboardWriteFailed": "Fehler beim Kopieren in die Zwischenablage. Stellen Sie sicher, dass die Seite über HTTPS oder localhost ausgeliefert wird.",
"clipboardReadFailed": "Lesen aus der Zwischenablage fehlgeschlagen. Stellen Sie sicher, dass die Zwischenablage Berechtigungen gewährt werden.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-Verbindung hergestellt",
"authError": "Authentifizierung fehlgeschlagen: {{message}}",
"unknownError": "Unbekannter Fehler aufgetreten",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Hervorheben von Befehlen, Pfaden, IPs und Log-Ebenen in Terminal-Ausgabe",
"enableCommandPaletteShortcut": "Tastenkürzel für Kommandopalette aktivieren",
"enableCommandPaletteShortcutDesc": "Doppeltippen Sie nach links, um die Befehlspalette zu öffnen, um schnell auf Hosts zuzugreifen",
"enableTerminalSessionPersistence": "Dauerhafte Terminalsitzungen",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "SSH-Verbindungen beim Wechseln von Tabs oder Schließen des Browsers beibehalten (kann instabil sein)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Οι καθολικές ρυθμίσεις παρακολούθησης αποθηκεύτηκαν",
"failedToSaveGlobalSettings": "Αποτυχία αποθήκευσης καθολικών ρυθμίσεων παρακολούθησης",
"failedToLoadGlobalSettings": "Αποτυχία φόρτωσης καθολικών ρυθμίσεων παρακολούθησης",
"guacamoleIntegration": "Απομακρυσμένη Ενσωμάτωση Επιφάνειας Εργασίας (Guacamole)",
"guacamoleIntegrationDesc": "Ενεργοποίηση συνδέσεων RDP, VNC και Telnet μέσω guacd. Απαιτεί μια παρουσία guacd να εκτελείται.",
"enableGuacamole": "Ενεργοποίηση υποστήριξης RDP/VNC/Telnet",
"guacdUrl": "guacd URL (υπολογιστής:θύρα)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Οι αλλαγές στο διακομιστή guacd απαιτούν επανεκκίνηση του διακομιστή για να τεθούν σε ισχύ.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "προσαρμόστηκε σε έγκυρο εύρος",
"loadingSessions": "Φόρτωση συνεδριών...",
"noActiveSessions": "Δεν βρέθηκαν ενεργές συνεδρίες.",
"device": "Συσκευή",
@@ -866,11 +876,21 @@
"importError": "Σφάλμα εισαγωγής",
"failedToImportJson": "Αποτυχία εισαγωγής αρχείου JSON",
"connectionDetails": "Λεπτομέρειες Σύνδεσης",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Οργανισμός",
"ipAddress": "Διεύθυνση IP ή όνομα κεντρικού υπολογιστή",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Θύρα",
"name": "Όνομα",
"username": "Όνομα Χρήστη",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Φάκελος",
"tags": "Ετικέτες",
"pin": "Καρφίτσα",
@@ -979,6 +999,8 @@
"tunnel": "Σήραγγα",
"fileManager": "Διαχειριστής Αρχείων",
"serverStats": "Στατιστικά Διακομιστή",
"status": "Status",
"statistics": "Στατιστικά",
"hostViewer": "Προβολέας Υπολογιστή",
"enableServerStats": "Ενεργοποίηση Στατιστικών Διακομιστή",
"enableServerStatsDesc": "Ενεργοποίηση/απενεργοποίηση συλλογής στατιστικών του διακομιστή για αυτόν τον υπολογιστή",
@@ -1028,7 +1050,6 @@
"openFileManager": "Άνοιγμα Διαχειριστή Αρχείων",
"openTunnels": "Άνοιγμα Σηράγγων",
"openServerDetails": "Άνοιγμα Λεπτομερειών Διακομιστή",
"statistics": "Στατιστικά",
"enabledWidgets": "Ενεργοποιημένα Widgets",
"openServerStats": "Άνοιγμα Στατιστικών Διακομιστή",
"enabledWidgetsDesc": "Επιλέξτε ποια γραφικά στοιχεία θα εμφανίζονται για αυτόν τον υπολογιστή",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Ελέγξτε αν ο διακομιστής είναι συνδεδεμένος ή εκτός σύνδεσης",
"statusCheckInterval": "Διάστημα Ελέγχου Κατάστασης",
"statusCheckIntervalDesc": "Πόσο συχνά πρέπει να ελέγξετε αν ο οικοδεσπότης είναι σε απευθείας σύνδεση (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Χρήση καθολικής προεπιλογής",
"useGlobalMetricsInterval": "Χρήση καθολικής προεπιλογής",
"usingGlobalDefault": "Χρήση καθολικής προεπιλογής ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Ενεργοποίηση Παρακολούθησης Μετρήσεων",
"metricsEnabledDesc": "Συλλογή CPU, RAM, δίσκου και άλλων στατιστικών συστημάτων",
"metricsInterval": "Διάστημα Συλλογής Μετρήσεων",
"metricsIntervalDesc": "Πόσο συχνά συλλέγουν στατιστικά στοιχεία διακομιστή (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "δευτερόλεπτα",
"intervalMinutes": "λεπτά",
"intervalValidation": "Τα διαστήματα παρακολούθησης πρέπει να είναι μεταξύ 5 και 1 ώρα (3600 δευτερόλεπτα)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Αντιγραφή Διεύθυνσης Tunnel",
"copyServerStatsUrl": "Αντιγραφή Url Στατιστικών Διακομιστή",
"copyDockerUrl": "Αντιγραφή URL Προσάρτησης",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Αντιγράψτε το URL για να ανοίξετε αυτήν την εφαρμογή σε πλήρη οθόνη",
"notEnabled": "Το Docker δεν είναι ενεργοποιημένο για αυτόν τον υπολογιστή. Ενεργοποιήστε το στις ρυθμίσεις κεντρικού υπολογιστή για να χρησιμοποιήσετε τα χαρακτηριστικά Docker.",
"validating": "Επικύρωση Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Επιλογή όλων",
"deselectAll": "Αποεπιλογή όλων",
"useGlobalStatusDefault": "Χρήση Καθολικής Προεπιλογής (Κατάσταση)",
"useGlobalMetricsDefault": "Χρήση Καθολικής Προεπιλογής (Μετρήσεις)"
"useGlobalMetricsDefault": "Χρήση Καθολικής Προεπιλογής (Μετρήσεις)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Τερματικό",
@@ -1372,6 +1489,7 @@
"connected": "Συνδεδεμένο",
"clipboardWriteFailed": "Αποτυχία αντιγραφής στο πρόχειρο. Βεβαιωθείτε ότι η σελίδα εξυπηρετείται μέσω HTTPS ή localhost.",
"clipboardReadFailed": "Αποτυχία ανάγνωσης από το πρόχειρο. Βεβαιωθείτε ότι έχουν χορηγηθεί δικαιώματα πρόχειρου.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Η σύνδεση SSH δημιουργήθηκε",
"authError": "Η πιστοποίηση απέτυχε: {{message}}",
"unknownError": "Προέκυψε άγνωστο σφάλμα",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Αυτόματη επισήμανση εντολών, μονοπατιών, IP και επιπέδων καταγραφής στην έξοδο τερματικού",
"enableCommandPaletteShortcut": "Ενεργοποίηση Συντόμευσης Παλέτας Εντολών",
"enableCommandPaletteShortcutDesc": "Διπλό χτύπημα αριστερά Shift για άνοιγμα της παλέτας εντολών για γρήγορη πρόσβαση στους υπολογιστές",
"enableTerminalSessionPersistence": "Επίμονες Συνεδρίες Τερματικού",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Διατήρηση συνδέσεων SSH κατά την εναλλαγή καρτελών ή το κλείσιμο του προγράμματος περιήγησης (μπορεί να είναι ασταθές)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Ajustes globales de monitoreo guardados",
"failedToSaveGlobalSettings": "Error al guardar la configuración global de monitoreo",
"failedToLoadGlobalSettings": "Error al cargar la configuración global de monitoreo",
"guacamoleIntegration": "Integración de escritorio remoto (Guacamole)",
"guacamoleIntegrationDesc": "Habilitar conexiones RDP, VNC y Telnet vía guacd. Requiere que una instancia guacd esté ejecutándose.",
"enableGuacamole": "Habilitar soporte RDP/VNC/Telnet",
"guacdUrl": "URL guacd (host:puerto)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Los cambios al host/puerto de guacd requieren un reinicio del servidor para que surta efecto.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "se ajustó al rango válido",
"loadingSessions": "Cargando sesiones...",
"noActiveSessions": "No se encontraron sesiones activas.",
"device": "Dispositivo",
@@ -866,11 +876,21 @@
"importError": "Error al importar",
"failedToImportJson": "Error al importar el archivo JSON",
"connectionDetails": "Detalles de la conexión",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organización",
"ipAddress": "Dirección IP o nombre de host",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Puerto",
"name": "Nombre",
"username": "Usuario",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Carpeta",
"tags": "Etiquetas",
"pin": "Fijar",
@@ -979,6 +999,8 @@
"tunnel": "Túnel",
"fileManager": "Gestor de archivos",
"serverStats": "Estadísticas del Servidor",
"status": "Status",
"statistics": "Estadísticas",
"hostViewer": "Visor de host",
"enableServerStats": "Habilitar estadísticas del servidor",
"enableServerStatsDesc": "Activar/desactivar la recopilación de estadísticas del servidor para este host",
@@ -1028,7 +1050,6 @@
"openFileManager": "Abrir gestor de archivos",
"openTunnels": "Abrir túneles",
"openServerDetails": "Abrir detalles del servidor",
"statistics": "Estadísticas",
"enabledWidgets": "Widgets habilitados",
"openServerStats": "Abrir estadísticas del servidor",
"enabledWidgetsDesc": "Seleccione qué widgets de estadísticas mostrar para este host",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Comprobar si el servidor está conectado o fuera de línea",
"statusCheckInterval": "Intervalo de verificación de estado",
"statusCheckIntervalDesc": "Con qué frecuencia comprobar si el host está en línea (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Usar global por defecto",
"useGlobalMetricsInterval": "Usar global por defecto",
"usingGlobalDefault": "Uso global por defecto ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Habilitar monitoreo de métricas",
"metricsEnabledDesc": "Recoge CPU, RAM, disco y otras estadísticas del sistema",
"metricsInterval": "Intervalo de recolección de métricas",
"metricsIntervalDesc": "Con qué frecuencia recolectar estadísticas del servidor (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "segundos",
"intervalMinutes": "minutos",
"intervalValidation": "Los intervalos de monitoreo deben estar entre 5 segundos y 1 hora (3600 segundos)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copiar URL del túnel",
"copyServerStatsUrl": "Copiar URL de las estadísticas del servidor",
"copyDockerUrl": "Copiar URL de Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copiar URL para abrir esta aplicación en modo de pantalla completa",
"notEnabled": "Docker no está habilitado para este host. Actívalo en la configuración del host para usar las funciones de Docker.",
"validating": "Validando Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Seleccionar todo",
"deselectAll": "Deseleccionar todo",
"useGlobalStatusDefault": "Usar predeterminado global (Estado)",
"useGlobalMetricsDefault": "Usar predeterminado global (métricas)"
"useGlobalMetricsDefault": "Usar predeterminado global (métricas)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Conectado",
"clipboardWriteFailed": "No se pudo copiar al portapapeles. Asegúrese de que la página se sirve sobre HTTPS o localhost.",
"clipboardReadFailed": "Error al leer desde el portapapeles. Asegúrate de que los permisos del portapapeles estén garantizados.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Conexión SSH establecida",
"authError": "Autenticación fallida: {{message}}",
"unknownError": "Ocurrió un error desconocido",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Destacar automáticamente comandos, rutas, direcciones IP y niveles de registro en la salida del terminal",
"enableCommandPaletteShortcut": "Habilitar acceso directo a la paleta de comandos",
"enableCommandPaletteShortcutDesc": "Toque dos veces a la izquierda para abrir la paleta de comandos para acceder rápidamente a los hosts",
"enableTerminalSessionPersistence": "Sesiones de Terminal persistentes",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Mantener conexiones SSH al cambiar pestañas o cerrar el navegador (puede ser inestable)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Yleiset seurantaasetukset tallennettu",
"failedToSaveGlobalSettings": "Yleisten seuranta-asetusten tallentaminen epäonnistui",
"failedToLoadGlobalSettings": "Globaalien valvontaasetusten lataaminen epäonnistui",
"guacamoleIntegration": "Etätyöpöydän Integraatio (Guacamole)",
"guacamoleIntegrationDesc": "Ota käyttöön RDP, VNC ja Telnet-yhteydet guacdilla. Vaatii guacd-ilmentymän käynnissä olevaksi.",
"enableGuacamole": "Ota käyttöön RD- NC/Telnet- tuki",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Muutokset guacd isäntä/portti vaativat palvelimen uudelleenkäynnistyksen voimaan.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "oli mukautettu kelvolliseen alueeseen",
"loadingSessions": "Ladataan istuntoja...",
"noActiveSessions": "Aktiivisia istuntoja ei löytynyt.",
"device": "Laite",
@@ -866,11 +876,21 @@
"importError": "Tuontivirhe",
"failedToImportJson": "JSON-tiedoston tuonti epäonnistui",
"connectionDetails": "Yhteyden Tiedot",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisaatio",
"ipAddress": "IP-osoite tai isäntänimi",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Portti",
"name": "Nimi",
"username": "Käyttäjätunnus",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Kansio",
"tags": "Tunnisteet",
"pin": "Kiinnitä",
@@ -979,6 +999,8 @@
"tunnel": "Tunneli",
"fileManager": "Tiedostojen Hallinta",
"serverStats": "Palvelimen Tilastot",
"status": "Status",
"statistics": "Tilastot",
"hostViewer": "Isäntäkatseluohjelma",
"enableServerStats": "Ota käyttöön palvelimen tilastot",
"enableServerStatsDesc": "Ota käyttöön/poista käytöstä palvelimen tilastotietojen kerääminen tälle isännälle",
@@ -1028,7 +1050,6 @@
"openFileManager": "Avaa tiedostonhallinta",
"openTunnels": "Avoimet tunnelit",
"openServerDetails": "Avaa palvelimen tiedot",
"statistics": "Tilastot",
"enabledWidgets": "Käytössä olevat widgetit",
"openServerStats": "Avaa palvelimen tilastot",
"enabledWidgetsDesc": "Valitse tälle isännälle näytettävät tilastowidgetit",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Tarkista, onko palvelin online-tilassa vai offline-tilassa",
"statusCheckInterval": "Tilan tarkistusväli",
"statusCheckIntervalDesc": "Kuinka usein tarkistaa, onko isäntä verkossa (5 s - 1 h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Käytä yleistä oletusta",
"useGlobalMetricsInterval": "Käytä yleistä oletusta",
"usingGlobalDefault": "Käytetään yleistä oletusta ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Ota käyttöön mittareiden seuranta",
"metricsEnabledDesc": "Kerää prosessorin, RAMin, levyn ja muiden järjestelmätilastojen tiedot",
"metricsInterval": "Mittarien keräysväli",
"metricsIntervalDesc": "Palvelintilastojen keräämisen tiheys (5 s - 1 h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekuntia",
"intervalMinutes": "minuuttia",
"intervalValidation": "Seurantavälien on oltava 5 sekunnista 1 tuntiin (3600 sekuntia).",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopioi Tunnelin URL",
"copyServerStatsUrl": "Kopioi Palvelimen Tilastot Url",
"copyDockerUrl": "Kopioi Docker URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Kopioi URL-osoite avataksesi tämän sovelluksen koko näytön tilassa",
"notEnabled": "Docker ei ole käytössä tässä isännässä. Ota se käyttöön isännän asetuksissa käyttääksesi Dockerin ominaisuuksia.",
"validating": "Dockerin validointi...",
@@ -1348,7 +1375,97 @@
"selectAll": "Valitse kaikki",
"deselectAll": "Poista kaikki valinnat",
"useGlobalStatusDefault": "Käytä Globaalia Oletusta (Tila)",
"useGlobalMetricsDefault": "Käytä Globaaleja Oletuksia (Metrics)"
"useGlobalMetricsDefault": "Käytä Globaaleja Oletuksia (Metrics)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Pääte",
@@ -1372,6 +1489,7 @@
"connected": "Yhdistetty",
"clipboardWriteFailed": "Kopiointi leikepöydälle epäonnistui. Varmista, että sivu on tarjolla HTTPS:n tai localhostin kautta.",
"clipboardReadFailed": "Leikepöydältä ei voitu lukea. Varmista, että leikepöydän oikeudet on myönnetty.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-yhteys muodostettu",
"authError": "Todennus epäonnistui: {{message}}",
"unknownError": "Tuntematon virhe tapahtui",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Korosta automaattisesti komennot, polut, IP-osoitteet ja lokitasot päätetulosteessa",
"enableCommandPaletteShortcut": "Ota Käyttöön Komentopaletin Pikakuvake",
"enableCommandPaletteShortcutDesc": "Kaksoisnapauta vasen Shift avataksesi komentopaletin saadaksesi nopean pääsyn isäntiin",
"enableTerminalSessionPersistence": "Pysyvät Pääteistunnot",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Säilytä SSH yhteydet kun välilehtiä vaihdetaan tai selain suljetaan (voi olla epävakaa)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Paramètres de surveillance globale enregistrés",
"failedToSaveGlobalSettings": "Impossible d'enregistrer les paramètres de surveillance globale",
"failedToLoadGlobalSettings": "Impossible de charger les paramètres de surveillance globale",
"guacamoleIntegration": "Intégration du bureau distant (Guacamole)",
"guacamoleIntegrationDesc": "Activer les connexions RDP, VNC et Telnet via guacd. Nécessite une instance guacd pour être en cours d'exécution.",
"enableGuacamole": "Activer le support RDP/VNC/Telnet",
"guacdUrl": "URL guacd (hôte:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Les modifications apportées à l'hôte/port guacd nécessitent un redémarrage du serveur pour prendre effet.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "a été ajusté à une plage valide",
"loadingSessions": "Chargement des sessions...",
"noActiveSessions": "Aucune session active trouvée.",
"device": "Appareil",
@@ -866,11 +876,21 @@
"importError": "Erreur d'importation",
"failedToImportJson": "Impossible d'importer le fichier JSON",
"connectionDetails": "Détails de la connexion",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisation",
"ipAddress": "Adresse IP ou nom d'hôte",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Nom",
"username": "Nom d'utilisateur",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Répertoire",
"tags": "Tags",
"pin": "Épingler",
@@ -979,6 +999,8 @@
"tunnel": "Tunnel",
"fileManager": "Gestionnaire de fichiers",
"serverStats": "Statistiques du serveur",
"status": "Status",
"statistics": "Statistiques",
"hostViewer": "Visionneuse Hôte",
"enableServerStats": "Activer les statistiques du serveur",
"enableServerStatsDesc": "Activer/désactiver la collecte des statistiques du serveur pour cet hôte",
@@ -1028,7 +1050,6 @@
"openFileManager": "Ouvrir le gestionnaire de fichiers",
"openTunnels": "Tunnels ouverts",
"openServerDetails": "Détails de l'Open Server",
"statistics": "Statistiques",
"enabledWidgets": "Widgets activés",
"openServerStats": "Statistiques du serveur ouvert",
"enabledWidgetsDesc": "Sélectionnez les widgets de statistiques à afficher pour cet hôte",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Vérifier si le serveur est en ligne ou hors ligne",
"statusCheckInterval": "Intervalle de vérification de l'état",
"statusCheckIntervalDesc": "À quelle fréquence vérifier si l'hôte est en ligne (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Utiliser la valeur par défaut globale",
"useGlobalMetricsInterval": "Utiliser la valeur par défaut globale",
"usingGlobalDefault": "Utiliser la valeur globale par défaut ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Activer la surveillance des métriques",
"metricsEnabledDesc": "Collecter des statistiques CPU, RAM, disque et autres systèmes",
"metricsInterval": "Intervalle de collecte des métriques",
"metricsIntervalDesc": "Fréquence de collecte des statistiques du serveur (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "secondes",
"intervalMinutes": "minutes",
"intervalValidation": "Les intervalles de surveillance doivent être compris entre 5 secondes et 1 heure (3600 secondes)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copier l'URL du tunnel",
"copyServerStatsUrl": "Copier l'URL des statistiques du serveur",
"copyDockerUrl": "Copier l'URL de Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copier l'URL pour ouvrir cette application en mode plein écran",
"notEnabled": "Docker n'est pas activé pour cet hôte. Activez-le dans les paramètres de l'hôte pour utiliser les fonctionnalités Docker.",
"validating": "Validation de Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Tout sélectionner",
"deselectAll": "Désélectionner tout",
"useGlobalStatusDefault": "Utiliser la valeur globale par défaut (Status)",
"useGlobalMetricsDefault": "Utiliser la valeur globale par défaut (métriques)"
"useGlobalMetricsDefault": "Utiliser la valeur globale par défaut (métriques)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Connecté",
"clipboardWriteFailed": "Échec de la copie dans le presse-papiers. Assurez-vous que la page est servie via HTTPS ou localhost.",
"clipboardReadFailed": "Échec de lecture du presse-papiers. Assurez-vous que les permissions du presse-papiers sont accordées.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Connexion SSH établie",
"authError": "Échec de l'authentification : {{message}}",
"unknownError": "Une erreur inconnue s'est produite",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Mettre automatiquement en surbrillance les commandes, chemins, IPs et niveaux de log dans la sortie du terminal",
"enableCommandPaletteShortcut": "Activer le raccourci de la palette de commandes",
"enableCommandPaletteShortcutDesc": "Tapotez deux fois vers la gauche pour ouvrir la palette de commandes pour un accès rapide aux hôtes",
"enableTerminalSessionPersistence": "Sessions terminales persistantes",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Maintenir les connexions SSH lors du changement d'onglets ou de la fermeture du navigateur (peut être instable)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "הגדרות ניטור גלובליות נשמרו",
"failedToSaveGlobalSettings": "נכשלה שמירת הגדרות הניטור הגלובליות",
"failedToLoadGlobalSettings": "נכשלה טעינת הגדרות הניטור הגלובליות",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "טוען סשנים...",
"noActiveSessions": "לא נמצאו סשנים פעילים.",
"device": "הֶתקֵן",
@@ -866,11 +876,21 @@
"importError": "שגיאת ייבוא",
"failedToImportJson": "ייבוא קובץ JSON נכשל",
"connectionDetails": "פרטי חיבור",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "אִרגוּן",
"ipAddress": "כתובת IP או שם מארח",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "נָמָל",
"name": "שֵׁם",
"username": "שם משתמש",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "תיקייה",
"tags": "תגיות",
"pin": "פִּין",
@@ -979,6 +999,8 @@
"tunnel": "מִנהָרָה",
"fileManager": "מנהל הקבצים",
"serverStats": "סטטיסטיקות שרת",
"status": "Status",
"statistics": "סטָטִיסטִיקָה",
"hostViewer": "צופה מארח",
"enableServerStats": "הפעל סטטיסטיקות שרת",
"enableServerStatsDesc": "הפעלה/השבתה של איסוף סטטיסטיקות שרת עבור מארח זה",
@@ -1028,7 +1050,6 @@
"openFileManager": "פתח את מנהל הקבצים",
"openTunnels": "מנהרות פתוחות",
"openServerDetails": "פתיחת פרטי שרת",
"statistics": "סטָטִיסטִיקָה",
"enabledWidgets": "ווידג'טים מופעלים",
"openServerStats": "סטטיסטיקות שרת פתוחות",
"enabledWidgetsDesc": "בחר אילו ווידג'טים של סטטיסטיקות להציג עבור מארח זה",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "בדוק אם השרת מחובר או לא מחובר",
"statusCheckInterval": "מרווח זמן לבדיקת סטטוס",
"statusCheckIntervalDesc": "באיזו תדירות לבדוק אם המארח מחובר (5 שניות - שעה)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "השתמש בברירת מחדל גלובלית",
"useGlobalMetricsInterval": "השתמש בברירת מחדל גלובלית",
"usingGlobalDefault": "שימוש בברירת מחדל גלובלית ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "הפעל ניטור מדדים",
"metricsEnabledDesc": "איסוף סטטיסטיקות של מעבד, זיכרון RAM, דיסק ונתונים סטטיסטיים אחרים של המערכת",
"metricsInterval": "מרווח איסוף מדדים",
"metricsIntervalDesc": "באיזו תדירות לאסוף סטטיסטיקות שרת (5 שניות - שעה)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "שניות",
"intervalMinutes": "פּרוֹטוֹקוֹל",
"intervalValidation": "מרווחי הניטור חייבים להיות בין 5 שניות לשעה (3600 שניות)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "העתקת כתובת URL של המנהרה",
"copyServerStatsUrl": "העתקת כתובת URL של סטטיסטיקות שרת",
"copyDockerUrl": "העתקת כתובת URL של Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "העתק כתובת URL כדי לפתוח אפליקציה זו במצב מסך מלא",
"notEnabled": "Docker אינו מופעל עבור מארח זה. הפעל אותו בהגדרות המארח כדי להשתמש בתכונות Docker.",
"validating": "מאמת את Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "בחר הכל",
"deselectAll": "בטל את הבחירה של הכל",
"useGlobalStatusDefault": "השתמש בברירת מחדל גלובלית (סטטוס)",
"useGlobalMetricsDefault": "השתמש בברירת מחדל גלובלית (מדדים)"
"useGlobalMetricsDefault": "השתמש בברירת מחדל גלובלית (מדדים)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "מָסוֹף",
@@ -1372,6 +1489,7 @@
"connected": "מְחוּבָּר",
"clipboardWriteFailed": "ההעתקה ללוח נכשלה. ודא שהדף מוגש דרך HTTPS או localhost.",
"clipboardReadFailed": "הקריאה מהלוח נכשלה. ודא שהרשאות הלוח ניתנות.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "נוצר חיבור SSH",
"authError": "האימות נכשל: {{message}}",
"unknownError": "אירעה שגיאה לא ידועה",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "סמן אוטומטית פקודות, נתיבים, כתובות IP ורמות יומן בפלט הטרמינל",
"enableCommandPaletteShortcut": "הפעל קיצור דרך של לוח הפקודות",
"enableCommandPaletteShortcutDesc": "הקש פעמיים על Shift שמאלי כדי לפתוח את לוח הפקודות לגישה מהירה למארחים",
"enableTerminalSessionPersistence": "הפעלות טרמינל מתמשכות",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "שמרו על חיבורי SSH בעת מעבר בין כרטיסיות או סגירת הדפדפן (ייתכן שזה לא יציב)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "वैश्विक निगरानी सेटिंग्स सहेजी गईं",
"failedToSaveGlobalSettings": "वैश्विक निगरानी सेटिंग्स को सहेजने में विफल।",
"failedToLoadGlobalSettings": "वैश्विक निगरानी सेटिंग्स लोड करने में विफल",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "सेशन लोड हो रहे हैं...",
"noActiveSessions": "कोई सक्रिय सत्र नहीं मिला।",
"device": "उपकरण",
@@ -866,11 +876,21 @@
"importError": "आयात त्रुटि",
"failedToImportJson": "JSON फ़ाइल आयात करने में विफल",
"connectionDetails": "कनेक्शन विवरण",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "संगठन",
"ipAddress": "आईपी पता या होस्टनाम",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "पत्तन",
"name": "नाम",
"username": "उपयोगकर्ता नाम",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "फ़ोल्डर",
"tags": "टैग",
"pin": "नत्थी करना",
@@ -979,6 +999,8 @@
"tunnel": "सुरंग",
"fileManager": "फ़ाइल मैनेजर",
"serverStats": "सर्वर आँकड़े",
"status": "Status",
"statistics": "आंकड़े",
"hostViewer": "मेज़बान दर्शक",
"enableServerStats": "सर्वर सांख्यिकी सक्षम करें",
"enableServerStatsDesc": "इस होस्ट के लिए सर्वर सांख्यिकी संग्रह को सक्षम/अक्षम करें",
@@ -1028,7 +1050,6 @@
"openFileManager": "फ़ाइल प्रबंधक खोलें",
"openTunnels": "खुली सुरंगें",
"openServerDetails": "सर्वर विवरण खोलें",
"statistics": "आंकड़े",
"enabledWidgets": "सक्षम विजेट",
"openServerStats": "ओपन सर्वर आँकड़े",
"enabledWidgetsDesc": "इस होस्ट के लिए कौन से सांख्यिकी विजेट प्रदर्शित करने हैं, यह चुनें।",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "जांचें कि सर्वर ऑनलाइन है या ऑफलाइन।",
"statusCheckInterval": "स्थिति जांच अंतराल",
"statusCheckIntervalDesc": "होस्ट ऑनलाइन है या नहीं, यह कितनी बार जांचना चाहिए (5 सेकंड - 1 घंटा)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "वैश्विक डिफ़ॉल्ट का उपयोग करें",
"useGlobalMetricsInterval": "वैश्विक डिफ़ॉल्ट का उपयोग करें",
"usingGlobalDefault": "वैश्विक डिफ़ॉल्ट का उपयोग करना ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "मैट्रिक्स मॉनिटरिंग सक्षम करें",
"metricsEnabledDesc": "सीपीयू, रैम, डिस्क और अन्य सिस्टम सांख्यिकी एकत्र करें",
"metricsInterval": "मैट्रिक्स संग्रह अंतराल",
"metricsIntervalDesc": "सर्वर सांख्यिकी को कितनी बार एकत्र करना है (5 सेकंड - 1 घंटा)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "सेकंड",
"intervalMinutes": "मिनट",
"intervalValidation": "निगरानी अंतराल 5 सेकंड और 1 घंटे (3600 सेकंड) के बीच होना चाहिए।",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "टनल यूआरएल कॉपी करें",
"copyServerStatsUrl": "सर्वर सांख्यिकी यूआरएल कॉपी करें",
"copyDockerUrl": "डॉकर यूआरएल कॉपी करें",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "इस ऐप को फुल-स्क्रीन मोड में खोलने के लिए URL कॉपी करें",
"notEnabled": "इस होस्ट के लिए डॉकर सक्षम नहीं है। डॉकर सुविधाओं का उपयोग करने के लिए इसे होस्ट सेटिंग्स में सक्षम करें।",
"validating": "डॉकर का सत्यापन किया जा रहा है...",
@@ -1348,7 +1375,97 @@
"selectAll": "सबका चयन करें",
"deselectAll": "सबको अचयनित करो",
"useGlobalStatusDefault": "वैश्विक डिफ़ॉल्ट (स्थिति) का उपयोग करें",
"useGlobalMetricsDefault": "वैश्विक डिफ़ॉल्ट (मैट्रिक्स) का उपयोग करें"
"useGlobalMetricsDefault": "वैश्विक डिफ़ॉल्ट (मैट्रिक्स) का उपयोग करें",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "टर्मिनल",
@@ -1372,6 +1489,7 @@
"connected": "जुड़े हुए",
"clipboardWriteFailed": "क्लिपबोर्ड पर कॉपी करने में विफल। सुनिश्चित करें कि पृष्ठ HTTPS या लोकलहोस्ट पर चल रहा है।",
"clipboardReadFailed": "क्लिपबोर्ड से पढ़ने में विफलता। सुनिश्चित करें कि क्लिपबोर्ड की अनुमतियाँ दी गई हैं।",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH कनेक्शन स्थापित हो गया",
"authError": "प्रमाणीकरण विफल: {{message}}",
"unknownError": "अज्ञात त्रुटि उत्पन्न हुई",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "टर्मिनल आउटपुट में कमांड, पाथ, आईपी और लॉग लेवल को स्वचालित रूप से हाइलाइट करें",
"enableCommandPaletteShortcut": "कमांड पैलेट शॉर्टकट सक्षम करें",
"enableCommandPaletteShortcutDesc": "होस्ट तक त्वरित पहुंच के लिए कमांड पैलेट खोलने के लिए बाएं Shift को दो बार टैप करें।",
"enableTerminalSessionPersistence": "निरंतर टर्मिनल सत्र",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "टैब बदलते समय या ब्राउज़र बंद करते समय SSH कनेक्शन बनाए रखें (यह अस्थिर हो सकता है)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globális monitorozási beállítások mentve",
"failedToSaveGlobalSettings": "Nem sikerült menteni a globális megfigyelési beállításokat",
"failedToLoadGlobalSettings": "Nem sikerült betölteni a globális megfigyelési beállításokat",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Munkamenetek betöltése...",
"noActiveSessions": "Nincsenek aktív munkamenetek.",
"device": "Eszköz",
@@ -866,11 +876,21 @@
"importError": "Importálási hiba",
"failedToImportJson": "Nem sikerült importálni a JSON fájlt",
"connectionDetails": "Kapcsolat részletei",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Szervezet",
"ipAddress": "IP-cím vagy hostnév",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Kikötő",
"name": "Név",
"username": "Felhasználónév",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Mappa",
"tags": "Címkék",
"pin": "Pin",
@@ -979,6 +999,8 @@
"tunnel": "Alagút",
"fileManager": "Fájlkezelő",
"serverStats": "Szerver statisztikák",
"status": "Status",
"statistics": "Statisztika",
"hostViewer": "Gazdagép-megjelenítő",
"enableServerStats": "Szerverstatisztikák engedélyezése",
"enableServerStatsDesc": "Szerverstatisztikák gyűjtésének engedélyezése/letiltása ehhez a gazdagéphez",
@@ -1028,7 +1050,6 @@
"openFileManager": "Fájlkezelő megnyitása",
"openTunnels": "Nyílt alagutak",
"openServerDetails": "Nyissa meg a szerver részleteit",
"statistics": "Statisztika",
"enabledWidgets": "Engedélyezett widgetek",
"openServerStats": "Szerver statisztikák megnyitása",
"enabledWidgetsDesc": "Válassza ki, hogy mely statisztikai widgeteket jelenítse meg ehhez a gazdagéphez",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Ellenőrizd, hogy a szerver online vagy offline állapotban van-e",
"statusCheckInterval": "Állapotellenőrzési intervallum",
"statusCheckIntervalDesc": "Milyen gyakran kell ellenőrizni, hogy a host online van-e (5 másodperc - 1 óra)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Globális alapértelmezett érték használata",
"useGlobalMetricsInterval": "Globális alapértelmezett érték használata",
"usingGlobalDefault": "Globális alapértelmezett érték használata ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Metrikák monitorozásának engedélyezése",
"metricsEnabledDesc": "CPU-, RAM-, lemez- és egyéb rendszerstatisztikák gyűjtése",
"metricsInterval": "Metrikagyűjtési intervallum",
"metricsIntervalDesc": "Milyen gyakran gyűjtsünk szerverstatisztikákat (5 másodperc - 1 óra)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "másodperc",
"intervalMinutes": "jegyzőkönyv",
"intervalValidation": "A monitorozási időközöknek 5 másodperc és 1 óra (3600 másodperc) között kell lenniük.",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Alagút URL-címének másolása",
"copyServerStatsUrl": "Szerverstatisztikák URL-címének másolása",
"copyDockerUrl": "Docker URL másolása",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "URL másolása az alkalmazás teljes képernyős módban történő megnyitásához",
"notEnabled": "A Docker nincs engedélyezve ehhez a gazdagéphez. Engedélyezze a Gazdagép beállításaiban a Docker funkcióinak használatához.",
"validating": "Docker érvényesítése...",
@@ -1348,7 +1375,97 @@
"selectAll": "Összes kijelölése",
"deselectAll": "Összes kijelölés törlése",
"useGlobalStatusDefault": "Globális alapértelmezett érték használata (Állapot)",
"useGlobalMetricsDefault": "Globális alapértelmezett érték használata (metrikák)"
"useGlobalMetricsDefault": "Globális alapértelmezett érték használata (metrikák)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminál",
@@ -1372,6 +1489,7 @@
"connected": "Csatlakoztatva",
"clipboardWriteFailed": "Nem sikerült a vágólapra másolni. Győződjön meg arról, hogy az oldal HTTPS vagy localhost protokollon keresztül jelenik meg.",
"clipboardReadFailed": "Nem sikerült beolvasni a vágólapról. Győződjön meg arról, hogy a vágólapra vonatkozó engedélyek meg vannak adva.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-kapcsolat létrejött",
"authError": "Hitelesítés sikertelen: {{message}}",
"unknownError": "Ismeretlen hiba történt",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Parancsok, elérési utak, IP-címek és naplózási szintek automatikus kiemelése a terminál kimenetében",
"enableCommandPaletteShortcut": "Parancspaletta billentyűparancsának engedélyezése",
"enableCommandPaletteShortcutDesc": "Koppintson duplán a bal Shift billentyűre a Parancspaletta megnyitásához, amelyen gyorsan elérheti a gazdagépeket.",
"enableTerminalSessionPersistence": "Állandó terminál munkamenetek",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "SSH-kapcsolatok fenntartása lapváltáskor vagy böngésző bezárásakor (instabil lehet)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Pengaturan pemantauan global tersimpan",
"failedToSaveGlobalSettings": "Gagal menyimpan pengaturan pemantauan global.",
"failedToLoadGlobalSettings": "Gagal memuat pengaturan pemantauan global.",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Memuat sesi...",
"noActiveSessions": "Tidak ditemukan sesi aktif.",
"device": "Perangkat",
@@ -866,11 +876,21 @@
"importError": "Kesalahan impor",
"failedToImportJson": "Gagal mengimpor file JSON",
"connectionDetails": "Detail Koneksi",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisasi",
"ipAddress": "Alamat IP atau Nama Host",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Pelabuhan",
"name": "Nama",
"username": "Nama belakang",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Map",
"tags": "Tag",
"pin": "Pin",
@@ -979,6 +999,8 @@
"tunnel": "Terowongan",
"fileManager": "Pengelola File",
"serverStats": "Statistik Server",
"status": "Status",
"statistics": "Statistik",
"hostViewer": "Pemirsa Pembawa Acara",
"enableServerStats": "Aktifkan Statistik Server",
"enableServerStatsDesc": "Aktifkan/nonaktifkan pengumpulan statistik server untuk host ini.",
@@ -1028,7 +1050,6 @@
"openFileManager": "Buka Pengelola File",
"openTunnels": "Terowongan Terbuka",
"openServerDetails": "Buka Detail Server",
"statistics": "Statistik",
"enabledWidgets": "Widget yang Diaktifkan",
"openServerStats": "Statistik Server Terbuka",
"enabledWidgetsDesc": "Pilih widget statistik mana yang akan ditampilkan untuk host ini.",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Periksa apakah server sedang online atau offline.",
"statusCheckInterval": "Interval Pemeriksaan Status",
"statusCheckIntervalDesc": "Seberapa sering memeriksa apakah host sedang online (5 detik - 1 jam)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Gunakan pengaturan default global.",
"useGlobalMetricsInterval": "Gunakan pengaturan default global.",
"usingGlobalDefault": "Menggunakan default global ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Aktifkan Pemantauan Metrik",
"metricsEnabledDesc": "Kumpulkan statistik CPU, RAM, disk, dan sistem lainnya.",
"metricsInterval": "Interval Pengumpulan Metrik",
"metricsIntervalDesc": "Seberapa sering mengumpulkan statistik server (5 detik - 1 jam)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "detik",
"intervalMinutes": "menit",
"intervalValidation": "Interval pemantauan harus antara 5 detik dan 1 jam (3600 detik).",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Salin URL Terowongan",
"copyServerStatsUrl": "Salin URL Statistik Server",
"copyDockerUrl": "Salin URL Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Salin URL untuk membuka aplikasi ini dalam mode layar penuh.",
"notEnabled": "Docker belum diaktifkan untuk host ini. Aktifkan di Pengaturan Host untuk menggunakan fitur Docker.",
"validating": "Memvalidasi Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Pilih semua",
"deselectAll": "Batalkan pilihan semua",
"useGlobalStatusDefault": "Gunakan Pengaturan Default Global (Status)",
"useGlobalMetricsDefault": "Gunakan Pengaturan Default Global (Metrik)"
"useGlobalMetricsDefault": "Gunakan Pengaturan Default Global (Metrik)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Terhubung",
"clipboardWriteFailed": "Gagal menyalin ke papan klip. Pastikan halaman disajikan melalui HTTPS atau localhost.",
"clipboardReadFailed": "Gagal membaca dari clipboard. Pastikan izin clipboard telah diberikan.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Koneksi SSH berhasil dibuat.",
"authError": "Autentikasi gagal: {{message}}",
"unknownError": "Terjadi kesalahan yang tidak diketahui.",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Secara otomatis menyorot perintah, jalur, IP, dan level log pada output terminal.",
"enableCommandPaletteShortcut": "Aktifkan Pintasan Palet Perintah",
"enableCommandPaletteShortcutDesc": "Tekan Shift kiri dua kali untuk membuka Palet Perintah guna akses cepat ke host.",
"enableTerminalSessionPersistence": "Sesi Terminal Permanen",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Pertahankan koneksi SSH saat beralih tab atau menutup browser (mungkin tidak stabil)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Impostazioni di monitoraggio globali salvate",
"failedToSaveGlobalSettings": "Impossibile salvare le impostazioni di monitoraggio globale",
"failedToLoadGlobalSettings": "Impossibile caricare le impostazioni di monitoraggio globale",
"guacamoleIntegration": "Integrazione Desktop Remoto (Guacamole)",
"guacamoleIntegrationDesc": "Abilita connessioni RDP, VNC e Telnet tramite guacd. Richiede un'istanza guacd per essere in esecuzione.",
"enableGuacamole": "Abilita supporto RDP/VNC/Telnet",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Le modifiche all'host/porta guacd richiedono che il riavvio del server abbia effetto.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "è stato adattato all'intervallo valido",
"loadingSessions": "Caricamento sessioni...",
"noActiveSessions": "Nessuna sessione attiva trovata.",
"device": "Dispositivo",
@@ -866,11 +876,21 @@
"importError": "Errore di importazione",
"failedToImportJson": "Importazione del file JSON non riuscita",
"connectionDetails": "Dettagli Della Connessione",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organizzazione",
"ipAddress": "Indirizzo IP o nome host",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Porta",
"name": "Nome",
"username": "Username",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Cartella",
"tags": "Etichette",
"pin": "Pin",
@@ -979,6 +999,8 @@
"tunnel": "Tunnel",
"fileManager": "Gestore File",
"serverStats": "Statistiche Server",
"status": "Status",
"statistics": "Statistiche",
"hostViewer": "Visualizzatore Host",
"enableServerStats": "Abilita Statistiche Server",
"enableServerStatsDesc": "Abilita/disabilita la raccolta di statistiche server per questo host",
@@ -1028,7 +1050,6 @@
"openFileManager": "Apri File Manager",
"openTunnels": "Gallerie Aperte",
"openServerDetails": "Apri Dettagli Server",
"statistics": "Statistiche",
"enabledWidgets": "Widget Abilitati",
"openServerStats": "Apri Statistiche Server",
"enabledWidgetsDesc": "Seleziona quali widget statistiche mostrare per questo host",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Controlla se il server è online o offline",
"statusCheckInterval": "Intervallo Controllo Stato",
"statusCheckIntervalDesc": "Quanto spesso controllare se l'host è online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Usa impostazione predefinita globale",
"useGlobalMetricsInterval": "Usa impostazione predefinita globale",
"usingGlobalDefault": "Utilizzo di default globale ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Abilita Monitoraggio Metriche",
"metricsEnabledDesc": "Raccogliere le statistiche CPU, RAM, disco e altre statistiche di sistema",
"metricsInterval": "Intervallo Di Raccolta Metriche",
"metricsIntervalDesc": "Quanto spesso raccogliere statistiche del server (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "secondi",
"intervalMinutes": "minuti",
"intervalValidation": "Gli intervalli di monitoraggio devono essere compresi tra 5 secondi e 1 ora (3600 secondi)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copia URL Tunnel",
"copyServerStatsUrl": "Copia Url Statistiche Server",
"copyDockerUrl": "Copia URL Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copia URL per aprire questa app in modalità a schermo intero",
"notEnabled": "Docker non è abilitato per questo host. Abilitarlo nelle impostazioni Host per utilizzare le funzioni Docker.",
"validating": "Convalida Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Seleziona tutto",
"deselectAll": "Deseleziona tutto",
"useGlobalStatusDefault": "Usa Global Default (Status)",
"useGlobalMetricsDefault": "Usa Globale Predefinito (Metrice)"
"useGlobalMetricsDefault": "Usa Globale Predefinito (Metrice)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminale",
@@ -1372,6 +1489,7 @@
"connected": "Connesso",
"clipboardWriteFailed": "Impossibile copiare negli appunti. Assicurarsi che la pagina sia servita su HTTPS o localhost.",
"clipboardReadFailed": "Lettura dagli appunti non riuscita. Assicurarsi che i permessi degli appunti siano concessi.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Connessione SSH stabilita",
"authError": "Autenticazione non riuscita: {{message}}",
"unknownError": "Errore sconosciuto",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Evidenzia automaticamente comandi, tracciati, IP e livelli di log nell'output del terminale",
"enableCommandPaletteShortcut": "Abilita Scorciatoia Tavolozza Comandi",
"enableCommandPaletteShortcutDesc": "Doppio tocco a sinistra Maiusc per aprire la Tavolozza dei comandi per un rapido accesso agli host",
"enableTerminalSessionPersistence": "Sessioni Terminali Persistenti",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Mantenere le connessioni SSH quando si cambiano schede o si chiude il browser (potrebbe essere instabile)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "グローバル監視設定を保存しました",
"failedToSaveGlobalSettings": "グローバル監視設定の保存に失敗しました",
"failedToLoadGlobalSettings": "グローバル監視設定の読み込みに失敗しました",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Guacd 経由で RDP、VNC、および Telnet 接続を有効にします。実行するには guacd インスタンスが必要です。",
"enableGuacamole": "RDP/VNC/Telnet のサポートを有効にする",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "guacd ホスト/ポートへの変更を有効にするにはサーバーの再起動が必要です。",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "有効な範囲に調整されました",
"loadingSessions": "セッションを読み込み中...",
"noActiveSessions": "アクティブなセッションが見つかりませんでした。",
"device": "デバイス",
@@ -866,11 +876,21 @@
"importError": "インポートエラー",
"failedToImportJson": "JSON ファイルのインポートに失敗しました",
"connectionDetails": "接続詳細",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "組織",
"ipAddress": "IPアドレスまたはホスト名",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "ポート",
"name": "名前",
"username": "ユーザー名",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "フォルダ",
"tags": "タグ",
"pin": "ピン留めする",
@@ -979,6 +999,8 @@
"tunnel": "トンネル",
"fileManager": "ファイルマネージャー",
"serverStats": "サーバーの統計",
"status": "Status",
"statistics": "統計情報",
"hostViewer": "ホストビューアー",
"enableServerStats": "サーバー統計を有効にする",
"enableServerStatsDesc": "このホストのサーバ統計情報収集を有効/無効にする",
@@ -1028,7 +1050,6 @@
"openFileManager": "ファイルマネージャを開く",
"openTunnels": "トンネルを開く",
"openServerDetails": "サーバーの詳細を開く",
"statistics": "統計情報",
"enabledWidgets": "有効なウィジェット",
"openServerStats": "サーバー統計を開く",
"enabledWidgetsDesc": "このホストに表示する統計ウィジェットを選択してください",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "サーバーがオンラインかオフラインかを確認する",
"statusCheckInterval": "ステータスチェックの間隔",
"statusCheckIntervalDesc": "ホストがオンラインかどうかを確認する頻度(5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "グローバルデフォルトを使用",
"useGlobalMetricsInterval": "グローバルデフォルトを使用",
"usingGlobalDefault": "グローバルデフォルト ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "メトリックモニタリングを有効にする",
"metricsEnabledDesc": "CPU、RAM、ディスク、その他のシステム統計を収集する",
"metricsInterval": "メトリックコレクションの間隔",
"metricsIntervalDesc": "サーバーの統計情報を収集する頻度(5秒~1時間)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "秒",
"intervalMinutes": "分",
"intervalValidation": "モニタリング間隔は5秒から1時間(3600秒)の間でなければなりません",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "トンネルURLをコピー",
"copyServerStatsUrl": "サーバー統計の URL をコピー",
"copyDockerUrl": "Docker URL をコピー",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "URLをコピーしてフルスクリーンモードでこのアプリを開く",
"notEnabled": "Docker はこのホストでは有効になっていません。format@@0で有効にして、Docker 機能を使用します。",
"validating": "Dockerを検証中...",
@@ -1348,7 +1375,97 @@
"selectAll": "すべて選択",
"deselectAll": "すべての選択を解除",
"useGlobalStatusDefault": "Use Global Default (Status)",
"useGlobalMetricsDefault": "グローバルデフォルトを使用 (メトリック)"
"useGlobalMetricsDefault": "グローバルデフォルトを使用 (メトリック)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "ターミナル",
@@ -1372,6 +1489,7 @@
"connected": "接続しました",
"clipboardWriteFailed": "クリップボードにコピーできませんでした。ページがHTTPSまたはlocalhostで配信されていることを確認してください。",
"clipboardReadFailed": "クリップボードからの読み取りに失敗しました。クリップボードのアクセス許可が付与されていることを確認してください。",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH接続が確立されました",
"authError": "認証に失敗しました: {{message}}",
"unknownError": "不明なエラーが発生しました",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "ターミナル出力でコマンド、パス、IP、ログレベルを自動的に強調表示する",
"enableCommandPaletteShortcut": "コマンドパレットショートカットを有効にする",
"enableCommandPaletteShortcutDesc": "左シフトをダブルタップしてコマンドパレットを開き、ホストへの迅速なアクセス",
"enableTerminalSessionPersistence": "永続的なターミナルセッション",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "タブの切り替えやブラウザの閉じ時にSSH接続を維持します (不安定な場合があります)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "글로벌 모니터링 설정이 저장되었습니다.",
"failedToSaveGlobalSettings": "전역 모니터링 설정을 저장하는 데 실패했습니다.",
"failedToLoadGlobalSettings": "전역 모니터링 설정을 불러오는 데 실패했습니다.",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "세션 불러오는 중...",
"noActiveSessions": "활성화된 세션이 없습니다.",
"device": "장치",
@@ -866,11 +876,21 @@
"importError": "가져오기 오류",
"failedToImportJson": "JSON 파일을 가져오는 데 실패했습니다.",
"connectionDetails": "연결 정보",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "조직",
"ipAddress": "IP 주소 또는 호스트 이름",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "포트",
"name": "이름",
"username": "사용자 이름",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "접는 사람",
"tags": "태그",
"pin": "핀",
@@ -979,6 +999,8 @@
"tunnel": "터널",
"fileManager": "파일 관리자",
"serverStats": "서버 통계",
"status": "Status",
"statistics": "통계",
"hostViewer": "호스트 뷰어",
"enableServerStats": "서버 통계 활성화",
"enableServerStatsDesc": "이 호스트에 대한 서버 통계 수집을 활성화/비활성화합니다.",
@@ -1028,7 +1050,6 @@
"openFileManager": "파일 관리자 열기",
"openTunnels": "개방형 터널",
"openServerDetails": "오픈 서버 세부 정보",
"statistics": "통계",
"enabledWidgets": "활성화된 위젯",
"openServerStats": "오픈 서버 통계",
"enabledWidgetsDesc": "이 호스트에 대해 표시할 통계 위젯을 선택하세요.",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "서버가 온라인 상태인지 오프라인 상태인지 확인하십시오.",
"statusCheckInterval": "상태 확인 간격",
"statusCheckIntervalDesc": "호스트가 온라인 상태인지 확인하는 빈도 (5초 ~ 1시간)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "전역 기본값을 사용합니다",
"useGlobalMetricsInterval": "전역 기본값을 사용합니다",
"usingGlobalDefault": "전역 기본값 사용({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "메트릭 모니터링 활성화",
"metricsEnabledDesc": "CPU, RAM, 디스크 및 기타 시스템 통계를 수집합니다.",
"metricsInterval": "측정항목 수집 간격",
"metricsIntervalDesc": "서버 통계 수집 빈도 (5초 ~ 1시간)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "초",
"intervalMinutes": "분",
"intervalValidation": "모니터링 간격은 5초에서 1시간(3600초) 사이여야 합니다.",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "터널 URL 복사",
"copyServerStatsUrl": "서버 통계 URL 복사",
"copyDockerUrl": "Docker URL 복사",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "이 앱을 전체 화면 모드로 열려면 URL을 복사하세요.",
"notEnabled": "이 호스트에서는 Docker가 활성화되어 있지 않습니다. Docker 기능을 사용하려면 호스트 설정에서 Docker를 활성화하십시오.",
"validating": "Docker 유효성 검사 중...",
@@ -1348,7 +1375,97 @@
"selectAll": "모두 선택하세요",
"deselectAll": "모두 선택 해제",
"useGlobalStatusDefault": "전역 기본값(상태) 사용",
"useGlobalMetricsDefault": "전역 기본값(메트릭) 사용"
"useGlobalMetricsDefault": "전역 기본값(메트릭) 사용",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "터미널",
@@ -1372,6 +1489,7 @@
"connected": "연결됨",
"clipboardWriteFailed": "클립보드에 복사하는 데 실패했습니다. 페이지가 HTTPS 또는 localhost를 통해 제공되는지 확인하세요.",
"clipboardReadFailed": "클립보드에서 읽는 데 실패했습니다. 클립보드 권한이 부여되었는지 확인하십시오.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH 연결이 설정되었습니다.",
"authError": "인증 실패: {{message}}",
"unknownError": "알 수 없는 오류가 발생했습니다.",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "터미널 출력에서 명령어, 경로, IP 주소 및 로그 레벨을 자동으로 강조 표시합니다.",
"enableCommandPaletteShortcut": "명령 팔레트 바로가기 활성화",
"enableCommandPaletteShortcutDesc": "왼쪽 Shift 키를 두 번 누르면 호스트에 빠르게 접근할 수 있는 명령 팔레트가 열립니다.",
"enableTerminalSessionPersistence": "영구 터미널 세션",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "탭을 전환하거나 브라우저를 닫을 때 SSH 연결을 유지합니다(불안정할 수 있음)."
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Algemene monitoring instellingen opgeslagen",
"failedToSaveGlobalSettings": "Fout bij het opslaan van de globale monitoring instellingen",
"failedToLoadGlobalSettings": "Fout bij het laden van de globale monitoring instellingen",
"guacamoleIntegration": "Externe Desktop integratie (Guacamole)",
"guacamoleIntegrationDesc": "Schakel RDP, VNC en Telnet verbindingen in via guacd. Vereist een guacd instantie om te worden uitgevoerd.",
"enableGuacamole": "RDP/VNC/Telnet ondersteuning inschakelen",
"guacdUrl": "guacd URL (host:poort)",
"guacdUrlPlaceholder": "adviseur:4822",
"guacdUrlNote": "Wijzigingen in de guacd host/poort vereisen een herstart van de server van kracht.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "is aangepast aan geldig bereik",
"loadingSessions": "Sessies laden...",
"noActiveSessions": "Geen actieve sessies gevonden.",
"device": "Apparaat",
@@ -866,11 +876,21 @@
"importError": "Fout bij importeren",
"failedToImportJson": "Kan JSON bestand niet importeren",
"connectionDetails": "Connectie Details",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Rekening",
"ipAddress": "IP-adres of hostnaam",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Poort",
"name": "naam",
"username": "Gebruikersnaam",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Map",
"tags": "Labels",
"pin": "Vastzetten",
@@ -979,6 +999,8 @@
"tunnel": "Tunnel",
"fileManager": "Bestands Beheer",
"serverStats": "Server Statistieken",
"status": "Status",
"statistics": "Statistieken",
"hostViewer": "Host Viewer",
"enableServerStats": "Server statistieken inschakelen",
"enableServerStatsDesc": "Schakel server statistieken verzameling voor deze host in/uit",
@@ -1028,7 +1050,6 @@
"openFileManager": "Bestandsbeheer openen",
"openTunnels": "Open Tunnels",
"openServerDetails": "Server details openen",
"statistics": "Statistieken",
"enabledWidgets": "Ingeschakelde Widgets",
"openServerStats": "Open Server Statistieken",
"enabledWidgetsDesc": "Selecteer welke statistieken widgets moeten worden weergegeven voor deze host",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Controleer of de server online of offline is",
"statusCheckInterval": "Status controle interval",
"statusCheckIntervalDesc": "Hoe vaak controleren of host online is (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Globale standaard gebruiken",
"useGlobalMetricsInterval": "Globale standaard gebruiken",
"usingGlobalDefault": "Gebruik van globale standaard ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Metrics monitoring inschakelen",
"metricsEnabledDesc": "Verzamel CPU, RAM, schijf en andere systeemstatistieken",
"metricsInterval": "Metrics Collectie Interval",
"metricsIntervalDesc": "Hoe vaak serverstatistieken worden verzameld (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "seconden",
"intervalMinutes": "minuten",
"intervalValidation": "Controleintervallen moeten tussen de 5 en 1 uur zijn (3600 seconden)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopieer Tunnel URL",
"copyServerStatsUrl": "Kopieer server statistieken URL",
"copyDockerUrl": "Docker URL kopiëren",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "URL kopiëren om deze app te openen in volledig scherm modus",
"notEnabled": "Docker is niet ingeschakeld voor deze host. Zet het aan in Hostinstellingen om de Docker-functies te gebruiken.",
"validating": "Docker valideren...",
@@ -1348,7 +1375,97 @@
"selectAll": "Alles selecteren",
"deselectAll": "Deselecteer alles",
"useGlobalStatusDefault": "Gebruik Global Default (Status)",
"useGlobalMetricsDefault": "Gebruik Globale Standaard (Metrieken)"
"useGlobalMetricsDefault": "Gebruik Globale Standaard (Metrieken)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Verbonden",
"clipboardWriteFailed": "Kopiëren naar klembord mislukt. Zorg ervoor dat de pagina via HTTPS of localhost wordt geserveerd.",
"clipboardReadFailed": "Lezen van klembord mislukt. Zorg ervoor dat machtigingen voor klembord zijn verleend.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH verbinding ingesteld",
"authError": "Authenticatie mislukt: {{message}}",
"unknownError": "Onbekende fout opgetreden",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Automatisch commando's, pad en IP's markeren en levels loggen in de einduitvoer",
"enableCommandPaletteShortcut": "Schakel Command Palette Snelkoppeling in",
"enableCommandPaletteShortcutDesc": "Dubbeltikken op linker Shift om het Opdrachtpalet te openen voor snelle toegang tot hosts",
"enableTerminalSessionPersistence": "Persistente terminal sessies",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Behoud SSH verbindingen bij het wisselen van tabs of het sluiten van de browser (kan instabiel zijn)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globale overvåkingsinnstillinger lagret",
"failedToSaveGlobalSettings": "Kan ikke lagre globale overvåkingsinnstillinger",
"failedToLoadGlobalSettings": "Kan ikke laste inn globale overvåkingsinnstillinger",
"guacamoleIntegration": "Eksternt skrivebordsintegrering (Guacamole)",
"guacamoleIntegrationDesc": "Aktiver RDP, VNC, og Telnet forbindelser via guacd. Krever en guacd instans for å kjøre.",
"enableGuacamole": "Aktiver støtte for RDP/VNC/Telnet",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Endringer i guacd vert/port krever at serveren startes på nytt.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "ble justert til gyldig område",
"loadingSessions": "Laster inn økter...",
"noActiveSessions": "Ingen aktive økter funnet.",
"device": "Enhet",
@@ -866,11 +876,21 @@
"importError": "Importfeil",
"failedToImportJson": "Kunne ikke importere JSON-fil",
"connectionDetails": "Tilkoblingsdetaljer",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisasjon",
"ipAddress": "IP adresse eller vertsnavn",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Navn",
"username": "Brukernavn",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Mappe",
"tags": "Tagger",
"pin": "Fest",
@@ -979,6 +999,8 @@
"tunnel": "Tunnelen",
"fileManager": "Filbehandler",
"serverStats": "Serverstatistikk",
"status": "Status",
"statistics": "Statistikk",
"hostViewer": "Vertvisning",
"enableServerStats": "Aktiver serverstatistikk",
"enableServerStatsDesc": "Aktiver/deaktiver innsamling av serverstatistikk for denne verten",
@@ -1028,7 +1050,6 @@
"openFileManager": "Åpne filbehandler",
"openTunnels": "Åpne tuneller",
"openServerDetails": "Åpne serverdetaljer",
"statistics": "Statistikk",
"enabledWidgets": "Aktiverte widgeter",
"openServerStats": "Åpne serverstatistikk",
"enabledWidgetsDesc": "Velg hvilke statistikk-widgeter som skal vises for denne verten",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Kontroller om serveren er online eller offline",
"statusCheckInterval": "Statussjekkintervall",
"statusCheckIntervalDesc": "Hvor ofte du skal kontrollere om verten er online (5s - 1t)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Bruk global standard",
"useGlobalMetricsInterval": "Bruk global standard",
"usingGlobalDefault": "Bruker global standard ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Aktiver statistikkovervåking",
"metricsEnabledDesc": "Samle inn CPU, RAM, disk og annen systemstatistikk",
"metricsInterval": "Intervall for statistikkinnsamling",
"metricsIntervalDesc": "Hvor ofte serverstatistikk skal innhentes (5s - 1t)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekunder",
"intervalMinutes": "minutter",
"intervalValidation": "Overvåkingsintervaller må være mellom 5 sekunder og 1 time (3600 sekunder)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopier tunnel URL",
"copyServerStatsUrl": "Kopier Server Statistikk URL",
"copyDockerUrl": "Kopier Docker URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Kopier URL for å åpne denne appen i fullskjermmodus",
"notEnabled": "Leger er ikke aktivert for denne verten. Aktiver dette i Vertsinnstillingene for å bruke Docker-funksjoner.",
"validating": "Validerer Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Velg alle",
"deselectAll": "Fjern all merking",
"useGlobalStatusDefault": "Bruk global standard (Status)",
"useGlobalMetricsDefault": "Bruk global standard (måltall)"
"useGlobalMetricsDefault": "Bruk global standard (måltall)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Tilkoblet",
"clipboardWriteFailed": "Kopiering til utklippstavlen. Sjekk at siden har tilgang til HTTPS eller localhost.",
"clipboardReadFailed": "Kan ikke lese fra utklippstavlen. Påse at utklippstavle tillatelser er gitt.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-tilkobling etablert",
"authError": "Autentisering mislyktes: {{message}}",
"unknownError": "Ukjent feil oppstod",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Automatisk markerer kommandoer, stier, IP-adresser og loggnivåer i terminalen",
"enableCommandPaletteShortcut": "Aktiver \"Kommando-palett\"-snarvei",
"enableCommandPaletteShortcutDesc": "Dobbelttrykk til venstre Skift for å åpne kommandopaletten for rask tilgang til verter",
"enableTerminalSessionPersistence": "Vedvarende terminaløkter",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Oppretthold SSH-forbindelser når du bytter faner eller lukker nettleseren (kan være ustabil)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globalne ustawienia monitorowania zapisane",
"failedToSaveGlobalSettings": "Nie udało się zapisać globalnych ustawień monitoringu",
"failedToLoadGlobalSettings": "Nie udało się załadować globalnych ustawień monitoringu",
"guacamoleIntegration": "Integracja zdalnego pulpitu (Guacamole)",
"guacamoleIntegrationDesc": "Włącz połączenia RDP, VNC i Telnet przez guacd. Wymaga instancji guacd do uruchomienia.",
"enableGuacamole": "Włącz obsługę RDP/VNC/Telnet",
"guacdUrl": "adres URL guacd (host:port)",
"guacdUrlPlaceholder": "guakd:4822",
"guacdUrlNote": "Zmiany hosta/portu guacd wymagają ponownego uruchomienia serwera.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "został dostosowany do prawidłowego zakresu",
"loadingSessions": "Ładowanie sesji...",
"noActiveSessions": "Nie znaleziono aktywnych sesji.",
"device": "Urządzenie",
@@ -866,11 +876,21 @@
"importError": "Błąd importu",
"failedToImportJson": "Nie udało się zaimportować pliku JSON",
"connectionDetails": "Szczegóły połączenia",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organizacja",
"ipAddress": "Adres IP lub nazwa hosta",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Nazwisko",
"username": "Nazwa użytkownika",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Folder",
"tags": "Tagi",
"pin": "Przypnij",
@@ -979,6 +999,8 @@
"tunnel": "Tunel",
"fileManager": "Menedżer plików",
"serverStats": "Statystyki serwera",
"status": "Status",
"statistics": "Statystyki",
"hostViewer": "Przeglądarka hostów",
"enableServerStats": "Włącz statystyki serwera",
"enableServerStatsDesc": "Włącz/Wyłącz kolekcję statystyk serwera dla tego hosta",
@@ -1028,7 +1050,6 @@
"openFileManager": "Otwórz menedżera plików",
"openTunnels": "Otwórz tunele",
"openServerDetails": "Otwórz szczegóły serwera",
"statistics": "Statystyki",
"enabledWidgets": "Włączone widżety",
"openServerStats": "Otwórz statystyki serwera",
"enabledWidgetsDesc": "Wybierz, które widżety statystyczne mają być wyświetlane dla tego hosta",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Sprawdź, czy serwer jest online lub offline",
"statusCheckInterval": "Interwał sprawdzania statusu",
"statusCheckIntervalDesc": "Jak często sprawdzać, czy host jest online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Użyj globalnego domyślnego",
"useGlobalMetricsInterval": "Użyj globalnego domyślnego",
"usingGlobalDefault": "Używanie domyślnych globalnych ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Włącz monitorowanie liczników",
"metricsEnabledDesc": "Zbieraj CPU, RAM, dysk i inne statystyki systemowe",
"metricsInterval": "Interwał kolekcji liczników",
"metricsIntervalDesc": "Jak często zbierać statystyki serwera (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekundy",
"intervalMinutes": "minuty",
"intervalValidation": "Częstotliwość monitorowania musi wynosić od 5 sekund do 1 godziny (3600 sekund)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Skopiuj adres URL tunelu",
"copyServerStatsUrl": "Skopiuj adres URL statystyk serwera",
"copyDockerUrl": "Skopiuj URL dokera",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Skopiuj adres URL, aby otworzyć aplikację w trybie pełnoekranowym",
"notEnabled": "Docker nie jest włączony dla tego hosta. Włącz go w Ustawieniach hosta, aby używać funkcji Dockera.",
"validating": "Sprawdzanie poprawności Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Zaznacz wszystkie",
"deselectAll": "Odznacz wszystkie",
"useGlobalStatusDefault": "Użyj globalnego domyślnego (Status)",
"useGlobalMetricsDefault": "Użyj globalnego domyślnego (Metrics)"
"useGlobalMetricsDefault": "Użyj globalnego domyślnego (Metrics)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Połączono",
"clipboardWriteFailed": "Nie udało się skopiować do schowka. Upewnij się, że strona jest obsługiwana przez HTTPS lub localhost.",
"clipboardReadFailed": "Nie udało się odczytać ze schowka. Upewnij się, że uprawnienia do schowka są przyznane.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Utworzono połączenie SSH",
"authError": "Uwierzytelnianie nie powiodło się: {{message}}",
"unknownError": "Wystąpił nieznany błąd",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Automatycznie podświetl polecenia, ścieżki, adresy IP i poziomy logów na wyjściu terminalu",
"enableCommandPaletteShortcut": "Włącz skrót palety poleceń",
"enableCommandPaletteShortcutDesc": "Dotknij dwukrotnie po lewej stronie, aby otworzyć paletę poleceń dla szybkiego dostępu do hostów",
"enableTerminalSessionPersistence": "Trwałe sesje terminali",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Utrzymuj połączenia SSH podczas przełączania kart lub zamykania przeglądarki (może być niestabilne)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Configurações globais de monitoramento salvas",
"failedToSaveGlobalSettings": "Falha ao salvar as configurações de monitoramento globais",
"failedToLoadGlobalSettings": "Falha ao carregar as configurações de monitoramento globais",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "foi ajustado para um intervalo válido",
"loadingSessions": "Carregando sessões...",
"noActiveSessions": "Não foram encontradas sessões ativas.",
"device": "Dispositivo",
@@ -866,11 +876,21 @@
"importError": "Erro ao importar",
"failedToImportJson": "Falha ao importar arquivo JSON",
"connectionDetails": "Detalhes da conexão",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Cliente",
"ipAddress": "Endereço IP ou Nome de Host",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Porta",
"name": "Nome:",
"username": "Usuário:",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "pasta",
"tags": "Etiquetas",
"pin": "PIN",
@@ -979,6 +999,8 @@
"tunnel": "Túnel",
"fileManager": "Gerenciador de Arquivos",
"serverStats": "Estatísticas do servidor",
"status": "Status",
"statistics": "estatísticas",
"hostViewer": "Visualizador do Host",
"enableServerStats": "Habilitar estatísticas do servidor",
"enableServerStatsDesc": "Ativar/desativar estatísticas do servidor para este host",
@@ -1028,7 +1050,6 @@
"openFileManager": "Abrir Gerenciador de Arquivos",
"openTunnels": "Abrir túneis",
"openServerDetails": "Abrir Detalhes do Servidor",
"statistics": "estatísticas",
"enabledWidgets": "Widgets ativos",
"openServerStats": "Estatísticas do Servidor Aberto",
"enabledWidgetsDesc": "Selecione quais widgets de estatísticas a exibir para este host",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Verifique se o servidor está online ou offline",
"statusCheckInterval": "Intervalo de verificação de status",
"statusCheckIntervalDesc": "Frequência para verificar se o host está online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Usar padrão global",
"useGlobalMetricsInterval": "Usar padrão global",
"usingGlobalDefault": "Usando padrão global ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Habilitar monitoramento de métricas",
"metricsEnabledDesc": "Coletar estatísticas de CPU, RAM, disco e outros sistemas",
"metricsInterval": "Intervalo de Coleção de Métricas",
"metricsIntervalDesc": "Com que frequência coletar estatísticas do servidor (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "segundos",
"intervalMinutes": "Minutos",
"intervalValidation": "Intervalos de monitoramento devem ser entre 5 segundos e 1 hora (3600 segundos)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copiar URL do túnel",
"copyServerStatsUrl": "Copiar URL das Estatísticas do Servidor",
"copyDockerUrl": "Copiar URL do Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copiar URL para abrir este app em tela cheia",
"notEnabled": "O Docker não está habilitado para este host. Habilite nas configurações de Host para usar os recursos Docker.",
"validating": "Validando o Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Selecionar todos",
"deselectAll": "Desmarcar todos",
"useGlobalStatusDefault": "Usar Padrão Global (Status)",
"useGlobalMetricsDefault": "Usar Padrão Global (Métricas)"
"useGlobalMetricsDefault": "Usar Padrão Global (Métricas)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Conectado",
"clipboardWriteFailed": "Falha ao copiar para a área de transferência. Certifique-se de que a página seja servida por HTTPS ou localhost.",
"clipboardReadFailed": "Falha ao ler da área de transferência. Certifique-se de que as permissões da área de transferência foram concedidas.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Conexão SSH estabelecida",
"authError": "Falha na autenticação: {{message}}",
"unknownError": "Ocorreu um erro desconhecido",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Destacar automaticamente comandos, caminhos, IPs e níveis de log na saída do terminal",
"enableCommandPaletteShortcut": "Ativar Atalho da Paleta de Comando",
"enableCommandPaletteShortcutDesc": "Toque duas vezes no botão esquerdo para abrir a Paleta de Comando para acesso rápido aos hosts",
"enableTerminalSessionPersistence": "Sessões Terminais Persistentes",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Manter conexões SSH ao alternar abas ou fechar o navegador (pode ser instável)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Configurações globais de monitoramento salvas",
"failedToSaveGlobalSettings": "Falha ao salvar as configurações de monitoramento globais",
"failedToLoadGlobalSettings": "Falha ao carregar as configurações de monitoramento globais",
"guacamoleIntegration": "Integração no Desktop Remoto (Guacamole)",
"guacamoleIntegrationDesc": "Habilitar conexões RDP, VNC e Telnet via guacd. Requer uma instância de guacd para estar rodando.",
"enableGuacamole": "Habilitar suporte a RDP/VNC/Telnet",
"guacdUrl": "URL guacd (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Alterações no host/porta do guacd requerem que o servidor reinicie para que tenha efeito.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "foi ajustado para um intervalo válido",
"loadingSessions": "Carregando sessões...",
"noActiveSessions": "Não foram encontradas sessões ativas.",
"device": "Dispositivo",
@@ -866,11 +876,21 @@
"importError": "Erro ao importar",
"failedToImportJson": "Falha ao importar arquivo JSON",
"connectionDetails": "Detalhes da conexão",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Cliente",
"ipAddress": "Endereço IP ou Nome de Host",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Porta",
"name": "Nome:",
"username": "Usuário:",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "pasta",
"tags": "Etiquetas",
"pin": "PIN",
@@ -979,6 +999,8 @@
"tunnel": "Túnel",
"fileManager": "Gerenciador de Arquivos",
"serverStats": "Estatísticas do servidor",
"status": "Status",
"statistics": "estatísticas",
"hostViewer": "Visualizador do Host",
"enableServerStats": "Habilitar estatísticas do servidor",
"enableServerStatsDesc": "Ativar/desativar estatísticas do servidor para este host",
@@ -1028,7 +1050,6 @@
"openFileManager": "Abrir Gerenciador de Arquivos",
"openTunnels": "Abrir túneis",
"openServerDetails": "Abrir Detalhes do Servidor",
"statistics": "estatísticas",
"enabledWidgets": "Widgets ativos",
"openServerStats": "Estatísticas do Servidor Aberto",
"enabledWidgetsDesc": "Selecione quais widgets de estatísticas a exibir para este host",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Verifique se o servidor está online ou offline",
"statusCheckInterval": "Intervalo de verificação de status",
"statusCheckIntervalDesc": "Frequência para verificar se o host está online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Usar padrão global",
"useGlobalMetricsInterval": "Usar padrão global",
"usingGlobalDefault": "Usando padrão global ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Habilitar monitoramento de métricas",
"metricsEnabledDesc": "Coletar estatísticas de CPU, RAM, disco e outros sistemas",
"metricsInterval": "Intervalo de Coleção de Métricas",
"metricsIntervalDesc": "Com que frequência coletar estatísticas do servidor (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "segundos",
"intervalMinutes": "Minutos",
"intervalValidation": "Intervalos de monitoramento devem ser entre 5 segundos e 1 hora (3600 segundos)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copiar URL do túnel",
"copyServerStatsUrl": "Copiar URL das Estatísticas do Servidor",
"copyDockerUrl": "Copiar URL do Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copiar URL para abrir este app em tela cheia",
"notEnabled": "O Docker não está habilitado para este host. Habilite nas configurações de Host para usar os recursos Docker.",
"validating": "Validando o Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Selecionar todos",
"deselectAll": "Desmarcar todos",
"useGlobalStatusDefault": "Usar Padrão Global (Status)",
"useGlobalMetricsDefault": "Usar Padrão Global (Métricas)"
"useGlobalMetricsDefault": "Usar Padrão Global (Métricas)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Conectado",
"clipboardWriteFailed": "Falha ao copiar para a área de transferência. Certifique-se de que a página seja servida por HTTPS ou localhost.",
"clipboardReadFailed": "Falha ao ler da área de transferência. Certifique-se de que as permissões da área de transferência foram concedidas.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Conexão SSH estabelecida",
"authError": "Falha na autenticação: {{message}}",
"unknownError": "Ocorreu um erro desconhecido",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Destacar automaticamente comandos, caminhos, IPs e níveis de log na saída do terminal",
"enableCommandPaletteShortcut": "Ativar Atalho da Paleta de Comando",
"enableCommandPaletteShortcutDesc": "Toque duas vezes no botão esquerdo para abrir a Paleta de Comando para acesso rápido aos hosts",
"enableTerminalSessionPersistence": "Sessões Terminais Persistentes",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Manter conexões SSH ao alternar abas ou fechar o navegador (pode ser instável)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Setări de monitorizare globale salvate",
"failedToSaveGlobalSettings": "Salvarea setărilor globale de monitorizare a eșuat",
"failedToLoadGlobalSettings": "Încărcarea setărilor globale de monitorizare a eșuat",
"guacamoleIntegration": "Integrarea Desktop la distanță (Guacamole)",
"guacamoleIntegrationDesc": "Activează conexiunile RDP, VNC și Telnet prin intermediul guacd. Necesită o instanță de ghacd pentru a rula.",
"enableGuacamole": "Activează suport RDP/VNC/Telnet",
"guacdUrl": "URL guacd (host:port)",
"guacdUrlPlaceholder": "guacd: 4822",
"guacdUrlNote": "Modificările guacd host/port necesită o repornire a serverului pentru a avea efect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "a fost ajustat la un interval valid",
"loadingSessions": "Se încarcă sesiunile...",
"noActiveSessions": "Nici o sesiune activă găsită.",
"device": "Dispozitiv",
@@ -866,11 +876,21 @@
"importError": "Eroare de import",
"failedToImportJson": "Nu s-a putut importa fișierul JSON",
"connectionDetails": "Detalii conexiune",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organizație",
"ipAddress": "Adresă IP sau nume gazdă",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Portul",
"name": "Nume",
"username": "Nume",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Dosar",
"tags": "Etichete",
"pin": "Fixează",
@@ -979,6 +999,8 @@
"tunnel": "Tunel",
"fileManager": "Manager fişiere",
"serverStats": "Statistici server",
"status": "Status",
"statistics": "Statistici",
"hostViewer": "Vizualizator Gazdă",
"enableServerStats": "Activează Statisticile Serverului",
"enableServerStatsDesc": "Activează/dezactivează colecția de statistici a serverului pentru această gazdă",
@@ -1028,7 +1050,6 @@
"openFileManager": "Deschide managerul de fişiere",
"openTunnels": "Deschide tuneluri",
"openServerDetails": "Deschide detaliile serverului",
"statistics": "Statistici",
"enabledWidgets": "Widget-uri activate",
"openServerStats": "Deschide statisticile serverului",
"enabledWidgetsDesc": "Selectați ce widget-uri de statistici să fie afișate pentru această gazdă",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Verifică dacă serverul este online sau offline",
"statusCheckInterval": "Interval verificare stare",
"statusCheckIntervalDesc": "Cât de des să verificați dacă gazda este online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Foloseste implicit global",
"useGlobalMetricsInterval": "Foloseste implicit global",
"usingGlobalDefault": "Utilizarea valorilor implicite globale ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Activează monitorizarea valorilor",
"metricsEnabledDesc": "Colectează statistici CPU, RAM, disk și alte statistici de sistem",
"metricsInterval": "Intervalul de colectare a valorilor",
"metricsIntervalDesc": "Cât de des se colectează statisticile serverului (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "secunde",
"intervalMinutes": "minute",
"intervalValidation": "Intervalele de monitorizare trebuie să fie între 5 secunde și 1 oră (3600 secunde)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Copiază URL-ul tunelului",
"copyServerStatsUrl": "Copiază URL-ul de statistici al serverului",
"copyDockerUrl": "Copiază URL-ul Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Copiați URL-ul pentru a deschide această aplicație în modul ecran complet",
"notEnabled": "Dockerul nu este activat pentru această gazdă. Activați-l în Setările Gazdei pentru a utiliza funcțiile Docker.",
"validating": "Se validează Doctorul...",
@@ -1348,7 +1375,97 @@
"selectAll": "Selectează tot",
"deselectAll": "Deselectează tot",
"useGlobalStatusDefault": "Utilizează Implicit Global (Stare)",
"useGlobalMetricsDefault": "Foloseste Global Implicit (Metrics)"
"useGlobalMetricsDefault": "Foloseste Global Implicit (Metrics)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Conectat",
"clipboardWriteFailed": "Copierea în clipboard a eșuat. Asigură-te că pagina este deservită prin HTTPS sau localhost.",
"clipboardReadFailed": "Nu a reușit să citească din clipboard. Asigurați-vă că sunt acordate permisiuni pentru clipboard.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Conexiune SSH stabilită",
"authError": "Autentificare eșuată: {{message}}",
"unknownError": "Eroare necunoscută",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Evidențiază automat comenzile, căile de acces, IP-urile și nivelurile de log în ieșirea terminalului",
"enableCommandPaletteShortcut": "Activează scurtătura pentru paleta de comenzi",
"enableCommandPaletteShortcutDesc": "Atingeți de două ori Shift stânga pentru a deschide paleta de comenzi pentru acces rapid la gazde",
"enableTerminalSessionPersistence": "Sesiuni persistente ale terminalului",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Menține conexiunile SSH la comutarea filelor sau închiderea browserului (poate fi instabilă)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Глобальные настройки мониторинга сохранены",
"failedToSaveGlobalSettings": "Не удалось сохранить глобальные настройки мониторинга",
"failedToLoadGlobalSettings": "Не удалось загрузить глобальные настройки мониторинга",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "был скорректирован на действительный диапазон",
"loadingSessions": "Загрузка сессий...",
"noActiveSessions": "Активные сессии не найдены.",
"device": "Устройство",
@@ -866,11 +876,21 @@
"importError": "Ошибка импорта",
"failedToImportJson": "Не удалось импортировать JSON файл",
"connectionDetails": "Детали подключения",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Организация",
"ipAddress": "IP-адрес или имя хоста",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Порт",
"name": "Наименование",
"username": "Имя пользователя",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Папка",
"tags": "Теги",
"pin": "Закрепить",
@@ -979,6 +999,8 @@
"tunnel": "Туннель",
"fileManager": "Файловый менеджер",
"serverStats": "Статистика сервера",
"status": "Status",
"statistics": "Статистика",
"hostViewer": "Просмотр узлов",
"enableServerStats": "Включить статистику сервера",
"enableServerStatsDesc": "Включить/отключить сбор статистики сервера для этого хоста",
@@ -1028,7 +1050,6 @@
"openFileManager": "Открыть файловый менеджер",
"openTunnels": "Открытые туннели",
"openServerDetails": "Открыть детали сервера",
"statistics": "Статистика",
"enabledWidgets": "Включенные виджеты",
"openServerStats": "Открыть статистику сервера",
"enabledWidgetsDesc": "Выберите, какие виджеты будут отображаться для этого узла",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Проверьте, включен ли сервер или оффлайн",
"statusCheckInterval": "Интервал проверки состояния",
"statusCheckIntervalDesc": "Как часто проверять, есть ли хост онлайн (5s - 1ч)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Глобальные значения по умолчанию",
"useGlobalMetricsInterval": "Глобальные значения по умолчанию",
"usingGlobalDefault": "По умолчанию используется глобальный ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Включить мониторинг метрик",
"metricsEnabledDesc": "Сбор статистики CPU, RAM, диска и другой системы",
"metricsInterval": "Интервал сбора метрик",
"metricsIntervalDesc": "Как часто собирать статистику сервера (5s - 1ч)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "секунд",
"intervalMinutes": "минуты",
"intervalValidation": "Интервал наблюдения должен быть от 5 секунд до 1 часа (3600 секунд)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Скопировать URL туннеля",
"copyServerStatsUrl": "Копировать URL статистики сервера",
"copyDockerUrl": "Скопировать URL Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Скопировать URL для открытия приложения в полноэкранном режиме",
"notEnabled": "Для этого узла Docker не включен. Включите его в настройках хоста, чтобы использовать функции Docker.",
"validating": "Проверка докера...",
@@ -1348,7 +1375,97 @@
"selectAll": "Выбрать все",
"deselectAll": "Отменить выбор",
"useGlobalStatusDefault": "Использовать глобальные по умолчанию (статус)",
"useGlobalMetricsDefault": "Использовать глобальные значения (Метрики)"
"useGlobalMetricsDefault": "Использовать глобальные значения (Метрики)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Терминал",
@@ -1372,6 +1489,7 @@
"connected": "Подключено",
"clipboardWriteFailed": "Не удалось скопировать в буфер обмена. Убедитесь, что страница отправляется через HTTPS или localhost.",
"clipboardReadFailed": "Не удалось прочитать из буфера обмена. Убедитесь, что права доступа предоставлены.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH соединение установлено",
"authError": "Ошибка аутентификации: {{message}}",
"unknownError": "Произошла неизвестная ошибка",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Автоматически выделять команды, пути, IP-адреса и уровни журнала в выводе терминала",
"enableCommandPaletteShortcut": "Включить ярлык в палитре команд",
"enableCommandPaletteShortcutDesc": "Дважды нажмите левый Shift для открытия командной палитры для быстрого доступа к узлам",
"enableTerminalSessionPersistence": "Постоянные сессии терминала",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Поддерживать SSH соединения при переключении вкладок или закрытии браузера (может быть нестабильным)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Подешавања глобалног праћења сачувана",
"failedToSaveGlobalSettings": "Чување подешавања глобалног праћења није успело",
"failedToLoadGlobalSettings": "Учитавање подешавања глобалног праћења није успело",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Учитавање сесија...",
"noActiveSessions": "Није пронађена ниједна активна сесија.",
"device": "Уређај",
@@ -866,11 +876,21 @@
"importError": "Грешка при увозу",
"failedToImportJson": "Увоз JSON датотеке није успео",
"connectionDetails": "Детаљи везе",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Организација",
"ipAddress": "IP адреса или име хоста",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Лука",
"name": "Име",
"username": "Корисничко име",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Фасцикла",
"tags": "Ознаке",
"pin": "Закачи",
@@ -979,6 +999,8 @@
"tunnel": "Тунел",
"fileManager": "Менаџер датотека",
"serverStats": "Статистика сервера",
"status": "Status",
"statistics": "Статистика",
"hostViewer": "Прегледач домаћина",
"enableServerStats": "Омогући статистику сервера",
"enableServerStatsDesc": "Омогући/онемогући прикупљање статистике сервера за овај хост",
@@ -1028,7 +1050,6 @@
"openFileManager": "Отвори менаџер датотека",
"openTunnels": "Отворени тунели",
"openServerDetails": "Отвори детаље сервера",
"statistics": "Статистика",
"enabledWidgets": "Омогућени виџети",
"openServerStats": "Отвори статистику сервера",
"enabledWidgetsDesc": "Изаберите које виџете за статистику желите да прикажете за овог хоста",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Проверите да ли је сервер онлајн или офлајн",
"statusCheckInterval": "Интервал провере статуса",
"statusCheckIntervalDesc": "Колико често проверавати да ли је домаћин онлајн (5 с - 1 сат)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Користи глобално подразумевано",
"useGlobalMetricsInterval": "Користи глобално подразумевано",
"usingGlobalDefault": "Коришћење глобалног подразумеваног подешавања ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Омогући праћење метрика",
"metricsEnabledDesc": "Прикупљајте статистику процесора, РАМ-а, диска и друге системске статистике",
"metricsInterval": "Интервал прикупљања метрика",
"metricsIntervalDesc": "Колико често прикупљати статистику сервера (5 с - 1 сат)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "секунде",
"intervalMinutes": "минута",
"intervalValidation": "Интервали праћења морају бити између 5 секунди и 1 сата (3600 секунди)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Копирај URL тунела",
"copyServerStatsUrl": "Копирај URL статистике сервера",
"copyDockerUrl": "Копирај Докер УРЛ",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Копирајте URL да бисте отворили ову апликацију у режиму целог екрана",
"notEnabled": "Докер није омогућен за овај хост. Омогућите га у подешавањима хоста да бисте користили Докер функције.",
"validating": "Валидација Докера...",
@@ -1348,7 +1375,97 @@
"selectAll": "Изабери све",
"deselectAll": "Поништи избор свих",
"useGlobalStatusDefault": "Користи глобално подразумевано (статус)",
"useGlobalMetricsDefault": "Користи глобално подразумевано (метрике)"
"useGlobalMetricsDefault": "Користи глобално подразумевано (метрике)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Терминал",
@@ -1372,6 +1489,7 @@
"connected": "Повезано",
"clipboardWriteFailed": "Копирање у међуспремник није успело. Уверите се да се страница приказује преко HTTPS-а или localhost-а.",
"clipboardReadFailed": "Читање из међуспремника није успело. Уверите се да су дозволе за међуспремник одобрене.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH веза успостављена",
"authError": "Аутентификација није успела: {{message}}",
"unknownError": "Дошло је до непознате грешке",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Аутоматски истакните команде, путање, IP адресе и нивое логова у терминалном излазу",
"enableCommandPaletteShortcut": "Омогући пречицу за палету команди",
"enableCommandPaletteShortcutDesc": "Двапут додирните леви Shift да бисте отворили палету команди за брз приступ хостовима",
"enableTerminalSessionPersistence": "Трајне терминалне сесије",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Одржавање SSH конекција приликом пребацивања картица или затварања прегледача (може бити нестабилно)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Globala övervakningsinställningar sparade",
"failedToSaveGlobalSettings": "Det gick inte att spara globala övervakningsinställningar",
"failedToLoadGlobalSettings": "Det gick inte att ladda globala övervakningsinställningar",
"guacamoleIntegration": "Integration med fjärrskrivbord (Guacamole)",
"guacamoleIntegrationDesc": "Aktivera RDP, VNC och Telnet anslutningar via guacd. Kräver en guacd instans för att köras.",
"enableGuacamole": "Aktivera stöd för RDP/VNC/Telnet",
"guacdUrl": "guacd URL (värd:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Ändringar av guacd värd/port kräver att en server startar om för att börja gälla.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "justerades till giltigt intervall",
"loadingSessions": "Laddar sessioner...",
"noActiveSessions": "Inga aktiva sessioner hittades.",
"device": "Enhet",
@@ -866,11 +876,21 @@
"importError": "Fel vid import",
"failedToImportJson": "Det gick inte att importera JSON-fil",
"connectionDetails": "Kontaktuppgifter",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organisation",
"ipAddress": "IP-adress eller värdnamn",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Port",
"name": "Namn",
"username": "Användarnamn",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Mapp",
"tags": "Taggar",
"pin": "Fäst",
@@ -979,6 +999,8 @@
"tunnel": "Tunnel",
"fileManager": "Filhanterare",
"serverStats": "Server statistik",
"status": "Status",
"statistics": "Statistik",
"hostViewer": "Värd Viewer",
"enableServerStats": "Aktivera serverstatistik",
"enableServerStatsDesc": "Aktivera/inaktivera serverstatistiksamling för den här värden",
@@ -1028,7 +1050,6 @@
"openFileManager": "Öppna filhanteraren",
"openTunnels": "Öppna tunnlar",
"openServerDetails": "Öppna serverdetaljer",
"statistics": "Statistik",
"enabledWidgets": "Aktiverade widgetar",
"openServerStats": "Öppna serverstatistik",
"enabledWidgetsDesc": "Välj vilken statistik-widgets som ska visas för denna värd",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Kontrollera om servern är online eller offline",
"statusCheckInterval": "Intervall för statuskontroll",
"statusCheckIntervalDesc": "Hur ofta att kontrollera om värd är online (5s - 1h)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Använd global standard",
"useGlobalMetricsInterval": "Använd global standard",
"usingGlobalDefault": "Använda global standard ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Aktivera Metrics Monitoring",
"metricsEnabledDesc": "Samla CPU, RAM, disk och annan systemstatistik",
"metricsInterval": "Intervall för Metrics samling",
"metricsIntervalDesc": "Hur ofta man samlar in serverstatistik (5s - 1h)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "sekunder",
"intervalMinutes": "minuter",
"intervalValidation": "Övervakningsintervall måste vara mellan 5 sekunder och 1 timme (3600 sekunder)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Kopiera tunnel URL",
"copyServerStatsUrl": "Kopiera serverstatistik URL",
"copyDockerUrl": "Kopiera Docker-URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Kopiera URL för att öppna appen i helskärmsläge",
"notEnabled": "Docker är inte aktiverat för den här värden. Aktivera den i Värdsinställningar för att använda Docker-funktioner.",
"validating": "Validerar docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Markera alla",
"deselectAll": "Avmarkera alla",
"useGlobalStatusDefault": "Använd Global Standard (Status)",
"useGlobalMetricsDefault": "Använd Global Standard (Metrics)"
"useGlobalMetricsDefault": "Använd Global Standard (Metrics)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Terminal",
@@ -1372,6 +1489,7 @@
"connected": "Ansluten",
"clipboardWriteFailed": "Det gick inte att kopiera till urklipp. Se till att sidan serveras över HTTPS eller localhost.",
"clipboardReadFailed": "Det gick inte att läsa från urklipp. Se till att urklippsbehörigheterna är beviljade.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH-anslutning etablerad",
"authError": "Autentisering misslyckades: {{message}}",
"unknownError": "Okänt fel uppstod",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Markera automatiskt kommandon, sökvägar, IP-adresser och loggnivåer i terminalutdata",
"enableCommandPaletteShortcut": "Aktivera genväg för kommandopalett",
"enableCommandPaletteShortcutDesc": "Dubbeltryck vänster Shift för att öppna kommandopaletten för snabb åtkomst till värdar",
"enableTerminalSessionPersistence": "Beständiga terminalsessioner",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Behåll SSH-anslutningar vid byte av flikar eller stängning av webbläsaren (kan vara instabil)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "บันทึกการตั้งค่าการตรวจสอบทั่วโลกแล้ว",
"failedToSaveGlobalSettings": "ไม่สามารถบันทึกการตั้งค่าการตรวจสอบทั่วโลกได้",
"failedToLoadGlobalSettings": "ไม่สามารถโหลดการตั้งค่าการตรวจสอบทั่วโลกได้",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "กำลังโหลดเซสชัน...",
"noActiveSessions": "ไม่พบเซสชันที่ใช้งานอยู่",
"device": "อุปกรณ์",
@@ -866,11 +876,21 @@
"importError": "ข้อผิดพลาดในการนำเข้า",
"failedToImportJson": "ไม่สามารถนำเข้าไฟล์ JSON ได้",
"connectionDetails": "รายละเอียดการเชื่อมต่อ",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "องค์กร",
"ipAddress": "ที่อยู่ IP หรือชื่อโฮสต์",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "ท่าเรือ",
"name": "ชื่อ",
"username": "ชื่อผู้ใช้",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "โฟลเดอร์",
"tags": "แท็ก",
"pin": "เข็มหมุด",
@@ -979,6 +999,8 @@
"tunnel": "อุโมงค์",
"fileManager": "ตัวจัดการไฟล์",
"serverStats": "สถิติเซิร์ฟเวอร์",
"status": "Status",
"statistics": "สถิติ",
"hostViewer": "โฮสต์ผู้ชม",
"enableServerStats": "เปิดใช้งานสถิติเซิร์ฟเวอร์",
"enableServerStatsDesc": "เปิด/ปิดการเก็บรวบรวมสถิติเซิร์ฟเวอร์สำหรับโฮสต์นี้",
@@ -1028,7 +1050,6 @@
"openFileManager": "เปิดตัวจัดการไฟล์",
"openTunnels": "อุโมงค์เปิด",
"openServerDetails": "ดูรายละเอียดเซิร์ฟเวอร์",
"statistics": "สถิติ",
"enabledWidgets": "วิดเจ็ตที่เปิดใช้งาน",
"openServerStats": "เปิดสถิติเซิร์ฟเวอร์",
"enabledWidgetsDesc": "เลือกวิดเจ็ตแสดงสถิติที่จะแสดงสำหรับโฮสต์นี้",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "ตรวจสอบว่าเซิร์ฟเวอร์ออนไลน์หรือออฟไลน์อยู่",
"statusCheckInterval": "ช่วงเวลาตรวจสอบสถานะ",
"statusCheckIntervalDesc": "ควรตรวจสอบสถานะออนไลน์ของโฮสต์บ่อยแค่ไหน (5 วินาที - 1 ชั่วโมง)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "ใช้ค่าเริ่มต้นทั่วโลก",
"useGlobalMetricsInterval": "ใช้ค่าเริ่มต้นทั่วโลก",
"usingGlobalDefault": "ใช้ค่าเริ่มต้นทั่วโลก ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "เปิดใช้งานการตรวจสอบเมตริก",
"metricsEnabledDesc": "รวบรวมสถิติ CPU, RAM, ดิสก์ และข้อมูลระบบอื่นๆ",
"metricsInterval": "ช่วงเวลาการเก็บรวบรวมเมตริก",
"metricsIntervalDesc": "ควรเก็บรวบรวมสถิติเซิร์ฟเวอร์บ่อยแค่ไหน (5 วินาที - 1 ชั่วโมง)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "วินาที",
"intervalMinutes": "นาที",
"intervalValidation": "ช่วงเวลาการตรวจสอบต้องอยู่ระหว่าง 5 วินาทีถึง 1 ชั่วโมง (3600 วินาที)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "คัดลอก URL อุโมงค์",
"copyServerStatsUrl": "คัดลอก URL สถิติเซิร์ฟเวอร์",
"copyDockerUrl": "คัดลอก URL ของ Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "คัดลอก URL เพื่อเปิดแอปนี้ในโหมดเต็มหน้าจอ",
"notEnabled": "Docker ยังไม่ได้เปิดใช้งานสำหรับโฮสต์นี้ โปรดเปิดใช้งานใน การตั้งค่าโฮสต์ เพื่อใช้งานคุณสมบัติของ Docker",
"validating": "กำลังตรวจสอบความถูกต้องของ Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "เลือกทั้งหมด",
"deselectAll": "ยกเลิกการเลือกทั้งหมด",
"useGlobalStatusDefault": "ใช้ค่าเริ่มต้นทั่วโลก (สถานะ)",
"useGlobalMetricsDefault": "ใช้ค่าเริ่มต้นทั่วโลก (เมตริก)"
"useGlobalMetricsDefault": "ใช้ค่าเริ่มต้นทั่วโลก (เมตริก)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "เทอร์มินัล",
@@ -1372,6 +1489,7 @@
"connected": "เชื่อมต่อแล้ว",
"clipboardWriteFailed": "ไม่สามารถคัดลอกไปยังคลิปบอร์ดได้ โปรดตรวจสอบให้แน่ใจว่าหน้าเว็บนั้นให้บริการผ่าน HTTPS หรือ localhost",
"clipboardReadFailed": "ไม่สามารถอ่านข้อมูลจากคลิปบอร์ดได้ โปรดตรวจสอบให้แน่ใจว่าได้ให้สิทธิ์การเข้าถึงคลิปบอร์ดแล้ว",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "การเชื่อมต่อ SSH สำเร็จแล้ว",
"authError": "การตรวจสอบสิทธิ์ล้มเหลว: {{message}}",
"unknownError": "เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "ไฮไลต์คำสั่ง เส้นทาง ที่อยู่ IP และระดับการบันทึกในเอาต์พุตเทอร์มินัลโดยอัตโนมัติ",
"enableCommandPaletteShortcut": "เปิดใช้งานทางลัด Command Palette",
"enableCommandPaletteShortcutDesc": "กดปุ่ม Shift ซ้ายสองครั้งเพื่อเปิด Command Palette สำหรับเข้าถึงโฮสต์อย่างรวดเร็ว",
"enableTerminalSessionPersistence": "เซสชันเทอร์มินัลแบบถาวร",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "รักษาการเชื่อมต่อ SSH ไว้เมื่อสลับแท็บหรือปิดเบราว์เซอร์ (อาจไม่เสถียร)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Küresel izleme ayarları kaydedildi.",
"failedToSaveGlobalSettings": "Küresel izleme ayarları kaydedilemedi.",
"failedToLoadGlobalSettings": "Küresel izleme ayarları yüklenemedi.",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Oturumlar yükleniyor...",
"noActiveSessions": "Aktif oturum bulunamadı.",
"device": "Cihaz",
@@ -866,11 +876,21 @@
"importError": "İçe aktarma hatası",
"failedToImportJson": "JSON dosyasını içe aktarma başarısız oldu.",
"connectionDetails": "Bağlantı Ayrıntıları",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Organizasyon",
"ipAddress": "IP Adresi veya Ana Bilgisayar Adı",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Liman",
"name": "İsim",
"username": "Kullanıcı adı",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Dosya",
"tags": "Etiketler",
"pin": "Pin",
@@ -979,6 +999,8 @@
"tunnel": "Tünel",
"fileManager": "Dosya Yöneticisi",
"serverStats": "Sunucu İstatistikleri",
"status": "Status",
"statistics": "İstatistikler",
"hostViewer": "Sunucu İzleyici",
"enableServerStats": "Sunucu İstatistiklerini Etkinleştir",
"enableServerStatsDesc": "Bu sunucu için sunucu istatistiklerinin toplanmasını etkinleştir/devre dışı bırak",
@@ -1028,7 +1050,6 @@
"openFileManager": "Dosya Yöneticisini Açın",
"openTunnels": "Açık Tüneller",
"openServerDetails": "Sunucu Ayrıntılarını Aç",
"statistics": "İstatistikler",
"enabledWidgets": "Etkinleştirilmiş Widget'lar",
"openServerStats": "Sunucu İstatistiklerini Aç",
"enabledWidgetsDesc": "Bu sunucu için hangi istatistik araçlarının görüntüleneceğini seçin.",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Sunucunun çevrimiçi mi yoksa çevrimdışı mı olduğunu kontrol edin.",
"statusCheckInterval": "Durum Kontrol Aralığı",
"statusCheckIntervalDesc": "Sunucunun çevrimiçi olup olmadığını ne sıklıkla kontrol etmeli (5 saniye - 1 saat)?",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Genel varsayılanı kullanın",
"useGlobalMetricsInterval": "Genel varsayılanı kullanın",
"usingGlobalDefault": "Genel varsayılanı kullanma ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Metrik İzlemeyi Etkinleştir",
"metricsEnabledDesc": "CPU, RAM, disk ve diğer sistem istatistiklerini toplayın.",
"metricsInterval": "Ölçüm Toplama Aralığı",
"metricsIntervalDesc": "Sunucu istatistikleri ne sıklıkla toplanmalı (5 saniye - 1 saat)?",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "saniyeler",
"intervalMinutes": "dakika",
"intervalValidation": "İzleme aralıkları 5 saniye ile 1 saat (3600 saniye) arasında olmalıdır.",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Tünel URL'sini Kopyala",
"copyServerStatsUrl": "Sunucu İstatistikleri URL'sini Kopyala",
"copyDockerUrl": "Docker URL'sini kopyala",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Bu uygulamayı tam ekran modunda açmak için URL'yi kopyalayın.",
"notEnabled": "Bu sunucuda Docker etkinleştirilmemiş. Docker özelliklerini kullanmak için Sunucu Ayarları'ndan etkinleştirin.",
"validating": "Docker doğrulaması yapılıyor...",
@@ -1348,7 +1375,97 @@
"selectAll": "Tümünü seç",
"deselectAll": "Tüm seçimleri kaldır",
"useGlobalStatusDefault": "Genel Varsayılanı (Durumu) Kullan",
"useGlobalMetricsDefault": "Genel Varsayılanı Kullan (Ölçütler)"
"useGlobalMetricsDefault": "Genel Varsayılanı Kullan (Ölçütler)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "terminal",
@@ -1372,6 +1489,7 @@
"connected": "Bağlı",
"clipboardWriteFailed": "Kopyalama işlemi panoya yapılamadı. Sayfanın HTTPS veya localhost üzerinden sunulduğundan emin olun.",
"clipboardReadFailed": "Panodan okuma işlemi başarısız oldu. Lütfen pano izinlerinin verildiğinden emin olun.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH bağlantısı kuruldu",
"authError": "Kimlik doğrulama başarısız oldu: {{message}}",
"unknownError": "Bilinmeyen bir hata oluştu.",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Terminal çıktısında komutları, yolları, IP adreslerini ve günlük seviyelerini otomatik olarak vurgula.",
"enableCommandPaletteShortcut": "Komut Paleti Kısayolunu Etkinleştir",
"enableCommandPaletteShortcutDesc": "Ana bilgisayarlara hızlı erişim için Komut Paletini açmak üzere sol Shift tuşuna iki kez dokunun.",
"enableTerminalSessionPersistence": "Kalıcı Terminal Oturumları",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Sekmeler arasında geçiş yaparken veya tarayıcıyı kapatırken SSH bağlantısını sürdürün (bu işlem kararsız olabilir)."
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Глобальні налаштування моніторингу збережено",
"failedToSaveGlobalSettings": "Не вдалося зберегти глобальні параметри моніторингу",
"failedToLoadGlobalSettings": "Не вдалося завантажити налаштування глобального моніторингу",
"guacamoleIntegration": "Інтерграція з віддаленим робочим процесом (Guacamole)",
"guacamoleIntegrationDesc": "Увімкнути RDP, VNC та Telnet-з'єднання через guacd. Вимагає додаткового екземпляра guacd.",
"enableGuacamole": "Увімкнути підтримку RDP/VNC/Telnet",
"guacdUrl": "URL guacd (хост:порт)",
"guacdUrlPlaceholder": "гуак:4822",
"guacdUrlNote": "Зміни на хост/порт guacd вимагає перезавантаження сервера для набуття чинності.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "було скориговано до дійсного діапазону",
"loadingSessions": "Завантаження сесій...",
"noActiveSessions": "Активних сесій не знайдено.",
"device": "Пристрій",
@@ -866,11 +876,21 @@
"importError": "Помилка імпорту",
"failedToImportJson": "Не вдалося імпортувати файл JSON",
"connectionDetails": "Відомості про підключення",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Організація",
"ipAddress": "IP-адреса або ім'я хоста",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Порт",
"name": "Ім'я",
"username": "Ім'я користувача",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Тека",
"tags": "Мітки",
"pin": "Закріплення повідомлень",
@@ -979,6 +999,8 @@
"tunnel": "Тунель",
"fileManager": "Файловий менеджер",
"serverStats": "Статистика на сервері",
"status": "Status",
"statistics": "Статистика",
"hostViewer": "Перегляд хоста",
"enableServerStats": "Увімкнути статистику сервера",
"enableServerStatsDesc": "Увімкнути/вимкнути збір статистики серверу для цього хосту",
@@ -1028,7 +1050,6 @@
"openFileManager": "Відкрити файловий менеджер",
"openTunnels": "Відкрити тунель",
"openServerDetails": "Відкрити деталі сервера",
"statistics": "Статистика",
"enabledWidgets": "Увімкнути віджети",
"openServerStats": "Відкрити статистику сервера",
"enabledWidgetsDesc": "Виберіть віджети статистики для цього хосту",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Перевірте, чи знаходиться сервер онлайн або офлайн",
"statusCheckInterval": "Інтервал перевірки стану",
"statusCheckIntervalDesc": "Як часто слід перевіряти, чи є хост в мережі (5 с - 1 год)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Використовувати глобальний типовий",
"useGlobalMetricsInterval": "Використовувати глобальний типовий",
"usingGlobalDefault": "Використання глобального значення за замовчуванням ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Увімкнути моніторинг метрик",
"metricsEnabledDesc": "Зберіть CPU, RAM, диск та іншу системну статистику",
"metricsInterval": "Інтервал збору метрик",
"metricsIntervalDesc": "Як часто збирати статистику серверу (5 с - 1 год)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "секунди",
"intervalMinutes": "хвилин",
"intervalValidation": "Період моніторингу повинна бути від 5 секунд до 1 години (3600 секунд)",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Копіювати URL тунелю",
"copyServerStatsUrl": "Скопіювати URL-адресу статистики сервера",
"copyDockerUrl": "Копіювати Docker URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Скопіюйте URL, щоб відкрити цей додаток у повноекранному режимі",
"notEnabled": "Docker вимкнений для цього хоста. Увімкніть його в налаштуваннях Хоста, щоб використовувати Docker функції.",
"validating": "Перевірка Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Виділити все",
"deselectAll": "Зняти всі виділення",
"useGlobalStatusDefault": "Використовувати глобальний типовий (стан)",
"useGlobalMetricsDefault": "Використовувати глобальний типовий (метрики)"
"useGlobalMetricsDefault": "Використовувати глобальний типовий (метрики)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Термінал",
@@ -1372,6 +1489,7 @@
"connected": "Підключено",
"clipboardWriteFailed": "Не вдалося скопіювати до буфера обміну. Переконайтеся, що сторінка подається через HTTPS або localhost.",
"clipboardReadFailed": "Не вдалося прочитати з буфера обміну. Переконайтеся, що дозволи доступу до буфера обміну надані.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "SSH підключення встановлено",
"authError": "Помилка автентифікації: {{message}}",
"unknownError": "Сталася невідома помилка",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Автоматично підсвічувати команди, шляхи, IP і рівні логів в терміналі",
"enableCommandPaletteShortcut": "Увімкнути ярлик команди",
"enableCommandPaletteShortcutDesc": "Двічі натисніть зліва Shift, щоб відкрити командну палітру для швидкого доступу до хостів",
"enableTerminalSessionPersistence": "Постійні термінали",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Зберігати SSH з'єднання при перемиканні вкладок або закритті браузера (може бути нестабільним)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "Cài đặt giám sát toàn cầu đã được lưu",
"failedToSaveGlobalSettings": "Không thể lưu cài đặt giám sát toàn cầu.",
"failedToLoadGlobalSettings": "Không thể tải cài đặt giám sát toàn cầu.",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "Đang tải phiên...",
"noActiveSessions": "Không tìm thấy phiên hoạt động nào.",
"device": "Thiết bị",
@@ -866,11 +876,21 @@
"importError": "Lỗi nhập khẩu",
"failedToImportJson": "Không thể nhập tệp JSON.",
"connectionDetails": "Chi tiết kết nối",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "Tổ chức",
"ipAddress": "Địa chỉ IP hoặc tên máy chủ",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "Cảng",
"name": "Tên",
"username": "Tên người dùng",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "Thư mục",
"tags": "Thẻ",
"pin": "Ghim",
@@ -979,6 +999,8 @@
"tunnel": "Đường hầm",
"fileManager": "Trình quản lý tập tin",
"serverStats": "Thống kê máy chủ",
"status": "Status",
"statistics": "Thống kê",
"hostViewer": "Người xem chủ trì",
"enableServerStats": "Bật thống kê máy chủ",
"enableServerStatsDesc": "Bật/tắt tính năng thu thập số liệu thống kê máy chủ cho máy chủ này",
@@ -1028,7 +1050,6 @@
"openFileManager": "Mở trình quản lý tệp",
"openTunnels": "Đường hầm mở",
"openServerDetails": "Chi tiết máy chủ mở",
"statistics": "Thống kê",
"enabledWidgets": "Các tiện ích đã được bật",
"openServerStats": "Thống kê máy chủ mở",
"enabledWidgetsDesc": "Chọn các tiện ích thống kê bạn muốn hiển thị cho máy chủ này.",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "Kiểm tra xem máy chủ đang trực tuyến hay ngoại tuyến.",
"statusCheckInterval": "Khoảng thời gian kiểm tra trạng thái",
"statusCheckIntervalDesc": "Tần suất kiểm tra xem máy chủ có trực tuyến hay không (5 giây - 1 giờ)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "Sử dụng mặc định toàn cầu",
"useGlobalMetricsInterval": "Sử dụng mặc định toàn cầu",
"usingGlobalDefault": "Sử dụng mặc định toàn cầu ({{value}}s)",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "Bật tính năng giám sát số liệu",
"metricsEnabledDesc": "Thu thập số liệu thống kê về CPU, RAM, ổ đĩa và các thông số khác của hệ thống.",
"metricsInterval": "Khoảng thời gian thu thập số liệu",
"metricsIntervalDesc": "Tần suất thu thập số liệu thống kê máy chủ (5 giây - 1 giờ)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "giây",
"intervalMinutes": "phút",
"intervalValidation": "Khoảng thời gian giám sát phải nằm trong khoảng từ 5 giây đến 1 giờ (3600 giây).",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "Sao chép URL đường hầm",
"copyServerStatsUrl": "Sao chép URL Thống kê Máy chủ",
"copyDockerUrl": "Sao chép URL Docker",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "Sao chép URL để mở ứng dụng này ở chế độ toàn màn hình",
"notEnabled": "Docker chưa được kích hoạt trên máy chủ này. Hãy kích hoạt nó trong Cài đặt máy chủ để sử dụng các tính năng của Docker.",
"validating": "Đang xác thực Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "Chọn tất cả",
"deselectAll": "Bỏ chọn tất cả",
"useGlobalStatusDefault": "Sử dụng cài đặt mặc định toàn cầu (Trạng thái)",
"useGlobalMetricsDefault": "Sử dụng cài đặt mặc định toàn cầu (Số liệu)"
"useGlobalMetricsDefault": "Sử dụng cài đặt mặc định toàn cầu (Số liệu)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "Phần cuối",
@@ -1372,6 +1489,7 @@
"connected": "Đã kết nối",
"clipboardWriteFailed": "Không thể sao chép vào clipboard. Hãy đảm bảo trang được phục vụ qua HTTPS hoặc localhost.",
"clipboardReadFailed": "Không thể đọc dữ liệu từ clipboard. Hãy đảm bảo rằng bạn đã cấp quyền truy cập clipboard.",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "Đã thiết lập kết nối SSH",
"authError": "Xác thực thất bại: {{message}}",
"unknownError": "Lỗi không xác định đã xảy ra",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "Tự động tô sáng các lệnh, đường dẫn, địa chỉ IP và cấp độ nhật ký trong đầu ra thiết bị đầu cuối.",
"enableCommandPaletteShortcut": "Bật phím tắt Bảng lệnh",
"enableCommandPaletteShortcutDesc": "Nhấn đúp phím Shift trái để mở Bảng lệnh, cho phép truy cập nhanh vào các máy chủ.",
"enableTerminalSessionPersistence": "Phiên thiết bị đầu cuối liên tục",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "Duy trì kết nối SSH khi chuyển đổi tab hoặc đóng trình duyệt (có thể không ổn định)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "全局监控设置已保存",
"failedToSaveGlobalSettings": "无法保存全局监控设置",
"failedToLoadGlobalSettings": "加载全局监控设置失败",
"guacamoleIntegration": "远程桌面集成 (Guacamole)",
"guacamoleIntegrationDesc": "启用 RDP, VNC 和 Telnet 连接通过 guacd 。需要一个guacd 实例才能运行。",
"enableGuacamole": "启用 RDP/VNC/Telnet 支持",
"guacdUrl": "guacd URL (主机:端口)",
"guacdUrlPlaceholder": "guacd4822",
"guacdUrlNote": "要更改guacd 主机/端口,需要重新启动服务器才能生效。",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "被调整为有效范围",
"loadingSessions": "正在加载会话...",
"noActiveSessions": "未找到活动会话。",
"device": "设备",
@@ -866,11 +876,21 @@
"importError": "导入错误",
"failedToImportJson": "导入 JSON 文件失败",
"connectionDetails": "连接详情",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "组织",
"ipAddress": "IP地址或主机名",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "端口",
"name": "名称",
"username": "用户名",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "文件夹",
"tags": "标签",
"pin": "置顶",
@@ -979,6 +999,8 @@
"tunnel": "隧道",
"fileManager": "文件管理器",
"serverStats": "服务器统计信息",
"status": "Status",
"statistics": "统计数据",
"hostViewer": "主机查看器",
"enableServerStats": "启用服务器统计信息",
"enableServerStatsDesc": "启用/禁用此主机的服务器统计信息收集",
@@ -1028,7 +1050,6 @@
"openFileManager": "打开文件管理器",
"openTunnels": "已开启隧道",
"openServerDetails": "打开服务器详情",
"statistics": "统计数据",
"enabledWidgets": "已启用的小部件",
"openServerStats": "打开服务器统计信息",
"enabledWidgetsDesc": "选择要为此主机显示的统计信息小部件",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "检查服务器是否在线或离线",
"statusCheckInterval": "状态检查间隔",
"statusCheckIntervalDesc": "检查主机是否在线的频率(5秒 - 1小时)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "使用全局默认值",
"useGlobalMetricsInterval": "使用全局默认值",
"usingGlobalDefault": "使用全局默认值({{value}}s",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "启用指标监控",
"metricsEnabledDesc": "收集 CPU、RAM、磁盘和其他系统统计信息",
"metricsInterval": "指标收集间隔",
"metricsIntervalDesc": "服务器统计信息收集频率(5秒-1小时)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "秒",
"intervalMinutes": "分钟",
"intervalValidation": "监测间隔必须在 5 秒到 1 小时(3600 秒)之间。",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "复制隧道 URL",
"copyServerStatsUrl": "复制服务器统计信息 URL",
"copyDockerUrl": "复制 Docker URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "复制 URL 以全屏模式打开此应用",
"notEnabled": "此主机未启用 Docker。请在主机设置中启用 Docker 以使用 Docker 功能。",
"validating": "正在验证 Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "选择所有",
"deselectAll": "取消全选",
"useGlobalStatusDefault": "使用全局默认(状态)",
"useGlobalMetricsDefault": "使用全局默认值(计量)"
"useGlobalMetricsDefault": "使用全局默认值(计量)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "终端",
@@ -1372,6 +1489,7 @@
"connected": "已连接",
"clipboardWriteFailed": "复制到剪贴板失败。请确认页面是通过 HTTPS 或本地主机服务的。",
"clipboardReadFailed": "从剪贴板读取失败。请确保已授予剪贴板权限。",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "已建立 SSH 连接",
"authError": "身份验证失败:{{message}}",
"unknownError": "发生未知错误",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "自动高亮终端输出中的命令、路径、IP 地址和日志级别",
"enableCommandPaletteShortcut": "启用命令面板快捷键",
"enableCommandPaletteShortcutDesc": "双击左Shift键打开命令面板,以便快速访问主机。",
"enableTerminalSessionPersistence": "持续的终端会话",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "切换标签页或关闭浏览器时保持SSH 连接 (可能不稳定)"
},
"user": {
+121 -3
View File
@@ -808,6 +808,16 @@
"globalSettingsSaved": "已儲存全域監控設定",
"failedToSaveGlobalSettings": "儲存全域監控設定失敗",
"failedToLoadGlobalSettings": "載入全域監控設定失敗",
"guacamoleIntegration": "Remote Desktop Integration (Guacamole)",
"guacamoleIntegrationDesc": "Enable RDP, VNC, and Telnet connections via guacd. Requires a guacd instance to be running.",
"enableGuacamole": "Enable RDP/VNC/Telnet support",
"guacdUrl": "guacd URL (host:port)",
"guacdUrlPlaceholder": "guacd:4822",
"guacdUrlNote": "Changes to the guacd host/port require a server restart to take effect.",
"guacamoleSettingsSaved": "Guacamole settings saved",
"failedToSaveGuacamoleSettings": "Failed to save guacamole settings",
"failedToLoadGuacamoleSettings": "Failed to load guacamole settings",
"clampedToValidRange": "was adjusted to valid range",
"loadingSessions": "正在載入會話...",
"noActiveSessions": "未找到活動會話。",
"device": "裝置",
@@ -866,11 +876,21 @@
"importError": "導入錯誤",
"failedToImportJson": "導入 JSON 檔案失敗",
"connectionDetails": "連線詳情",
"connectionType": "Connection Type",
"ssh": "SSH",
"rdp": "RDP",
"vnc": "VNC",
"telnet": "Telnet",
"remoteDesktop": "Remote Desktop",
"guacamoleSettings": "Remote Desktop Settings",
"organization": "組織",
"ipAddress": "IP位址或主機名",
"ipRequired": "IP address is required",
"portRequired": "Port is required",
"port": "連接埠",
"name": "姓名",
"username": "使用者名稱",
"usernameRequired": "Username is required (SSH/Telnet only)",
"folder": "資料夾",
"tags": "標籤",
"pin": "置頂",
@@ -979,6 +999,8 @@
"tunnel": "隧道",
"fileManager": "檔案管理器",
"serverStats": "伺服器統計訊息",
"status": "Status",
"statistics": "統計數據",
"hostViewer": "主機檢視器",
"enableServerStats": "啟用伺服器統計訊息",
"enableServerStatsDesc": "啟用/停用此主機的伺服器統計資料收集",
@@ -1028,7 +1050,6 @@
"openFileManager": "開啟檔案管理器",
"openTunnels": "開放式隧道",
"openServerDetails": "開啟伺服器詳情",
"statistics": "統計數據",
"enabledWidgets": "已啟用的小工具",
"openServerStats": "開放伺服器統計數據",
"enabledWidgetsDesc": "選擇要為此主機顯示的統計資訊小工具",
@@ -1038,13 +1059,18 @@
"statusCheckEnabledDesc": "檢查伺服器是否在線或離線",
"statusCheckInterval": "狀態檢查間隔",
"statusCheckIntervalDesc": "檢查主機是否在線的頻率(5秒 - 1小時)",
"statusChecks": "Status Checks",
"disableTcpPing": "Disable TCP Ping",
"disableTcpPingDescription": "Turn off status checks (online/offline detection) for this host",
"useGlobalStatusInterval": "使用全域預設值",
"useGlobalMetricsInterval": "使用全域預設值",
"usingGlobalDefault": "使用全域預設值({{value}}s",
"metricsCollection": "Metrics Collection",
"metricsEnabled": "啟用指標監控",
"metricsEnabledDesc": "收集 CPU、RAM、磁碟和其他系統統計訊息",
"metricsInterval": "指標收集間隔",
"metricsIntervalDesc": "伺服器統計資訊收集頻率(5秒-1小時)",
"metricsNotAvailableForConnectionType": "Server metrics are only available for SSH hosts. TCP ping status checks can still be enabled above.",
"intervalSeconds": "秒",
"intervalMinutes": "分分鐘",
"intervalValidation": "監測間隔必須在 5 秒到 1 小時(3600 秒)之間。",
@@ -1232,6 +1258,7 @@
"copyTunnelUrl": "複製隧道 URL",
"copyServerStatsUrl": "複製伺服器統計資料 URL",
"copyDockerUrl": "複製 Docker URL",
"copyRemoteDesktopUrl": "Copy Remote Desktop URL",
"fullScreenUrlTooltip": "複製 URL 以全螢幕模式開啟此應用",
"notEnabled": "此主機未啟用 Docker。請在主機設定中啟用 Docker 以使用 Docker 功能。",
"validating": "正在驗證 Docker...",
@@ -1348,7 +1375,97 @@
"selectAll": "全選",
"deselectAll": "取消選擇所有",
"useGlobalStatusDefault": "使用全域預設值(狀態)",
"useGlobalMetricsDefault": "使用全域預設值(指標)"
"useGlobalMetricsDefault": "使用全域預設值(指標)",
"remoteDesktopSettings": "Remote Desktop Settings",
"domain": "Domain",
"securityMode": "Security Mode",
"ignoreCert": "Ignore Certificate",
"ignoreCertDesc": "Skip TLS certificate verification for this connection",
"displaySettings": "Display Settings",
"colorDepth": "Color Depth",
"width": "Width",
"height": "Height",
"dpi": "DPI",
"resizeMethod": "Resize Method",
"forceLossless": "Force Lossless",
"audioSettings": "Audio Settings",
"disableAudio": "Disable Audio",
"enableAudioInput": "Enable Audio Input",
"rdpPerformance": "Performance",
"enableWallpaper": "Enable Wallpaper",
"enableTheming": "Enable Theming",
"enableFontSmoothing": "Enable Font Smoothing",
"enableFullWindowDrag": "Enable Full Window Drag",
"enableDesktopComposition": "Enable Desktop Composition",
"enableMenuAnimations": "Enable Menu Animations",
"disableBitmapCaching": "Disable Bitmap Caching",
"disableOffscreenCaching": "Disable Offscreen Caching",
"disableGlyphCaching": "Disable Glyph Caching",
"enableGfx": "Enable GFX",
"deviceRedirection": "Device Redirection",
"enablePrinting": "Enable Printing",
"enableDrive": "Enable Drive Redirection",
"driveName": "Drive Name",
"drivePath": "Drive Path",
"createDrivePath": "Create Drive Path",
"disableDownload": "Disable Download",
"disableUpload": "Disable Upload",
"enableTouch": "Enable Touch",
"rdpSession": "Session",
"clientName": "Client Name",
"consoleSession": "Console Session",
"initialProgram": "Initial Program",
"serverLayout": "Server Keyboard Layout",
"timezone": "Timezone",
"gatewaySettings": "Gateway",
"gatewayHostname": "Gateway Hostname",
"gatewayPort": "Gateway Port",
"gatewayUsername": "Gateway Username",
"gatewayPassword": "Gateway Password",
"gatewayDomain": "Gateway Domain",
"remoteApp": "RemoteApp",
"remoteAppProgram": "Remote Application",
"remoteAppDir": "Remote App Directory",
"remoteAppArgs": "Remote App Arguments",
"clipboardSettings": "Clipboard",
"normalizeClipboard": "Normalize Clipboard",
"disableCopy": "Disable Copy",
"disablePaste": "Disable Paste",
"vncSettings": "VNC Settings",
"cursorMode": "Cursor Mode",
"swapRedBlue": "Swap Red/Blue",
"readOnly": "Read Only",
"recordingSettings": "Recording",
"recordingPath": "Recording Path",
"recordingName": "Recording Name",
"createRecordingPath": "Create Recording Path",
"excludeOutput": "Exclude Output",
"excludeMouse": "Exclude Mouse",
"includeKeys": "Include Keys",
"wakeOnLan": "Wake-on-LAN",
"sendWolPacket": "Send WoL Packet",
"wolMacAddr": "MAC Address",
"wolBroadcastAddr": "Broadcast Address",
"wolUdpPort": "UDP Port",
"wolWaitTime": "Wait Time (seconds)",
"connectionSettings": "Connection Settings",
"rdpOnly": "RDP only",
"vncOnly": "VNC only",
"telnetTerminalSettings": "Terminal Settings",
"terminalType": "Terminal Type",
"guacFontName": "Font Name",
"guacFontSize": "Font Size",
"guacColorScheme": "Color Scheme",
"guacBackspaceKey": "Backspace Key"
},
"guacamole": {
"connecting": "Connecting to {{type}} session...",
"rdpConnecting": "Connecting to RDP server...",
"vncConnecting": "Connecting to VNC server...",
"telnetConnecting": "Connecting to Telnet server...",
"connectionError": "Connection error",
"connectionFailed": "Connection failed",
"failedToConnect": "Failed to get connection token"
},
"terminal": {
"title": "終端機",
@@ -1372,6 +1489,7 @@
"connected": "已連接",
"clipboardWriteFailed": "複製到剪貼簿失敗。請確保頁面是透過 HTTPS 或本地主機存取的。",
"clipboardReadFailed": "讀取剪貼簿內容失敗。請確保已授予剪貼簿權限。",
"clipboardHttpWarning": "Paste requires HTTPS. Use Ctrl+Shift+V or serve Termix over HTTPS.",
"sshConnected": "已建立 SSH 連接",
"authError": "驗證失敗: {{message}}",
"unknownError": "發生未知錯誤",
@@ -2154,7 +2272,7 @@
"terminalSyntaxHighlightingDesc": "自動高亮顯示終端輸出中的指令、路徑、IP位址和日誌等級",
"enableCommandPaletteShortcut": "啟用指令面板快速鍵",
"enableCommandPaletteShortcutDesc": "雙擊左 Shift 鍵開啟指令面板,以便快速存取主機。",
"enableTerminalSessionPersistence": "持久終端會話",
"enableTerminalSessionPersistence": "Persistent Tabs/Sessions",
"enableTerminalSessionPersistenceDesc": "切換標籤頁或關閉瀏覽器時保持 SSH 連線(可能不穩定)"
},
"user": {
+6 -1
View File
@@ -8,12 +8,13 @@ import { ThemeProvider } from "@/components/theme-provider";
import { ElectronVersionCheck } from "@/ui/desktop/user/ElectronVersionCheck.tsx";
import "./i18n/i18n";
import { isElectron } from "./ui/main-axios.ts";
import HostManagerApp from "./ui/desktop/apps/HostManagerApp.tsx";
import HostManagerApp from "./ui/desktop/apps/host-manager/HostManagerApp.tsx";
import TerminalApp from "./ui/desktop/apps/features/terminal/TerminalApp.tsx";
import FileManagerApp from "./ui/desktop/apps/features/file-manager/FileManagerApp.tsx";
import TunnelApp from "./ui/desktop/apps/features/tunnel/TunnelApp.tsx";
import ServerStatsApp from "./ui/desktop/apps/features/server-stats/ServerStatsApp.tsx";
import DockerApp from "./ui/desktop/apps/features/docker/DockerApp.tsx";
import GuacamoleApp from "@/ui/desktop/apps/features/guacamole/GuacamoleApp.tsx";
const FullscreenApp: React.FC = () => {
const searchParams = new URLSearchParams(window.location.search);
@@ -33,6 +34,10 @@ const FullscreenApp: React.FC = () => {
return <ServerStatsApp hostId={hostId || undefined} />;
case "docker":
return <DockerApp hostId={hostId || undefined} />;
case "rdp":
case "vnc":
case "telnet":
return <GuacamoleApp hostId={hostId || undefined} />;
default:
return <DesktopApp />;
}
+108
View File
@@ -0,0 +1,108 @@
declare module "guacamole-common-js" {
namespace Guacamole {
class Client {
constructor(tunnel: Tunnel);
connect(data?: string): void;
disconnect(): void;
getDisplay(): Display;
sendKeyEvent(pressed: number, keysym: number): void;
sendMouseState(state: Mouse.State): void;
setClipboard(stream: OutputStream, mimetype: string): void;
createClipboardStream(mimetype: string): OutputStream;
onstatechange: ((state: number) => void) | null;
onerror: ((error: Status) => void) | null;
onclipboard: ((stream: InputStream, mimetype: string) => void) | null;
}
class Display {
getElement(): HTMLElement;
getWidth(): number;
getHeight(): number;
scale(scale: number): void;
onresize: (() => void) | null;
}
class Tunnel {
onerror: ((status: Status) => void) | null;
onstatechange: ((state: number) => void) | null;
}
class WebSocketTunnel extends Tunnel {
constructor(url: string);
}
class Mouse {
constructor(element: HTMLElement);
onmousedown: ((state: Mouse.State) => void) | null;
onmouseup: ((state: Mouse.State) => void) | null;
onmousemove: ((state: Mouse.State) => void) | null;
onmouseout: ((state: Mouse.State) => void) | null;
}
namespace Mouse {
class State {
constructor(
x: number,
y: number,
left?: boolean,
middle?: boolean,
right?: boolean,
up?: boolean,
down?: boolean,
);
constructor(state: {
x: number;
y: number;
left?: boolean;
middle?: boolean;
right?: boolean;
up?: boolean;
down?: boolean;
});
x: number;
y: number;
left: boolean;
middle: boolean;
right: boolean;
up: boolean;
down: boolean;
}
}
class Keyboard {
constructor(element: Document | HTMLElement);
onkeydown: ((keysym: number) => void) | null;
onkeyup: ((keysym: number) => void) | null;
}
class Status {
code: number;
message: string;
isError(): boolean;
}
class InputStream {
onblob: ((data: string) => void) | null;
onend: (() => void) | null;
}
class OutputStream {
sendBlob(data: string): void;
sendEnd(): void;
}
class StringReader {
constructor(stream: InputStream);
ontext: ((text: string) => void) | null;
onend: (() => void) | null;
}
class StringWriter {
constructor(stream: OutputStream);
sendText(text: string): void;
sendEnd(): void;
}
}
export default Guacamole;
}
+36 -4
View File
@@ -2,9 +2,21 @@ import type { Client } from "ssh2";
import type { Request } from "express";
// ============================================================================
// SSH HOST TYPES
// HOST TYPES (SSH, RDP, VNC, Telnet)
// ============================================================================
export type ConnectionType = "ssh" | "rdp" | "vnc" | "telnet";
export type SSHAuthType = "password" | "key" | "credential" | "none" | "opkssh";
export type GuacamoleAuthType = "password" | "credential";
export interface HostFeatureFlags {
enableTerminal: boolean; // SSH, Telnet only
enableTunnel: boolean; // SSH only
enableFileManager: boolean; // SSH only
enableDocker: boolean; // SSH only
enableRemoteDesktop: boolean; // RDP, VNC only
}
export interface JumpHost {
hostId: number;
}
@@ -14,7 +26,7 @@ export interface QuickAction {
snippetId: number;
}
export interface SSHHost {
export interface Host {
id: number;
name: string;
ip: string;
@@ -62,6 +74,12 @@ export interface SSHHost {
socks5Password?: string;
socks5ProxyChain?: ProxyNode[];
connectionType?: "ssh" | "rdp" | "vnc" | "telnet";
domain?: string;
security?: string;
ignoreCert?: boolean;
guacamoleConfig?: string | Record<string, unknown>;
createdAt: string;
updatedAt: string;
@@ -87,7 +105,7 @@ export interface ProxyNode {
password?: string;
}
export interface SSHHostData {
export interface HostData {
name?: string;
ip: string;
port: number;
@@ -127,8 +145,18 @@ export interface SSHHostData {
socks5Username?: string;
socks5Password?: string;
socks5ProxyChain?: ProxyNode[];
connectionType?: "ssh" | "rdp" | "vnc" | "telnet";
domain?: string;
security?: string;
ignoreCert?: boolean;
guacamoleConfig?: Record<string, unknown> | null;
dockerConfig?: Record<string, unknown> | null;
}
export type SSHHost = Host;
export type SSHHostData = HostData;
export interface SSHFolder {
id: number;
userId: string;
@@ -415,12 +443,16 @@ export interface TabContextTab {
| "file_manager"
| "user_profile"
| "docker"
| "network_graph";
| "network_graph"
| "rdp"
| "vnc"
| "telnet";
title: string;
hostConfig?: SSHHost;
terminalRef?: any;
initialTab?: string;
_updateTimestamp?: number;
connectionConfig?: Record<string, unknown>;
}
export type SplitLayout = "2h" | "2v" | "3l" | "3r" | "3t" | "4grid";
+2
View File
@@ -57,6 +57,7 @@ export interface StatsConfig {
metricsEnabled: boolean;
metricsInterval: number;
useGlobalMetricsInterval?: boolean;
disableTcpPing?: boolean;
}
export const DEFAULT_STATS_CONFIG: StatsConfig = {
@@ -75,4 +76,5 @@ export const DEFAULT_STATS_CONFIG: StatsConfig = {
metricsEnabled: true,
metricsInterval: 30,
useGlobalMetricsInterval: true,
disableTcpPing: false,
};
+15 -3
View File
@@ -5,6 +5,7 @@ import React, {
useEffect,
useCallback,
useRef,
useMemo,
} from "react";
import { getAllServerStatuses, getSSHHosts } from "@/ui/main-axios";
import { DEFAULT_STATS_CONFIG } from "@/types/stats-widgets";
@@ -71,7 +72,13 @@ export function ServerStatusProvider({
}
});
setEnabledHostIds(enabled);
setEnabledHostIds((prev) => {
if (prev.size !== enabled.size) return enabled;
for (const id of enabled) {
if (!prev.has(id)) return enabled;
}
return prev;
});
return enabled;
} catch (error) {
return new Set<number>();
@@ -125,14 +132,19 @@ export function ServerStatusProvider({
}
}, [isAuthenticated]);
const stableEnabledHostIds = useMemo(
() => enabledHostIds,
[[...enabledHostIds].sort().join(",")],
);
const getStatus = useCallback(
(hostId: number): StatusValue => {
if (!enabledHostIds.has(hostId)) {
if (!stableEnabledHostIds.has(hostId)) {
return "offline";
}
return statuses.get(hostId)?.status || "degraded";
},
[statuses, enabledHostIds],
[statuses, stableEnabledHostIds],
);
useEffect(() => {
+5 -3
View File
@@ -156,9 +156,8 @@ function AppContent({
if (hostIdentifier) {
const openTerminal = async () => {
try {
const { getSSHHostById, getSSHHosts } = await import(
"@/ui/main-axios.ts"
);
const { getSSHHostById, getSSHHosts } =
await import("@/ui/main-axios.ts");
let host = null;
if (/^\d+$/.test(hostIdentifier)) {
@@ -282,6 +281,9 @@ function AppContent({
currentTabData?.type === "terminal" ||
currentTabData?.type === "server_stats" ||
currentTabData?.type === "file_manager" ||
currentTabData?.type === "rdp" ||
currentTabData?.type === "vnc" ||
currentTabData?.type === "telnet" ||
currentTabData?.type === "tunnel" ||
currentTabData?.type === "docker" ||
currentTabData?.type === "network_graph";
@@ -17,7 +17,10 @@ import {
updatePasswordResetAllowed,
getGlobalMonitoringSettings,
updateGlobalMonitoringSettings,
getGuacamoleSettings,
updateGuacamoleSettings,
} from "@/ui/main-axios.ts";
import { Button } from "@/components/ui/button.tsx";
interface GeneralSettingsTabProps {
allowRegistration: boolean;
@@ -51,9 +54,10 @@ export function GeneralSettingsTab({
const [passwordLoginLoading, setPasswordLoginLoading] = React.useState(false);
const [passwordResetLoading, setPasswordResetLoading] = React.useState(false);
// Global monitoring defaults
const [statusInterval, setStatusInterval] = React.useState(60);
const [metricsInterval, setMetricsInterval] = React.useState(30);
const [statusInputValue, setStatusInputValue] = React.useState("60");
const [metricsInputValue, setMetricsInputValue] = React.useState("30");
const [statusUnit, setStatusUnit] = React.useState<"seconds" | "minutes">(
"seconds",
);
@@ -62,55 +66,101 @@ export function GeneralSettingsTab({
);
const [monitoringLoading, setMonitoringLoading] = React.useState(false);
const [guacEnabled, setGuacEnabled] = React.useState(true);
const [guacUrl, setGuacUrl] = React.useState("guacd:4822");
const [guacLoading, setGuacLoading] = React.useState(false);
React.useEffect(() => {
getGlobalMonitoringSettings()
getGuacamoleSettings()
.then((data) => {
setStatusInterval(data.statusCheckInterval);
setMetricsInterval(data.metricsInterval);
setGuacEnabled(data.enabled);
setGuacUrl(data.url);
})
.catch(() => {
// Use defaults silently
toast.error(t("admin.failedToLoadGuacamoleSettings"));
});
}, []);
}, [t]);
const saveMonitoringDebounce = React.useRef<NodeJS.Timeout | null>(null);
const saveGuacDebounce = React.useRef<NodeJS.Timeout | null>(null);
const saveMonitoringSettings = React.useCallback(
(newStatus: number, newMetrics: number) => {
if (saveMonitoringDebounce.current) {
clearTimeout(saveMonitoringDebounce.current);
const saveGuacSettings = React.useCallback(
(newEnabled: boolean, newUrl: string) => {
if (saveGuacDebounce.current) {
clearTimeout(saveGuacDebounce.current);
}
saveMonitoringDebounce.current = setTimeout(async () => {
setMonitoringLoading(true);
saveGuacDebounce.current = setTimeout(async () => {
setGuacLoading(true);
try {
await updateGlobalMonitoringSettings({
statusCheckInterval: newStatus,
metricsInterval: newMetrics,
});
toast.success(t("admin.globalSettingsSaved"));
await updateGuacamoleSettings({ enabled: newEnabled, url: newUrl });
toast.success(t("admin.guacamoleSettingsSaved"));
} catch {
toast.error(t("admin.failedToSaveGlobalSettings"));
toast.error(t("admin.failedToSaveGuacamoleSettings"));
} finally {
setMonitoringLoading(false);
setGuacLoading(false);
}
}, 800);
},
[t],
);
const handleStatusIntervalChange = (value: string) => {
const num = parseInt(value) || 0;
React.useEffect(() => {
getGlobalMonitoringSettings()
.then((data) => {
setStatusInterval(data.statusCheckInterval);
setMetricsInterval(data.metricsInterval);
setStatusInputValue(String(data.statusCheckInterval));
setMetricsInputValue(String(data.metricsInterval));
})
.catch(() => {
// Use defaults silently
});
}, []);
const saveMonitoringSettings = React.useCallback(
async (newStatus: number, newMetrics: number) => {
setMonitoringLoading(true);
try {
await updateGlobalMonitoringSettings({
statusCheckInterval: newStatus,
metricsInterval: newMetrics,
});
toast.success(t("admin.globalSettingsSaved"));
} catch (error) {
const errorMessage =
error instanceof Error
? error.message
: t("admin.failedToSaveGlobalSettings");
toast.error(errorMessage);
} finally {
setMonitoringLoading(false);
}
},
[t],
);
const handleStatusBlur = () => {
const num = parseInt(statusInputValue) || 0;
const seconds = statusUnit === "minutes" ? num * 60 : num;
const clamped = Math.max(5, Math.min(3600, seconds));
setStatusInterval(clamped);
setStatusInputValue(
statusUnit === "minutes"
? String(Math.round(clamped / 60))
: String(clamped),
);
saveMonitoringSettings(clamped, metricsInterval);
};
const handleMetricsIntervalChange = (value: string) => {
const num = parseInt(value) || 0;
const handleMetricsBlur = () => {
const num = parseInt(metricsInputValue) || 0;
const seconds = metricsUnit === "minutes" ? num * 60 : num;
const clamped = Math.max(5, Math.min(3600, seconds));
setMetricsInterval(clamped);
setMetricsInputValue(
metricsUnit === "minutes"
? String(Math.round(clamped / 60))
: String(clamped),
);
saveMonitoringSettings(statusInterval, clamped);
};
@@ -240,12 +290,9 @@ export function GeneralSettingsTab({
<div className="flex gap-2 mt-1">
<Input
type="number"
value={
statusUnit === "minutes"
? Math.round(statusInterval / 60)
: statusInterval
}
onChange={(e) => handleStatusIntervalChange(e.target.value)}
value={statusInputValue}
onChange={(e) => setStatusInputValue(e.target.value)}
onBlur={handleStatusBlur}
disabled={monitoringLoading}
className="flex-1"
/>
@@ -253,6 +300,11 @@ export function GeneralSettingsTab({
value={statusUnit}
onValueChange={(value: "seconds" | "minutes") => {
setStatusUnit(value);
setStatusInputValue(
value === "minutes"
? String(Math.round(statusInterval / 60))
: String(statusInterval),
);
}}
>
<SelectTrigger className="w-[120px]">
@@ -276,12 +328,9 @@ export function GeneralSettingsTab({
<div className="flex gap-2 mt-1">
<Input
type="number"
value={
metricsUnit === "minutes"
? Math.round(metricsInterval / 60)
: metricsInterval
}
onChange={(e) => handleMetricsIntervalChange(e.target.value)}
value={metricsInputValue}
onChange={(e) => setMetricsInputValue(e.target.value)}
onBlur={handleMetricsBlur}
disabled={monitoringLoading}
className="flex-1"
/>
@@ -289,6 +338,11 @@ export function GeneralSettingsTab({
value={metricsUnit}
onValueChange={(value: "seconds" | "minutes") => {
setMetricsUnit(value);
setMetricsInputValue(
value === "minutes"
? String(Math.round(metricsInterval / 60))
: String(metricsInterval),
);
}}
>
<SelectTrigger className="w-[120px]">
@@ -307,6 +361,55 @@ export function GeneralSettingsTab({
</div>
</div>
</div>
<div className="rounded-lg border-2 border-border bg-card p-4 space-y-4">
<h3 className="text-lg font-semibold">
{t("admin.guacamoleIntegration")}
</h3>
<p className="text-sm text-muted-foreground">
{t("admin.guacamoleIntegrationDesc")}
</p>
<Button
variant="outline"
size="sm"
className="h-8 px-3 text-xs"
onClick={() =>
window.open("https://docs.termix.site/remote-desktop", "_blank")
}
>
{t("common.documentation")}
</Button>
<label className="flex items-center gap-2">
<Checkbox
checked={guacEnabled}
onCheckedChange={(checked) => {
const val = checked === true;
setGuacEnabled(val);
saveGuacSettings(val, guacUrl);
}}
disabled={guacLoading}
/>
{t("admin.enableGuacamole")}
</label>
{guacEnabled && (
<div>
<label className="text-sm font-medium">{t("admin.guacdUrl")}</label>
<Input
className="mt-1"
value={guacUrl}
placeholder={t("admin.guacdUrlPlaceholder")}
disabled={guacLoading}
onChange={(e) => {
setGuacUrl(e.target.value);
saveGuacSettings(guacEnabled, e.target.value);
}}
/>
<p className="text-xs text-muted-foreground mt-1">
{t("admin.guacdUrlNote")}
</p>
</div>
)}
</div>
</div>
);
}
@@ -16,6 +16,9 @@ import {
User,
Github,
Terminal,
Monitor,
Eye,
MessagesSquare,
FolderOpen,
Pencil,
EllipsisVertical,
@@ -27,8 +30,14 @@ import { BiMoney, BiSupport } from "react-icons/bi";
import { BsDiscord } from "react-icons/bs";
import { GrUpdate } from "react-icons/gr";
import { useTabs } from "@/ui/desktop/navigation/tabs/TabContext.tsx";
import { getRecentActivity, getSSHHosts } from "@/ui/main-axios.ts";
import {
getRecentActivity,
getSSHHosts,
getGuacamoleToken,
logActivity,
} from "@/ui/main-axios.ts";
import type { RecentActivityItem } from "@/ui/main-axios.ts";
import { toast } from "sonner";
import { DEFAULT_STATS_CONFIG } from "@/types/stats-widgets";
import {
DropdownMenu,
@@ -62,6 +71,16 @@ interface SSHHost {
statsConfig?: string;
createdAt: string;
updatedAt: string;
connectionType?: "ssh" | "rdp" | "vnc" | "telnet";
domain?: string;
security?: string;
ignoreCert?: boolean;
guacamoleConfig?: any;
showTerminalInSidebar?: boolean;
showFileManagerInSidebar?: boolean;
showTunnelInSidebar?: boolean;
showDockerInSidebar?: boolean;
showServerStatsInSidebar?: boolean;
}
export function CommandPalette({
@@ -204,10 +223,60 @@ export function CommandPalette({
setIsOpen(false);
};
const handleHostTerminalClick = (host: SSHHost) => {
const handleHostTerminalClick = async (host: SSHHost) => {
const title = host.name?.trim()
? host.name
: `${host.username}@${host.ip}:${host.port}`;
if (
host.connectionType === "rdp" ||
host.connectionType === "vnc" ||
host.connectionType === "telnet"
) {
try {
const protocol = host.connectionType as "rdp" | "vnc" | "telnet";
const result = await getGuacamoleToken({
protocol,
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
ignoreCert: host.ignoreCert,
guacamoleConfig: host.guacamoleConfig as any,
});
addTab({
type: protocol,
title,
hostConfig: host,
connectionConfig: {
token: result.token,
protocol,
type: protocol,
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
"ignore-cert": host.ignoreCert,
},
});
try {
await logActivity(protocol, host.id, title);
} catch (err) {
console.warn(`Failed to log ${protocol} activity:`, err);
}
} catch (err) {
console.error("Failed to get Guacamole token:", err);
}
setIsOpen(false);
return;
}
addTab({ type: "terminal", title, hostConfig: host });
setIsOpen(false);
};
@@ -340,6 +409,9 @@ export function CommandPalette({
shouldShowMetrics = true;
}
const isSSH =
!host.connectionType || host.connectionType === "ssh";
let hasTunnelConnections = false;
try {
const tunnelConnections = Array.isArray(
@@ -356,13 +428,18 @@ export function CommandPalette({
const visibleButtons = [
host.enableTerminal && (host.showTerminalInSidebar ?? true),
host.enableFileManager &&
isSSH &&
host.enableFileManager &&
(host.showFileManagerInSidebar ?? false),
host.enableTunnel &&
isSSH &&
host.enableTunnel &&
hasTunnelConnections &&
(host.showTunnelInSidebar ?? false),
host.enableDocker && (host.showDockerInSidebar ?? false),
shouldShowMetrics &&
isSSH &&
host.enableDocker &&
(host.showDockerInSidebar ?? false),
isSSH &&
shouldShowMetrics &&
(host.showServerStatsInSidebar ?? false),
].filter(Boolean).length;
@@ -395,11 +472,20 @@ export function CommandPalette({
handleHostTerminalClick(host);
}}
>
<Terminal className="h-3 w-3" />
{host.connectionType === "rdp" ? (
<Monitor className="h-3 w-3" />
) : host.connectionType === "vnc" ? (
<Eye className="h-3 w-3" />
) : host.connectionType === "telnet" ? (
<MessagesSquare className="h-3 w-3" />
) : (
<Terminal className="h-3 w-3" />
)}
</Button>
)}
{host.enableFileManager &&
{isSSH &&
host.enableFileManager &&
(host.showFileManagerInSidebar ?? false) && (
<Button
variant="outline"
@@ -413,7 +499,8 @@ export function CommandPalette({
</Button>
)}
{host.enableTunnel &&
{isSSH &&
host.enableTunnel &&
hasTunnelConnections &&
(host.showTunnelInSidebar ?? false) && (
<Button
@@ -428,7 +515,8 @@ export function CommandPalette({
</Button>
)}
{host.enableDocker &&
{isSSH &&
host.enableDocker &&
(host.showDockerInSidebar ?? false) && (
<Button
variant="outline"
@@ -442,7 +530,8 @@ export function CommandPalette({
</Button>
)}
{shouldShowMetrics &&
{isSSH &&
shouldShowMetrics &&
(host.showServerStatsInSidebar ?? false) && (
<Button
variant="outline"
@@ -484,13 +573,22 @@ export function CommandPalette({
}}
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-hover text-foreground-secondary"
>
<Terminal className="h-4 w-4" />
{host.connectionType === "rdp" ? (
<Monitor className="h-4 w-4" />
) : host.connectionType === "vnc" ? (
<Eye className="h-4 w-4" />
) : host.connectionType === "telnet" ? (
<MessagesSquare className="h-4 w-4" />
) : (
<Terminal className="h-4 w-4" />
)}
<span className="flex-1">
{t("hosts.openTerminal")}
</span>
</DropdownMenuItem>
)}
{shouldShowMetrics &&
{isSSH &&
shouldShowMetrics &&
!(host.showServerStatsInSidebar ?? false) && (
<DropdownMenuItem
onClick={(e) => {
@@ -505,7 +603,8 @@ export function CommandPalette({
</span>
</DropdownMenuItem>
)}
{host.enableFileManager &&
{isSSH &&
host.enableFileManager &&
!(host.showFileManagerInSidebar ?? false) && (
<DropdownMenuItem
onClick={(e) => {
@@ -520,7 +619,8 @@ export function CommandPalette({
</span>
</DropdownMenuItem>
)}
{host.enableTunnel &&
{isSSH &&
host.enableTunnel &&
hasTunnelConnections &&
!(host.showTunnelInSidebar ?? false) && (
<DropdownMenuItem
@@ -536,7 +636,8 @@ export function CommandPalette({
</span>
</DropdownMenuItem>
)}
{host.enableDocker &&
{isSSH &&
host.enableDocker &&
!(host.showDockerInSidebar ?? false) && (
<DropdownMenuItem
onClick={(e) => {
+103
View File
@@ -15,6 +15,7 @@ import {
getServerMetricsById,
registerMetricsViewer,
sendMetricsHeartbeat,
getGuacamoleToken,
type RecentActivityItem,
} from "@/ui/main-axios.ts";
import { useSidebar } from "@/components/ui/sidebar.tsx";
@@ -386,6 +387,108 @@ export function Dashboard({
title: item.hostName,
hostConfig: host,
});
} else if (item.type === "telnet") {
getGuacamoleToken({
protocol: "telnet",
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
ignoreCert: host.ignoreCert,
guacamoleConfig: host.guacamoleConfig as any,
})
.then((result) => {
addTab({
type: "telnet",
title: item.hostName,
hostConfig: host,
connectionConfig: {
token: result.token,
protocol: "telnet",
type: "telnet",
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
"ignore-cert": host.ignoreCert,
},
});
})
.catch((error) => {
console.error("Failed to get telnet token:", error);
});
} else if (item.type === "vnc") {
getGuacamoleToken({
protocol: "vnc",
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
ignoreCert: host.ignoreCert,
guacamoleConfig: host.guacamoleConfig as any,
})
.then((result) => {
addTab({
type: "vnc",
title: item.hostName,
hostConfig: host,
connectionConfig: {
token: result.token,
protocol: "vnc",
type: "vnc",
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
"ignore-cert": host.ignoreCert,
},
});
})
.catch((error) => {
console.error("Failed to get vnc token:", error);
});
} else if (item.type === "rdp") {
getGuacamoleToken({
protocol: "rdp",
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
ignoreCert: host.ignoreCert,
guacamoleConfig: host.guacamoleConfig as any,
})
.then((result) => {
addTab({
type: "rdp",
title: item.hostName,
hostConfig: host,
connectionConfig: {
token: result.token,
protocol: "rdp",
type: "rdp",
hostname: host.ip,
port: host.port,
username: host.username,
password: host.password,
domain: host.domain,
security: host.security,
"ignore-cert": host.ignoreCert,
},
});
})
.catch((error) => {
console.error("Failed to get rdp token:", error);
});
}
});
};
@@ -8,6 +8,10 @@ import {
Server,
ArrowDownUp,
Container,
Monitor,
Eye,
MessagesSquare,
Network,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { type RecentActivityItem } from "@/ui/main-axios";
@@ -83,6 +87,12 @@ export function RecentActivityCard({
<ArrowDownUp size={20} className="shrink-0" />
) : item.type === "docker" ? (
<Container size={20} className="shrink-0" />
) : item.type === "telnet" ? (
<MessagesSquare size={20} className="shrink-0" />
) : item.type === "vnc" ? (
<Eye size={20} className="shrink-0" />
) : item.type === "rdp" ? (
<Monitor size={20} className="shrink-0" />
) : (
<Terminal size={20} className="shrink-0" />
)}
@@ -249,7 +249,7 @@ export function ConsoleTerminal({
window.location.port === "");
const baseWsUrl = isDev
? `${window.location.protocol === "https:" ? "wss" : "ws"}://localhost:30008`
? `${window.location.protocol === "https:" ? "wss" : "ws"}://localhost:30009`
: isElectronApp
? (() => {
const baseUrl =

Some files were not shown because too many files have changed in this diff Show More