Merge branch 'main' into embedded-vnc

This commit is contained in:
Viktor Liu
2026-08-25 18:26:29 +02:00
439 changed files with 35257 additions and 5725 deletions
+31 -4
View File
@@ -60,8 +60,7 @@ func startClient(ctx context.Context, nbClient *netbird.Client) error {
// parseClientOptions extracts NetBird options from JavaScript object
func parseClientOptions(jsOptions js.Value) (netbird.Options, error) {
options := netbird.Options{
DeviceName: "dashboard-client",
LogLevel: defaultLogLevel,
LogLevel: defaultLogLevel,
}
if jwtToken := jsOptions.Get("jwtToken"); !jwtToken.IsNull() && !jwtToken.IsUndefined() {
@@ -91,13 +90,41 @@ func parseClientOptions(jsOptions js.Value) (netbird.Options, error) {
options.DeviceName = deviceName.String()
}
if disableIPv6 := jsOptions.Get("disableIPv6"); !disableIPv6.IsNull() && !disableIPv6.IsUndefined() {
options.DisableIPv6 = disableIPv6.Bool()
disableIPv6, err := boolOption(jsOptions, "disableIPv6")
if err != nil {
return options, err
}
if disableIPv6 != nil {
options.DisableIPv6 = *disableIPv6
}
// The caller decides whether this client uses lazy connections; left unset it
// defers to the management feature flag. A short-lived, interactive caller
// turns it off so its sessions reach the few peers their grant covers eagerly,
// instead of the first request waiting for the connection to be established.
lazyConnectionEnabled, err := boolOption(jsOptions, "lazyConnectionEnabled")
if err != nil {
return options, err
}
options.LazyConnectionEnabled = lazyConnectionEnabled
return options, nil
}
// boolOption reads a boolean option, returning nil when the caller left it out.
// js.Value.Bool panics on any other type, so a wrong type is reported instead.
func boolOption(jsOptions js.Value, name string) (*bool, error) {
v := jsOptions.Get(name)
if v.IsNull() || v.IsUndefined() {
return nil, nil
}
if v.Type() != js.TypeBoolean {
return nil, fmt.Errorf("option %s must be a boolean, got %s", name, v.Type())
}
b := v.Bool()
return &b, nil
}
// createStartMethod creates the start method for the client
func createStartMethod(client *netbird.Client) js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) any {
+64
View File
@@ -0,0 +1,64 @@
//go:build js
package main
import (
"syscall/js"
"testing"
)
// TestParseClientOptionsBooleans covers the boolean options against the value
// kinds a JS caller can pass: js.Value.Bool panics on anything but a boolean,
// so a wrong type has to be rejected before it reaches the client.
func TestParseClientOptionsBooleans(t *testing.T) {
t.Run("unset leaves the lazy override empty", func(t *testing.T) {
options, err := parseClientOptions(js.Global().Get("Object").New())
if err != nil {
t.Fatalf("parse options: %v", err)
}
if options.LazyConnectionEnabled != nil {
t.Errorf("lazy override should stay unset, got %v", *options.LazyConnectionEnabled)
}
if options.DisableIPv6 {
t.Error("disableIPv6 should default to false")
}
})
t.Run("null defers to the management flag", func(t *testing.T) {
jsOptions := js.Global().Get("Object").New()
jsOptions.Set("lazyConnectionEnabled", js.Null())
options, err := parseClientOptions(jsOptions)
if err != nil {
t.Fatalf("parse options: %v", err)
}
if options.LazyConnectionEnabled != nil {
t.Errorf("lazy override should stay unset, got %v", *options.LazyConnectionEnabled)
}
})
t.Run("booleans are carried through", func(t *testing.T) {
jsOptions := js.Global().Get("Object").New()
jsOptions.Set("lazyConnectionEnabled", false)
jsOptions.Set("disableIPv6", true)
options, err := parseClientOptions(jsOptions)
if err != nil {
t.Fatalf("parse options: %v", err)
}
if options.LazyConnectionEnabled == nil || *options.LazyConnectionEnabled {
t.Errorf("lazy override should be false, got %v", options.LazyConnectionEnabled)
}
if !options.DisableIPv6 {
t.Error("disableIPv6 should be true")
}
})
t.Run("a non-boolean is rejected", func(t *testing.T) {
for _, value := range []any{"true", 1, js.Global().Get("Object").New()} {
jsOptions := js.Global().Get("Object").New()
jsOptions.Set("lazyConnectionEnabled", value)
if _, err := parseClientOptions(jsOptions); err == nil {
t.Errorf("value %v should be rejected", value)
}
}
})
}