refactor(auth): leave for single sign-on through one helper

The sign-in page and the profile take-over page each cleared the offline
copies with the same capped wait before leaving for the identity
provider, with the limit written down twice. leaveForSingleSignOn does
it once for both.
This commit is contained in:
Marc-André Bombeck committed 2026-11-12 14:15:55 +01:00
1 parent 4ff3e4e1b7
commit d8c270859b
3 files changed
+18 -27

No files matched your search

+2 -13
View File
@@ -24,7 +24,7 @@ import { OIDC_MFA_COOKIE, OIDC_MFA_COOKIE_PATH } from "@/lib/auth/oidc-cookie";
import { isDashboardSnapshotEnabled } from "@/lib/dashboard/snapshot-flag";
import { prefetchDashboardSnapshot } from "@/lib/queries/use-dashboard-snapshot";
import { clearOfflineCachesForSessionEnd } from "@/lib/pwa/query-persister";
import { settleWithin } from "@/lib/async/settle-within";
import { leaveForSingleSignOn } from "@/lib/auth/leave-for-single-sign-on";
import { sanitizeSameOriginPath } from "@/lib/url-safety";
import { localizedSignInError } from "@/lib/api/localized-error";
import { formatDate } from "@/lib/format";
@@ -52,9 +52,6 @@ function deletionPendingMessage(t: Translate, purgeAt: unknown): string {
: t("auth.deletionPendingNoDate");
}
/** How long the single-sign-on start waits for the offline copies to go. */
const SSO_CLEANUP_WAIT_MS = 1_500;
/** The message for the `?error=` a sign-in redirect (the SSO callback) set. */
function signInRedirectError(
searchParams: URLSearchParams,
@@ -187,15 +184,7 @@ export default function LoginPage() {
params.set("client_proto", clientTransport.protocol);
params.set("client_host", clientTransport.host);
}
// The session starts on the way back; the last account's copies go
// first. Bounded: WebKit can leave an IndexedDB open hanging after the
// app returns from the background, and the button must still work.
await settleWithin(
clearOfflineCachesForSessionEnd(),
SSO_CLEANUP_WAIT_MS,
undefined,
);
loadDocument(`/api/auth/oidc/login?${params}`);
await leaveForSingleSignOn(`/api/auth/oidc/login?${params}`);
}
function getRedirectTarget(): string {
+2 -14
View File
@@ -21,18 +21,13 @@ import {
import { ApiError } from "@/lib/api/api-fetch";
import { showErrorToast } from "@/lib/errors/error-toast";
import { useFormatters, useTranslations } from "@/lib/i18n/context";
import { loadDocument } from "@/lib/navigation/load-document";
import { clearOfflineCachesForSessionEnd } from "@/lib/pwa/query-persister";
import { settleWithin } from "@/lib/async/settle-within";
import { leaveForSingleSignOn } from "@/lib/auth/leave-for-single-sign-on";
import {
useClaimProfile,
useClaimProfileSso,
useProfileClaimPreview,
} from "@/lib/queries/use-profile-claim";
/** How long the single-sign-on claim waits for the offline copies to go. */
const SSO_CLEANUP_WAIT_MS = 1_500;
/**
* v1.42 (#959) — the person a managed profile describes takes it over as
* their own account (`/auth/claim?token=hlp_…`).
@@ -115,14 +110,7 @@ export function ClaimProfile({
next.searchParams.set("client_proto", clientTransport.protocol);
next.searchParams.set("client_host", clientTransport.host);
}
// The session starts on the way back; the last account's copies
// go first, waited on no longer than on the sign-in page.
await settleWithin(
clearOfflineCachesForSessionEnd(),
SSO_CLEANUP_WAIT_MS,
undefined,
);
loadDocument(`${next.pathname}${next.search}`);
await leaveForSingleSignOn(`${next.pathname}${next.search}`);
},
},
);
+14
View File
@@ -0,0 +1,14 @@
import { settleWithin } from "@/lib/async/settle-within";
import { loadDocument } from "@/lib/navigation/load-document";
import { clearOfflineCachesForSessionEnd } from "@/lib/pwa/query-persister";
/**
* Leave for the identity provider. The session starts on the way back, so
* the last account's offline copies go first. The wait for them is capped:
* WebKit can leave an IndexedDB open hanging after the installed app returns
* from the background, and the button must still work then.
*/
export async function leaveForSingleSignOn(url: string): Promise<void> {
await settleWithin(clearOfflineCachesForSessionEnd(), 1_500, undefined);
loadDocument(url);
}