services

package
v0.78.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: BSD-3-Clause Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EventStatusSnapshot = "netbird:status"
	// EventDaemonNotification carries each SubscribeEvents message. Auto-update
	// SystemEvents are also forwarded to updater.Holder.OnSystemEvent so the typed
	// update state needs no second daemon subscription.
	EventDaemonNotification = "netbird:event"
	// EventProfileChanged fires after a daemon-side switch (payload: the new
	// ProfileRef). The daemon emits no profile event, so this is the only signal
	// that lets a flip driven from one surface paint in the others.
	EventProfileChanged = "netbird:profile:changed"
	// EventSessionWarning is a typed sibling of EventDaemonNotification so
	// subscribers needn't filter the notification firehose. Consumers branch on
	// SessionWarning.Final to tell the T-10 event from the T-2 fallback.
	EventSessionWarning = "netbird:session:warning"

	// StatusDaemonUnavailable is the synthetic Status emitted when the daemon's
	// gRPC socket is unreachable. No internal.Status* collides with this label.
	StatusDaemonUnavailable = "DaemonUnavailable"

	// Daemon connection status strings — mirror internal.Status* in
	// client/internal/state.go.
	StatusConnected      = "Connected"
	StatusConnecting     = "Connecting"
	StatusIdle           = "Idle"
	StatusNeedsLogin     = "NeedsLogin"
	StatusLoginFailed    = "LoginFailed"
	StatusSessionExpired = "SessionExpired"

	// SeverityCritical is the lower-cased proto SystemEvent_CRITICAL severity, as
	// emitted by systemEventFromProto. Critical events bypass the notifications gate.
	SeverityCritical = "critical"
)
View Source
const (
	FlagApplyPrivilegedSettings = "apply-privileged-settings"
	FlagDaemonAddr              = "daemon-addr"
	FlagProfile                 = "profile"
	FlagUser                    = "user"
	FlagLogLevel                = "log-level"
	FlagManagementURL           = "management-url"
	FlagAllowServerSSH          = "allow-server-ssh"
	FlagEnableSSHRoot           = "enable-ssh-root"
	FlagDisableSSHAuth          = "disable-ssh-auth"
)

The command line of the one-shot mode this binary runs itself in, elevated, to apply a setting the daemon restricts to root/administrator. The setting flags spell the same words as `netbird up`, so the command a user is shown and what runs behind the prompt read alike. Parsed in oneshot.go.

View Source
const (
	CodeElevationUnavailable = "elevation_unavailable"
	CodeElevationFailed      = "elevation_failed"
)

Error codes for the ways asking for privileges can fail.

View Source
const EventBrowserLoginCancel = "browser-login:cancel"

EventBrowserLoginCancel signals the user dismissed the BrowserLogin popup.

View Source
const EventSettingsOpen = "netbird:settings:open"

EventSettingsOpen tells the mounted settings window which tab to show.

View Source
const EventTriggerLogin = "trigger-login"

EventTriggerLogin asks the frontend's startLogin() to begin an SSO flow.

View Source
const EventWindowPainted = "netbird:window-painted"
View Source
const WindowHeight = 660

WindowHeight is shared by the main and Settings windows.

Variables

View Source
var WindowBackgroundColour = application.NewRGB(24, 26, 29) // bg-nb-gray-950

Functions

func AbortSessionEnd added in v0.75.1

func AbortSessionEnd()

func AppleMacOSAppearanceOptions

func AppleMacOSAppearanceOptions() application.MacWindow

AppleMacOSAppearanceOptions is the shared macOS chrome; FullScreenNone keeps the fixed-size layout.

func BeginSessionEnd added in v0.75.1

func BeginSessionEnd()

func BeginShutdown added in v0.75.1

func BeginShutdown()

func DialogWindowOptions

func DialogWindowOptions(name, title, url string, linuxIcon []byte) application.WebviewWindowOptions

DialogWindowOptions is the baseline for every auxiliary dialog window; callers override per-dialog.

func IsPrivilegedSettingsRun added in v0.78.0

func IsPrivilegedSettingsRun(args []string) bool

IsPrivilegedSettingsRun reports whether this process was started as the one-shot. The flag is a marker rather than a value, so only the bare forms count: reading a value would mean "--flag=false" started it too.

func LinuxAppearanceOptions

func LinuxAppearanceOptions(icon []byte) application.LinuxWindow

LinuxAppearanceOptions is the shared Linux chrome; opaque so fake-translucency compositors paint it.

func MicrosoftWindowsAppearanceOptions

func MicrosoftWindowsAppearanceOptions() application.WindowsWindow

MicrosoftWindowsAppearanceOptions is the shared Windows chrome (Mica + dark + custom title bar).

func RunPrivilegedSettings added in v0.78.0

func RunPrivilegedSettings(args []string, connect func(addr string) (proto.DaemonServiceClient, error)) int

RunPrivilegedSettings applies the requested settings and returns the process exit code. connect dials the daemon, which is the caller's business because only it knows how this build talks to it.

Everything it reports goes to stderr, which is what the parent captures where the platform lets it. On success it says so on standard output, because macOS gives the parent no exit status to read: see elevate.AppliedMarker.

func ShuttingDown added in v0.75.1

func ShuttingDown() bool

Types

type ActiveProfile

type ActiveProfile struct {
	// ID is the active profile's stable on-disk identity. Use it (not the
	// display name) as the handle for daemon requests and active-profile
	// comparisons, since names can collide.
	ID          string `json:"id"`
	ProfileName string `json:"profileName"`
	Username    string `json:"username"`
}

type Autostart

type Autostart struct {
	// contains filtered or unexported fields
}

Autostart facade over Wails' AutostartManager. The OS autostart entry registration is the single source of truth; nothing is mirrored to preferences.

