mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-08 09:49:54 +00:00
[client/ui-wails] Surface daemon SessionExpired in the tray
Port the Fyne UI's onSessionExpire 1:1 to the Wails tray so an SSO token expiry no longer leaves the user staring at a stale peer list. When applyStatus sees the transition into the daemon's StatusSessionExpired, fire a single OS notification (the lastStatus guard rate-limits it to the transition itself, mirroring the Fyne sendNotification flag) and bring the main window forward on the /login route so the frontend can drive the renewed SSO flow. The Fyne client achieved the same end with a runSelfCommand "login-url" helper; here the window is already in-process so we route to it directly.
This commit is contained in:
@@ -56,11 +56,18 @@ const (
|
||||
notifyErrorTitle = "Error"
|
||||
notifyErrorConnect = "Failed to connect"
|
||||
notifyErrorDisconnect = "Failed to disconnect"
|
||||
notifySessionExpiredTitle = "NetBird session expired"
|
||||
notifySessionExpiredBody = "Your NetBird session has expired. Please log in again."
|
||||
|
||||
// Notification IDs (used to coalesce duplicate toasts).
|
||||
notifyIDUpdatePrefix = "netbird-update-"
|
||||
notifyIDEvent = "netbird-event-"
|
||||
notifyIDTrayError = "netbird-tray-error"
|
||||
notifyIDUpdatePrefix = "netbird-update-"
|
||||
notifyIDEvent = "netbird-event-"
|
||||
notifyIDTrayError = "netbird-tray-error"
|
||||
notifyIDSessionExpired = "netbird-session-expired"
|
||||
|
||||
// Daemon status string for an SSO session that has expired and needs
|
||||
// re-authentication. Mirrors internal.StatusSessionExpired.
|
||||
statusSessionExpired = "SessionExpired"
|
||||
|
||||
// External URLs.
|
||||
urlGitHubRepo = "https://github.com/netbirdio/netbird"
|
||||
@@ -405,6 +412,13 @@ func (t *Tray) applyStatus(st services.Status) {
|
||||
t.mu.Lock()
|
||||
connected := strings.EqualFold(st.Status, "Connected")
|
||||
iconChanged := connected != t.connected || st.Status != t.lastStatus
|
||||
// Detect the transition into SessionExpired: the daemon emits the
|
||||
// state on every Status snapshot for as long as the session stays
|
||||
// expired, so without this guard we would re-fire the notification
|
||||
// on every push. Mirrors the legacy Fyne client's sendNotification
|
||||
// flag in onSessionExpire.
|
||||
sessionExpiredEnter := strings.EqualFold(st.Status, statusSessionExpired) &&
|
||||
!strings.EqualFold(t.lastStatus, statusSessionExpired)
|
||||
t.connected = connected
|
||||
t.lastStatus = st.Status
|
||||
|
||||
@@ -428,6 +442,24 @@ func (t *Tray) applyStatus(st services.Status) {
|
||||
if exitNodesChanged {
|
||||
t.rebuildExitNodes(exitNodes)
|
||||
}
|
||||
if sessionExpiredEnter {
|
||||
t.handleSessionExpired()
|
||||
}
|
||||
}
|
||||
|
||||
// handleSessionExpired surfaces the SSO re-authentication path when the
|
||||
// daemon reports StatusSessionExpired. Posts a single OS notification
|
||||
// (the applyStatus guard ensures it fires only on the transition, not
|
||||
// on every status snapshot) and brings the main window forward so the
|
||||
// frontend's /login route can drive the renewed SSO flow. Mirrors the
|
||||
// Fyne client's onSessionExpire, which used a runSelfCommand to spawn
|
||||
// the login-url helper; here the window is already in-process.
|
||||
func (t *Tray) handleSessionExpired() {
|
||||
t.notify(notifySessionExpiredTitle, notifySessionExpiredBody, notifyIDSessionExpired)
|
||||
if t.window != nil {
|
||||
t.window.SetURL("/#/login")
|
||||
t.window.Show()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tray) rebuildExitNodes(nodes []string) {
|
||||
|
||||
Reference in New Issue
Block a user