mirror of
https://github.com/hanzoai/openid-client.git
synced 2026-09-24 17:01:10 +00:00
624 lines
16 KiB
TypeScript
624 lines
16 KiB
TypeScript
/// <reference types="node" />
|
|
// TypeScript Version: 3.6
|
|
|
|
import * as http from 'http';
|
|
import * as https from 'https';
|
|
import * as http2 from 'http2';
|
|
|
|
import { URL } from 'url';
|
|
import * as jose from 'jose';
|
|
import * as crypto from 'crypto';
|
|
import { format } from 'util';
|
|
|
|
export type HttpOptions = Partial<
|
|
Pick<
|
|
https.RequestOptions,
|
|
| 'agent'
|
|
| 'ca'
|
|
| 'cert'
|
|
| 'crl'
|
|
| 'headers'
|
|
| 'key'
|
|
| 'lookup'
|
|
| 'passphrase'
|
|
| 'pfx'
|
|
| 'timeout'
|
|
>
|
|
>;
|
|
export type RetryFunction = (retry: number, error: Error) => number;
|
|
export type CustomHttpOptionsProvider = (
|
|
url: URL,
|
|
options: Omit<https.RequestOptions, keyof URL>,
|
|
) => HttpOptions;
|
|
export type TokenTypeHint = 'access_token' | 'refresh_token' | string;
|
|
export type DPoPInput = crypto.KeyObject | Parameters<typeof crypto.createPrivateKey>[0];
|
|
|
|
interface UnknownObject {
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export const custom: {
|
|
setHttpOptionsDefaults(params: HttpOptions): undefined;
|
|
readonly http_options: unique symbol;
|
|
readonly clock_tolerance: unique symbol;
|
|
};
|
|
|
|
export type ResponseType = 'code' | 'id_token' | 'code id_token' | 'none' | string;
|
|
export type ClientAuthMethod =
|
|
| 'client_secret_basic'
|
|
| 'client_secret_post'
|
|
| 'client_secret_jwt'
|
|
| 'private_key_jwt'
|
|
| 'tls_client_auth'
|
|
| 'self_signed_tls_client_auth'
|
|
| 'none';
|
|
|
|
export interface ClientMetadata {
|
|
// important
|
|
client_id: string;
|
|
id_token_signed_response_alg?: string;
|
|
token_endpoint_auth_method?: ClientAuthMethod;
|
|
client_secret?: string;
|
|
redirect_uris?: string[];
|
|
response_types?: ResponseType[];
|
|
post_logout_redirect_uris?: string[];
|
|
default_max_age?: number;
|
|
require_auth_time?: boolean;
|
|
tls_client_certificate_bound_access_tokens?: boolean;
|
|
request_object_signing_alg?: string;
|
|
|
|
// less important
|
|
id_token_encrypted_response_alg?: string;
|
|
id_token_encrypted_response_enc?: string;
|
|
introspection_endpoint_auth_method?: ClientAuthMethod;
|
|
introspection_endpoint_auth_signing_alg?: string;
|
|
request_object_encryption_alg?: string;
|
|
request_object_encryption_enc?: string;
|
|
revocation_endpoint_auth_method?: ClientAuthMethod;
|
|
revocation_endpoint_auth_signing_alg?: string;
|
|
token_endpoint_auth_signing_alg?: string;
|
|
userinfo_encrypted_response_alg?: string;
|
|
userinfo_encrypted_response_enc?: string;
|
|
userinfo_signed_response_alg?: string;
|
|
authorization_encrypted_response_alg?: string;
|
|
authorization_encrypted_response_enc?: string;
|
|
authorization_signed_response_alg?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface ClaimsParameterMember {
|
|
essential?: boolean;
|
|
value?: string;
|
|
values?: string[];
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface AuthorizationParameters {
|
|
acr_values?: string;
|
|
audience?: string;
|
|
claims?:
|
|
| string
|
|
| {
|
|
id_token?: {
|
|
[key: string]: null | ClaimsParameterMember;
|
|
};
|
|
userinfo?: {
|
|
[key: string]: null | ClaimsParameterMember;
|
|
};
|
|
};
|
|
claims_locales?: string;
|
|
client_id?: string;
|
|
code_challenge_method?: string;
|
|
code_challenge?: string;
|
|
display?: string;
|
|
id_token_hint?: string;
|
|
login_hint?: string;
|
|
max_age?: number;
|
|
nonce?: string;
|
|
prompt?: string;
|
|
redirect_uri?: string;
|
|
registration?: string;
|
|
request_uri?: string;
|
|
request?: string;
|
|
resource?: string | string[];
|
|
response_mode?: string;
|
|
response_type?: string;
|
|
scope?: string;
|
|
state?: string;
|
|
ui_locales?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface EndSessionParameters {
|
|
id_token_hint?: TokenSet | string;
|
|
post_logout_redirect_uri?: string;
|
|
state?: string;
|
|
client_id?: string;
|
|
logout_hint?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface CallbackParamsType {
|
|
access_token?: string;
|
|
code?: string;
|
|
error?: string;
|
|
error_description?: string;
|
|
error_uri?: string;
|
|
expires_in?: string;
|
|
id_token?: string;
|
|
state?: string;
|
|
token_type?: string;
|
|
session_state?: string;
|
|
response?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface OAuthCallbackChecks {
|
|
response_type?: string;
|
|
state?: string;
|
|
code_verifier?: string;
|
|
jarm?: boolean;
|
|
scope?: string; // TODO: remove in v6.x
|
|
}
|
|
|
|
export interface OpenIDCallbackChecks extends OAuthCallbackChecks {
|
|
max_age?: number;
|
|
nonce?: string;
|
|
}
|
|
|
|
export interface CallbackExtras {
|
|
exchangeBody?: object;
|
|
clientAssertionPayload?: object;
|
|
DPoP?: DPoPInput;
|
|
}
|
|
|
|
export interface RefreshExtras {
|
|
exchangeBody?: object;
|
|
clientAssertionPayload?: object;
|
|
DPoP?: DPoPInput;
|
|
}
|
|
|
|
export interface GrantBody {
|
|
grant_type: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface GrantExtras {
|
|
clientAssertionPayload?: object;
|
|
DPoP?: DPoPInput;
|
|
}
|
|
|
|
export interface IntrospectExtras {
|
|
introspectBody?: object;
|
|
clientAssertionPayload?: object;
|
|
}
|
|
|
|
export interface RevokeExtras {
|
|
revokeBody?: object;
|
|
clientAssertionPayload?: object;
|
|
}
|
|
|
|
export interface RequestObjectPayload extends AuthorizationParameters {
|
|
client_id?: string;
|
|
iss?: string;
|
|
aud?: string;
|
|
iat?: number;
|
|
exp?: number;
|
|
jti?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface RegisterOther {
|
|
jwks?: { keys: jose.JWK[] };
|
|
initialAccessToken?: string;
|
|
}
|
|
|
|
export interface DeviceAuthorizationParameters {
|
|
client_id?: string;
|
|
scope?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface DeviceAuthorizationExtras {
|
|
exchangeBody?: object;
|
|
clientAssertionPayload?: object;
|
|
DPoP?: DPoPInput;
|
|
}
|
|
|
|
export interface PushedAuthorizationRequestExtras {
|
|
clientAssertionPayload?: object;
|
|
}
|
|
|
|
export type Address<ExtendedAddress extends {} = UnknownObject> = Override<
|
|
{
|
|
formatted?: string;
|
|
street_address?: string;
|
|
locality?: string;
|
|
region?: string;
|
|
postal_code?: string;
|
|
country?: string;
|
|
},
|
|
ExtendedAddress
|
|
>;
|
|
|
|
export type UserinfoResponse<
|
|
UserInfo extends {} = UnknownObject,
|
|
ExtendedAddress extends {} = UnknownObject,
|
|
> = Override<
|
|
{
|
|
sub: string;
|
|
name?: string;
|
|
given_name?: string;
|
|
family_name?: string;
|
|
middle_name?: string;
|
|
nickname?: string;
|
|
preferred_username?: string;
|
|
profile?: string;
|
|
picture?: string;
|
|
website?: string;
|
|
email?: string;
|
|
email_verified?: boolean;
|
|
gender?: string;
|
|
birthdate?: string;
|
|
zoneinfo?: string;
|
|
locale?: string;
|
|
phone_number?: string;
|
|
updated_at?: number;
|
|
address?: Address<ExtendedAddress>;
|
|
},
|
|
UserInfo
|
|
>;
|
|
|
|
export interface IntrospectionResponse {
|
|
active: boolean;
|
|
client_id?: string;
|
|
exp?: number;
|
|
iat?: number;
|
|
sid?: string;
|
|
iss?: string;
|
|
jti?: string;
|
|
username?: string;
|
|
aud?: string | string[];
|
|
scope: string;
|
|
sub?: string;
|
|
nbf?: number;
|
|
token_type?: string;
|
|
cnf?: {
|
|
'x5t#S256'?: string;
|
|
|
|
[key: string]: unknown;
|
|
};
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface ClientOptions {
|
|
additionalAuthorizedParties?: string | string[];
|
|
}
|
|
|
|
export type Client = InstanceType<Issuer['Client']>;
|
|
declare class BaseClient {
|
|
constructor(metadata: ClientMetadata, jwks?: { keys: jose.JWK[] }, options?: ClientOptions);
|
|
[custom.http_options]: CustomHttpOptionsProvider;
|
|
[custom.clock_tolerance]: number;
|
|
metadata: ClientMetadata;
|
|
issuer: Issuer<this>;
|
|
static issuer: Issuer<BaseClient>;
|
|
|
|
authorizationUrl(parameters?: AuthorizationParameters): string;
|
|
endSessionUrl(parameters?: EndSessionParameters): string;
|
|
callbackParams(
|
|
input: string | http.IncomingMessage | http2.Http2ServerRequest,
|
|
): CallbackParamsType;
|
|
callback(
|
|
redirectUri: string | undefined,
|
|
parameters: CallbackParamsType,
|
|
checks?: OpenIDCallbackChecks,
|
|
extras?: CallbackExtras,
|
|
): Promise<TokenSet>;
|
|
oauthCallback(
|
|
redirectUri: string | undefined,
|
|
parameters: CallbackParamsType,
|
|
checks?: OAuthCallbackChecks,
|
|
extras?: CallbackExtras,
|
|
): Promise<TokenSet>;
|
|
refresh(refreshToken: TokenSet | string, extras?: RefreshExtras): Promise<TokenSet>;
|
|
userinfo<TUserInfo extends {} = UnknownObject, TAddress extends {} = UnknownObject>(
|
|
accessToken: TokenSet | string,
|
|
options?: {
|
|
method?: 'GET' | 'POST';
|
|
via?: 'header' | 'body';
|
|
tokenType?: string;
|
|
params?: object;
|
|
DPoP?: DPoPInput;
|
|
},
|
|
): Promise<UserinfoResponse<TUserInfo, TAddress>>;
|
|
requestResource(
|
|
resourceUrl: string | URL,
|
|
accessToken: TokenSet | string,
|
|
options?: {
|
|
headers?: object;
|
|
body?: string | Buffer;
|
|
method?: 'GET' | 'POST' | 'PUT' | 'HEAD' | 'DELETE' | 'OPTIONS' | 'TRACE' | 'PATCH';
|
|
tokenType?: string;
|
|
DPoP?: DPoPInput;
|
|
},
|
|
): Promise<{ body?: Buffer } & http.IncomingMessage>;
|
|
grant(body: GrantBody, extras?: GrantExtras): Promise<TokenSet>;
|
|
introspect(
|
|
token: string,
|
|
tokenTypeHint?: TokenTypeHint,
|
|
extras?: IntrospectExtras,
|
|
): Promise<IntrospectionResponse>;
|
|
revoke(token: string, tokenTypeHint?: TokenTypeHint, extras?: RevokeExtras): Promise<undefined>;
|
|
requestObject(payload: RequestObjectPayload): Promise<string>;
|
|
deviceAuthorization(
|
|
parameters?: DeviceAuthorizationParameters,
|
|
extras?: DeviceAuthorizationExtras,
|
|
): Promise<DeviceFlowHandle<BaseClient>>;
|
|
pushedAuthorizationRequest(
|
|
parameters?: AuthorizationParameters,
|
|
extras?: PushedAuthorizationRequestExtras,
|
|
): Promise<{
|
|
request_uri: string;
|
|
expires_in: number;
|
|
[key: string]: unknown;
|
|
}>;
|
|
static register(metadata: object, other?: RegisterOther & ClientOptions): Promise<BaseClient>;
|
|
static fromUri(
|
|
registrationClientUri: string,
|
|
registrationAccessToken: string,
|
|
jwks?: { keys: jose.JWK[] },
|
|
clientOptions?: ClientOptions,
|
|
): Promise<BaseClient>;
|
|
static [custom.http_options]: CustomHttpOptionsProvider;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
interface DeviceFlowPollOptions {
|
|
// @ts-ignore
|
|
signal?: AbortSignal;
|
|
}
|
|
|
|
export class DeviceFlowHandle<TClient extends BaseClient = BaseClient> {
|
|
poll(options?: DeviceFlowPollOptions): Promise<TokenSet>;
|
|
abort(): void;
|
|
expired(): boolean;
|
|
expires_at: number;
|
|
client: TClient;
|
|
user_code: string;
|
|
device_code: string;
|
|
verification_uri: string;
|
|
verification_uri_complete: string;
|
|
expires_in: number;
|
|
}
|
|
|
|
export interface IssuerMetadata {
|
|
issuer: string;
|
|
authorization_endpoint?: string;
|
|
token_endpoint?: string;
|
|
jwks_uri?: string;
|
|
userinfo_endpoint?: string;
|
|
revocation_endpoint?: string;
|
|
end_session_endpoint?: string;
|
|
registration_endpoint?: string;
|
|
token_endpoint_auth_methods_supported?: string[];
|
|
token_endpoint_auth_signing_alg_values_supported?: string[];
|
|
introspection_endpoint_auth_methods_supported?: string[];
|
|
introspection_endpoint_auth_signing_alg_values_supported?: string[];
|
|
revocation_endpoint_auth_methods_supported?: string[];
|
|
revocation_endpoint_auth_signing_alg_values_supported?: string[];
|
|
request_object_signing_alg_values_supported?: string[];
|
|
mtls_endpoint_aliases?: MtlsEndpointAliases;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface MtlsEndpointAliases {
|
|
token_endpoint?: string;
|
|
userinfo_endpoint?: string;
|
|
revocation_endpoint?: string;
|
|
introspection_endpoint?: string;
|
|
device_authorization_endpoint?: string;
|
|
}
|
|
|
|
export interface TypeOfGenericClient<TClient extends BaseClient = BaseClient> {
|
|
new (metadata: ClientMetadata, jwks?: { keys: jose.JWK[] }, options?: ClientOptions): TClient;
|
|
[custom.http_options]: CustomHttpOptionsProvider;
|
|
[custom.clock_tolerance]: number;
|
|
}
|
|
|
|
export class Issuer<TClient extends BaseClient = BaseClient> {
|
|
constructor(metadata: IssuerMetadata);
|
|
|
|
Client: TypeOfGenericClient<TClient>;
|
|
|
|
FAPI1Client: TypeOfGenericClient<TClient>;
|
|
FAPI2Client: TypeOfGenericClient<TClient>;
|
|
|
|
metadata: IssuerMetadata;
|
|
[custom.http_options]: CustomHttpOptionsProvider;
|
|
static discover(issuer: string): Promise<Issuer<BaseClient>>;
|
|
static webfinger(input: string): Promise<Issuer<BaseClient>>;
|
|
static [custom.http_options]: CustomHttpOptionsProvider;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface TokenSetParameters {
|
|
access_token?: string;
|
|
token_type?: string;
|
|
id_token?: string;
|
|
refresh_token?: string;
|
|
scope?: string;
|
|
|
|
expires_at?: number;
|
|
session_state?: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export interface IdTokenClaims extends UserinfoResponse {
|
|
acr?: string;
|
|
amr?: string[];
|
|
at_hash?: string;
|
|
aud: string | string[];
|
|
auth_time?: number;
|
|
azp?: string;
|
|
c_hash?: string;
|
|
exp: number;
|
|
iat: number;
|
|
iss: string;
|
|
nonce?: string;
|
|
s_hash?: string;
|
|
sub: string;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export class TokenSet implements TokenSetParameters {
|
|
access_token?: string;
|
|
token_type?: string;
|
|
id_token?: string;
|
|
refresh_token?: string;
|
|
expires_in?: number;
|
|
expires_at?: number;
|
|
session_state?: string;
|
|
scope?: string;
|
|
|
|
constructor(input?: TokenSetParameters);
|
|
|
|
expired(): boolean;
|
|
claims(): IdTokenClaims;
|
|
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export type StrategyVerifyCallbackUserInfo<
|
|
TUser,
|
|
TUserInfo extends {} = UnknownObject,
|
|
TAddress extends {} = UnknownObject,
|
|
> = (
|
|
tokenset: TokenSet,
|
|
userinfo: UserinfoResponse<TUserInfo, TAddress>,
|
|
done: (err: any, user?: TUser) => void,
|
|
) => void;
|
|
export type StrategyVerifyCallback<TUser> = (
|
|
tokenset: TokenSet,
|
|
done: (err: any, user?: TUser) => void,
|
|
) => void;
|
|
export type StrategyVerifyCallbackReqUserInfo<
|
|
TUser,
|
|
TUserInfo extends {} = UnknownObject,
|
|
TAddress extends {} = UnknownObject,
|
|
> = (
|
|
req: http.IncomingMessage,
|
|
tokenset: TokenSet,
|
|
userinfo: UserinfoResponse<TUserInfo, TAddress>,
|
|
done: (err: any, user?: TUser) => void,
|
|
) => void;
|
|
export type StrategyVerifyCallbackReq<TUser> = (
|
|
req: http.IncomingMessage,
|
|
tokenset: TokenSet,
|
|
done: (err: any, user?: TUser) => void,
|
|
) => void;
|
|
|
|
export interface StrategyOptions<TClient extends BaseClient = BaseClient> {
|
|
client: TClient;
|
|
params?: AuthorizationParameters;
|
|
extras?: CallbackExtras;
|
|
passReqToCallback?: boolean;
|
|
usePKCE?: boolean | string;
|
|
sessionKey?: string;
|
|
}
|
|
|
|
export class Strategy<TUser, TClient extends BaseClient = BaseClient> {
|
|
constructor(
|
|
options: StrategyOptions<TClient>,
|
|
verify:
|
|
| StrategyVerifyCallback<TUser>
|
|
| StrategyVerifyCallbackUserInfo<TUser>
|
|
| StrategyVerifyCallbackReq<TUser>
|
|
| StrategyVerifyCallbackReqUserInfo<TUser>,
|
|
);
|
|
|
|
authenticate(req: any, options?: any): void;
|
|
success(user: any, info?: any): void;
|
|
fail(challenge: any, status: number): void;
|
|
fail(status: number): void;
|
|
redirect(url: string, status?: number): void;
|
|
pass(): void;
|
|
error(err: Error): void;
|
|
}
|
|
|
|
export namespace generators {
|
|
function random(bytes?: number): string;
|
|
function state(bytes?: number): string;
|
|
function nonce(bytes?: number): string;
|
|
function codeVerifier(bytes?: number): string;
|
|
function codeChallenge(verifier: string): string;
|
|
}
|
|
|
|
export namespace errors {
|
|
class OPError extends Error {
|
|
error_description?: string;
|
|
error?: string;
|
|
error_uri?: string;
|
|
state?: string;
|
|
scope?: string;
|
|
session_state?: string;
|
|
response?: { body?: UnknownObject | Buffer } & http.IncomingMessage;
|
|
|
|
constructor(
|
|
params: {
|
|
error: string;
|
|
error_description?: string;
|
|
error_uri?: string;
|
|
state?: string;
|
|
scope?: string;
|
|
session_state?: string;
|
|
},
|
|
response?: { body?: UnknownObject | Buffer } & http.IncomingMessage,
|
|
);
|
|
}
|
|
|
|
class RPError extends Error {
|
|
jwt?: string;
|
|
checks?: object;
|
|
params?: object;
|
|
body?: object;
|
|
response?: { body?: UnknownObject | Buffer } & http.IncomingMessage;
|
|
now?: number;
|
|
tolerance?: number;
|
|
nbf?: number;
|
|
exp?: number;
|
|
iat?: number;
|
|
auth_time?: number;
|
|
|
|
constructor(...args: Parameters<typeof format>);
|
|
constructor(options: {
|
|
message?: string;
|
|
printf?: Parameters<typeof format>;
|
|
response?: { body?: UnknownObject | Buffer } & http.IncomingMessage;
|
|
[key: string]: unknown;
|
|
});
|
|
}
|
|
}
|
|
|
|
type KnownKeys<T> = {
|
|
[K in keyof T]: string extends K ? never : number extends K ? never : K;
|
|
} extends { [_ in keyof T]: infer U }
|
|
? {} extends U
|
|
? never
|
|
: U
|
|
: never;
|
|
type Override<T1, T2> = Omit<T1, keyof Omit<T2, keyof KnownKeys<T2>>> & T2;
|