UNPKG

oauth4webapi

Version:

Low-Level OAuth 2 / OpenID Connect Client API for JavaScript Runtimes

1,383 lines (1,382 loc) 109 kB
/** * @ignore */ export type CryptoKey = Extract<Awaited<ReturnType<typeof crypto.subtle.generateKey>>, { type: string; }>; export interface CryptoKeyPair { privateKey: CryptoKey; publicKey: CryptoKey; } /** * JSON Object */ export type JsonObject = { [Key in string]?: JsonValue; }; /** * JSON Array */ export type JsonArray = JsonValue[]; /** * JSON Primitives */ export type JsonPrimitive = string | number | boolean | null; /** * JSON Values */ export type JsonValue = JsonPrimitive | JsonObject | JsonArray; export interface ModifyAssertionFunction { ( /** * JWS Header to modify right before it is signed. */ header: Record<string, JsonValue | undefined>, /** * JWT Claims Set to modify right before it is signed. */ payload: Record<string, JsonValue | undefined>): void; } /** * Interface to pass an asymmetric private key and, optionally, its associated JWK Key ID to be * added as a `kid` JOSE Header Parameter. */ export interface PrivateKey { /** * An asymmetric private CryptoKey. * * Its algorithm must be compatible with a supported {@link JWSAlgorithm JWS Algorithm}. */ key: CryptoKey; /** * JWK Key ID to add to JOSE headers when this key is used. When not provided no `kid` (JWK Key * ID) will be added to the JOSE Header. */ kid?: string; } /** * JWS `alg` Algorithm identifiers from the * {@link https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms JSON Web Signature and Encryption Algorithms IANA registry} * for which Digital Signature validation is implemented. */ export type JWSAlgorithm = 'PS256' | 'ES256' | 'RS256' | 'Ed25519' | 'ES384' | 'PS384' | 'RS384' | 'ES512' | 'PS512' | 'RS512' | 'EdDSA'; export interface JWK { readonly kty?: string; readonly kid?: string; readonly alg?: string; readonly use?: string; readonly key_ops?: string[]; readonly e?: string; readonly n?: string; readonly crv?: string; readonly x?: string; readonly y?: string; readonly [parameter: string]: JsonValue | undefined; } /** * By default the module only allows interactions with HTTPS endpoints. Setting this option to * `true` removes that restriction. * * @deprecated To make it stand out as something you shouldn't use, possibly only for local * development and testing against non-TLS secured environments. */ export declare const allowInsecureRequests: unique symbol; /** * Use to adjust the assumed current time. Positive and negative finite values representing seconds * are allowed. Default is `0` (Date.now() + 0 seconds is used). * * @example * * When the local clock is mistakenly 1 hour in the past * * ```ts * let client: oauth.Client = { * client_id: 'abc4ba37-4ab8-49b5-99d4-9441ba35d428', * // ... other metadata * [oauth.clockSkew]: +(60 * 60), * } * ``` * * @example * * When the local clock is mistakenly 1 hour in the future * * ```ts * let client: oauth.Client = { * client_id: 'abc4ba37-4ab8-49b5-99d4-9441ba35d428', * // ... other metadata * [oauth.clockSkew]: -(60 * 60), * } * ``` */ export declare const clockSkew: unique symbol; /** * Use to set allowed clock tolerance when checking DateTime JWT Claims. Only positive finite values * representing seconds are allowed. Default is `30` (30 seconds). * * @example * * Tolerate 30 seconds clock skew when validating JWT claims like exp or nbf. * * ```ts * let client: oauth.Client = { * client_id: 'abc4ba37-4ab8-49b5-99d4-9441ba35d428', * // ... other metadata * [oauth.clockTolerance]: 30, * } * ``` */ export declare const clockTolerance: unique symbol; /** * When configured on an interface that extends {@link HttpRequestOptions}, this applies to `options` * parameter for functions that may trigger HTTP requests, this replaces the use of global fetch. As * a fetch replacement the arguments and expected return are the same as fetch. * * In theory any module that claims to be compatible with the Fetch API can be used but your mileage * may vary. No workarounds to allow use of non-conform {@link !Response}s will be considered. * * If you only need to update the {@link !Request} properties you do not need to use a Fetch API * module, just change what you need and pass it to globalThis.fetch just like this module would * normally do. * * Its intended use cases are: * * - {@link !Request}/{@link !Response} tracing and logging * - Custom caching strategies for responses of Authorization Server Metadata and JSON Web Key Set * (JWKS) endpoints * - Changing the {@link !Request} properties like headers, body, credentials, mode before it is passed * to fetch * * Known caveats: * * - Expect Type-related issues when passing the inputs through to fetch-like modules, they hardly * ever get their typings inline with actual fetch, you should `@ts-expect-error` them. * - Returning self-constructed {@link !Response} instances prohibits AS/RS-signalled DPoP Nonce * caching. * * @example * * Using [sindresorhus/ky](https://github.com/sindresorhus/ky) for retries and its hooks feature for * logging outgoing requests and their responses. * * ```js * import ky from 'ky' * * // example use * await oauth.discoveryRequest(new URL('https://as.example.com'), { * [oauth.customFetch]: (...args) => * ky(args[0], { * ...args[1], * hooks: { * beforeRequest: [ * (request) => { * logRequest(request) * }, * ], * beforeRetry: [ * ({ request, error, retryCount }) => { * logRetry(request, error, retryCount) * }, * ], * afterResponse: [ * (request, _, response) => { * logResponse(request, response) * }, * ], * }, * }), * }) * ``` * * @example * * Using [nodejs/undici](https://github.com/nodejs/undici) to detect and use HTTP proxies. * * ```ts * import * as undici from 'undici' * * // see https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent * let envHttpProxyAgent = new undici.EnvHttpProxyAgent() * * // example use * await oauth.discoveryRequest(new URL('https://as.example.com'), { * // @ts-ignore * [oauth.customFetch](...args) { * return undici.fetch(args[0], { ...args[1], dispatcher: envHttpProxyAgent }) // prettier-ignore * }, * }) * ``` * * @example * * Using [nodejs/undici](https://github.com/nodejs/undici) to automatically retry network errors. * * ```ts * import * as undici from 'undici' * * // see https://undici.nodejs.org/#/docs/api/RetryAgent * let retryAgent = new undici.RetryAgent(new undici.Agent(), { * statusCodes: [], * errorCodes: [ * 'ECONNRESET', * 'ECONNREFUSED', * 'ENOTFOUND', * 'ENETDOWN', * 'ENETUNREACH', * 'EHOSTDOWN', * 'UND_ERR_SOCKET', * ], * }) * * // example use * await oauth.discoveryRequest(new URL('https://as.example.com'), { * // @ts-ignore * [oauth.customFetch](...args) { * return undici.fetch(args[0], { ...args[1], dispatcher: retryAgent }) // prettier-ignore * }, * }) * ``` * * @example * * Using [nodejs/undici](https://github.com/nodejs/undici) to mock responses in tests. * * ```ts * import * as undici from 'undici' * * // see https://undici.nodejs.org/#/docs/api/MockAgent * let mockAgent = new undici.MockAgent() * mockAgent.disableNetConnect() * * // example use * await oauth.discoveryRequest(new URL('https://as.example.com'), { * // @ts-ignore * [oauth.customFetch](...args) { * return undici.fetch(args[0], { ...args[1], dispatcher: mockAgent }) // prettier-ignore * }, * }) * ``` */ export declare const customFetch: unique symbol; /** * Use to mutate JWT header and payload before they are signed. Its intended use is working around * non-conform server behaviours, such as modifying JWT "aud" (audience) claims, or otherwise * changing fixed claims used by this library. * * @example * * Changing the `alg: "Ed25519"` back to `alg: "EdDSA"` * * ```ts * let as!: oauth.AuthorizationServer * let client!: oauth.Client * let parameters!: URLSearchParams * let key!: oauth.CryptoKey | oauth.PrivateKey * let keyPair!: oauth.CryptoKeyPair * * let remapEd25519: oauth.ModifyAssertionOptions = { * [oauth.modifyAssertion]: (header, _payload) => { * if (header.alg === 'Ed25519') { * header.alg = 'EdDSA' * } * }, * } * * // For JAR * oauth.issueRequestObject(as, client, parameters, key, remapEd25519) * * // For Private Key JWT * oauth.PrivateKeyJwt(key, remapEd25519) * * // For DPoP * oauth.DPoP(client, keyPair, remapEd25519) * ``` */ export declare const modifyAssertion: unique symbol; /** * Use to add support for decrypting JWEs the client encounters, namely * * - Encrypted ID Tokens returned by the Token Endpoint * - Encrypted ID Tokens returned as part of FAPI 1.0 Advanced Detached Signature authorization * responses * - Encrypted JWT UserInfo responses * - Encrypted JWT Introspection responses * - Encrypted JARM Responses * * @example * * Decrypting JARM responses * * ```ts * import * as jose from 'jose' * * let as!: oauth.AuthorizationServer * let client!: oauth.Client * let key!: oauth.CryptoKey * let alg!: string * let enc!: string * let currentUrl!: URL * let state!: string | undefined * * let decoder = new TextDecoder() * let jweDecrypt: oauth.JweDecryptFunction = async (jwe) => { * const { plaintext } = await jose * .compactDecrypt(jwe, key, { * keyManagementAlgorithms: [alg], * contentEncryptionAlgorithms: [enc], * }) * .catch((cause: unknown) => { * throw new oauth.OperationProcessingError('decryption failed', { cause }) * }) * * return decoder.decode(plaintext) * } * * let params = await oauth.validateJwtAuthResponse(as, client, currentUrl, state, { * [oauth.jweDecrypt]: jweDecrypt, * }) * ``` */ export declare const jweDecrypt: unique symbol; /** * > [!WARNING]\ * > This option has security implications that must be understood, assessed for applicability, and * > accepted before use. It is critical that the JSON Web Key Set cache only be writable by your own * > code. * * This option is intended for cloud computing runtimes that cannot keep an in memory cache between * their code's invocations. Use in runtimes where an in memory cache between requests is available * is not desirable. * * When configured on an interface that extends {@link JWKSCacheOptions}, this applies to `options` * parameter for functions that may trigger HTTP requests to * {@link AuthorizationServer.jwks_uri `as.jwks_uri`}, this allows the passed in object to: * * - Serve as an initial value for the JSON Web Key Set that the module would otherwise need to * trigger an HTTP request for * - Have the JSON Web Key Set the function optionally ended up triggering an HTTP request for * assigned to it as properties * * The intended use pattern is: * * - Before executing a function with {@link JWKSCacheOptions} in its `options` parameter you pull the * previously cached object from a low-latency key-value store offered by the cloud computing * runtime it is executed on; * - Default to an empty object `{}` instead when there's no previously cached value; * - Pass it into the options interfaces that extend {@link JWKSCacheOptions}; * - Afterwards, update the key-value storage if the {@link ExportedJWKSCache.uat `uat`} property of * the object has changed. * * @example * * ```ts * let as!: oauth.AuthorizationServer * let request!: Request * let expectedAudience!: string * let getPreviouslyCachedJWKS!: () => Promise<oauth.ExportedJWKSCache> * let storeNewJWKScache!: (cache: oauth.ExportedJWKSCache) => Promise<void> * * // Load JSON Web Key Set cache * let jwksCache: oauth.JWKSCacheInput = (await getPreviouslyCachedJWKS()) || {} * let { uat } = jwksCache * * // Use JSON Web Key Set cache * let accessTokenClaims = await oauth.validateJwtAccessToken(as, request, expectedAudience, { * [oauth.jwksCache]: jwksCache, * }) * * if (uat !== jwksCache.uat) { * // Update JSON Web Key Set cache * await storeNewJWKScache(jwksCache) * } * ``` */ export declare const jwksCache: unique symbol; /** * Authorization Server Metadata * * @group Authorization Server Metadata * * @see [IANA OAuth Authorization Server Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata) */ export interface AuthorizationServer { /** * Authorization server's Issuer Identifier URL. */ readonly issuer: string; /** * URL of the authorization server's authorization endpoint. */ readonly authorization_endpoint?: string; /** * URL of the authorization server's token endpoint. */ readonly token_endpoint?: string; /** * URL of the authorization server's JWK Set document. */ readonly jwks_uri?: string; /** * URL of the authorization server's Dynamic Client Registration Endpoint. */ readonly registration_endpoint?: string; /** * JSON array containing a list of the `scope` values that this authorization server supports. */ readonly scopes_supported?: string[]; /** * JSON array containing a list of the `response_type` values that this authorization server * supports. */ readonly response_types_supported?: string[]; /** * JSON array containing a list of the `response_mode` values that this authorization server * supports. */ readonly response_modes_supported?: string[]; /** * JSON array containing a list of the `grant_type` values that this authorization server * supports. */ readonly grant_types_supported?: string[]; /** * JSON array containing a list of client authentication methods supported by this token endpoint. */ readonly token_endpoint_auth_methods_supported?: string[]; /** * JSON array containing a list of the JWS signing algorithms supported by the token endpoint for * the signature on the JWT used to authenticate the client at the token endpoint. */ readonly token_endpoint_auth_signing_alg_values_supported?: string[]; /** * URL of a page containing human-readable information that developers might want or need to know * when using the authorization server. */ readonly service_documentation?: string; /** * Languages and scripts supported for the user interface, represented as a JSON array of language * tag values from RFC 5646. */ readonly ui_locales_supported?: string[]; /** * URL that the authorization server provides to the person registering the client to read about * the authorization server's requirements on how the client can use the data provided by the * authorization server. */ readonly op_policy_uri?: string; /** * URL that the authorization server provides to the person registering the client to read about * the authorization server's terms of service. */ readonly op_tos_uri?: string; /** * URL of the authorization server's revocation endpoint. */ readonly revocation_endpoint?: string; /** * JSON array containing a list of client authentication methods supported by this revocation * endpoint. */ readonly revocation_endpoint_auth_methods_supported?: string[]; /** * JSON array containing a list of the JWS signing algorithms supported by the revocation endpoint * for the signature on the JWT used to authenticate the client at the revocation endpoint. */ readonly revocation_endpoint_auth_signing_alg_values_supported?: string[]; /** * URL of the authorization server's introspection endpoint. */ readonly introspection_endpoint?: string; /** * JSON array containing a list of client authentication methods supported by this introspection * endpoint. */ readonly introspection_endpoint_auth_methods_supported?: string[]; /** * JSON array containing a list of the JWS signing algorithms supported by the introspection * endpoint for the signature on the JWT used to authenticate the client at the introspection * endpoint. */ readonly introspection_endpoint_auth_signing_alg_values_supported?: string[]; /** * PKCE code challenge methods supported by this authorization server. */ readonly code_challenge_methods_supported?: string[]; /** * Signed JWT containing metadata values about the authorization server as claims. */ readonly signed_metadata?: string; /** * URL of the authorization server's device authorization endpoint. */ readonly device_authorization_endpoint?: string; /** * Indicates authorization server support for mutual-TLS client certificate-bound access tokens. */ readonly tls_client_certificate_bound_access_tokens?: boolean; /** * JSON object containing alternative authorization server endpoints, which a client intending to * do mutual TLS will use in preference to the conventional endpoints. */ readonly mtls_endpoint_aliases?: MTLSEndpointAliases; /** * URL of the authorization server's UserInfo Endpoint. */ readonly userinfo_endpoint?: string; /** * JSON array containing a list of the Authentication Context Class References that this * authorization server supports. */ readonly acr_values_supported?: string[]; /** * JSON array containing a list of the Subject Identifier types that this authorization server * supports. */ readonly subject_types_supported?: string[]; /** * JSON array containing a list of the JWS `alg` values supported by the authorization server for * the ID Token. */ readonly id_token_signing_alg_values_supported?: string[]; /** * JSON array containing a list of the JWE `alg` values supported by the authorization server for * the ID Token. */ readonly id_token_encryption_alg_values_supported?: string[]; /** * JSON array containing a list of the JWE `enc` values supported by the authorization server for * the ID Token. */ readonly id_token_encryption_enc_values_supported?: string[]; /** * JSON array containing a list of the JWS `alg` values supported by the UserInfo Endpoint. */ readonly userinfo_signing_alg_values_supported?: string[]; /** * JSON array containing a list of the JWE `alg` values supported by the UserInfo Endpoint. */ readonly userinfo_encryption_alg_values_supported?: string[]; /** * JSON array containing a list of the JWE `enc` values supported by the UserInfo Endpoint. */ readonly userinfo_encryption_enc_values_supported?: string[]; /** * JSON array containing a list of the JWS `alg` values supported by the authorization server for * Request Objects. */ readonly request_object_signing_alg_values_supported?: string[]; /** * JSON array containing a list of the JWE `alg` values supported by the authorization server for * Request Objects. */ readonly request_object_encryption_alg_values_supported?: string[]; /** * JSON array containing a list of the JWE `enc` values supported by the authorization server for * Request Objects. */ readonly request_object_encryption_enc_values_supported?: string[]; /** * JSON array containing a list of the `display` parameter values that the authorization server * supports. */ readonly display_values_supported?: string[]; /** * JSON array containing a list of the Claim Types that the authorization server supports. */ readonly claim_types_supported?: string[]; /** * JSON array containing a list of the Claim Names of the Claims that the authorization server MAY * be able to supply values for. */ readonly claims_supported?: string[]; /** * Languages and scripts supported for values in Claims being returned, represented as a JSON * array of RFC 5646 language tag values. */ readonly claims_locales_supported?: string[]; /** * Boolean value specifying whether the authorization server supports use of the `claims` * parameter. */ readonly claims_parameter_supported?: boolean; /** * Boolean value specifying whether the authorization server supports use of the `request` * parameter. */ readonly request_parameter_supported?: boolean; /** * Boolean value specifying whether the authorization server supports use of the `request_uri` * parameter. */ readonly request_uri_parameter_supported?: boolean; /** * Boolean value specifying whether the authorization server requires any `request_uri` values * used to be pre-registered. */ readonly require_request_uri_registration?: boolean; /** * Indicates where authorization request needs to be protected as Request Object and provided * through either `request` or `request_uri` parameter. */ readonly require_signed_request_object?: boolean; /** * URL of the authorization server's pushed authorization request endpoint. */ readonly pushed_authorization_request_endpoint?: string; /** * Indicates whether the authorization server accepts authorization requests only via PAR. */ readonly require_pushed_authorization_requests?: boolean; /** * JSON array containing a list of algorithms supported by the authorization server for * introspection response signing. */ readonly introspection_signing_alg_values_supported?: string[]; /** * JSON array containing a list of algorithms supported by the authorization server for * introspection response content key encryption (`alg` value). */ readonly introspection_encryption_alg_values_supported?: string[]; /** * JSON array containing a list of algorithms supported by the authorization server for * introspection response content encryption (`enc` value). */ readonly introspection_encryption_enc_values_supported?: string[]; /** * Boolean value indicating whether the authorization server provides the `iss` parameter in the * authorization response. */ readonly authorization_response_iss_parameter_supported?: boolean; /** * JSON array containing a list of algorithms supported by the authorization server for * introspection response signing. */ readonly authorization_signing_alg_values_supported?: string[]; /** * JSON array containing a list of algorithms supported by the authorization server for * introspection response encryption (`alg` value). */ readonly authorization_encryption_alg_values_supported?: string[]; /** * JSON array containing a list of algorithms supported by the authorization server for * introspection response encryption (`enc` value). */ readonly authorization_encryption_enc_values_supported?: string[]; /** * CIBA Backchannel Authentication Endpoint. */ readonly backchannel_authentication_endpoint?: string; /** * JSON array containing a list of the JWS signing algorithms supported for validation of signed * CIBA authentication requests. */ readonly backchannel_authentication_request_signing_alg_values_supported?: string[]; /** * Supported CIBA authentication result delivery modes. */ readonly backchannel_token_delivery_modes_supported?: string[]; /** * Indicates whether the authorization server supports the use of the CIBA `user_code` parameter. */ readonly backchannel_user_code_parameter_supported?: boolean; /** * URL of an authorization server iframe that supports cross-origin communications for session * state information with the RP Client, using the HTML5 postMessage API. */ readonly check_session_iframe?: string; /** * JSON array containing a list of the JWS algorithms supported for DPoP Proof JWTs. */ readonly dpop_signing_alg_values_supported?: string[]; /** * URL at the authorization server to which an RP can perform a redirect to request that the * End-User be logged out at the authorization server. */ readonly end_session_endpoint?: string; /** * Boolean value specifying whether the authorization server can pass `iss` (issuer) and `sid` * (session ID) query parameters to identify the RP session with the authorization server when the * `frontchannel_logout_uri` is used. */ readonly frontchannel_logout_session_supported?: boolean; /** * Boolean value specifying whether the authorization server supports HTTP-based logout. */ readonly frontchannel_logout_supported?: boolean; /** * Boolean value specifying whether the authorization server can pass a `sid` (session ID) Claim * in the Logout Token to identify the RP session with the OP. */ readonly backchannel_logout_session_supported?: boolean; /** * Boolean value specifying whether the authorization server supports back-channel logout. */ readonly backchannel_logout_supported?: boolean; /** * JSON array containing a list of resource identifiers for OAuth protected resources. */ readonly protected_resources?: string[]; readonly [metadata: string]: JsonValue | undefined; } export interface MTLSEndpointAliases extends Pick<AuthorizationServer, 'backchannel_authentication_endpoint' | 'device_authorization_endpoint' | 'introspection_endpoint' | 'pushed_authorization_request_endpoint' | 'revocation_endpoint' | 'token_endpoint' | 'userinfo_endpoint'> { readonly [metadata: string]: string | undefined; } /** * Recognized Client Metadata that have an effect on the exposed functionality. * * @see [IANA OAuth Client Registration Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#client-metadata) */ export interface Client { /** * Client identifier. */ client_id: string; /** * JWS `alg` algorithm required for signing the ID Token issued to this Client. When not * configured the default is to allow only algorithms listed in * {@link AuthorizationServer.id_token_signing_alg_values_supported `as.id_token_signing_alg_values_supported`} * and fall back to `RS256` when the authorization server metadata is not set. */ id_token_signed_response_alg?: string; /** * JWS `alg` algorithm required for signing authorization responses. When not configured the * default is to allow only algorithms listed in * {@link AuthorizationServer.authorization_signing_alg_values_supported `as.authorization_signing_alg_values_supported`} * and fall back to `RS256` when the authorization server metadata is not set. */ authorization_signed_response_alg?: string; /** * Boolean value specifying whether the {@link IDToken.auth_time `auth_time`} Claim in the ID Token * is REQUIRED. Default is `false`. */ require_auth_time?: boolean; /** * JWS `alg` algorithm REQUIRED for signing UserInfo Responses. When not configured the default is * to allow only algorithms listed in * {@link AuthorizationServer.userinfo_signing_alg_values_supported `as.userinfo_signing_alg_values_supported`} * and fail otherwise. */ userinfo_signed_response_alg?: string; /** * JWS `alg` algorithm REQUIRED for signed introspection responses. When not configured the * default is to allow only algorithms listed in * {@link AuthorizationServer.introspection_signing_alg_values_supported `as.introspection_signing_alg_values_supported`} * and fall back to `RS256` when the authorization server metadata is not set. */ introspection_signed_response_alg?: string; /** * Default Maximum Authentication Age. */ default_max_age?: number; /** * Indicates the requirement for a client to use mutual TLS endpoint aliases defined by the AS * where present. Default is `false`. * * When combined with {@link customFetch} (to use a Fetch API implementation that supports client * certificates) this can be used to target security profiles that utilize Mutual-TLS for either * client authentication or sender constraining. * * @example * * (Node.js) Using [nodejs/undici](https://github.com/nodejs/undici) for Mutual-TLS Client * Authentication and Certificate-Bound Access Tokens support. * * ```ts * import * as undici from 'undici' * * let as!: oauth.AuthorizationServer * let client!: oauth.Client & { use_mtls_endpoint_aliases: true } * let params!: URLSearchParams * let key!: string // PEM-encoded key * let cert!: string // PEM-encoded certificate * * let clientAuth = oauth.TlsClientAuth() * let agent = new undici.Agent({ connect: { key, cert } }) * * let response = await oauth.pushedAuthorizationRequest(as, client, clientAuth, params, { * // @ts-ignore * [oauth.customFetch]: (...args) => * undici.fetch(args[0], { ...args[1], dispatcher: agent }), * }) * ``` * * @example * * (Deno) Using Deno.createHttpClient API for Mutual-TLS Client Authentication and * Certificate-Bound Access Tokens support. * * ```ts * let as!: oauth.AuthorizationServer * let client!: oauth.Client & { use_mtls_endpoint_aliases: true } * let params!: URLSearchParams * let key!: string // PEM-encoded key * let cert!: string // PEM-encoded certificate * * let clientAuth = oauth.TlsClientAuth() * // @ts-ignore * let agent = Deno.createHttpClient({ key, cert }) * * let response = await oauth.pushedAuthorizationRequest(as, client, clientAuth, params, { * // @ts-ignore * [oauth.customFetch]: (...args) => fetch(args[0], { ...args[1], client: agent }), * }) * ``` * * @see [RFC 8705 - OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens](https://www.rfc-editor.org/rfc/rfc8705.html) */ use_mtls_endpoint_aliases?: boolean; /** * See {@link clockSkew}. */ [clockSkew]?: number; /** * See {@link clockTolerance}. */ [clockTolerance]?: number; [metadata: string]: JsonValue | undefined; } /** * @group Errors */ export declare class UnsupportedOperationError extends Error { code: string; /** * @ignore */ constructor(message: string, options?: { cause?: unknown; }); } /** * @group Errors */ export declare class OperationProcessingError extends Error { code?: string; /** * @ignore */ constructor(message: string, options?: { cause?: unknown; code?: string; }); } export interface JWKSCacheOptions { /** * See {@link jwksCache}. */ [jwksCache]?: JWKSCacheInput; } export interface CustomFetchOptions<Method, BodyType = undefined> { /** * The request body content to send to the server */ body: BodyType; /** * HTTP Headers */ headers: Record<string, string>; /** * The {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods request method} */ method: Method; /** * See {@link !Request.redirect} */ redirect: 'manual'; /** * Depending on whether {@link HttpRequestOptions.signal} was used, if so, it is the value passed, * otherwise undefined */ signal?: AbortSignal; } export interface HttpRequestOptions<Method, BodyType = undefined> { /** * An AbortSignal instance, or a factory returning one, to abort the HTTP request(s) triggered by * this function's invocation. * * @example * * A 5000ms timeout AbortSignal for every request * * ```js * let signal = () => AbortSignal.timeout(5_000) // Note: AbortSignal.timeout may not yet be available in all runtimes. * ``` */ signal?: (() => AbortSignal) | AbortSignal; /** * Headers to additionally send with the HTTP request(s) triggered by this function's invocation. */ headers?: [string, string][] | Record<string, string> | Headers; /** * See {@link customFetch}. */ [customFetch]?: ( /** * URL the request is being made sent to {@link !fetch} as the `resource` argument */ url: string, /** * Options otherwise sent to {@link !fetch} as the `options` argument */ options: CustomFetchOptions<Method, BodyType>) => Promise<Response>; /** * See {@link allowInsecureRequests}. * * @deprecated */ [allowInsecureRequests]?: boolean; } export interface DiscoveryRequestOptions extends HttpRequestOptions<'GET'> { /** * The issuer transformation algorithm to use. */ algorithm?: 'oidc' | 'oauth2'; } /** * Performs an authorization server metadata discovery using one of two * {@link DiscoveryRequestOptions.algorithm transformation algorithms} applied to the * `issuerIdentifier` argument. * * - `oidc` (default) as defined by OpenID Connect Discovery 1.0. * - `oauth2` as defined by RFC 8414. * * @param issuerIdentifier Issuer Identifier to resolve the well-known discovery URI for. * * @returns Resolves with a {@link !Response} to then invoke {@link processDiscoveryResponse} with * * @group Authorization Server Metadata * @group OpenID Connect (OIDC) Discovery * * @see [RFC 8414 - OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414.html#section-3) * @see [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0-errata2.html#ProviderConfig) */ export declare function discoveryRequest(issuerIdentifier: URL, options?: DiscoveryRequestOptions): Promise<Response>; /** * Validates {@link !Response} instance to be one coming from the authorization server's well-known * discovery endpoint. * * @param expectedIssuerIdentifier Expected Issuer Identifier value. * @param response Resolved value from {@link discoveryRequest}. * * @returns Resolves with the discovered Authorization Server Metadata. * * @group Authorization Server Metadata * @group OpenID Connect (OIDC) Discovery * * @see [RFC 8414 - OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414.html#section-3) * @see [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0-errata2.html#ProviderConfig) */ export declare function processDiscoveryResponse(expectedIssuerIdentifier: URL, response: Response): Promise<AuthorizationServer>; /** * Generate random `code_verifier` value. * * @group Utilities * @group Authorization Code Grant * @group Authorization Code Grant w/ OpenID Connect (OIDC) * @group Proof Key for Code Exchange (PKCE) * * @see [RFC 7636 - Proof Key for Code Exchange (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4) */ export declare function generateRandomCodeVerifier(): string; /** * Generate random `state` value. * * @group Utilities * * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.1) */ export declare function generateRandomState(): string; /** * Generate random `nonce` value. * * @group Utilities * * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0-errata2.html#IDToken) */ export declare function generateRandomNonce(): string; /** * Calculates the PKCE `code_challenge` value to send with an authorization request using the S256 * PKCE Code Challenge Method transformation. * * @param codeVerifier `code_verifier` value generated e.g. from {@link generateRandomCodeVerifier}. * * @group Authorization Code Grant * @group Authorization Code Grant w/ OpenID Connect (OIDC) * @group Proof Key for Code Exchange (PKCE) * * @see [RFC 7636 - Proof Key for Code Exchange (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4) */ export declare function calculatePKCECodeChallenge(codeVerifier: string): Promise<string>; export interface DPoPRequestOptions { /** * DPoP handle, obtained from {@link DPoP} */ DPoP?: DPoPHandle; } export interface PushedAuthorizationRequestOptions extends HttpRequestOptions<'POST', URLSearchParams>, DPoPRequestOptions { } /** * Implementation of the Client's Authentication Method at the Authorization Server. * * @see {@link ClientSecretPost} * @see {@link ClientSecretBasic} * @see {@link PrivateKeyJwt} * @see {@link None} * @see {@link TlsClientAuth} * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) */ export type ClientAuth = (as: AuthorizationServer, client: Client, body: URLSearchParams, headers: Headers) => void | Promise<void>; /** * **`client_secret_post`** uses the HTTP request body to send `client_id` and `client_secret` as * `application/x-www-form-urlencoded` body parameters * * @example * * ```ts * let clientSecret!: string * * let clientAuth = oauth.ClientSecretPost(clientSecret) * ``` * * @param clientSecret * * @group Client Authentication * * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-2.3) * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0-errata2.html#ClientAuthentication) */ export declare function ClientSecretPost(clientSecret: string): ClientAuth; /** * **`client_secret_basic`** uses the HTTP `Basic` authentication scheme to send `client_id` and * `client_secret` in an `Authorization` HTTP Header. * * @example * * ```ts * let clientSecret!: string * * let clientAuth = oauth.ClientSecretBasic(clientSecret) * ``` * * @param clientSecret * * @group Client Authentication * * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-2.3) * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0-errata2.html#ClientAuthentication) */ export declare function ClientSecretBasic(clientSecret: string): ClientAuth; export interface ModifyAssertionOptions { /** * Use to modify a JWT assertion payload or header right before it is signed. * * @see {@link modifyAssertion} */ [modifyAssertion]?: ModifyAssertionFunction; } /** * **`private_key_jwt`** uses the HTTP request body to send `client_id`, `client_assertion_type`, * and `client_assertion` as `application/x-www-form-urlencoded` body parameters. Digital signature * is used for the assertion's authenticity and integrity. * * @example * * ```ts * let key!: oauth.CryptoKey | oauth.PrivateKey * * let clientAuth = oauth.PrivateKeyJwt(key) * ``` * * @param clientPrivateKey * * @group Client Authentication * * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0-errata2.html#ClientAuthentication) */ export declare function PrivateKeyJwt(clientPrivateKey: CryptoKey | PrivateKey, options?: ModifyAssertionOptions): ClientAuth; /** * **`client_secret_jwt`** uses the HTTP request body to send `client_id`, `client_assertion_type`, * and `client_assertion` as `application/x-www-form-urlencoded` body parameters. HMAC is used for * the assertion's authenticity and integrity. * * @example * * ```ts * let clientSecret!: string * * let clientAuth = oauth.ClientSecretJwt(clientSecret) * ``` * * @param clientSecret * @param options * * @group Client Authentication * * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0-errata2.html#ClientAuthentication) */ export declare function ClientSecretJwt(clientSecret: string, options?: ModifyAssertionOptions): ClientAuth; /** * **`none`** (public client) uses the HTTP request body to send only `client_id` as * `application/x-www-form-urlencoded` body parameter. * * ```ts * let clientAuth = oauth.None() * ``` * * @group Client Authentication * * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0-errata2.html#ClientAuthentication) */ export declare function None(): ClientAuth; /** * **`tls_client_auth`** uses the HTTP request body to send only `client_id` as * `application/x-www-form-urlencoded` body parameter and the mTLS key and certificate is configured * through {@link customFetch}. * * ```ts * let clientAuth = oauth.TlsClientAuth() * ``` * * @group Client Authentication * * @see [OAuth Token Endpoint Authentication Methods](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method) * @see [RFC 8705 - OAuth 2.0 Mutual-TLS Client Authentication (PKI Mutual-TLS Method)](https://www.rfc-editor.org/rfc/rfc8705.html#name-pki-mutual-tls-method) */ export declare function TlsClientAuth(): ClientAuth; /** * Generates a signed JWT-Secured Authorization Request (JAR). * * @param as Authorization Server Metadata. * @param client Client Metadata. * @param privateKey Private key to sign the Request Object with. * * @group Authorization Code Grant * @group Authorization Code Grant w/ OpenID Connect (OIDC) * @group JWT-Secured Authorization Request (JAR) * * @see [RFC 9101 - The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)](https://www.rfc-editor.org/rfc/rfc9101.html#name-request-object-2) */ export declare function issueRequestObject(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], privateKey: CryptoKey | PrivateKey, options?: ModifyAssertionOptions): Promise<string>; /** * @ignore */ export declare function checkProtocol(url: URL, enforceHttps: boolean | undefined): void; /** * Performs a Pushed Authorization Request at the * {@link AuthorizationServer.pushed_authorization_request_endpoint `as.pushed_authorization_request_endpoint`}. * * @param as Authorization Server Metadata. * @param client Client Metadata. * @param clientAuthentication Client Authentication Method. * @param parameters Authorization Request parameters. * * @returns Resolves with a {@link !Response} to then invoke * {@link processPushedAuthorizationResponse} with * * @group Pushed Authorization Requests (PAR) * * @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests (PAR)](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques) * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-with-pushed-authorizat) */ export declare function pushedAuthorizationRequest(as: AuthorizationServer, client: Client, clientAuthentication: ClientAuth, parameters: URLSearchParams | Record<string, string> | string[][], options?: PushedAuthorizationRequestOptions): Promise<Response>; /** * DPoP handle, obtained from {@link DPoP} */ export interface DPoPHandle { /** * Calculates the JWK Thumbprint of the DPoP public key using the SHA-256 hash function for use as * the optional `dpop_jkt` authorization request parameter. * * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-authorization-code-binding-) */ calculateThumbprint(): Promise<string>; } /** * Used to determine if a rejected error indicates the need to retry the request due to an * expired/missing nonce. * * @group DPoP */ export declare function isDPoPNonceError(err: unknown): boolean; /** * Returns a wrapper / handle around a {@link CryptoKeyPair} that is used for negotiating and proving * proof-of-possession to sender-constrain OAuth 2.0 tokens via DPoP at the Authorization Server and * Resource Server. * * This wrapper / handle also keeps track of server-issued nonces, allowing requests to be retried * with a fresh nonce when the server indicates the need to use one. {@link isDPoPNonceError} can be * used to determine if a rejected error indicates the need to retry the request due to an * expired/missing nonce. * * @example * * ```ts * let client!: oauth.Client * let keyPair!: oauth.CryptoKeyPair * * let DPoP = oauth.DPoP(client, keyPair) * ``` * * @param keyPair Public/private key pair to sign the DPoP Proof JWT with * * @group DPoP * * @see {@link https://www.rfc-editor.org/rfc/rfc9449.html RFC 9449 - OAuth 2.0 Demonstrating Proof of Possession (DPoP)} */ export declare function DPoP(client: Pick<Client, typeof clockSkew>, keyPair: CryptoKeyPair, options?: ModifyAssertionOptions): DPoPHandle; export interface PushedAuthorizationResponse { readonly request_uri: string; readonly expires_in: number; readonly [parameter: string]: JsonValue | undefined; } export interface OAuth2Error { readonly error: string; readonly error_description?: string; readonly error_uri?: string; readonly algs?: string; readonly scope?: string; readonly [parameter: string]: JsonValue | undefined; } /** * Throw when a server responds with an "OAuth-style" error JSON body * * @example * * ```http * HTTP/1.1 400 Bad Request * Content-Type: application/json;charset=UTF-8 * Cache-Control: no-store * Pragma: no-cache * * { * "error": "invalid_request" * } * ``` * * @group Errors */ export declare class ResponseBodyError extends Error { /** * The parsed JSON response body */ cause: Record<string, JsonValue | undefined>; code: typeof RESPONSE_BODY_ERROR; /** * Error code given in the JSON response */ error: string; /** * HTTP Status Code of the response */ status: number; /** * Human-readable text providing additional information, used to assist the developer in * understanding the error that occurred, given in the JSON response */ error_description?: string; /** * The "OAuth-style" error {@link !Response}, its {@link !Response.bodyUsed} is `true` and the JSON * body is available in {@link ResponseBodyError.cause} */ response: Response; /** * @ignore */ constructor(message: string, options: { cause: OAuth2Error; response: Response; }); } /** * Thrown when OAuth 2.0 Authorization Error Response is encountered. * * @example * * ```http * HTTP/1.1 302 Found * Location: https://client.example.com/cb?error=access_denied&state=xyz * ``` * * @group Errors */ export declare class AuthorizationResponseError extends Error { /** * Authorization Response parameters as {@link !URLSearchParams} */ cause: URLSearchParams; code: typeof AUTHORIZATION_RESPONSE_ERROR; /** * Error code given in the Authorization Response */ error: string; /** * Human-readable text providing additional information, used to assist the developer in * understanding the error that occurred, given in the Authorization Response */ error_description?: string; /** * @ignore */ constructor(message: string, options: { cause: URLSearchParams; }); } /** * Thrown when a server responds with a parseable WWW-Authenticate challenges, typically because of * expired tokens, or bad client authentication * * @example * * ```http * HTTP/1.1 401 Unauthorized * WWW-Authenticate: Bearer error="invalid_token", error_description="The access token expired" * ``` * * @group Errors */ export declare class WWWAuthenticateChallengeError extends Error { /** * The parsed WWW-Authenticate HTTP Header challenges */ cause: WWWAuthenticateChallenge[]; code: typeof WWW_AUTHENTICATE_CHALLENGE; /** * The {@link !Response} that included a WWW-Authenticate HTTP Header challenges, its * {@link !Response.bodyUsed} is `false` */ response: Response; /** * HTTP Status Code of the response */ status: number; /** * @ignore */ constructor(message: string, options: { cause: WWWAuthenticateChallenge[]; response: Response; }); } /** * WWW-Authenticate challenge auth-param dictionary with known and unknown parameter names */ export interface WWWAuthenticateChallengeParameters { /** * Identifies the protection space */ readonly realm?: string; /** * A machine-readable error code value */ readonly error?: string; /** * Human-readable ASCII text providing additional information, used to assist the client developer * in understanding the error that occurred */ readonly error_description?: string; /**