Commit Graph

1531 Commits

Author SHA1 Message Date
Eduard Gert
13b4bf93b9 fix settings provider order 2026-06-11 14:34:20 +02:00
Eduard Gert
0d950d46f3 fix recenter? 2026-06-10 18:24:20 +02:00
Eduard Gert
4854e5d370 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-06-10 17:42:12 +02:00
Eduard Gert
cdcdd6a44f remove close animation from dialogs 2026-06-10 17:36:29 +02:00
Eduard Gert
7648aa7015 remove close animation from language picker 2026-06-10 16:58:52 +02:00
Eduard Gert
4b705d472c fix copy to clipboard for resources 2026-06-10 16:53:15 +02:00
Zoltán Papp
8a4e686098 [client] Fix tray notification crash on Linux
The Wails notifications service connects to the D-Bus session bus in its
ServiceStartup, which Wails runs synchronously inside app.Run. daemonFeed.Watch
was started before app.Run, so the first daemon SubscribeEvents message (which
replays the cached available-update state) fanned out to the tray's update-state
listener and fired an OS notification before that startup ran. The notifier's
*dbus.Conn was still nil, so SendNotification nil-dereferenced deep in godbus and
the panic was fatal to the whole process (observed on Linux Mint).

Move daemonFeed.Watch into the ApplicationStarted hook so it runs after the
service-startup loop, and route every notification send through a new
safeSendNotification helper that recovers from a panic and logs it, so a broken
or unavailable notification bus degrades to a skipped toast instead of crashing.
2026-06-10 16:49:12 +02:00
Eduard Gert
7eaea03bc9 hide password toggle for saved psk 2026-06-10 16:46:50 +02:00
Eduard Gert
eb788cad88 fix dynamic window height on linux 2026-06-10 16:37:07 +02:00
Zoltán Papp
439b85c584 [client] Forward frontend console logs through the standard logger
Use the shared logrus logger alias and carry the JS origin in a dedicated
"ui" log field instead of inlining a [ui ...] tag in the message, keeping
frontend logs distinct from the Go-caller source.
2026-06-10 16:06:26 +02:00
Eduard Gert
11281b681b fix unclassified errors 2026-06-10 09:54:48 +02:00
Zoltán Papp
6e9f4797e9 Merge branch 'main' into ui-refactor 2026-06-09 19:10:42 +02:00
Zoltán Papp
bbba18fc96 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-06-09 19:07:45 +02:00
Eduard Gert
d70b3a3fa4 update debug bundle text 2026-06-09 18:23:07 +02:00
Eduard Gert
dac2ca4088 fix dropdown animation 2026-06-09 18:08:47 +02:00
Eduard Gert
4e1e7f9518 add common languages 2026-06-09 18:04:59 +02:00
Eduard Gert
9049974f26 lint 2026-06-09 16:33:30 +02:00
Eduard Gert
f8e3ac6d92 refactor, lint, cleanup 2026-06-09 16:31:52 +02:00
Zoltán Papp
96d31c3a5a Align Linux UI packaging deps with Wails v3 GTK4 stack
The Wails v3 tray is a pure DBus StatusNotifierItem implementation and no
longer links libappindicator (a Fyne-era dependency). Drop the
libayatana-appindicator runtime and build deps, and move the rpm package
and dev-dependency docs onto the GTK4 / WebKitGTK 6.0 stack that the
default (non-gtk3) build actually links against.
2026-06-09 12:52:46 +02:00
Viktor Liu
d56859dc5d [client] Filter DNS fallback upstreams matching our server IP to prevent loops (#6183) 2026-06-09 12:26:03 +02:00
Eduard Gert
32be58cb24 add description to translations 2026-06-09 11:33:54 +02:00
Eduard Gert
aaa5dbb606 forward ui browser logs to go 2026-06-09 10:55:56 +02:00
Viktor Liu
106527182f [client] Snapshot iptables rule maps before persisting state (#6345) 2026-06-09 10:24:51 +02:00
Viktor Liu
8e1d5b78c2 [client] Preserve user deselect-all across management route sync (#6363) 2026-06-09 10:24:17 +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
Zoltán Papp
b598274424 [client/ui] Refresh profile list on CLI profile select
SwitchProfile now publishes the same profile-list-changed event that
AddProfile/RemoveProfile already emit. The daemon emits no dedicated
profile RPC event, and the React ProfileContext only refreshes on
EventProfileChanged (unlike the tray, which also re-fetches on every
status-string transition via loadProfiles). So a CLI-driven
"netbird down; profile select X; netbird up" refreshed the tray (the
down/up status flips trigger loadProfiles) but left the React profile
dropdown stale, since the select path never surfaced an event.

Publishing the marked INFO/SYSTEM event from SwitchProfile closes that
gap: dispatchSystemEvent re-emits EventProfileChanged, which
ProfileContext.refresh already subscribes to. No proto change.
2026-06-08 17:26:54 +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
Maycon Santos
60d2fa08b0 [client] Mask sensitive data in debug bundle creation (#6364)
* [client] Mask sensitive data in debug bundle creation

* Avoid nil reference in turn and use masked constant
2026-06-08 13:17:04 +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
1108808ab1 [client] Persist sync response only after network map is applied
Previously the SyncResponse was persisted to syncStore before
updateNetworkMap() ran. If applying the network map failed, the engine
persisted state it never applied, so GetLatestSyncResponse() could return
stale/unapplied state. Move the persistence into the post-apply success
path so the persisted response always reflects what the engine applied.
2026-06-04 18:31:37 +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