Commit Graph

320 Commits

Author SHA1 Message Date
LukeGus 612ba046a8 Merge remote-tracking branch 'origin/main' 2026-06-16 16:58:59 -05:00
LukeGus 27d613e50c chore: automated release updates 2026-06-16 16:58:52 -05:00
Luke Gustafson b02e9876ae Update termix.rb 2026-06-16 16:40:15 -05:00
LukeGus e2db514173 chore: fix automated docs release 2026-06-16 16:25:27 -05:00
Luke Gustafson ac24fdcba8 release-2.4.0 (#913)
* feat: continued adding features to the release.yml

* feat: added auto youtube submit

* feat: add dry run to release workflow

* feat: improve release workflow mode system with new dropdown and overwrite release mode

* fix: make credentials start collapsed

* fix: make hostname fill entire column and truncate at proper spot in dashboard

* fix: guacamole display using an incorrect height

* feat: add folder management (nested folders, folder icons, folder colors, improved folder selection, etc.)

* feat: move ssh host config outside of top tab bar and into new tab bar visible when on SSH tab

* fix: 2FA failing to disable

* feat: Proxmox guest discovery and import (#881)

* feat(db): add Proxmox host fields and schema migration

Add enableProxmox flag and proxmoxConfig JSON to the hosts table so an
SSH host can be marked as a Proxmox node and carry per-host discovery
settings (default credential, Windows/Docker name patterns, preferred
IP prefixes). Includes addColumnIfNotExists migration entries and the
matching SSHHost / HostData / Host type definitions.

* feat(api): add Proxmox guest discovery endpoint

Add POST /proxmox/discover which connects to a Proxmox node over SSH
using the host's existing stored credentials (no separate API token),
runs pvesh to enumerate cluster guests, and returns VMs and LXC
containers ready to import. Guest IPs are resolved with bounded
concurrency (LXC from net config, QEMU via guest agent) to stay within
the node's SSH MaxSessions; configured preferred prefixes pick the
address when a guest has several. Name patterns flag Windows guests as
RDP and enable Docker. Node names are validated before use in shell
commands and the SSH connection is always closed via try/finally. The
endpoint carries an OpenAPI annotation. Persists the new host fields
across host create/update/select, the normalizers (transformHostResponse)
and the bulk routes, with normalizer test coverage.

* feat(ui): add Proxmox host settings and guest import

Add a Proxmox tab to the host editor (following the Docker tab pattern)
to enable the integration and configure the default credential, name
patterns and preferred IP ranges. Proxmox-enabled hosts show a discover
action in the sidebar that opens an import dialog listing the cluster's
guests with multi-select; the import reuses the host's credential, maps
Windows guests to RDP, and groups imported guests into a folder named
after the Proxmox host. Also exposes the import via the hosts
import/export menu. All user-facing strings are added to the en.json
locale and rendered via i18n. Built with the existing shadcn Select,
dialog and section-card components to match the dark theme.

* feat(ui): add Proxmox to the bulk feature toggle

Proxmox was the only host feature missing from the multi-select
"Features" menu. Enabling it in bulk is special: unlike the other
toggles it needs a credential to be useful, so each host now defaults
its Proxmox credential to the credential already stored on that host
(host.credentialId). Discovery then works right away without picking
one by hand, and per-host settings can still be adjusted afterwards.

- SidebarTree: Enable/Disable Proxmox entries (Boxes icon) in the
  bulk Features dropdown
- host-bulk-routes: enabling Proxmox runs per-host so each host keeps
  its own default credential; existing proxmoxConfig is preserved;
  disabling stays a simple flag flip
- en.json: enableProxmoxFeature / disableProxmoxFeature

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* fix: reliable OIDC group syncing for admin roles (#882)

- always fetch from the userinfo endpoint to get extra claims (like `groups` from Authelia) instead of skipping it if the id_token was already parsed
- handle cases where the OIDC provider sends groups as a single string, a comma-separated string
- add debug logging

* fix: incorrect guacd screen height

* fix: guacd black screen on connnection

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* feat: initial server stats rewrite (renamed to host metrics)

* feat: continue renaming and improving host metrics features and UI

* fix: clipboard copy fails in Brave/non-HTTPS, dashboard total credentials stuck at 0, host username ignored when credential attached, cloned host can't switch auth method, file-manager context menu off-screen, file delete affecting inactive tabs, silent delete failure on Windows hosts, iPad host tap does nothing, OIDC custom group claim support

* chore: update dependabot for my app and add auto merge/branch update

* chore: update dependabot for my app and add auto merge/branch update

* Feat/docker release tag (#894)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* feat(docker): add version tag to production Docker image tags

---------

Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>

* fix: disable hardware acceleration on Windows to prevent startup crash (#895)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* fix: disable hardware acceleration on Windows to prevent startup crash

---------

Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>

* chore(deps-dev): bump the dev-patch-updates group across 1 directory with 23 updates (#893)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps-dev): bump the dev-patch-updates group across 1 directory with 23 updates

Bumps the dev-patch-updates group with 22 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/autocomplete](https://github.com/codemirror/autocomplete) | `6.20.2` | `6.20.3` |
| [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) | `21.0.1` | `21.0.2` |
| [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/config-conventional) | `21.0.1` | `21.0.2` |
| [@radix-ui/react-accordion](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/accordion) | `1.2.12` | `1.2.13` |
| [@radix-ui/react-alert-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/alert-dialog) | `1.1.15` | `1.1.16` |
| [@radix-ui/react-checkbox](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/checkbox) | `1.3.3` | `1.3.4` |
| [@radix-ui/react-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dialog) | `1.1.15` | `1.1.16` |
| [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.1.16` | `2.1.17` |
| [@radix-ui/react-label](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/label) | `2.1.8` | `2.1.9` |
| [@radix-ui/react-popover](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/popover) | `1.1.15` | `1.1.16` |
| [@radix-ui/react-progress](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/progress) | `1.1.8` | `1.1.9` |
| [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/scroll-area) | `1.2.10` | `1.2.11` |
| [@radix-ui/react-separator](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/separator) | `1.1.8` | `1.1.9` |
| [@radix-ui/react-tabs](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tabs) | `1.1.13` | `1.1.14` |
| [@radix-ui/react-tooltip](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tooltip) | `1.2.8` | `1.2.9` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.1` | `25.9.2` |
| [i18next](https://github.com/i18next/i18next) | `26.3.0` | `26.3.1` |
| [lint-staged](https://github.com/lint-staged/lint-staged) | `17.0.5` | `17.0.7` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.6` | `19.2.7` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.2.15` | `19.2.17` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.6` | `19.2.7` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.0.14` | `8.0.16` |



Updates `@codemirror/autocomplete` from 6.20.2 to 6.20.3
- [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/autocomplete/commits)

Updates `@commitlint/cli` from 21.0.1 to 21.0.2
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v21.0.2/@commitlint/cli)

Updates `@commitlint/config-conventional` from 21.0.1 to 21.0.2
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/config-conventional/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v21.0.2/@commitlint/config-conventional)

Updates `@radix-ui/react-accordion` from 1.2.12 to 1.2.13
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/accordion/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/accordion)

Updates `@radix-ui/react-alert-dialog` from 1.1.15 to 1.1.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/alert-dialog)

Updates `@radix-ui/react-checkbox` from 1.3.3 to 1.3.4
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/checkbox/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/checkbox)

Updates `@radix-ui/react-dialog` from 1.1.15 to 1.1.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dialog)

Updates `@radix-ui/react-dropdown-menu` from 2.1.16 to 2.1.17
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dropdown-menu/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dropdown-menu)

Updates `@radix-ui/react-label` from 2.1.8 to 2.1.9
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/label/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/label)

Updates `@radix-ui/react-popover` from 1.1.15 to 1.1.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/popover/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/popover)

Updates `@radix-ui/react-progress` from 1.1.8 to 1.1.9
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/progress/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/progress)

Updates `@radix-ui/react-scroll-area` from 1.2.10 to 1.2.11
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/scroll-area)

Updates `@radix-ui/react-separator` from 1.1.8 to 1.1.9
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/separator/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/separator)

Updates `@radix-ui/react-slot` from 1.2.4 to 1.2.5
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/slot/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slot)

Updates `@radix-ui/react-tabs` from 1.1.13 to 1.1.14
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tabs/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tabs)

Updates `@radix-ui/react-tooltip` from 1.2.8 to 1.2.9
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tooltip/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tooltip)

Updates `@types/node` from 25.9.1 to 25.9.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `i18next` from 26.3.0 to 26.3.1
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.3.0...v26.3.1)

Updates `lint-staged` from 17.0.5 to 17.0.7
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v17.0.5...v17.0.7)

Updates `react` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react)

Updates `@types/react` from 19.2.15 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react-dom)

Updates `vite` from 8.0.14 to 8.0.16
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite)

