/**
 * MCP OAuth Service
 *
 * Handles OAuth 2.0 Authorization Code flow with PKCE for MCP authentication
 */
interface PKCEChallenge {
    codeVerifier: string;
    codeChallenge: string;
}
interface OAuthTokenResponse {
    access_token: string;
    token_type: string;
    expires_in: number;
    refresh_token?: string;
    scope?: string;
}
/**
 * Redirect URIs allowed when the authorization request is from a tunnel (non-local Host).
 * Prevents sending the authorization code to a third-party site. Allows localhost, loopback,
 * known app schemes, and trusted hosted OAuth callbacks (OpenAI/Claude).
 */
export declare function isRedirectUriAllowedForTunnel(redirectUri: string): boolean;
/**
 * Generate PKCE challenge and verifier
 *
 * Creates a cryptographically secure code verifier and corresponding SHA-256 challenge
 * for OAuth 2.0 PKCE (Proof Key for Code Exchange) flow.
 *
 * @returns Object containing codeVerifier (128 chars) and codeChallenge (base64url SHA-256 hash)
 * @example
 * const { codeVerifier, codeChallenge } = generatePKCE();
 * // codeVerifier: "abc123..." (128 chars)
 * // codeChallenge: "xyz789..." (43 chars)
 */
export declare function generatePKCE(): PKCEChallenge;
/**
 * Encrypt refresh token for storage
 * Exported for testing purposes only
 */
export declare function encryptRefreshToken(token: string): string;
/**
 * Decrypt refresh token from storage
 * Exported for testing purposes only
 */
export declare function decryptRefreshToken(encrypted: string): string;
/**
 * Handle RFC 7591 Dynamic Client Registration requests.
 * Used by Cursor and other MCP clients that require registration_endpoint in discovery.
 * Registers a client for the given redirect_uris and returns client metadata.
 */
export declare function handleDynamicRegistration(body: {
    redirect_uris: string[];
    client_name?: string;
    scope?: string;
}): Promise<{
    client_id: string;
    client_id_issued_at: number;
    redirect_uris: string[];
    grant_types_supported: string[];
    response_types_supported: string[];
    code_challenge_methods_supported: string[];
    scope?: string;
}>;
/**
 * Create OAuth authorization URL
 *
 * Uses PKCE flow for OAuth 2.0 Authorization Code flow.
 *
 * **Automatic Client Registration:**
 * - If `NEOTOMA_OAUTH_CLIENT_ID` is not set, this function will attempt to register a client
 *   dynamically using auth admin createOAuthClient()
 * - This requires "Allow Dynamic OAuth Apps" to be enabled in auth server
 * - The registered `client_id` is cached in memory to avoid re-registration
 * - If dynamic registration fails, a clear error message is provided with instructions
 *
 * **Manual Client Registration (Alternative):**
 * - Set `NEOTOMA_OAUTH_CLIENT_ID` in `.env` file to use a manually registered client
 * - Manual registration takes precedence over dynamic registration
 */
export declare function createAuthUrl(state: string, codeChallenge: string, redirectUri: string): Promise<string>;
/**
 * Start background cleanup job
 *
 * Starts periodic cleanup of expired OAuth states (runs every 5 minutes).
 * Should be called once when HTTP server starts.
 *
 * @example
 * startStateCleanupJob();
 * // Background job runs every 5 minutes
 */
export declare function startStateCleanupJob(): void;
/**
 * Stop background cleanup job
 *
 * Stops periodic state cleanup. Should be called when server is shutting down.
 *
 * @example
 * stopStateCleanupJob();
 * // Background job stops
 */
export declare function stopStateCleanupJob(): void;
/**
 * Initiate OAuth flow for MCP connection
 *
 * Creates OAuth authorization URL with PKCE challenge and stores state in database.
 * Returns authorization URL that user should visit to complete authentication.
 *
 * @param connectionId - Unique identifier for this MCP connection (alphanumeric, dashes, underscores)
 * @param clientName - Optional name of MCP client (e.g., "Cursor", "Claude Desktop")
 * @param redirectUri - Optional redirect URI (defaults to API callback endpoint)
 * @param clientState - Optional client state to return in callback (used by Cursor)
 * @returns Authorization URL, connection ID, and state expiration time
 * @throws {OAuthError} If connection_id format is invalid or state storage fails
 * @example
 * const result = await initiateOAuthFlow("cursor-2025-01-27-abc123", "Cursor");
 * // User should visit result.authUrl to complete authentication
 */
