Commit Graph

3095 Commits

Author SHA1 Message Date
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
ad7d7fa881 change font weight 2026-05-27 17:03:31 +02:00
Eduard Gert
b84c7618e7 fix viewmode height, update other ui stuff 2026-05-27 16:40:57 +02:00
Eduard Gert
ec5da43d73 persist viewMode across restarts 2026-05-27 15:52:15 +02:00
Eduard Gert
a8ad73d2d9 add shortcuts in tray for quit and settings item 2026-05-27 15:37:05 +02:00
Eduard Gert
a241112a1d disable resize 2026-05-27 15:35:51 +02:00
Eduard Gert
e62dff0f66 add github, docs links etc. to settings about page 2026-05-27 15:35:40 +02:00
Eduard Gert
5cecca2c23 store viewmode in ui preferences 2026-05-27 15:21:51 +02:00
Eduard Gert
0e83d2ad94 add peer details 2026-05-27 14:52:19 +02:00
Zoltan Papp
004a305e46 tray: add 30s ticker to keep session-expiry countdown fresh 2026-05-27 00:33:09 +02:00
Zoltan Papp
c77e5cef85 tray: revert on-open click handler — OpenMenu freezes tray and React
Binding OnClick/OnRightClick to call OpenMenu() on macOS routes the menu
open through showMenu(), which runs the blocking [button mouseDown:] inside
a dispatched block on the serial main GCD queue. While the menu is open that
block never returns, starving every other main-queue task — both tray item
updates and the webview event delivery that drives React freeze until the
menu closes.

Revert to the pre-d9f0189 state: no click handlers bound, native NSStatusItem
auto-show for left-click, Wails default rightClickHandler for right-click.
refreshSessionExpiresLabel() is kept for the follow-up fix.
2026-05-27 00:24:46 +02:00
Zoltan Papp
13179081d2 Merge branch 'main' into ui-refactor 2026-05-26 23:41:18 +02:00
Zoltan Papp
2d3c8fc555 tray: drop dead iconMenuNetbird and openRoute after menu rework
The menu reorganisation removed the About brand-mark bitmap and rerouted
every openRoute caller to WindowManager auxiliary windows, leaving both
the iconMenuNetbird embed (all three platforms) and the openRoute helper
unreferenced. Remove them so the unused linter passes.
2026-05-26 23:25:45 +02:00
Zoltan Papp
61aa3a53ed tray: re-enable Exit Node menu item when candidates arrive post-connect
The parent Exit Node item's enablement was only refreshed on icon/status
transitions. The daemon ships peer routes in a later snapshot than the
Connected status text, so after a profile switch the candidate list flips
empty to non-empty while the status string is unchanged — leaving the item
greyed and the freshly painted rows unreachable. Re-evaluate enablement in
the exitNodesChanged branch too.
2026-05-26 23:15:03 +02:00
Zoltan Papp
80d6df6260 tray: rework menu layout, exit-node submenu, session countdown wording
- Reorder the menu: status, Connect/Disconnect, profile block, Open
  NetBird, Exit Node, then Settings… / Help & Support / Quit NetBird.
- Rename About → Help & Support, Quit → Quit NetBird, Settings → Settings…
  (ellipsis flags the window-opening action per the macOS HIG); drop the
  brand icon from Open NetBird; enable Documentation (opens docs.netbird.io)
  and add a Troubleshoot entry that deep-links the Settings window.
- Exit Node is now a submenu listing only peers that advertise a default
  route (0.0.0.0/0 or ::/0), sorted case-insensitively; the row stays
  visible but greyed when the tunnel is down or no candidate exists.
- Session row reads "Session expires in <n minutes/hours/days>" and
  recomputes on menu open so the countdown tracks wall time between the
  daemon's status pushes.