---
updated-dependencies:
- dependency-name: "@codemirror/autocomplete"
  dependency-version: 6.20.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@commitlint/cli"
  dependency-version: 21.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@commitlint/config-conventional"
  dependency-version: 21.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-accordion"
  dependency-version: 1.2.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-alert-dialog"
  dependency-version: 1.1.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-checkbox"
  dependency-version: 1.3.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-dialog"
  dependency-version: 1.1.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-dropdown-menu"
  dependency-version: 2.1.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-popover"
  dependency-version: 1.1.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-progress"
  dependency-version: 1.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-scroll-area"
  dependency-version: 1.2.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-separator"
  dependency-version: 1.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-slot"
  dependency-version: 1.2.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-tabs"
  dependency-version: 1.1.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@radix-ui/react-tooltip"
  dependency-version: 1.2.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/node"
  dependency-version: 25.9.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: i18next
  dependency-version: 26.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: lint-staged
  dependency-version: 17.0.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/react"
  dependency-version: 19.2.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: react-dom
  dependency-version: 19.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: vite
  dependency-version: 8.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump undici from 7.26.0 to 8.4.0 (#891)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps): bump undici from 7.26.0 to 8.4.0

Bumps [undici](https://github.com/nodejs/undici) from 7.26.0 to 8.4.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.26.0...v8.4.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 8.4.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump the prod-minor-updates group with 2 updates (#890)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps): bump the prod-minor-updates group with 2 updates

Bumps the prod-minor-updates group with 2 updates: [axios](https://github.com/axios/axios) and [js-yaml](https://github.com/nodeca/js-yaml).


Updates `axios` from 1.16.1 to 1.17.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.16.1...v1.17.0)

Updates `js-yaml` from 4.1.1 to 4.2.0
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/commits)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: js-yaml
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/setup-node from 4 to 6 (#887)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps): bump actions/setup-node from 4 to 6

Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/checkout from 4 to 6 (#886)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps): bump actions/checkout from 4 to 6

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/upload-artifact from 4 to 7 (#885)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps): bump actions/upload-artifact from 4 to 7

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/download-artifact from 4 to 8 (#884)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* chore(deps): bump actions/download-artifact from 4 to 8

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: automate rebasing dependabot

* feat: add admin settings audit log feature

* feat: add customizability of app rail tabs

* fix: host metrics giving sudo password error

* feat: add terminal session logging

* feat: sso system redesign (multiple oidc, ldap support, etc.)

* feat: tailscale auth support

* feat: improve syntax highlighting system

* feat: improve nested folder system/ui

* feat: improve nested folder system/ui

* fix: move tailscale i18n and add scrollbar to ssh host manager customization

* feat: improve syntax highlighting, fix tailscale bugs and host manger UX

* fix: admin page not loading user admin information

* chore: update crowdin workflow

* fix: guacd getting passed incorrect protocol for app view

* fix: add SFTP jump-host fallback from host data (#902)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* fix: add SFTP jump-host fallback from host data

---------

Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* feat(tmux-monitor): add per-host tmux session monitor (#896)

* fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)

* Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"

This reverts commit 4d04559ca5.

* feat(tmux-monitor): add per-host tmux session monitor

New isolated feature module following the docker/server-stats pattern:

- Backend Express service on port 30010 (src/backend/ssh/tmux-monitor.ts)
  listing tmux sessions/windows/panes, pane capture, cross-session
  output search, and per-pane CPU/RAM/GPU metrics over pooled SSH
  connections. Read-only; reuses host-resolver, jump-host-chain,
  connection pool and RBAC access checks.
- tmux_session_tags table for per-user project tags on sessions.
- Frontend fullscreen app at ?view=tmux-monitor with host selector,
  session/window/pane tree, live pane preview (2s polling), search
  bar, metrics display, and tag editing.
- nginx location blocks for /tmux_monitor in Docker deployments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): live streaming backend and shell integration

- WebSocket service on port 30011 (tmux-monitor-live.ts) bridging tmux
  control mode (-C attach-session) to the browser: subscribe per pane,
  decoded %output events streamed as JSON, structure-change and detach
  notifications. Pure control-mode parser with 17 unit tests.
- Register tmux_monitor as a singleton shell tab: AppRail entry below
  Network Graph, global Command Palette action, and per-host palette
  action (gated on enableTerminal) that opens with the host preselected.
- nginx WebSocket location /tmux_monitor/live/ for Docker deployments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): xterm live preview and UX polish

- Pane preview is now a read-only xterm.js terminal with ANSI colors
  (capture-pane -e via new ansi=1 param) fed by the live WebSocket;
  status chip shows live/connecting/polling and the original 2s REST
  polling remains as automatic fallback.
- useTmuxLive hook: survives React StrictMode remounts (unmounted flag
  reset on mount), force-closes sockets stuck in CONNECTING after 8s so
  retry/fallback always engages, uses import.meta.env.DEV for dev
  detection.
- UX: skeleton loading, error state with retry, actionable empty states,
  persisted host/expanded-session selection, "/" and Escape shortcuts,
  search match highlighting, fresh relative timestamps.

Verified end-to-end in Chrome against a local backend: live chip goes
green and pane output streams in real time over the control-mode bridge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(tmux-monitor): replace control-mode bridge with native PTY attach

The pane preview now embeds the real Terminal component and attaches to
the selected session through the existing terminal WebSocket (new
tmuxAttachSession handshake field in ssh/terminal.ts), making the
preview fully interactive — typing, mouse scrolling and tmux copy-mode
behave exactly like a normal terminal tab. Pane clicks within a session
use the new /focus endpoint (select-window/select-pane) instead of
remounting the terminal.

This removes the entire custom live-streaming stack: the control-mode
WebSocket service on port 30011 (tmux-monitor-live.ts), the control
sequence parser and its tests, the useTmuxLive hook, the nginx
/tmux_monitor/live/ location blocks, and the now-unused live/polling
status chip locale keys.

Verified end-to-end against a dockerized SSH host (Alpine + tmux 3.6):
session tree, interactive preview with ANSI colors, cross-session
search with jump-to-pane, per-pane CPU/RAM metrics, session tags, and
attach-in-new-tab.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): use printable field separator in tmux format strings

The unit separator control character (\x1f) used to delimit fields in
tmux -F output gets sanitized to "_" by tmux itself — tmux replaces
control characters (and, under non-UTF-8 locales, any multibyte
character) in expanded format output. On such hosts every list-sessions
line came back as a single unsplittable field, so the monitor showed
session names like "build_1781066459_1781066459_0" and windows/panes
failed to parse entirely.

Switch SEP to the printable ASCII token "<<TMX>>", which survives every
tmux version and locale. Reproduced and verified against tmux 3.6 on
Alpine (C locale) in a docker container.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): create sessions and split panes from the monitor

- POST /tmux_monitor/:hostId/sessions creates a detached session
  (tmux new-session -d), starting the tmux server if needed. Session
  names are validated against a conservative charset on both ends
  (tmux forbids ":" and "."), and a duplicate name returns 409 with
  tmux's own message surfaced in the toast.
- POST /tmux_monitor/:hostId/split splits the window containing a pane
  (tmux split-window -h/-v), with the new pane starting in the source
  pane's working directory via -c '#{pane_current_path}'.
- UI: a "+" button next to the host selector opens a name popover
  (Enter or Create); the pane preview header gains split-right and
  split-down buttons. Splits appear instantly in the attached preview
  terminal and a silent overview reload updates the tree; new sessions
  are auto-expanded.

Command syntax verified against tmux 3.6 in a dockerized SSH host.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): VSCode tmux-manager style tree with window actions

Restyle the session tree after the VSCode tmux manager view:

- Header toolbar: new-session (+) popover and refresh moved next to the
  panel title; the host selector row is back to a plain full-width
  select.
- Session rows gain hover actions — attach (play) and new window (+) —
  revealed with the opacity pattern used by docker's ContainerCard so
  they stay keyboard-focusable, with aria-labels on all icon buttons.
- Window rows are collapsible (chevron, "index: name" with a window
  icon); panes show "index: command" plus the pane's working directory
  in muted text with a full-path tooltip.
- New POST /tmux_monitor/:hostId/windows route runs tmux new-window
  against an exact-match ("=name") shell-escaped target; rejects names
  containing ":"/"."/newline and returns 404 for missing sessions.
- Pane preview header groups the split buttons apart from close with a
  separator.

Reviewed by SA/BA/UX subagent panel; keyboard accessibility and
aria-label findings applied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): rename/kill sessions, collapse-all, no-flash refresh

- Session rows gain a "…" menu with Rename (dialog, validated name) and
  Kill (destructive confirmation). Rename migrates saved tags to the
  new name and re-attaches an open preview; kill closes the preview and
  drops the session's tags. Both routes use exact-match ("=name")
  shell-escaped targets and map tmux's "can't find session" /
  "duplicate session" errors to 404/409.
- Header gains a VSCode-style collapse-all / expand-all toggle for the
  session tree.
- Refresh UX: manual refresh no longer blanks the tree into skeletons —
  the skeleton is reserved for a host's first load; refresh keeps the
  tree, spins the icon (header and toolbar) and reports failures with a
  toast instead of silently keeping stale data.

tmux command syntax verified against tmux 3.6 in the docker test host.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): single-row sessions, overlay hover actions, tag dialog

UI cleanup after desktop testing showed the tree looked cluttered:

- Sessions are now a single row. The permanently visible tags row (a
  mostly empty line with a lone tag icon under every session) is gone:
  tags render as inline badges after the name (max 2, then "+n" with a
  full-list tooltip) and editing moved to the "…" menu, which opens a
  dialog like rename.
- Session metrics merged into the right-hand meta label
  ("just now · 0% · 7 MB"). Hover actions (attach, new window, …) are
  stacked over that label in a grid cell with an opacity cross-fade, so
  the row never shifts and the buttons remain keyboard-focusable
  (focus-within reveals them).
- Dropdown items no longer wrap: short labels (Rename / Edit tags /
  Kill), whitespace-nowrap, min-w-36, align="end".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): kill pane; fix session actions in the desktop app

- Kill pane: hover ✕ on pane rows and a trash button in the preview
  header, both behind a confirmation dialog (kill-pane terminates the
  pane's process; the last pane closes its window). New
  POST /tmux_monitor/:hostId/kill-pane route with pane-id validation.
- Fix attach (▷) doing nothing in the Electron build: window.open of
  internal file:// URLs is denied by the window-open handler, so on
  desktop the button now attaches inline — expands the session and
  selects its active pane in the embedded terminal. Browsers keep the
  open-in-new-tab behavior.
- Enlarge the hover-action hit areas (-m-1 p-1) so clicks land on the
  buttons instead of toggling the session row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): session hover actions were unclickable

The meta label (time · cpu · mem) fades to opacity-0 on hover, which
turns it into a stacking context painted above its plain-flow sibling —
the invisible label sat on top of the attach/new-window/menu buttons
and swallowed their clicks, so clicking them toggled the session row
instead. Give the actions overlay z-10 and make the label
pointer-events-none.

Reproduced and verified in Chrome with elementFromPoint before/after;
create → rename → kill all work end-to-end through the UI now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): resizable session tree panel

The tree panel was fixed at w-72; long session names and pane paths had
no room. Its right edge is now a drag handle (200–520px, same pattern
and styling as the AppShell host sidebar), double-click resets to the
default width, and the width persists in localStorage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): split buttons on pane rows

Pane rows' hover actions gain split-right and split-down next to the
kill button, so a pane can be split straight from the tree. splitPane
now takes the target pane id instead of implicitly using the selected
pane; the preview header passes its own pane through.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): repair garbled preview after layout changes

External split / kill-pane / new-window actions can leave the attached
preview client with stale borders (the redraw races the xterm size).
Two-part fix:

- After any layout-changing action the monitor nudges the embedded
  terminal (fit + notifyResize + refresh) — the PTY resize forces tmux
  to fully redraw the client.
- The preview header gains a re-attach button that remounts the
  terminal with a fresh PTY as a one-click rescue when the view is
  garbled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): kill window, compact mode, session status tooltip

- Kill window: hover ✕ on window rows behind a confirmation dialog
  (kills every pane; the last window ends the session). New
  POST /tmux_monitor/:hostId/kill-window route with exact-match target
  and 404 mapping.
- Narrow tree panel (<280px) hides the inline "time · cpu · mem" label,
  which used to crush long session names into "bui…".
- Hovering a session row now shows a status board tooltip (attached
  state, activity, window/pane counts, CPU/RAM/GPU, tags) — the numbers
  stay reachable in compact mode and richer in normal mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): keep preview attached after killing the viewed pane

Killing the selected pane (or its window) dumped the user back to the
"select a pane" empty state even though the session was still alive and
the attached terminal had already focused a sibling pane. After the
kill the monitor now refetches the overview and selects the session's
new active pane, so the preview stays on the same attach connection
(same session key → no remount); the empty state only appears when the
whole session died with the pane.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): require execute permission, audit destructive actions, persist tag mutations

- Mutating endpoints (kill/kill-window/kill-pane/rename/split/focus,
  create session/window) now require "execute" host access like docker;
  read-only shared hosts could previously kill sessions and spawn shells
- Log kill/rename actions to the audit log (same pattern as host.ts)
- Trigger a DB save after tag updates in rename/kill handlers; the dirty
  flag was never set, so a crash could lose or resurrect tags
- Add host_id -> ssh_data FK with ON DELETE CASCADE to tmux_session_tags
  (drizzle schema + SQL migration), with a rebuild migration for
  pre-release tables created without the FK

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): stop polling and key handling while the tab is hidden, guard stale host responses

- Pass isVisible into TmuxMonitor (like DockerManager/HostMetricsTab);
  the global "/"+Escape keydown listener and both SSH polling loops now
  pause while the tab is mounted but hidden
- Split the overview polling interval out of the host-change effect so
  resuming a tab does not reset state or flash the skeleton
