mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-27 23:09:08 +01:00
[client] Fix browser dialog not closing on renew session flow
This commit is contained in:
@@ -73,6 +73,13 @@ export default function SessionExpirationDialog() {
|
|||||||
|
|
||||||
let offCancel: (() => void) | undefined;
|
let offCancel: (() => void) | undefined;
|
||||||
|
|
||||||
|
// Return the dialog to its interactive state and dismiss the browser popup
|
||||||
|
const resetDialog = () => {
|
||||||
|
offCancel?.();
|
||||||
|
WindowManager.CloseBrowserLogin().catch(console.error);
|
||||||
|
setBusy(false);
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const start = await Session.RequestExtend({ hint: "" });
|
const start = await Session.RequestExtend({ hint: "" });
|
||||||
const uri = start.verificationUriComplete || start.verificationUri;
|
const uri = start.verificationUriComplete || start.verificationUri;
|
||||||
@@ -105,25 +112,22 @@ export default function SessionExpirationDialog() {
|
|||||||
if (outcome.kind === "cancel") {
|
if (outcome.kind === "cancel") {
|
||||||
waitPromise.cancel?.();
|
waitPromise.cancel?.();
|
||||||
waitPromise.catch(() => {});
|
waitPromise.catch(() => {});
|
||||||
|
resetDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another surface owns this flow; keep the dialog open to retry.
|
// Another surface owns this flow; keep the dialog open to retry.
|
||||||
if (outcome.result.preempted) {
|
if (outcome.result.preempted) {
|
||||||
|
resetDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
WindowManager.CloseRenewFlow().catch(console.error);
|
||||||
// Close before the popup so the restore can't flash this window back.
|
|
||||||
WindowManager.CloseSessionExpiration().catch(console.error);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
resetDialog();
|
||||||
await errorDialog({
|
await errorDialog({
|
||||||
Title: t("sessionExpiration.extendFailedTitle"),
|
Title: t("sessionExpiration.extendFailedTitle"),
|
||||||
Message: formatErrorMessage(e),
|
Message: formatErrorMessage(e),
|
||||||
});
|
});
|
||||||
} finally {
|
|
||||||
offCancel?.();
|
|
||||||
WindowManager.CloseBrowserLogin().catch(console.error);
|
|
||||||
setBusy(false);
|
|
||||||
}
|
}
|
||||||
}, [busy, t]);
|
}, [busy, t]);
|
||||||
|
|
||||||
@@ -139,12 +143,11 @@ export default function SessionExpirationDialog() {
|
|||||||
});
|
});
|
||||||
WindowManager.CloseSessionExpiration().catch(console.error);
|
WindowManager.CloseSessionExpiration().catch(console.error);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
setBusy(false);
|
||||||
await errorDialog({
|
await errorDialog({
|
||||||
Title: t("sessionExpiration.logoutFailedTitle"),
|
Title: t("sessionExpiration.logoutFailedTitle"),
|
||||||
Message: formatErrorMessage(e),
|
Message: formatErrorMessage(e),
|
||||||
});
|
});
|
||||||
} finally {
|
|
||||||
setBusy(false);
|
|
||||||
}
|
}
|
||||||
}, [busy, t]);
|
}, [busy, t]);
|
||||||
|
|
||||||
|
|||||||
@@ -185,18 +185,12 @@ func (s *WindowManager) OpenBrowserLogin(uri string) {
|
|||||||
startURL = "/#/dialog/browser-login?uri=" + url.QueryEscape(uri)
|
startURL = "/#/dialog/browser-login?uri=" + url.QueryEscape(uri)
|
||||||
}
|
}
|
||||||
s.hideOtherWindowsLocked("browser-login")
|
s.hideOtherWindowsLocked("browser-login")
|
||||||
// Prefer the main window's screen (multi-monitor); falls back to OS-default centering.
|
|
||||||
var screen *application.Screen
|
|
||||||
if s.mainWindow != nil {
|
|
||||||
if sc, err := s.mainWindow.GetScreen(); err == nil {
|
|
||||||
screen = sc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opts := DialogWindowOptions("browser-login", s.title("window.title.signIn"), startURL, s.linuxIcon)
|
opts := DialogWindowOptions("browser-login", s.title("window.title.signIn"), startURL, s.linuxIcon)
|
||||||
// Not always-on-top: it would obscure the browser tab the user logs in through.
|
// Not always-on-top: it would obscure the browser tab the user logs in through.
|
||||||
opts.AlwaysOnTop = false
|
opts.AlwaysOnTop = false
|
||||||
opts.InitialPosition = application.WindowCentered
|
opts.InitialPosition = application.WindowCentered
|
||||||
opts.Screen = screen
|
// Open on the active (where users cursor is) display, like the session-expiration dialog.
|
||||||
|
opts.Screen = s.getScreenBasedOnCursorPosition()
|
||||||
s.browserLogin = s.app.Window.NewWithOptions(opts)
|
s.browserLogin = s.app.Window.NewWithOptions(opts)
|
||||||
bl := s.browserLogin
|
bl := s.browserLogin
|
||||||
// Red-X close means cancel: emit the event so startLogin() tears down the SSO wait.
|
// Red-X close means cancel: emit the event so startLogin() tears down the SSO wait.
|
||||||
@@ -207,15 +201,15 @@ func (s *WindowManager) OpenBrowserLogin(uri string) {
|
|||||||
s.restoreHiddenWindowsLocked()
|
s.restoreHiddenWindowsLocked()
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
})
|
})
|
||||||
s.centerWhenReady(s.browserLogin)
|
s.centerOnCursorScreen(s.browserLogin)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if uri != "" {
|
if uri != "" {
|
||||||
s.browserLogin.SetURL("/#/dialog/browser-login?uri=" + url.QueryEscape(uri))
|
s.browserLogin.SetURL("/#/dialog/browser-login?uri=" + url.QueryEscape(uri))
|
||||||
}
|
}
|
||||||
|
s.centerOnCursorScreen(s.browserLogin)
|
||||||
s.browserLogin.Show()
|
s.browserLogin.Show()
|
||||||
s.browserLogin.Focus()
|
s.browserLogin.Focus()
|
||||||
s.centerWhenReady(s.browserLogin)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BrowserLoginWindow returns the live SSO popup, or nil. While non-nil it is the
|
// BrowserLoginWindow returns the live SSO popup, or nil. While non-nil it is the
|
||||||
@@ -279,6 +273,36 @@ func (s *WindowManager) CloseSessionExpiration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 (s *WindowManager) CloseRenewFlow() {
|
||||||
|
s.mu.Lock()
|
||||||
|
bl := s.browserLogin
|
||||||
|
se := s.sessionExpiration
|
||||||
|
s.browserLogin = nil
|
||||||
|
s.sessionExpiration = nil
|
||||||
|
if se != nil {
|
||||||
|
kept := s.hiddenForLogin[:0]
|
||||||
|
for _, w := range s.hiddenForLogin {
|
||||||
|
if w != se {
|
||||||
|
kept = append(kept, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.hiddenForLogin = kept
|
||||||
|
}
|
||||||
|
s.mu.Unlock()
|
||||||
|
|
||||||
|
// Close the popup first (its WindowClosing restores the main window), then
|
||||||
|
// the session-expiration window. Both run after the unlock, so the
|
||||||
|
// re-entrant handlers can take s.mu without deadlocking.
|
||||||
|
if bl != nil {
|
||||||
|
bl.Close()
|
||||||
|
}
|
||||||
|
if se != nil {
|
||||||
|
se.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OpenInstallProgress shows the install-progress window and hides the rest for the duration
|
// 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.
|
// (restored on close). It owns its own result polling since the daemon restarts mid-install.
|
||||||
func (s *WindowManager) OpenInstallProgress(version string) {
|
func (s *WindowManager) OpenInstallProgress(version string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user