/** * Cross-product SSO deposit helpers (BOFF-4463). * * The deposit hop is a TOP-LEVEL navigation from a product origin to the * central bridge host (`app.burdenoff.com/auth/sso-deposit#sso=...`) so the * bridge's first-party localStorage receives the session that later powers * `/auth/sso-relay` for every other product. Two failure modes this module * addresses: * * 1. The deposit navigation is provisional for a few hundred ms; ANY * same-document navigation fired by post-login React effects (URL param * sync via history.replaceState, router redirects) cancels it * (net::ERR_ABORTED) and the bridge silently never gets the session. * → `beginSsoNavigation()` marks a pending cross-document SSO navigation so * known same-document navigators (ActiveContextProvider URL sync) hold off, * and callers can schedule a retry. * * 2. Tokens copied verbatim to other origins share ONE rotating refresh-token * lineage — the first origin to refresh revokes the token every other copy * holds. → `mintSsoSessionTokens()` calls the public `mintSsoSession` * mutation to obtain a dedicated lineage for the bridge/target origin. */ /** Query param the deposit initiator embeds in returnTo; its presence on boot * proves the deposit hop committed and bounced back. */ export declare const SSO_DEPOSITED_PARAM = "bf_sso_deposited"; /** Mark that a cross-document SSO navigation (deposit/relay hop) was just * initiated. Same-document navigators should stay quiet until it commits. */ export declare function beginSsoNavigation(): void; export declare function isSsoNavigationPending(): boolean; export declare function clearSsoNavigation(): void; export interface SsoDepositState { profileId: string; status: 'pending' | 'done'; at: number; attempts: number; } export declare function readSsoDepositState(): SsoDepositState | null; export declare function writeSsoDepositState(state: SsoDepositState): void; export declare function markSsoDepositPending(profileId: string): void; export declare function markSsoDepositDone(profileId: string): void; export declare function clearSsoDepositState(): void; /** * True when the app should attempt (or re-attempt) the deposit hop for this * profile: nothing recorded yet (legacy session that never deposited), a * pending attempt that evidently never committed, or a stale `done` record * past its trust window. Bounded by attempt count + cooldown so a persistently * failing bridge can never turn into a redirect loop. */ export declare function shouldAttemptSsoDeposit(profileId: string): boolean; export interface MintedSsoTokens { accessToken: string; refreshToken: string; expiresAt: number; } export interface MintSsoSessionResult { tokens: MintedSsoTokens | null; /** * True when the server EXPLICITLY rejected the source refresh token / * session (revoked, rotated away, user inactive). Distinguishes a dead * session (caller should treat the stored pair as unusable) from the * mutation merely being unreachable (rollout gap, network) where a legacy * fallback is still reasonable. */ denied: boolean; } /** * Mint a dedicated refresh-token lineage for another origin (bridge host or * relay target) from this origin's valid refresh token. */ export declare function mintSsoSessionTokens(globalGraphqlUrl: string, refreshToken: string, options?: { timeoutMs?: number; }): Promise; export interface SsoDepositPayload { profileId: string; tokens: string; user: string; profiles: string | null; } /** * Build the full deposit URL: bridge-host /auth/sso-deposit with the payload in * the fragment (never sent to servers) and the deposit-committed marker param * embedded in returnTo so the bounce-back proves completion. */ export declare function buildSsoDepositUrl(bridgeOrigin: string, returnTo: string, payload: SsoDepositPayload): string; /** * On boot: if the URL carries the deposit-committed marker, record success and * strip the param (via history.replaceState — safe, no SSO navigation is * pending during a fresh boot with the marker present). * Returns true when the marker was found. */ export declare function consumeSsoDepositMarker(profileId: string | null): boolean; //# sourceMappingURL=ssoDeposit.d.ts.map