/**
 * OAuth 2.1 authorization-server HTTP handlers for mailpouch.
 *
 * Implements the surface required by the 2025-11-25 MCP spec for an
 * authenticated remote deployment:
 *
 *   GET  /.well-known/oauth-authorization-server  — RFC 8414 metadata
 *   GET  /.well-known/oauth-protected-resource    — RFC 9728 metadata
 *   POST /oauth/register                          — RFC 7591 DCR
 *   GET  /oauth/authorize                         — consent page
 *   POST /oauth/authorize                         — consent submission
 *   POST /oauth/token                             — code exchange (PKCE)
 *   POST /oauth/revoke                            — token revocation
 *
 * The "consent page" is a single minimal HTML form that asks the user to
 * paste the admin password — a value distinct from remoteBearerToken,
 * configured separately as remoteOauthAdminPassword. The intent is to
 * prove physical presence, not to model a full user base. Do NOT reuse
 * the bearer token here: a single shared secret across both auth modes
 * means compromise of one path compromises both.
 *
 * Rate-limited through the shared TokenBucketLimiter (per client IP).
 */
import type { IncomingMessage, ServerResponse } from "http";
import { OAuthStore } from "./oauth-store.js";
import { TokenBucketLimiter } from "./rate-limit.js";
/**
 * Strip control characters / ANSI escapes and length-cap a DCR-supplied
 * client_name (XPORT-002 from the 2026-05-28 audit). Exported for tests
 * — production callers go through `handleRegister` which uses it inline.
 * Returns undefined for empty/missing input so the consent page falls
 * back to "(unnamed client)" rather than rendering an empty string.
 */
export declare function sanitizeDcrClientName(raw: string | undefined): string | undefined;
export interface OAuthEndpointsConfig {
    /** Externally-visible base URL of the server, e.g. https://mcp.example.com. */
    issuer: string;
    /** Absolute URL for the /mcp endpoint — used in oauth-protected-resource. */
    resource: string;
    /** Admin password that gates the consent screen. */
    adminPassword: string;
}
export interface OAuthHandlerResult {
    /** True when the handler has already written a response. */
    handled: boolean;
}
export declare class OAuthHandlers {
    private readonly store;
    private readonly cfg;
    private readonly limiter;
    private readonly onClientRegistered?;
    /**
     * XPORT-008: per-process secret used to HMAC the consent CSRF token. The
     * token has no server-side state — it is `HMAC(client_id)` minted by the GET
     * consent page and required (constant-time compared) on the POST. A
     * cross-site form on attacker.local cannot read the GET response to learn the
     * token, so it cannot forge a valid submission even if it knows the password.
     */
    private readonly csrfSecret;
    constructor(store: OAuthStore, cfg: OAuthEndpointsConfig, limiter: TokenBucketLimiter, onClientRegistered?: (c: {
        client_id: string;
        client_name?: string;
    }) => void);
    /** XPORT-008: mint a CSRF token bound to the client_id of this consent flow. */
    private mintCsrfToken;
    /** XPORT-008: constant-time verify a CSRF token against the expected client_id. */
    private verifyCsrfToken;
    /**
     * XPORT-008: reject state-changing POSTs whose Origin is cross-site. The
     * consent form is same-origin (`form-action 'self'`); a present Origin that
     * doesn't match the issuer means a cross-site submission. A missing Origin is
     * allowed through (some same-origin form posts omit it) — the CSRF token is
     * the primary defence; the Origin check is belt-and-suspenders.
     */
    private originAllowed;
    /**
     * Dispatch an HTTP request to the right OAuth endpoint. Returns
     * `{ handled: true }` when we owned the response; false lets the caller
     * fall through to the MCP endpoint.
     */
    dispatch(req: IncomingMessage, res: ServerResponse, url: URL): Promise<OAuthHandlerResult>;
    /** RFC 8414 §3 — Authorization Server Metadata. */
    private serveAuthServerMetadata;
    /** RFC 9728 — Protected Resource Metadata. */
    private serveProtectedResourceMetadata;
    /** RFC 7591 Dynamic Client Registration. Public, no secret issued. */
    private handleRegister;
    /** Consent page — returns a small HTML form rather than a redirect. */
    private handleAuthorizeGet;
    /** Consent form POST — validates admin password, mints code, 302s back to redirect_uri. */
    private handleAuthorizePost;
    /** Token endpoint — exchanges auth code for access token under PKCE. */
    private handleToken;
    private handleRevoke;
    /** Simple consent HTML with CSP to block script injection via reflected params. */
    private consentPage;
}
//# sourceMappingURL=oauth-handlers.d.ts.map