Commit Graph

343 Commits

Author SHA1 Message Date
Eduard Gert
aaa5dbb606 forward ui browser logs to go 2026-06-09 10:55:56 +02:00
Eduard Gert
727e6d3004 update position of not connected text 2026-06-08 18:13:37 +02:00
Eduard Gert
4a79c24792 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-06-08 18:09:29 +02:00
Eduard Gert
6b2ae1c34c update session expiration dialog texts, add monitor aware position 2026-06-08 18:09:22 +02:00
Zoltán Papp
43175e0730 Move no-op rationale into empty function bodies
Replace the doc comments above the empty no-op stubs (bindTrayClick,
startTrayTheme, noopSessionWatcher.Dismiss/Close) with short in-body
comments explaining why each is empty.
2026-06-08 17:34:18 +02:00
Zoltan Papp
6e23ed4da7 [client] Add error event publishing for rejected session deadlines (#6358)
* [client] Surface session deadline rejections via SystemEvent and add timer arm debug logs

When sessionwatch.Watcher.Update rejects a deadline (pre-epoch, too far
in the future, or past the clock-skew tolerance) it silently zeroes the
status recorder, leaving the UI with no "expires in" row and no
indication of why. Publish a SystemEvent_ERROR on the AUTHENTICATION
channel so the rejection appears in the UI event feed and the user
knows re-login may be required.

Also add Debugf log lines in armTimerLocked so that warning and
final-warning timer fire-times are visible in logs without having to
add instrumentation after the fact.

https://claude.ai/code/session_01Y3bQoNgcVjTD4zDTvv7a8u

* [client] Remove verbose arm-timer debug logs from sessionwatch

The per-arm Debugf lines added noise on every deadline update.
Rejection logging already happens at the call site in engine_authsession.go;
the watcher itself needs no extra instrumentation.

https://claude.ai/code/session_01Y3bQoNgcVjTD4zDTvv7a8u

* [client] Leave userMessage empty on deadline-rejected event; use metadata key

Daemon-layer PublishEvent userMessage strings are not localized — the UI
reads metadata keys and builds its own locale-aware copy (same pattern
as the session-warning events in event.go). Drop the hardcoded English
sentence from the deadline-rejected event and instead surface the
rejection reason via a new MetaSessionDeadlineRejected metadata key so
the UI can detect and localize it.

https://claude.ai/code/session_01Y3bQoNgcVjTD4zDTvv7a8u

* [client] Revert silent deadline-rejected event; restore userMessage

MetaSessionDeadlineRejected had no UI consumer: the tray only does
metadata-driven localisation for MetaSessionWarning events; all other
SystemEvents display userMessage directly (tray_events.go). Leaving
userMessage empty made the rejection invisible to the user.

Restore the English userMessage so the generic event path shows
something, and remove the unused MetaSessionDeadlineRejected constant.

https://claude.ai/code/session_01Y3bQoNgcVjTD4zDTvv7a8u

* [client] Localize session deadline rejected notification via metadata key

Follow the same pattern as session-warning events: the daemon emits an
empty userMessage and puts the signal in a typed metadata key
(MetaSessionDeadlineRejected); the UI tray detects the key and builds a
locale-aware OS notification from i18n strings.

Changes:
- sessionwatch/event.go: add MetaSessionDeadlineRejected constant
- engine_authsession.go: empty userMessage, use the new metadata key
- ui/authsession/warning.go: re-export MetaDeadlineRejected for UI consumers
- ui/tray_events.go: gate on isDeadlineRejected alongside isSessionWarning;
  new branch calls t.notify with localized title/body
- i18n locales (en/de/hu): add notify.sessionDeadlineRejected.{title,body}

https://claude.ai/code/session_01Y3bQoNgcVjTD4zDTvv7a8u

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-08 17:10:15 +02:00
Eduard Gert
b067544c8a update padding and text 2026-06-08 16:02:42 +02:00
Eduard Gert
10d84b758f add ipv6 2026-06-08 15:22:35 +02:00
Eduard Gert
0e4d0128b6 add custom error dialog 2026-06-08 12:44:33 +02:00
Zoltán Papp
21f1142355 Merge branch 'main' into ui-refactor
# Conflicts:
#	client/ui/debug.go
#	go.mod
#	go.sum
2026-06-05 17:50:18 +02:00
Eduard Gert
9ecc083139 update missing translations 2026-06-05 14:57:32 +02:00
Eduard Gert
efd874efac add cloud / selfhosted segment in profile creation 2026-06-05 14:38:00 +02:00
Eduard Gert
5877880789 replace native confirm dialog with modals in settings 2026-06-05 13:16:39 +02:00
Eduard Gert
4427aaa31f update advanced port margin, update settings bottom bar height 2026-06-05 12:29:18 +02:00
Zoltán Papp
0ce3fbf5af [client] Tolerate already-deleted peer on profile logout, clear stale email
logoutFromProfile failed hard when the management server returned NotFound
(peer already deleted from the dashboard), blocking both profile logout and
profile removal. Treat NotFound as success — the peer is already gone, so
deregistering it is already satisfied.

Also drop the user-side per-profile state file on logout. The account email is
sourced from <profile>.state.json (written by the CLI after SSO login), which
the root daemon can't reach, so logout left a stale email showing in the UI.
Connection.Logout now removes it from the UI process after a successful logout;
the next SSO login recreates it.
2026-06-05 12:05:41 +02:00
Zoltán Papp
3967864172 [client/ui] Center windows on show under minimal WMs (XEmbed tray)
On minimal window managers (fluxbox et al, the in-process XEmbed-tray
path) the WM neither centers small windows nor restores their position
across a hide -> show round-trip, so the main, Settings, and dialog
windows opened in the top-left corner instead of centered.

These windows are created Hidden, so Wails' Linux/GTK4 backend skips its
post-Show centering pass (gated on !Hidden) and InitialPosition has no
effect on an unrealized window. Re-center from Go after Show, gated on
the minimal-WM environment via a recenterOnShow predicate (set to
xembedTrayAvailable on Linux, nil on macOS/Windows where the WM handles
placement). centerWhenReady polls from a background goroutine until the
move actually lands -- Center() moves via raw X11, which no-ops while the
GdkSurface is still nil and GTK4 realizes it asynchronously after Show().

Also reorder xembed_host_linux.go so the static helpers (xembedTrayAvailable,
goMenuItemClicked) sit at the end, after the constructor and methods.
2026-06-05 11:42:03 +02:00
Eduard Gert
296d3f124b truncate dns in main screen 2026-06-05 09:55:50 +02:00
Eduard Gert
adf1fe1858 add ready prop to autosize hook 2026-06-05 09:48:17 +02:00
Zoltán Papp
db371a0263 [client/ui] Fix tray submenu not updating on KDE/Plasma
The Profiles and Exit Node submenus (and the About version/Update rows)
stopped reflecting changes on KDE/Plasma: after the first profile switch
the menu froze on its initial snapshot, and "Manage Profiles" — plus the
profile rows themselves — stopped responding to clicks entirely.

Root cause (confirmed via dbus-monitor): Plasma's StatusNotifierItem host
caches a submenu's layout the first time it is opened (GetLayout for that
submenu id) and never re-fetches it on a LayoutUpdated(parent=0) signal.
The old submenu.Clear()+Add() repaint allocated fresh monotonic item ids
each time but reused the same submenu container id, so Plasma kept showing
the stale snapshot and, on click, sent the stale ids back — which the
rebuilt itemMap no longer knew, silently no-op'ing the click.

