Commit Graph
53 Commits
Author SHA1 Message Date
Eduard Gert 7538a9a133 update window width and dialogs top padding on macos 2026-06-01 09:51:59 +02:00
Zoltan Papp 18348e1491 client+ui: remove SSO handoff flicker and clean up abandoned login via context
Two follow-ups to the "hold NeedsLogin during the SSO browser wait" change.
Both target the visible state churn the tray showed during the auto-login
handoff (Connect / profile-switch lands on NeedsLogin -> the UI's startLogin
kicks off the SSO flow) and the broken recovery after the user dismisses the
browser-login popup with the window's X.

Background
----------
When a connect attempt lands on NeedsLogin, the UI's startLogin() drives the
SSO flow: Connection.Login() -> (NeedsSSOLogin) open the browser-login popup
-> Connection.WaitSSOLogin() blocks until the browser leg completes. The tray
and the React status page both paint the raw daemon status, so any transient
state the daemon publishes during this handoff is visible as a flicker.

Previously the handoff churned the daemon status through
  NeedsLogin -> Idle -> Connecting -> NeedsLogin
which read as a flicker on the tray icon and the status dot. Two distinct
sources produced the two intermediate states:

  * Idle       came from the UI's defensive cli.Down() at the top of
                Connection.Login (services/connection.go): it tore the engine
                down before every login to dislodge a possibly-parked
                WaitSSOLogin, emitting a StatusIdle on the way.
  * Connecting  came from server.go Login() unconditionally setting
                StatusConnecting before deciding whether the request is an
                SSO flow (which immediately returns NeedsLogin) or a
                setup-key flow (which actually dials Management).

Changes
-------
1. server.go Login(): only set StatusConnecting on the setup-key path, where
   we are about to dial Management with the key and the Connecting paint is
   meaningful. The SSO path returns NeedsLogin and parks on the browser leg,
   so it no longer flashes Connecting first. Removes the Connecting blip.

2. services/connection.go Login(): drop the pre-Login cli.Down(). The daemon
   already dislodges a pending WaitSSOLogin at Login entry (actCancel), and an
   abandoned browser leg is now torn down by cancelling the WaitSSOLogin RPC
   (see 3/4). Removing the Down removes the Idle blip on every login.

3. MainConnectionStatusSwitch.tsx startLogin(): on cancel (the browser-login
   popup's Cancel button or its window X, both routed through
   EventBrowserLoginCancel), cancel the in-flight WaitSSOLogin gRPC call via
   waitPromise.cancel() instead of issuing a heavy Connection.Down(). The
   daemon ties the wait to this call's context, so cancelling the call ends
   the wait cleanly with no engine teardown and no Idle paint.

4. server.go WaitSSOLogin(): when the wait unblocks with context.Canceled and
   the cancellation came from our caller (callerCtx.Err() != nil — the client
   cancelled the RPC or went away), clear the cached oauthAuthFlow so a fresh
   Login starts a new device code instead of reusing the abandoned one. The
   entry NeedsLogin stays in place, so a reattaching client still shows the
   login affordance. An internal abort (actCancel fired by a newer
   Login/WaitSSOLogin while our callerCtx is still live) is left untouched so
   the new owner's flow is not clobbered.

Effect
------
The auto-login handoff now goes Connected -> Connecting -> NeedsLogin and
holds, with no Idle/Connecting flicker in between. Dismissing the browser-login
popup with X now recovers the same way as the Cancel button: the WaitSSOLogin
RPC is cancelled, the stale OAuth flow is cleared, and the next connect opens a
fresh browser-login window instead of getting stuck.
2026-05-31 04:26:15 +02:00
Zoltan Papp 8b03c96851 ui: add launch-at-login (autostart) toggle for the UI
Add an Autostart Wails service wrapping app.Autostart and a toggle in
the General settings tab. The OS login-item registration is the single
source of truth (nothing mirrored to the preferences file). Affects the
graphical UI only, not the daemon. The toggle hides itself on platforms
where autostart is unsupported.
2026-05-31 02:01:02 +02:00
Eduard Gert b0d8ac6489 fix auto size detection 2026-05-29 17:21:45 +02:00
Eduard Gert 0b19a99693 update ui for win11 2026-05-29 15:40:34 +02:00
Eduard Gert d0d7252c24 update settings bottom bar height 2026-05-29 14:25:36 +02:00
Eduard Gert 16570b3223 prevent content flash in settings 2026-05-29 13:43:48 +02:00
Zoltán Papp e94a4cbce5 session-extend: preempt previous WaitExtendAuthSession on new wait
When the tray "Extend now" notification action and the about-to-expire
dialog both start a flow for the same deadline, the daemon was running
two independent IdP polls and the older one surfaced an InvalidArgument
toast as soon as the second RequestExtend overwrote the pending flow.

Follow the WaitSSOLogin pattern: at the top of WaitExtendAuthSession
cancel the previous wait (the SetWaitCancel/CancelWait pair on
PendingFlow already existed but was unused), then register the new
wait's cancel. Preempted callers exit with codes.Canceled; the
authsession service translates that into ExtendResult{Preempted: true}
so the tray and the React dialog can stay silent on the losing flow
instead of showing a false-failure toast / error dialog.
2026-05-28 19:17:46 +02:00
Eduard Gert 51b243bdfa remove unused stuff, refactor frontend folder structure 2026-05-28 16:26:13 +02:00
Eduard Gert ac8d417c12 update exit node tab 2026-05-28 14:43:28 +02:00
Eduard Gert dccc0ebe4b update resources tab 2026-05-28 14:28:51 +02:00
Zoltan Papp 966fbec119 routemanager: enforce a single selected exit node
Exit nodes are mutually exclusive, but the RouteSelector stores routes with
default-on semantics, so every available exit node reported as selected at once.

Reconcile exit-node selection on each network map (and on runtime selection):
keep at most one selected — the user's persisted pick, else whatever management
marks for auto-apply (SkipAutoApply=false), else none. Never auto-activate an
exit node the map doesn't request; it stays off until the user picks it.

The server deselects sibling exit nodes when the user activates one (leaving
non-exit routes untouched), and the tray/React exit-node toggle now appends so
activating an exit node no longer wipes network-route selections.
2026-05-27 20:48:16 +02:00
Zoltan Papp f693d268b4 tray: selectable exit nodes + push-based network list refresh
Make the tray Exit Node submenu selectable (mutually exclusive, sourced from
ListNetworks by NetID) instead of read-only.

Add networksRevision to the status snapshot, bumped by the route manager on
network-map and selection changes, so the tray and the React NetworksContext
re-fetch ListNetworks via the push stream instead of polling. The peer-status
route list only carries chosen routes, so a candidate exit node appearing or
disappearing would otherwise never reach the UI.
2026-05-27 20:48:16 +02:00
Eduard Gert 09f4109b01 update peers ui 2026-05-27 18:01:06 +02:00
Eduard Gert b84c7618e7 fix viewmode height, update other ui stuff 2026-05-27 16:40:57 +02:00
Eduard Gert e62dff0f66 add github, docs links etc. to settings about page 2026-05-27 15:35:40 +02:00
Eduard Gert 0e83d2ad94 add peer details 2026-05-27 14:52:19 +02:00
Eduard Gert 67a1f3c4fe add peers, networks and exit node list (wip) 2026-05-26 12:09:08 +02:00
Eduard Gert b14feef1d7 add copy to clipboard 2026-05-26 11:23:08 +02:00
Eduard Gert 4818599a93 sort peers 2026-05-26 09:50:18 +02:00
Eduard Gert f8c107b087 update peers filter, fix duplicate url open in dev 2026-05-26 09:35:03 +02:00
Eduard Gert 513ecd456c remove mock peers 2026-05-22 16:28:24 +02:00
Eduard Gert 8f957ff41a fix scroll in settings 2026-05-22 16:09:55 +02:00
Eduard Gert 598fcbd817 remove unused lang icons, disable text selection 2026-05-22 15:59:27 +02:00
Eduard Gert 17a365926d update auto update wordings, add update available into ui 2026-05-22 13:04:04 +02:00
Eduard Gert 577ce6deb5 fix connect flow in tray 2026-05-22 10:16:13 +02:00
Eduard Gert df61f22d96 add error msg to profile context and auto update 2026-05-21 09:49:32 +02:00
Eduard Gert 32df29bbd4 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor
# Conflicts:
#	client/ui/frontend/src/screens/Update.tsx
2026-05-21 09:34:45 +02:00
Zoltan Papp d3b660afba classify daemon login errors and surface localised dialogs
The daemon returns gRPC errors whose message is a wrapped mgm + JWT
stack (e.g. "invalid jwt token, err: token could not be parsed: ...").
Showing that in a native dialog is unreadable. Connection now maps the
substrings it recognises to a ClientError{code, short, long} so the UI
can render a localised summary plus a Details: block carrying the raw
daemon text. formatErrorMessage on the TS side reads the structured
payload from Wails' Error.cause (or the JSON-stringified Error.message)
and falls back to plain Error.message for callers not yet migrated.

