mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-08-30 02:41:34 +00:00
release-2.6.0 (#1085)
* fix: general bug fixes * fix: general qol additions * ci(deps): bump actions/setup-node in the github-actions group (#1068) Bumps the github-actions group with 1 update: [actions/setup-node](https://github.com/actions/setup-node). Updates `actions/setup-node` from 6 to 7 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump the dev-patch-updates group with 28 updates (#1069) Bumps the dev-patch-updates group with 28 updates: | Package | From | To | | --- | --- | --- | | [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.5.2` | `2.5.4` | | [@codemirror/view](https://github.com/codemirror/view) | `6.43.5` | `6.43.6` | | [@radix-ui/react-accordion](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/accordion) | `1.2.15` | `1.2.17` | | [@radix-ui/react-alert-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/alert-dialog) | `1.1.18` | `1.1.20` | | [@radix-ui/react-checkbox](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/checkbox) | `1.3.6` | `1.3.8` | | [@radix-ui/react-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dialog) | `1.1.18` | `1.1.20` | | [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.1.19` | `2.1.21` | | [@radix-ui/react-label](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/label) | `2.1.11` | `2.1.12` | | [@radix-ui/react-popover](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/popover) | `1.1.18` | `1.1.20` | | [@radix-ui/react-progress](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/progress) | `1.1.11` | `1.1.13` | | [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/scroll-area) | `1.2.13` | `1.2.15` | | [@radix-ui/react-select](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/select) | `2.3.2` | `2.3.4` | | [@radix-ui/react-separator](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/separator) | `1.1.11` | `1.1.12` | | [@radix-ui/react-slider](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slider) | `1.4.2` | `1.4.4` | | [@radix-ui/react-switch](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/switch) | `1.3.2` | `1.3.4` | | [@radix-ui/react-tabs](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tabs) | `1.1.16` | `1.1.18` | | [@radix-ui/react-tooltip](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tooltip) | `1.2.11` | `1.2.13` | | [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.3.2` | `4.3.3` | | [@uiw/codemirror-extensions-langs](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` | | [@uiw/codemirror-theme-github](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` | | [@uiw/react-codemirror](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` | | [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.1.9` | `4.1.10` | | [@vitest/ui](https://github.com/vitest-dev/vitest/tree/HEAD/packages/ui) | `4.1.9` | `4.1.10` | | [i18next](https://github.com/i18next/i18next) | `26.3.4` | `26.3.6` | | [radix-ui](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radix-ui) | `1.6.1` | `1.6.3` | | [react-i18next](https://github.com/i18next/react-i18next) | `17.0.8` | `17.0.10` | | [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.3.2` | `4.3.3` | | [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.9` | `4.1.10` | Updates `@biomejs/biome` from 2.5.2 to 2.5.4 - [Release notes](https://github.com/biomejs/biome/releases) - [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md) - [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.5.4/packages/@biomejs/biome) Updates `@codemirror/view` from 6.43.5 to 6.43.6 - [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/view/commits) Updates `@radix-ui/react-accordion` from 1.2.15 to 1.2.17 - [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.18 to 1.1.20 - [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.6 to 1.3.8 - [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.18 to 1.1.20 - [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.19 to 2.1.21 - [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.11 to 2.1.12 - [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.18 to 1.1.20 - [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.11 to 1.1.13 - [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.13 to 1.2.15 - [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-select` from 2.3.2 to 2.3.4 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/select/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/select) Updates `@radix-ui/react-separator` from 1.1.11 to 1.1.12 - [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-slider` from 1.4.2 to 1.4.4 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/slider/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slider) Updates `@radix-ui/react-switch` from 1.3.2 to 1.3.4 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/switch/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/switch) Updates `@radix-ui/react-tabs` from 1.1.16 to 1.1.18 - [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.11 to 1.2.13 - [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 `@tailwindcss/vite` from 4.3.2 to 4.3.3 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-vite) Updates `@uiw/codemirror-extensions-langs` from 4.25.10 to 4.25.11 - [Release notes](https://github.com/uiwjs/react-codemirror/releases) - [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11) Updates `@uiw/codemirror-theme-github` from 4.25.10 to 4.25.11 - [Release notes](https://github.com/uiwjs/react-codemirror/releases) - [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11) Updates `@uiw/react-codemirror` from 4.25.10 to 4.25.11 - [Release notes](https://github.com/uiwjs/react-codemirror/releases) - [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11) Updates `@vitest/coverage-v8` from 4.1.9 to 4.1.10 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/coverage-v8) Updates `@vitest/ui` from 4.1.9 to 4.1.10 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/ui) Updates `i18next` from 26.3.4 to 26.3.6 - [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.4...v26.3.6) Updates `radix-ui` from 1.6.1 to 1.6.3 - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/radix-ui/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/radix-ui) Updates `react-i18next` from 17.0.8 to 17.0.10 - [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/react-i18next/compare/v17.0.8...v17.0.10) Updates `tailwindcss` from 4.3.2 to 4.3.3 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/tailwindcss) Updates `vitest` from 4.1.9 to 4.1.10 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest) --- updated-dependencies: - dependency-name: "@biomejs/biome" dependency-version: 2.5.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@codemirror/view" dependency-version: 6.43.6 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.17 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.20 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.8 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.20 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.21 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.12 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.20 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.13 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.15 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@radix-ui/react-select" dependency-version: 2.3.4 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.12 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@radix-ui/react-slider" dependency-version: 1.4.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@radix-ui/react-switch" 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-tabs" dependency-version: 1.1.18 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.13 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@tailwindcss/vite" dependency-version: 4.3.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@uiw/codemirror-extensions-langs" dependency-version: 4.25.11 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@uiw/codemirror-theme-github" dependency-version: 4.25.11 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@uiw/react-codemirror" dependency-version: 4.25.11 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@vitest/coverage-v8" dependency-version: 4.1.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: "@vitest/ui" dependency-version: 4.1.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: i18next dependency-version: 26.3.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: radix-ui dependency-version: 1.6.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: react-i18next dependency-version: 17.0.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: tailwindcss dependency-version: 4.3.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: vitest dependency-version: 4.1.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ws in the prod-patch-updates group (#1071) Bumps the prod-patch-updates group with 1 update: [ws](https://github.com/websockets/ws). Updates `ws` from 8.21.0 to 8.21.1 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/8.21.0...8.21.1) --- updated-dependencies: - dependency-name: ws dependency-version: 8.21.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the major-updates group with 2 updates (#1072) Bumps the major-updates group with 2 updates: [nanoid](https://github.com/ai/nanoid) and [typescript](https://github.com/microsoft/TypeScript). Updates `nanoid` from 5.1.16 to 6.0.0 - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/5.1.16...6.0.0) Updates `typescript` from 6.0.3 to 7.0.2 - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Commits](https://github.com/microsoft/TypeScript/commits) --- updated-dependencies: - dependency-name: nanoid dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: major-updates - dependency-name: typescript dependency-version: 7.0.2 dependency-type: direct:development update-type: version-update:semver-major dependency-group: major-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: general qol additions and new analytics/telemetrics feature * fix: incorrect version sent to posthog * feat: add multiplayer/shared sessions for terminal and guacd * feat: rework Electron desktop app to run standalone-first with optional two-way sync to a remote Termix server * Fix Guacamole tab visibility lifecycle (#1074) Co-authored-by: default-student <default-student@github.com> Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com> * fix(alerts): send channel config as object payload instead of JSON string (#1075) * fix tmux-monitor tailscale issue (#1076) * Initial plan * fix(tmux-monitor): explicitly handle tailscale auth in PanePreview hostConfig For Tailscale-auth hosts the pane-preview attach path was building the Terminal hostConfig with only the generic spread of host fields. This could omit or mismap auth-critical details and trigger a plain TCP/SSH reachability path that doesn't work with Tailscale-only SSH endpoints. The fix branches on `host.authType === "tailscale"` and: - Carries `authType: "tailscale"` explicitly so the backend always selects the Tailscale-aware PTY path regardless of how the host object evolves. - Derives `port` from `host.sshPort ?? host.port` so Tailscale SSH endpoints on a non-default SSH port are reached correctly. - Leaves all non-tailscale auth types on the unchanged code path. Reattach (bumping instanceId + attachNonce) continues to work because terminalHostConfig is recomputed on every render with the latest instanceIdRef.current value. * refactor(tmux-monitor): simplify tailscale port logic with extracted variable Address code review feedback: extract resolvedPort into a local variable to avoid the duplicated `host.sshPort ?? host.port` expression that was assigned to both `port` and `sshPort`. Restructure as an if/else block instead of an IIFE for readability. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: run prettier * chore: update beta release text * fix: cant update credential of an RDP host * feat: add custom key shortcuts * feat: add support for MFA over SSH * fix: Invalid websocket frame causing code 10006 crash triggering restart loop * fix(net): correct SSRF blocklist false-positive blocking all outbound IPv4 (#1079) * fix: correct IPv4-mapped-IPv6 blocklist entry blocking all outbound IPv4 ::ffff:0:0/96 in the IPv6 blocklist matches every IPv4 address once mapped, since Node's BlockList compares addresses in their mapped form internally regardless of the declared family. This caused safeOutboundFetch to reject all IPv4-resolved destinations as private, breaking outbound requests (e.g. ntfy/webhook notifications) whenever DNS resolved to IPv4. Replaced with individual mapped ranges mirroring the existing IPv4 blocklist. * test: cover isBlockedAddress and link the Node BlockList citation Exports isBlockedAddress so its family-crossing behavior around IPv4-mapped-IPv6 addresses can actually be asserted, instead of relying on manual container debugging to notice a regression. Also swaps the prior "Node's BlockList compares addresses in mapped form" comment for one citing the documented example in the Node docs (https://nodejs.org/api/net.html#class-netblocklist), since that behavior isn't otherwise obvious from the addSubnet/check call sites. Related: Termix-SSH/Support#1024 * refactor: derive IPv6 mirror from IPv4 list, split DNS error messages Two follow-ups from review: - The IPv6 blocklist previously hand-duplicated each IPv4 range as its IPv4-mapped-IPv6 equivalent. Nothing enforced the two stayed in sync, which is exactly how the original bug (a mismatched ::ffff:0:0/96 entry blocking all IPv4) was introduced in the first place. Now derived from a single blockedIpv4Ranges list in one loop. - The connect.lookup hook threw the same "Private destinations are not allowed" for both an empty DNS result and an actually-blocked address. An empty result is a resolution failure, not a privacy decision, and conflating the two is the same kind of opaque-error problem that made this bug slow to diagnose in production. Split into distinct messages. Also extracted the lookup hook itself (createDnsLookupHook) so it can be unit-tested against a fake resolver directly, instead of only through a real fetch()/Agent call — the bug lived entirely in this callback, and undici wraps any error thrown here as a generic "fetch failed" TypeError, which is why isolating it matters for testability. --------- Co-authored-by: brennanneoh <497569+brennanneoh@users.noreply.github.com> * fix(ssh): do not offer chacha20-poly1305 without the native ssh2 binding (#1081) The availability probe treated a working OpenSSL "chacha20" cipher as proof that chacha20-poly1305@openssh.com is usable. It is not: ssh2 pure-JS chacha20-poly1305 corrupts the transport, so the peer aborts the KEX ("incomplete message [preauth]") and the connection times out. Easy to hit on jump-host connections whose target sshd negotiates chacha20-poly1305 first. Only trust the native binding (sshcrypto.node); otherwise leave the cipher disabled so filterCiphers() drops it and AES-GCM is negotiated instead. Co-authored-by: XtraLarge <> * fix: add Swiss German server layout (#1078) * chore: update release notes * feat: continue improving desktop app 2-way sync with logic fixes and a migration dialog * fix: dekstop app showing auth form without syncing * feat: create desktop auto sessions for existing setups * feat: add electron backend killing * fix: electron login and session related bugs and updated readme for v2.6.0 * chore: finalize release notes * fix: click to expand hosts including extra bottom margin * fix: desktop auth modal failing to log users in * fix: desktop app failing to sync * fix: reverse proxy causing sync error * chore: lint, format, and bump version to 2.6.0 * chore: sync Crowdin translations for 2.6.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: L.H. <117188168+default-student@users.noreply.github.com> Co-authored-by: default-student <default-student@github.com> Co-authored-by: Brad Baker <xyzulu@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Brennan Neoh <brennanneoh@users.noreply.github.com> Co-authored-by: brennanneoh <497569+brennanneoh@users.noreply.github.com> Co-authored-by: XtraLarge <eMail@WilliWerres.de> Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
This commit is contained in:
co-authored by
XtraLarge
dependabot[bot]
L.H.
default-student
Brad Baker
copilot-swe-agent[bot]
Copilot Autofix powered by AI
Brennan Neoh
brennanneoh
XtraLarge
ZacharyZcR
parent
cf3e2cb499
commit
1a26628a48
+216
-3
@@ -389,6 +389,45 @@
|
||||
"noSavedServers": "No saved servers",
|
||||
"removeServer": "Remove"
|
||||
},
|
||||
"migrationNotice": {
|
||||
"title": "Termix Desktop now runs standalone",
|
||||
"body1": "This app used to connect straight to your Termix server. It's been reworked to run fully on its own, storing hosts and credentials locally so it keeps working offline. Two-way sync with a self-hosted Termix server is now optional.",
|
||||
"body2": "Your existing hosts and credentials are still on {{url}}. Turn on Remote Sync and reconnect to that server to bring them back and keep both in sync going forward.",
|
||||
"dismiss": "Not now",
|
||||
"setUpSync": "Set Up Remote Sync"
|
||||
},
|
||||
"remoteSync": {
|
||||
"title": "Remote Sync",
|
||||
"description": "Optionally connect this desktop app to a self-hosted Termix server to sync your hosts, credentials, and snippets across devices. The app always works fully offline whether or not you connect.",
|
||||
"notConnected": "Not connected",
|
||||
"connected": "Connected",
|
||||
"connectedTo": "Connected to {{url}}",
|
||||
"lastSynced": "Last synced {{time}}",
|
||||
"neverSynced": "Never synced",
|
||||
"syncError": "Sync error: {{message}}",
|
||||
"needsReauth": "Sign-in expired",
|
||||
"connectButton": "Connect to Server",
|
||||
"disconnectButton": "Disconnect",
|
||||
"syncNowButton": "Sync Now",
|
||||
"syncing": "Syncing...",
|
||||
"serverUrl": "Server URL",
|
||||
"enterServerUrl": "Please enter a server URL",
|
||||
"mustIncludeProtocol": "Server URL must start with http:// or https://",
|
||||
"connectionTestFailed": "Could not reach a Termix server at that URL",
|
||||
"allowInvalidCertificate": "Allow invalid certificate",
|
||||
"allowInvalidCertificateDesc": "Use only for trusted self-hosted servers with self-signed or IP-address certificates.",
|
||||
"savedServers": "Saved Servers",
|
||||
"removeServer": "Remove",
|
||||
"continueButton": "Continue",
|
||||
"cancelButton": "Cancel",
|
||||
"signInTitle": "Sign in to {{url}}",
|
||||
"originTitle": "Connection Origin",
|
||||
"originDescription": "Choose where SSH connections originate from by default. This can be overridden per host.",
|
||||
"originLocal": "This device (local network)",
|
||||
"originRemote": "Remote server",
|
||||
"bannerReconnect": "Reconnect",
|
||||
"bannerMessage": "Remote sync needs re-authentication"
|
||||
},
|
||||
"versionCheck": {
|
||||
"error": "Version Check Error",
|
||||
"checkFailed": "Failed to check for updates",
|
||||
@@ -602,6 +641,7 @@
|
||||
"overrideCredentialUsername": "Override Credential Username",
|
||||
"overrideCredentialUsernameDesc": "Use the username specified above instead of the credential's username",
|
||||
"oidcUsernameHint": "Use $oidc.preferred_username to substitute your OIDC login name.",
|
||||
"tailscaleUsernameHint": "This must be a Unix user your Tailscale identity is granted in the tailnet's SSH ACL, not necessarily root.",
|
||||
"jumpHostChain": "Jump Host Chain",
|
||||
"portKnocking": "Port Knocking",
|
||||
"addKnock": "Add Port",
|
||||
@@ -650,6 +690,11 @@
|
||||
"delayAfterMs": "Delay After (ms)",
|
||||
"useSocks5Proxy": "Use SOCKS5 Proxy",
|
||||
"useSocks5ProxyDesc": "Route connection through a proxy server",
|
||||
"connectionOrigin": "Connection Origin",
|
||||
"connectionOriginDesc": "Where this host's SSH connection originates from. Overrides the desktop app's global default.",
|
||||
"connectionOriginDefault": "Use default",
|
||||
"connectionOriginLocal": "This device (local network)",
|
||||
"connectionOriginRemote": "Remote server",
|
||||
"proxyHost": "Proxy Host",
|
||||
"proxyPort": "Proxy Port",
|
||||
"proxyUsername": "Proxy Username",
|
||||
@@ -762,6 +807,14 @@
|
||||
"customThemeBrightCyan": "Bright Cyan",
|
||||
"customThemeBrightWhite": "Bright White",
|
||||
"customThemeResetTooltip": "Reset to defaults",
|
||||
"savedThemesLabel": "Saved Themes",
|
||||
"saveAsGlobalTheme": "Save as Global Theme",
|
||||
"saveGlobalThemeNamePrompt": "Enter a name for this theme",
|
||||
"saveGlobalThemeSuccess": "Theme saved",
|
||||
"saveGlobalThemeError": "Failed to save theme",
|
||||
"applyGlobalThemeTooltip": "Apply this theme",
|
||||
"deleteGlobalThemeTooltip": "Delete this theme",
|
||||
"noSavedThemes": "No saved themes yet",
|
||||
"syntaxHighlightingLabel": "Syntax Highlighting",
|
||||
"syntaxHighlightingDesc": "Colorize terminal output (errors, paths, IPs, timestamps)",
|
||||
"syntaxHighlightingCategories": "Highlight Categories",
|
||||
@@ -791,6 +844,8 @@
|
||||
"enableAutoTmuxDesc": "Automatically launch or attach to tmux session",
|
||||
"enableSessionLogging": "Session Logging",
|
||||
"enableSessionLoggingDesc": "Record terminal session output for later review",
|
||||
"allowSessionSharing": "Allow Session Sharing",
|
||||
"allowSessionSharingDesc": "Let live sessions on this host be shared via link or with other users",
|
||||
"enableCommandHistory": "Command History",
|
||||
"enableCommandHistoryDesc": "Record commands run in this terminal for history and autocomplete",
|
||||
"linkClickBehaviorLabel": "Link Click Behavior",
|
||||
@@ -895,6 +950,7 @@
|
||||
"proxmoxResultImported": "{{count}} imported",
|
||||
"proxmoxResultUpdated": "{{count}} updated",
|
||||
"proxmoxResultFailed": "{{count}} failed",
|
||||
"proxmoxResultSkippedNoIp": "{{count}} skipped (no IP found)",
|
||||
"proxmoxImportComplete": "Proxmox import complete: {{summary}}",
|
||||
"proxmoxDiscoveryFailed": "Discovery failed",
|
||||
"proxmoxImportFailed": "Import failed",
|
||||
@@ -961,6 +1017,9 @@
|
||||
"failedToSaveCredential": "Failed to save credential",
|
||||
"credentialNameRequired": "Please enter a name for the credential",
|
||||
"credentialAuthRequired": "Add a password, an SSH key, or both",
|
||||
"createCredentialFromHostBtn": "Create Credential",
|
||||
"createCredentialFromHostTitle": "Create Credential From Host",
|
||||
"createCredentialFromHostDesc": "Create a reusable, shareable credential entry prefilled with this host's current username, password, and/or SSH key.",
|
||||
"backToHosts": "Back to Hosts",
|
||||
"backToCredentials": "Back to Credentials",
|
||||
"pinned": "Pinned",
|
||||
@@ -1000,6 +1059,9 @@
|
||||
"folderNestingHint": "Use / to separate levels and create nested folders.",
|
||||
"folderColor": "Color",
|
||||
"folderIcon": "Icon",
|
||||
"folderCredential": "Credential",
|
||||
"folderCredentialNone": "No credential assigned",
|
||||
"folderCredentialHint": "Hosts in this folder that use \"Stored credential\" auth without their own credential selected will inherit this one.",
|
||||
"folderPreview": "Preview",
|
||||
"folderNameFallback": "Untitled folder",
|
||||
"createFolderButton": "Create folder",
|
||||
@@ -1181,6 +1243,10 @@
|
||||
"filterTagsGroup": "Tags",
|
||||
"shareHost": "Share Host",
|
||||
"shareHostTitle": "Share: {{name}}",
|
||||
"shareFolder": "Share Folder",
|
||||
"shareFolderTitle": "Share folder: {{name}}",
|
||||
"folderSharedSuccessfully": "Shared {{count}} host(s) in folder",
|
||||
"failedToShareFolder": "Failed to share folder",
|
||||
"sharing": {
|
||||
"loadError": "Failed to load sharing data. Please try again.",
|
||||
"shareWithSection": "Share with",
|
||||
@@ -1221,6 +1287,7 @@
|
||||
"shareWithCount": "Share ({{count}})",
|
||||
"currentAccess": "Current access",
|
||||
"noAccessEntries": "This host has not been shared yet",
|
||||
"folderShareSummary": "Shared {{shared}} of {{total}} host(s) in this folder",
|
||||
"grantedBy": "Granted by",
|
||||
"expires": "Expires",
|
||||
"expired": "Expired",
|
||||
@@ -1242,6 +1309,8 @@
|
||||
"authMethod": "Auth Method",
|
||||
"authTypeDirect": "Direct",
|
||||
"authTypeCredential": "Credential",
|
||||
"authTypeNone": "None",
|
||||
"authTypeNoneDesc": "No credentials are stored. You'll be prompted for a username and password each time you connect; they are not saved.",
|
||||
"selectCredential": "Select a credential...",
|
||||
"connectionSettings": "Connection Settings",
|
||||
"displaySettings": "Display Settings",
|
||||
@@ -1259,6 +1328,7 @@
|
||||
"rdpPort": "RDP Port",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"passwordSaved": "Password saved, type to change",
|
||||
"domain": "Domain",
|
||||
"securityMode": "Security Mode",
|
||||
"colorDepth": "Color Depth",
|
||||
@@ -1424,7 +1494,60 @@
|
||||
"expiresIn": "Expires in {{duration}}",
|
||||
"search": "Search connections...",
|
||||
"noSearchResults": "No connections match your search",
|
||||
"rename": "Rename session"
|
||||
"rename": "Rename session",
|
||||
"sectionSharedWithMe": "Shared with me",
|
||||
"sharedBy": "Shared by {{username}}",
|
||||
"join": "Join",
|
||||
"sharedSessionLabel": "{{hostName}} (shared)"
|
||||
},
|
||||
"sessionSharing": {
|
||||
"guestView": {
|
||||
"loading": "Connecting to shared session...",
|
||||
"linkInvalid": "This share link is invalid, expired, or has been revoked",
|
||||
"rateLimited": "Too many attempts, please try again shortly",
|
||||
"sessionEnded": "This session has ended",
|
||||
"readOnlyBadge": "View only"
|
||||
},
|
||||
"modalTitle": "Share session",
|
||||
"shareButton": "Share",
|
||||
"notReadyToShare": "Session is not ready to share yet",
|
||||
"modeTab": {
|
||||
"link": "Link",
|
||||
"user": "User"
|
||||
},
|
||||
"linkModeDescription": "Anyone with this link can join, no account required.",
|
||||
"userModeDescription": "Share with a specific user who already has access to this host. If they do not have access yet, share the host with them first or use a link instead. Once shared, the session appears in their Connections tab.",
|
||||
"permissionLevel": {
|
||||
"label": "Permission level",
|
||||
"readOnly": "Read-only",
|
||||
"readOnlyDescription": "Can watch the session live but cannot type or interact.",
|
||||
"readWrite": "Read-write",
|
||||
"readWriteDescription": "Can type and interact with the session just like the owner."
|
||||
},
|
||||
"expiryLabel": "Link expiry",
|
||||
"createLinkButton": "Create link",
|
||||
"createShareButton": "Share with user",
|
||||
"searchUsersPlaceholder": "Search users...",
|
||||
"noUsersFound": "No users found",
|
||||
"linkCreated": "Share link created",
|
||||
"linkCopied": "Link copied to clipboard",
|
||||
"copyLink": "Copy link",
|
||||
"shareCreated": "Session shared. It will appear in their Connections tab.",
|
||||
"shareFailed": "Failed to create share",
|
||||
"userLacksHostAccess": "That user does not have access to this host yet. Share the host with them first, or use a link instead.",
|
||||
"activeShares": "Active shares",
|
||||
"noActiveShares": "No active shares for this session",
|
||||
"revoke": "Revoke",
|
||||
"revokeConfirmTitle": "Revoke this share?",
|
||||
"revokeConfirmDescription": "Anyone using this share will lose access immediately.",
|
||||
"revoked": "Share revoked",
|
||||
"revokeFailed": "Failed to revoke share",
|
||||
"joinCount": "{{count}} join",
|
||||
"joinCount_other": "{{count}} joins",
|
||||
"expiresAt": "Expires {{date}}",
|
||||
"linkShareBadge": "Link",
|
||||
"userShareBadge": "User: {{username}}",
|
||||
"loadSharesFailed": "Failed to load active shares"
|
||||
},
|
||||
"guacamole": {
|
||||
"connecting": "Connecting to {{type}} session...",
|
||||
@@ -1436,6 +1559,9 @@
|
||||
"reconnect": "Reconnect",
|
||||
"retry": "Retry",
|
||||
"guacdUnavailable": "Remote desktop service (guacd) is not available. Please ensure guacd is running and accessible and configured properly in admin settings.",
|
||||
"credentialPromptTitle": "Enter RDP Credentials",
|
||||
"credentialPromptDescription": "This host is set to prompt for credentials on connect. They are used for this session only and are not saved.",
|
||||
"connect": "Connect",
|
||||
"ctrlAltDel": "Ctrl+Alt+Del",
|
||||
"toolbar": {
|
||||
"ctrlAltDel": "Ctrl+Alt+Del",
|
||||
@@ -1461,7 +1587,9 @@
|
||||
"reconnect": "Reconnect Session",
|
||||
"collapse": "Collapse toolbar",
|
||||
"expand": "Expand toolbar",
|
||||
"dragHandle": "Drag to reposition"
|
||||
"dragHandle": "Drag to reposition",
|
||||
"switchToTrackpad": "Switch to trackpad mode (drag to move cursor, tap to click)",
|
||||
"switchToTouch": "Switch to touch mode (tap directly where you want to click)"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -1508,6 +1636,11 @@
|
||||
"totpRequired": "Two-Factor Authentication Required",
|
||||
"totpCodeLabel": "Verification Code",
|
||||
"totpVerify": "Verify",
|
||||
"mfaPromptRequired": "Authentication Required",
|
||||
"mfaPushRequired": "Push Authentication Required",
|
||||
"mfaMenuPlaceholder": "Enter your response",
|
||||
"mfaWaitingApproval": "Waiting for approval on your device...",
|
||||
"mfaSendRequest": "Send Request",
|
||||
"warpgateAuthRequired": "Warpgate Authentication Required",
|
||||
"warpgateSecurityKey": "Security Key",
|
||||
"warpgateAuthUrl": "Authentication URL",
|
||||
@@ -2277,7 +2410,8 @@
|
||||
"resetCodeRateLimited": "Rate limited: Too many verification attempts. Please try again later.",
|
||||
"resetCodeRateLimitedWithTime": "Rate limited: Too many verification attempts. Please wait {{time}} seconds before trying again.",
|
||||
"authTokenSaveFailed": "Failed to save authentication token",
|
||||
"failedToLoadServer": "Failed to load server"
|
||||
"failedToLoadServer": "Failed to load server",
|
||||
"remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type."
|
||||
},
|
||||
"messages": {
|
||||
"registrationDisabled": "New account registration is currently disabled by an admin. Please log in or contact an administrator.",
|
||||
@@ -2644,6 +2778,17 @@
|
||||
"sslSaveFailed": "Failed to save SSL settings",
|
||||
"sslRequiresDomain": "Domain and email are required",
|
||||
"sslInfoNote": "After issuing a certificate, enable SSL in your environment variables (ENABLE_SSL=true) and restart Termix.",
|
||||
"sslManualOption": "Manual (upload certificate)",
|
||||
"sslManualCert": "Certificate (PEM)",
|
||||
"sslManualCertPlaceholder": "-----BEGIN CERTIFICATE-----",
|
||||
"sslManualKey": "Private Key (PEM)",
|
||||
"sslManualKeyPlaceholder": "-----BEGIN PRIVATE KEY-----",
|
||||
"sslManualDesc": "Paste your existing certificate and private key, including a full chain if required by your CA.",
|
||||
"sslManualUpload": "Upload & Install Certificate",
|
||||
"sslManualUploadLoading": "Uploading certificate...",
|
||||
"sslManualUploadSuccess": "Certificate uploaded and installed successfully",
|
||||
"sslManualUploadFailed": "Certificate upload failed",
|
||||
"sslManualRequiresFields": "Certificate and private key are required",
|
||||
"auditLogTotal": "{{total}} total entries",
|
||||
"auditLogEmpty": "No audit log entries found",
|
||||
"auditLogSuccess": "Success",
|
||||
@@ -2672,6 +2817,12 @@
|
||||
"commandHistoryEnabled": "Command History",
|
||||
"commandHistoryEnabledDesc": "Allow command history recording. When disabled, history is not saved regardless of per-host settings.",
|
||||
"updateCommandHistoryFailed": "Failed to update command history setting",
|
||||
"analyticsEnabled": "Share Anonymous Usage Statistics",
|
||||
"analyticsEnabledDesc": "Sends an anonymous daily count of users, hosts, and feature usage to help improve Termix. No personal data or connection details are ever included.",
|
||||
"updateAnalyticsFailed": "Failed to update analytics setting",
|
||||
"sessionSharingGloballyEnabled": "Allow Session Sharing",
|
||||
"sessionSharingGloballyEnabledDesc": "Allow live terminal, RDP, VNC, and Telnet sessions to be shared instance-wide. Overrides every per-host sharing toggle when disabled.",
|
||||
"updateSessionSharingFailed": "Failed to update session sharing setting",
|
||||
"sessionTimeout": "Session Timeout",
|
||||
"hours": "hours",
|
||||
"sessionTimeoutRange": "Min 1h · Max 720h",
|
||||
@@ -3119,6 +3270,47 @@
|
||||
"executionSuccess": "Success",
|
||||
"executionFailed": "Failed"
|
||||
},
|
||||
"keybindings": {
|
||||
"title": "Keyboard Shortcuts",
|
||||
"description": "Customize terminal copy, paste, and control shortcuts, or bind keys to send text or run a snippet.",
|
||||
"defaultsHeading": "Built-in Shortcuts",
|
||||
"customHeading": "Custom Shortcuts",
|
||||
"addBinding": "Add Shortcut",
|
||||
"addBindingTitle": "Add Shortcut",
|
||||
"editBindingTitle": "Edit Shortcut",
|
||||
"loading": "Loading...",
|
||||
"noCustomBindings": "No custom shortcuts yet",
|
||||
"defaultBadge": "Default",
|
||||
"customizedBadge": "Customized",
|
||||
"customize": "Customize",
|
||||
"resetToDefault": "Reset to default",
|
||||
"resetAllToDefaults": "Reset all to defaults",
|
||||
"close": "Close",
|
||||
"cancel": "Cancel",
|
||||
"saveBinding": "Save Shortcut",
|
||||
"saveError": "Failed to save keyboard shortcuts",
|
||||
"pressKeysToRecord": "Key combination",
|
||||
"pressKeysPlaceholder": "Click and press keys",
|
||||
"recording": "Press keys...",
|
||||
"comboRequiredError": "Press a key combination first",
|
||||
"textRequiredError": "Enter the text to send",
|
||||
"controlCodeRequiredError": "Enter a single letter for the control code",
|
||||
"snippetRequiredError": "Select a snippet",
|
||||
"conflictWarning": "This combination is already bound to {{combo}}. Saving will make both fire.",
|
||||
"actionLabel": "Action",
|
||||
"actionCopy": "Copy selection",
|
||||
"actionPaste": "Paste",
|
||||
"actionSendControlCode": "Send Ctrl+letter signal",
|
||||
"actionSendText": "Send text",
|
||||
"actionRunSnippet": "Run existing snippet",
|
||||
"controlCodeLabel": "Letter",
|
||||
"textLabel": "Text to send",
|
||||
"appendEnterLabel": "Press Enter after sending",
|
||||
"snippetLabel": "Snippet",
|
||||
"selectSnippetPlaceholder": "Select a snippet",
|
||||
"orphanedSnippetWarning": "snippet not found",
|
||||
"clipboardPermissionNote": "May prompt for clipboard permission on first use in some browsers."
|
||||
},
|
||||
"userProfile": {
|
||||
"donateTitle": "Keep Termix alive",
|
||||
"donateDescription": "Termix is free, self-hosted, and built by only a few people in their spare time. If it's saved you time or money, a crypto donation helps keep it going.",
|
||||
@@ -3134,6 +3326,7 @@
|
||||
"sectionAppearance": "Appearance",
|
||||
"sectionSecurity": "Security",
|
||||
"sectionApiKeys": "API Keys",
|
||||
"sectionData": "Data",
|
||||
"sectionC2sTunnels": "C2S Tunnels",
|
||||
"usernameLabel": "Username",
|
||||
"roleLabel": "Role",
|
||||
@@ -3162,6 +3355,9 @@
|
||||
"settingsTerminal": "Terminal",
|
||||
"commandAutocomplete": "Command Autocomplete",
|
||||
"commandAutocompleteDesc": "Show autocomplete while typing",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"keyboardShortcutsDescription": "Customize terminal copy, paste, and command shortcuts",
|
||||
"manageShortcuts": "Manage",
|
||||
"terminalLinkBehavior": "Terminal Link Click",
|
||||
"terminalLinkBehaviorDesc": "Default behavior when clicking links in the terminal",
|
||||
"historyTracking": "History Tracking",
|
||||
@@ -3228,6 +3424,22 @@
|
||||
"apiKeyUsageHint": "Include your key in the",
|
||||
"apiKeyUsageHintHeader": "header.",
|
||||
"apiKeyPermissionsHint": "Keys inherit the permissions of the creating user.",
|
||||
"exportData": "Export My Data",
|
||||
"exportDataDesc": "Download a backup of your hosts, credentials, and settings to transfer to another device",
|
||||
"export": "Export",
|
||||
"exporting": "Exporting...",
|
||||
"importData": "Import My Data",
|
||||
"importDataDesc": "Restore your hosts, credentials, and settings from a .sqlite backup file",
|
||||
"importDataSelected": "Selected: {{name}}",
|
||||
"selectFile": "Select File",
|
||||
"changeFile": "Change",
|
||||
"import": "Import",
|
||||
"importing": "Importing...",
|
||||
"exportSuccess": "Data exported successfully",
|
||||
"exportFailed": "Data export failed",
|
||||
"importSelectFile": "Please select a file first",
|
||||
"importCompleted": "Import completed: {{total}} items imported, {{skipped}} skipped",
|
||||
"importFailed": "Import failed: {{error}}",
|
||||
"roleUser": "User",
|
||||
"authMethodDual": "Dual Auth",
|
||||
"authMethodOidc": "OIDC",
|
||||
@@ -3379,6 +3591,7 @@
|
||||
"pageUp": "PgUp",
|
||||
"pageDown": "PgDn",
|
||||
"delete": "Del",
|
||||
"paste": "Paste",
|
||||
"editQuickKeys": "Edit quick keys",
|
||||
"quickKeysTitle": "Quick Keys",
|
||||
"quickKeysDesc": "Tap × to remove. Supports up to 8 characters.",
|
||||
|
||||
Reference in New Issue
Block a user