func NewAutostart

func NewAutostart(mgr *application.AutostartManager) *Autostart

func (*Autostart) IsEnabled

func (a *Autostart) IsEnabled(_ context.Context) (bool, error)

IsEnabled returns false without error on unsupported platforms.

func (*Autostart) SetEnabled

func (a *Autostart) SetEnabled(_ context.Context, enabled bool) error

SetEnabled takes effect on the next login, not immediately.

func (*Autostart) Supported

func (a *Autostart) Supported(_ context.Context) bool

type ClientError

type ClientError struct {
	Code  string `json:"code"`
	Short string `json:"short"`
	Long  string `json:"long"`
	// Command is a command the user can run to complete the operation
	// themselves, set when the daemon refused it for want of privileges. The
	// frontend offers it for copying.
	Command string `json:"command,omitempty"`
}

ClientError is a structured error returned to the frontend. The frontend translates Code via i18n; Short is an English fallback; Long carries the unwrapped daemon message.

func (*ClientError) Error

func (e *ClientError) Error() string

Error returns the short message for plain Go callers.

func (*ClientError) MarshalJSON

func (e *ClientError) MarshalJSON() ([]byte, error)

MarshalJSON emits the struct so the Wails binding sends an object, not the default "error: ..." string.

type Compat

type Compat struct {
	// contains filtered or unexported fields
}

Compat answers whether the running daemon is new enough to drive this UI.

func NewCompat

func NewCompat(conn DaemonConn) *Compat

func (*Compat) DaemonReady

func (c *Compat) DaemonReady(ctx context.Context) (bool, error)

DaemonReady probes the WailsUIReady RPC once. A true result means the daemon implements it and is compatible. An Unimplemented response means the daemon predates this UI and is too old; the caller should surface an upgrade prompt. Any other error (daemon not running, transport failure) is returned so the frontend can tell "outdated" apart from "not reachable".

type Config

type Config struct {
	ManagementURL                 string `json:"managementUrl"`
	AdminURL                      string `json:"adminUrl"`
	ConfigFile                    string `json:"configFile"`
	LogFile                       string `json:"logFile"`
	PreSharedKeySet               bool   `json:"preSharedKeySet"`
	InterfaceName                 string `json:"interfaceName"`
	WireguardPort                 int64  `json:"wireguardPort"`
	MTU                           int64  `json:"mtu"`
	DisableAutoConnect            bool   `json:"disableAutoConnect"`
	ServerSSHAllowed              bool   `json:"serverSshAllowed"`
	RosenpassEnabled              bool   `json:"rosenpassEnabled"`
	RosenpassPermissive           bool   `json:"rosenpassPermissive"`
	DisableNotifications          bool   `json:"disableNotifications"`
	BlockInbound                  bool   `json:"blockInbound"`
	NetworkMonitor                bool   `json:"networkMonitor"`
	DisableClientRoutes           bool   `json:"disableClientRoutes"`
	DisableServerRoutes           bool   `json:"disableServerRoutes"`
	DisableDNS                    bool   `json:"disableDns"`
	DisableIPv6                   bool   `json:"disableIpv6"`
	BlockLANAccess                bool   `json:"blockLanAccess"`
	EnableSSHRoot                 bool   `json:"enableSshRoot"`
	EnableSSHSFTP                 bool   `json:"enableSshSftp"`
	EnableSSHLocalPortForwarding  bool   `json:"enableSshLocalPortForwarding"`
	EnableSSHRemotePortForwarding bool   `json:"enableSshRemotePortForwarding"`
	DisableSSHAuth                bool   `json:"disableSshAuth"`
	SSHJWTCacheTTL                int32  `json:"sshJwtCacheTtl"`
}

type ConfigParams

type ConfigParams struct {
	ProfileName string `json:"profileName"`
	Username    string `json:"username"`
}

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

Connection groups the daemon RPCs that drive login / connect / disconnect.

func NewConnection

func NewConnection(conn DaemonConn, translator ErrorTranslator, prefs LanguagePreference) *Connection

NewConnection wires up a Connection. translator or prefs may be nil, in which case classifyDaemonError falls back to the bare error key.

func (*Connection) Down

func (s *Connection) Down(ctx context.Context) error

func (*Connection) Login

func (s *Connection) Login(ctx context.Context, p LoginParams) (LoginResult, error)

func (*Connection) Logout

func (s *Connection) Logout(ctx context.Context, p LogoutParams) error

func (*Connection) OpenURL

func (s *Connection) OpenURL(url string) error

OpenURL opens url in an external browser; the embedded webview blocks window.open, so the SSO verification page can't pop inline. Honors $BROWSER before the platform default.

func (*Connection) Up

func (s *Connection) Up(ctx context.Context, p UpParams) error

func (*Connection) WaitSSOLoginAndUp

func (s *Connection) WaitSSOLoginAndUp(ctx context.Context, wait WaitSSOParams, up UpParams) (string, error)

WaitSSOLoginAndUp blocks until the SSO login completes and then brings the connection up, both from the Go side. Keeping the post-login Up here rather than as a frontend continuation is deliberate: during SSO the tray window is hidden and the webview is suspended (macOS App Nap / hidden-window timer throttling), so a frontend-driven Up would not run until the user woke the window (e.g. by hovering the tray icon). Doing it in Go connects the moment the daemon reports SSO success. Returns the authenticated user's email.

type DaemonConn

type DaemonConn interface {
	Client() (proto.DaemonServiceClient, error)
}

DaemonConn returns a lazy gRPC client to the NetBird daemon. All services receive a DaemonConn so they share a single connection.

type DaemonFeed

type DaemonFeed struct {
	// contains filtered or unexported fields
}

