UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

1,330 lines 68.6 kB
import { Alepha, Async, KIND, Primitive, Static } from "alepha"; import { Cookies, ServerCookiesProvider } from "alepha/server/cookies"; import { DateTimeProvider } from "alepha/datetime"; import { AccessTokenResponse, IssuerPrimitive, SecurityProvider, UserAccount } from "alepha/security"; import { ServerRawRequest, ServerReply } from "alepha/server"; import { ServerLinksProvider } from "alepha/server/links"; //#region ../../src/server/auth/helpers/appleClientSecret.d.ts interface AppleClientSecretOptions { privateKeyPem: string; teamId: string; serviceId: string; keyId: string; ttlSeconds?: number; } /** Signs Apple's short-lived ES256 client_secret JWT on demand (no rotation job). */ declare function signAppleClientSecret(opts: AppleClientSecretOptions): Promise<string>; //#endregion //#region ../../src/server/auth/constants/routes.d.ts declare const alephaServerAuthRoutes: { login: string; callback: string; logout: string; token: string; refresh: string; userinfo: string; }; //#endregion //#region ../../src/server/auth/schemas/authenticationProviderSchema.d.ts declare const authenticationProviderSchema: import("zod").ZodObject<{ name: import("zod").ZodString; type: import("zod").ZodEnum<{ CREDENTIALS: "CREDENTIALS"; OAUTH2: "OAUTH2"; OIDC: "OIDC"; }>; }, import("zod/v4/core").$strip>; type AuthenticationProvider = Static<typeof authenticationProviderSchema>; //#endregion //#region ../../src/server/auth/schemas/tokenResponseSchema.d.ts declare const tokenResponseSchema: import("zod").ZodObject<{ provider: import("zod").ZodString; access_token: import("zod").ZodString; issued_at: import("zod").ZodNumber; expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_token: import("zod").ZodOptional<import("zod").ZodString>; refresh_token_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; id_token: import("zod").ZodOptional<import("zod").ZodString>; scope: import("zod").ZodOptional<import("zod").ZodString>; user: import("zod").ZodObject<{ id: import("zod").ZodString; name: import("zod").ZodOptional<import("zod").ZodString>; firstName: import("zod").ZodOptional<import("zod").ZodString>; lastName: import("zod").ZodOptional<import("zod").ZodString>; email: import("zod").ZodOptional<import("zod").ZodString>; username: import("zod").ZodOptional<import("zod").ZodString>; picture: import("zod").ZodOptional<import("zod").ZodString>; sessionId: import("zod").ZodOptional<import("zod").ZodString>; organization: import("zod").ZodOptional<import("zod").ZodString>; roles: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; realm: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; api: import("zod").ZodObject<{ prefix: import("zod").ZodOptional<import("zod").ZodString>; actions: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{ path: import("zod").ZodString; method: import("zod").ZodOptional<import("zod").ZodString>; contentType: import("zod").ZodOptional<import("zod").ZodString>; kind: import("zod").ZodOptional<import("zod").ZodString>; service: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; permissions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; }, import("zod/v4/core").$strip>; }, import("zod/v4/core").$strip>; type TokenResponse = Static<typeof tokenResponseSchema>; //#endregion //#region ../../src/server/auth/schemas/tokensSchema.d.ts declare const tokensSchema: import("zod").ZodObject<{ provider: import("zod").ZodString; access_token: import("zod").ZodString; issued_at: import("zod").ZodNumber; expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_token: import("zod").ZodOptional<import("zod").ZodString>; refresh_token_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; id_token: import("zod").ZodOptional<import("zod").ZodString>; scope: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; type Tokens = Static<typeof tokensSchema>; //#endregion //#region ../../src/server/auth/schemas/userinfoResponseSchema.d.ts declare const userinfoResponseSchema: import("zod").ZodObject<{ user: import("zod").ZodOptional<import("zod").ZodObject<{ id: import("zod").ZodString; name: import("zod").ZodOptional<import("zod").ZodString>; firstName: import("zod").ZodOptional<import("zod").ZodString>; lastName: import("zod").ZodOptional<import("zod").ZodString>; email: import("zod").ZodOptional<import("zod").ZodString>; username: import("zod").ZodOptional<import("zod").ZodString>; picture: import("zod").ZodOptional<import("zod").ZodString>; sessionId: import("zod").ZodOptional<import("zod").ZodString>; organization: import("zod").ZodOptional<import("zod").ZodString>; roles: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; realm: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; api: import("zod").ZodObject<{ prefix: import("zod").ZodOptional<import("zod").ZodString>; actions: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{ path: import("zod").ZodString; method: import("zod").ZodOptional<import("zod").ZodString>; contentType: import("zod").ZodOptional<import("zod").ZodString>; kind: import("zod").ZodOptional<import("zod").ZodString>; service: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; permissions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; }, import("zod/v4/core").$strip>; }, import("zod/v4/core").$strip>; type UserinfoResponse = Static<typeof userinfoResponseSchema>; //#endregion //#region ../../../../node_modules/oauth4webapi/build/index.d.ts /** * JSON Object */ type JsonObject = { [Key in string]?: JsonValue; }; /** * JSON Array */ type JsonArray = JsonValue[]; /** * JSON Primitives */ type JsonPrimitive = string | number | boolean | null; /** * JSON Values */ type JsonValue = JsonPrimitive | JsonObject | JsonArray; /** * 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), * } * ``` */ 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, * } * ``` */ 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. * * @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 * }, * }) * ``` */ declare const customFetch$1: 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) */ 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; } 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) */ 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; } /** * Removes all Symbol properties from a type */ type OmitSymbolProperties<T> = { [K in keyof T as K extends symbol ? never : K]: T[K]; }; //#endregion //#region ../../../../node_modules/openid-client/build/index.d.ts /** * Implementation of the Client's Authentication Method at the Authorization * Server. * * The default is {@link ClientSecretPost} if {@link ClientMetadata.client_secret} * is present, {@link None} otherwise. * * Other Client Authentication Methods must be provided explicitly and their * implementations are linked below. * * @see {@link ClientSecretBasic} * @see {@link ClientSecretJwt} * @see {@link ClientSecretPost} * @see {@link None} * @see {@link PrivateKeyJwt} * @see {@link TlsClientAuth} */ type ClientAuth = (as: ServerMetadata, client: ClientMetadata, body: URLSearchParams, headers: Headers) => void; /** * When set on a {@link Configuration}, 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 * {@link !fetch Fetch API} can be used but your mileage may vary. No workarounds * to allow use of non-conform {@link !Response} instances will be considered. * * If you only need to update the {@link !Request} properties you do not need to * use a {@link !fetch 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 * - 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. * * @example * * Using [sindresorhus/ky](https://github.com/sindresorhus/ky) for retries and * its hooks feature for logging outgoing requests and their responses. * * ```ts * import ky from 'ky' * * let config!: client.Configuration * let logRequest!: (request: Request) => void * let logResponse!: (request: Request, response: Response) => void * let logRetry!: ( * request: Request, * error: Error, * retryCount: number, * ) => void * * config[client.customFetch] = (...args) => * // @ts-expect-error * 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() * * let config!: client.Configuration * * // @ts-ignore * config[client.customFetch] = (...args) => { * // @ts-ignore * 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', * ], * }) * * let config!: client.Configuration * * // @ts-ignore * config[client.customFetch] = (...args) => { * // @ts-ignore * 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() * * let config!: client.Configuration * * // @ts-ignore * config[client.customFetch] = (...args) => { * // @ts-ignore * return undici.fetch(args[0], { ...args[1], dispatcher: mockAgent }) // prettier-ignore * } * ``` * * @example * * Correcting the `redirect_uri` token endpoint request parameter when the * registered redirect URI contains query string components or when URL * normalization alters it (e.g. adding a trailing slash to a bare origin). The * module derives `redirect_uri` from the callback URL by stripping all query * parameters but it cannot distinguish the redirect URI's own parameters from * those added by the authorization server response. * * ```ts * let config!: client.Configuration * let registeredRedirectUri!: string * * // @ts-ignore * config[client.customFetch] = (...args) => { * let [url, options] = args * if ( * options.body instanceof URLSearchParams && * options.body.get('grant_type') === 'authorization_code' * ) { * options.body.set('redirect_uri', registeredRedirectUri) * } * * // @ts-ignore * return fetch(...args) * } * ``` */ declare const customFetch: typeof customFetch$1; type FetchBody = ArrayBuffer | null | ReadableStream | string | Uint8Array | undefined | URLSearchParams; /** * A subset of the [IANA OAuth Client Metadata * registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#client-metadata) * that has an effect on how the Client functions * * @group You are probably looking for this */ interface ClientMetadata extends Client { /** * Client secret. */ client_secret?: string; /** * Indicates the requirement for a client to use mutual TLS endpoint aliases * indicated by the * {@link ServerMetadata.mtls_endpoint_aliases Authorization Server Metadata}. * Default is `false`. * * When combined with {@link customFetch} (to use a {@link !fetch 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 config!: client.Configuration * let key!: string // PEM-encoded key * let cert!: string // PEM-encoded certificate * * let agent = new undici.Agent({ connect: { key, cert } }) * * config[client.customFetch] = (...args) => * // @ts-expect-error * 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 config!: client.Configuration * let key!: string // PEM-encoded key * let cert!: string // PEM-encoded certificate * * // @ts-expect-error * let agent = Deno.createHttpClient({ key, cert }) * * config[client.customFetch] = (...args) => * // @ts-expect-error * 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; } /** * Authorization Server Metadata * * @group You are probably looking for this * * @see [IANA OAuth Authorization Server Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata) */ interface ServerMetadata extends AuthorizationServer {} interface ServerMetadataHelpers { /** * Determines whether the Authorization Server supports a given Code Challenge * Method * * @param method Code Challenge Method. Default is `S256` */ supportsPKCE(method?: string): boolean; } /** * Public methods available on a {@link Configuration} instance */ interface ConfigurationMethods { /** * Used to retrieve the Authorization Server Metadata */ serverMetadata(): Readonly<ServerMetadata> & ServerMetadataHelpers; /** * Used to retrieve the Client Metadata */ clientMetadata(): Readonly<OmitSymbolProperties<ClientMetadata>>; } interface CustomFetchOptions { /** * The request body content to send to the server */ body: FetchBody; /** * HTTP Headers */ headers: Record<string, string>; /** * The * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods request method} */ method: string; /** * See {@link !Request.redirect} */ redirect: 'manual'; /** * An AbortSignal configured as per the {@link ConfigurationProperties.timeout} * value */ signal?: AbortSignal; } /** * @see {@link customFetch} */ type 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) => Promise<Response>; /** * Public properties available on a {@link Configuration} instance */ interface ConfigurationProperties { /** * Custom {@link !fetch Fetch API} implementation to use for the HTTP Requests * the client will be making. * * @see {@link customFetch} */ [customFetch]?: CustomFetch; /** * Timeout (in seconds) for the HTTP Requests the client will be making. * Default is `30` (seconds) */ timeout?: number; } /** * Configuration is an abstraction over the * {@link ServerMetadata OAuth 2.0 Authorization Server metadata} and * {@link ClientMetadata OAuth 2.0 Client metadata} * * Configuration instances are obtained either through * * - (RECOMMENDED) the {@link discovery} function that discovers the * {@link ServerMetadata OAuth 2.0 Authorization Server metadata} using the * Authorization Server's Issuer Identifier, or * - The {@link Configuration} constructor if the * {@link ServerMetadata OAuth 2.0 Authorization Server metadata} is known * upfront * * @example * * (RECOMMENDED) Setting up a Configuration with a Server Metadata discovery * step * * ```ts * let server!: URL * let clientId!: string * let clientSecret!: string | undefined * * let config = await client.discovery(server, clientId, clientSecret) * ``` * * @example * * Setting up a Configuration with a constructor * * ```ts * let server!: client.ServerMetadata * let clientId!: string * let clientSecret!: string | undefined * * let config = new client.Configuration(server, clientId, clientSecret) * ``` * * @group Configuration */ declare class Configuration implements ConfigurationMethods, ConfigurationProperties { /** * @param server Authorization Server Metadata * @param clientId Client Identifier at the Authorization Server * @param metadata Client Metadata, when a string is passed it is a shorthand * for passing just {@link ClientMetadata.client_secret}. * @param clientAuthentication Implementation of the Client's Authentication * Method at the Authorization Server. Default is {@link ClientSecretPost} * using the {@link ClientMetadata.client_secret}. */ constructor(server: ServerMetadata, clientId: string, metadata?: Partial<ClientMetadata> | string, clientAuthentication?: ClientAuth); /** * @ignore */ serverMetadata(): Readonly<ServerMetadata> & ServerMetadataHelpers; /** * @ignore */ clientMetadata(): Readonly<OmitSymbolProperties<ClientMetadata>>; /** * @ignore */ get timeout(): number | undefined; /** * @ignore */ set timeout(value: number | undefined); /** * @ignore */ get [customFetch](): CustomFetch | undefined; /** * @ignore */ set [customFetch](value: CustomFetch); } //#endregion //#region ../../src/server/auth/providers/ServerAuthProvider.d.ts declare class ServerAuthProvider { protected readonly log: import("alepha/logger").Logger; protected readonly alepha: Alepha; protected readonly serverCookiesProvider: ServerCookiesProvider; protected readonly dateTimeProvider: DateTimeProvider; protected readonly serverLinksProvider: ServerLinksProvider; /** * Validates that a redirect URI is a safe relative path, or — when * COOKIE_PARENT_DOMAIN is configured — an https URL whose host is the * parent domain or a subdomain of it. Used by SaaS deployments where the * OAuth callback dispatches users back to their tenant subdomain. * * Prevents open redirect attacks by rejecting any other absolute URL. */ protected validateRedirectUri(uri: string): string; get identities(): Array<AuthPrimitive>; protected readonly authorizationCode: import("alepha/server/cookies").AbstractCookiePrimitive<import("zod").ZodObject<{ provider: import("zod").ZodString; realm: import("zod").ZodOptional<import("zod").ZodString>; codeVerifier: import("zod").ZodOptional<import("zod").ZodString>; redirectUri: import("zod").ZodOptional<import("zod").ZodString>; loginUri: import("zod").ZodOptional<import("zod").ZodString>; state: import("zod").ZodOptional<import("zod").ZodString>; nonce: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; readonly tokens: import("alepha/server/cookies").AbstractCookiePrimitive<import("zod").ZodObject<{ provider: import("zod").ZodString; access_token: import("zod").ZodString; issued_at: import("zod").ZodNumber; expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_token: import("zod").ZodOptional<import("zod").ZodString>; refresh_token_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; id_token: import("zod").ZodOptional<import("zod").ZodString>; scope: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; protected readonly configure: import("alepha").HookPrimitive<"configure">; /** * Fill request headers with access token from cookies or fallback to provider's fallback function. */ protected readonly onRequest: import("alepha").HookPrimitive<"server:onRequest">; /** * Get user information. */ readonly userinfo: import("alepha/server").RoutePrimitive<{ response: import("zod").ZodObject<{ user: import("zod").ZodOptional<import("zod").ZodObject<{ id: import("zod").ZodString; name: import("zod").ZodOptional<import("zod").ZodString>; firstName: import("zod").ZodOptional<import("zod").ZodString>; lastName: import("zod").ZodOptional<import("zod").ZodString>; email: import("zod").ZodOptional<import("zod").ZodString>; username: import("zod").ZodOptional<import("zod").ZodString>; picture: import("zod").ZodOptional<import("zod").ZodString>; sessionId: import("zod").ZodOptional<import("zod").ZodString>; organization: import("zod").ZodOptional<import("zod").ZodString>; roles: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; realm: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; api: import("zod").ZodObject<{ prefix: import("zod").ZodOptional<import("zod").ZodString>; actions: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{ path: import("zod").ZodString; method: import("zod").ZodOptional<import("zod").ZodString>; contentType: import("zod").ZodOptional<import("zod").ZodString>; kind: import("zod").ZodOptional<import("zod").ZodString>; service: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; permissions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; }, import("zod/v4/core").$strip>; }, import("zod/v4/core").$strip>; }>; /** * Refresh a token for internal providers. */ readonly refresh: import("alepha/server").RoutePrimitive<{ query: import("zod").ZodObject<{ provider: import("zod").ZodString; }, import("zod/v4/core").$strip>; body: import("zod").ZodObject<{ refresh_token: import("zod").ZodString; access_token: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ provider: import("zod").ZodString; access_token: import("zod").ZodString; issued_at: import("zod").ZodNumber; expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_token: import("zod").ZodOptional<import("zod").ZodString>; refresh_token_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; id_token: import("zod").ZodOptional<import("zod").ZodString>; scope: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; }>; /** * Login for local password-based authentication. */ readonly token: import("alepha/server").RoutePrimitive<{ query: import("zod").ZodObject<{ provider: import("zod").ZodString; realm: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; body: import("zod").ZodObject<{ username: import("zod").ZodString; password: import("zod").ZodString; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ provider: import("zod").ZodString; access_token: import("zod").ZodString; issued_at: import("zod").ZodNumber; expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_token: import("zod").ZodOptional<import("zod").ZodString>; refresh_token_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; refresh_expires_in: import("zod").ZodOptional<import("zod").ZodNumber>; id_token: import("zod").ZodOptional<import("zod").ZodString>; scope: import("zod").ZodOptional<import("zod").ZodString>; user: import("zod").ZodObject<{ id: import("zod").ZodString; name: import("zod").ZodOptional<import("zod").ZodString>; firstName: import("zod").ZodOptional<import("zod").ZodString>; lastName: import("zod").ZodOptional<import("zod").ZodString>; email: import("zod").ZodOptional<import("zod").ZodString>; username: import("zod").ZodOptional<import("zod").ZodString>; picture: import("zod").ZodOptional<import("zod").ZodString>; sessionId: import("zod").ZodOptional<import("zod").ZodString>; organization: import("zod").ZodOptional<import("zod").ZodString>; roles: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; realm: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; api: import("zod").ZodObject<{ prefix: import("zod").ZodOptional<import("zod").ZodString>; actions: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{ path: import("zod").ZodString; method: import("zod").ZodOptional<import("zod").ZodString>; contentType: import("zod").ZodOptional<import("zod").ZodString>; kind: import("zod").ZodOptional<import("zod").ZodString>; service: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>>; permissions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>; }, import("zod/v4/core").$strip>; }, import("zod/v4/core").$strip>; }>; /** * Oauth2/OIDC login route. */ readonly login: import("alepha/server").RoutePrimitive<{ query: import("zod").ZodObject<{ provider: import("zod").ZodString; realm: import("zod").ZodOptional<import("zod").ZodString>; redirect_uri: import("zod").ZodOptional<import("zod").ZodString>; }, import("zod/v4/core").$strip>; }>; /** * Extracts provider-specific extra profile fields delivered via the * authorization callback form body rath