- Ignore overview responses for a host the user has switched away from;
  a slow response could overwrite the selected host's tree
- Format SearchResults/SessionTree/TmuxMonitorApp/SidebarTree with
  prettier (pr-check was failing on these)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): show an empty state when no SSH hosts exist

With zero hosts the host dropdown opened an empty popover and the
preview area showed the unrelated "select a pane" hint. Disable the
select (its placeholder now says no hosts are available) and show a
central no-hosts message with a pointer to the Host Manager.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): refresh the host list when hosts change elsewhere

The list was fetched once on mount, but the tab stays mounted forever,
so adding the first host in Host Manager left the monitor stuck on
"no hosts" until the tab was closed and reopened. Listen to the
app-wide termix:hosts-changed event (same as AppShell/HostManager),
keep the current selection when still valid, auto-select the first
host when one appears, and clear the session tree when the selected
host is deleted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): keep pane/window actions reachable on a narrow tree

Pane rows kept the split/kill buttons and the "index: command" label at
fixed width, so dragging the panel toward the 200px minimum pushed the
buttons past the right edge; Radix ScrollArea's display:table viewport
wrapper made it worse by stretching every row to the widest pane path,
clipping the window kill button too.

Stack the cpu label and the hover actions in one grid cell (the same
overlay pattern as the session rows), let the command and path labels
truncate, and force the viewport wrapper back to display:block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): reskin the session status tooltip as a popover card

The base TooltipContent is the inverted one-line chip (bg-foreground,
sharp corners, arrow), so the multi-row session board inherited a light
surface that washed out its muted-foreground labels and clashed with
every other floating card in the app. Restyle this one instance with the
popover surface tokens and hide the chip arrow (important is needed
because Radix sets display on the arrow svg inline).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): disable new-session and search when tmux is missing

On a host without tmux the + button still opened the create popover
(submitting just surfaced the backend TMUX_NOT_INSTALLED toast) and
search silently returned "0 matches". Gate both on overview.available
like the neighboring refresh/expand buttons; the search input carries
the unavailable message as its tooltip.

Verified against a real no-tmux host (alpine+sshd container): both
controls disable on it and stay enabled on a host with tmux.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): restyle floating surfaces to match the square UI

Review feedback on #896: the host selector, the new-session popover,
the session status tooltip and the three kill confirmations rendered
with the stock rounded shadcn look while the rest of the app moved to
square corners, ring borders and blurred dialog overlays. Convert the
kill confirmations from AlertDialog to the already-restyled Dialog and
override the remaining surfaces with rounded-none + ring-border.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(host-editor): format the tailscale device options with project prettier

The block arrived unformatted in the dev-2.4.0 merge; committing the
reformat separately keeps the tmux-monitor commits free of unrelated
churn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tmux-monitor): per-host opt-in flag, disabled by default

Review feedback on #896: the tmux actions appeared on every SSH host's
sidebar entry even though most users do not use tmux. Add an
enable_tmux_monitor column (default off) mirroring the enableDocker
plumbing, expose it as an "Enable Tmux Monitor" toggle in the host
editor's Terminal tab, and gate every per-host tmux surface on it:
the sidebar hover action and copy-URL menu item, the command palette
entry, the monitor's host selector, and the tmux-monitor API itself
(refusing like docker.ts does when the feature is off).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): drop the redundant navbar rail entry

The monitor is per-host opt-in, so the global rail item opened a
host-less view. Hosts with enableTmuxMonitor still expose it via the
host action in the sidebar tree and the command palette.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tmux-monitor): fill the status popover card width

TooltipContent is an inline-flex container, so the inner block sized
to its natural content width and left a dead gutter on the right of
the w-56 card. Stretch it with w-full so the values align to the edge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: remove unused dropdown, seperate 3 line menu, and fix a few small UI bugs

---------

Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* fix: add i18n for tmux

* feat: continue improving terminal highlighint with more options and more consistency

* feat: add per host configuration of history tracking with overarching admin toggle

* feat: add storage preference to user profile settings (local or DB)

* chore: update release notes

* fix: return user password reset code to logs

* fix: missing tailscale errors and i18n

* fix: sso/browser preference fixes

* fix: remove SSL_ENABLED references

* feat: add filter/sort to credentials list and fixed some JSDoc comments

* chore: update release notes

* chore: update readmes

* chore: update readmes and add docs links

* feat: continue improving SSO system

* fix: host metrics bugs

* fix: session logging api endpoint fail

* chore: make electron.yml auto deliver to macos app store

* chore: fix linting issues

* chore: fix linting issues

* chore: lint, format, and bump version to 2.4.0

* chore: crowdin using incorrect api key name

