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:
Luke Gustafson
2026-07-26 18:47:27 -05:00
committed by GitHub
co-authored by XtraLarge <> dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> L.H. default-student Brad Baker copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Copilot Autofix powered by AI Brennan Neoh brennanneoh XtraLarge ZacharyZcR
parent cf3e2cb499
commit 1a26628a48
232 changed files with 50585 additions and 32016 deletions
+216 -3
View File
@@ -389,6 +389,45 @@
"noSavedServers": "Ingen gemte servere",
"removeServer": "Fjerne"
},
"migrationNotice": {
"title": "Termix Desktop kører nu selvstændigt",
"body1": "Denne app plejede at oprette forbindelse direkte til din Termix-server. Den er blevet omarbejdet til at køre fuldt ud alene og gemmer værter og legitimationsoplysninger lokalt, så den fortsætter med at fungere offline. Tovejssynkronisering med en selvhostet Termix-server er nu valgfri.",
"body2": "Dine eksisterende værter og loginoplysninger er stadig på {{url}}. Aktivér fjernsynkronisering, og opret forbindelse til serveren igen for at få dem tilbage og holde begge synkroniseret fremadrettet.",
"dismiss": "Ikke nu",
"setUpSync": "Opsæt fjernsynkronisering"
},
"remoteSync": {
"title": "Fjernsynkronisering",
"description": "Du kan eventuelt tilslutte denne desktop-app til en selvhostet Termix-server for at synkronisere dine værter, legitimationsoplysninger og kodestykker på tværs af enheder. Appen fungerer altid fuldt offline, uanset om du opretter forbindelse eller ej.",
"notConnected": "Ikke forbundet",
"connected": "Forbundet",
"connectedTo": "Forbundet til {{url}}",
"lastSynced": "Sidst synkroniseret {{time}}",
"neverSynced": "Aldrig synkroniseret",
"syncError": "Synkroniseringsfejl: {{message}}",
"needsReauth": "Login udløbet",
"connectButton": "Opret forbindelse til serveren",
"disconnectButton": "Afbryde",
"syncNowButton": "Synkroniser nu",
"syncing": "Synkroniserer...",
"serverUrl": "Server-URL",
"enterServerUrl": "Indtast venligst en server-URL",
"mustIncludeProtocol": "Server-URL skal starte med http:// eller https://",
"connectionTestFailed": "Kunne ikke nå en Termix-server på den URL",
"allowInvalidCertificate": "Tillad ugyldigt certifikat",
"allowInvalidCertificateDesc": "Brug kun til betroede, selvhostede servere med selvsignerede certifikater eller IP-adressecertifikater.",
"savedServers": "Gemte servere",
"removeServer": "Fjerne",
"continueButton": "Fortsætte",
"cancelButton": "Ophæve",
"signInTitle": "Log ind på {{url}}",
"originTitle": "Forbindelsens oprindelse",
"originDescription": "Vælg som standard, hvor SSH-forbindelser stammer fra. Dette kan tilsidesættes pr. vært.",
"originLocal": "Denne enhed (lokalt netværk)",
"originRemote": "Fjernserver",
"bannerReconnect": "Genopret forbindelse",
"bannerMessage": "Fjernsynkronisering skal godkendes igen"
},
"versionCheck": {
"error": "Versionskontrolfejl",
"checkFailed": "Kunne ikke søge efter opdateringer",
@@ -602,6 +641,7 @@
"overrideCredentialUsername": "Tilsidesæt brugernavn til legitimationsoplysninger",
"overrideCredentialUsernameDesc": "Brug det ovenfor angivne brugernavn i stedet for legitimationsoplysningernes brugernavn",
"oidcUsernameHint": "Brug $oidc.preferred_username til at erstatte dit OIDC-loginnavn.",
"tailscaleUsernameHint": "Dette skal være en Unix-bruger, som din Tailscale-identitet er tildelt i tailnets SSH ACL, ikke nødvendigvis root.",
"jumpHostChain": "Jump Host Chain",
"portKnocking": "Port Knocking",
"addKnock": "Tilføj port",
@@ -650,6 +690,11 @@
"delayAfterMs": "Forsinkelse efter (ms)",
"useSocks5Proxy": "Brug SOCKS5 Proxy",
"useSocks5ProxyDesc": "Rut forbindelsen via en proxyserver",
"connectionOrigin": "Forbindelsens oprindelse",
"connectionOriginDesc": "Hvor denne værts SSH-forbindelse stammer fra. Tilsidesætter desktop-appens globale standard.",
"connectionOriginDefault": "Brug standard",
"connectionOriginLocal": "Denne enhed (lokalt netværk)",
"connectionOriginRemote": "Fjernserver",
"proxyHost": "Proxy-vært",
"proxyPort": "Proxyport",
"proxyUsername": "Proxy-brugernavn",
@@ -762,6 +807,14 @@
"customThemeBrightCyan": "Lys cyan",
"customThemeBrightWhite": "Klar hvid",
"customThemeResetTooltip": "Nulstil til standardindstillinger",
"savedThemesLabel": "Gemte temaer",
"saveAsGlobalTheme": "Gem som globalt tema",
"saveGlobalThemeNamePrompt": "Indtast et navn til dette tema",
"saveGlobalThemeSuccess": "Tema gemt",
"saveGlobalThemeError": "Temaet kunne ikke gemmes",
"applyGlobalThemeTooltip": "Anvend dette tema",
"deleteGlobalThemeTooltip": "Slet dette tema",
"noSavedThemes": "Ingen gemte temaer endnu",
"syntaxHighlightingLabel": "Syntaksfremhævning",
"syntaxHighlightingDesc": "Farvlæg terminaloutput (fejl, stier, IP'er, tidsstempler)",
"syntaxHighlightingCategories": "Fremhæv kategorier",
@@ -791,6 +844,8 @@
"enableAutoTmuxDesc": "Start eller tilslut automatisk til tmux-session",
"enableSessionLogging": "Sessionslogning",
"enableSessionLoggingDesc": "Optag output fra terminalsessionen til senere gennemgang",
"allowSessionSharing": "Tillad deling af sessioner",
"allowSessionSharingDesc": "Tillad live-sessioner på denne vært at blive delt via link eller med andre brugere",
"enableCommandHistory": "Kommandohistorik",
"enableCommandHistoryDesc": "Optagelseskommandoer køres i denne terminal for historik og autofuldførelse",
"linkClickBehaviorLabel": "Linkkliksadfærd",
@@ -895,6 +950,7 @@
"proxmoxResultImported": "{{count}} importeret",
"proxmoxResultUpdated": "{{count}} opdateret",
"proxmoxResultFailed": "{{count}} mislykkedes",
"proxmoxResultSkippedNoIp": "{{count}} sprunget over (ingen IP fundet)",
"proxmoxImportComplete": "Proxmox-import fuldført: {{summary}}",
"proxmoxDiscoveryFailed": "Opdagelsen mislykkedes",
"proxmoxImportFailed": "Importen mislykkedes",
@@ -961,6 +1017,9 @@
"failedToSaveCredential": "Kunne ikke gemme legitimationsoplysninger",
"credentialNameRequired": "Indtast venligst et navn til legitimationsoplysningerne",
"credentialAuthRequired": "Tilføj en adgangskode, en SSH-nøgle eller begge dele",
"createCredentialFromHostBtn": "Opret legitimationsoplysninger",
"createCredentialFromHostTitle": "Opret legitimationsoplysninger fra vært",
"createCredentialFromHostDesc": "Opret en genanvendelig, delbar legitimationsoplysningspost, der er forudfyldt med denne værts nuværende brugernavn, adgangskode og/eller SSH-nøgle.",
"backToHosts": "Tilbage til værter",
"backToCredentials": "Tilbage til legitimationsoplysninger",
"pinned": "Fastgjort",
@@ -1000,6 +1059,9 @@
"folderNestingHint": "Brug / til at adskille niveauer og oprette indbyggede mapper.",
"folderColor": "Farve",
"folderIcon": "Ikon",
"folderCredential": "Legitimationsoplysninger",
"folderCredentialNone": "Ingen legitimationsoplysninger tildelt",
"folderCredentialHint": "Værter i denne mappe, der bruger godkendelsen \"Gemte legitimationsoplysninger\" uden at have valgt deres egne legitimationsoplysninger, arver denne.",
"folderPreview": "Forhåndsvisning",
"folderNameFallback": "Unavngivet mappe",
"createFolderButton": "Opret mappe",
@@ -1181,6 +1243,10 @@
"filterTagsGroup": "Tags",
"shareHost": "Del vært",
"shareHostTitle": "Del: {{name}}",
"shareFolder": "Del mappe",
"shareFolderTitle": "Del mappe: {{name}}",
"folderSharedSuccessfully": "Delte {{count}} vært(er) i mappe",
"failedToShareFolder": "Mappen kunne ikke deles",
"sharing": {
"loadError": "Delingsdataene kunne ikke indlæses. Prøv igen.",
"shareWithSection": "Del med",
@@ -1221,6 +1287,7 @@
"shareWithCount": "Del ({{count}})",
"currentAccess": "Nuværende adgang",
"noAccessEntries": "Denne vært er ikke blevet delt endnu",
"folderShareSummary": "Delte {{shared}} af {{total}} vært(er) i denne mappe",
"grantedBy": "Tildelt af",
"expires": "Udløber",
"expired": "Udløbet",
@@ -1242,6 +1309,8 @@
"authMethod": "Godkendelsesmetode",
"authTypeDirect": "Direkte",
"authTypeCredential": "Legitimationsoplysninger",
"authTypeNone": "Ingen",
"authTypeNoneDesc": "Ingen loginoplysninger gemmes. Du vil blive bedt om et brugernavn og en adgangskode, hver gang du opretter forbindelse; de gemmes ikke.",
"selectCredential": "Vælg en legitimationsoplysninger...",
"connectionSettings": "Forbindelsesindstillinger",
"displaySettings": "Skærmindstillinger",
@@ -1259,6 +1328,7 @@
"rdpPort": "RDP-port",
"username": "Brugernavn",
"password": "Adgangskode",
"passwordSaved": "Adgangskode gemt, skriv for at ændre",
"domain": "Domæne",
"securityMode": "Sikkerhedstilstand",
"colorDepth": "Farvedybde",
@@ -1424,7 +1494,60 @@
"expiresIn": "Udløber om {{duration}}",
"search": "Søg efter forbindelser...",
"noSearchResults": "Ingen forbindelser matcher din søgning",
"rename": "Omdøb session"
"rename": "Omdøb session",
"sectionSharedWithMe": "Delt med mig",
"sharedBy": "Delt af {{username}}",
"join": "Deltag",
"sharedSessionLabel": "{{hostName}} (delt)"
},
"sessionSharing": {
"guestView": {
"loading": "Forbinder til delt session...",
"linkInvalid": "Dette delingslink er ugyldigt, udløbet eller er blevet tilbagekaldt",
"rateLimited": "For mange forsøg, prøv igen om lidt",
"sessionEnded": "Denne session er afsluttet",
"readOnlyBadge": "Kun visning"
},
"modalTitle": "Del session",
"shareButton": "Dele",
"notReadyToShare": "Sessionen er ikke klar til deling endnu",
"modeTab": {
"link": "Forbindelse",
"user": "Bruger"
},
"linkModeDescription": "Alle med dette link kan tilmelde sig, ingen konto kræves.",
"userModeDescription": "Del med en bestemt bruger, der allerede har adgang til denne vært. Hvis de ikke har adgang endnu, skal du først dele værten med dem eller bruge et link i stedet. Når sessionen er delt, vises den under deres fane Forbindelser.",
"permissionLevel": {
"label": "Tilladelsesniveau",
"readOnly": "Skrivebeskyttet",
"readOnlyDescription": "Kan se sessionen live, men kan ikke skrive eller interagere.",
"readWrite": "Læs-skriv",
"readWriteDescription": "Kan skrive og interagere med sessionen ligesom ejeren."
},
"expiryLabel": "Linkudløb",
"createLinkButton": "Opret link",
"createShareButton": "Del med brugeren",
"searchUsersPlaceholder": "Søg efter brugere...",
"noUsersFound": "Ingen brugere fundet",
"linkCreated": "Delingslink oprettet",
"linkCopied": "Link kopieret til udklipsholder",
"copyLink": "Kopiér link",
"shareCreated": "Session delt. Den vises i fanen Forbindelser.",
"shareFailed": "Kunne ikke oprette deling",
"userLacksHostAccess": "Den bruger har endnu ikke adgang til denne vært. Del værten med dem først, eller brug et link i stedet.",
"activeShares": "Aktive aktier",
"noActiveShares": "Ingen aktive delinger for denne session",
"revoke": "Tilbagekald",
"revokeConfirmTitle": "Tilbagekald denne deling?",
"revokeConfirmDescription": "Enhver, der bruger denne deling, mister adgangen med det samme.",
"revoked": "Deling tilbagekaldt",
"revokeFailed": "Delingen kunne ikke tilbagekaldes",
"joinCount": "{{count}} tilmeld dig",
"joinCount_other": "{{count}} deltager",
"expiresAt": "Udløber {{date}}",
"linkShareBadge": "Forbindelse",
"userShareBadge": "Bruger: {{username}}",
"loadSharesFailed": "Kunne ikke indlæse aktive delinger"
},
"guacamole": {
"connecting": "Forbinder til {{type}} session...",
@@ -1436,6 +1559,9 @@
"reconnect": "Genopret forbindelse",
"retry": "Prøv igen",
"guacdUnavailable": "Fjernskrivebordstjenesten (guacd) er ikke tilgængelig. Sørg for, at guacd kører, er tilgængelig og konfigureret korrekt i administratorindstillingerne.",
"credentialPromptTitle": "Indtast RDP-legitimationsoplysninger",
"credentialPromptDescription": "Denne vært er indstillet til at bede om legitimationsoplysninger ved forbindelse. De bruges kun til denne session og gemmes ikke.",
"connect": "Forbinde",
"ctrlAltDel": "Ctrl+Alt+Del",
"toolbar": {
"ctrlAltDel": "Ctrl+Alt+Del",
@@ -1461,7 +1587,9 @@
"reconnect": "Genopret forbindelse til sessionen",
"collapse": "Skjul værktøjslinjen",
"expand": "Udvid værktøjslinjen",
"dragHandle": "Træk for at flytte"
"dragHandle": "Træk for at flytte",
"switchToTrackpad": "Skift til trackpad-tilstand (træk for at flytte markøren, tryk for at klikke)",
"switchToTouch": "Skift til berøringstilstand (tryk direkte der, hvor du vil klikke)"
}
},
"terminal": {
@@ -1508,6 +1636,11 @@
"totpRequired": "Tofaktorgodkendelse påkrævet",
"totpCodeLabel": "Bekræftelseskode",
"totpVerify": "Verificere",
"mfaPromptRequired": "Godkendelse påkrævet",
"mfaPushRequired": "Push-godkendelse påkrævet",
"mfaMenuPlaceholder": "Indtast dit svar",
"mfaWaitingApproval": "Venter på godkendelse på din enhed...",
"mfaSendRequest": "Send anmodning",
"warpgateAuthRequired": "Warpgate-godkendelse påkrævet",
"warpgateSecurityKey": "Sikkerhedsnøgle",
"warpgateAuthUrl": "Godkendelses-URL",
@@ -2277,7 +2410,8 @@
"resetCodeRateLimited": "Begrænset hastighed: For mange bekræftelsesforsøg. Prøv igen senere.",
"resetCodeRateLimitedWithTime": "Begrænset hastighed: For mange bekræftelsesforsøg. Vent {{time}} sekunder, før du prøver igen.",
"authTokenSaveFailed": "Kunne ikke gemme godkendelsestoken",
"failedToLoadServer": "Kunne ikke indlæse serveren"
"failedToLoadServer": "Kunne ikke indlæse serveren",
"remoteServerRequired": "Fjernserver kræves. Opret forbindelse til en fjernserver i Indstillinger for at bruge denne forbindelsestype."
},
"messages": {
"registrationDisabled": "Registrering af nye kontoer er i øjeblikket deaktiveret af en administrator. Log venligst ind eller kontakt en administrator.",
@@ -2644,6 +2778,17 @@
"sslSaveFailed": "Kunne ikke gemme SSL-indstillinger",
"sslRequiresDomain": "Domæne og e-mail er påkrævet",
"sslInfoNote": "Efter udstedelse af et certifikat, skal du aktivere SSL i dine miljøvariabler (ENABLE_SSL=true) og genstarte Termix.",
"sslManualOption": "Manual (upload certifikat)",
"sslManualCert": "Certifikat (PEM)",
"sslManualCertPlaceholder": "-----STARTCERTIFIKAT-----",
"sslManualKey": "Privat nøgle (PEM)",
"sslManualKeyPlaceholder": "-----START PRIVAT NØGLE-----",
"sslManualDesc": "Indsæt dit eksisterende certifikat og din private nøgle, inklusive en fuld kæde, hvis det kræves af din CA.",
"sslManualUpload": "Upload og installer certifikat",
"sslManualUploadLoading": "Uploader certifikat...",
"sslManualUploadSuccess": "Certifikatet er uploadet og installeret",
"sslManualUploadFailed": "Upload af certifikat mislykkedes",
"sslManualRequiresFields": "Certifikat og privat nøgle er påkrævet",
"auditLogTotal": "{{total}} samlede poster",
"auditLogEmpty": "Ingen poster i revisionsloggen fundet",
"auditLogSuccess": "Succes",
@@ -2672,6 +2817,12 @@
"commandHistoryEnabled": "Kommandohistorik",
"commandHistoryEnabledDesc": "Tillad optagelse af kommandohistorik. Når den er deaktiveret, gemmes historikken ikke uanset indstillingerne for den enkelte vært.",
"updateCommandHistoryFailed": "Kunne ikke opdatere indstillingen for kommandohistorik",
"analyticsEnabled": "Del anonym brugsstatistik",
"analyticsEnabledDesc": "Sender en anonym daglig optælling af brugere, værter og funktionsbrug for at forbedre Termix. Ingen personlige data eller forbindelsesoplysninger inkluderes nogensinde.",
"updateAnalyticsFailed": "Analyseindstillingen kunne ikke opdateres",
"sessionSharingGloballyEnabled": "Tillad deling af sessioner",
"sessionSharingGloballyEnabledDesc": "Tillad deling af live terminal-, RDP-, VNC- og Telnet-sessioner på tværs af instanser. Tilsidesætter alle delingsindstillinger pr. vært, når de er deaktiveret.",
"updateSessionSharingFailed": "Indstillingen for deling af session kunne ikke opdateres",
"sessionTimeout": "Sessionstimeout",
"hours": "timer",
"sessionTimeoutRange": "Min. 1 time · Maks. 720 timer",
@@ -3119,6 +3270,47 @@
"executionSuccess": "Succes",
"executionFailed": "Mislykkedes"
},
"keybindings": {
"title": "Tastaturgenveje",
"description": "Tilpas genveje til kopiering, indsættelse og styring af terminaler, eller bind taster for at sende tekst eller køre et kodestykke.",
"defaultsHeading": "Indbyggede genveje",
"customHeading": "Brugerdefinerede genveje",
"addBinding": "Tilføj genvej",
"addBindingTitle": "Tilføj genvej",
"editBindingTitle": "Rediger genvej",
"loading": "Indlæser...",
"noCustomBindings": "Ingen brugerdefinerede genveje endnu",
"defaultBadge": "Misligholdelse",
"customizedBadge": "Tilpasset",
"customize": "Tilpas",
"resetToDefault": "Nulstil til standard",
"resetAllToDefaults": "Nulstil alle til standardindstillingerne",
"close": "Tæt",
"cancel": "Ophæve",
"saveBinding": "Gem genvej",
"saveError": "Kunne ikke gemme tastaturgenveje",
"pressKeysToRecord": "Tastekombination",
"pressKeysPlaceholder": "Klik og tryk på tasterne",
"recording": "Tryk på tasterne...",
"comboRequiredError": "Tryk først på en tastekombination",
"textRequiredError": "Indtast den tekst, der skal sendes",
"controlCodeRequiredError": "Indtast et enkelt bogstav for kontrolkoden",
"snippetRequiredError": "Vælg et uddrag",
"conflictWarning": "Denne kombination er allerede bundet til {{combo}}. Hvis du gemmer dem, aktiveres begge.",
"actionLabel": "Handling",
"actionCopy": "Kopiér valg",
"actionPaste": "Indsæt",
"actionSendControlCode": "Send Ctrl+bogstavsignal",
"actionSendText": "Send sms",
"actionRunSnippet": "Kør eksisterende kodestykke",
"controlCodeLabel": "Bogstav",
"textLabel": "Tekst der skal sendes",
"appendEnterLabel": "Tryk Enter efter afsendelse",
"snippetLabel": "Uddrag",
"selectSnippetPlaceholder": "Vælg et uddrag",
"orphanedSnippetWarning": "uddrag ikke fundet",
"clipboardPermissionNote": "Kan bede om tilladelse til udklipsholder ved første brug i nogle browsere."
},
"userProfile": {
"donateTitle": "Hold Termix i live",
"donateDescription": "Termix er gratis, selvhostet og bygget af kun få personer i deres fritid. Hvis det har sparet dig tid eller penge, kan en kryptodonation hjælpe med at holde det kørende.",
@@ -3134,6 +3326,7 @@
"sectionAppearance": "Udseende",
"sectionSecurity": "Sikkerhed",
"sectionApiKeys": "API-nøgler",
"sectionData": "Data",
"sectionC2sTunnels": "C2S-tunneler",
"usernameLabel": "Brugernavn",
"roleLabel": "Rolle",
@@ -3162,6 +3355,9 @@
"settingsTerminal": "Terminal",
"commandAutocomplete": "Kommando Autofuldførelse",
"commandAutocompleteDesc": "Vis autofuldførelse under indtastning",
"keyboardShortcuts": "Tastaturgenveje",
"keyboardShortcutsDescription": "Tilpas genveje til terminalkopiering, -indsætning og -kommandoer",
"manageShortcuts": "Styre",
"terminalLinkBehavior": "Klik på terminallink",
"terminalLinkBehaviorDesc": "Standardadfærd ved klik på links i terminalen",
"historyTracking": "Historiksporing",
@@ -3228,6 +3424,22 @@
"apiKeyUsageHint": "Medtag din nøgle i",
"apiKeyUsageHintHeader": "overskrift.",
"apiKeyPermissionsHint": "Nøgler arver tilladelserne fra den oprettende bruger.",
"exportData": "Eksporter mine data",
"exportDataDesc": "Download en sikkerhedskopi af dine værter, loginoplysninger og indstillinger for at overføre dem til en anden enhed.",
"export": "Eksportere",
"exporting": "Eksporterer...",
"importData": "Importer mine data",
"importDataDesc": "Gendan dine værter, legitimationsoplysninger og indstillinger fra en .sqlite-backupfil",
"importDataSelected": "Valgt: {{name}}",
"selectFile": "Vælg fil",
"changeFile": "Forandring",
"import": "Importere",
"importing": "Importerer...",
"exportSuccess": "Data eksporteret",
"exportFailed": "Dataeksport mislykkedes",
"importSelectFile": "Vælg venligst en fil først",
"importCompleted": "Import fuldført: {{total}} elementer importeret, {{skipped}} sprunget over",
"importFailed": "Import mislykkedes: {{error}}",
"roleUser": "Bruger",
"authMethodDual": "Dobbeltgodkendelse",
"authMethodOidc": "OIDC",
@@ -3379,6 +3591,7 @@
"pageUp": "Side op",
"pageDown": "PgDn",
"delete": "Del",
"paste": "Indsæt",
"editQuickKeys": "Rediger genvejstaster",
"quickKeysTitle": "Hurtigtaster",
"quickKeysDesc": "Tryk på × for at fjerne. Understøtter op til 8 tegn.",