diff --git a/app/(main)/[locale]/login/page.tsx b/app/(main)/[locale]/login/page.tsx index 1b81ea206..bd29046e7 100644 --- a/app/(main)/[locale]/login/page.tsx +++ b/app/(main)/[locale]/login/page.tsx @@ -4,6 +4,7 @@ import { Suspense, useState, useEffect, useRef, useCallback, useId, useMemo } fr import { IS_DESKTOP_BUILD } from "@/lib/desktop/flag"; import { forgetDesktopServer, getDesktopBridge } from "@/lib/desktop/bridge"; import { customServerAllowedByDesktopPolicy, jmapServerAllowedByDesktopPolicy, useDesktopPolicy } from "@/lib/desktop/policy"; +import { accountRefusedByDesktopPolicy } from "@/lib/desktop/refused-accounts"; import { browserSignInAvailable, runDesktopBrowserSignIn } from "@/lib/desktop/browser-sign-in"; import { useRouter } from "@/i18n/navigation"; import { useParams, useSearchParams } from "next/navigation"; @@ -201,10 +202,15 @@ function LoginPageContent() { const params = useParams(); const searchParams = useSearchParams(); const isAddAccountMode = searchParams.get("mode") === "add-account"; - // Also when the app sent someone here because their server came off the list. - const [desktopPolicyNotice, setDesktopPolicyNotice] = useState( - searchParams.get("notice") === "server_refused" ? tDesktopPolicy("server_refused") : null, - ); + const [desktopPolicyNotice, setDesktopPolicyNotice] = useState(null); + // Whichever way someone got here: every account they have is on a server the device's + // OS policy refuses for now. They wait, and come back when it's allowed again. + useEffect(() => { + const stored = useAccountStore.getState().accounts; + if (stored.length > 0 && stored.every((account) => accountRefusedByDesktopPolicy(account, desktopPolicy))) { + setDesktopPolicyNotice(tDesktopPolicy("server_refused")); + } + }, [desktopPolicy, tDesktopPolicy]); // When the mobile app launches the webmail in a browser tab it tacks on // these params. We grab them once at mount and stash them in a ref so any diff --git a/stores/auth-store.ts b/stores/auth-store.ts index 6307b1e0d..5b10e2b78 100644 --- a/stores/auth-store.ts +++ b/stores/auth-store.ts @@ -3682,10 +3682,12 @@ function leaveForRefusedServer(): void { closePopoutWindow(); return; } - replaceWindowLocation(`${getLocaleLoginPath()}?notice=server_refused`); + replaceWindowLocation(getLocaleLoginPath()); } -const stoppedForPolicy = new Set(); +// What's refused now, as of this page's start too: a reload to the login page mustn't +// forget that an account is waiting, or it wouldn't come back when it's allowed again. +let refusedAccounts = new Set(); /** * The device's OS policy took a server off its list, or put one back. A refused account @@ -3698,7 +3700,6 @@ export function applyDesktopServerPolicy(): void { const accounts = useAccountStore.getState().accounts; const plan = planForRefusedAccounts(accounts, auth.activeAccountId, getDesktopPolicy()); for (const id of plan.stop) { - stoppedForPolicy.add(id); clearRefreshTimer(id); const client = clients.get(id); if (client) { @@ -3708,8 +3709,8 @@ export function applyDesktopServerPolicy(): void { } useAccountStore.getState().updateAccount(id, { isConnected: false }); } - const returned = [...stoppedForPolicy].filter((id) => !plan.refused.includes(id)); - for (const id of returned) stoppedForPolicy.delete(id); + const returned = [...refusedAccounts].filter((id) => !plan.refused.includes(id)); + refusedAccounts = new Set(plan.refused); if (plan.activeRefused) { if (plan.next) void auth.switchAccount(plan.next); @@ -3724,7 +3725,10 @@ export function applyDesktopServerPolicy(): void { if (returned.length > 0 && !auth.client) window.location.replace('/'); } -if (typeof window !== 'undefined') onDesktopPolicyChange(applyDesktopServerPolicy); +if (typeof window !== 'undefined') { + refusedAccounts = new Set(planForRefusedAccounts(useAccountStore.getState().accounts, null, getDesktopPolicy()).refused); + onDesktopPolicyChange(applyDesktopServerPolicy); +} // See canEnterLoginInPlace. let signedInSincePageLoad = useAuthStore.getState().isAuthenticated;