export declare function initiateOAuthFlow(connectionId: string, clientName?: string, redirectUri?: string, clientState?: string, 
/** When provided (e.g. Custom GPT flow without client PKCE), use instead of generating. */
serverPkce?: {
    codeVerifier: string;
    codeChallenge: string;
}): Promise<{
    authUrl: string;
    connectionId: string;
    expiresAt: string;
}>;
export declare function createLocalAuthorizationRequest(params: {
    connectionId: string;
    redirectUri: string;
    clientState?: string;
    codeChallenge: string;
    /** When provided (e.g. Custom GPT flow without client PKCE), use instead of generating. Must match codeChallenge. */
    codeVerifier?: string;
}): Promise<{
    authUrl: string;
    connectionId: string;
    state: string;
    expiresAt: string;
}>;
export declare function completeLocalAuthorization(state: string, userId: string, clientName?: string | null): Promise<{
    connectionId: string;
    redirectUri?: string;
    clientState?: string;
}>;
/**
 * Handle OAuth callback and store connection
 *
 * Exchanges authorization code for access and refresh tokens, validates state,
 * and stores encrypted refresh token in database for long-lived authentication.
 *
 * @param code - Authorization code from OAuth provider
 * @param state - State token from OAuth flow (must match stored state)
 * @returns Connection ID, user ID, and optional redirect URI and client state
 * @throws {OAuthError} If state is invalid/expired, code exchange fails, or connection storage fails
 * @example
 * const result = await handleOAuthCallback(code, state);
 * // result.connectionId: "cursor-2025-01-27-abc123"
 * // result.userId: "44e026a5-..."
 */
export declare function handleOAuthCallback(code: string, state: string): Promise<{
    connectionId: string;
    userId: string;
    redirectUri?: string;
    clientState?: string;
}>;
/**
 * Get valid access token for connection (refresh if needed)
 *
 * Returns cached access token if still valid (>5 minutes until expiry).
 * Automatically refreshes token using stored refresh token if expired or near expiration.
 *
 * @param connectionId - MCP connection identifier
 * @returns Access token and associated user ID
 * @throws {OAuthError} If connection not found, revoked, or token refresh fails
 * @example
 * const { accessToken, userId } = await getAccessTokenForConnection("cursor-2025-01-27-abc123");
 * // Use accessToken for authenticated requests
 */
export declare function getAccessTokenForConnection(connectionId: string): Promise<{
    accessToken: string;
    userId: string;
}>;
export declare function refreshAccessToken(refreshToken: string): Promise<OAuthTokenResponse>;
/**
 * Return OAuth token endpoint response for a connection (code=connection_id exchange)
 *
 * Used by Cursor and other RFC 8414-compliant OAuth clients after redirect with code=connection_id.
 * Returns standard OAuth 2.0 token response format.
 *
 * @param connectionId - MCP connection identifier (used as authorization code)
 * @returns OAuth token response with access_token, token_type, and expires_in
 * @throws {OAuthError} If connection not found or token retrieval fails
 * @example
 * const response = await getTokenResponseForConnection("cursor-2025-01-27-abc123");
 * // response.access_token: "eyJ..."
 * // response.token_type: "Bearer"
 * // response.expires_in: 3600
 */
export declare function getTokenResponseForConnection(connectionId: string): Promise<OAuthTokenResponse>;
/**
 * Validate Bearer token and get associated connection ID
 *
 * Validates the access token and returns the connection ID it belongs to.
 *
 * @param accessToken - Bearer access token from OAuth flow
 * @returns Connection ID and user ID
 * @throws {OAuthError} If token is invalid or no connection found
 * @example
 * const { connectionId, userId } = await validateTokenAndGetConnectionId("eyJ...");
 * // connectionId: "cursor-2025-01-27-abc123"
 */
export declare function validateTokenAndGetConnectionId(accessToken: string): Promise<{
    connectionId: string;
    userId: string;
}>;
/**
 * Get connection status
 *
 * Checks if OAuth connection is pending (not yet authorized), active, or expired (revoked/deleted).
 *
 * @param connectionId - MCP connection identifier
 * @returns Connection status: "pending", "active", or "expired"
 * @example
 * const status = await getConnectionStatus("cursor-2025-01-27-abc123");
 * // status: "active" | "pending" | "expired"
 */
export declare function getConnectionStatus(connectionId: string): Promise<"pending" | "active" | "expired">;
/**
 * List user's MCP connections
 *
 * Returns all active (non-revoked) OAuth connections for a user.
 *
 * @param userId - User's UUID
 * @returns Array of connections with ID, client name, and timestamps
 * @throws {OAuthError} If database query fails
 * @example
 * const connections = await listConnections("44e026a5-...");
 * // connections: [{ connectionId: "cursor-...", clientName: "Cursor", ... }]
 */
export declare function listConnections(userId: string): Promise<Array<{
    connectionId: string;
    clientName: string | null;
    createdAt: string;
    lastUsedAt: string | null;
}>>;
/**
 * Revoke MCP connection
 *
 * Soft-deletes OAuth connection by setting revoked_at timestamp.
 * Connection cannot be used after revocation.
 *
 * @param connectionId - MCP connection identifier to revoke
 * @param userId - User's UUID (for authorization)
 * @throws {OAuthError} If connection not found or revocation fails
 * @example
 * await revokeConnection("cursor-2025-01-27-abc123", "44e026a5-...");
 * // Connection is now revoked
 */
export declare function revokeConnection(connectionId: string, userId: string): Promise<void>;
export {};
//# sourceMappingURL=mcp_oauth.d.ts.map