/** * SQL-backed storage for standard remote MCP OAuth. * * Additive framework tables only. We store OAuth client registrations, * short-lived authorization codes, and hashed refresh tokens. Access tokens * are signed JWTs and are never persisted. */ import { type DbExec } from "../db/client.js"; export declare const MCP_OAUTH_CODE_TTL_MS: number; export declare const MCP_OAUTH_ACCESS_TOKEN_TTL: string; export declare const MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS: number; export declare const MCP_OAUTH_REGISTER_MAX = 60; export declare const MCP_OAUTH_REGISTER_WINDOW_MS = 60000; export declare const mcpOauthStore: import("../db/store-registry.js").Store; export declare function ensureTable(): Promise; export declare const ensureOAuthTables: typeof ensureTable; export interface OAuthClientRow { clientId: string; clientName: string | null; redirectUris: string[]; grantTypes: string[]; responseTypes: string[]; tokenEndpointAuthMethod: string; applicationType: "native" | "web"; createdAt: number | null; } export interface OAuthCodeRow { clientName: string | null; code: string; clientId: string; redirectUri: string; codeChallenge: string; codeChallengeMethod: string; ownerEmail: string; issuedForEmail: string | null; orgId: string | null; orgDomain: string | null; scope: string; resource: string; createdAt: number | null; expiresAt: number | null; consumedAt: number | null; } export interface OAuthRefreshTokenRow { id: string; tokenHash: string; clientId: string; ownerEmail: string; issuedForEmail: string | null; orgId: string | null; orgDomain: string | null; scope: string; resource: string; grantCreatedAtMs: number | null; expiresAt: number | null; lastUsedAt: number | null; revokedAt: number | null; replacedByHash: string | null; } export declare function generateOpaqueToken(): string; export declare function hashOAuthToken(token: string): string; export declare function registerOAuthClient(params: { clientName?: string | null; redirectUris: string[]; grantTypes?: string[]; responseTypes?: string[]; tokenEndpointAuthMethod?: string; applicationType?: "native" | "web"; }): Promise; export declare function getOAuthClient(clientId: string): Promise; /** * A user's connection to an OAuth client, as an approval page names it. The * client chose its own registered name, so two clients can share one; when * this user first authorized it is what tells them apart. */ export interface OAuthClientConnection { clientName: string | null; connectedAt: number | null; } export declare function getOAuthClientConnection(clientId: string, ownerEmail: string): Promise; export declare function createOAuthCode(params: { clientId: string; clientName?: string | null; redirectUri: string; codeChallenge: string; codeChallengeMethod: string; ownerEmail: string; orgId?: string | null; orgDomain?: string | null; scope: string; resource: string; }, db?: DbExec): Promise; export declare function getOAuthCode(code: string): Promise; export declare function consumeOAuthCode(code: string, expectedOwnerEmail?: string, db?: DbExec): Promise; export declare function createOAuthRefreshToken(params: { refreshToken: string; clientId: string; ownerEmail: string; orgId?: string | null; orgDomain?: string | null; scope: string; resource: string; grantCreatedAtMs: number | null; }, db?: DbExec): Promise; export declare function rotateOAuthRefreshToken(params: { oldRefreshToken: string; newRefreshToken: string; }, db?: DbExec): Promise; export declare function getOAuthRefreshToken(refreshToken: string): Promise; /** * Remove the expiry from an existing grant on successful use. Refresh grants * remain valid until they are revoked or their owner loses access. * The caller supplies the owner whose membership it verified. */ export declare function touchOAuthRefreshToken(refreshToken: string, expectedOwnerEmail: string, db?: DbExec): Promise<"renewed" | "invalid">; /** * Revoke one refresh token so it can never mint another access token. * Idempotent: an already-revoked token keeps its first timestamp. */ export declare function revokeOAuthRefreshToken(refreshToken: string, expectedOwnerEmail?: string): Promise;