Resolve conflicts and complete the profile display-name -> ID migration
across the daemon, CLI, UI services, tray, and React frontend.
- Regenerate client/proto daemon.pb.go from the merged proto so it carries
both branches' RPCs (ui-refactor: SubscribeStatus/RegisterUILog/ExtendAuthSession,
main: RenameProfile + id fields); keep the v6.33.1 generator header
- server.go: combine ui-refactor's profile-list-changed events with main's
id-bearing responses; publish profile-list-changed on rename
- Drop the deleted Fyne client_ui.go/profile.go and port main's profile-ID
changes into the refactored services/tray
- UI services, tray and React: send the profile ID as the daemon handle and
keep the display name for rendering only (activeProfileId vs activeProfile)
- Relax the profile-name input to match the daemon's sanitizeDisplayName
(spaces, emoji, any valid UTF-8); cap at 128
- Expose RenameProfile via a Profiles.Rename services wrapper (+ regenerated
bindings) for the frontend to wire up
- cmd/login.go: use the profile ID for GetProfileState
Integrates main's MDM configuration-profile feature and adapts it to the
Wails UI (this branch had already replaced the Fyne UI).
Conflict resolution:
- go.mod/go.sum: take main's deps; howett.net/plist pinned to v1.0.2-... (tidy)
- client/proto/daemon.pb.go: regenerated from the merged daemon.proto
- client/internal/peer/status.go: union of ipToKey (main) + sessionExpiresAt (HEAD)
- client/server/server.go: main's intent/liveness model (connectionGoroutineRunning,
clientRunning no longer cleared by the goroutine) + empty-PSK guard
- client/ui/client_ui.go, client/ui/profile.go: removed (dead Fyne UI)
MDM port (backend + tray):
- services/settings.go: expose MDMManagedFields plus a managedFields map keyed
by Config field names so the settings form can gate a control without
translating mdm.Key* names
- tray: gate Profiles / Exit Node menus on DisableProfiles / DisableNetworks via
GetFeatures, refreshed on the config_changed system event (replaces the legacy
2s poll); localized MDM policy-applied toast in all shipped locales
- client/proto/metadata.go: shared constants for the config_changed /
policy_applied event markers
PreSharedKey: GetConfig now returns preSharedKeySet (bool) instead of the masked
value; the settings form provides its own placeholder and sends a new key only
when the user types one.
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.