2026-05-26 23:15:03 +02:00
Zoltan Papp
53bbc2d551 session: clear stale SSO deadline on teardown and after expiry
The session deadline lived in two sinks kept in sync by hand:
ApplySessionDeadline wrote both the (engine-scoped) sessionwatch.Watcher
and the (server-scoped) peer.Status recorder. The clear paths only
touched the watcher, so the recorder — which is what the Status RPC /
SubscribeStatus snapshot the UI reads from — kept reporting a deadline
that had gone stale, surfacing as a frozen "expires in …" countdown.

Two cases were leaking:
- Profile switch / Down: the watcher is recreated per engine but the
  recorder outlives it, so a switch to a profile whose server sends no
  deadline left the previous profile's value in place.
- In-place expiry: the watcher arms warning timers at T-WarningLead and
  T-FinalWarningLead but nothing at the deadline itself, so once the
  moment passed the recorder kept the now-past value indefinitely.

Make the watcher the single writer of the recorder deadline (Update /
clearLocked / Close all route through SetSessionExpiresAt) so teardown
clears it, and guard GetSessionExpiresAt to report a past deadline as
none so in-place expiry stops painting a stale countdown.
2026-05-26 23:15:03 +02:00
Zoltan Papp
d9f0189b57 tray: reorganise menu, refresh expiry countdown on open
Layout changes:
- Drop "Debug Bundle" row; reach the flow via the in-window Settings UI.
- Move the brand-mark icon from the About row to "Open NetBird".
- Collapse Settings / Exit Node / About into a single block, with the
  Settings → Exit Node order swap to put the configuration entry first.
- Relocate Connect / Disconnect to the bottom block, sharing its
  separator with Quit. Drops the connectSeparator field + lastMenuItem
  helper that only existed to suppress the daemon-unavailable double
  separator in the old position.