DaemonFeed fans the daemon's two long-running gRPC streams (SubscribeStatus, SubscribeEvents) out to the frontend and tray, and exposes a one-shot Status RPC for callers wanting the current snapshot without subscribing.

Profile-switch suppression: BeginProfileSwitch makes statusStreamLoop swallow the transient stale Connected and Idle pushes the daemon emits during Down, so consumers see Connecting → new-profile-state instead of the full blink.

Two flags govern the switch lifecycle, evaluated independently by consumeForSwitch on every push because their lifetimes differ:

switchInProgress (suppression): clears on the first real push from the new
    Up. Daemon-side StatusConnecting comes BEFORE any NeedsLogin, so
    suppression must release here before the terminal arrives.
switchLoginWatch (trigger):     outlives suppression. Watches for NeedsLogin
    / LoginFailed / SessionExpired along the Up's retry loop and emits
    EventTriggerLogin so the React orchestrator opens browser-login.

┌────────────────────────────────────────────┬──────────────────────────────────┐
│ Incoming daemon status                     │ Action                           │
├────────────────────────────────────────────┼──────────────────────────────────┤
│ Connected, Idle (while switchInProgress)   │ Suppress (the blink we hide)     │
│ Connecting                                 │ Emit, clear switchInProgress     │
│ NeedsLogin, LoginFailed, SessionExpired    │ Emit, clear both flags, also     │
│                                            │   emit EventTriggerLogin         │
│ Connected, Idle (while only login-watch)   │ Emit, clear switchLoginWatch     │
│ DaemonUnavailable                          │ Emit, clear both flags           │
│ (timeout elapsed)                          │ Clear flags, emit normally       │
└────────────────────────────────────────────┴──────────────────────────────────┘

func NewDaemonFeed

func NewDaemonFeed(conn DaemonConn, emitter Emitter, updaterHolder *updater.Holder, logCtl LogController) *DaemonFeed

NewDaemonFeed builds the feed. logCtl may be nil (server build / GUI log not managed), in which case log-level markers on the event stream are ignored.

func (*DaemonFeed) BeginProfileSwitch

func (s *DaemonFeed) BeginProfileSwitch()

BeginProfileSwitch arms suppression for a switch from Connected/Connecting, where the daemon emits stale Connected updates during Down's teardown then an Idle before the new Up; statusStreamLoop drops those, and a synthetic Connecting snapshot is emitted so consumers paint optimistically. A 30s safety timeout clears the flag if no follow-up status arrives.

func (*DaemonFeed) CancelProfileSwitch

func (s *DaemonFeed) CancelProfileSwitch()

CancelProfileSwitch aborts a switch midway (tray Disconnect while Connecting): clears suppression so the next daemon Idle paints through, and disarms the login-watch so the abort doesn't pop a browser-login after the user cancelled.

func (*DaemonFeed) Get

func (s *DaemonFeed) Get(ctx context.Context) (Status, error)

Get returns the current daemon status snapshot. An unreachable daemon socket yields Status{Status: StatusDaemonUnavailable} rather than an error, so the frontend keys off a single status enum without a parallel "error" path.

func (*DaemonFeed) ServiceShutdown

func (s *DaemonFeed) ServiceShutdown() error

ServiceShutdown is the Wails service hook fired on app exit.

func (*DaemonFeed) Watch

func (s *DaemonFeed) Watch(ctx context.Context)

Watch starts the two background stream loops. Idempotent (a second call while running is a no-op); both loops self-restart via exponential backoff.

type Debug

type Debug struct {
	// contains filtered or unexported fields
}

func NewDebug

func NewDebug(conn DaemonConn) *Debug

func (*Debug) Bundle

func (*Debug) GetLogLevel

func (s *Debug) GetLogLevel(ctx context.Context) (LogLevel, error)

func (*Debug) RegisterUILog

func (s *Debug) RegisterUILog(ctx context.Context, path string) error

RegisterUILog reports the GUI log path to the daemon for bundle collection; the daemon runs as root and can't resolve the user's config dir. Called on each daemon (re)connect.

func (*Debug) RevealFile

func (s *Debug) RevealFile(_ context.Context, path string) error

RevealFile opens the OS file manager focused on path. Needed because Wails' Browser.OpenURL refuses non-http(s) schemes like file://.

func (*Debug) SetLogLevel

func (s *Debug) SetLogLevel(ctx context.Context, lvl LogLevel) error

func (*Debug) StartBundleCapture

func (s *Debug) StartBundleCapture(ctx context.Context, timeoutSeconds int32) error

func (*Debug) StopBundleCapture

func (s *Debug) StopBundleCapture(ctx context.Context) error

type DebugBundleParams

type DebugBundleParams struct {
	Anonymize bool `json:"anonymize"`
	// AnonymizeLevel is "default" or "strict"; strict also anonymizes
	// private IP ranges, peer names, and WireGuard public keys.
	AnonymizeLevel string `json:"anonymizeLevel"`
	SystemInfo     bool   `json:"systemInfo"`
	UploadURL      string `json:"uploadUrl"`
	LogFileCount   uint32 `json:"logFileCount"`
}

type DebugBundleResult

type DebugBundleResult struct {
	Path                string `json:"path"`
	UploadedKey         string `json:"uploadedKey"`
	UploadFailureReason string `json:"uploadFailureReason"`
}

DebugBundleResult: Path is set for local-only bundles, UploadedKey on upload success, UploadFailureReason on upload failure.

type Emitter

type Emitter interface {
	Emit(name string, data ...any) bool
}

Emitter sends a named payload to the frontend. Satisfied by Wails app.Event.

type ErrorTranslator

type ErrorTranslator interface {
	Translate(lang i18n.LanguageCode, key string, args ...string) string
}

ErrorTranslator localises daemon errors; runtime impl is *i18n.Bundle.

type ExtendResult

type ExtendResult = authsession.ExtendResult

