/** The subset of `fetch` this client needs — injectable for tests. */ export type FetchLike = (input: string | URL, init?: RequestInit) => Promise; /** * How the client sends its secret to the token endpoint: `body` puts * `client_secret` in the form body, `basic` sends it as an HTTP Basic * `Authorization` header (`client_secret_basic`). */ export type ClientAuthMethod = 'body' | 'basic'; /** Configuration for an {@link OAuth2Client}. */ export interface OAuth2Config { /** The client identifier registered with the provider. */ clientId: string; /** Required for confidential clients; omit for public (PKCE-only) clients. */ clientSecret?: string; /** Full URL of the provider's authorization endpoint; the base of the login URL built by {@link OAuth2Client.createAuthorizationUrl}. */ authorizationEndpoint: string; /** Full URL of the provider's token endpoint; `POST`ed server-to-server for code exchange and refresh. */ tokenEndpoint: string; /** Callback URL the provider redirects back to with the code; must exactly match one registered with the provider, and is re-sent on {@link OAuth2Client.exchangeCode}. */ redirectUri: string; /** Default scopes requested by {@link OAuth2Client.createAuthorizationUrl} (overridable per call); include `openid` to receive an {@link TokenResponse.idToken}. */ scopes?: string[]; /** How to send {@link OAuth2Config.clientSecret} (default `"body"`); irrelevant for public clients that have no secret. */ clientAuth?: ClientAuthMethod; /** Injected `fetch` (default the global). */ fetch?: FetchLike; } /** The result of {@link OAuth2Client.createAuthorizationUrl}. */ export interface AuthorizationRequest { /** The URL to redirect the user to. */ url: string; /** CSRF token — persist it and compare on callback. */ state: string; /** PKCE verifier — persist it and pass it to {@link OAuth2Client.exchangeCode}. */ codeVerifier: string; } /** A token endpoint response, normalized from the provider's snake_case JSON into camelCase (the untouched original stays in {@link TokenResponse.raw}). */ export interface TokenResponse { /** The access token to call APIs with. */ accessToken: string; /** The token type, typically `"Bearer"`. */ tokenType: string; /** Access-token lifetime in seconds, if the provider returned one. */ expiresIn?: number; /** Refresh token for {@link OAuth2Client.refreshToken}, if issued. */ refreshToken?: string; /** OIDC ID token (a JWT), if the `openid` scope was granted. */ idToken?: string; /** Scopes actually granted, space-delimited; may be narrower than requested, so check it before assuming access. */ scope?: string; /** The raw JSON, for provider-specific fields. */ raw: Record; } /** Thrown when the token or userinfo endpoint responds with a non-2xx status. */ export declare class OAuth2Error extends Error { /** HTTP status returned by the endpoint. */ readonly status: number; /** Parsed error body (or raw text) from the endpoint, for diagnostics. */ readonly details: unknown; /** Construct an error for a failed token or userinfo request. */ constructor(message: string, /** HTTP status returned by the endpoint. */ status: number, /** Parsed error body (or raw text) from the endpoint, for diagnostics. */ details: unknown); } /** * A minimal OAuth 2.0 / OIDC authorization-code client with PKCE — the basis for * social and enterprise sign-in. Endpoints are configured generically, so it * works with any conformant provider. Build a login URL with * {@link OAuth2Client.createAuthorizationUrl} (persist the returned `state` and * `codeVerifier`), then swap the returned code for tokens with * {@link OAuth2Client.exchangeCode}. Dependency-free — network calls go through * the global `fetch` (or an injected one). * * ```ts * const client = new OAuth2Client({ clientId, clientSecret, authorizationEndpoint, * tokenEndpoint, redirectUri, scopes: ['openid', 'email'] }) * const { url, state, codeVerifier } = client.createAuthorizationUrl() * // redirect to `url`; on callback verify `state`, then: * const tokens = await client.exchangeCode({ code, codeVerifier }) * ``` */ export declare class OAuth2Client { private readonly config; private readonly fetch; /** Create a client for the given provider configuration. */ constructor(config: OAuth2Config); /** * Build an authorization URL with a fresh `state` and PKCE challenge. * * @param options - overrides the config `scopes`, or pins `state`/`codeVerifier` (both default to fresh 256-bit random tokens — pin only for tests); `params` adds extra query parameters such as `prompt` or `login_hint`. */ createAuthorizationUrl(options?: { scopes?: string[]; state?: string; codeVerifier?: string; params?: Record; }): AuthorizationRequest; /** * Exchange an authorization `code` (plus its PKCE verifier) for tokens. * Throws {@link OAuth2Error} if the endpoint replies non-2xx. * * @param options - the authorization `code` from the callback, the `codeVerifier` you persisted alongside its `state` (required to satisfy PKCE), and a `redirectUri` override that must match the one originally sent. */ exchangeCode(options: { code: string; codeVerifier?: string; redirectUri?: string; }): Promise; /** * Exchange a refresh token for a fresh access token. * * @param refreshToken - a refresh token from a prior {@link TokenResponse}; some providers rotate it and return a new one, so persist the response's `refreshToken` if present. * @returns The refreshed token set (throws {@link OAuth2Error} on a non-2xx response). */ refreshToken(refreshToken: string): Promise; /** * Fetch the OIDC userinfo profile with an access token. * * @typeParam T - the expected shape of the userinfo JSON; unchecked, so validate it if the source is untrusted. * @param accessToken - a valid access token, sent as a `Bearer` credential in the `Authorization` header. * @param userInfoEndpoint - the provider's userinfo endpoint (kept out of {@link OAuth2Config} since it is per-provider; read it from the OIDC discovery document). * @returns The parsed userinfo profile; throws {@link OAuth2Error} on a non-2xx response. */ fetchUserInfo>(accessToken: string, userInfoEndpoint: string): Promise; private tokenRequest; } //# sourceMappingURL=oauth2.d.ts.map