Fix: route every dynamic tray-menu change through a new relayoutMenu that
rebuilds the whole tree (buildMenu + repaint cached state + a single
SetMenu), allocating brand-new submenu container ids. Plasma treats those
as unseen and re-queries them on next open, fixing both the stale paint
and the dead clicks. loadProfiles/refreshExitNodes now cache their rows
and drive relayoutMenu; the update row goes through a new onMenuChange
hook; the daemon-version row relayouts too. relayoutMenu is serialised by
menuMu and the fill*Submenu helpers are pure UI (no fetch, no SetMenu) so
it never recurses. The whole-tree SetMenu also subsumes the prior darwin
detached-NSMenu workaround.
2026-06-04 18:28:30 +02:00
Theodor Midtlien
512899d82d [client] Prevent corruption from competing log rotation and improve debug bundle (#6214)
* Adds heuristic to detect an edge case on Linux where a system has configured logrotate as a separate service to rotate log files which would mangle our client log files. If we detect logrotate being configured for netbird, we disable our rotation.

* Adds new env var to disable log rotation: NB_LOG_DISABLE_ROTATION

* Adds compressed and plain logrotate files to debug bundle.

* Replaces lumberjack with timberjack (maintained fork with bug fixes and extra features).

* Clarifies which daemon version is running in the bundle stats.

* Change logging for client service status to console
2026-06-04 17:36:45 +02:00
Zoltán Papp
ca6f6d88cb Merge branch 'main' into ui-refactor 2026-06-04 17:06:11 +02:00
Zoltán Papp
e298747203 [client/ui] Refresh profile list in tray + UI on CLI profile add/remove
The daemon emits no dedicated profile-changed RPC event, and a profile
add/remove doesn't move the connection status, so the UI's SubscribeStatus
path never fired for CLI-driven `netbird profile add|remove` (and the tray's
iconChanged guard would swallow it anyway). The tray menu and the React
profile list stayed stale until the next status-string transition.

AddProfile/RemoveProfile now publish a marked INFO/SYSTEM event over
SubscribeEvents (metadata kind=profile-list-changed, empty userMessage so it
stays silent). The UI's dispatchSystemEvent recognises the marker and
re-emits the existing EventProfileChanged, which the tray's loadProfiles and
React's ProfileContext.refresh already subscribe to — so both surfaces
refresh from a single signal that originates in the shared daemon handler
(covering both CLI and UI-initiated removals). No proto change.

Also drop a stray, build-breaking `app.Updater` line in main.go.
2026-06-04 16:03:22 +02:00
Theodor Midtlien
5993ec6e43 [client] Allow wireguard port to be zero in UI and show port in status command (#6158)
* Allow wireguard port to be set to 0 in UI

* Add wireguard port to cmd status

* Correct protoc version
2026-06-04 15:04:11 +02:00
Zoltán Papp
cba4a8a63b [client/ui] Fix login wedging until restart after a failed SSO attempt
startLogin held both guards (the module-level loginInFlight and the
caller's React-level loginGuard) across the post-failure errorDialog
await. The native Windows MessageBox disables its parent for its whole
lifetime while the main window's WindowClosing hook hides instead of
closing, so the dialog promise can outlive the click — and even a clean
dismissal kept the guards held until the promise settled. Until then
every later Connect click and tray trigger-login was silently dropped at
the guard check, so the only way back was a client restart.

Release both guards the instant the flow itself settles, before the
dialog: startLogin now takes an onSettled callback fired in its finally
(driveLogin releases loginGuard through it), and the errorDialog await
moved out of the try/finally so no guard is ever gated on the dialog.
2026-06-04 13:42:29 +02:00
Zoltán Papp
93e068f753 [client/ui] Honour DEV=true in windows:build:console for DevTools
windows:build:console fixed -tags production, which disables the
WebKit/WebView2 DevTools inspector — so there was no way to get a
console-attached Windows binary with the frontend JS console reachable.
Mirror build:native's DEV handling: DEV=true drops the production tag
while keeping the console subsystem (no -H windowsgui).
2026-06-04 13:21:41 +02:00
Zoltán Papp
94065a8058 [client/ui] Enable tray status row on Linux to avoid greyed-out indicator
The informational status row at the top of the tray menu was disabled on
Linux, which painted the connection-status indicator greyed-out. Enable
it on Linux so the row renders at full opacity; it has no OnClick handler
so clicking it remains a no-op.
2026-06-04 11:42:22 +02:00
Eduard Gert
64199209cf add onboarding 2026-06-03 17:33:13 +02:00
Eduard Gert
1710868a09 add exit node switcher 2026-06-02 17:23:56 +02:00
Zoltán Papp
7798b7cf14 [client/ui] Disable WebKit compositing on Linux to avoid Intel/Mesa SIGSEGV
WebKitGTK's accelerated GL compositor crashes with a SIGSEGV inside
g_application_run on some Intel setups, hitting Mesa anv/i965 code paths
for DRM format modifiers that aren't implemented (FINISHME: YUV
colorspace / multi-planar formats). Disabling the DMA-BUF renderer alone
doesn't cover the GL compositor, so the crash survived that workaround.

Set WEBKIT_DISABLE_COMPOSITING_MODE=1 in init() (skipped if the user
already set it) to force CPU rendering, which is fine for a UI this
small and sidesteps the broken modifier path.
2026-06-02 15:10:45 +02:00
Zoltán Papp
179966b000 [client/ui] Detect KDE panel dark mode from kdeglobals Complementary colour
Split Linux panel-theme detection into two files and fix the KDE case
where the tray icon picked the wrong mono variant.

The freedesktop Settings portal's color-scheme reports the *global*
light/dark preference, but the KDE panel is painted from the
Complementary colour group, which can be dark even when the global
scheme is Light. The tray sits on the panel, so keying its black/white
mono icon off the portal value alone gave the wrong contrast on KDE.

Changes:
  - tray_theme_linux.go keeps the dark/light decision; on KDE it now
    reads the user's kdeglobals [Colors:Complementary] BackgroundNormal
    to determine the actual panel luminance, falling back to the portal
    color-scheme / GTK_THEME chain elsewhere.
  - tray_theme_watcher_linux.go (new) owns the live half: a private
    session-bus connection for the portal SettingChanged signal plus an
    fsnotify watch on kdeglobals, repainting the tray on a panel-theme
    flip.
  - tray_theme_linux_test.go (new) covers the kdeglobals Complementary
    parse against the KDE test-VM's real file layout.
2026-06-02 14:29:45 +02:00
Eduard Gert
48265a0143 add profile switch into settings, scroll to top after profile switch, add netbird icon to linux windows 2026-06-02 14:20:36 +02:00
Zoltán Papp
9a76507b14 [client/ui] Fix Linux package metadata and KDE Wayland icon association
Two Linux packaging issues, both surfaced by the netbird-ui deb/rpm
built from .goreleaser_ui.yaml.

1) License / vendor metadata
----------------------------
The nfpm entries for the UI package set only maintainer/description/
homepage, leaving the License and Vendor RPM/DEB tags empty. KDE
Discover (and GNOME Software) then render the package as
"Licenses: Unknown" / "Unknown author", with a scary license-warning
popup on install. The daemon's main .goreleaser.yaml already set
license (commit #5659) but never vendor, and the UI config was skipped
entirely.

Fix: add `license: BSD-3-Clause` + `vendor: NetBird` to both UI nfpm
entries (deb + rpm), and `vendor: NetBird` to the daemon's deb + rpm
entries for consistency. BSD-3-Clause is correct for client/ui — the
repo is BSD-3-Clause except management/, signal/, relay/, combined/
(AGPLv3), none of which the UI touches.

2) KDE Wayland window/taskbar icon
----------------------------------
On KDE Plasma 6 under Wayland the app launched with the generic Wails
icon in the window titlebar and the taskbar / Alt-Tab switcher, even
though /usr/share/pixmaps/netbird.png (the launcher icon, resolved from
the desktop entry's `Icon=netbird`) was correct.

Root cause is how a Wayland compositor decides a window's icon. Unlike
X11 there is no per-window _NET_WM_ICON the app can push at runtime —
GTK4 even removed gtk_window_set_icon, so the embedded assets/netbird.png
the binary carries is simply ignored. Instead the compositor matches the
window's Wayland **app_id** to an installed .desktop file and uses that
entry's `Icon=` key.

The app_id is not "netbird": Wails hardcodes it as `org.wails.<name>`
(pkg/application/linux_cgo.go: `fmt.Sprintf("org.wails.%s", name)`, name
= sanitized Options.Name), yielding **org.wails.netbird**. There is no
Wails option to override the prefix. Verified the live value on the
Fedora-40 / KDE 6.3 / Wayland test VM by dumping workspace.windowList()
via a KWin script:

    js: ZZZWIN org.wails.netbird ## NetBird

KDE needs two things to associate the running window with our desktop
entry and thus paint our icon:
  - the desktop entry's basename should equal the app_id, so the
    titlebar decoration (which looks the entry up by app_id ->
    <app_id>.desktop) finds it, and
  - a `StartupWMClass=<app_id>` line, which the taskbar / task switcher
    use to map the surface to the entry.

Fix (no Wails fork needed — app_id stays org.wails.netbird, which the
user never sees; only Name=NetBird and the icon are visible):
  - install the desktop file as `org.wails.netbird.desktop` instead of
    `netbird.desktop` (both deb and rpm contents in .goreleaser_ui.yaml)
  - add `StartupWMClass=org.wails.netbird` to
    client/ui/build/linux/netbird.desktop

`Icon=netbird` and the pixmaps/netbird.png payload are unchanged — they
were already correct. Confirmed on the test VM that both the titlebar
and taskbar/Alt-Tab now show the NetBird icon.
2026-06-02 12:52:24 +02:00
Eduard Gert
c3a0c1beeb update language switcher, remove flags 2026-06-02 12:36:29 +02:00
Eduard Gert
45095818bc update paddings and icons 2026-06-02 12:04:55 +02:00
braginini
1f74ee9c78 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-06-02 11:45:39 +02:00
braginini
562a538e91 fix(tray): round session-remaining to nearest hour/day 2026-06-02 11:45:29 +02:00
Eduard Gert
50b26a21fd Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-06-02 11:38:03 +02:00
Eduard Gert
fefd0da7bf Adjust peers and resources tabs 2026-06-02 11:37:56 +02:00
braginini
d1f3d88f0d Rephrase session expiration 2026-06-02 11:37:48 +02:00
Zoltán Papp
a71ef1bab0 [client/ui] Guard session expiry updates to log only on change 2026-06-02 11:09:20 +02:00
Zoltán Papp
072d789463 client/ui: retry XEmbed-tray probe before claiming SNI watcher
The XEmbed tray (panel) can come up after the autostarted UI on minimal
WMs, so the single startup probe added in #6320 could miss a tray that
appears a second or two later, leaving the icon silently absent. Re-probe
for a ~10s grace period in a goroutine, claiming the watcher as soon as a
tray shows up; back off cleanly if none ever appears (headless/Wayland).
2026-06-01 21:55:04 +02:00
Pascal Fischer
8d05fe07bf Fix watcher registration on wayland (#6320)
* Fix hover label on linux

* Fix watcher registration on wayland
2026-06-01 21:48:39 +02:00
Zoltán Papp
4cee07bef5 client/ui: use monochrome tray icons on Linux
Linux now shows monochrome (black/white silhouette) tray icons instead
of the colored orange PNGs, matching the macOS template look. Since
Wails' Linux SNI backend ignores SetDarkModeIcon (its setDarkModeIcon
just calls setIcon, last-write-wins) and the SNI spec carries no panel
light/dark hint, the panel color scheme is detected in-process and the
black-vs-white silhouette is chosen in iconForState, pushed via a single
SetIcon.

Detection order (tray_theme_linux.go): freedesktop Settings portal
(org.freedesktop.appearance/color-scheme) -> GTK_THEME env (:dark
suffix) -> default dark. A SettingChanged subscription repaints live on
theme flips. macOS (template) and Windows (colored) paths are unchanged.

Icons are 48x48 mono PNGs (3% margin) generated from the macOS
silhouettes.
2026-06-01 20:23:46 +02:00
Zoltán Papp
5bebecc427 ui: disable WebKit sandbox when unprivileged userns are blocked
WebKitGTK crashes at startup when its bubblewrap sandbox can't create an
unprivileged user namespace (bwrap: setting up uid map: Permission denied
-> Failed to fully launch dbus-proxy -> panic in webkit_web_view_load_uri).
This happens in containers/VMs and on Ubuntu 24.04+ where AppArmor
restricts unprivileged user namespaces. Detect that the kernel blocks
userns via procfs and set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS so the
UI stays usable; honor an explicit user override either way.
2026-06-01 20:06:44 +02:00
Zoltán Papp
3dbd96b172 Add Version service exposing GUI version to frontend 2026-06-01 19:23:41 +02:00
Eduard Gert
6fe35cae83 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-06-01 17:50:38 +02:00
Eduard Gert
88bd1f91a8 update session expire dialog to account for hours, days etc. 2026-06-01 17:50:21 +02:00
Eduard Gert
acfd680560 remove icons from profile dropdown 2026-06-01 17:37:05 +02:00
Pascal Fischer
0b8aae4566 Fix hover label on linux (#6318) 2026-06-01 17:36:39 +02:00
Eduard Gert
daf9a74d8f update dialog error for connection switch 2026-06-01 17:18:31 +02:00