Re-exports so generated bindings reference services.* without importing authsession.

type ExtendStartParams

type ExtendStartParams = authsession.ExtendStartParams

Re-exports so generated bindings reference services.* without importing authsession.

type ExtendStartResult

type ExtendStartResult = authsession.ExtendStartResult

Re-exports so generated bindings reference services.* without importing authsession.

type ExtendWaitParams

type ExtendWaitParams = authsession.ExtendWaitParams

Re-exports so generated bindings reference services.* without importing authsession.

type Features

type Features struct {
	DisableProfiles       bool `json:"disableProfiles"`
	DisableNetworks       bool `json:"disableNetworks"`
	DisableUpdateSettings bool `json:"disableUpdateSettings"`
}

type Forwarding

type Forwarding struct {
	// contains filtered or unexported fields
}

Forwarding groups the daemon RPCs that surface exposed/forwarded services.

func NewForwarding

func NewForwarding(conn DaemonConn) *Forwarding

func (*Forwarding) List

func (s *Forwarding) List(ctx context.Context) ([]ForwardingRule, error)

type ForwardingRule

type ForwardingRule struct {
	Protocol           string   `json:"protocol"`
	DestinationPort    PortInfo `json:"destinationPort"`
	TranslatedAddress  string   `json:"translatedAddress"`
	TranslatedHostname string   `json:"translatedHostname"`
	TranslatedPort     PortInfo `json:"translatedPort"`
}

ForwardingRule is one entry from the daemon's reverse-proxy table.

type GuardedSettings added in v0.78.0

type GuardedSettings struct {
	ProfileName      string `json:"profileName"`
	Username         string `json:"username"`
	ManagementURL    string `json:"managementUrl,omitempty"`
	ServerSSHAllowed *bool  `json:"serverSshAllowed,omitempty"`
	EnableSSHRoot    *bool  `json:"enableSshRoot,omitempty"`
	DisableSSHAuth   *bool  `json:"disableSshAuth,omitempty"`
}

GuardedSettings is the subset of the config the daemon restricts to root/administrator. Only the fields that are set are changed: a nil pointer, or an empty management URL, leaves that setting alone.

The management URL is in here because pointing a host with the SSH server running at another management identity hands the decision of who may open a shell on it to whoever runs that server, which is the same power as enabling the SSH server in the first place.

type I18n

type I18n struct {
	// contains filtered or unexported fields
}

I18n is the Wails-bound facade over i18n.Bundle; the translation logic lives in client/ui/i18n.

func NewI18n

func NewI18n(bundle *i18n.Bundle) *I18n

func (*I18n) Bundle

func (s *I18n) Bundle(_ context.Context, code i18n.LanguageCode) (map[string]string, error)

Bundle returns the full key->text map so the React side can drive its own translation library off the same source bundles.

func (*I18n) Languages

func (s *I18n) Languages(_ context.Context) ([]i18n.Language, error)

Languages returns the shipped locales.

type LanguagePreference

type LanguagePreference interface {
	Get() preferences.UIPreferences
}

LanguagePreference reports the current UI language; runtime impl is *preferences.Store.

type LanguageSubscriber

type LanguageSubscriber interface {
	Subscribe() (<-chan preferences.UIPreferences, func())
}

LanguageSubscriber delivers UI preference changes so window titles follow the language.

type LocalPeer

type LocalPeer struct {
	IP       string   `json:"ip"`
	IPv6     string   `json:"ipv6"`
	PubKey   string   `json:"pubKey"`
	Fqdn     string   `json:"fqdn"`
	Networks []string `json:"networks"`
}

LocalPeer mirrors LocalPeerState.

type LogController

type LogController interface {
	Apply(level string)
	Path() string
}