Also bumps Wails to v3.0.0-alpha.95.
2026-05-20 19:13:13 +02:00
Eduard Gert 414e7815e4 update default view icon, remove capitalize from profile name 2026-05-20 16:45:06 +02:00
Zoltán Papp ef6b4f7538 add SSO session extend flow
Adds an end-to-end SSO session-extension feature: the management server
publishes per-peer session deadlines on every Login/Sync, a new
ExtendAuthSession RPC refreshes the deadline using a fresh JWT without
tearing down the tunnel, and the daemon tracks the deadline locally so
the UI can fire a T-10min warning toast with an interactive "Extend now"
action.
2026-05-20 16:43:14 +02:00
Eduard Gert a7b26e3c0d add updating dialog 2026-05-20 16:20:40 +02:00
Eduard Gert 42534b24c5 fix scrollarea inside settings 2026-05-20 13:43:18 +02:00
Eduard Gert 620233a7ac update dropdown ui padding, remove unused stuff 2026-05-20 13:38:23 +02:00
Eduard Gert 1c15e9976b add profiles tab to settings 2026-05-20 13:17:13 +02:00
Eduard Gert 5b71a4f2ad update dialogs, hide main window on browser login, keep state as disconnected when needslogin 2026-05-18 16:31:59 +02:00
Eduard Gert 741ce8581d fix open settings in tray, prevent loading profiles when daemon is down 2026-05-18 13:07:34 +02:00
Zoltan Papp 6b44d65cac report daemon-down as DaemonUnavailable on initial Peers.Get and gate UI
- Peers.Get returns Status{Status: DaemonUnavailable} on Unavailable
  instead of an error so the React useStatus initial refresh picks up
  the same string the live event stream emits — the overlay no longer
  depends on receiving the synthetic event during boot.
- ProfileContext.refresh swallows Unavailable so the redundant
  "Load Profiles Failed" popup does not overlap the overlay.
- Tray Profiles submenu is disabled while the daemon is unavailable,
  matching the existing settings/debug/connect gating.
- gRPC client uses a 5s ConnectParams MaxDelay; the default 120s cap
  was keeping the SubChannel in backoff for tens of seconds after the
  daemon came back, masking the recovery.
2026-05-18 12:33:46 +02:00
Eduard Gert f84b1df857 remove unused import 2026-05-18 11:37:55 +02:00
Eduard Gert c24349e4f1 add overlay when daemon not available 2026-05-18 11:37:42 +02:00
Eduard Gert 7f7bee630f update about settings dev version, keep profile switch in sync between ui and tray 2026-05-18 10:56:27 +02:00
Eduard Gert 4e0eb9f2d4 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-05-18 10:41:12 +02:00
Eduard Gert 78fb15e327 update profile context 2026-05-18 10:39:32 +02:00
Zoltán Papp 7fae703a27 [client/ui] Port IPv6 toggle and paired default-route filter to Wails UI
Brings two main-side PRs' UI behavior across the Fyne→Wails rewrite:

- #5631 (IPv6 overlay support): add "Enable IPv6" row to the polished
  SettingsNetwork tab; the legacy screens/Settings.tsx already had it,
  but modules/settings/SettingsNetwork.tsx (the user-visible Settings
  window) was missing the toggle.
- #6150 (mirror v4 exit selection onto v6 pair): replace the literal
  "0.0.0.0/0" || "::/0" filter in screens/Networks.tsx with an
  isDefaultRoute() helper that handles the daemon's merged-range
  display string (e.g. "0.0.0.0/0, ::/0"), so paired v4/v6 exit
  nodes are classified correctly.
2026-05-18 10:25:18 +02:00
Eduard Gert 5bdccfe8f4 add i18n to frontend 2026-05-15 16:22:14 +02:00
Zoltan Papp 9d8eb76746 [client/ui] Replace update event fan-out with typed UpdateState API
The auto-update feature was driven by two narrow Wails events
(netbird:update:available and :progress) plus a SystemEvent-metadata
iteration on the React side. Both surfaces had to know the daemon
metadata schema (new_version_available, enforced, progress_window),
and the frontend had no pull endpoint to seed its state on mount.

Extract the state machine into a new client/ui/updater package, mirroring
how i18n and preferences are split between domain logic and a thin
services facade. The package owns the State type, the metadata-key
parsing, the mutex-guarded Holder, and the single netbird:update:state
event. services.Update keeps the daemon RPCs (Trigger, GetInstallerResult,
Quit) and gains GetState as a Wails pull endpoint.

Tray-side update behaviour moves out of tray.go into a dedicated
trayUpdater (tray_update.go): owns its menu item, OS notification,
click handler, and the /update window opener triggered by the
daemon's progress_window:show. tray.go drops three callbacks and four
fields, and reads hasUpdate through the updater.

Frontend ClientVersionContext now seeds from Update.GetState() and
subscribes to netbird:update:state; the status.events iteration and
metadata-key string literals are gone. UpdateAvailableBanner renders
only for the enforced && !installing branch and labels its action
"Install now"; UpdateVersionCard splits the install vs. download
branches by Enforced so the disabled flow routes to GitHub.
2026-05-15 13:31:17 +02:00
Eduard Gert 5411fa4350 remove old code, add german lang 2026-05-15 12:56:09 +02:00
Eduard Gert 1932b76f5b update stuff 2026-05-13 16:28:51 +02:00
Eduard Gert 1c8a6e3798 wip 2026-05-13 10:11:38 +02:00
Eduard Gert c8e18585c6 add update context 2026-05-11 17:21:38 +02:00