- Introduced new localization strings for short download links and their hints in various languages.
- Added validation messages for short link requirements, including character restrictions and length constraints.
- Updated existing download link hints to inform users that old hex links will continue to function after changes to short links.
- Ensured consistency across all language files to enhance user experience and clarity in the interface.
Sync all 26 locale files to the EN+PL baseline (3432 keys), add OBSIDIAN tier strings, and ship i18n apply/audit tooling. Improve server attestation UX and convert orphaned node:test scripts to Jest so the full test suite passes.
- Introduced a new permission for server attestation, allowing users to run and view server performance attestations.
- Updated localization files in English and Polish to include descriptions for the new permission.
- Modified authentication middleware and various UI components to integrate the server attestation feature, ensuring proper access control and visibility in the sidebar.
- Enhanced the server attestation page to handle rendering and error management effectively.
- Swapped the descriptions for the 'platinum' and 'titanium' tiers in both English and Polish localization files to accurately reflect their connection capacities.
- Updated the tier descriptions to enhance clarity regarding server performance and infrastructure capabilities.
- Introduced server attestation functionality with performance benchmarking capabilities.
- Added new localization strings for server attestation in English and Polish.
- Updated authentication routes to include server attestation data on login.
- Enhanced desktop and standard login views to display attestation badge.
- Integrated server attestation link in the sidebar for easy access.
This feature provides users with insights into server performance and connection capacity.
- Improved logging in the device registration process to capture detailed enrollment information.
- Updated the enrollment token handling to ensure each device registers independently, eliminating the use of shared tokens.
- Introduced new API endpoints for managing help requests, allowing operators to acknowledge and resolve requests through the panel.
- Enhanced the generator routes to support the new help request functionality, improving overall API integration and user experience.
- Refactored the branding process to remove legacy enrollment token references, streamlining the support agent's configuration.
- Added new UI components and functionality for managing client builds, including a section for displaying build statuses and a button to rebuild all platform installers.
- Enhanced the generator routes to support rebuilding of bundles, including error handling for revoked bundles.
- Updated the agent build worker to facilitate the rebuilding process for platform builds associated with a specific bundle.
- Improved localization by adding relevant strings for build management in English and Polish language files.
- Introduced CSS styles for the new builds section to enhance visual presentation and user experience.
- Added audio stream handling to the agent, including support for audio start and stop messages.
- Introduced lifecycle callbacks for consent and session management in the agent configuration.
- Updated desktop handling to utilize new consent handler and session start/end callbacks.
- Improved UI to reflect enrollment status and consent requests, enhancing user experience.
- Refactored branding structure to include additional color properties for better theming.
Restore POST /api/peers/{id}/restore removed in a9e217c, add signal tests
that managed mode queues pending_device_* while locked does not, and move
RustDesk enrollment controls to Settings with full approval (folder, groups,
tag picker) wired through the registrations flow.
Expose global connection strategy in the web panel with systemd/Docker persistence, extend server health diagnostics, enforce org network policy in the signal handler, and document when relay fallback is expected vs misconfiguration.
Utils.api already unwraps API data, so the file list was always empty.
Add fixed paths for session secret, audit log, build.env, and Docker files.
Co-authored-by: Cursor <cursoragent@cursor.com>
Let server.config admins edit .env, blocklist, and systemd units from the
panel with backups on save and service restart via the existing updater.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add auth_provider attribute (local/ldap/oidc) to User model across SQLite and PostgreSQL with automatic migration (existing accounts default to local). Rewrite login to be provider-bound: LDAP-backed accounts never fall through to local password verification, OIDC accounts reject password login, and LDAP/OIDC provisioning stores an unusable random local password instead of the provider password. LDAP/OIDC accounts always re-apply provider role mapping on every login so a matching local account can no longer override AD-mapped permissions. Guard handleUpdateUser against setting a local password on non-local accounts. Propagate auth_provider through the Node.js sync layer and panel API, add a Provider column with badges in the users table, hide local password reset for provider-managed accounts, and add EN/PL i18n keys.
This commit was made possible thanks to Insolve.
Redesign the console backup into a complete .tar.gz disaster-recovery bundle that can be restored on a fresh machine to bring the entire server back online. Adds zero-dependency tar.gz writer/reader (backupArchive.js), logical dumpAllTables/importAllTables for SQLite and PostgreSQL, and packs the console database, auth.db, .env, .session_secret, branding uploads, and Go server identity (Ed25519 keys, .api_key, db_v2.sqlite3) plus a recovery README. Restore auto-detects archive vs legacy JSON snapshot, supports per-component selection (database/uploads/secrets/.env/Go DB) with restart-required signaling, and warns that the archive contains secrets. EN/PL/ZH i18n added.
This commit was made possible thanks to Insolve.
Add console wallpaper, login page branding (title/subtitle/background/footer), global agent download page branding, footer/copyright with 'Powered by BetterDesk' toggle, and custom CSS injection. Includes background image upload route (8MB), sanitization for colors/gradients/CSS, dynamic theme CSS for app and login pages, sidebar attribution, and EN/PL/ZH i18n keys.
This commit was made possible thanks to Insolve.
Implement RustDesk-desktop-style display switching and virtual display management in the web remote client.
- client.js: rewrite switchMonitor to send SwitchDisplay + CaptureDisplays messages with keyframe refresh; getMonitors marks primary (origin 0,0) and current display; add getCurrentDisplay, _processPeerInfo, _parseVirtualDisplaySupport, getVirtualDisplaySupport, toggleVirtualDisplay; switchDisplay receive handler tracks current display.
- remote.js: add i18n helper, peer_info/display_switched/virtual_display_toggled listeners, refreshMonitorButton; rewrite updateMonitorMenu with monitor list plus rustdesk_idd (4 checkboxes) and amyuni_idd (+/- counter) virtual display controls and plug-out-all.
- remote.css: styles for divider, active monitor/virtual items, counter controls.
- i18n: add virtual_displays, virtual_display, plug_out_all keys to en/pl/zh.
This commit was made possible thanks to Insolve.
Redesign the web remote toolbar into a RustDesk-style floating pill. The compact handle (move / fullscreen / expand) is always visible and the action pill no longer auto-opens on hover - it expands only on an explicit click of the expand button. The left handle drags the toolbar horizontally along one axis. The 'back to devices' control is now a button that closes the script-opened rdclient tab (re-focusing the opener) instead of navigating this tab to /devices, which previously spawned duplicate web-panel tabs. closeSession uses the same returnToDevices() helper. Adds move_toolbar/toggle_menu i18n keys (EN/PL/ZH) and an updated cross-platform feature matrix.
This commit was made possible thanks to Insolve.
Complete the web console locale set so all 26 language files share the EN/PL baseline with no missing keys, extra keys, empty values, or English fallback values.
Keep strict i18n audit behavior and disabled auto-fix flow so incomplete translations are surfaced for manual review instead of being filled with English fallback text.
Validated with the strict web-nodejs i18n audit, JSON parsing for all locale files, placeholder preservation checks, and VS Code diagnostics.
This commit was made possible thanks to Insolve.
Bump golang.org/x/crypto to v0.52.0 and x/sys to v0.45.0 in betterdesk-server, x/sys to v0.45.0 in betterdesk-agent, and aiohttp to >=3.10.11 in the rest-webhook bridge. Validated clean via govulncheck.
Add an explicit Go server rebuild path to the in-app updater so security/library updates actually reach the running binary: updateService now marks the server binary stale when the source changed but a non-critical rebuild/deploy step failed, exposes getServerBinaryStatus() and rebuildServerBinary(), and surfaces a warning banner plus a Rebuild button in the settings update panel. New REST endpoints GET/POST /api/settings/updates/server-binary/{status,rebuild} guarded by server.config permission. i18n keys added across all locales.
This commit was made possible thanks to Insolve.
Add a codec selector (Auto/VP9/AV1/H264/VP8/H265) to the remote viewer display menu so users can request a GPU-friendly codec from the peer. setCodec() re-advertises SupportedDecoding abilities with the chosen prefer codec via OptionMessage and forces a fresh keyframe. Browser decode abilities are probed (VideoDecoder.isConfigSupported) and unsupported codecs are disabled in the menu and advertised honestly at login. Raise default image quality from Balanced to Best at both client-creation sites and pause adaptive auto-quality once the user makes a manual quality/codec choice so it no longer overrides them.
This commit was made possible thanks to Insolve.
Add a device verification/enrollment workflow so new registrations are
held for operator review instead of connecting silently.
Go server (signal + api):
- Signal-mode pending: in 'managed' mode, unknown stock RustDesk clients
are queued (pending_device_<id>) instead of being silently rejected.
- Rich approve: handleApproveDevice accepts display_name, sync_mode and
normalized tags; handleRejectDevice supports an optional ban.
Node.js console:
- registrations.ejs approve modal (name, sync mode, tags, folder) and
reject modal with ban option; betterdeskApi + routes wire display_name,
sync_mode, tags and folder assignment through to the Go server.
- EN/PL/ZH i18n for all new strings.
Installers (managed default for FRESH installs only; existing installs
stay on the Go default 'open' or their DB-persisted mode):
- betterdesk.sh / betterdesk.ps1 write ENROLLMENT_MODE=managed to the
server env only when no existing database is detected (FRESH_INSTALL).
- Docker single + multi container entrypoints detect fresh volumes via a
sentinel plus id_ed25519/db_v2.sqlite3 presence and default to managed;
ENROLLMENT_MODE is now passed through supervisord and all compose files.
This commit was made possible thanks to Insolve.
Privilege separation across all installers so the long-running services no longer run with full administrative rights:
betterdesk.sh: installer keeps root but systemd units now run as a dedicated unprivileged 'betterdesk' system account by default (auto-created via ensure_service_user). Added full systemd hardening for the Go server (NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, ReadWritePaths) and light hardening for the Node.js console. chown migrates existing root-owned data to the service account on update. Opt-out via --run-as-root / BETTERDESK_RUN_AS_ROOT=1; custom account via BETTERDESK_SERVICE_USER. Minimal mode covered too.
betterdesk.ps1: NSSM services now run under their per-service low-privilege virtual accounts (NT SERVICE\<service>) instead of LocalSystem, with scoped icacls grants on the install/data dirs (Set-ServiceLeastPrivilege helper). Applied to the Go server, Node.js console and minimal-mode service. Opt-out via -RunAsRoot / BETTERDESK_RUN_AS_ROOT=1.
Docker: verified already privilege-separated (supervisord drops both programs to user=betterdesk; multi-container images drop via su-exec).
Also bundles in-progress changes to the Go server API, Node.js console services and Docker compose/Dockerfiles.
This commit was made possible thanks to Insolve.
- Updated Polish and Chinese language files to reflect changes in update descriptions and confirmations.
- Modified settings.js to automatically include server updates in the update process.
- Simplified the update installation API to automatically handle server updates without user intervention.
- Improved updateService.js to ensure all supported components are updated together, enhancing reliability.
- Added logic to check and install the Go toolchain as needed during updates, ensuring compatibility.
- Enhanced error handling and logging during the update process for better visibility of issues.
Make device group edit/delete actions visible, add direct user-group management entry points from the device group ACL modal, and allow device group editors to load user groups for ACL assignment.
Refs #140.
- Implemented user groups creation, editing, and deletion features.
- Added API endpoints for managing user groups: create, update, and delete.
- Enhanced user interface with a dedicated user groups manager section.
- Updated translations for user groups related strings in multiple languages.
- Improved CSS styles for user groups display and actions.
- Added tests for user groups API functionality.
- Added user group membership functionality, allowing users to be assigned to groups.
- Introduced validation for group GUIDs and enhanced error handling in user routes.
- Updated device group routes to support allowed user groups, enabling better access control for devices.
- Enhanced database schema to include user group memberships and device group user group access.
- Updated services and database adapters to handle user group data and relationships.
- Modified front-end views to display and manage user groups effectively.
- Added tests to ensure proper functionality of user group assignments and device access control.
Address the follow-up feedback on #136 about the user-management UX
feeling disjointed and using non-standard role labels:
- Rename the base organization role from "Viewer"/"User" to
"Member" across all 26 locales. This removes the vocabulary
collision with the server-wide "Viewer" role and makes the
two-axis role model (server role vs per-org role) clearer.
- Add an Organizations column to the System > Users table so
admins can see each user's org memberships at a glance without
opening a modal. Badges are clickable and reopen the existing
Organizations modal for that user.
- Clarify the Add/Edit User form: the role dropdown is now
labelled "Server Role" with a hint that per-organization roles
are configured separately under each user's Organizations.
- The Organizations modal now has an explicit section heading and
a short hint, and uses i18n labels for the role dropdown with
an aria-label so the org role is visually distinct from the
server role.
Backend role values are unchanged ("user"/"operator"/"admin"/
"owner" for orgs, existing 7 server roles), so this is a pure
UX/i18n change with no schema or API impact.
Refs: #136
Suggested-by: Sterlyn Kong <68391309+SterlynKong@users.noreply.github.com>
Complete Czech console translation from PR #133, update Docker quick-start admin credential lookup from PR #134, and fix live device-status updates found while reviewing PR #35.
Refs: #133, #134, #35
Co-authored-by: Karel Lowprize K <lowprize@gmail.com>
Suggested-by: Rafael Monteiro <96262868+rafaelgm@users.noreply.github.com>
- Implemented server management service providing resource snapshots, file browser, service control, and audit logging.
- Added terminal proxy for WebSocket-backed PTY, allowing browser-based shell access with user authentication and role-based access control.
- Created server management view with tabs for overview, terminal, file management, and services, including UI elements for displaying system metrics and managing files/services.
Co-authored-by: Copilot <copilot@github.com>
Backfill missing web console translation keys across all available locale files using the English and Polish catalogs as the completeness baseline.
Also normalize the locale JSON files so they parse consistently during tooling and validation.
Three independent bugs combined to make 'Add Relay' silently do nothing:
1. saveRelay() in public/js/scaling.js used raw fetch() without the panel's
CSRF token, so every POST/PUT/DELETE was rejected by the CSRF middleware.
2. The catch block swallowed every error and the modal closed regardless of
the response code, so the user never saw the rejection.
3. The relay/rules routes proxied to /scaling/relays on the Go server, but
the Go server doesn't (yet) implement those endpoints — every request
ended up as a 404 and the panel's relay table stayed empty forever.
Changes:
- routes/scaling.routes.js: drop the dead Go proxy, persist relay-node
metadata and assignment rules in the existing 'settings' table
(auth.db / DATABASE_URL). Strict input validation (host:port,
Unicode-safe name, ranges for sessions/bandwidth/priority), 409 on
duplicate addresses, capped at 100 relays / 200 rules. Health and
metrics endpoints now return explicit 'live telemetry not yet
available' placeholders instead of 500s.
- public/js/scaling.js: every mutating fetch() now sends x-csrf-token,
validates inputs with a toast, parses JSON error bodies, only closes
the modal and reloads on success. Falls back to alert() if the toast
service is missing so users are never left guessing.
- views/scaling.ejs: info banner above the Relay Nodes table making
clear that the list is operator-side metadata and that actual relay
routing is configured via RELAY_SERVERS on the BetterDesk server.
- public/css/scaling.css: styles for the new info banner.
- lang/en.json, lang/pl.json: i18n keys for the banner, validation
messages and success/failure toasts.
Note: the reporter also tried RELAY=... — only RELAY_SERVERS is read
by the Go server (see config/config.go:160). Worth surfacing in docs
in a follow-up.
Reported-by: @Elektrik1
The 'Add User' modal in an organization showed Owner / Admin / Operator / User
while the server-level 'Add User' modal showed Viewer / Operator / Administrator
/ Global Admin / Server Admin / Super Admin / Pro. Same conceptual roles had
inconsistent labels (Admin vs Administrator) and the lowest tier used different
words (User vs Viewer), making the two modals look unrelated.
Server-only roles (Super Admin, Server Admin, Global Admin, Pro) intentionally
remain absent from the org modal — they are not org-scoped.
Changes:
- web-nodejs/public/js/organizationDetail.js: reorder roleOptions() to
lowest-first ['user','operator','admin','owner'] to match the server modal's
Viewer→Pro ordering pattern.
- web-nodejs/lang/*.json (26 locales): in the 'organizations' section, rename
role_user label to the localized equivalent of 'Viewer' (matching the
server section's role_viewer) and role_admin to 'Administrator' (matching
server section's role_admin). Backend enum values ('user', 'admin') are
unchanged — this is a pure label change, no schema migration required.
Reported-by: @SterlynKong
- deployServerBinary: use rename(2) for atomic replace, fixes ETXTBSY
when target Go binary is busy (Linux kernel handles inode swap).
Falls back to copyFileSync on cross-device rename or non-Linux.
Windows: rename target out of the way first, then move new in.
- settings.js: mark 'server' phase as error when build succeeded but
deploy failed (was incorrectly marking 'done' from build alone).
- settings.js: completion modal now shows error title, error message
and pre-formatted stderr when serverDeploy.success === false.
- i18n: added complete_with_errors, modal_done_with_errors_title in
en/pl.
- updateService: enhanced checkGoAvailable() to scan well-known paths
(/usr/local/go, /snap, vendored data/go-toolchain, /usr/lib/go-1.x)
and return absolute binary path so spawned exec works without PATH.
- New installGoToolchain(): dynamically fetches go.dev/dl/?mode=json,
picks newest stable >= 1.23.0 for current OS/arch, downloads archive,
verifies SHA-256 from manifest, extracts to data/go-toolchain/.
- buildGoServer() now uses absolute go path, 600s timeout.
- New 'install-go' update strategy + auto-fallback in 'auto' mode:
when host has neither Go nor a prebuilt release, the toolchain is
installed automatically and compilation proceeds.
- New POST /api/settings/updates/install-go endpoint for explicit
install (audit-logged, server.config permission gated).
- Settings UI: third 'Auto-install Go and compile' radio. Update
checkbox is no longer disabled when Go is missing — auto-install
is always offered as a fallback.
- installUpdate() rewritten as Modal-based phased dialog:
Confirmation -> Backup -> Console -> Server -> Restart -> Done.
Live phase icons (pending/active/done/error/skipped), progress bar,
log pane, completion modal with reload CTA, auto-reload after
successful console restart.
- New i18n keys (EN+PL): strategy_install_go, auto_strategy,
toolchain_*, modal_*, phase_*, confirm_*, etc.
- New CSS (.update-progress-modal, .update-phase, .update-progress-log).
Expose an update strategy UI and support downloading pre-built server binaries as an alternative to compiling from source.
- Add new translation keys (en/pl/zh) for strategy labels, badges, download/build messages and install Go hint.
- Update settings UI: show strategy selection (download / compile), badges with availability/release/size, auto-select best strategy, and adjust status/info messages and progress text.
- settings.routes: make server-info handler async and include prebuilt info; accept serverStrategy in updates/install request and forward to updateService.
- updateService: add helpers getReleaseBinaryName, checkPrebuiltAvailable, downloadPrebuiltBinary and getPrebuiltInfo; extend getServerUpdateInfo to include expected binary/platform/arch. Implement server update flow to support compile or download strategies (auto fallback), download/prep binary, validate size, deploy binary, and record method/size in results.
This enables faster updates on platforms with prebuilt releases while preserving the compile-from-source path and providing clear UI feedback and fallbacks.
Add OS-level admin detection and use it to gate sensitive agent UI and tray actions. Introduce privileges.rs (Windows TokenElevation / Unix geteuid) and expose is_os_admin as a Tauri command; wire it into tray setup to hide admin-only menu items (Settings, Quit) and re-check privileges before executing those actions. Add show_window helper and emit navigate events from the tray; frontend listens for navigate and conditionally renders /settings (shows AdminRequired component for non-admins). Update App.tsx to query is_os_admin on startup and include navigation listener; add AdminRequired component, styles, and i18n keys. Update Cargo.toml with platform deps (windows features + libc for unix). Also add UI/locale assets and CSS for agent lazy-loaded device tabs and a notifications dropdown, plus several web-nodejs route/view/style updates and new task docs describing phase work.
Enable optional compilation and deployment of the Go server as part of the self-update flow. UI: add checkbox/status/info area in settings.js, check /api/settings/updates/server-info, include server component when selected, adjust progress/messages and longer timeouts. API/Server: add server-info endpoint and extend install request timeouts. Service: updateService now sets server localRoot and implements functions to detect Go, fetch server source (git or GitHub API), build the binary, and deploy it. i18n: add related translation keys across many locale files. Misc: improve input validation and error logging in desktop.routes, and return graceful defaults for missing policy routes in policies.routes.