LogController is the subset of guilog.DebugLog that DaemonFeed drives: Apply turns the GUI file log on/off for a daemon level; Path is the gui-client.log path to register with the daemon (empty when the GUI doesn't own its log).

type LogLevel

type LogLevel struct {
	Level string `json:"level"`
}

LogLevel carries a logrus level name: "error", "warn", "info", "debug", "trace".

type LoginParams

type LoginParams struct {
	ProfileName   string `json:"profileName"`
	Username      string `json:"username"`
	ManagementURL string `json:"managementUrl"`
	SetupKey      string `json:"setupKey"`
	PreSharedKey  string `json:"preSharedKey"`
	Hostname      string `json:"hostname"`
	Hint          string `json:"hint"`
}

LoginParams are the inputs to Login.

type LoginResult

type LoginResult struct {
	NeedsSSOLogin           bool   `json:"needsSsoLogin"`
	UserCode                string `json:"userCode"`
	VerificationURI         string `json:"verificationUri"`
	VerificationURIComplete string `json:"verificationUriComplete"`
	// ProfileID is the ID of the profile this login ran against, or "" when the
	// caller named the profile itself and no ID was resolved. Pass it back in
	// WaitSSOParams so the account email lands on this profile even if the
	// active one changes during SSO.
	ProfileID string `json:"profileId"`
}

LoginResult is the daemon's reply to Login.

type LogoutParams

type LogoutParams struct {
	ProfileName string `json:"profileName"`
	Username    string `json:"username"`
}

LogoutParams selects the profile to log out.

type MDMFields

type MDMFields struct {
	ManagementURL            string `json:"managementURL"`
	PreSharedKey             bool   `json:"preSharedKey"`
	WireguardPort            bool   `json:"wireguardPort"`
	RosenpassEnabled         bool   `json:"rosenpassEnabled"`
	RosenpassPermissive      bool   `json:"rosenpassPermissive"`
	DisableClientRoutes      bool   `json:"disableClientRoutes"`
	DisableServerRoutes      bool   `json:"disableServerRoutes"`
	AllowServerSSH           *bool  `json:"allowServerSSH"`
	DisableAutoConnect       bool   `json:"disableAutoConnect"`
	DisableAutostart         bool   `json:"disableAutostart"`
	BlockInbound             bool   `json:"blockInbound"`
	DisableMetricsCollection bool   `json:"disableMetricsCollection"`
	SplitTunnelMode          bool   `json:"splitTunnelMode"`
	SplitTunnelApps          bool   `json:"splitTunnelApps"`
	DisableAdvancedView      bool   `json:"disableAdvancedView"`
}

type Network

type Network struct {
	ID          string              `json:"id"`
	Range       string              `json:"range"`
	Selected    bool                `json:"selected"`
	Domains     []string            `json:"domains"`
	ResolvedIPs map[string][]string `json:"resolvedIps"`
}

type Networks

type Networks struct {
	// contains filtered or unexported fields
}

func NewNetworks

func NewNetworks(conn DaemonConn) *Networks

func (*Networks) Deselect

func (s *Networks) Deselect(ctx context.Context, p SelectNetworksParams) error

func (*Networks) List

func (s *Networks) List(ctx context.Context) ([]Network, error)

func (*Networks) Select

type PeerLink struct {
	URL       string `json:"url"`
	Connected bool   `json:"connected"`
	Error     string `json:"error,omitempty"`
}

PeerLink is this peer's connection to its mgmt or signal server.

type PeerStatus

type PeerStatus struct {
	IP                         string   `json:"ip"`
	IPv6                       string   `json:"ipv6"`
	PubKey                     string   `json:"pubKey"`
	ConnStatus                 string   `json:"connStatus"`
	ConnStatusUpdateUnix       int64    `json:"connStatusUpdateUnix"`
	Relayed                    bool     `json:"relayed"`
	LocalIceCandidateType      string   `json:"localIceCandidateType"`
	RemoteIceCandidateType     string   `json:"remoteIceCandidateType"`
	LocalIceCandidateEndpoint  string   `json:"localIceCandidateEndpoint"`
	RemoteIceCandidateEndpoint string   `json:"remoteIceCandidateEndpoint"`
	Fqdn                       string   `json:"fqdn"`
	BytesRx                    int64    `json:"bytesRx"`
	BytesTx                    int64    `json:"bytesTx"`
	LatencyMs                  int64    `json:"latencyMs"`
	RelayAddress               string   `json:"relayAddress"`
	LastHandshakeUnix          int64    `json:"lastHandshakeUnix"`
	RosenpassEnabled           bool     `json:"rosenpassEnabled"`
	Networks                   []string `json:"networks"`
}

PeerStatus is the frontend-facing shape of a daemon PeerState.

type PortInfo

type PortInfo struct {
	Port  *uint32    `json:"port,omitempty"`
	Range *PortRange `json:"range,omitempty"`
}

PortInfo holds exactly one of Port or Range (the daemon's oneof).

type PortRange

type PortRange struct {
	Start uint32 `json:"start"`
	End   uint32 `json:"end"`
}

PortRange is a port range; both ends are inclusive.

type Preferences

type Preferences struct {
	// contains filtered or unexported fields
}

Preferences is the Wails-bound facade over preferences.Store; the context.Context-first signatures are what the binding generator requires.

func NewPreferences

func NewPreferences(store *preferences.Store) *Preferences

func (*Preferences) Get

func (*Preferences) SetKeepConnectedOnQuit added in v0.76.2

func (s *Preferences) SetKeepConnectedOnQuit(_ context.Context, keep bool) error

func (*Preferences) SetLanguage

func (s *Preferences) SetLanguage(_ context.Context, lang i18n.LanguageCode) error

func (*Preferences) SetOnboardingCompleted

func (s *Preferences) SetOnboardingCompleted(_ context.Context, done bool) error

func (*Preferences) SetViewMode

func (s *Preferences) SetViewMode(_ context.Context, mode preferences.ViewMode) error

type Privilege added in v0.76.0

type Privilege struct {
	Privileged bool `json:"privileged"`
	// ActorKey identifies the principal the operation requires without wording it,
	// so the frontend can name it in the user's language: see
	// ipcauth.PrivilegedActorKey. The words are not sent, because English ones
	// cannot be dropped into a translated sentence.
	ActorKey string `json:"actorKey"`
	// CanElevate reports whether a guarded control can offer to authorize the
	// change through the platform's own prompt: see SetGuardedSettings.
	CanElevate bool `json:"canElevate"`
	// Commands equivalent to the settings the daemon guards, ready to copy.
	AllowSSHServer string `json:"allowSshServer"`
	EnableSSHRoot  string `json:"enableSshRoot"`
	DisableSSHAuth string `json:"disableSshAuth"`
}

Privilege tells the frontend whether this process may perform the changes the daemon restricts to root/administrator, whether it can ask the operating system for the privileges instead, and the command for each so a control that can do neither can still show the way.

type Profile

type Profile struct {
	// ID is the daemon-generated on-disk identity of the profile. Display
	// names can collide and be renamed, so the ID is the stable handle the
	// daemon resolves switch/remove/logout requests against.
	ID       string `json:"id"`
	Name     string `json:"name"`
	IsActive bool   `json:"isActive"`
	// Email is read from the user-owned per-profile state file (CLI writes it
	// after SSO login), not via ListProfiles: the daemon runs as root and can't
	// reach it, while the UI runs as the logged-in user.
	Email string `json:"email"`
}

type ProfileRef

type ProfileRef struct {
	ProfileName string `json:"profileName"`
	Username    string `json:"username"`
}

type ProfileSwitcher

type ProfileSwitcher struct {
	// contains filtered or unexported fields
}

ProfileSwitcher holds the switch policy shared by the tray and React frontend so both flip profiles identically. SwitchActive (plain selection: header dropdown, tray submenu) always connects after the switch; SwitchActiveNoConnect (manage-profiles screen) never does, so the user can still adjust the management URL before connecting. prevStatus from DaemonFeed.Get at entry only decides the teardown:

Connected/Connecting/NeedsLogin/LoginFailed/SessionExpired → Down first.
Idle → no Down.

func NewProfileSwitcher

func NewProfileSwitcher(profiles *Profiles, connection *Connection, feed *DaemonFeed) *ProfileSwitcher

func (*ProfileSwitcher) SwitchActive

func (s *ProfileSwitcher) SwitchActive(ctx context.Context, p ProfileRef) error

SwitchActive switches to the named profile and always connects afterwards.

func (*ProfileSwitcher) SwitchActiveNoConnect

func (s *ProfileSwitcher) SwitchActiveNoConnect(ctx context.Context, p ProfileRef) error

SwitchActiveNoConnect switches to the named profile without connecting, tearing down any existing connection first.

type Profiles

type Profiles struct {
	// contains filtered or unexported fields
}

func NewProfiles

func NewProfiles(conn DaemonConn) *Profiles

func (*Profiles) Add

func (s *Profiles) Add(ctx context.Context, p ProfileRef) (string, error)

Add creates a profile with the given display name and returns its daemon-generated on-disk ID, so callers can address the new profile by ID (e.g. to write config or switch to it) without re-resolving the name.

func (*Profiles) GetActive

func (s *Profiles) GetActive(ctx context.Context) (ActiveProfile, error)

func (*Profiles) List

func (s *Profiles) List(ctx context.Context, username string) ([]Profile, error)

func (*Profiles) Remove

func (s *Profiles) Remove(ctx context.Context, p ProfileRef) error

func (*Profiles) Rename

func (s *Profiles) Rename(ctx context.Context, p RenameProfileParams) (string, error)

Rename changes a profile's display name. The on-disk ID is unaffected, so the active profile and any ID-based references stay valid (the default profile can be renamed too — only its display name changes). Returns the profile's previous display name as confirmation.

func (*Profiles) Switch

func (s *Profiles) Switch(ctx context.Context, p ProfileRef) (string, error)

Switch sends a profile switch to the daemon and returns the resolved on-disk ID of the now-active profile. ProfileName is treated as a handle (exact ID, unique ID prefix, or unique display name); the daemon resolves it server-side and echoes back the canonical ID.

func (*Profiles) Username

func (s *Profiles) Username() (string, error)

Username returns the OS username the daemon expects for profile lookups.

type RenameProfileParams

type RenameProfileParams struct {
	// Handle selects the profile to rename: an exact ID, a unique ID prefix,
	// or a unique display name. The daemon resolves it server-side.
	Handle string `json:"handle"`
	// NewName is the new free-form display name. The daemon sanitizes it
	// (strips control characters, trims, caps length) but keeps spaces, emoji,
	// punctuation, and non-ASCII letters.
	NewName string `json:"newName"`

	Username string `json:"username"`
}

RenameProfileParams selects a profile by handle and carries its new display name.

type Restrictions

type Restrictions struct {
	MDM      MDMFields `json:"mdm"`
	Features Features  `json:"features"`
}

type SaveOutcome added in v0.78.0

type SaveOutcome struct {
	// Declined is set when the user dismissed the authorization prompt, or was
	// refused by policy. Nothing was changed.
	Declined bool `json:"declined"`
}

SaveOutcome reports what became of a change that needed authorization.

A declined prompt is a result, not an error: the user was asked and said no, so nothing was applied and nothing went wrong. Reporting it as an error would have every cancelled prompt logged as one.

type SelectNetworksParams

type SelectNetworksParams struct {
	NetworkIDs []string `json:"networkIds"`
	Append     bool     `json:"append"`
	All        bool     `json:"all"`
}

SelectNetworksParams: All targets every available network; Append merges IDs into the existing selection.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session wraps authsession.Session, exposing only the subset the React frontend calls; the tray uses authsession.Session directly, keeping the generated TS surface minimal.

func NewSession

func NewSession(inner *authsession.Session, translator ErrorTranslator, prefs LanguagePreference) *Session

NewSession wraps inner; the caller retains ownership and may use it directly. translator or prefs may be nil, in which case errors fall back to the bare code key.

func (*Session) RequestExtend

func (s *Session) RequestExtend(ctx context.Context, p ExtendStartParams) (ExtendStartResult, error)

RequestExtend starts the SSO session-extension flow; the result carries the verification URI to open.

func (*Session) WaitExtend

func (s *Session) WaitExtend(ctx context.Context, p ExtendWaitParams) (ExtendResult, error)

WaitExtend blocks until the RequestExtend flow completes; the deadline is nil when the peer is ineligible.

type SetConfigParams

type SetConfigParams struct {
	ProfileName                   string  `json:"profileName"`
	Username                      string  `json:"username"`
	ManagementURL                 string  `json:"managementUrl"`
	AdminURL                      string  `json:"adminUrl"`
	InterfaceName                 *string `json:"interfaceName,omitempty"`
	WireguardPort                 *int64  `json:"wireguardPort,omitempty"`
	MTU                           *int64  `json:"mtu,omitempty"`
	PreSharedKey                  *string `json:"preSharedKey,omitempty"`
	DisableAutoConnect            *bool   `json:"disableAutoConnect,omitempty"`
	ServerSSHAllowed              *bool   `json:"serverSshAllowed,omitempty"`
	RosenpassEnabled              *bool   `json:"rosenpassEnabled,omitempty"`
	RosenpassPermissive           *bool   `json:"rosenpassPermissive,omitempty"`
	DisableNotifications          *bool   `json:"disableNotifications,omitempty"`
	BlockInbound                  *bool   `json:"blockInbound,omitempty"`
	NetworkMonitor                *bool   `json:"networkMonitor,omitempty"`
	DisableClientRoutes           *bool   `json:"disableClientRoutes,omitempty"`
	DisableServerRoutes           *bool   `json:"disableServerRoutes,omitempty"`
	DisableDNS                    *bool   `json:"disableDns,omitempty"`
	DisableIPv6                   *bool   `json:"disableIpv6,omitempty"`
	DisableFirewall               *bool   `json:"disableFirewall,omitempty"`
	BlockLANAccess                *bool   `json:"blockLanAccess,omitempty"`
	EnableSSHRoot                 *bool   `json:"enableSshRoot,omitempty"`
	EnableSSHSFTP                 *bool   `json:"enableSshSftp,omitempty"`
	EnableSSHLocalPortForwarding  *bool   `json:"enableSshLocalPortForwarding,omitempty"`
	EnableSSHRemotePortForwarding *bool   `json:"enableSshRemotePortForwarding,omitempty"`
	DisableSSHAuth                *bool   `json:"disableSshAuth,omitempty"`
	SSHJWTCacheTTL                *int32  `json:"sshJwtCacheTtl,omitempty"`
}

SetConfigParams is a partial update — only non-nil pointer fields are sent to the daemon; nil fields are preserved.

type Settings

type Settings struct {
	// contains filtered or unexported fields
}

func NewSettings

func NewSettings(conn DaemonConn, translator ErrorTranslator, prefs LanguagePreference, daemonAddr string) *Settings

func (*Settings) GetConfig

func (s *Settings) GetConfig(ctx context.Context, p ConfigParams) (Config, error)

func (*Settings) GetRestrictions

func (s *Settings) GetRestrictions(ctx context.Context) (Restrictions, error)

func (*Settings) Privilege added in v0.76.0

func (s *Settings) Privilege() Privilege

Privilege reports whether this UI process could carry out the changes the daemon restricts to root/administrator, whether it can instead ask the operating system for the privileges when the user wants one of them, and the command that performs the ones users hit in the SSH settings. It applies the daemon's own rule to what it can see locally, so the frontend can decide up front how to present those controls instead of letting a save fail. No daemon round-trip, so it also works while the daemon is down.

Being root or an elevated administrator is one way. The other is running as the daemon's own user while the daemon is unprivileged, which the daemon accepts because such a caller can already rewrite the config it reads; that is the rootless-container and Windows netstack-mode case, and it is read from the ownership of the socket or pipe the daemon created.

func (*Settings) SetConfig

func (s *Settings) SetConfig(ctx context.Context, p SetConfigParams) (SaveOutcome, error)

func (*Settings) SetGuardedSettings added in v0.78.0

func (s *Settings) SetGuardedSettings(ctx context.Context, p GuardedSettings) (SaveOutcome, error)

SetGuardedSettings applies settings the daemon refuses from an unprivileged caller, by having the operating system run this binary again, elevated, to send the same request the frontend would have sent itself.

The user authorizes it at the platform's own prompt: the UAC consent dialog, the macOS authentication dialog, or the polkit agent's. Any credentials are the operating system's business; NetBird neither sees nor asks for them. Nothing about the daemon's rules changes, and the elevated process is authorized like any other privileged caller, from the identity the kernel reports for it.

A declined prompt comes back as SaveOutcome.Declined with no error. When there is no prompt to raise, or the elevated run failed, the error carries the command that does the same thing from a terminal.

type Status

type Status struct {
	Status        string        `json:"status"`
	DaemonVersion string        `json:"daemonVersion"`
	Management    PeerLink      `json:"management"`
	Signal        PeerLink      `json:"signal"`
	Local         LocalPeer     `json:"local"`
	Peers         []PeerStatus  `json:"peers"`
	Events        []SystemEvent `json:"events"`
	// NetworksRevision bumps whenever the daemon's routed-networks set or their
	// selected state changes, so consumers know when to re-fetch ListNetworks
	// instead of polling every snapshot.
	NetworksRevision uint64 `json:"networksRevision"`
	// SessionExpiresAt is the absolute UTC instant the SSO session expires; nil
	// when the peer is not SSO-tracked or login expiration is disabled.
	SessionExpiresAt *time.Time `json:"sessionExpiresAt,omitempty"`
}

Status is the snapshot the frontend renders on the dashboard.

type SystemEvent

type SystemEvent struct {
	ID          string            `json:"id"`
	Severity    string            `json:"severity"`
	Category    string            `json:"category"`
	Message     string            `json:"message"`
	UserMessage string            `json:"userMessage"`
	Timestamp   int64             `json:"timestamp"`
	Metadata    map[string]string `json:"metadata"`
}

SystemEvent is the frontend-facing shape of a daemon SystemEvent.

type UILog

type UILog struct{}

UILog forwards frontend console output into logrus, tagging the JS origin as the "ui" field to stay distinct from logrus's Go-caller source.

func NewUILog

func NewUILog() *UILog

func (*UILog) Log

func (s *UILog) Log(_ context.Context, level, source, msg string)

Log maps an unrecognised level to info; empty source becomes "unknown".

type UpParams

type UpParams struct {
	ProfileName string `json:"profileName"`
	Username    string `json:"username"`
}

UpParams selects the profile to bring up.

type Update

type Update struct {
	// contains filtered or unexported fields
}

Update is the Wails-bound facade over the daemon's update RPCs. The state machine and push event live in client/ui/updater.

func NewUpdate

func NewUpdate(conn DaemonConn, holder *updater.Holder) *Update

func (*Update) DownloadURL added in v0.75.1

func (s *Update) DownloadURL() string

DownloadURL returns the platform-appropriate installer download link for manual (non-enforced) updates.

func (*Update) GetInstallerResult

func (s *Update) GetInstallerResult(ctx context.Context) (UpdateResult, error)

func (*Update) GetState

func (s *Update) GetState() updater.State

func (*Update) Quit

func (s *Update) Quit()

Quit exits the app. Scheduled off the calling goroutine so the JS caller's response returns before the runtime tears down.

func (*Update) Trigger

func (s *Update) Trigger(ctx context.Context) (UpdateResult, error)

type UpdateResult

type UpdateResult struct {
	Success  bool   `json:"success"`
	ErrorMsg string `json:"errorMsg"`
}

UpdateResult mirrors TriggerUpdateResponse.

type Version

type Version struct{}

Version reports only the GUI's own version; the daemon version comes from the status feed's DaemonVersion field.

func NewVersion

func NewVersion() *Version

func (*Version) GUI

func (v *Version) GUI(_ context.Context) string

GUI returns the UI binary's version, stamped via ldflags ("development" if un-stamped).

type WaitSSOParams

type WaitSSOParams struct {
	UserCode string `json:"userCode"`
	Hostname string `json:"hostname"`
	// ProfileID is the profile the login was started for, used to file the
	// account email against it rather than against whichever profile is active
	// when the flow returns. Optional: empty falls back to the active profile.
	ProfileID string `json:"profileId"`
}

WaitSSOParams are the inputs to waitSSOLogin.

type WindowManager

type WindowManager struct {
	// contains filtered or unexported fields
}

func NewWindowManager

func NewWindowManager(app *application.App, mainWindow *application.WebviewWindow, translator ErrorTranslator, prefs LanguagePreference, linuxIcon []byte) *WindowManager

func (*WindowManager) BrowserLoginWindow

func (s *WindowManager) BrowserLoginWindow() *application.WebviewWindow

BrowserLoginWindow returns the live SSO popup, or nil. While non-nil it is the app's focal window: tray "Open" and dock activation hand off to it, not the main window.

func (*WindowManager) CloseBrowserLogin

func (s *WindowManager) CloseBrowserLogin()

func (*WindowManager) CloseError

func (s *WindowManager) CloseError()

func (*WindowManager) CloseInstallProgress

func (s *WindowManager) CloseInstallProgress()

func (*WindowManager) CloseRenewFlow

func (s *WindowManager) CloseRenewFlow()

CloseRenewFlow tears down the SSO session-renewal UI in a single call: it closes the browser-login popup and the session-expiration window together.

func (*WindowManager) CloseSessionExpiration

func (s *WindowManager) CloseSessionExpiration()

func (*WindowManager) CloseWelcome

func (s *WindowManager) CloseWelcome()

func (*WindowManager) ForgetMain added in v0.78.0

func (s *WindowManager) ForgetMain()

func (*WindowManager) InstallProgressWindow

func (s *WindowManager) InstallProgressWindow() *application.WebviewWindow

InstallProgressWindow returns the live install-progress window, or nil. Same focal-window contract as BrowserLoginWindow; install supersedes everything, so check this first.

func (*WindowManager) MainWindow added in v0.78.0

func (s *WindowManager) MainWindow() *application.WebviewWindow

func (*WindowManager) OpenBrowserLogin

func (s *WindowManager) OpenBrowserLogin(uri string)

OpenBrowserLogin shows the SSO popup, creating it on first use.

func (*WindowManager) OpenError

func (s *WindowManager) OpenError(title, message, command string)

OpenError shows the custom error dialog; title/message/command are pre-localised and ride in the start URL. command is optional and, when set, is offered for copying so the user can run the operation the daemon refused. A second error replaces the open one via SetURL. Singleton, destroyed on close.

func (*WindowManager) OpenInstallProgress

func (s *WindowManager) OpenInstallProgress(version string)

OpenInstallProgress shows the install-progress window and hides the rest for the duration (restored on close). It owns its own result polling since the daemon restarts mid-install.

func (*WindowManager) OpenMain

func (s *WindowManager) OpenMain()

OpenMain brings the main window forward; the welcome handoff uses it instead of the tray.

func (*WindowManager) OpenSessionExpiration

func (s *WindowManager) OpenSessionExpiration(seconds int, deadlineUnixMilli int64)

OpenSessionExpiration shows the countdown warning on the cursor's display; seconds seeds the countdown and deadlineUnixMilli (0 when unknown) is the absolute deadline the dialog compares renewal snapshots against. Singleton, destroyed on close.

func (*WindowManager) OpenSettings

func (s *WindowManager) OpenSettings(tab string)

OpenSettings shows the settings window on tab (empty → General), switching tab via EventSettingsOpen rather than SetURL (which would remount the provider tree).

func (*WindowManager) OpenWelcome

func (s *WindowManager) OpenWelcome()

OpenWelcome shows the first-launch onboarding window. Singleton, destroyed on close.

func (*WindowManager) SetMainFactory added in v0.78.0

func (s *WindowManager) SetMainFactory(f func(startURL string) *application.WebviewWindow)

func (*WindowManager) SetRecenterOnShow

func (s *WindowManager) SetRecenterOnShow(pred func() bool)

SetRecenterOnShow installs the recenterOnShow predicate (see the field).

func (*WindowManager) ShowMain

func (s *WindowManager) ShowMain()

ShowMain brings the main window forward (re-centering on minimal WMs). The single entry point every surface (tray, SIGUSR1, welcome) should use so centering applies uniformly.

func (*WindowManager) ShowMainAndEmit added in v0.78.0

func (s *WindowManager) ShowMainAndEmit(event string)

ShowMainAndEmit brings the main window forward and emits event once its frontend is ready.

func (*WindowManager) ShowMainAt added in v0.78.0

func (s *WindowManager) ShowMainAt(url string)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL