/**
 * hosting/signin/redirectRoutes — the sign-in door's redirect half:
 * `GET /auth/login` and `GET /auth/callback` (design §5.2). PENDING
 * INDEPENDENT REVIEW before a company install.
 *
 * `GET /auth/login`
 *   Check `returnTo` (§5.5). Make `state`, `nonce` and (unless PKCE is off) a
 *   PKCE verifier. SEAL them, with `returnTo` and the time, into this
 *   attempt's transaction cookie. Nothing is written on the server. Redirect
 *   to the identity provider.
 *
 * `GET /auth/callback`, in this order:
 *   1. Open the transaction cookie named by `state` — sealed by this server,
 *      for this attempt, less than 10 minutes old — and compare `state`.
 *   2. Clear the transaction cookie, WHATEVER the outcome: `state` is single use.
 *   3. The strategy exchanges the code (client authentication + the PKCE
 *      verifier), checks the ID token (`iss`, `aud`, `nonce`, `exp`) and runs
 *      its OWN `verify` on the access token — the person test included.
 *   4. End any sign-in the browser already carries; create the new one.
 *   5. 303 to `returnTo`, with `Referrer-Policy: no-referrer` so the code in
 *      this URL does not leak onward.
 *   A failure is a 303 to `/?signin_error=<code>`: a fixed reason code, never
 *   the identity provider's text.
 *
 * Bounded per browser (review idI57 S-2): a login keeps at most the newest
 * {@link KEPT_PENDING} OTHER pending transaction cookies and expires the rest,
 * and a sealed transaction is at most {@link MAX_SEALED_BYTES} — so no page
 * can stack enough cookies on this origin to make every request a 431.
 *
 * A failure that is the deployment's, not the browser's (the IdP or the store
 * unreachable, the library missing) is logged by CLASS, once per change.
 *
 * Two `GET` routes change state, deliberately: the login sets a cookie and the
 * callback creates a sign-in. Both are safe — the callback needs the sealed
 * cookie issued to THIS browser, a matching `state`, and a single-use code
 * bound to the PKCE verifier and nonce.
 */
/// <reference types="node" />
import type { IncomingMessage, ServerResponse } from 'node:http';
import type { SignInOutcome, SignInReason } from './audit.js';
import { type SealKey } from './seal.js';
import { type RedirectSignIn, type SignInAccepted } from './types.js';
/** What the door hands the redirect half. */
export interface RedirectContext {
    readonly strategy: RedirectSignIn;
    readonly publicUrl: URL;
    readonly prefix: string;
    readonly cookie: {
        txName(attempt: string): string;
        issueTx(attempt: string, sealed: string): string;
        expireTx(attempt: string): string;
    };
    readonly sealKey: SealKey;
    readonly now: () => number;
    /** Where an operator line goes (a failure class, once per change). */
    readonly warn: (message: string) => void;
    endPresent(req: IncomingMessage): Promise<boolean>;
    startSignIn(accepted: SignInAccepted, strategy: string): Promise<{
        setCookie: string;
        body: Record<string, string>;
    }>;
    /** File the callback's outcome in the door's audit trail (the door adds strategy, address, time). */
    audit(req: IncomingMessage, outcome: SignInOutcome, reason: SignInReason, userId?: string): void;
}
export interface RedirectRoutes {
    login(req: IncomingMessage, res: ServerResponse): Promise<void>;
    callback(req: IncomingMessage, res: ServerResponse): Promise<void>;
    /** Where the page goes after sign-out: the IdP's end-session URL, or `/`. */
    logoutNext(): Promise<string>;
}
/** Pending transactions a login keeps besides its own — so one browser holds at most three. */
export declare const KEPT_PENDING = 2;
/** The largest sealed transaction, in bytes; a larger one is re-sealed with `returnTo` = `/`. */
export declare const MAX_SEALED_BYTES = 1200;
export declare function redirectRoutesFor(ctx: RedirectContext): RedirectRoutes;
