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.
Multiple security and maintenance fixes across components:
- betterdesk-mgmt: validate peer_id format to prevent injection in connect_to_peer (reject empty/oversized/invalid chars).
- betterdesk-mgmt (tauri.conf.json): tighten CSP by removing 'unsafe-eval' from script-src.
- betterdesk-agent-client: increase device ID entropy from 4 to 8 bytes (BD- prefix) to reduce collision/brute-force risk.
- betterdesk-server: enforce RBAC (operator+) before upgrading CDAP video WebSocket to block unauthorized access.
- betterdesk-server DBs: exclude soft_deleted peers in GetPeer queries for Postgres and SQLite.
- web-nodejs: add audit log housekeeping (hourly cleanup), add indices for audit_log, and implement cleanupOldAuditLogs(days) in sqlite adapter.
- web-nodejs brandingService: validate logo/favicon URLs to allow only http(s) or relative paths, preventing javascript:/data: XSS/SSRF vectors.
- docs: add AUDIT_BETTERDESK_2026-04-17.md (security audit summary).
These changes tighten client CSP, improve input validation, increase device identifier entropy, ensure RBAC is enforced before websocket upgrades, hide soft-deleted peers from normal queries, and add audit log maintenance and DB indexes for better performance and retention management.
Use the layout-provided CSRF token (window.BetterDesk?.csrfToken) instead of a non-existent meta tag. This fixes failing PUT requests for organization policy saves (Issue #112), and resolves attestation verify/revoke failures. Also replace toolkit's cached meta lookup with a getCsrfToken() helper so API calls always read the current token. Updated .github/copilot-instructions.md to document the Phase 53 CSRF fixes.
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.
Add warnings for TLS API misconfiguration and enrollment restrictions. The Go server now logs a clear warning when TLS on the API port is enabled (explaining it breaks HTTP consumers and how to fix) and logs active enrollment restriction when restored from DB. The Node.js API client (betterdeskApi.js) and event bus handler (deviceStatusPush.js) now detect TLS/HTTP mismatches and surface actionable console/error messages to help operators debug the issue (references issue #104). Files changed: betterdesk-server/main.go, web-nodejs/services/betterdeskApi.js, web-nodejs/services/deviceStatusPush.js.
Toast.js is only loaded on pages that explicitly include it via pageScripts,
but policies, attestation, chat, languages, organizations, and
organizationDetail pages relied on Toast for user feedback — which silently
failed because typeof Toast === 'undefined' on those pages.
Replaced all Toast.success/error/warning() calls with Notifications
equivalents (globally available via main.ejs layout). Fixed parameter
order (Toast: title,message → Notifications: message,title).
Added i18n keys: policies.save_success/save_failed/load_failed,
attestation.verify_success/verify_failed/revoke_success/revoke_failed
in EN, PL, ZH.
Fixes#105
Extend localization across multiple locale files: add a new permissions section and related role/organization strings, 2FA prompts, branding/typography keys, baseline/backup status keys, and many organization/device/user management messages. Also add load_orgs_failed and verify/2fa messages, update plural/device count keys in betterdesk-mgmt en/zh-TW, and adjust several existing messages (e.g. field_required placeholder and various delete_confirm texts) to improve clarity.
- Restore enrollment_mode from DB on server startup (was always resetting to 'open')
- Fix GetDeviceTokenByPeerID to include 'pending' status tokens (was filtering them out)
- Fix managed mode: validate token by hash instead of peer binding
- Fix locked mode: allow enrollment with valid token (was rejecting everything)
- Bind token to peer and increment use count on successful token enrollment
- Update i18n: clarify 'Token Prefix' column label, fix mode descriptions (EN/PL/ZH)
Replace client-side base64 logo handling with server disk uploads and update related UI/locales. Increases logo size limit to 2 MB, adds success messages and revised hints in en/pl/zh locales. Client JS now POSTs the file to /api/settings/branding/upload-logo with CSRF header and fills the image path on success. Adds an Express route using multer to store uploads under dataDir/uploads, validate types/sizes, remove previous uploaded logo, and log the action. Also serves the /uploads static directory from the persistent data dir.
Several cross-cutting fixes and refactors:
- API routing: Consolidated multiple org policy PUT endpoints into a single parameterized route (/api/org/{id}/policy/{category}) to simplify handlers (api/server.go).
- Relay/LAN handling: Prefer server LAN IP for LAN relay addresses (with proper port detection from configured relay), added strconv import and fallback to configured relay when LAN IP unknown; improves reliability with NAT hairpin issues (signal/handler.go).
- Web security: Allow inline event handlers (scriptSrcAttr: 'unsafe-inline') while still requiring nonced <script> tags for scripts used by admin pages (web-nodejs/middleware/security.js).
- CSRF: Include x-csrf-token header when POSTing language fix requests from the UI (web-nodejs/public/js/languages.js).
- Admin roles: Broaden admin checks to accept multiple admin role names via ADMIN_ROLES and update requireAdmin and RustDesk payload is_admin logic (web-nodejs/routes/rustdesk-api.routes.js).
- Admin credentials & startup resilience: authService now searches additional candidate dirs (config.dataDir, extra Windows/RustDesk paths, /app/data in Docker), skips empty candidates, and increases retries/delays when waiting for .admin_credentials (web-nodejs/services/authService.js).
- Chat API paths: Updated chat-related API calls to use /chat/* (instead of /api/chat/*) across persistence, history, contacts, groups, read and other operations (web-nodejs/services/chatRelay.js).
These changes improve compatibility (LAN relay, admin detection), robustness (longer retries, Docker/Windows path checks), and frontend behavior (CSRF token, inline handlers, updated chat endpoints).
DB: Use current_schema() when checking columns for deferred index creation and add exception handling to skip index creation if column is absent (avoids cross-schema false positives and race errors).
Signal: Harden isSameNetwork by normalizing IPv4, handling mapped addresses, adding detailed debug logs for loopback/private/subnet checks, and logging LAN detection failures in the RequestRelay handler.
Auth/API: Add tighter debug logging and trimming for /api/login (redacting passwords), and reject empty/invalid usernames early in authenticate() to address Issue #104.
UI: Add save button feedback (spinner, disable/restore), extra logging and error handling when saving org settings, and make logo image URL input editable by removing readonly.
Add broad request logging in auth middleware and more granular debug logs for login handling (JSON decode errors and non-password login fields) to aid troubleshooting. Trim and sanitize username/password on the web login route and log whitespace/empty username cases and missing credentials. Extend isSameNetwork logic to treat loopback ↔ private-IP pairs as same network (covers local server → LAN target cases). Fix remote viewer templates to avoid inline string interpolation by injecting device data via JSON and setting DOM textContent (prevents XSS and EJS injection); also minor formatting/alignment tweaks in role handler comments/structs.
Add typography support and a text-based logo option plus several TLS/connectivity improvements. Introduces a new font service (web-nodejs/services/fontService.js) to search, download and serve Google Fonts for self-hosting, new API routes for font management, and client-side font picker UI/logic (settings.js) with CSS (pages.css, main.css) and i18n entries (en/pl/zh). BrandingService now supports logo text/accent and font heading/body and includes generated font CSS. Views (login/sidebar) updated to render text logos and a new theme (themes/insolve.json) added. Server and TLS updates: API server now prefers TLS on the API port when valid certs exist, and dual-mode listener in tls.go adds a short peek timeout to avoid deadlocks with RustDesk clients.
Remove theme selection UI, CSS and logic and enforce dark theme across the app. Deleted sidebar and settings theme toggle markup and related CSS (.sidebar-theme-toggle, .theme-selector) and removed theme handling (storage keys, applyTheme/cycleTheme, event handlers and public theme API) from desktop-mode.js. Instead the app now forces the dark theme via document attributes/classes (comment: conflicts with branding). Files changed: public CSS (main.css, ui-polish.css), desktop-mode.js, main layout and sidebar templates. Local theme storage/controls are no longer used.
Implement RBAC Phase 52: add server-side role & permission handlers and wire API routes, plus frontend UI, styles and translations.
Server: new role_handlers.go exposing endpoints to list roles, get effective role permissions, list/set/delete role permission overrides; routes registered in server.go with permission checks (PermUserView / PermServerConfig). Protects super-admin defaults and validates inputs.
Frontend (management & web UI): add permissions page assets (CSS, JS, view), add i18n strings for en/pl/zh, update sidebar to filter items by canView, show user role badge in topbar and empty access-denied state when no permission. Add role badges styling in users.css and small UX/i18n improvements in organizationDetail.js.
Also several route and service adjustments to support the new permissions UI. This change introduces RBAC UI/API plumbing for managing role-based permissions and overrides.
Adds a full Phase-52 RBAC implementation and multiple server/frontend fixes. Key changes: new auth/permissions.go with 28 granular permissions and DefaultRolePermissions, expanded 7-role hierarchy and helpers in auth/roles.go, JWT org context and GenerateOrgToken, requirePermission/requireOrgMembership middlewares (Go + Node.js), DB schema & adapter changes for role_permissions and is_server_admin, org role boundary checks and peer org scoping, and guards for last-admin demotion and self-demotion. Also: TCP EOF/connection-reset log filtering in signal/relay servers, improved startup banner port display, KEYS_PATH auto-detect warning, CSS hover/transition layout fixes, admin password race mitigation, ID-change ghost peer cleanup, added Tauri ACL schema files, and a new RBAC_PHASE52.md doc. Misc: numerous web-nodejs i18n, CSS, JS and route updates and an updated .github/copilot-instructions.md timestamp/summary.
- Fix critical SQLite migration bug: auth.db column migrations (last_login,
totp_*, settings.updated_at) were in ensureInventoryTables() which receives
main DB handle — PRAGMA table_info(users) returned empty on main DB, so
ALTER TABLE never executed. Moved to ensureAuthTables() (auth DB handle).
- Add migration logging (console.log for each added column)
- Add branding_config.updated_at migration
- Fix bd-api.routes.js: session cookie fallback auth for desktop client
- Fix auth.routes.js: rate limiter improvements
- MGMT client: add logging module, improve auth store with TOTP + token
acquisition, enhance RemoteView with session logging, improve relay
connection handling in bd_relay.rs
devices.js and deviceDetail.js used betterdesk:// protocol for the
Connect Desktop button, but standard RustDesk clients only register
the rustdesk:// URI handler. Changed to rustdesk:// for compatibility.
help-requests.js and widget-plugins.js already used rustdesk:// correctly.
- ensureDefaultAdmin() now reads Go server's .admin_credentials file as
fallback when DEFAULT_ADMIN_PASSWORD env var is not set
- Searches multiple candidate dirs: keysPath, keysPath/data, /opt/betterdesk,
/opt/betterdesk/data, /opt/rustdesk, /opt/rustdesk/data
- Parses 'Admin Password: <value>' line from the file
- Fixes password mismatch on manual installs without ALL-IN-ONE scripts
- Existing installs with .env DEFAULT_ADMIN_PASSWORD are unaffected (env wins)
- config.js: resolveKeysPath() checks for id_ed25519 in /opt/betterdesk first,
then /opt/rustdesk, respecting env var override as highest priority
- betterdesk.sh: add /opt/betterdesk to COMMON_RUSTDESK_PATHS search list,
change default for new installs from /opt/rustdesk to /opt/betterdesk
- server.js: show resolved Keys path in startup banner for easier debugging
- Existing installs with KEYS_PATH env var are unaffected
- Windows already defaults to C:\BetterDesk (no change needed)
- Replace release-based check (always 404) with commit-SHA tracking
- Track deployed state via data/.update_sha file
- Detect changes across all components (console, server, agent, scripts)
- Show recent commits, component breakdown, and file counts
- Auto-update console + script files, manual badge for Go server
- Pre-update backup with SHA-tracked restore
- Support npm install when package.json changes
- Service restart for console (auto) and Go server (on demand)
- 15 new i18n keys in EN/PL/ZH for update UI
- CSS for commit list, component rows, rebuild warning
- de.json, es.json, fr.json had multiple missing commas and broken
JSON structure causing 'Failed to load language' errors on startup
- Rebuilt all 3 files using en.json as structural template, preserving
existing translations (de: 2145, es: 2245, fr: 2242 keys preserved)
- languages.routes.js: read both 'meta' and '_meta' keys (some files
use 'meta', others '_meta') to correctly display language names
- Change default GITHUB_REPO from 'Rustdesk-FreeConsole' to 'BetterDesk'
(repo was renamed, causing 404 on releases/latest API call)
- Handle 404 gracefully when no GitHub releases exist yet: return
'up to date' response instead of throwing error
- Add 'updateAvailable' and 'releaseNotes' fields to response object
(frontend settings.js expects these field names)
- users.js: Change parseInt(userId, 10) to Number() on both sides of
comparison to handle BigInt/string/number ID types correctly
- dbAdapter.js: Wrap all lastInsertRowid with Number() to prevent
BigInt leak from better-sqlite3 v9+ (BigInt === Number is always false)
Root cause: better-sqlite3 v9+ returns lastInsertRowid as BigInt.
If user objects with BigInt IDs ended up in the users array, strict
equality (===) with parseInt result (Number) always fails silently,
making edit/reset-password/delete buttons appear unresponsive.
- Add zh-TW translations for web console, agent client, and MGMT client
- Update VALID_LANG_CODE regex to support BCP 47 tags (e.g. zh-TW)
- Add zh-TW to LANGUAGE_META in i18nService
Introduce a SessionManager for relay-based remote sessions in the Tauri MGMT client: new SessionCommand API, start/stop/session input routing, clipboard/recording/quality controls, and notification read/dismiss state. Wire AppState with new mutexes and show main window on startup. CI: add SBOM generation (anchore) and Trivy vulnerability scan steps. Misc: change console Docker DB path, large README/CHANGELOG updates (chat E2E, unattended access/WOL, i18n expansion, CDAP/SDK docs), and many web-nodejs assets/locales/routes/views/services and server-side changes.
Introduce a server-side API proxy and cookie-enabled HTTP client in the Tauri backend to bypass WebView CORS/mixed-content limitations and support session-based auth. Cargo.toml enables reqwest cookie_store; AppState and lib.rs build and expose a shared reqwest::Client and register api_proxy and api_clear_session commands. commands.rs implements api_proxy (forwards requests, returns JSON with __status and proper error reporting) and a stubbed api_clear_session.
Add a large set of frontend UI components and features: AutomationPanel, ChatPanel, DataGuardPanel, DeviceDetail, FileTransferPanel, HelpRequestsPanel, NotificationCenter, RemoteView, ServerPanel, SessionHistoryPanel, ToastContainer and a toast store. Update Dashboard and DeviceList to include recent sessions, help requests, device actions/WOL, retry buttons, and an actions menu. Also update layout/Sidebar/Settings, add locale strings (en/pl), and tweak global styles and some web-nodejs assets (desktop widgets, desktop-mode, tutorial, main layout) to support the new panels and behavior.
Simplify the management app startup and UI: App.tsx now initializes auth and conditionally renders Login or Layout with a minimal Splash. Introduces an auth store and new Login/Layout components, adds DeviceList and Settings components, and updates Sidebar, Dashboard, locales and global styles. Removes the legacy chat window (HTML + entry), the tauri chat window entry, and many panel components that were unused (Activity, Automation, CDAP, ChatWindow, Connection, RemoteAgent, Management, NotificationCenter, Operator, OrgLogin, PasswordDialog, RemoteBadge, RemoteView, ServerPanel, SettingsPanel, SetupWizard, TotpDialog, Toolbar, etc.). Also adds a favicon and updates vite/server config and main entry adjustments to reflect the new streamlined, auth-driven layout.
Introduce two new desktop apps: betterdesk-mgmt (operator/admin console) and betterdesk-agent-client (lightweight endpoint agent).
Key changes:
- Add complete betterdesk-agent-client scaffold: frontend (index.html, TSX components, i18n, styles, Vite/TS configs, package.json) and Rust Tauri backend (Cargo.toml, build.rs, tauri.conf.json, commands.rs, config.rs, registration.rs, sysinfo_collect.rs, NSIS language file).
- Add betterdesk-mgmt entries and assets (registered in docs) and update repo docs to describe both MGMT and Agent clients.
- Update .github/copilot-instructions.md to reflect MGMT/Agent client split and add detailed TODO/feature lists.
- Update .gitignore to exclude build artifacts for both new Tauri apps.
- Add docs/new_agents/client1.md and docs/new_agents/client2.md.
- Minor changes to server DB files and web-nodejs i18n/asset files.
This commit adds the initial scaffolding and core IPC/registration/diag features for the agent and registers the MGMT client in repository docs; further implementation and testing remain.
Introduce a topbar shortcuts feature with edit mode and drag/drop support, backed by localStorage. Add translations for the new "edit_shortcuts" label across locales and update the main layout to include the shortcuts container and edit button. Rework desktop-mode CSS/JS to replace the previous compact taskbar with a slim full-width taskbar that expands on hover and shows tab-style indicators; update TASKBAR_HEIGHT and taskbar rendering logic. Add drag support to app-drawer tiles for adding shortcuts, implement shortcut rendering/reordering/removal, and fix snap preview assignment order.
Add multiple security hardenings across the server and web console: enforce proof-of-possession for /ws/bd-mgmt using Ed25519-signed headers with timestamp/nonce and replay protection (public key binding, canonicalization, storage, verification, and tests); remove legacy API key query param and config-table fallback in favor of scoped api_keys (migrate bootstrap key into api_keys); tighten WebSocket origin handling for relay and signal servers to allow only localhost origins by default unless an explicit allowlist is set; update auth middleware public paths and test helpers to use X-API-Key header; add ensureScopedAPIKey migration and related helpers; add a GitHub Secret Scan workflow and an audit report. Misc: propagate audit logging on bd-mgmt connect/disconnect and validate enrollment public keys during device register.
Introduce a Web Remote experience with multi-session management, UI and security improvements.
Highlights:
- Add i18n keys for web_remote, new_connection, device_id_placeholder and http_warning across locales.
- UI/CSS: replace single viewer with session/tab UI, session tab bar, HTTP/security banners, toolbar repositioning and numerous style additions for multi-tab sessions and warnings.
- devices.js: add a Web Remote action and use BroadcastChannel to attempt adding a session to an existing remote page (fallback to opening a new tab).
- remote.js: large refactor to support multiple concurrent RDClient sessions (SessionInfo), tab creation/switching/closing, shared toolbar syncing, session lifecycle management, reconnect logic and autoplay/overlay handling.
- rdclient: security and robustness enhancements:
- rdclient/crypto.js: add Ed25519 SignedId verification (verifySignedId, _hexToBytes) and expose signatureVerified metadata.
- rdclient/client.js: log severity changes, emit encryption/signature warnings, verify server-signed IdPk to detect MITM, expose renderer cursor readiness via events, and reduce stall detection thresholds / quicker recovery.
- rdclient/renderer.js: notify when remote cursor image is ready so CSS can hide local cursor.
- rdclient/video.js: improved MSE health checks, dynamic buffer trimming, JMuxer reinitialization for stuck pipelines, switch timing to ~60fps timestamps, and more aggressive playback catch-up behavior.
These changes improve UX for web remote sessions, add security verification against server-signed identity, and make video playback and recovery more robust.
Introduce a dedicated desktop layout overlay and auto-arrange features plus operator session endpoints. UI changes: add BD_icon_small.png, update .gitignore, add new overlay styles in desktop-mode.css, and rename widget snap CSS classes in desktop-widgets.css to avoid conflicts. JS updates: implement open/close layout overlay, autoArrangeWindows, shouldReserveTaskbarSpace, improved taskbar hide/toggle logic, and expose layout APIs from DesktopMode; widgets will call DesktopMode.openLayoutOverlay when available and otherwise use the widget picker. Backend changes: add requireOperatorRole middleware, helpers (normalizeSessionAction, toTimestamp, buildSessionHistory), enforce operator/admin checks on device/help-request endpoints, and add POST /api/bd/operator/sessions and GET /api/bd/operator/sessions to record and retrieve operator session history with input validation and duration computation.
Add unit tests and test helpers (5 suites, 41 tests) and test npm scripts; introduce deviceStatusPush service and WS real-time device status push integration. Fix chatRelay to acknowledge connections (send `welcome`), and apply multiple web remote/rdclient fixes (video ack/timing, keyframe refresh, SourceBuffer trimming, input focus handling) to improve FPS and control. Add new server route file (system.routes.js), new device-status service, update server.js and package.json, and modify various frontend CSS/JS/views. Update English and Polish locale files with many new widget/i18n keys and remove the Russian locale file (ru.json). Also include assorted UI/desktop-widget dashboard tweaks and documentation status updates in .github/copilot-instructions.md.
Add localization keys (en/pl) for uptime and widget actions. Update widget CSS to position panels absolutely, improve scrolling behavior and layout containment. Simplify desktop mode JS by removing the start menu, taskbar console button and clock logic, and related markup in main layout. Adjust canvas sizing math to match new topnav/sidebar dimensions and replace many sidebar route buttons with Edit/Reset actions; implement edit-mode toggle and a reset that clears stored layout and re-initializes widgets. These changes streamline the desktop/widgets UX and fix layout/scrolling issues.
Introduce persisted chat features and a BetterDesk desktop management WebSocket channel. Adds new REST chat handlers (history, send, read, unread, contacts, groups), bd-mgmt WebSocket and management REST endpoints, and routes in the HTTP server. Extend Database interface and models (ChatMessage, ChatGroup, ChatContact) and implement schema migrations + CRUD for PostgreSQL and SQLite. Adjust auth middleware to allow /ws/bd-mgmt/* and relax server WriteTimeout / increase IdleTimeout to accommodate long-lived WS connections. Also add a 3.0 roadmap document and minor frontend/localization/service updates related to chat and relay.
Update client links to open the remote-desktop UI (replace /remote/ with /remote-desktop/). In remoteRelay: transform viewer 'input' frames into the agent's expected InputEvent shape (map event_type -> type) before forwarding, and decode+validate the agent device ID on WebSocket upgrade (reject malformed IDs) to reduce path-traversal/abuse risk. In bdRelay: simplify upgrade handling so this handler only processes /ws/bd-relay and /ws/bd-signal paths and otherwise yields to other upgrade handlers, avoiding manual delegation. These changes improve compatibility, security, and routing correctness.
Introduce full CDAP subsystem and devices UI overhaul. Adds a new CDAP WebSocket gateway (cdap/gateway.go) with auth, connection lifecycle, message loop, heartbeat monitor and APIs (cdap/api.go, cdap/auth.go, cdap/handler.go, cdap/manifest.go, cdap/messages.go). Wire CDAP into the server (api/server.go + handlers in api/cdap_handlers.go) exposing REST endpoints for status, device list, info, manifest, state and sending commands. Enhance peer handling: CDAP-connected overlay in peer list/get, device revocation/cascade support in handleDeletePeer (blocklist, connection teardown, events + audit), and new audit action ActionPeerRevoked. Frontend updates include CDAP device page, widgets, commands, styles and services; major devices page UI redesign (responsive folder chips, toolbar, slim table, kebab menu) plus related CSS/JS/views, translations, docs and assets. Overall adds CDAP features, revocation workflow, and a responsive devices UI.
Introduce peer metrics persistence and partial peer updates, plus relay UUID recovery and soft-delete protections.
- DB: add PeerMetric type and new Database methods (SavePeerMetric, GetPeerMetrics, GetLatestPeerMetric, CleanupOldMetrics, UpdatePeerFields, IsPeerSoftDeleted). Add peer_metrics table and indexes in SQLite and PostgreSQL migrations; implement all methods for both backends.
- API: handleClientHeartbeat now parses cpu/memory/disk and saves metrics; new endpoints PATCH /api/peers/{id} to update note/user/tags and GET /api/peers/{id}/metrics for historical metrics. handleSetPeerTags now accepts either string or array JSON payloads. Added audit.ActionPeerUpdated.
- Signal server: add pendingRelayUUIDs store (with TTL cleanup, store/get helpers) to recover missing UUIDs from old clients when RelayResponse contains empty uuid; store pending UUIDs when forwarding RequestRelay/PunchHole. Add IsPeerSoftDeleted checks to reject re-registration of soft-deleted devices.
- Node.js panel: betterdeskApi.setPeerTags now sends tags as array and exposes updatePeer() for PATCH; serverBackend.updateDevice routes note/user updates through Go PATCH endpoint and preserves local auth.db writes as fallback; devices.routes deletes now call cleanupDeletedPeerData.
- dbAdapter: add cleanupDeletedPeerData implementations for SQLite and Postgres to remove related auth.db rows when a peer is deleted.
These changes fix zombie device re-registration, ensure metrics are stored & retrievable, centralize peer metadata updates through the Go API, and recover relay pairing failures with legacy clients.
Co-Authored-By: boruto79 <176351662+boruto79@users.noreply.github.com>
Co-Authored-By: БлагоЯр <3672314+blagoyar@users.noreply.github.com>