alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
1,330 lines • 68.6 kB
TypeScript
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