import type { AuthorizationUrlOptions, OAuthProviderConfig, OAuthServiceConfig, OAuthState, OAuthTokens, TokenExchangeOptions, TokenExchangeResult, TokenStore } from "../types.js"; export type EnvReader = (key: string) => string | undefined; /** Implement oauth provider. */ export declare class OAuthProvider { protected readonly config: OAuthProviderConfig; protected readonly envReader: EnvReader; constructor(config: OAuthProviderConfig, envReader?: EnvReader); getClientId(): string | null; getClientSecret(): string | null; isConfigured(): boolean; /** Declared PKCE behavior for this provider (`supported` by default). */ get pkceMode(): "required" | "supported" | "unsupported"; /** Separator used to serialize the provider's configured scope set. */ get scopeSeparator(): " " | ","; createAuthorizationUrl(options?: AuthorizationUrlOptions & { defaultScopes?: string[]; }): Promise<{ url: string; state: OAuthState; }>; /** * Headers for a client-authenticated request to the provider's auth server. * `useBasicAuth` providers carry the client credentials here; every other * provider carries them in the body via {@link buildClientCredentialsParams}. */ private buildClientAuthHeaders; private buildTokenHeaders; /** * Parse a successful token-endpoint body into {@link OAuthTokens}. * * Returns `null` when the response carries no usable access token. A 2xx * status alone is NOT sufficient evidence of success: some providers (e.g. * Slack) signal errors with `200 {"ok": false, "error": ...}`, and a missing * `access_token` must never be persisted as an empty-but-"connected" token. * See bugs H11/H12. */ private parseTokenResponse; private postTokenRequest; private buildClientCredentialsParams; private exchangeToken; exchangeCode(options: TokenExchangeOptions, signal?: AbortSignal): Promise; refreshTokens(refreshToken: string, signal?: AbortSignal): Promise; revokeToken(token: string, callerSignal?: AbortSignal): Promise; } /** Implement oauth service. */ export declare class OAuthService extends OAuthProvider { protected readonly serviceConfig: OAuthServiceConfig; protected tokenStore?: TokenStore; constructor(config: OAuthServiceConfig, tokenStore?: TokenStore, envReader?: EnvReader); get serviceId(): string; get displayName(): string; /** Detached credential variable names for operator-only diagnostics. */ get credentialEnvironmentVariables(): readonly [string, string]; get apiBaseUrl(): string; createAuthorizationUrl(options?: AuthorizationUrlOptions): Promise<{ url: string; state: OAuthState; }>; /** Whether a stored token carries a built-in grant this config superseded. */ isSupersededGrant(tokens: OAuthTokens): boolean; /** * Get a valid access token for the given user, refreshing if needed. * * `userId` is required — this store is keyed by `(serviceId, userId)` to * prevent one user's OAuth completion from overwriting another user's * tokens. See VULN-AUTH-2. */ getAccessToken(userId: string, signal?: AbortSignal): Promise; private refreshAndStoreAccessToken; private readTokenSnapshot; private readCurrentUnexpiredAccessToken; private isRejectedSupersededSnapshot; /** * Resolve `endpoint` against `apiBaseUrl`, validating that absolute URLs * share the configured origin. * * Without this check, a caller that forwards user-controlled data as * `endpoint` could cause `fetch()` to issue requests to arbitrary hosts * (including cloud metadata services and internal infrastructure). See * SEC-003 in the security audit. */ private resolveEndpointUrl; fetch(userId: string, endpoint: string, options?: RequestInit): Promise; } //# sourceMappingURL=base.d.ts.map