Countdown freshness: the daemon's Status snapshots arrive too coarse to
keep a minute-grained "Expires in …" row honest while the menu is
closed. Wails v3 alpha 95 does not expose a public NSMenu needsUpdate
hook, so the tray binds OnClick / OnRightClick and recomputes the label
from cached sessionExpiresAt just before the menu paints. macOS and
Windows right-click additionally call OpenMenu() to restore the native
auto-show that binding the handler suppresses; Linux's dbusmenu host
paints the menu itself.
2026-05-26 23:15:03 +02:00
Bethuel Mmbaga
14af179556 [management] Refactor management server bootstrap (#6256) 2026-05-26 17:44:28 +03:00
Pascal Fischer
1fbb5e6d5d [management] fix owner role update (#6264) 2026-05-26 16:37:58 +02:00
Viktor Liu
6771e35d57 [client] Release js.FuncOf callbacks in wasm ssh and rdp to prevent leaks (#5982) 2026-05-26 14:32:39 +02:00
Eduard Gert
91e0520f27 move locales to client/ui/i18n 2026-05-26 12:34:01 +02:00
Eduard Gert
67a1f3c4fe add peers, networks and exit node list (wip) 2026-05-26 12:09:08 +02:00
Viktor Liu
e89b1e0596 [proxy, client] Bound embed client WireGuard per-Device memory (#5962) 2026-05-26 11:51:53 +02:00
Zoltan Papp
b6d20edfeb tray: show NetBird brand mark next to About on macOS
NSMenuItem rejected the dedicated netbird-menu-24.png brand mark
(rendered muddy) and the full 256x256 brand PNG (stretched the row).
Ship an 18x18 sips-downscale of assets/netbird.png — same source the
legacy Fyne client used for its About row — to sit visually alongside
the cap-height of the surrounding text.
2026-05-26 11:40:30 +02:00
Zoltan Papp
18d0019332 tray: drop Networks menu item, make session-expiry row open extend flow
Networks row removed from the tray; Exit Node remains the only routed-
state entry. Clicking the "Expires in …" row now opens the
SessionAboutToExpire window seeded with the actual remaining seconds, so
users can extend the SSO session proactively instead of waiting for the
daemon's T-FinalWarningLead auto-prompt.
2026-05-26 11:40:30 +02:00
Eduard Gert
ecee7df5d8 Merge remote-tracking branch 'origin/ui-refactor' into ui-refactor 2026-05-26 11:27:17 +02:00
Eduard Gert
1d783c33d9 adjust left offset in ip and fqdn 2026-05-26 11:26:51 +02:00
Eduard Gert
b14feef1d7 add copy to clipboard 2026-05-26 11:23:08 +02:00
Zoltán Papp
0935a5675d tray: move session-expiry row under profile email, hide separator when daemon unavailable
- Relocate the session-expiry row from below the status item to below the
  profile email so active profile, email, and session deadline form one block.
- Rename the label to "Expires in {remaining}" (en/hu/de).
- Capture the Connect/Disconnect separator via lastMenuItem and hide it when
  both action rows are hidden (daemon unavailable), avoiding two adjacent
  separators with nothing between them.
2026-05-26 10:59:36 +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
Philip Laine
d542c60e21 Refactor Linux system info to use syscalls (#6230) 2026-05-25 21:00:24 +02:00
Viktor Liu
4983b5cf17 [client] Match DNS wildcard handlers on label boundaries (#6255) 2026-05-25 18:38:48 +02:00
Viktor Liu
b3b0feb3b8 [client] Filter scoped/cloned default routes from BSD network monitor RTM_ADD (#6208) 2026-05-25 18:38:21 +02:00
Maycon Santos
7aebdd69dd [management, client, proxy] add expose NetBird-only services over tunnel peers (#6226)
Adds a new "private" service mode for the reverse proxy: services reachable exclusively over the embedded WireGuard tunnel, gated by per-peer group membership instead of operator auth schemes.

Wire contract
- ProxyMapping.private (field 13): the proxy MUST call ValidateTunnelPeer and fail closed; operator schemes are bypassed.
- ProxyCapabilities.private (4) + supports_private_service (5): capability gate. Management never streams private mappings to proxies that don't claim the capability; the broadcast path applies the same filter via filterMappingsForProxy.
- ValidateTunnelPeer RPC: resolves an inbound tunnel IP to a peer, checks the peer's groups against service.AccessGroups, and mints a session JWT on success. checkPeerGroupAccess fails closed when a private service has empty AccessGroups.
- ValidateSession/ValidateTunnelPeer responses now carry peer_group_ids + peer_group_names so the proxy can authorise policy-aware middlewares without an extra management round-trip.
- ProxyInboundListener + SendStatusUpdate.inbound_listener: per-account inbound listener state surfaced to dashboards.
- PathTargetOptions.direct_upstream (11): bypass the embedded NetBird client and dial the target via the proxy host's network stack for upstreams reachable without WireGuard.

Data model
- Service.Private (bool) + Service.AccessGroups ([]string, JSON- serialised). Validate() rejects bearer auth on private services. Copy() deep-copies AccessGroups. pgx getServices loads the columns.
- DomainConfig.Private threaded into the proxy auth middleware. Request handler routes private services through forwardWithTunnelPeer and returns 403 on validation failure.
- Account-level SynthesizePrivateServiceZones (synthetic DNS) and injectPrivateServicePolicies (synthetic ACL) gate on len(svc.AccessGroups) > 0.

Proxy
- /netbird proxy --private (embedded mode) flag; Config.Private in proxy/lifecycle.go.
- Per-account inbound listener (proxy/inbound.go) binding HTTP/HTTPS on the embedded NetBird client's WireGuard tunnel netstack.
- proxy/internal/auth/tunnel_cache: ValidateTunnelPeer response cache with single-flight de-duplication and per-account eviction.
- Local peerstore short-circuit: when the inbound IP isn't in the account roster, deny fast without an RPC.
- proxy/server.go reports SupportsPrivateService=true and redacts the full ProxyMapping JSON from info logs (auth_token + header-auth hashed values now only at debug level).

Identity forwarding
- ValidateSessionJWT returns user_id, email, method, groups, group_names. sessionkey.Claims carries Email + Groups + GroupNames so the proxy can stamp identity onto upstream requests without an extra management round-trip on every cookie-bearing request.
- CapturedData carries userEmail / userGroups / userGroupNames; the proxy stamps X-NetBird-User and X-NetBird-Groups on r.Out from the authenticated identity (strips client-supplied values first to prevent spoofing).
- AccessLog.UserGroups: access-log enrichment captures the user's group memberships at write time so the dashboard can render group context without reverse-resolving stale memberships.

OpenAPI/dashboard surface
- ReverseProxyService gains private + access_groups; ReverseProxyCluster gains private + supports_private. ReverseProxyTarget target_type enum gains "cluster". ServiceTargetOptions gains direct_upstream. ProxyAccessLog gains user_groups.
2026-05-25 17:41:50 +02:00
Eduard Gert
d624c2db74 fix i18n label 2026-05-22 16:36:07 +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
580cfa0dc5 add default and advanced resize 2026-05-22 09:53:08 +02:00
Zoltán Papp
8d4f35352f skip About-row brand mark on macOS
NSMenuItem.setImage stretches the row to the leading image's pixel
size regardless of the surrounding rows, so any non-empty bitmap on
the About entry made it visibly taller than the rest of the tray
menu — leaving 16, 18 or 22 px versions all looking wrong next to
the unadorned rows above and below.

Drop the macOS brand mark and gate the SetBitmap call on a non-empty
byte slice; iconMenuNetbird is now nil on macOS, so the About row
falls back to text only. Windows and Linux still ship the brand mark
through their per-platform embed files.
2026-05-21 17:01:08 +02:00
Zoltán Papp
85029898a5 per-platform tray menu icons and Windows-specific status row
The Windows menu renderer paints leading bitmaps into the Win32
check-mark slot (SetMenuItemBitmaps), which differs from how Cocoa
and GTK handle NSMenuItem.image / menu-row icons:

  - SM_CXMENUCHECK sizing: Windows expects ~16x16 at 100% DPI in the
    check-mark slot and visually overflows the row for anything bigger.
  - Disabled-state mask: Windows desaturates both the row text and the
    bitmap when MFS_DISABLED is set, so a disabled informational row
    renders the coloured status dot in greyscale.

Per the platform icon guidelines:

  Platform | Size           | Notes
  ---------|----------------|-----------------------------------------
  Windows  | 16x16          | check-mark slot, status row stays enabled
  macOS    | 22x22 (18-22)  | NSMenuItem leading image, HIG
  Linux    | 24x24 (22-48)  | GTK4 menu-row icon channel

Changes:

  * Split the menu-row icon embeds into icons_menu_{windows,darwin,linux}.go
    so each platform pulls its own size; the brand mark is rendered from
    assets/svg/netbird-menu.svg (new vector source) at 16/22/24 px with
    Inkscape, and the Windows status dots ship as 8x8 content centred on
    a 16x16 transparent canvas (the renderer upscales the bitmap, so the
    padding keeps the dot visually proportional to the row text).

  * Introduce statusRowEnabled() in tray_status_enabled_{windows,other}.go:
    true on Windows so the disabled-state mask does not strip the dot's
    colour; false on macOS/Linux where disabled menu rows fade the label
    without desaturating the leading bitmap, signalling that the row is
    informational.

  * Add an icon to the About submenu using the same brand mark.
2026-05-21 16:41:52 +02:00
Viktor Liu
0358be2313 [client] Revert "Clean up legacy 32-bit and HKCU registry entries on Windows install (#6176)" (#6232)
This reverts commit d927ef468a.
v0.71.4
2026-05-21 16:27:12 +02:00
Zoltán Papp
c3aeb5be15 force dark window theme on Windows 2026-05-21 14:59:00 +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