* chore: sync Crowdin translations for 2.4.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: XtraLarge <eMail@WilliWerres.de>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: verybadsoldier <364469+verybadsoldier@users.noreply.github.com>
Co-authored-by: i/o agent <273482092+claw-io@users.noreply.github.com>
Co-authored-by: Félix MARQUET <72651575+BreizhHardware@users.noreply.github.com>
Co-authored-by: Rabindra Kumar Meher <rabindrameher116@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jose Tenggren <kf16el42@students.muetkhp.edu.pk>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Kang <78076796+khengyun@users.noreply.github.com>
release-2.4.0-tag
2026-06-16 15:59:53 -05:00
Luke Gustafson 580c284065 Update README.md 2026-06-12 15:16:31 -05:00
LukeGus 2d5da0439e Revert "fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883)"
This reverts commit 4d04559ca5.
2026-06-07 02:57:08 -05:00
i/o agent 4d04559ca5 fix(docker): use resolveTermixThemeColors for Docker console terminal background (#883) 2026-06-06 15:01:53 -04:00
LukeGus f0f3e0b063 chore: bump Homebrew cask to 2.3.2 2026-06-04 20:05:47 +00:00
Luke Gustafson c3282b5dca New Crowdin updates (#876)
* New translations en.json (Romanian)

[ci skip]

* New translations en.json (French)

[ci skip]

* New translations en.json (Spanish)

[ci skip]

* New translations en.json (Afrikaans)

[ci skip]

* New translations en.json (Arabic)

[ci skip]

* New translations en.json (Bulgarian)

[ci skip]

* New translations en.json (Catalan)

[ci skip]

* New translations en.json (Czech)

[ci skip]

* New translations en.json (Danish)

[ci skip]

* New translations en.json (German)

[ci skip]

* New translations en.json (Greek)

[ci skip]

* New translations en.json (Finnish)

[ci skip]

* New translations en.json (Hebrew)

[ci skip]

* New translations en.json (Hungarian)

[ci skip]

* New translations en.json (Italian)

[ci skip]

* New translations en.json (Japanese)

[ci skip]

* New translations en.json (Korean)

[ci skip]

* New translations en.json (Dutch)

[ci skip]

* New translations en.json (Norwegian)

[ci skip]

* New translations en.json (Polish)

[ci skip]

* New translations en.json (Portuguese)

[ci skip]

* New translations en.json (Russian)

[ci skip]

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

[ci skip]

* New translations en.json (Swedish)

[ci skip]

* New translations en.json (Turkish)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Traditional)

[ci skip]

* New translations en.json (Vietnamese)

[ci skip]

* New translations en.json (Portuguese, Brazilian)

[ci skip]

* New translations en.json (Indonesian)

[ci skip]

* New translations en.json (Bengali)

[ci skip]

* New translations en.json (Thai)

[ci skip]

* New translations en.json (Hindi)

[ci skip]
release-2.3.2-tag
2026-06-04 14:24:54 -05:00
LukeGus dccaae07ab chore: fix lint warnings and run formating 2026-06-04 14:23:53 -05:00
Luke Gustafson 52f4e51ae0 v2.3.2 (#874)
* fix: patch critical security vulnerabilities (GHSA-5fqh, GHSA-ccm8, GHSA-wqfw, GHSA-xmjh)

- Remove passwordHash from /users/list API response
- Require both password and TOTP code for MFA-critical operations
- Restrict tunnel kill commands to tunnelMarker-only matching
- Add session ownership middleware for file manager endpoints

* fix: allow navigating away from split-view to non-pane tabs

Show the normal view container on top of the split view when the active
tab is not assigned to any pane, so users can switch to dashboard or
other tabs while split mode is active.

Closes #739

* fix: add inline quick-action buttons on host name row

Show Terminal, Files, RDP, and VNC shortcut icons on the host name row
on hover, so users can launch connections with a single click without
expanding the full action tray.

Closes #736

* fix: restore SSH keepalive interval to 30s to prevent random disconnects

Revert keepalive defaults from 60s/5 to 30s/3 across terminal, tunnel,
and server-stats SSH connections. The 60s interval introduced in 2.3.0
causes firewalls and NAT devices to drop idle connections before the
next keepalive probe.

Closes #733

* fix: apply guacamole-lite protocol patch in Docker builds

The Dockerfile uses --ignore-scripts which skips the postinstall hook
that patches guacamole-lite for guacd 1.6.0 protocol VERSION_1_5_0.
Without this patch, the timezone handshake instruction is not sent for
protocol versions above 1.1.0, causing VNC connections to fail
immediately on connect.

Closes #734

* fix: show correct icons for network interface types

Detect interface type from name pattern and show appropriate icons:
WiFi for wlan/wl*, Ethernet (Cable) for eth/en*, Container for
docker/bridge/virtual, generic Network for others.

Closes #720

* fix: resolve sudo password for shared host users

The password endpoint required hosts.userId to match the requesting
user, which fails for shared hosts. Now falls back to decrypting with
the owner's key when the requesting user doesn't own the host.

Closes #717

* fix: use jump hosts for online status check and metrics collection

Status polling now pings the first jump host instead of the unreachable
target when jump hosts are configured. The /metrics/start endpoint now
tunnels through the jump host chain to reach the target host.

Closes #716

* fix: broaden sudo prompt detection for newer distros

Add patterns for 'password for <user>:' and bare 'Password:' prompts
in addition to the existing [sudo] and sudo: patterns. Covers Ubuntu
26.04 and other distros that use different sudo prompt formats.

Closes #718

* fix: recalculate terminal layout after web fonts load

xterm.js measures character widths at open() time. If custom fonts
haven't loaded yet, measurements use the fallback font and spacing
becomes incorrect. Now refresh and re-fit the terminal once
document.fonts.ready resolves.

Closes #710

* fix: improve terminal cwd detection and initial directory command

Remove '&& pwd' from initial directory command — the shell prompt
shows the new directory naturally. Fixes PowerShell 5.1 which doesn't
support '&&' as a statement separator.

Prepend Ctrl+U to get_cwd command to clear any pending input before
injecting the cwd probe, reducing interference with foreground programs.

Closes #713, #714

* fix: decode base64 file content as UTF-8 in file manager

Replace bare atob() with TextDecoder('utf-8') for base64 content
decoding. atob() only handles Latin-1, so multi-byte UTF-8 characters
like 'é' were decoded as 'é'.

Closes #719

* fix: normalize lazy import default exports for iOS compatibility

Wrap all lazy() imports with explicit .then(m => ({ default: m.default }))
to ensure consistent module resolution across platforms. iOS Safari/WebView
may handle bare lazy(() => import(...)) differently, returning the module
object instead of extracting the default export.

Closes #721

* fix: prevent RDP display from snapping back after container resize

Remove immediate rescaleDisplay() from ResizeObserver callback. The
display.onresize event already triggers rescaling when the RDP server
responds with the new resolution. Calling rescaleDisplay before the
server responds uses stale display dimensions, causing the bottom of
the screen to be truncated.

Closes #725

* fix: add portal Desktop DBus permission for Flatpak URL opening

Flatpak sandbox blocks window.open() without the portal permission,
causing terminal link clicks to open about:blank. Add talk-name for
org.freedesktop.portal.Desktop to enable xdg-desktop-portal URL
handling.

Closes #704

* chore: remove unused code and fix PR checks (#851)

* chore: remove unused frontend code

* chore: prune unused theme exports

* ci: fix pr check failures

* chore: reduce lint warnings

* feat(oidc): expose admin_group via OIDC_ADMIN_GROUP env var (#828)

The admin-group OIDC sync added in 2.3.0 (#782) reads `config.admin_group`
to sync the user's admin flag from OIDC group membership on each login.
That field is only populated when the OIDC config is stored in the
in-app DB — `getOIDCConfigFromEnv()` does not expose it, so deployments
using the env-var config path (declarative IaC: Helm/Compose/Puppet)
cannot enable the feature without abandoning env vars and pasting the
client_secret into the admin UI.

Add `admin_group: process.env.OIDC_ADMIN_GROUP || ""` to the env-config
return type and object. Backward compatible: when unset, the existing
`if (config.admin_group)` guard at users.ts:1336 keeps the sync block
skipped, matching today's behavior.

* chore: reduce explicit-any warnings

* chore: reduce more explicit-any warnings

* chore: reduce lint warnings

* chore: silence intentional hook dependency warnings

* chore: clean dependency tooling

* chore: narrow frontend tsconfig scope

* chore: reduce type assertion debt

* refactor: split host manager components

* refactor: split host editor sections

* refactor: split api client modules

* refactor: split more api clients

* refactor: split user settings api clients

* refactor: split tab and history api clients

* refactor: split tunnel api clients

* refactor: split server stats api client

* refactor: split file manager data api

* refactor: split ssh file operations api

* refactor: split host editor general tab

* refactor: split host editor guacamole tabs

* refactor: split ssh host management api

* refactor: split admin general settings sections

* refactor: split admin database section

* refactor: split admin management sections

* refactor: split admin keys and dialogs

* refactor: split system status api clients

* refactor: split user route helpers

* refactor: split host route helpers

* refactor: split file manager ssh helpers

* refactor: split file manager session helpers

* refactor: split file manager listing routes

* refactor: split host opkssh routes

* refactor: split file manager content routes

* refactor: split user api key routes

* refactor: split host folder routes

* refactor: split user settings routes

* refactor: split user totp routes

* refactor: split host file manager bookmark routes

* refactor: split file manager operation routes

* refactor: split server stats settings routes

* refactor: split user session routes

* refactor: split host command history routes

* refactor: split server stats viewer routes

* refactor: split docker container routes

* refactor: split user oidc account routes

* refactor: split host autostart routes

* refactor: split host internal routes

* refactor: split host network routes

* refactor: split user password reset routes

* refactor: split user admin routes

* refactor: split user data access routes

* refactor: split credential key routes

* refactor: split credential deploy routes

* refactor: split host bulk routes

* refactor: split server stats connection helpers

* refactor: split tunnel helpers

* refactor: split file manager action routes

* refactor: split terminal auth helpers

* refactor: split terminal jump host helpers

* refactor: split tunnel relay helpers

* refactor: split tunnel socks relay helpers

* refactor: split tunnel c2s relay handlers

* refactor: split server stats session helpers

* refactor: split terminal presentation helpers

* refactor: split file manager presentation helpers

* refactor: split file manager toolbar

* fix(guacamole-lite): send name instruction for protocol >= 1.3.0

The Guacamole protocol added the `name` handshake instruction in 1.3.0
(an optional human-readable identifier for the joining user). guacd 1.6.0
began requiring it during the VNC handshake even when negotiating older
protocol versions, causing connections to silently drop right after the
"User joined" log line with no client-visible error.

This patch extends scripts/patch-guacamole-lite.cjs with a third
idempotent string-replacement that injects the `name` instruction send
when guacamole-lite has negotiated protocol VERSION_1_3_0 or VERSION_1_5_0.

Verified end-to-end: guacd debug logs now show `Processing instruction:
name` and `Client is using protocol version "VERSION_1_5_0"` (previously
stuck at VERSION_1_1_0). VNC session connects successfully against
guacd 1.5.5 / macOS Tahoe target.

Related: Termix-SSH/Support#567, #734

* fix: resolve recent support bugs

* fix(admin): wire up OIDC-to-password link dialog submit + visibility

The admin user-management UI already shipped a link icon and a "Link
Account" dialog, but two things blocked the flow:

1. The submit button had no onClick handler and the username input was
   uncontrolled (no value/onChange). Clicking "Link Accounts" was a
   no-op — no network request, no console error, no toast.
2. The link icon's visibility condition was `user.isOidc &&
   !user.passwordHash`, which hid the button on OIDC users that had
   been auto-provisioned with a passwordHash. Termix's OIDC provisioning
   sets a passwordHash by default, so the button was hidden on virtually
   every OIDC-provisioned user.

This change:
- Adds `linkOIDCToPasswordAccount` to the imports from `@/main-axios`.
- Adds two pieces of dialog state: `linkAccountTargetUsername` and
  `linkAccountSubmitting`.
- Makes the dialog's Input field a controlled component.
- Wires the submit Button's onClick to call `linkOIDCToPasswordAccount`,
  emit success/error toasts, refresh the local user list, and close
  the dialog.
- Loosens the visibility condition to `user.isOidc` (the backend
  handler already enforces all integrity checks).
- Adds `linkAccountSuccess`, `linkAccountFailed`, and
  `linkAccountInProgress` translation keys to `en.json`.

Verified locally: full Docker build via docker/Dockerfile passes;
`tsc --noEmit` is clean; `prettier --check .` is clean; ESLint produces
the same warning count as upstream (16 pre-existing `any`-type warnings,
0 errors).

* fix: support native oidc callbacks (#856)

* docs: add cloudflare tunnel guidance (#857)

* fix: sync appearance preferences (#858)

* fix: pass through terminal tab completion (#859)

* fix: resolve terminal jump hosts server-side (#860)

* fix(electron): auto-allow SSL certificates for private network hosts (#861)

Add private network IP detection (RFC 1918, link-local, loopback, IPv6
ULA) to the Electron certificate-error handler so that connections to
local/private servers like 192.168.x.x bypass SSL validation
automatically. Also add an explicit "Allow invalid certificate" toggle
in the server config UI for public HTTPS servers with self-signed certs.

* fix: restore host password copy actions (#862)

* feat: support single-host direct tunnels (ssh -L style) (#863)

Add direct tunnel mode that uses a single SSH host for port forwarding,
matching the behavior of ssh -L / ssh -R / ssh -D without requiring a
second endpoint host in the Termix database. The Termix server creates a
local TCP listener and forwards through the SSH channel directly.

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* Merge commit from fork

* fix: backend build errors (Type)

* fix: mobile auth failing to login with webview

* fix: mobile app geting incorrectly sent auth token

* feat: commit existing frontend/backend e2e/unit tests (skipped tests containing private info like OIDC and real server testing)

* feat: host-to-host file transfer via server relay

* feat: removed host management from command palette, fixed command palette opening wrong protocol, export/import failing for ssh key hosts, docker ssh2 native crypto not compiled, persisted terminal tabs attempt SSh on RDP hosts after migration, improved layout for click to expand hosts, show ip/username without having to hover over hosts

* fix: credentials not indexing into host manager until refresh

* feat: update credentials lists to match hosts list UI/UX

* feat: add rename folder UI

* feat: improve transfer to host UI/UX

* chore: increment ver

* feat: improve transfer to host UI

* feat: implement initial auto release system

---------

Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
Co-authored-by: nicodarge <43711429+nicodarge@users.noreply.github.com>
Co-authored-by: Raman Gupta <7243222+raman325@users.noreply.github.com>
Co-authored-by: luc <luc_cook@hotmail.co.uk>
2026-06-04 14:16:53 -05:00
LukeGus da79b01db4 chore: update cask 2026-05-28 22:45:53 -05:00
LukeGus bc386b1247 fix: uuid crypto error when creating a tab on http based setups 2026-05-28 22:29:30 -05:00
Luke Gustafson dd008e4d6b New Crowdin updates (#836)
* New translations en.json (Romanian)

[ci skip]

* New translations en.json (French)

[ci skip]

* New translations en.json (Spanish)

[ci skip]

* New translations en.json (Afrikaans)

[ci skip]

* New translations en.json (Arabic)

[ci skip]

* New translations en.json (Bulgarian)

[ci skip]

* New translations en.json (Catalan)

[ci skip]

* New translations en.json (Czech)

[ci skip]

* New translations en.json (Danish)

[ci skip]

* New translations en.json (German)

[ci skip]

* New translations en.json (Greek)

[ci skip]

* New translations en.json (Finnish)

[ci skip]

* New translations en.json (Hebrew)

[ci skip]

* New translations en.json (Hungarian)

[ci skip]

* New translations en.json (Italian)

[ci skip]

* New translations en.json (Japanese)

[ci skip]

* New translations en.json (Korean)

[ci skip]

* New translations en.json (Dutch)

[ci skip]

* New translations en.json (Norwegian)

[ci skip]

* New translations en.json (Polish)

[ci skip]

* New translations en.json (Portuguese)

[ci skip]

* New translations en.json (Russian)

[ci skip]

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

[ci skip]

* New translations en.json (Swedish)

[ci skip]

* New translations en.json (Turkish)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Traditional)

[ci skip]

* New translations en.json (Vietnamese)

[ci skip]

* New translations en.json (Portuguese, Brazilian)

[ci skip]

* New translations en.json (Indonesian)

[ci skip]

* New translations en.json (Bengali)

[ci skip]

* New translations en.json (Thai)

[ci skip]

* New translations en.json (Hindi)

[ci skip]
2026-05-28 22:29:30 -05:00
Luke Gustafson 7370e8f3df v2.3.1 (#833)
* feat: add host list sort

* feat: fixed rdp truncating (taskbar invisible unless resizing window) and improved split screen system

* feat: revamp conneciton persistance system to save to backend with a new connections panel to restore old connections and view current ones. Also added new user profile toggle to reopen all tabs (saves and loads from backend). Added user profile toggle for host tray click vs hover.

* feat: added WOL button, added proper use of BASE_PATH, toggles/buttons in admin/user profile now are always visible regardless of sidebar width, duplicating hosts not adding jumphost/socks5, keepalive internal not mulitplying into seconds causing a keepalive error, and finally guacamole giving 1_0_0 and 1_1_0 errors

* feat: add filter host button, improve alert system UI, save sidebar width to localstorage, and fix host toolbar row overflow (add host going off screen on small sidebar width)

* feat: add pin rail toggle, fix command pallete toggle not working, fixed command pallete toggling when typing in a field, made file manager not uppercase, host manager custom ports not loading, guacd hosts made on >=2.2.1, fixed host tags toggling, added reorder snippet sfeature, made snippet folder clllapse and require confimration toggle work, removed file manager color toggle, and fixed macos not displaying GUI until switching to another app and coming back, and jump host servers failing.

* feat: use blacksmith caching for docker compile and improve keepalive system for ssh to all match the same implementation and use the data from the host config instead of a predefined value

* feat: reset host manager state if the form is left and remove file manager color logic from the removed toggle

* feat: update electron version check to use new ui

* feat: improve duplication system to proplery map all fields
2026-05-28 22:29:29 -05:00
LukeGus b5ab1479ce chore: update casks 2026-05-28 22:29:29 -05:00
LukeGus c060d668e0 chore: update cask 2026-05-28 22:29:29 -05:00
LukeGus 5777351145 v2.3.0 2026-05-28 22:29:20 -05:00
LukeGus 33dcde0827 feat: initial ui redesign from demo 2026-05-13 01:29:43 -05:00
LukeGus eaa758effe fix: rdp fails with readText undefined error 2026-05-13 01:06:34 -05:00
LukeGus 557a789a6c chore: update cask 2026-05-13 00:41:18 -05:00
Luke Gustafson d2e13cdfd8 fix: desktop local server failure (#756)
* fix: remote desktop blank screen

* fix: desktop local server failure
2026-05-12 23:54:51 -05:00
Luke Gustafson dc79d170b6 fix: remote desktop blank screen (#755) 2026-05-12 23:50:25 -05:00
LukeGus 604de8a683 fix: remote desktop blank screen 2026-05-12 22:50:51 -05:00
LukeGus 3b465a0747 chore: update casks 2026-05-12 22:33:36 -05:00
LukeGus f803fc83a4 chore: update casks 2026-05-12 22:33:28 -05:00
Luke Gustafson 10794f1e8d v2.2.1 (#754)
* fix: rdp, desktop app, and mobile app login issues and guacd issues

* fix: general fixes

* fix: mobile/desktop login isssues

* fix: mobile/desktop login isssues

* fix: mobile/desktop login isssues

* chore: format
release-2.2.1-tag
2026-05-12 21:55:14 -05:00
LukeGus ada8a268bb fix: desktop app not launching 2026-05-06 22:02:11 -05:00
LukeGus 0d8c82d7f8 chore: update cask 2026-05-06 15:40:30 -05:00
Luke Gustafson f09f1748ec New Crowdin updates (#740)
* New translations en.json (Romanian)

[ci skip]

* New translations en.json (French)

[ci skip]

* New translations en.json (Spanish)

[ci skip]

* New translations en.json (Afrikaans)

[ci skip]

* New translations en.json (Arabic)

[ci skip]

* New translations en.json (Bulgarian)

[ci skip]

* New translations en.json (Catalan)

[ci skip]

* New translations en.json (Czech)

[ci skip]

* New translations en.json (Danish)

[ci skip]

* New translations en.json (German)

[ci skip]

* New translations en.json (Greek)

[ci skip]

* New translations en.json (Finnish)

[ci skip]

* New translations en.json (Hebrew)

[ci skip]

* New translations en.json (Hungarian)

[ci skip]

* New translations en.json (Italian)

[ci skip]

* New translations en.json (Japanese)

[ci skip]

* New translations en.json (Korean)

[ci skip]

* New translations en.json (Dutch)

[ci skip]

* New translations en.json (Norwegian)

[ci skip]

* New translations en.json (Polish)

[ci skip]

* New translations en.json (Portuguese)

[ci skip]

* New translations en.json (Russian)

[ci skip]

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

[ci skip]

* New translations en.json (Swedish)

[ci skip]

* New translations en.json (Turkish)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Traditional)

[ci skip]

* New translations en.json (Vietnamese)

[ci skip]

* New translations en.json (Portuguese, Brazilian)

[ci skip]

* New translations en.json (Indonesian)

[ci skip]

* New translations en.json (Bengali)

[ci skip]

* New translations en.json (Thai)

[ci skip]

* New translations en.json (Hindi)

[ci skip]
release-2.2.0-tag
2026-05-06 15:18:55 -05:00
Luke Gustafson 2768f11dfc v2.2.0 (#738)
* Improve Docker container list UI

* Rework SSH tunnel forwarding

* Update macOS Electron packaging

* Optimize frontend bundle splitting

* Add beta version update status

* Add client tunnel preset management

* Secure cookie authentication flows

* Add client tunnel bridge support

* Preserve sessions on restart

* Update runtime to Node 24

* Add client remote tunnel support

* Fix stale frontend cache handling

* Fix Docker image platforms for Node 24

* Fix Electron packaging workflows

* Fix client auth cache after upgrades

* chore: cleanup files

* fix: npm i error

* Fix OIDC auth cookie readiness

* Fix Docker npm ci config

* Add react-is peer dependency

* Fix Electron auth and cache handling

* Improve terminal clipboard and refresh actions

* feat: add API keys

* feat: improve lazy loading with loading spinners

* feat: Introduce FolderTree component with lazy-loading and motion animations for improved file manager UX (#735)

* feat: integrate FolderTree component with lazy-loading for file manager sidebar

- Add motion animation library (v12.38.0) for smooth UI transitions
- Create new FolderTree component with advanced keyboard navigation support
- Refactor kbd component: introduce KbdKey and KbdSeparator subcomponents
- Implement lazy-loading strategy for directory tree in FileManagerSidebar
- Refactor FileManagerSidebar with improved code organization and better separation of concerns
- Update keyboard shortcut displays across CommandPalette, FileViewer, and Dashboard
- Change React/ReactDOM dependency flags from dev to devOptional in package-lock.json

BREAKING CHANGE: KbdGroup component has been replaced. Use <Kbd><KbdKey>...</KbdKey><KbdSeparator /></Kbd> instead.

- Improves UX with smooth animations and better folder navigation
- Reduces initial load time through lazy-loading subdirectories
- Enhances accessibility with ARIA labels and keyboard navigation
- Maintains dark mode support and proper styling

* fix: incorrect use of the theme system and linked file manger sidebar with current folder

---------

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

* Enhance VNC token generation to include optional username parameter and refactor username input handling in HostGeneralTab (#733)

* Fix Docker build info generation

* Remove unused node-fetch dependency

* feat: prompt user for SSH key passphrase on use (#715)

When an encrypted SSH key has no stored passphrase, show a lightweight
dialog prompting the user to enter it at connection time instead of
failing with a parse error. Supports both desktop and mobile terminals.

Closes Termix-SSH/Support#354

* fix: prevent session crash when uploading to permission-denied directory (#716)

- Wrap writeFile sftp.stat callback in try-catch to prevent uncaught
  exceptions from escaping the callback into the event loop
- Add missing stream.stderr error handler in writeFile fallback to
  prevent unhandled error events from crashing the process
- Remove bogus activeOperations decrement in both writeFile and
  uploadFile fallback methods (counter was never incremented)
- Add res.headersSent checks in fallback disconnect paths to prevent
  ERR_HTTP_HEADERS_SENT crashes

Closes Termix-SSH/Support#652

* feat: add LOG_TIMESTAMP_FORMAT env var for 24h/ISO log timestamps (#718)

Support LOG_TIMESTAMP_FORMAT environment variable with values:
- "24h": 24-hour format (14:58:45)
- "iso": ISO 8601 format (2026-04-25T14:58:45.000Z)
- default: locale format (2:58:45 PM)

Closes Termix-SSH/Support#650

* feat: open file manager at terminal current working directory (#719)

* feat: open file manager at terminal current working directory

When right-clicking in the terminal and selecting "Open File Manager
Here", query the current working directory via a separate SSH exec
channel and pass it as the initial path to the file manager tab.

Closes Termix-SSH/Support#649

* chore: sync package-lock.json with node-fetch and deps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: remove undefined TerminalContextMenu from bad merge resolution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>

* fix: show reconnect overlay when SSH server reboots (#720)

When the remote server reboots, the SSH connection closes while the
stream is still active. The close handler only sent the "disconnected"
message when sshStream was null, so the frontend never received the
disconnect notification and hung with a blinking cursor.

Change the else-if condition to always send the "disconnected" message
regardless of stream state.

Closes Termix-SSH/Support#648

* feat: support read-only Docker container mode (#721)

Move nginx runtime files (config, pid, logs, temp dirs) from /app/nginx/
to /tmp/nginx/ so the container can run with read_only: true. Template
files remain in /app/nginx/ as read-only assets.

Users can now harden the container with:
  read_only: true
  tmpfs:
    - /tmp

Closes Termix-SSH/Support#647

* fix: allow editing host folder without re-entering password (#722)

When editing an existing host, the password field is stripped by the
backend for security. The form validation treated the empty password
as invalid, disabling the Update Host button even for non-auth changes
like folder assignment.

Use an "existing_password" sentinel (mirroring the existing
"existing_key" pattern) to represent an unchanged password during
editing, skip validation for it, and omit it from the update payload.

Closes Termix-SSH/Support#645

* fix: auto-close tab on graceful SSH disconnect (exit/Ctrl+D) (#723)

Distinguish between graceful shell exit and unexpected disconnection
using the stream close event's exit code. When the shell exits normally
(code != null), send "session_ended" instead of "disconnected". The
frontend auto-closes the tab on session_ended, and shows the reconnect
overlay only on unexpected disconnections.

Closes Termix-SSH/Support#643

* fix: reattach existing SSH session on WebSocket reconnect (#724)

WebSocket reconnection was always creating a new SSH connection with
full authentication instead of reattaching to the existing SSH session.
The condition `!isReconnectingRef.current` prevented session reattach
during reconnection, causing repeated password auth attempts that
trigger SSHGuard/fail2ban blocking.

Remove the guard so reconnection tries to reattach the persisted
session first. If the session has expired, the backend sends
sessionExpired and the frontend falls back to a new connection.

Closes Termix-SSH/Support#644

* fix: prevent browser crash when uploading large files (>100MB) (#725)

The file-to-base64 conversion used a byte-by-byte string concatenation
loop (String.fromCharCode + btoa), which allocated ~3x the file size
in intermediate strings, causing the browser tab to OOM on files over
~100MB.

Replace with FileReader.readAsDataURL which delegates base64 encoding
to the browser engine natively, avoiding the intermediate allocations.

Closes Termix-SSH/Support#577

* fix: support SSH multi-factor auth with publickey + password (#726)

When sshd requires AuthenticationMethods publickey,password, the
connection failed because the key auth branch only set privateKey
without also setting password. After publickey partial auth succeeded,
ssh2 sent keyboard-interactive (due to tryKeyboard:true) instead of
password, which the server rejected.

Pass the credential password alongside the private key so ssh2 can
complete the password step after publickey succeeds.

Closes Termix-SSH/Support#629

* feat(oidc): add OIDC_ALLOW_REGISTRATION env to bypass allow_registration for OIDC (#727)

The `allow_registration` setting blocks both password-based and OIDC user
creation. Admins who want to close password registration but still onboard
new users via a trusted IdP (with the existing `OIDC_ALLOWED_USERS` whitelist)
have no way to do that today.

Introduce an `OIDC_ALLOW_REGISTRATION` env var. When set to `true`, the OIDC
callback skips the `allow_registration` settings check while still honoring
the `OIDC_ALLOWED_USERS` whitelist. Password registration via `POST
/users/create` continues to respect `allow_registration`.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* perf: lazy load locales, file previews, and decouple startup imports (#729)

* perf: lazy load locale bundles

* perf: lazy load file preview modules

* perf: avoid eager api client load on startup

* chore: remove dead code, tighten types, fix lint warnings (#730)

* chore: clean up low-risk lint warnings

* chore: tighten utility types

* chore: preserve backend error causes

* chore: simplify command palette host state

* chore: remove unused frontend code

* chore: prune stale frontend state

* chore: trim unused navigation code

* chore: prune unused user settings props

* chore: trim unused sidebar state

* chore: remove stale host editor imports

* chore: tighten shared frontend types

* chore: narrow desktop helper types

* chore: type network topology data

* chore: type connection log errors

* chore: use typed tab context

* chore: type api client error metadata

* chore: tighten terminal config types

* chore: type host proxy chains

* chore: type host editor form data

* chore: use typed host viewer fields

* chore: format app builder patch script

* Fix client auth cache after upgrades

* chore: fix pr checks after dev merge

* fix: remove duplicate session-expired useEffect in FullScreenAppWrapper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Xenthys <x@dis.gg>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: npm package warnings

* feat: reconnect after file manager disconnects

* feat: add docs button in api keys

* feat: change colors for server tunnels

* fix: fetch password from API for Copy Password button (#736)

* chore: update readme's

* feat: improve c2s UI in user profile

* feat: improve ssh key detection and move open file manager at path for terminal button

* fix: restore missing getHostPassword import in Tab.tsx (#737)

* fix: security related fixes

* feat: improve alert code

* Fix Electron clipboard handling

* fix: untranslated alert text

---------

Co-authored-by: Xenthys <x@dis.gg>
Co-authored-by: PT Kelana Tech Solutions <ptkelanatechsolutions@gmail.com>
Co-authored-by: suryacagur <suryacagur.dev@gmail.com>
Co-authored-by: zimmra <28514085+zimmra@users.noreply.github.com>
Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Fuad <funtik1229@yandex.ru>
2026-05-06 15:12:07 -05:00
Luke Gustafson af9fc95b0e Update README.md 2026-05-01 15:03:45 -05:00
LukeGus 18633c5760 chore: update cask 2026-04-22 17:47:56 -05:00
Luke Gustafson c67d914e61 New Crowdin updates (#713)
* 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 (Korean)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* 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 (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Bengali)

* New translations en.json (Thai)

* New translations en.json (Hindi)
release-2.1.0-tag
2026-04-22 17:10:21 -05:00
Luke Gustafson e3cb1f82af v2.1.0 (#711)
* feat: enhance terminal theme preview and persistence (#637)

- Refactor Terminal.tsx to optimize theme update logic and eliminate flashes
- Implement localStorage persistence for terminal themes per host
- Fix hover preview to redraw buffer content instantly
- Ensure theme preferences survive cookie clears

Co-authored-by: Gemini CLI <gemini@cli.local>

* fix: update darwin platform identifier to osx (#626)

* feat: implement SSH algorithms mapping and refactor cipher usage across SSH modules (#627)

* feat: enhance WebSocket connection handling for embedded mode (#628)

* fix(auth): pass JWT token via URL param for Electron/mobile OIDC callback (#630)

The OIDC callback redirect did not include the JWT token as a URL
parameter for desktop/mobile device types, causing Electron and
React Native webviews to have jwt = undefined after login.

Closes Termix-SSH/Support#562

* fix: remove hardcoded version number from dashboard (#632)

The version text was initialized to "v1.8.0" which displayed incorrect
version on the dashboard before the API response. Changed to empty
string so it shows nothing until the real version is fetched.

Closes Termix-SSH/Support#550

* fix: admin role toggle showing incorrect state after update (#633)

After successfully toggling admin status, onSuccess() closes the dialog
and clears the user reference, but onOpenChange(true) then reopens the
dialog with null user, causing isAdmin state to not sync properly.

Removed the redundant dialog reopen after success - let onSuccess
handle the cleanup normally.

Closes Termix-SSH/Support#549

* fix: allow disabling password login when OIDC is configured via env vars (#634)

The admin OIDC config endpoint only checked the database for OIDC
configuration, ignoring environment variables. This caused the frontend
to incorrectly block disabling password login when OIDC was configured
via OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, etc.

Now falls back to getOIDCConfigFromEnv() when no database config exists,
matching the behavior of the public /oidc-config endpoint.

Closes Termix-SSH/Support#561

* fix: sync snippet selected terminals count when tabs are closed (#635)

selectedSnippetTabIds was not cleaned up when terminal tabs were closed,
causing the snippet dialog to show stale terminal count. Added useEffect
to filter out IDs of closed tabs.

Closes Termix-SSH/Support#534

* feature: toggle history globally (#636)

* Fix RDP audio output and dynamic session resize (#625)

Co-authored-by: AllX <contact@alexmaftei.com>

* fix: check connection state before fallback exec in file manager (#644)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: check connection state before fallback exec in file manager

When SFTP operations fail and tryFallbackMethod is called, the SSH
client may already be disconnected. Calling client.exec() on a
disconnected client throws an unhandled exception that crashes the
backend process.

Added connection state check at the start of all three
tryFallbackMethod closures (listFiles, writeFile, uploadFile).

Closes Termix-SSH/Support#451

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: restrict postMessage targetOrigin to prevent JWT leakage (#645)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: restrict postMessage targetOrigin to prevent JWT leakage

Multiple postMessage calls used wildcard "*" as targetOrigin, allowing
any parent window to intercept JWT tokens if Termix is embedded in an
iframe.

Changes:
- main-axios.ts: Only send postMessage in Electron iframe context
  (added isElectron() check), use window.location.origin as target
- Auth.tsx: Replace "*" with window.location.origin for all three
  AUTH_SUCCESS postMessage calls (already gated by isInElectronWebView)
- ElectronLoginForm.tsx: Use server URL origin for iframe postMessage,
  fall back to "*" only if origin parsing fails

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: stats monitoring resolves SSH key from credential privateKey field (#643)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: stats monitoring resolves SSH key from credential privateKey field

When loading credentials for status monitoring, only the `key` field
was checked but not `privateKey`. The ssh_credentials table has both
fields and some credentials store the key in `privateKey`. This caused
stats polling to fail with auth errors for key-based credentials.

Closes Termix-SSH/Support#429

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* feat: add collapse/expand all button for host manager folders (#642)

* Update sha256 value for v2.0.0 universal dmg (#629)

* feat: add collapse/expand all button for host manager folders

All folders were always auto-expanded with no way to collapse them all
at once. Added a toggle button in the toolbar that collapses or expands
all folder accordions. Icon switches between ChevronsDownUp (collapse)
and ChevronsUpDown (expand) to indicate current action.

Closes Termix-SSH/Support#488

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: prevent invalid SSH key from crashing stats polling loop (#640)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: prevent invalid SSH key from crashing stats polling loop

Two fixes:
1. Add .catch() to pollHostMetrics() call inside setInterval to prevent
   unhandled promise rejections from crashing the process
2. Add "Invalid SSH key format" to the auth failure error patterns in
   collectMetrics so it's properly tracked instead of re-thrown

Closes Termix-SSH/Support#478

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: revoke all sessions when password is changed or reset (#647)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: revoke all sessions when password is changed or reset

logoutUser() without sessionId only cleared in-memory crypto state
but did not delete session records from the database. This meant
old JWT tokens remained valid after password change/reset.

Now deletes all session records for the user when no specific
sessionId is provided, which is the code path used by password
reset and password change handlers.

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: isolate RDP keyboard input to active tab (#663)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: disable RDP keyboard input when tab is not visible

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* Fix clipboard paste browser popup (#667)

* feat: switch to adjacent tab when closing current tab (#661)

* Update sha256 value for v2.0.0 universal dmg (#629)

* feat: switch to adjacent tab when closing current tab

Previously closing the current tab always switched to the first
remaining tab (often Dashboard). Now switches to the adjacent tab —
the next one in order, or the previous if the closed tab was last.

This matches the tab-close behavior of browsers and IDEs.

Closes Termix-SSH/Support#606

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: add auth token to database export/import in Electron app (#664)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: add Bearer token to database export/import requests in Electron

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* Fix WebSocket reconnection and add connection lost overlay (#668)

* fix: skip metrics collection for hosts with authType none or opkssh (#639)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: skip metrics collection for hosts with authType none or opkssh

supportsMetrics() only checked connectionType but ignored authType.
Hosts configured with Authentication: None (e.g. Tailscale SSH) or
opkssh would trigger SSH metrics polling, causing repeated auth
failures since no credentials are available.

Closes Termix-SSH/Support#515

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: align cookie maxAge with JWT expiration to prevent early logout (#658)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: align cookie maxAge with JWT expiration to prevent early logout

The JWT cookie maxAge for regular (non-rememberMe) logins was set to
2 hours, while the JWT token itself was valid for 24 hours. After 2
hours the cookie expired and the user was logged out, even during
active SSH sessions.

Changed cookie maxAge from 2h to 24h for regular logins to match
the JWT expiration. Affects both password login and OIDC login paths.

Closes Termix-SSH/Support#595
Closes Termix-SSH/Support#583

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: remove sensitive data from log output (#649)

- Password reset: stop logging the 6-digit reset code in plaintext.
  The code is still stored in the settings table for retrieval.
- Password reset: return identical response for non-existent users
  and OIDC users to prevent username enumeration.
- OPKSSH callback: remove URL, query params, and forwarded headers
  from log output to prevent token/code leakage.

* feat: display file owner and group in file manager list view (#654)

* Update sha256 value for v2.0.0 universal dmg (#629)

* feat: display file owner and group in file manager list view

Added an Owner column to the file manager list view showing owner:group
for each file. The data was already returned by the backend (SFTP
returns uid/gid, ls fallback returns usernames) but not displayed.

Column is hidden on small screens (md:block) to avoid crowding.

Closes Termix-SSH/Support#603

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: prevent file manager from showing stale directory contents (#655)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: prevent file manager from showing stale directory contents

Two issues caused the file browser to get stuck showing outdated
directory contents after folder operations:

1. handleRefreshDirectory could be blocked by a lingering isLoading
   state from a previous request. Now force-resets loading state
   before initiating the refresh.

2. debouncedLoadDirectory skipped requests when the path hadn't
   changed (path === lastPathChangeRef), but after create/move/delete
   operations the path stays the same while contents change. Added
   force parameter to bypass the path equality check.

Closes Termix-SSH/Support#599

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: fallback to default layout when dashboard preferences lack cards (#652)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: fallback to default layout when dashboard preferences lack cards

getDashboardPreferences may return null, empty object, or an object
without a cards array (e.g. when behind a reverse proxy that alters
the response, or on first load for a new user). This caused
layout.cards.filter() to throw, leaving the dashboard as a black
screen after login.

Now validates that the response has a cards array before using it,
falling back to DEFAULT_LAYOUT otherwise.

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: bind SSH sessions to userId and verify ownership on access (#650)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: bind SSH sessions to userId and verify ownership on access

SSHSession objects in file-manager and docker did not store userId,
allowing any authenticated user to operate on another user's session
if they knew the sessionId.

Changes:
- Added userId field to SSHSession interface in both modules
- Store userId when creating sessions (connect, TOTP, Warpgate paths)
- Added verifySessionOwnership() helper in file-manager
- Applied ownership checks to sudo-password, status, keepalive,
  listFiles endpoints in file-manager
- Applied ownership check to keepalive endpoint in docker
- Session creation in docker now stores userId in all 3 paths

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: use cookie-based auth for WebSocket instead of URL token (#646)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: use cookie-based auth for WebSocket instead of URL token

JWT tokens in WebSocket URL query strings are exposed in nginx access
logs, browser history, and proxy logs.

Backend: terminal and docker-console WebSocket servers now read JWT
from the cookie header as fallback when no URL token is provided.

Frontend: desktop terminal and docker console no longer append token
to WebSocket URL, relying on cookies sent automatically by the browser.

Mobile and Guacamole WebSocket connections are unchanged as they may
not have cookie access.

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: prevent long Docker container names from overflowing card bounds (#653)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: prevent long Docker container names from overflowing card bounds

Container names were not constrained to the card width, causing long
names to overlay adjacent container cards. Added overflow-hidden and
min-w-0 to the Card root element so the existing truncate class on
CardTitle takes effect within the grid layout.

Closes Termix-SSH/Support#601

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: preserve original timestamps in SSH login statistics (#657)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: preserve original timestamps in SSH login statistics

Failed login attempts showed the current time instead of the actual
attempt time. Two issues:

1. auth.log dates (e.g. "Mar 15 10:23:45") were parsed with a format
   that could fail on some platforms, falling back to new Date() which
   gives the current time. Changed to a more reliable format
   ("Mar 15, 2026 10:23:45") and fall back to the raw string instead
   of the current time.

2. Dates from previous years (e.g. December logs viewed in January)
   were assigned the current year, producing future dates. Now checks
   if the parsed date is in the future and subtracts a year.

Also fixed the same fallback issue for successful login timestamps.

Closes Termix-SSH/Support#570

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: remove plaintext credentials from internal host API responses (#651)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: remove plaintext credentials from internal host API responses

/db/host/internal and /db/host/internal/all returned password, key,
keyPassword, and autostart credentials in plaintext, protected only
by a static INTERNAL_AUTH_TOKEN. If the token leaked, all SSH
credentials would be exposed.

Changes:
- Stripped password, key, keyPassword, autostartPassword, autostartKey,
  autostartKeyPassword from both internal API responses
- Only return hostId, userId, and non-sensitive connection metadata
- Updated tunnel.ts endpoint resolution to use resolveHostById() for
  credentials instead of reading from HTTP response
- Autostart tunnel initialization no longer receives credentials from
  internal API, relying on server-side DB resolution at connect time

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: default keyType to auto instead of blocking host update (#641)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: default keyType to auto instead of blocking host update

When editing a host with key authentication, missing keyType value
caused form validation to fail silently, preventing the Update Host
button from saving changes. Now defaults keyType to "auto" instead
of raising a validation error.

Closes Termix-SSH/Support#510

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: downgrade credential migration errors to warnings (#659)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: downgrade credential migration errors to warnings

Credential migration failures during login (e.g. corrupted encrypted
data from older versions) were logged at ERROR level, causing alarm
in Docker logs. The migration is non-blocking — login succeeds
regardless — so these should be warnings.

Changed individual credential decryption failures and overall migration
failures from error to warn level. Also improved log messages to be
more descriptive.

Closes Termix-SSH/Support#541

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* feat: add Select All / Deselect All buttons for snippet terminal selection (#660)

* Update sha256 value for v2.0.0 universal dmg (#629)

* feat: add Select All / Deselect All buttons for snippet terminal selection

When running snippets on many terminals, users had to click each
terminal individually. Added Select All and Deselect All buttons
above the terminal list for batch selection.

Closes Termix-SSH/Support#535

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: admin user list not reading OIDC and admin status correctly (#665)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: align admin user list field names with API response (camelCase)

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: enable clipboard paste from host to RDP session (#666)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: sync host clipboard to RDP session on tab focus and mouse enter

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* fix: validate containerId and timestamp params to prevent command injection (#648)

* Update sha256 value for v2.0.0 universal dmg (#629)

* fix: validate containerId and timestamp params to prevent command injection

Docker API endpoints passed containerId, since, and until parameters
directly into shell commands via SSH exec without validation. An
authenticated user with Docker access could inject arbitrary shell
commands on the remote host.

Added Express param middleware to validate containerId against
^[a-zA-Z0-9][a-zA-Z0-9_.-]*$ for all 9 endpoints. Also validate
since/until timestamps in the logs endpoint against a strict regex.

---------

Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>

* Merge commit from fork

* Merge commit from fork

Replace double-quoted shell string interpolation with single-quoted
escaping in extractArchive and compressFiles endpoints. Double quotes
allow $(command) substitution, enabling arbitrary command execution
on the remote SSH host via crafted archive paths or file names.

Now uses the same single-quote escaping pattern used by all other
file manager operations in this file.

* Merge commit from fork

CORS: Replace permissive origin checks (any http/https) across all 6
microservices with a shared cors-config module that only allows:
- Same-origin requests (derived from Host header)
- Configured origins via CORS_ALLOWED_ORIGINS env var
- Dev origins (localhost:5173)

Docker console: Validate containerId against ^[a-zA-Z0-9][a-zA-Z0-9_.-]*$
and restrict shell to allowlist [bash, sh, ash, zsh] to prevent command
injection via WebSocket messages.

* Merge commit from fork

* refactor: add shared host-resolver for server-side credential resolution

Creates resolveHostById() utility that loads a host from DB and resolves
its credentials entirely server-side. This will be used by connection
modules to avoid receiving credentials from the frontend.

Also adds checkHostAccess() for permission validation.

* fix: strip sensitive credentials from host API responses

Remove password, key, keyPassword, sudoPassword, and other credential
fields from GET /db/host and GET /db/host/:id responses. Add boolean
indicators (hasPassword, hasKey, hasSudoPassword) so the frontend
knows capabilities without seeing actual values.

Add GET /db/host/:id/password endpoint for the copy-password feature
to fetch a specific password on demand.

* refactor: docker-console resolves credentials server-side by hostId

Instead of receiving the full hostConfig with credentials from the
frontend WebSocket message, docker-console now extracts hostId and
uses resolveHostById() to load credentials from the database.

Also validates containerId format and restricts shell to allowlist.

* feat: add getHostPassword API and update copy-password to use it

Add getHostPassword() frontend function that calls the new server-side
password endpoint instead of reading from the host object.

Update Tab component to use boolean indicators (hasPassword, hasKey,
hasSudoPassword) from the sanitized API response, with backward
compatibility for the old response format.

Add boolean indicator fields to Host type definition.

* refactor: file-manager resolves credentials server-side via host-resolver

When frontend doesn't provide password/sshKey (due to API stripping),
file-manager now uses resolveHostById() to load credentials from DB.
Falls back to provided credentials for backward compatibility.

* refactor: terminal resolves credentials server-side via host-resolver

When frontend doesn't provide password/key (due to API stripping),
terminal now uses resolveHostById() to load credentials from DB.
Preserves backward compatibility with reconnect_with_credentials
where user provides credentials interactively.

* refactor: tunnel resolves source credentials server-side via host-resolver

When frontend doesn't provide sourcePassword/sourceSSHKey (due to API
stripping), tunnel now uses resolveHostById() to load credentials from
DB for both the connect and cleanup paths.

* fix: terminal sudo auto-fill fetches password from server on demand

After credentials are stripped from API responses, hostConfig.password
is no longer available. Sudo auto-fill now checks boolean indicators
to show the prompt, then fetches the actual password via getHostPassword
API only when the user confirms the auto-fill action.

* fix: host editor fetches full credentials via export API for editing

After credentials are stripped from the host list API, the editor would
show empty password/key fields. Now uses exportSSHHostWithCredentials()
to fetch the full host data with credentials when opening the editor.
Applies to all paths: direct edit, sidebar click, and external navigation.

---------

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

* feat: update jsdoc comments for /host instead of /ssh

* fix: align OIDC login cookie maxAge with JWT expiration (2h → 24h) (#671)

* fix: persist OIDC JWT token to localStorage in Electron app (#672)

* fix: add error toast for empty file download and remove stray prop in tab bar (#674)

* fix: prevent server status failure from blocking host list loading (#673)

* fix: show server config dialog on first launch instead of auto-selecting embedded (#675)

* fix: remove unnecessary registration disabled toast on login page (#670)

* fix: add clipboard fallback and toast feedback for Copy Password button (#669)

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

* fix: allow file origin for packaged Electron desktop app (#676)

* Add AWS logo to README

* fix: allow file origin for packaged Electron desktop app

---------

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

* fix: backend compliation errors

* feat: remove theme selector from nav bar

* fix: validate and fallback credentialId during JSON host bulk import (#677)

* Add AWS logo to README

* fix: validate and fallback credentialId during JSON host bulk import

---------

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

* fix: await tunnel cleanup to prevent new connection from being killed (#678)

* Add AWS logo to README

* fix: await tunnel cleanup before creating new connection to prevent race condition

---------

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

* fix: disable keyboard-interactive when host auth is set to None (#682)

* Add AWS logo to README

* fix: disable keyboard-interactive auth when host authType is none

---------

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

* fix: use carriage return for mobile startup snippet execution (#680)

* Add AWS logo to README

* fix: use carriage return for mobile startup snippet execution

---------

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

* fix: prevent file upload from crashing backend on permission denied (#681)

* Add AWS logo to README

* fix: add stderr error handlers and connection check to prevent upload crash

---------

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

* fix: add missing stream error handlers in Docker console (#684)

* Add AWS logo to README

* fix: add missing stream error handlers in Docker console to prevent crashes

---------

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

* fix: use carriage return for snippet execution to support PowerShell (#679)

* Add AWS logo to README

* fix: use carriage return instead of line feed for snippet and command execution

---------

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

* fix: restrict remaining postMessage targetOrigin from wildcard to origin (#685)

* Add AWS logo to README

* fix: restrict postMessage targetOrigin to prevent JWT token leakage

---------

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

* feat: add SESSION_TIMEOUT_HOURS environment variable for customizable session duration (#662)

* feat: add SESSION_TIMEOUT_HOURS environment variable for session duration

Session timeout was hardcoded to 24h (JWT) and 2h (cookie). Now both
are configurable via SESSION_TIMEOUT_HOURS env var (default: 24).

Set in docker-compose.yml:
  environment:
    SESSION_TIMEOUT_HOURS: "72"

Also fixes the cookie maxAge mismatch (was 2h, now matches JWT).
Remember Me sessions remain at 30 days regardless of this setting.

Closes Termix-SSH/Support#609
Closes Termix-SSH/Support#595

* refactor: move session timeout from env var to Admin Settings

Replace SESSION_TIMEOUT_HOURS environment variable with a database-backed
setting configurable from Admin Settings UI. Default remains 24 hours.

---------

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

* feat: add port knocking support for SSH connections (#694)

* Add AWS logo to README

* feat: add port knocking support for SSH connections

Send TCP/UDP knock packets to a configurable port sequence before
establishing SSH connections. Configured per-host in the host editor
under a new Port Knocking accordion section. Supports custom protocol
(TCP/UDP) and delay between knocks. Knocking failures don't block
the connection attempt.

Closes Termix-SSH/Support#524

---------

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

* feat: add Wake-on-LAN support for hosts (#696)

* Add AWS logo to README

* feat: add Wake-on-LAN support for hosts

---------

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

* feat: add export all hosts as JSON (#688)

* Add AWS logo to README

* feat: add export all hosts as JSON

Add GET /ssh/db/hosts/export endpoint and Export All button in the host
manager toolbar. Exported format is compatible with existing bulk import.
Includes sensitive data warning confirmation before download.

Closes Termix-SSH/Support#582

---------

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

* feat: add snippet sharing with users and roles (#691)

* Add AWS logo to README

* feat: add snippet sharing with users and roles

Add snippetAccess table and RBAC routes for sharing snippets, following
the same pattern as host sharing. Users can share snippets with other
users or roles via a share dialog. Shared snippets appear in a dedicated
section in the snippets sidebar as read-only with copy support.

Closes Termix-SSH/Support#474

---------

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

* fix: auth errors and ws connection errors in dev env

* feat: add opt-in tmux integration for persistent terminal sessions (#683)

* Add backend tmux integration with native scrollback

Detect tmux on remote hosts via SSH exec channel, auto-attach or create
sessions with mouse mode, history-limit 50000, set-clipboard on, and
allow-passthrough on for native scrollback, OSC 52 clipboard sync, and
safe paste handling. Use && exit so the shell only closes if tmux
started successfully. Query session name after auto-creation.

* Add frontend tmux session handling and picker dialog

Desktop: handle tmux WebSocket messages, show session picker with window
count, attached clients, and last activity when multiple sessions exist.
Toast warning when Auto-tmux is enabled but tmux is missing on remote.
Mobile: auto-attach to first available session. All user-facing strings
are localized via i18n.

* Add Auto-tmux toggle in host settings and i18n strings

Per-host opt-in toggle following the existing autoMosh pattern.
English i18n strings for all tmux-related UI elements.

* Show a toast hint on first drag inside a tmux session

When the user drags the mouse inside a tmux-wrapped terminal, show a
localized toast ("Adjust selection and press Enter to copy") once per
tab session. Purely frontend so the hint is i18n-ready and doesn't
pollute the tmux status bar.

* chore: increment ver

* feat: add right-click context menu in terminal to open file manager (#695)

* Add AWS logo to README

* feat: add right-click context menu in terminal to open file manager

---------

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

* Fix/desktop guac connect flow (#687)

* fix: use direct guacamole websocket port in embedded electron mode

* Fix desktop remote token flow for redacted hosts

---------

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

* fix: allow file:// origin in shared cors middleware (#686)

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

* feat: add command history toggle and sensitive command filtering (#693)

* Add AWS logo to README

* feat: add command history toggle and sensitive command filtering

Add on/off toggle for command history recording in User Profile settings.
Commands matching sensitive patterns (passwords, secrets, tokens, API keys)
are automatically filtered on both frontend and backend, never stored.

Closes Termix-SSH/Support#461

---------

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

* OPKSSH proxy, certificate auth, and inline provider selection (#692)

* fix: OPKSSH proxy integration for remote deployments

Migrate proxy routes from /ssh/ to /host/ prefix. Use session's
remote redirect URI for callback path instead of hardcoded
/login-callback. Add OAuth callback fallback for external browser
redirects with state parameter binding to prevent cross-session
mixup. Reject cookie-less callbacks that can't be identified.

* fix: implement OPKSSH certificate authentication for ssh2

Extract OPKSSH certificate auth into shared module that works
around ssh2's lack of native certificate support: grafts cert
blob onto parsed key, wraps ECDSA sign() for DER-to-SSH
conversion, and patches Protocol.authPK for correct algorithm.
Applied across terminal, file-manager, docker, and server-stats.
Removes legacy temp file approach in favor of in-memory keys.

* feat: inline OPKSSH provider selection in dialog

Parse OIDC provider aliases and issuers from config.yml using
js-yaml and send them to the frontend via the WebSocket message.
The dialog renders a "Sign in with {Provider}" button per provider,
opening the browser directly to the OAuth flow and skipping the
external chooser page. Falls back to the existing "Open in Browser"
behavior when providers aren't available.

---------

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

* feat: add configurable log level via Admin Settings (#690)

* Add AWS logo to README

* feat: add configurable log level via Admin Settings

Add log verbosity control (debug/info/warn/error) through Admin Settings
UI and LOG_LEVEL environment variable. Database setting takes precedence.
Changes take effect immediately without restart.

Closes Termix-SSH/Support#499

---------

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

* feat: add reconnect button for disconnected SSH sessions (#689)

* Add AWS logo to README

* feat: add reconnect button for disconnected SSH sessions

When an SSH connection drops, show a reconnect overlay instead of
closing the tab. Users can click Reconnect to re-establish the
connection or Close to dismiss. Also triggers after auto-reconnect
attempts are exhausted.

Closes Termix-SSH/Support#596
Closes Termix-SSH/Support#542
Closes Termix-SSH/Support#604

---------

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

* feat: fix port knocking and mac address not saving to backend

* fix: fix snippets table not being created

* fix: command history logic error, snippet sharing failing and improved UI for it

* Reset stale trust state when TOTP is enabled (#697)

* Add AWS logo to README

* Reset stale trust state when TOTP is enabled

Enablement now updates the user record, revokes existing sessions, clears trusted devices, and persists the result using the existing route flow. The change stays narrow and avoids introducing a one-off auth-manager wrapper or changing the save helper contract.

Constraint: Keep the change close to the existing auth route and avoid extra abstractions
Rejected: Keep the dedicated auth-manager helper | it was single-use and widened the surface area
Confidence: high
Scope-risk: narrow
Directive: If this behavior changes again, keep the reset logic at the route boundary unless another caller appears
Tested: tsc -p tsconfig.node.json --pretty false, git diff --check
Not-tested: full frontend build

---------

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

* fix: version disabling in user profile not properly disabling and mac address not saving in host manager

* feat: improved reconnect ui for terminals

* feat: improve right click copy/paste

* fix: some themes not including all the needed colors

* chore: remove donate button

* fix: schema errors, password logic errors, sswapped line order in host.ts

* fix: cors being too strict

* fix: passphrase erorr and tmux error

* fix: guacd improvements, ui bugs, connection problems, etc

* fix: shrink image, opkssh fixes, desktop ui changes

* feat: dont require password to export and fixed export failures

* feat: opkssh fixes, guacamole ui fixes, update readme for release

* fix: tabs closing fast causiung no tab to be active and electron header persistance issue

* fix: guacd params getting malformed

* fix: desktop app header persistance

* fix: desktop app header persistance

* feat: desktop app not logging in

* feat: improve okpkssh implementation and fix redirect uri bug

* fix: opkssh redirect

* fix: backend hang (ongoing)

* fix: tunnels not being able to be saved

* fix: c2s networking stability (activity/log, metrics, status) (#701)

- /activity/log: the trim-over-100 path called SimpleDBOps.delete with a
  userId instead of a where clause and 500'd every call. Use inArray on
  the actual ids, best-effort (trim failures don't fail the log).

- /metrics/register-viewer: now a graceful 200 no-op when the host
  can't be found, metrics are disabled, or the connection type doesn't
  support metrics. Any internal error is reported as skipped instead
  of a 500, and the fire-and-forget startMetricsForHost can no longer
  leak an unhandled rejection.

- /metrics/🆔 treat 404 as "no metrics yet / disabled" rather than
  an error. Dashboard skips hosts known to be offline before asking
  for metrics.

- /status: retry with 2s/5s/8s timeouts and 3s/5s pauses (23s worst
  case, fits in the 30s poll cycle) before surfacing a network error;
  intermediate attempts stay silent.

- Replace the blocking "connection lost" overlay with a persistent,
  non-dismissible toast ("Unstable server connection, recovering…")
  carrying a Reload action. Users keep full access to the UI; if they
  try to connect to a host and it fails, that's on them. The toast
  clears to the usual "Server connection restored" success toast on
  the next healthy API response. The toast triggers on any of
  ERR_NETWORK / ECONNREFUSED / ECONNABORTED / ECONNRESET / ETIMEDOUT
  / ERR_CANCELED, "Request aborted"/timeout messages, or
  database/drizzle/sqlite errors.

* fix(guacamole): honor host RDP DPI in client and tab params (#703)

* fix(file-manager): preserve remote file mode after SFTP write (#704)

* fix(admin): target admin toggle APIs by user id (#705)

* fix(terminal): resolve Electron SSH websocket URL from server config (#706)

* fix(snippets): accept snippets or legacy updates in reorder API (#707)

* fix(admin): fetch users list when users tab is opened (#708)

* fix(docker): improve list layout and overflow for container cards (#709)

* fix(guacamole): gate keyboard capture on focus and visibility (#710)

* fix: remove snippets test file

* chore: run linter

* fix: increase macos memory for building

* Potential fix for pull request finding 'Unused variable, import, function or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

---------

Co-authored-by: Will Moore <will@clevercode.ca>
Co-authored-by: Gemini CLI <gemini@cli.local>
Co-authored-by: Chakyiu <49145984+Chakyiu@users.noreply.github.com>
Co-authored-by: Jozef Rebjak <jozefrebjak@icloud.com>
Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
Co-authored-by: Daniel Quinan <68088383+DanielQuinan@users.noreply.github.com>
Co-authored-by: allxm4 <77125344+allxm4@users.noreply.github.com>
Co-authored-by: AllX <contact@alexmaftei.com>
Co-authored-by: Razvan Aurariu <38325118+rzv-me@users.noreply.github.com>
Co-authored-by: Dylan Ysmal <Xenthys@users.noreply.github.com>
Co-authored-by: vvbbnn00 <vvbbnn00@foxmail.com>
Co-authored-by: Lbubeer <Lbubeer1@gmail.com>
Co-authored-by: Dominik <DL6ER@users.noreply.github.com>
Co-authored-by: LukeGus <lukegustafson06@gmail.com>
Co-authored-by: TerrifiedBug <35064668+TerrifiedBug@users.noreply.github.com>
Co-authored-by: JIHUN <asdfgl98@naver.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
2026-04-22 16:55:23 -05:00
Luke Gustafson 9b1cc3dbf4 Simplify language selection section in README 2026-04-20 17:23:51 -05:00
Luke Gustafson e87abe676e Update guacd image version to 1.6.0 2026-04-20 17:16:01 -05:00
Luke Gustafson 4f092f7c4b Delete .github/FUNDING.yml 2026-04-14 16:04:24 -05:00
Luke Gustafson 579fa81ac3 Remove sponsorship information from README
Removed sponsorship section from README.
2026-04-14 16:04:06 -05:00
Luke Gustafson 1492549d36 Add AWS logo to README 2026-04-09 16:36:13 -05:00
Luke Gustafson 8aa8911671 Update Akamai logo height in README.md 2026-04-06 22:19:03 -05:00
Luke Gustafson 76aad24f94 Add Akamai logo to README 2026-04-06 22:17:55 -05:00
Razvan Aurariu 2931fd71bb Update sha256 value for v2.0.0 universal dmg (#629) 2026-03-29 00:28:54 -05:00
Luke Gustafson 0656e1aee4 Update logo from DartNode to TailScale
Replaced DartNode logo with TailScale logo in README.
2026-03-25 16:27:41 -05:00
Luke Gustafson 4aa7d6e3d1 Update DartNode logo in README 2026-03-22 15:53:44 -05:00
Luke Gustafson dfa8f25299 Update image alt text and add DartNode logo 2026-03-22 15:50:41 -05:00
LukeGus 69eca2652b feat: add migration to fix host loading errors 2026-03-15 00:52:21 -05:00
Luke Gustafson aef1036ab0 New Crowdin updates (#624)
* Update source file en.json

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Arabic)

* 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 (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 (Swedish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* 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 21:55:14 -05:00
Luke Gustafson d695663e41 Add Guacamole integration settings to en.json 2026-03-14 21:49:17 -05:00