The debug-bundle paths that upload without a human picking a destination
compiled the vendor endpoint in: the mobile clients and the desktop UI hold
`https://upload.debug.netbird.io/upload-url` as a constant, the CLI defaults its
flag to it, and the remote job falls back to it when nothing else is set. A
self-hosted deployment therefore shipped peer logs, routes, DNS and firewall
state to NetBird-run infrastructure without its operator ever configuring that,
and had no way to point those paths anywhere else. #7147 and #7153 gave the
remote job a per-job URL and an MDM override, but neither reaches the mobile,
UI or CLI paths, and both fail open when unset.
Publish the destination from the management server instead, on the channel that
already carries stun/turn/signal/relay/flow/metrics:
- `NetbirdConfig.debug.upload_url`, sourced from the new account setting
`debug_bundle_upload_url` (REST + dashboard) and falling back to the new
`DebugUpload.URL` in the management server config, which a self-hosted install
can set once so a fresh account is not left on the vendor default. Both are
validated as https-with-host where they are written; a change fans out to
connected peers rather than waiting for the next login.
- One resolver on the client, `debug.ResolveUploadURL`, used by every path:
MDM override > explicitly named URL > destination published by management >
the NetBird service, but only for a peer enrolled with NetBird's cloud.
Anything else fails closed with ErrNoUploadDestination and the bundle stays
local, which is the behaviour change: a self-hosted deployment that names no
upload service no longer uploads at all.
- The engine keeps the published value (`Engine.DebugUploadURL`) so the bundle
paths, which run off the engine loop, do not have to read it back out of the
opt-in sync-response store.
- The daemon request grows `upload`, so "upload to wherever this deployment
says" is expressible; an empty `uploadURL` no longer has to mean "no upload".
The privilege gate is unchanged and still applies only to a URL the local
caller named — a destination published by management is the operator naming
their own service.
- The desktop UI stops carrying a vendor URL of its own and sends the intent.
Reported privately as GHSA-hf99-43rj-h577.
- **Wails v3 application** (`client/ui`) with a React + TypeScript + Tailwind frontend replacing the Fyne UI: main connection view, exit-node switcher, networks/peers browser with detail panels, profile management, settings (general, network, SSH, security, troubleshooting, appearance), debug-bundle creation, and a first-run welcome flow.
- **Internationalization**: go-i18n bundle with 9 locales (en, de, es, fr, hu, it, pt, ru, zh-CN) shared between the tray and the frontend.
- **New system tray** implementation with per-platform theme-aware icons, including a native XEmbed host for Linux (`xembed_tray_linux.c`) and a Linux theme watcher.
- **Session handling**: auth session watcher (`client/internal/auth/sessionwatch`), pending login flow, session-expiration dialog and tray notifications, and `netbird login` improvements.
- **Daemon API extensions** (`daemon.proto`): status stream subscription, event stream, networks/exit-node selection endpoints, and richer full status — with probe throttling on the daemon side to protect against UI-driven request storms.
- **UI preferences store** persisted per profile, autostart management via the daemon (single source of truth in HKCU on Windows).
- **Build system**: Taskfile-based builds per platform (macOS, Linux, Windows), Docker cross-compilation images, MSIX/NSIS/nfpm/AppImage packaging, and a new `frontend-ui` CI workflow.
Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com>
Co-authored-by: Eduard Gert <kontakt@eduardgert.de>
Co-authored-by: braginini <bangvalo@gmail.com>
Co-authored-by: Pascal Fischer <32096965+pascal-fischer@users.noreply.github.com>
Co-authored-by: riccardom <riccardomanfrin@gmail.com>