import type { AppDispatch } from "../../store/types"; /** * Platform-agnostic OAuth helpers shared by the web (`@sublay/react-js`) and * Expo (`@sublay/expo`) `useOAuthSignIn` hooks. * * These helpers deliberately contain NO browser/DOM globals (`window`, * `document`, `localStorage`) and NO React Native globals, so the same code * path runs on every platform. Each platform owns only its own I/O: obtaining * the redirect URL (web reads `window.location`, Expo opens a web-browser auth * session) and any navigation/URL cleanup. */ export declare const OAUTH_BASE_URL = "https://api.sublay.io/v7"; /** * Server-call head: POST to `/{projectId}/oauth/{authorize|link}` and return the * provider `authorizationUrl`. * * - `authorize` is unauthenticated; `link` requires the caller's access token, * passed via `accessToken` (sent as a Bearer header only when present). * - Throws an `Error` carrying the server's `error` body on a non-ok response. * * `link` resolves its token through the auth gate rather than trusting the * value the caller read, which is what makes it survive a cold start (the * caller's `accessToken` is still null while the bootstrap is in flight) and an * idle stretch (a token at or past `exp` is rotated before it goes out). It * throws if the active account changed while it waited, so the provider cannot * be linked to an account the caller never chose. This is a raw `fetch`, so * there is no interceptor to recover if the token is rejected anyway — same * limitation as the account-management thunks. * * `authorize` deliberately does NOT consult the gate: it is the sign-IN call, * and an armed gate returns whatever token is current rather than the null the * caller passed — which would attach the already-signed-in user's bearer to a * request that must go out unauthenticated. */ export declare function requestOAuthAuthorizationUrl({ projectId, endpoint, provider, redirectAfterAuth, accessToken, baseUrl, }: { projectId: string; endpoint: "authorize" | "link"; provider: string; redirectAfterAuth: string; /** Required for `link`, omitted for `authorize`. */ accessToken?: string | null; baseUrl?: string; }): Promise; export interface OAuthRedirectParams { accessToken: string | null; refreshToken: string | null; error: string | null; errorDescription: string | null; } /** * Tolerantly parse a redirect URL string into OAuth params. * * The Sublay OAuth callback carries tokens in the URL **fragment** * (`#accessToken=...&refreshToken=...`) and errors in the **query** * (`?error=...&error_description=...`). This splits the string by hand rather * than relying on `new URL().hash`, whose fragment handling is unreliable under * React Native's URL polyfill — exactly where the tokens live. */ export declare function parseOAuthRedirectUrl(url: string): OAuthRedirectParams; export interface HandleOAuthRedirectResult { /** True when tokens were found and dispatched. */ success: boolean; /** A human-readable error message when the redirect carried an `?error=`. */ error: string | null; } /** * Token-handling tail: given a redirect URL **string**, extract the tokens / * error and, on success, perform the same Redux dispatches the web hook has * always done (`setTokens` → `setInitialized` → the profile refresh, now via * `completeOAuthSignInThunk`, which wraps that refresh with the account-cap * gate). * * **The cap cannot surface as a rejection here.** This function is synchronous * and shared by both platform hooks, so an over-limit OAuth sign-in is caught * after the fact: the session it created is signed out server-side, the * previous selection is restored, and `accountLimitReached` is raised for the * UI to read. Sign-up, email sign-in and external verification reject their * callers instead — a deliberate asymmetry, documented on the OAuth pages. * * Pure of any I/O beyond dispatching: it does not read globals, navigate, or * clean the URL — the caller owns that. Accepts a URL string (or pre-parsed * `params`, e.g. from `expo-linking`) so any platform can feed it whatever it * obtained however it likes. * * Returns `{ success, error }` instead of throwing so callers can drive their * own loading/error UI state. */ export declare function handleOAuthRedirect({ dispatch, projectId, url, params, }: { dispatch: AppDispatch; projectId: string | null | undefined; url?: string; params?: OAuthRedirectParams; }): HandleOAuthRedirectResult;