@monocloud/auth-core 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +6 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +7 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{types-hokU85Zr.d.mts → types-DmlJMcTH.d.mts} +17 -3
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/internal.cjs +26 -0
- package/dist/utils/internal.cjs.map +1 -1
- package/dist/utils/internal.d.mts +14 -2
- package/dist/utils/internal.mjs +26 -1
- package/dist/utils/internal.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -609,10 +609,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
609
609
|
delete idTokenClaims[x];
|
|
610
610
|
});
|
|
611
611
|
const session = {
|
|
612
|
-
user:
|
|
613
|
-
...idTokenClaims,
|
|
614
|
-
...userinfo ?? {}
|
|
615
|
-
},
|
|
612
|
+
user: require_utils_internal.profileSync(void 0, idTokenClaims, userinfo, true),
|
|
616
613
|
idToken: tokens.id_token,
|
|
617
614
|
refreshToken: tokens.refresh_token,
|
|
618
615
|
authorizedScopes: requestedScopes,
|
|
@@ -629,7 +626,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
629
626
|
}
|
|
630
627
|
/**
|
|
631
628
|
* Refetches user information for an existing session using the userinfo endpoint.
|
|
632
|
-
* Updates the session's user object with the latest user information
|
|
629
|
+
* Updates the session's user object with the latest user information.
|
|
633
630
|
*
|
|
634
631
|
* @param accessToken - Access token used to fetch the userinfo.
|
|
635
632
|
* @param session - The current MonoCloudSession.
|
|
@@ -651,10 +648,8 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
651
648
|
async refetchUserInfo(accessToken, session, options) {
|
|
652
649
|
if (!accessToken.scopes?.includes("openid")) throw new MonoCloudValidationError("Fetching userinfo requires the openid scope");
|
|
653
650
|
const userinfo = await this.userinfo(accessToken.accessToken);
|
|
654
|
-
session.
|
|
655
|
-
|
|
656
|
-
...userinfo
|
|
657
|
-
};
|
|
651
|
+
const idTokenClaims = session.idToken && options?.strictProfileSync ? MonoCloudOidcClient.decodeJwt(session.idToken) : void 0;
|
|
652
|
+
session.user = require_utils_internal.profileSync(session.user, idTokenClaims, userinfo, options?.strictProfileSync);
|
|
658
653
|
await options?.onSessionCreating?.(session, void 0, userinfo);
|
|
659
654
|
return session;
|
|
660
655
|
}
|
|
@@ -692,6 +687,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
692
687
|
const jwks = options?.jwks ?? await this.getJwks();
|
|
693
688
|
idTokenClaims = await this.validateIdToken(tokens.id_token, jwks.keys, options?.idTokenClockSkew ?? 0, options?.idTokenClockTolerance ?? 0);
|
|
694
689
|
} else idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);
|
|
690
|
+
else if (session.idToken) idTokenClaims = MonoCloudOidcClient.decodeJwt(session.idToken);
|
|
695
691
|
(options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach((x) => {
|
|
696
692
|
delete idTokenClaims[x];
|
|
697
693
|
});
|
|
@@ -699,11 +695,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
699
695
|
let scopes = options?.refreshGrantOptions?.scopes;
|
|
700
696
|
if (!resource && !scopes) scopes = session.authorizedScopes;
|
|
701
697
|
const accessToken = require_utils_internal.findToken(session.accessTokens, resource, scopes);
|
|
702
|
-
const user =
|
|
703
|
-
...session.user,
|
|
704
|
-
...idTokenClaims,
|
|
705
|
-
...userinfo ?? {}
|
|
706
|
-
};
|
|
698
|
+
const user = require_utils_internal.profileSync(session.user, idTokenClaims, userinfo, options?.strictProfileSync);
|
|
707
699
|
const newTokens = session.accessTokens?.filter((t) => t !== accessToken) ?? [];
|
|
708
700
|
newTokens.push({
|
|
709
701
|
scopes: tokens.scope,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["randomBytes","encodeBase64Url","stringToArrayBuffer","parseSpaceSeparated","now","findToken","decodeBase64Url","getPublicSigKeyFromIssuerJwks","stringToArrayBuffer"],"sources":["../src/errors/monocloud-auth-base-error.ts","../src/errors/monocloud-op-error.ts","../src/errors/monocloud-http-error.ts","../src/errors/monocloud-token-error.ts","../src/errors/monocloud-validation-error.ts","../src/client-auth.ts","../src/monocloud-oidc-client.ts"],"sourcesContent":["/**\n * Base class for all MonoCloud authentication errors.\n *\n * All errors thrown by the MonoCloud SDK extend this class, allowing applications to safely detect and handle MonoCloud-specific failures using `instanceof`.\n *\n * @category Error Classes\n */\nexport class MonoCloudAuthBaseError extends Error {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * OAuth error returned by the authorization server during an authentication or token request.\n *\n * These errors correspond to standard OAuth / OpenID Connect error responses such as `invalid_request`, `access_denied`, or `invalid_grant`.\n *\n * @category Error Classes\n */\nexport class MonoCloudOPError extends MonoCloudAuthBaseError {\n /** OAuth error code returned by the authorization server. */\n error: string;\n\n /** Human-readable description of the error. */\n errorDescription?: string;\n\n constructor(error: string, errorDescription?: string) {\n super(error);\n this.error = error;\n this.errorDescription = errorDescription;\n }\n}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a request to the MonoCloud authorization server fails.\n *\n * This error typically indicates a network failure, an unexpected HTTP response, or an unsuccessful response returned by the authorization server.\n *\n * @category Error Classes\n */\nexport class MonoCloudHttpError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a token operation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudTokenError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when validation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudValidationError extends MonoCloudAuthBaseError {}\n","import {\n encodeBase64Url,\n randomBytes,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { ClientAuthMethod, Jwk } from './types';\n\nconst algToSubtle = (\n alg?: string\n): HmacImportParams | RsaHashedImportParams | EcKeyImportParams => {\n switch (alg) {\n case 'HS256':\n case 'HS384':\n case 'HS512':\n return { name: 'HMAC', hash: `SHA-${alg.slice(-3)}` };\n case 'PS256':\n case 'PS384':\n case 'PS512':\n return { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n case 'RS256':\n case 'RS384':\n case 'RS512':\n return { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n case 'ES256':\n case 'ES384':\n return { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n case 'ES512':\n return { name: 'ECDSA', namedCurve: 'P-521' };\n /* v8 ignore next */\n default:\n throw new Error('unsupported JWS algorithm');\n }\n};\n\nconst psAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'PS256';\n case 'SHA-384':\n return 'PS384';\n case 'SHA-512':\n return 'PS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst rsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'RS256';\n case 'SHA-384':\n return 'RS384';\n case 'SHA-512':\n return 'RS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst esAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as EcKeyAlgorithm).namedCurve) {\n case 'P-256':\n return 'ES256';\n case 'P-384':\n return 'ES384';\n case 'P-521':\n return 'ES512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported EcKeyAlgorithm namedCurve');\n }\n};\n\nconst hsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as HmacKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'HS256';\n case 'SHA-384':\n return 'HS384';\n case 'SHA-512':\n return 'HS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported HMAC Algorithm hash');\n }\n};\n\nconst keyToJws = (key: CryptoKey): string => {\n switch (key.algorithm.name) {\n case 'HMAC':\n return hsAlg(key);\n case 'RSA-PSS':\n return psAlg(key);\n case 'RSASSA-PKCS1-v1_5':\n return rsAlg(key);\n case 'ECDSA':\n return esAlg(key);\n /* v8 ignore next */\n default:\n throw new Error('unsupported CryptoKey algorithm name');\n }\n};\n\nconst checkRsaKeyAlgorithm = (key: CryptoKey): void => {\n const { algorithm } = key as CryptoKey & { algorithm: RsaHashedKeyAlgorithm };\n\n /* v8 ignore if -- @preserve */\n if (\n typeof algorithm.modulusLength !== 'number' ||\n algorithm.modulusLength < 2048\n ) {\n throw new Error(`Unsupported ${algorithm.name} modulusLength`);\n }\n};\n\nconst ecdsaHashName = (key: CryptoKey): string => {\n const { algorithm } = key as CryptoKey & { algorithm: EcKeyAlgorithm };\n switch (algorithm.namedCurve) {\n case 'P-256':\n return 'SHA-256';\n case 'P-384':\n return 'SHA-384';\n case 'P-521':\n return 'SHA-512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported ECDSA namedCurve');\n }\n};\n\nexport const keyToSubtle = (\n key: CryptoKey\n): AlgorithmIdentifier | RsaPssParams | EcdsaParams => {\n switch (key.algorithm.name) {\n case 'HMAC': {\n return { name: key.algorithm.name };\n }\n case 'ECDSA':\n return {\n name: key.algorithm.name,\n hash: ecdsaHashName(key),\n } as EcdsaParams;\n case 'RSA-PSS': {\n checkRsaKeyAlgorithm(key);\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256': // Fall through\n case 'SHA-384': // Fall through\n case 'SHA-512':\n return {\n name: key.algorithm.name,\n saltLength:\n parseInt(\n (key.algorithm as RsaHashedKeyAlgorithm).hash.name.slice(-3),\n 10\n ) >> 3,\n } as RsaPssParams;\n /* v8 ignore next */\n default:\n throw new Error('unsupported RSA-PSS hash name');\n }\n }\n case 'RSASSA-PKCS1-v1_5':\n checkRsaKeyAlgorithm(key);\n return key.algorithm.name;\n }\n /* v8 ignore next -- @preserve */\n throw new Error('unsupported CryptoKey algorithm name');\n};\n\nconst clientAssertionPayload = (\n issuer: string,\n clientId: string,\n skew: number\n): Record<string, number | string> => {\n const now = Math.floor(Date.now() / 1000) + skew;\n return {\n jti: randomBytes(),\n aud: issuer,\n exp: now + 60,\n iat: now,\n nbf: now,\n iss: clientId,\n sub: clientId,\n };\n};\n\nconst jwtAssertionGenerator = async (\n issuer: string,\n clientId: string,\n clientSecret: Jwk,\n body: URLSearchParams,\n skew: number\n): Promise<void> => {\n const key = await crypto.subtle.importKey(\n 'jwk',\n clientSecret as JsonWebKey,\n algToSubtle(clientSecret.alg),\n false,\n ['sign']\n );\n\n const header = { alg: keyToJws(key), kid: clientSecret.kid };\n const payload = clientAssertionPayload(issuer, clientId, skew);\n\n body.set('client_id', clientId);\n body.set(\n 'client_assertion_type',\n 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\n );\n\n const input = `${encodeBase64Url(stringToArrayBuffer(JSON.stringify(header)))}.${encodeBase64Url(stringToArrayBuffer(JSON.stringify(payload)))}`;\n const signature = encodeBase64Url(\n await crypto.subtle.sign(\n keyToSubtle(key),\n key,\n stringToArrayBuffer(input) as BufferSource\n )\n );\n\n body.set('client_assertion', `${input}.${signature}`);\n};\n\nexport const clientAuth = async (\n clientId: string,\n clientSecret?: string | Jwk,\n method?: ClientAuthMethod,\n issuer?: string,\n headers?: Record<string, string>,\n body?: URLSearchParams,\n jwtAssertionSkew?: number\n): Promise<void> => {\n switch (true) {\n case method === 'client_secret_basic' && !!headers: {\n // eslint-disable-next-line no-param-reassign\n headers.authorization = `Basic ${btoa(`${clientId}:${clientSecret ?? ''}`)}`;\n break;\n }\n\n case method === 'client_secret_post' && !!body: {\n body.set('client_id', clientId);\n if (typeof clientSecret === 'string') {\n body.set('client_secret', clientSecret);\n }\n break;\n }\n\n case method === 'client_secret_jwt' &&\n !!issuer &&\n !!body &&\n (typeof clientSecret === 'string' || clientSecret?.kty === 'oct'): {\n const cs =\n typeof clientSecret === 'string'\n ? {\n k: encodeBase64Url(stringToArrayBuffer(clientSecret)),\n kty: 'oct',\n alg: 'HS256',\n }\n : clientSecret;\n\n await jwtAssertionGenerator(\n issuer,\n clientId,\n cs,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n case method === 'private_key_jwt' &&\n typeof clientSecret === 'object' &&\n clientSecret.kty !== 'oct' &&\n !!issuer &&\n !!body: {\n await jwtAssertionGenerator(\n issuer,\n clientId,\n clientSecret,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n default:\n throw new Error('Invalid Client Authentication Method');\n }\n};\n","import {\n decodeBase64Url,\n findToken,\n getPublicSigKeyFromIssuerJwks,\n now,\n parseSpaceSeparated,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { clientAuth, keyToSubtle } from './client-auth';\nimport {\n AccessToken,\n AuthenticateOptions,\n AuthorizationParams,\n ClientAuthMethod,\n EndSessionParameters,\n IdTokenClaims,\n IssuerMetadata,\n Jwk,\n Jwks,\n SecurityAlgorithms,\n JwsHeaderParameters,\n MonoCloudClientOptions,\n MonoCloudSession,\n MonoCloudUser,\n ParResponse,\n PushedAuthorizationParams,\n RefetchUserInfoOptions,\n RefreshGrantOptions,\n RefreshSessionOptions,\n Tokens,\n UserinfoResponse,\n} from './types';\nimport { MonoCloudOPError } from './errors/monocloud-op-error';\nimport { MonoCloudHttpError } from './errors/monocloud-http-error';\nimport { MonoCloudValidationError } from './errors/monocloud-validation-error';\nimport { MonoCloudTokenError } from './errors/monocloud-token-error';\nimport { MonoCloudAuthBaseError } from './errors/monocloud-auth-base-error';\n\nconst JWT_ASSERTION_CLOCK_SKEW = 5;\n\nconst FILTER_ID_TOKEN_CLAIMS = [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n];\n\nfunction assertMetadataProperty<K extends keyof IssuerMetadata>(\n metadata: IssuerMetadata,\n property: K\n): asserts metadata is IssuerMetadata & Required<Pick<IssuerMetadata, K>> {\n if (metadata[property] === undefined || metadata[property] === null) {\n throw new MonoCloudValidationError(\n `${property as string} endpoint is required but not available in the issuer metadata`\n );\n }\n}\n\nconst innerFetch = async (\n input: string,\n reqInit: RequestInit = {}\n): Promise<Response> => {\n try {\n return await fetch(input, reqInit);\n } catch (e) {\n /* v8 ignore next -- @preserve */\n throw new MonoCloudHttpError(\n (e as any).message ?? 'Unexpected Network Error'\n );\n }\n};\n\nconst deserializeJson = async <T = any>(res: Response): Promise<T> => {\n try {\n return await res.json();\n } catch (e) {\n throw new MonoCloudHttpError(\n /* v8 ignore next -- @preserve */\n `Failed to parse response body as JSON ${(e as any).message ? `: ${(e as any).message}` : ''}`\n );\n }\n};\n\n/**\n * @category Classes\n */\nexport class MonoCloudOidcClient {\n private readonly tenantDomain: string;\n\n private readonly clientId: string;\n\n private readonly clientSecret?: string | Jwk;\n\n private readonly authMethod: ClientAuthMethod;\n\n private readonly idTokenSigningAlgorithm: SecurityAlgorithms;\n\n private jwks?: Jwks;\n\n private jwksCacheExpiry = 0;\n\n private jwksCacheDuration = 300;\n\n private metadata?: IssuerMetadata;\n\n private metadataCacheExpiry = 0;\n\n private metadataCacheDuration = 300;\n\n constructor(\n tenantDomain: string,\n clientId: string,\n options?: MonoCloudClientOptions\n ) {\n // eslint-disable-next-line no-param-reassign\n tenantDomain ??= '';\n /* v8 ignore next -- @preserve */\n this.tenantDomain = `${!tenantDomain.startsWith('https://') ? 'https://' : ''}${tenantDomain.endsWith('/') ? tenantDomain.slice(0, -1) : tenantDomain}`;\n this.clientId = clientId;\n this.clientSecret = options?.clientSecret;\n this.authMethod = options?.clientAuthMethod ?? 'client_secret_basic';\n this.idTokenSigningAlgorithm = options?.idTokenSigningAlgorithm ?? 'RS256';\n\n if (options?.jwksCacheDuration) {\n this.jwksCacheDuration = options.jwksCacheDuration;\n }\n\n if (options?.metadataCacheDuration) {\n this.metadataCacheDuration = options.metadataCacheDuration;\n }\n }\n\n /**\n * Generates an authorization URL with specified parameters.\n *\n * If no values are provided for `responseType`, or `codeChallengeMethod`, they default to `code`, and `S256`, respectively.\n *\n * @param params - Authorization URL parameters.\n *\n * @returns Tenant's authorization URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authorizationUrl(params: AuthorizationParams): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n queryParams.set('redirect_uri', params.redirectUri);\n }\n\n if (params.requestUri) {\n queryParams.set('request_uri', params.requestUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n queryParams.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n queryParams.set('response_type', params.responseType);\n }\n\n if (\n (!params.responseType || params.responseType.length === 0) &&\n !params.requestUri\n ) {\n queryParams.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n queryParams.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n queryParams.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n queryParams.set('request', params.request);\n }\n\n if (params.responseMode) {\n queryParams.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n queryParams.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n queryParams.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n queryParams.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n queryParams.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n queryParams.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n queryParams.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n queryParams.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n queryParams.set('code_challenge', params.codeChallenge);\n queryParams.set(\n 'code_challenge_method',\n params.codeChallengeMethod ?? 'S256'\n );\n }\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'authorization_endpoint');\n\n return `${metadata.authorization_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Fetches the authorization server metadata from the .well-known endpoint.\n * The metadata is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh metadata from the server.\n *\n * @returns The issuer metadata for the tenant, retrieved from the OpenID Connect discovery endpoint.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getMetadata(forceRefresh = false): Promise<IssuerMetadata> {\n if (!forceRefresh && this.metadata && this.metadataCacheExpiry > now()) {\n return this.metadata;\n }\n\n this.metadata = undefined;\n\n const response = await innerFetch(\n `${this.tenantDomain}/.well-known/openid-configuration`\n );\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching metadata. Unexpected status code: ${response.status}`\n );\n }\n\n const metadata = await deserializeJson<IssuerMetadata>(response);\n\n this.metadata = metadata;\n this.metadataCacheExpiry = now() + this.metadataCacheDuration;\n\n return metadata;\n }\n\n /**\n * Fetches the JSON Web Keys used to sign the ID token.\n * The JWKS is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh set of JWKS from the server.\n *\n * @returns The JSON Web Key Set containing the public keys for token verification.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getJwks(forceRefresh = false): Promise<Jwks> {\n if (!forceRefresh && this.jwks && this.jwksCacheExpiry > now()) {\n return this.jwks;\n }\n\n this.jwks = undefined;\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'jwks_uri');\n\n const response = await innerFetch(metadata.jwks_uri);\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching JWKS. Unexpected status code: ${response.status}`\n );\n }\n const jwks = await deserializeJson<Jwks>(response);\n\n this.jwks = jwks;\n this.jwksCacheExpiry = now() + this.jwksCacheDuration;\n\n return jwks;\n }\n\n /**\n * Performs a pushed authorization request.\n *\n * @param params - Authorization Parameters.\n *\n * @returns Response from Pushed Authorization Request (PAR) endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the request is invalid.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async pushedAuthorizationRequest(\n params: PushedAuthorizationParams\n ): Promise<ParResponse> {\n const body = new URLSearchParams();\n\n body.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n body.set('redirect_uri', params.redirectUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n body.set('response_type', params.responseType);\n } else {\n body.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n body.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n body.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n body.set('request', params.request);\n }\n\n if (params.responseMode) {\n body.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n body.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n body.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n body.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n body.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n body.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n body.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n body.set('code_challenge', params.codeChallenge);\n body.set('code_challenge_method', params.codeChallengeMethod ?? 'S256');\n }\n\n if (params.state) {\n body.set('state', params.state);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'pushed_authorization_request_endpoint');\n\n const response = await innerFetch(\n metadata.pushed_authorization_request_endpoint,\n {\n body: body.toString(),\n method: 'POST',\n headers,\n }\n );\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'par_request_failed',\n standardBodyError.error_description ??\n 'Pushed Authorization Request Failed'\n );\n }\n\n if (response.status !== 201) {\n throw new MonoCloudHttpError(\n `Error while performing pushed authorization request. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<ParResponse>(response);\n }\n\n /**\n * Fetches userinfo associated with the provided access token.\n *\n * @param accessToken - A valid access token used to retrieve userinfo.\n *\n * @returns The authenticated user's claims.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error (e.g., 'invalid_token') in the 'WWW-Authenticate' header\n * following a 401 Unauthorized response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n * @throws {@link MonoCloudValidationError} - When the access token is invalid.\n *\n */\n async userinfo(accessToken: string): Promise<UserinfoResponse> {\n if (!accessToken.trim().length) {\n throw new MonoCloudValidationError(\n 'Access token is required for fetching userinfo'\n );\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'userinfo_endpoint');\n\n const response = await innerFetch(metadata.userinfo_endpoint, {\n method: 'GET',\n headers: {\n authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (response.status === 401) {\n const authenticateError = response.headers.get('WWW-Authenticate');\n\n if (authenticateError) {\n const errorMatch = /error=\"([^\"]+)\"/.exec(authenticateError);\n const error = errorMatch ? errorMatch[1] : 'userinfo_failed';\n\n const errorDescMatch = /error_description=\"([^\"]+)\"/.exec(\n authenticateError\n );\n\n const errorDescription = errorDescMatch\n ? errorDescMatch[1]\n : 'Userinfo authentication error';\n\n throw new MonoCloudOPError(error, errorDescription);\n }\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching userinfo. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<UserinfoResponse>(response);\n }\n\n /**\n * Generates OpenID end session URL for signing out.\n *\n * Note - The `state` is added only when `postLogoutRedirectUri` is present.\n *\n * @param params - Parameters to build end session URL.\n *\n * @returns Tenant's end session URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async endSessionUrl(params: EndSessionParameters): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.idToken) {\n queryParams.set('id_token_hint', params.idToken);\n }\n\n if (params.postLogoutRedirectUri) {\n queryParams.set('post_logout_redirect_uri', params.postLogoutRedirectUri);\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'end_session_endpoint');\n\n return `${metadata.end_session_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Exchanges an authorization code for tokens.\n *\n * @param code - The authorization code received from the authorization server.\n * @param redirectUri - The redirect URI used in the initial authorization request.\n * @param codeVerifier - Code verifier for PKCE.\n * @param resource - Space-separated list of resources the access token should be scoped to.\n *\n * @returns Tokens obtained by exchanging an authorization code at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async exchangeAuthorizationCode(\n code: string,\n redirectUri: string,\n codeVerifier?: string,\n resource?: string\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'authorization_code');\n body.set('code', code);\n body.set('redirect_uri', redirectUri);\n\n if (codeVerifier) {\n body.set('code_verifier', codeVerifier);\n }\n\n const resources = parseSpaceSeparated(resource) ?? [];\n\n if (resources.length > 0) {\n for (const r of resources) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'code_grant_failed',\n standardBodyError.error_description ?? 'Authorization code grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Exchanges a refresh token for new tokens.\n *\n * @param refreshToken - The refresh token used to request new tokens.\n * @param options - Refresh grant options.\n *\n * @returns Tokens obtained by exchanging a refresh token at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshGrant(\n refreshToken: string,\n options?: RefreshGrantOptions\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'refresh_token');\n body.set('refresh_token', refreshToken);\n\n const scopes = parseSpaceSeparated(options?.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n const resource = parseSpaceSeparated(options?.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'refresh_grant_failed',\n standardBodyError.error_description ?? 'Refresh token grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing refresh token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Generates a session with user and tokens by exchanging authorization code from callback params.\n *\n * @param code - The authorization code received from the callback.\n * @param redirectUri - The redirect URI that was used in the authorization request.\n * @param requestedScopes - A space-separated list of scopes originally requested via the `/authorize` endpoint.\n * This is stored in the session to ensure the correct access token can be identified and refreshed during `refreshSession()`.\n * @param resource - A space-separated list of resource indicators originally requested via the `/authorize` endpoint.\n * Used alongside scopes to uniquely identify and refresh the specific access token associated with these resources.\n * @param options - Options for authenticating a user with authorization code.\n *\n * @returns The user's session containing authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain the openid scope,\n * or if 'expires_in' or 'scope' is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized.\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authenticate(\n code: string,\n redirectUri: string,\n requestedScopes: string,\n resource?: string,\n options?: AuthenticateOptions\n ): Promise<MonoCloudSession> {\n const tokens = await this.exchangeAuthorizationCode(\n code,\n redirectUri,\n options?.codeVerifier,\n resource\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0,\n options?.idTokenMaxAge,\n options?.idTokenNonce\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const session: MonoCloudSession = {\n user: {\n ...idTokenClaims,\n ...(userinfo ?? {}),\n } as MonoCloudUser,\n idToken: tokens.id_token,\n refreshToken: tokens.refresh_token,\n authorizedScopes: requestedScopes,\n accessTokens: [\n {\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes,\n },\n ],\n };\n\n await options?.onSessionCreating?.(session, idTokenClaims, userinfo);\n\n return session;\n }\n\n /**\n * Refetches user information for an existing session using the userinfo endpoint.\n * Updates the session's user object with the latest user information while preserving existing properties.\n *\n * @param accessToken - Access token used to fetch the userinfo.\n * @param session - The current MonoCloudSession.\n * @param options - Userinfo refetch options.\n *\n * @returns Updated session with the latest userinfo.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain openid scope\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refetchUserInfo(\n accessToken: AccessToken,\n session: MonoCloudSession,\n options?: RefetchUserInfoOptions\n ): Promise<MonoCloudSession> {\n if (!accessToken.scopes?.includes('openid')) {\n throw new MonoCloudValidationError(\n 'Fetching userinfo requires the openid scope'\n );\n }\n\n const userinfo = await this.userinfo(accessToken.accessToken);\n\n // eslint-disable-next-line no-param-reassign\n session.user = { ...session.user, ...userinfo };\n\n await options?.onSessionCreating?.(session, undefined, userinfo);\n\n return session;\n }\n\n /**\n * Refreshes an existing session using the refresh token.\n * This function requests new tokens using the refresh token and optionally updates user information.\n *\n * @param session - The current MonoCloudSession containing the refresh token.\n * @param options - Session refresh options.\n *\n * @returns User's session containing refreshed authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - If the refresh token is not present in the session,\n * or if 'expires_in' or 'scope' (including the openid scope) is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshSession(\n session: MonoCloudSession,\n options?: RefreshSessionOptions\n ): Promise<MonoCloudSession> {\n if (!session.refreshToken) {\n throw new MonoCloudValidationError(\n 'Session does not contain refresh token'\n );\n }\n\n const tokens = await this.refreshGrant(\n session.refreshToken,\n options?.refreshGrantOptions\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const resource = options?.refreshGrantOptions?.resource;\n let scopes = options?.refreshGrantOptions?.scopes;\n\n if (!resource && !scopes) {\n scopes = session.authorizedScopes;\n }\n\n const accessToken = findToken(session.accessTokens, resource, scopes);\n\n const user =\n Object.keys(idTokenClaims).length === 0 && !userinfo\n ? session.user\n : ({\n ...session.user,\n ...idTokenClaims,\n ...(userinfo ?? {}),\n } as MonoCloudUser);\n\n const newTokens =\n session.accessTokens?.filter(t => t !== accessToken) ?? [];\n\n newTokens.push({\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes: scopes,\n });\n\n const updatedSession: MonoCloudSession = {\n ...session,\n user,\n idToken: tokens.id_token ?? session.idToken,\n refreshToken: tokens.refresh_token ?? session.refreshToken,\n accessTokens: newTokens,\n };\n\n await options?.onSessionCreating?.(updatedSession, idTokenClaims, userinfo);\n\n return updatedSession;\n }\n\n /**\n * Revokes an access token or refresh token, rendering it invalid for future use.\n *\n * @param token - The token string to be revoked.\n * @param tokenType - Hint about the token type ('access_token' or 'refresh_token').\n *\n * @returns If token revocation succeeded.\n *\n * @throws {@link MonoCloudValidationError} - If token is invalid or unsupported token type\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n */\n async revokeToken(token: string, tokenType?: string): Promise<void> {\n if (!token.trim().length) {\n throw new MonoCloudValidationError('Invalid token');\n }\n\n if (\n tokenType &&\n tokenType !== 'access_token' &&\n tokenType !== 'refresh_token'\n ) {\n throw new MonoCloudValidationError(\n 'Only access_token and refresh_token types are supported.'\n );\n }\n\n const body = new URLSearchParams();\n body.set('token', token);\n if (tokenType) {\n body.set('token_type_hint', tokenType);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'revocation_endpoint');\n\n const response = await innerFetch(metadata.revocation_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'revocation_failed',\n standardBodyError.error_description ?? 'Token revocation failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing revocation request. Unexpected status code: ${response.status}`\n );\n }\n }\n\n /**\n * Validates an ID Token.\n *\n * @param idToken - The ID Token JWT string to validate.\n * @param jwks - Array of JSON Web Keys (JWK) used to verify the token's signature.\n * @param clockSkew - Number of seconds to adjust the current time to account for clock differences.\n * @param clockTolerance - Additional time tolerance in seconds for time-based claim validation.\n * @param maxAge - Maximum authentication age in seconds.\n * @param nonce - Nonce value to validate against the token's nonce claim.\n *\n * @returns Validated ID Token claims.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n */\n async validateIdToken(\n idToken: string,\n jwks: Jwk[],\n clockSkew: number,\n clockTolerance: number,\n maxAge?: number,\n nonce?: string\n ): Promise<IdTokenClaims> {\n if (typeof idToken !== 'string' || idToken.trim().length === 0) {\n throw new MonoCloudTokenError(\n 'ID Token must be a valid non-empty string'\n );\n }\n\n const {\n 0: protectedHeader,\n 1: payload,\n 2: encodedSignature,\n length,\n } = idToken.split('.');\n\n if (length !== 3) {\n throw new MonoCloudTokenError(\n 'ID Token must have a header, payload and signature'\n );\n }\n\n let header: JwsHeaderParameters;\n try {\n header = JSON.parse(decodeBase64Url(protectedHeader));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Header');\n }\n\n if (\n header === null ||\n typeof header !== 'object' ||\n Array.isArray(header)\n ) {\n throw new MonoCloudTokenError('JWT Header must be a top level object');\n }\n\n if (this.idTokenSigningAlgorithm !== header.alg) {\n throw new MonoCloudTokenError('Invalid signing alg');\n }\n\n if (header.crit !== undefined) {\n throw new MonoCloudTokenError('Unexpected JWT \"crit\" header parameter');\n }\n\n const binary = decodeBase64Url(encodedSignature);\n\n const signature = new Uint8Array(binary.length);\n\n for (let i = 0; i < binary.length; i++) {\n signature[i] = binary.charCodeAt(i);\n }\n\n const key = await getPublicSigKeyFromIssuerJwks(jwks, header);\n\n const input = `${protectedHeader}.${payload}`;\n\n const verified = await crypto.subtle.verify(\n keyToSubtle(key),\n key,\n signature,\n stringToArrayBuffer(input) as BufferSource\n );\n\n if (!verified) {\n throw new MonoCloudTokenError('JWT signature verification failed');\n }\n\n let claims: IdTokenClaims;\n\n try {\n claims = JSON.parse(decodeBase64Url(payload));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Payload');\n }\n\n if (\n claims === null ||\n typeof claims !== 'object' ||\n Array.isArray(claims)\n ) {\n throw new MonoCloudTokenError('JWT Payload must be a top level object');\n }\n\n if ((claims.nonce || nonce) && claims.nonce !== nonce) {\n throw new MonoCloudTokenError('Nonce mismatch');\n }\n\n const current = now() + clockSkew;\n\n /* v8 ignore else -- @preserve */\n if (claims.exp !== undefined) {\n if (typeof claims.exp !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim type'\n );\n }\n\n if (claims.exp <= current - clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim value, timestamp is <= now()'\n );\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (claims.iat !== undefined) {\n if (typeof claims.iat !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"iat\" (issued at) claim type'\n );\n }\n }\n\n if (\n typeof claims.auth_time === 'number' &&\n typeof maxAge === 'number' &&\n claims.auth_time + maxAge < current\n ) {\n throw new MonoCloudTokenError(\n 'Too much time has elapsed since the last End-User authentication'\n );\n }\n\n if (claims.iss !== this.tenantDomain) {\n throw new MonoCloudTokenError('Invalid Issuer');\n }\n\n if (claims.nbf !== undefined) {\n if (typeof claims.nbf !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim type'\n );\n }\n\n if (claims.nbf > current + clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim value, timestamp is > now()'\n );\n }\n }\n\n const audience = Array.isArray(claims.aud) ? claims.aud : [claims.aud];\n\n if (!audience.includes(this.clientId)) {\n throw new MonoCloudTokenError('Invalid audience claim');\n }\n\n return claims;\n }\n\n /**\n * Decodes the payload of a JSON Web Token (JWT) and returns it as an object.\n *\n * >Note: THIS METHOD DOES NOT VERIFY JWT TOKENS.\n *\n * @param jwt - JWT to decode.\n *\n * @returns Decoded payload.\n *\n * @throws {@link MonoCloudTokenError} - If decoding fails\n *\n */\n static decodeJwt(jwt: string): IdTokenClaims {\n try {\n const [, payload] = jwt.split('.');\n\n if (!payload?.trim()) {\n throw new MonoCloudTokenError('JWT does not contain payload');\n }\n\n const decoded = decodeBase64Url(payload);\n\n if (!decoded.startsWith('{')) {\n throw new MonoCloudTokenError('Payload is not an object');\n }\n\n return JSON.parse(decoded) as IdTokenClaims;\n } catch (e) {\n if (e instanceof MonoCloudAuthBaseError) {\n throw e;\n }\n\n throw new MonoCloudTokenError(\n 'Could not parse payload. Malformed payload'\n );\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAOA,IAAa,yBAAb,cAA4C,MAAM;;;;;;;;;;;ACElD,IAAa,mBAAb,cAAsC,uBAAuB;CAO3D,YAAY,OAAe,kBAA2B;AACpD,QAAM,MAAM;AACZ,OAAK,QAAQ;AACb,OAAK,mBAAmB;;;;;;;;;;;;;ACV5B,IAAa,qBAAb,cAAwC,uBAAuB;;;;;;;;;ACF/D,IAAa,sBAAb,cAAyC,uBAAuB;;;;;;;;;ACAhE,IAAa,2BAAb,cAA8C,uBAAuB;;;;ACArE,MAAM,eACJ,QACiE;AACjE,SAAQ,KAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAQ,MAAM,OAAO,IAAI,MAAM,GAAG;GAAI;EACvD,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAW,MAAM,OAAO,IAAI,MAAM,GAAG;GAAI;EAC1D,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAqB,MAAM,OAAO,IAAI,MAAM,GAAG;GAAI;EACpE,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAS,YAAY,KAAK,IAAI,MAAM,GAAG;GAAI;EAC5D,KAAK,QACH,QAAO;GAAE,MAAM;GAAS,YAAY;GAAS;EAE/C,QACE,OAAM,IAAI,MAAM,4BAA4B;;;AAIlD,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAAoC,KAAK,MAAtD;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,8CAA8C;;;AAIpE,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAAoC,KAAK,MAAtD;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,8CAA8C;;;AAIpE,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAA6B,YAA1C;EACE,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,wCAAwC;;;AAI9D,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAA+B,KAAK,MAAjD;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,kCAAkC;;;AAIxD,MAAM,YAAY,QAA2B;AAC3C,SAAQ,IAAI,UAAU,MAAtB;EACE,KAAK,OACH,QAAO,MAAM,IAAI;EACnB,KAAK,UACH,QAAO,MAAM,IAAI;EACnB,KAAK,oBACH,QAAO,MAAM,IAAI;EACnB,KAAK,QACH,QAAO,MAAM,IAAI;EAEnB,QACE,OAAM,IAAI,MAAM,uCAAuC;;;AAI7D,MAAM,wBAAwB,QAAyB;CACrD,MAAM,EAAE,cAAc;;AAGtB,KACE,OAAO,UAAU,kBAAkB,YACnC,UAAU,gBAAgB,KAE1B,OAAM,IAAI,MAAM,eAAe,UAAU,KAAK,gBAAgB;;AAIlE,MAAM,iBAAiB,QAA2B;CAChD,MAAM,EAAE,cAAc;AACtB,SAAQ,UAAU,YAAlB;EACE,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,+BAA+B;;;AAIrD,MAAa,eACX,QACqD;AACrD,SAAQ,IAAI,UAAU,MAAtB;EACE,KAAK,OACH,QAAO,EAAE,MAAM,IAAI,UAAU,MAAM;EAErC,KAAK,QACH,QAAO;GACL,MAAM,IAAI,UAAU;GACpB,MAAM,cAAc,IAAI;GACzB;EACH,KAAK;AACH,wBAAqB,IAAI;AACzB,WAAS,IAAI,UAAoC,KAAK,MAAtD;IACE,KAAK;IACL,KAAK;IACL,KAAK,UACH,QAAO;KACL,MAAM,IAAI,UAAU;KACpB,YACE,SACG,IAAI,UAAoC,KAAK,KAAK,MAAM,GAAG,EAC5D,GACD,IAAI;KACR;IAEH,QACE,OAAM,IAAI,MAAM,gCAAgC;;EAGtD,KAAK;AACH,wBAAqB,IAAI;AACzB,UAAO,IAAI,UAAU;;;AAGzB,OAAM,IAAI,MAAM,uCAAuC;;AAGzD,MAAM,0BACJ,QACA,UACA,SACoC;CACpC,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,GAAG;AAC5C,QAAO;EACL,KAAKA,oCAAa;EAClB,KAAK;EACL,KAAK,MAAM;EACX,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACN;;AAGH,MAAM,wBAAwB,OAC5B,QACA,UACA,cACA,MACA,SACkB;CAClB,MAAM,MAAM,MAAM,OAAO,OAAO,UAC9B,OACA,cACA,YAAY,aAAa,IAAI,EAC7B,OACA,CAAC,OAAO,CACT;CAED,MAAM,SAAS;EAAE,KAAK,SAAS,IAAI;EAAE,KAAK,aAAa;EAAK;CAC5D,MAAM,UAAU,uBAAuB,QAAQ,UAAU,KAAK;AAE9D,MAAK,IAAI,aAAa,SAAS;AAC/B,MAAK,IACH,yBACA,yDACD;CAED,MAAM,QAAQ,GAAGC,uCAAgBC,2CAAoB,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,GAAGD,uCAAgBC,2CAAoB,KAAK,UAAU,QAAQ,CAAC,CAAC;CAC9I,MAAM,YAAYD,uCAChB,MAAM,OAAO,OAAO,KAClB,YAAY,IAAI,EAChB,KACAC,2CAAoB,MAAM,CAC3B,CACF;AAED,MAAK,IAAI,oBAAoB,GAAG,MAAM,GAAG,YAAY;;AAGvD,MAAa,aAAa,OACxB,UACA,cACA,QACA,QACA,SACA,MACA,qBACkB;AAClB,SAAQ,MAAR;EACE,KAAK,WAAW,yBAAyB,CAAC,CAAC;AAEzC,WAAQ,gBAAgB,SAAS,KAAK,GAAG,SAAS,GAAG,gBAAgB,KAAK;AAC1E;EAGF,KAAK,WAAW,wBAAwB,CAAC,CAAC;AACxC,QAAK,IAAI,aAAa,SAAS;AAC/B,OAAI,OAAO,iBAAiB,SAC1B,MAAK,IAAI,iBAAiB,aAAa;AAEzC;EAGF,KAAK,WAAW,uBACd,CAAC,CAAC,UACF,CAAC,CAAC,SACD,OAAO,iBAAiB,YAAY,cAAc,QAAQ;AAU3D,SAAM,sBACJ,QACA,UAVA,OAAO,iBAAiB,WACpB;IACE,GAAGD,uCAAgBC,2CAAoB,aAAa,CAAC;IACrD,KAAK;IACL,KAAK;IACN,GACD,cAMJ,MACA,oBAAoB,EACrB;AACD;EAGF,KAAK,WAAW,qBACd,OAAO,iBAAiB,YACxB,aAAa,QAAQ,SACrB,CAAC,CAAC,UACF,CAAC,CAAC;AACF,SAAM,sBACJ,QACA,UACA,cACA,MACA,oBAAoB,EACrB;AACD;EAGF,QACE,OAAM,IAAI,MAAM,uCAAuC;;;;;;AC1P7D,MAAM,2BAA2B;AAEjC,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,uBACP,UACA,UACwE;AACxE,KAAI,SAAS,cAAc,UAAa,SAAS,cAAc,KAC7D,OAAM,IAAI,yBACR,GAAG,SAAmB,gEACvB;;AAIL,MAAM,aAAa,OACjB,OACA,UAAuB,EAAE,KACH;AACtB,KAAI;AACF,SAAO,MAAM,MAAM,OAAO,QAAQ;UAC3B,GAAG;;AAEV,QAAM,IAAI,mBACP,EAAU,WAAW,2BACvB;;;AAIL,MAAM,kBAAkB,OAAgB,QAA8B;AACpE,KAAI;AACF,SAAO,MAAM,IAAI,MAAM;UAChB,GAAG;AACV,QAAM,IAAI;;GAER,yCAA0C,EAAU,UAAU,KAAM,EAAU,YAAY;GAC3F;;;;;;AAOL,IAAa,sBAAb,MAAa,oBAAoB;CAuB/B,YACE,cACA,UACA,SACA;yBAdwB;2BAEE;6BAIE;+BAEE;AAQ9B,mBAAiB;;AAEjB,OAAK,eAAe,GAAG,CAAC,aAAa,WAAW,WAAW,GAAG,aAAa,KAAK,aAAa,SAAS,IAAI,GAAG,aAAa,MAAM,GAAG,GAAG,GAAG;AACzI,OAAK,WAAW;AAChB,OAAK,eAAe,SAAS;AAC7B,OAAK,aAAa,SAAS,oBAAoB;AAC/C,OAAK,0BAA0B,SAAS,2BAA2B;AAEnE,MAAI,SAAS,kBACX,MAAK,oBAAoB,QAAQ;AAGnC,MAAI,SAAS,sBACX,MAAK,wBAAwB,QAAQ;;;;;;;;;;;;;;;CAiBzC,MAAM,iBAAiB,QAA8C;EACnE,MAAM,cAAc,IAAI,iBAAiB;AAEzC,cAAY,IAAI,aAAa,KAAK,SAAS;AAE3C,MAAI,OAAO,YACT,aAAY,IAAI,gBAAgB,OAAO,YAAY;AAGrD,MAAI,OAAO,WACT,aAAY,IAAI,eAAe,OAAO,WAAW;EAGnD,MAAM,SAASC,2CAAoB,OAAO,OAAO,IAAI,EAAE;AAEvD,MAAI,OAAO,SAAS,EAClB,aAAY,IAAI,SAAS,OAAO,KAAK,IAAI,CAAC;AAG5C,MAAI,OAAO,gBAAgB,OAAO,aAAa,SAAS,EACtD,aAAY,IAAI,iBAAiB,OAAO,aAAa;AAGvD,OACG,CAAC,OAAO,gBAAgB,OAAO,aAAa,WAAW,MACxD,CAAC,OAAO,WAER,aAAY,IAAI,iBAAiB,OAAO;AAG1C,MAAI,OAAO,kBACT,aAAY,IAAI,sBAAsB,OAAO,kBAAkB;AAGjE,MAAI,OAAO,UACT,aAAY,IAAI,cAAc,OAAO,UAAU;AAGjD,MAAI,OAAO,QACT,aAAY,IAAI,WAAW,OAAO,QAAQ;AAG5C,MAAI,OAAO,aACT,aAAY,IAAI,iBAAiB,OAAO,aAAa;AAGvD,MAAI,OAAO,aAAa,OAAO,UAAU,SAAS,EAChD,aAAY,IAAI,cAAc,OAAO,UAAU,KAAK,IAAI,CAAC;AAG3D,MAAI,OAAO,MACT,aAAY,IAAI,SAAS,OAAO,MAAM;AAGxC,MAAI,OAAO,UACT,aAAY,IAAI,cAAc,OAAO,UAAU;AAGjD,MAAI,OAAO,QACT,aAAY,IAAI,WAAW,OAAO,QAAQ;AAG5C,MAAI,OAAO,OAAO,WAAW,SAC3B,aAAY,IAAI,WAAW,OAAO,OAAO,UAAU,CAAC;AAGtD,MAAI,OAAO,OACT,aAAY,IAAI,UAAU,OAAO,OAAO;EAG1C,MAAM,WAAWA,2CAAoB,OAAO,SAAS,IAAI,EAAE;AAE3D,MAAI,SAAS,SAAS,EACpB,MAAK,MAAM,KAAK,SACd,aAAY,OAAO,YAAY,EAAE;AAIrC,MAAI,OAAO,eAAe;AACxB,eAAY,IAAI,kBAAkB,OAAO,cAAc;AACvD,eAAY,IACV,yBACA,OAAO,uBAAuB,OAC/B;;AAGH,MAAI,OAAO,MACT,aAAY,IAAI,SAAS,OAAO,MAAM;EAGxC,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,yBAAyB;AAE1D,SAAO,GAAG,SAAS,uBAAuB,GAAG,YAAY,UAAU;;;;;;;;;;;;;;CAerE,MAAM,YAAY,eAAe,OAAgC;AAC/D,MAAI,CAAC,gBAAgB,KAAK,YAAY,KAAK,sBAAsBC,4BAAK,CACpE,QAAO,KAAK;AAGd,OAAK,WAAW;EAEhB,MAAM,WAAW,MAAM,WACrB,GAAG,KAAK,aAAa,mCACtB;AAED,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,0DAA0D,SAAS,SACpE;EAGH,MAAM,WAAW,MAAM,gBAAgC,SAAS;AAEhE,OAAK,WAAW;AAChB,OAAK,sBAAsBA,4BAAK,GAAG,KAAK;AAExC,SAAO;;;;;;;;;;;;;;CAeT,MAAM,QAAQ,eAAe,OAAsB;AACjD,MAAI,CAAC,gBAAgB,KAAK,QAAQ,KAAK,kBAAkBA,4BAAK,CAC5D,QAAO,KAAK;AAGd,OAAK,OAAO;EAEZ,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,WAAW;EAE5C,MAAM,WAAW,MAAM,WAAW,SAAS,SAAS;AAEpD,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,sDAAsD,SAAS,SAChE;EAEH,MAAM,OAAO,MAAM,gBAAsB,SAAS;AAElD,OAAK,OAAO;AACZ,OAAK,kBAAkBA,4BAAK,GAAG,KAAK;AAEpC,SAAO;;;;;;;;;;;;;;;CAgBT,MAAM,2BACJ,QACsB;EACtB,MAAM,OAAO,IAAI,iBAAiB;AAElC,OAAK,IAAI,aAAa,KAAK,SAAS;AAEpC,MAAI,OAAO,YACT,MAAK,IAAI,gBAAgB,OAAO,YAAY;EAG9C,MAAM,SAASD,2CAAoB,OAAO,OAAO,IAAI,EAAE;AAEvD,MAAI,OAAO,SAAS,EAClB,MAAK,IAAI,SAAS,OAAO,KAAK,IAAI,CAAC;AAGrC,MAAI,OAAO,gBAAgB,OAAO,aAAa,SAAS,EACtD,MAAK,IAAI,iBAAiB,OAAO,aAAa;MAE9C,MAAK,IAAI,iBAAiB,OAAO;AAGnC,MAAI,OAAO,kBACT,MAAK,IAAI,sBAAsB,OAAO,kBAAkB;AAG1D,MAAI,OAAO,UACT,MAAK,IAAI,cAAc,OAAO,UAAU;AAG1C,MAAI,OAAO,QACT,MAAK,IAAI,WAAW,OAAO,QAAQ;AAGrC,MAAI,OAAO,aACT,MAAK,IAAI,iBAAiB,OAAO,aAAa;AAGhD,MAAI,OAAO,aAAa,OAAO,UAAU,SAAS,EAChD,MAAK,IAAI,cAAc,OAAO,UAAU,KAAK,IAAI,CAAC;AAGpD,MAAI,OAAO,MACT,MAAK,IAAI,SAAS,OAAO,MAAM;AAGjC,MAAI,OAAO,UACT,MAAK,IAAI,cAAc,OAAO,UAAU;AAG1C,MAAI,OAAO,QACT,MAAK,IAAI,WAAW,OAAO,QAAQ;AAGrC,MAAI,OAAO,OAAO,WAAW,SAC3B,MAAK,IAAI,WAAW,OAAO,OAAO,UAAU,CAAC;AAG/C,MAAI,OAAO,OACT,MAAK,IAAI,UAAU,OAAO,OAAO;EAGnC,MAAM,WAAWA,2CAAoB,OAAO,SAAS,IAAI,EAAE;AAE3D,MAAI,SAAS,SAAS,EACpB,MAAK,MAAM,KAAK,SACd,MAAK,OAAO,YAAY,EAAE;AAI9B,MAAI,OAAO,eAAe;AACxB,QAAK,IAAI,kBAAkB,OAAO,cAAc;AAChD,QAAK,IAAI,yBAAyB,OAAO,uBAAuB,OAAO;;AAGzE,MAAI,OAAO,MACT,MAAK,IAAI,SAAS,OAAO,MAAM;EAGjC,MAAM,UAAU;GACd,gBAAgB;GAChB,QAAQ;GACT;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,wCAAwC;EAEzE,MAAM,WAAW,MAAM,WACrB,SAAS,uCACT;GACE,MAAM,KAAK,UAAU;GACrB,QAAQ;GACR;GACD,CACF;AAED,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,sBAC3B,kBAAkB,qBAChB,sCACH;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,gFAAgF,SAAS,SAC1F;AAGH,SAAO,MAAM,gBAA6B,SAAS;;;;;;;;;;;;;;;;;;;CAoBrD,MAAM,SAAS,aAAgD;AAC7D,MAAI,CAAC,YAAY,MAAM,CAAC,OACtB,OAAM,IAAI,yBACR,iDACD;EAGH,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,oBAAoB;EAErD,MAAM,WAAW,MAAM,WAAW,SAAS,mBAAmB;GAC5D,QAAQ;GACR,SAAS,EACP,eAAe,UAAU,eAC1B;GACF,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,SAAS,QAAQ,IAAI,mBAAmB;AAElE,OAAI,mBAAmB;IACrB,MAAM,aAAa,kBAAkB,KAAK,kBAAkB;IAC5D,MAAM,QAAQ,aAAa,WAAW,KAAK;IAE3C,MAAM,iBAAiB,8BAA8B,KACnD,kBACD;AAMD,UAAM,IAAI,iBAAiB,OAJF,iBACrB,eAAe,KACf,gCAE+C;;;AAIvD,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,0DAA0D,SAAS,SACpE;AAGH,SAAO,MAAM,gBAAkC,SAAS;;;;;;;;;;;;;;;CAgB1D,MAAM,cAAc,QAA+C;EACjE,MAAM,cAAc,IAAI,iBAAiB;AAEzC,cAAY,IAAI,aAAa,KAAK,SAAS;AAE3C,MAAI,OAAO,QACT,aAAY,IAAI,iBAAiB,OAAO,QAAQ;AAGlD,MAAI,OAAO,uBAAuB;AAChC,eAAY,IAAI,4BAA4B,OAAO,sBAAsB;AAEzE,OAAI,OAAO,MACT,aAAY,IAAI,SAAS,OAAO,MAAM;;EAI1C,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,uBAAuB;AAExD,SAAO,GAAG,SAAS,qBAAqB,GAAG,YAAY,UAAU;;;;;;;;;;;;;;;;;;;CAoBnE,MAAM,0BACJ,MACA,aACA,cACA,UACiB;EACjB,MAAM,OAAO,IAAI,iBAAiB;AAElC,OAAK,IAAI,cAAc,qBAAqB;AAC5C,OAAK,IAAI,QAAQ,KAAK;AACtB,OAAK,IAAI,gBAAgB,YAAY;AAErC,MAAI,aACF,MAAK,IAAI,iBAAiB,aAAa;EAGzC,MAAM,YAAYA,2CAAoB,SAAS,IAAI,EAAE;AAErD,MAAI,UAAU,SAAS,EACrB,MAAK,MAAM,KAAK,UACd,MAAK,OAAO,YAAY,EAAE;EAI9B,MAAM,UAAU;GACd,gBAAgB;GAChB,QAAQ;GACT;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,iBAAiB;EAElD,MAAM,WAAW,MAAM,WAAW,SAAS,gBAAgB;GACzD,QAAQ;GACR,MAAM,KAAK,UAAU;GACrB;GACD,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,qBAC3B,kBAAkB,qBAAqB,kCACxC;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,+DAA+D,SAAS,SACzE;AAGH,SAAO,MAAM,gBAAwB,SAAS;;;;;;;;;;;;;;;;;CAkBhD,MAAM,aACJ,cACA,SACiB;EACjB,MAAM,OAAO,IAAI,iBAAiB;AAElC,OAAK,IAAI,cAAc,gBAAgB;AACvC,OAAK,IAAI,iBAAiB,aAAa;EAEvC,MAAM,SAASA,2CAAoB,SAAS,OAAO,IAAI,EAAE;AAEzD,MAAI,OAAO,SAAS,EAClB,MAAK,IAAI,SAAS,OAAO,KAAK,IAAI,CAAC;EAGrC,MAAM,WAAWA,2CAAoB,SAAS,SAAS,IAAI,EAAE;AAE7D,MAAI,SAAS,SAAS,EACpB,MAAK,MAAM,KAAK,SACd,MAAK,OAAO,YAAY,EAAE;EAI9B,MAAM,UAAU;GACd,gBAAgB;GAChB,QAAQ;GACT;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,iBAAiB;EAElD,MAAM,WAAW,MAAM,WAAW,SAAS,gBAAgB;GACzD,QAAQ;GACR,MAAM,KAAK,UAAU;GACrB;GACD,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,wBAC3B,kBAAkB,qBAAqB,6BACxC;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,uEAAuE,SAAS,SACjF;AAGH,SAAO,MAAM,gBAAwB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BhD,MAAM,aACJ,MACA,aACA,iBACA,UACA,SAC2B;EAC3B,MAAM,SAAS,MAAM,KAAK,0BACxB,MACA,aACA,SAAS,cACT,SACD;EAED,MAAM,wBACJ,OAAO,OAAO,eAAe,WACzBC,4BAAK,GAAG,OAAO,aACf;AAEN,MAAI,CAAC,sBACH,OAAM,IAAI,yBAAyB,sCAAsC;AAG3E,MAAI,CAAC,OAAO,MACV,OAAM,IAAI,yBAAyB,mCAAmC;EAGxE,IAAI;AAEJ,MAAI,SAAS,iBAAiB,OAAO,OAAO,SAAS,SAAS,CAC5D,YAAW,MAAM,KAAK,SAAS,OAAO,aAAa;EAGrD,IAAI,gBAAwC,EAAE;AAE9C,MAAI,OAAO,SACT,KAAI,SAAS,mBAAmB,MAAM;GACpC,MAAM,OAAO,SAAS,QAAS,MAAM,KAAK,SAAS;AAEnD,mBAAgB,MAAM,KAAK,gBACzB,OAAO,UACP,KAAK,MACL,SAAS,oBAAoB,GAC7B,SAAS,yBAAyB,GAClC,SAAS,eACT,SAAS,aACV;QAED,iBAAgB,oBAAoB,UAAU,OAAO,SAAS;AAIlE,GAAC,SAAS,yBAAyB,wBAAwB,SAAQ,MAAK;AAEtE,UAAO,cAAc;IACrB;EAEF,MAAM,UAA4B;GAChC,MAAM;IACJ,GAAG;IACH,GAAI,YAAY,EAAE;IACnB;GACD,SAAS,OAAO;GAChB,cAAc,OAAO;GACrB,kBAAkB;GAClB,cAAc,CACZ;IACE,QAAQ,OAAO;IACf,aAAa,OAAO;IACpB;IACA;IACA;IACD,CACF;GACF;AAED,QAAM,SAAS,oBAAoB,SAAS,eAAe,SAAS;AAEpE,SAAO;;;;;;;;;;;;;;;;;;;;;;;CAwBT,MAAM,gBACJ,aACA,SACA,SAC2B;AAC3B,MAAI,CAAC,YAAY,QAAQ,SAAS,SAAS,CACzC,OAAM,IAAI,yBACR,8CACD;EAGH,MAAM,WAAW,MAAM,KAAK,SAAS,YAAY,YAAY;AAG7D,UAAQ,OAAO;GAAE,GAAG,QAAQ;GAAM,GAAG;GAAU;AAE/C,QAAM,SAAS,oBAAoB,SAAS,QAAW,SAAS;AAEhE,SAAO;;;;;;;;;;;;;;;;;;;;;;;CAwBT,MAAM,eACJ,SACA,SAC2B;AAC3B,MAAI,CAAC,QAAQ,aACX,OAAM,IAAI,yBACR,yCACD;EAGH,MAAM,SAAS,MAAM,KAAK,aACxB,QAAQ,cACR,SAAS,oBACV;EAED,MAAM,wBACJ,OAAO,OAAO,eAAe,WACzBA,4BAAK,GAAG,OAAO,aACf;AAEN,MAAI,CAAC,sBACH,OAAM,IAAI,yBAAyB,sCAAsC;AAG3E,MAAI,CAAC,OAAO,MACV,OAAM,IAAI,yBAAyB,mCAAmC;EAGxE,IAAI;AAEJ,MAAI,SAAS,iBAAiB,OAAO,OAAO,SAAS,SAAS,CAC5D,YAAW,MAAM,KAAK,SAAS,OAAO,aAAa;EAGrD,IAAI,gBAAwC,EAAE;AAE9C,MAAI,OAAO,SACT,KAAI,SAAS,mBAAmB,MAAM;GACpC,MAAM,OAAO,SAAS,QAAS,MAAM,KAAK,SAAS;AAEnD,mBAAgB,MAAM,KAAK,gBACzB,OAAO,UACP,KAAK,MACL,SAAS,oBAAoB,GAC7B,SAAS,yBAAyB,EACnC;QAED,iBAAgB,oBAAoB,UAAU,OAAO,SAAS;AAIlE,GAAC,SAAS,yBAAyB,wBAAwB,SAAQ,MAAK;AAEtE,UAAO,cAAc;IACrB;EAEF,MAAM,WAAW,SAAS,qBAAqB;EAC/C,IAAI,SAAS,SAAS,qBAAqB;AAE3C,MAAI,CAAC,YAAY,CAAC,OAChB,UAAS,QAAQ;EAGnB,MAAM,cAAcC,iCAAU,QAAQ,cAAc,UAAU,OAAO;EAErE,MAAM,OACJ,OAAO,KAAK,cAAc,CAAC,WAAW,KAAK,CAAC,WACxC,QAAQ,OACP;GACC,GAAG,QAAQ;GACX,GAAG;GACH,GAAI,YAAY,EAAE;GACnB;EAEP,MAAM,YACJ,QAAQ,cAAc,QAAO,MAAK,MAAM,YAAY,IAAI,EAAE;AAE5D,YAAU,KAAK;GACb,QAAQ,OAAO;GACf,aAAa,OAAO;GACpB;GACA;GACA,iBAAiB;GAClB,CAAC;EAEF,MAAM,iBAAmC;GACvC,GAAG;GACH;GACA,SAAS,OAAO,YAAY,QAAQ;GACpC,cAAc,OAAO,iBAAiB,QAAQ;GAC9C,cAAc;GACf;AAED,QAAM,SAAS,oBAAoB,gBAAgB,eAAe,SAAS;AAE3E,SAAO;;;;;;;;;;;;;;;;;;CAmBT,MAAM,YAAY,OAAe,WAAmC;AAClE,MAAI,CAAC,MAAM,MAAM,CAAC,OAChB,OAAM,IAAI,yBAAyB,gBAAgB;AAGrD,MACE,aACA,cAAc,kBACd,cAAc,gBAEd,OAAM,IAAI,yBACR,2DACD;EAGH,MAAM,OAAO,IAAI,iBAAiB;AAClC,OAAK,IAAI,SAAS,MAAM;AACxB,MAAI,UACF,MAAK,IAAI,mBAAmB,UAAU;EAGxC,MAAM,UAAU,EACd,gBAAgB,qCACjB;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,sBAAsB;EAEvD,MAAM,WAAW,MAAM,WAAW,SAAS,qBAAqB;GAC9D,QAAQ;GACR,MAAM,KAAK,UAAU;GACrB;GACD,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,qBAC3B,kBAAkB,qBAAqB,0BACxC;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,sEAAsE,SAAS,SAChF;;;;;;;;;;;;;;;;;CAmBL,MAAM,gBACJ,SACA,MACA,WACA,gBACA,QACA,OACwB;AACxB,MAAI,OAAO,YAAY,YAAY,QAAQ,MAAM,CAAC,WAAW,EAC3D,OAAM,IAAI,oBACR,4CACD;EAGH,MAAM,EACJ,GAAG,iBACH,GAAG,SACH,GAAG,kBACH,WACE,QAAQ,MAAM,IAAI;AAEtB,MAAI,WAAW,EACb,OAAM,IAAI,oBACR,qDACD;EAGH,IAAI;AACJ,MAAI;AACF,YAAS,KAAK,MAAMC,uCAAgB,gBAAgB,CAAC;UAC/C;AACN,SAAM,IAAI,oBAAoB,6BAA6B;;AAG7D,MACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,OAAO,CAErB,OAAM,IAAI,oBAAoB,wCAAwC;AAGxE,MAAI,KAAK,4BAA4B,OAAO,IAC1C,OAAM,IAAI,oBAAoB,sBAAsB;AAGtD,MAAI,OAAO,SAAS,OAClB,OAAM,IAAI,oBAAoB,2CAAyC;EAGzE,MAAM,SAASA,uCAAgB,iBAAiB;EAEhD,MAAM,YAAY,IAAI,WAAW,OAAO,OAAO;AAE/C,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IACjC,WAAU,KAAK,OAAO,WAAW,EAAE;EAGrC,MAAM,MAAM,MAAMC,qDAA8B,MAAM,OAAO;EAE7D,MAAM,QAAQ,GAAG,gBAAgB,GAAG;AASpC,MAAI,CAPa,MAAM,OAAO,OAAO,OACnC,YAAY,IAAI,EAChB,KACA,WACAC,2CAAoB,MAAM,CAC3B,CAGC,OAAM,IAAI,oBAAoB,oCAAoC;EAGpE,IAAI;AAEJ,MAAI;AACF,YAAS,KAAK,MAAMF,uCAAgB,QAAQ,CAAC;UACvC;AACN,SAAM,IAAI,oBAAoB,8BAA8B;;AAG9D,MACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,OAAO,CAErB,OAAM,IAAI,oBAAoB,yCAAyC;AAGzE,OAAK,OAAO,SAAS,UAAU,OAAO,UAAU,MAC9C,OAAM,IAAI,oBAAoB,iBAAiB;EAGjD,MAAM,UAAUF,4BAAK,GAAG;;AAGxB,MAAI,OAAO,QAAQ,QAAW;AAC5B,OAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,oBACR,sDACD;AAGH,OAAI,OAAO,OAAO,UAAU,eAC1B,OAAM,IAAI,oBACR,8EACD;;;AAKL,MAAI,OAAO,QAAQ,QACjB;OAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,oBACR,gDACD;;AAIL,MACE,OAAO,OAAO,cAAc,YAC5B,OAAO,WAAW,YAClB,OAAO,YAAY,SAAS,QAE5B,OAAM,IAAI,oBACR,mEACD;AAGH,MAAI,OAAO,QAAQ,KAAK,aACtB,OAAM,IAAI,oBAAoB,iBAAiB;AAGjD,MAAI,OAAO,QAAQ,QAAW;AAC5B,OAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,oBACR,iDACD;AAGH,OAAI,OAAO,MAAM,UAAU,eACzB,OAAM,IAAI,oBACR,wEACD;;AAML,MAAI,EAFa,MAAM,QAAQ,OAAO,IAAI,GAAG,OAAO,MAAM,CAAC,OAAO,IAAI,EAExD,SAAS,KAAK,SAAS,CACnC,OAAM,IAAI,oBAAoB,yBAAyB;AAGzD,SAAO;;;;;;;;;;;;;;CAeT,OAAO,UAAU,KAA4B;AAC3C,MAAI;GACF,MAAM,GAAG,WAAW,IAAI,MAAM,IAAI;AAElC,OAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,oBAAoB,+BAA+B;GAG/D,MAAM,UAAUE,uCAAgB,QAAQ;AAExC,OAAI,CAAC,QAAQ,WAAW,IAAI,CAC1B,OAAM,IAAI,oBAAoB,2BAA2B;AAG3D,UAAO,KAAK,MAAM,QAAQ;WACnB,GAAG;AACV,OAAI,aAAa,uBACf,OAAM;AAGR,SAAM,IAAI,oBACR,6CACD"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["randomBytes","encodeBase64Url","stringToArrayBuffer","parseSpaceSeparated","now","profileSync","findToken","decodeBase64Url","getPublicSigKeyFromIssuerJwks","stringToArrayBuffer"],"sources":["../src/errors/monocloud-auth-base-error.ts","../src/errors/monocloud-op-error.ts","../src/errors/monocloud-http-error.ts","../src/errors/monocloud-token-error.ts","../src/errors/monocloud-validation-error.ts","../src/client-auth.ts","../src/monocloud-oidc-client.ts"],"sourcesContent":["/**\n * Base class for all MonoCloud authentication errors.\n *\n * All errors thrown by the MonoCloud SDK extend this class, allowing applications to safely detect and handle MonoCloud-specific failures using `instanceof`.\n *\n * @category Error Classes\n */\nexport class MonoCloudAuthBaseError extends Error {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * OAuth error returned by the authorization server during an authentication or token request.\n *\n * These errors correspond to standard OAuth / OpenID Connect error responses such as `invalid_request`, `access_denied`, or `invalid_grant`.\n *\n * @category Error Classes\n */\nexport class MonoCloudOPError extends MonoCloudAuthBaseError {\n /** OAuth error code returned by the authorization server. */\n error: string;\n\n /** Human-readable description of the error. */\n errorDescription?: string;\n\n constructor(error: string, errorDescription?: string) {\n super(error);\n this.error = error;\n this.errorDescription = errorDescription;\n }\n}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a request to the MonoCloud authorization server fails.\n *\n * This error typically indicates a network failure, an unexpected HTTP response, or an unsuccessful response returned by the authorization server.\n *\n * @category Error Classes\n */\nexport class MonoCloudHttpError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a token operation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudTokenError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when validation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudValidationError extends MonoCloudAuthBaseError {}\n","import {\n encodeBase64Url,\n randomBytes,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { ClientAuthMethod, Jwk } from './types';\n\nconst algToSubtle = (\n alg?: string\n): HmacImportParams | RsaHashedImportParams | EcKeyImportParams => {\n switch (alg) {\n case 'HS256':\n case 'HS384':\n case 'HS512':\n return { name: 'HMAC', hash: `SHA-${alg.slice(-3)}` };\n case 'PS256':\n case 'PS384':\n case 'PS512':\n return { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n case 'RS256':\n case 'RS384':\n case 'RS512':\n return { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n case 'ES256':\n case 'ES384':\n return { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n case 'ES512':\n return { name: 'ECDSA', namedCurve: 'P-521' };\n /* v8 ignore next */\n default:\n throw new Error('unsupported JWS algorithm');\n }\n};\n\nconst psAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'PS256';\n case 'SHA-384':\n return 'PS384';\n case 'SHA-512':\n return 'PS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst rsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'RS256';\n case 'SHA-384':\n return 'RS384';\n case 'SHA-512':\n return 'RS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst esAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as EcKeyAlgorithm).namedCurve) {\n case 'P-256':\n return 'ES256';\n case 'P-384':\n return 'ES384';\n case 'P-521':\n return 'ES512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported EcKeyAlgorithm namedCurve');\n }\n};\n\nconst hsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as HmacKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'HS256';\n case 'SHA-384':\n return 'HS384';\n case 'SHA-512':\n return 'HS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported HMAC Algorithm hash');\n }\n};\n\nconst keyToJws = (key: CryptoKey): string => {\n switch (key.algorithm.name) {\n case 'HMAC':\n return hsAlg(key);\n case 'RSA-PSS':\n return psAlg(key);\n case 'RSASSA-PKCS1-v1_5':\n return rsAlg(key);\n case 'ECDSA':\n return esAlg(key);\n /* v8 ignore next */\n default:\n throw new Error('unsupported CryptoKey algorithm name');\n }\n};\n\nconst checkRsaKeyAlgorithm = (key: CryptoKey): void => {\n const { algorithm } = key as CryptoKey & { algorithm: RsaHashedKeyAlgorithm };\n\n /* v8 ignore if -- @preserve */\n if (\n typeof algorithm.modulusLength !== 'number' ||\n algorithm.modulusLength < 2048\n ) {\n throw new Error(`Unsupported ${algorithm.name} modulusLength`);\n }\n};\n\nconst ecdsaHashName = (key: CryptoKey): string => {\n const { algorithm } = key as CryptoKey & { algorithm: EcKeyAlgorithm };\n switch (algorithm.namedCurve) {\n case 'P-256':\n return 'SHA-256';\n case 'P-384':\n return 'SHA-384';\n case 'P-521':\n return 'SHA-512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported ECDSA namedCurve');\n }\n};\n\nexport const keyToSubtle = (\n key: CryptoKey\n): AlgorithmIdentifier | RsaPssParams | EcdsaParams => {\n switch (key.algorithm.name) {\n case 'HMAC': {\n return { name: key.algorithm.name };\n }\n case 'ECDSA':\n return {\n name: key.algorithm.name,\n hash: ecdsaHashName(key),\n } as EcdsaParams;\n case 'RSA-PSS': {\n checkRsaKeyAlgorithm(key);\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256': // Fall through\n case 'SHA-384': // Fall through\n case 'SHA-512':\n return {\n name: key.algorithm.name,\n saltLength:\n parseInt(\n (key.algorithm as RsaHashedKeyAlgorithm).hash.name.slice(-3),\n 10\n ) >> 3,\n } as RsaPssParams;\n /* v8 ignore next */\n default:\n throw new Error('unsupported RSA-PSS hash name');\n }\n }\n case 'RSASSA-PKCS1-v1_5':\n checkRsaKeyAlgorithm(key);\n return key.algorithm.name;\n }\n /* v8 ignore next -- @preserve */\n throw new Error('unsupported CryptoKey algorithm name');\n};\n\nconst clientAssertionPayload = (\n issuer: string,\n clientId: string,\n skew: number\n): Record<string, number | string> => {\n const now = Math.floor(Date.now() / 1000) + skew;\n return {\n jti: randomBytes(),\n aud: issuer,\n exp: now + 60,\n iat: now,\n nbf: now,\n iss: clientId,\n sub: clientId,\n };\n};\n\nconst jwtAssertionGenerator = async (\n issuer: string,\n clientId: string,\n clientSecret: Jwk,\n body: URLSearchParams,\n skew: number\n): Promise<void> => {\n const key = await crypto.subtle.importKey(\n 'jwk',\n clientSecret as JsonWebKey,\n algToSubtle(clientSecret.alg),\n false,\n ['sign']\n );\n\n const header = { alg: keyToJws(key), kid: clientSecret.kid };\n const payload = clientAssertionPayload(issuer, clientId, skew);\n\n body.set('client_id', clientId);\n body.set(\n 'client_assertion_type',\n 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\n );\n\n const input = `${encodeBase64Url(stringToArrayBuffer(JSON.stringify(header)))}.${encodeBase64Url(stringToArrayBuffer(JSON.stringify(payload)))}`;\n const signature = encodeBase64Url(\n await crypto.subtle.sign(\n keyToSubtle(key),\n key,\n stringToArrayBuffer(input) as BufferSource\n )\n );\n\n body.set('client_assertion', `${input}.${signature}`);\n};\n\nexport const clientAuth = async (\n clientId: string,\n clientSecret?: string | Jwk,\n method?: ClientAuthMethod,\n issuer?: string,\n headers?: Record<string, string>,\n body?: URLSearchParams,\n jwtAssertionSkew?: number\n): Promise<void> => {\n switch (true) {\n case method === 'client_secret_basic' && !!headers: {\n // eslint-disable-next-line no-param-reassign\n headers.authorization = `Basic ${btoa(`${clientId}:${clientSecret ?? ''}`)}`;\n break;\n }\n\n case method === 'client_secret_post' && !!body: {\n body.set('client_id', clientId);\n if (typeof clientSecret === 'string') {\n body.set('client_secret', clientSecret);\n }\n break;\n }\n\n case method === 'client_secret_jwt' &&\n !!issuer &&\n !!body &&\n (typeof clientSecret === 'string' || clientSecret?.kty === 'oct'): {\n const cs =\n typeof clientSecret === 'string'\n ? {\n k: encodeBase64Url(stringToArrayBuffer(clientSecret)),\n kty: 'oct',\n alg: 'HS256',\n }\n : clientSecret;\n\n await jwtAssertionGenerator(\n issuer,\n clientId,\n cs,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n case method === 'private_key_jwt' &&\n typeof clientSecret === 'object' &&\n clientSecret.kty !== 'oct' &&\n !!issuer &&\n !!body: {\n await jwtAssertionGenerator(\n issuer,\n clientId,\n clientSecret,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n default:\n throw new Error('Invalid Client Authentication Method');\n }\n};\n","import {\n decodeBase64Url,\n findToken,\n profileSync,\n getPublicSigKeyFromIssuerJwks,\n now,\n parseSpaceSeparated,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { clientAuth, keyToSubtle } from './client-auth';\nimport {\n AccessToken,\n AuthenticateOptions,\n AuthorizationParams,\n ClientAuthMethod,\n EndSessionParameters,\n IdTokenClaims,\n IssuerMetadata,\n Jwk,\n Jwks,\n SecurityAlgorithms,\n JwsHeaderParameters,\n MonoCloudClientOptions,\n MonoCloudSession,\n MonoCloudUser,\n ParResponse,\n PushedAuthorizationParams,\n RefetchUserInfoOptions,\n RefreshGrantOptions,\n RefreshSessionOptions,\n Tokens,\n UserinfoResponse,\n} from './types';\nimport { MonoCloudOPError } from './errors/monocloud-op-error';\nimport { MonoCloudHttpError } from './errors/monocloud-http-error';\nimport { MonoCloudValidationError } from './errors/monocloud-validation-error';\nimport { MonoCloudTokenError } from './errors/monocloud-token-error';\nimport { MonoCloudAuthBaseError } from './errors/monocloud-auth-base-error';\n\nconst JWT_ASSERTION_CLOCK_SKEW = 5;\n\nconst FILTER_ID_TOKEN_CLAIMS = [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n];\n\nfunction assertMetadataProperty<K extends keyof IssuerMetadata>(\n metadata: IssuerMetadata,\n property: K\n): asserts metadata is IssuerMetadata & Required<Pick<IssuerMetadata, K>> {\n if (metadata[property] === undefined || metadata[property] === null) {\n throw new MonoCloudValidationError(\n `${property as string} endpoint is required but not available in the issuer metadata`\n );\n }\n}\n\nconst innerFetch = async (\n input: string,\n reqInit: RequestInit = {}\n): Promise<Response> => {\n try {\n return await fetch(input, reqInit);\n } catch (e) {\n /* v8 ignore next -- @preserve */\n throw new MonoCloudHttpError(\n (e as any).message ?? 'Unexpected Network Error'\n );\n }\n};\n\nconst deserializeJson = async <T = any>(res: Response): Promise<T> => {\n try {\n return await res.json();\n } catch (e) {\n throw new MonoCloudHttpError(\n /* v8 ignore next -- @preserve */\n `Failed to parse response body as JSON ${(e as any).message ? `: ${(e as any).message}` : ''}`\n );\n }\n};\n\n/**\n * @category Classes\n */\nexport class MonoCloudOidcClient {\n private readonly tenantDomain: string;\n\n private readonly clientId: string;\n\n private readonly clientSecret?: string | Jwk;\n\n private readonly authMethod: ClientAuthMethod;\n\n private readonly idTokenSigningAlgorithm: SecurityAlgorithms;\n\n private jwks?: Jwks;\n\n private jwksCacheExpiry = 0;\n\n private jwksCacheDuration = 300;\n\n private metadata?: IssuerMetadata;\n\n private metadataCacheExpiry = 0;\n\n private metadataCacheDuration = 300;\n\n constructor(\n tenantDomain: string,\n clientId: string,\n options?: MonoCloudClientOptions\n ) {\n // eslint-disable-next-line no-param-reassign\n tenantDomain ??= '';\n /* v8 ignore next -- @preserve */\n this.tenantDomain = `${!tenantDomain.startsWith('https://') ? 'https://' : ''}${tenantDomain.endsWith('/') ? tenantDomain.slice(0, -1) : tenantDomain}`;\n this.clientId = clientId;\n this.clientSecret = options?.clientSecret;\n this.authMethod = options?.clientAuthMethod ?? 'client_secret_basic';\n this.idTokenSigningAlgorithm = options?.idTokenSigningAlgorithm ?? 'RS256';\n\n if (options?.jwksCacheDuration) {\n this.jwksCacheDuration = options.jwksCacheDuration;\n }\n\n if (options?.metadataCacheDuration) {\n this.metadataCacheDuration = options.metadataCacheDuration;\n }\n }\n\n /**\n * Generates an authorization URL with specified parameters.\n *\n * If no values are provided for `responseType`, or `codeChallengeMethod`, they default to `code`, and `S256`, respectively.\n *\n * @param params - Authorization URL parameters.\n *\n * @returns Tenant's authorization URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authorizationUrl(params: AuthorizationParams): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n queryParams.set('redirect_uri', params.redirectUri);\n }\n\n if (params.requestUri) {\n queryParams.set('request_uri', params.requestUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n queryParams.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n queryParams.set('response_type', params.responseType);\n }\n\n if (\n (!params.responseType || params.responseType.length === 0) &&\n !params.requestUri\n ) {\n queryParams.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n queryParams.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n queryParams.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n queryParams.set('request', params.request);\n }\n\n if (params.responseMode) {\n queryParams.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n queryParams.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n queryParams.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n queryParams.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n queryParams.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n queryParams.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n queryParams.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n queryParams.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n queryParams.set('code_challenge', params.codeChallenge);\n queryParams.set(\n 'code_challenge_method',\n params.codeChallengeMethod ?? 'S256'\n );\n }\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'authorization_endpoint');\n\n return `${metadata.authorization_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Fetches the authorization server metadata from the .well-known endpoint.\n * The metadata is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh metadata from the server.\n *\n * @returns The issuer metadata for the tenant, retrieved from the OpenID Connect discovery endpoint.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getMetadata(forceRefresh = false): Promise<IssuerMetadata> {\n if (!forceRefresh && this.metadata && this.metadataCacheExpiry > now()) {\n return this.metadata;\n }\n\n this.metadata = undefined;\n\n const response = await innerFetch(\n `${this.tenantDomain}/.well-known/openid-configuration`\n );\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching metadata. Unexpected status code: ${response.status}`\n );\n }\n\n const metadata = await deserializeJson<IssuerMetadata>(response);\n\n this.metadata = metadata;\n this.metadataCacheExpiry = now() + this.metadataCacheDuration;\n\n return metadata;\n }\n\n /**\n * Fetches the JSON Web Keys used to sign the ID token.\n * The JWKS is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh set of JWKS from the server.\n *\n * @returns The JSON Web Key Set containing the public keys for token verification.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getJwks(forceRefresh = false): Promise<Jwks> {\n if (!forceRefresh && this.jwks && this.jwksCacheExpiry > now()) {\n return this.jwks;\n }\n\n this.jwks = undefined;\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'jwks_uri');\n\n const response = await innerFetch(metadata.jwks_uri);\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching JWKS. Unexpected status code: ${response.status}`\n );\n }\n const jwks = await deserializeJson<Jwks>(response);\n\n this.jwks = jwks;\n this.jwksCacheExpiry = now() + this.jwksCacheDuration;\n\n return jwks;\n }\n\n /**\n * Performs a pushed authorization request.\n *\n * @param params - Authorization Parameters.\n *\n * @returns Response from Pushed Authorization Request (PAR) endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the request is invalid.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async pushedAuthorizationRequest(\n params: PushedAuthorizationParams\n ): Promise<ParResponse> {\n const body = new URLSearchParams();\n\n body.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n body.set('redirect_uri', params.redirectUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n body.set('response_type', params.responseType);\n } else {\n body.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n body.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n body.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n body.set('request', params.request);\n }\n\n if (params.responseMode) {\n body.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n body.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n body.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n body.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n body.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n body.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n body.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n body.set('code_challenge', params.codeChallenge);\n body.set('code_challenge_method', params.codeChallengeMethod ?? 'S256');\n }\n\n if (params.state) {\n body.set('state', params.state);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'pushed_authorization_request_endpoint');\n\n const response = await innerFetch(\n metadata.pushed_authorization_request_endpoint,\n {\n body: body.toString(),\n method: 'POST',\n headers,\n }\n );\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'par_request_failed',\n standardBodyError.error_description ??\n 'Pushed Authorization Request Failed'\n );\n }\n\n if (response.status !== 201) {\n throw new MonoCloudHttpError(\n `Error while performing pushed authorization request. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<ParResponse>(response);\n }\n\n /**\n * Fetches userinfo associated with the provided access token.\n *\n * @param accessToken - A valid access token used to retrieve userinfo.\n *\n * @returns The authenticated user's claims.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error (e.g., 'invalid_token') in the 'WWW-Authenticate' header\n * following a 401 Unauthorized response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n * @throws {@link MonoCloudValidationError} - When the access token is invalid.\n *\n */\n async userinfo(accessToken: string): Promise<UserinfoResponse> {\n if (!accessToken.trim().length) {\n throw new MonoCloudValidationError(\n 'Access token is required for fetching userinfo'\n );\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'userinfo_endpoint');\n\n const response = await innerFetch(metadata.userinfo_endpoint, {\n method: 'GET',\n headers: {\n authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (response.status === 401) {\n const authenticateError = response.headers.get('WWW-Authenticate');\n\n if (authenticateError) {\n const errorMatch = /error=\"([^\"]+)\"/.exec(authenticateError);\n const error = errorMatch ? errorMatch[1] : 'userinfo_failed';\n\n const errorDescMatch = /error_description=\"([^\"]+)\"/.exec(\n authenticateError\n );\n\n const errorDescription = errorDescMatch\n ? errorDescMatch[1]\n : 'Userinfo authentication error';\n\n throw new MonoCloudOPError(error, errorDescription);\n }\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching userinfo. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<UserinfoResponse>(response);\n }\n\n /**\n * Generates OpenID end session URL for signing out.\n *\n * Note - The `state` is added only when `postLogoutRedirectUri` is present.\n *\n * @param params - Parameters to build end session URL.\n *\n * @returns Tenant's end session URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async endSessionUrl(params: EndSessionParameters): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.idToken) {\n queryParams.set('id_token_hint', params.idToken);\n }\n\n if (params.postLogoutRedirectUri) {\n queryParams.set('post_logout_redirect_uri', params.postLogoutRedirectUri);\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'end_session_endpoint');\n\n return `${metadata.end_session_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Exchanges an authorization code for tokens.\n *\n * @param code - The authorization code received from the authorization server.\n * @param redirectUri - The redirect URI used in the initial authorization request.\n * @param codeVerifier - Code verifier for PKCE.\n * @param resource - Space-separated list of resources the access token should be scoped to.\n *\n * @returns Tokens obtained by exchanging an authorization code at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async exchangeAuthorizationCode(\n code: string,\n redirectUri: string,\n codeVerifier?: string,\n resource?: string\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'authorization_code');\n body.set('code', code);\n body.set('redirect_uri', redirectUri);\n\n if (codeVerifier) {\n body.set('code_verifier', codeVerifier);\n }\n\n const resources = parseSpaceSeparated(resource) ?? [];\n\n if (resources.length > 0) {\n for (const r of resources) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'code_grant_failed',\n standardBodyError.error_description ?? 'Authorization code grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Exchanges a refresh token for new tokens.\n *\n * @param refreshToken - The refresh token used to request new tokens.\n * @param options - Refresh grant options.\n *\n * @returns Tokens obtained by exchanging a refresh token at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshGrant(\n refreshToken: string,\n options?: RefreshGrantOptions\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'refresh_token');\n body.set('refresh_token', refreshToken);\n\n const scopes = parseSpaceSeparated(options?.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n const resource = parseSpaceSeparated(options?.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'refresh_grant_failed',\n standardBodyError.error_description ?? 'Refresh token grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing refresh token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Generates a session with user and tokens by exchanging authorization code from callback params.\n *\n * @param code - The authorization code received from the callback.\n * @param redirectUri - The redirect URI that was used in the authorization request.\n * @param requestedScopes - A space-separated list of scopes originally requested via the `/authorize` endpoint.\n * This is stored in the session to ensure the correct access token can be identified and refreshed during `refreshSession()`.\n * @param resource - A space-separated list of resource indicators originally requested via the `/authorize` endpoint.\n * Used alongside scopes to uniquely identify and refresh the specific access token associated with these resources.\n * @param options - Options for authenticating a user with authorization code.\n *\n * @returns The user's session containing authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain the openid scope,\n * or if 'expires_in' or 'scope' is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized.\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authenticate(\n code: string,\n redirectUri: string,\n requestedScopes: string,\n resource?: string,\n options?: AuthenticateOptions\n ): Promise<MonoCloudSession> {\n const tokens = await this.exchangeAuthorizationCode(\n code,\n redirectUri,\n options?.codeVerifier,\n resource\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0,\n options?.idTokenMaxAge,\n options?.idTokenNonce\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const session: MonoCloudSession = {\n user: profileSync(undefined, idTokenClaims, userinfo, true),\n idToken: tokens.id_token,\n refreshToken: tokens.refresh_token,\n authorizedScopes: requestedScopes,\n accessTokens: [\n {\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes,\n },\n ],\n };\n\n await options?.onSessionCreating?.(session, idTokenClaims, userinfo);\n\n return session;\n }\n\n /**\n * Refetches user information for an existing session using the userinfo endpoint.\n * Updates the session's user object with the latest user information.\n *\n * @param accessToken - Access token used to fetch the userinfo.\n * @param session - The current MonoCloudSession.\n * @param options - Userinfo refetch options.\n *\n * @returns Updated session with the latest userinfo.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain openid scope\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refetchUserInfo(\n accessToken: AccessToken,\n session: MonoCloudSession,\n options?: RefetchUserInfoOptions\n ): Promise<MonoCloudSession> {\n if (!accessToken.scopes?.includes('openid')) {\n throw new MonoCloudValidationError(\n 'Fetching userinfo requires the openid scope'\n );\n }\n\n const userinfo = await this.userinfo(accessToken.accessToken);\n\n const idTokenClaims =\n session.idToken && options?.strictProfileSync\n ? MonoCloudOidcClient.decodeJwt(session.idToken)\n : undefined;\n\n // eslint-disable-next-line no-param-reassign\n session.user = profileSync(\n session.user,\n idTokenClaims,\n userinfo,\n options?.strictProfileSync\n );\n\n await options?.onSessionCreating?.(session, undefined, userinfo);\n\n return session;\n }\n\n /**\n * Refreshes an existing session using the refresh token.\n * This function requests new tokens using the refresh token and optionally updates user information.\n *\n * @param session - The current MonoCloudSession containing the refresh token.\n * @param options - Session refresh options.\n *\n * @returns User's session containing refreshed authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - If the refresh token is not present in the session,\n * or if 'expires_in' or 'scope' (including the openid scope) is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshSession(\n session: MonoCloudSession,\n options?: RefreshSessionOptions\n ): Promise<MonoCloudSession> {\n if (!session.refreshToken) {\n throw new MonoCloudValidationError(\n 'Session does not contain refresh token'\n );\n }\n\n const tokens = await this.refreshGrant(\n session.refreshToken,\n options?.refreshGrantOptions\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n } else if (session.idToken) {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(session.idToken);\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const resource = options?.refreshGrantOptions?.resource;\n let scopes = options?.refreshGrantOptions?.scopes;\n\n if (!resource && !scopes) {\n scopes = session.authorizedScopes;\n }\n\n const accessToken = findToken(session.accessTokens, resource, scopes);\n\n const user = profileSync(\n session.user,\n idTokenClaims,\n userinfo,\n options?.strictProfileSync\n );\n\n const newTokens =\n session.accessTokens?.filter(t => t !== accessToken) ?? [];\n\n newTokens.push({\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes: scopes,\n });\n\n const updatedSession: MonoCloudSession = {\n ...session,\n user,\n idToken: tokens.id_token ?? session.idToken,\n refreshToken: tokens.refresh_token ?? session.refreshToken,\n accessTokens: newTokens,\n };\n\n await options?.onSessionCreating?.(updatedSession, idTokenClaims, userinfo);\n\n return updatedSession;\n }\n\n /**\n * Revokes an access token or refresh token, rendering it invalid for future use.\n *\n * @param token - The token string to be revoked.\n * @param tokenType - Hint about the token type ('access_token' or 'refresh_token').\n *\n * @returns If token revocation succeeded.\n *\n * @throws {@link MonoCloudValidationError} - If token is invalid or unsupported token type\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n */\n async revokeToken(token: string, tokenType?: string): Promise<void> {\n if (!token.trim().length) {\n throw new MonoCloudValidationError('Invalid token');\n }\n\n if (\n tokenType &&\n tokenType !== 'access_token' &&\n tokenType !== 'refresh_token'\n ) {\n throw new MonoCloudValidationError(\n 'Only access_token and refresh_token types are supported.'\n );\n }\n\n const body = new URLSearchParams();\n body.set('token', token);\n if (tokenType) {\n body.set('token_type_hint', tokenType);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'revocation_endpoint');\n\n const response = await innerFetch(metadata.revocation_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'revocation_failed',\n standardBodyError.error_description ?? 'Token revocation failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing revocation request. Unexpected status code: ${response.status}`\n );\n }\n }\n\n /**\n * Validates an ID Token.\n *\n * @param idToken - The ID Token JWT string to validate.\n * @param jwks - Array of JSON Web Keys (JWK) used to verify the token's signature.\n * @param clockSkew - Number of seconds to adjust the current time to account for clock differences.\n * @param clockTolerance - Additional time tolerance in seconds for time-based claim validation.\n * @param maxAge - Maximum authentication age in seconds.\n * @param nonce - Nonce value to validate against the token's nonce claim.\n *\n * @returns Validated ID Token claims.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n */\n async validateIdToken(\n idToken: string,\n jwks: Jwk[],\n clockSkew: number,\n clockTolerance: number,\n maxAge?: number,\n nonce?: string\n ): Promise<IdTokenClaims> {\n if (typeof idToken !== 'string' || idToken.trim().length === 0) {\n throw new MonoCloudTokenError(\n 'ID Token must be a valid non-empty string'\n );\n }\n\n const {\n 0: protectedHeader,\n 1: payload,\n 2: encodedSignature,\n length,\n } = idToken.split('.');\n\n if (length !== 3) {\n throw new MonoCloudTokenError(\n 'ID Token must have a header, payload and signature'\n );\n }\n\n let header: JwsHeaderParameters;\n try {\n header = JSON.parse(decodeBase64Url(protectedHeader));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Header');\n }\n\n if (\n header === null ||\n typeof header !== 'object' ||\n Array.isArray(header)\n ) {\n throw new MonoCloudTokenError('JWT Header must be a top level object');\n }\n\n if (this.idTokenSigningAlgorithm !== header.alg) {\n throw new MonoCloudTokenError('Invalid signing alg');\n }\n\n if (header.crit !== undefined) {\n throw new MonoCloudTokenError('Unexpected JWT \"crit\" header parameter');\n }\n\n const binary = decodeBase64Url(encodedSignature);\n\n const signature = new Uint8Array(binary.length);\n\n for (let i = 0; i < binary.length; i++) {\n signature[i] = binary.charCodeAt(i);\n }\n\n const key = await getPublicSigKeyFromIssuerJwks(jwks, header);\n\n const input = `${protectedHeader}.${payload}`;\n\n const verified = await crypto.subtle.verify(\n keyToSubtle(key),\n key,\n signature,\n stringToArrayBuffer(input) as BufferSource\n );\n\n if (!verified) {\n throw new MonoCloudTokenError('JWT signature verification failed');\n }\n\n let claims: IdTokenClaims;\n\n try {\n claims = JSON.parse(decodeBase64Url(payload));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Payload');\n }\n\n if (\n claims === null ||\n typeof claims !== 'object' ||\n Array.isArray(claims)\n ) {\n throw new MonoCloudTokenError('JWT Payload must be a top level object');\n }\n\n if ((claims.nonce || nonce) && claims.nonce !== nonce) {\n throw new MonoCloudTokenError('Nonce mismatch');\n }\n\n const current = now() + clockSkew;\n\n /* v8 ignore else -- @preserve */\n if (claims.exp !== undefined) {\n if (typeof claims.exp !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim type'\n );\n }\n\n if (claims.exp <= current - clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim value, timestamp is <= now()'\n );\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (claims.iat !== undefined) {\n if (typeof claims.iat !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"iat\" (issued at) claim type'\n );\n }\n }\n\n if (\n typeof claims.auth_time === 'number' &&\n typeof maxAge === 'number' &&\n claims.auth_time + maxAge < current\n ) {\n throw new MonoCloudTokenError(\n 'Too much time has elapsed since the last End-User authentication'\n );\n }\n\n if (claims.iss !== this.tenantDomain) {\n throw new MonoCloudTokenError('Invalid Issuer');\n }\n\n if (claims.nbf !== undefined) {\n if (typeof claims.nbf !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim type'\n );\n }\n\n if (claims.nbf > current + clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim value, timestamp is > now()'\n );\n }\n }\n\n const audience = Array.isArray(claims.aud) ? claims.aud : [claims.aud];\n\n if (!audience.includes(this.clientId)) {\n throw new MonoCloudTokenError('Invalid audience claim');\n }\n\n return claims;\n }\n\n /**\n * Decodes the payload of a JSON Web Token (JWT) and returns it as an object.\n *\n * >Note: THIS METHOD DOES NOT VERIFY JWT TOKENS.\n *\n * @param jwt - JWT to decode.\n *\n * @returns Decoded payload.\n *\n * @throws {@link MonoCloudTokenError} - If decoding fails\n *\n */\n static decodeJwt(jwt: string): IdTokenClaims {\n try {\n const [, payload] = jwt.split('.');\n\n if (!payload?.trim()) {\n throw new MonoCloudTokenError('JWT does not contain payload');\n }\n\n const decoded = decodeBase64Url(payload);\n\n if (!decoded.startsWith('{')) {\n throw new MonoCloudTokenError('Payload is not an object');\n }\n\n return JSON.parse(decoded) as IdTokenClaims;\n } catch (e) {\n if (e instanceof MonoCloudAuthBaseError) {\n throw e;\n }\n\n throw new MonoCloudTokenError(\n 'Could not parse payload. Malformed payload'\n );\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAOA,IAAa,yBAAb,cAA4C,MAAM;;;;;;;;;;;ACElD,IAAa,mBAAb,cAAsC,uBAAuB;CAO3D,YAAY,OAAe,kBAA2B;AACpD,QAAM,MAAM;AACZ,OAAK,QAAQ;AACb,OAAK,mBAAmB;;;;;;;;;;;;;ACV5B,IAAa,qBAAb,cAAwC,uBAAuB;;;;;;;;;ACF/D,IAAa,sBAAb,cAAyC,uBAAuB;;;;;;;;;ACAhE,IAAa,2BAAb,cAA8C,uBAAuB;;;;ACArE,MAAM,eACJ,QACiE;AACjE,SAAQ,KAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAQ,MAAM,OAAO,IAAI,MAAM,GAAG;GAAI;EACvD,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAW,MAAM,OAAO,IAAI,MAAM,GAAG;GAAI;EAC1D,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAqB,MAAM,OAAO,IAAI,MAAM,GAAG;GAAI;EACpE,KAAK;EACL,KAAK,QACH,QAAO;GAAE,MAAM;GAAS,YAAY,KAAK,IAAI,MAAM,GAAG;GAAI;EAC5D,KAAK,QACH,QAAO;GAAE,MAAM;GAAS,YAAY;GAAS;EAE/C,QACE,OAAM,IAAI,MAAM,4BAA4B;;;AAIlD,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAAoC,KAAK,MAAtD;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,8CAA8C;;;AAIpE,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAAoC,KAAK,MAAtD;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,8CAA8C;;;AAIpE,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAA6B,YAA1C;EACE,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,wCAAwC;;;AAI9D,MAAM,SAAS,QAA2B;AACxC,SAAS,IAAI,UAA+B,KAAK,MAAjD;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,kCAAkC;;;AAIxD,MAAM,YAAY,QAA2B;AAC3C,SAAQ,IAAI,UAAU,MAAtB;EACE,KAAK,OACH,QAAO,MAAM,IAAI;EACnB,KAAK,UACH,QAAO,MAAM,IAAI;EACnB,KAAK,oBACH,QAAO,MAAM,IAAI;EACnB,KAAK,QACH,QAAO,MAAM,IAAI;EAEnB,QACE,OAAM,IAAI,MAAM,uCAAuC;;;AAI7D,MAAM,wBAAwB,QAAyB;CACrD,MAAM,EAAE,cAAc;;AAGtB,KACE,OAAO,UAAU,kBAAkB,YACnC,UAAU,gBAAgB,KAE1B,OAAM,IAAI,MAAM,eAAe,UAAU,KAAK,gBAAgB;;AAIlE,MAAM,iBAAiB,QAA2B;CAChD,MAAM,EAAE,cAAc;AACtB,SAAQ,UAAU,YAAlB;EACE,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,KAAK,QACH,QAAO;EAET,QACE,OAAM,IAAI,MAAM,+BAA+B;;;AAIrD,MAAa,eACX,QACqD;AACrD,SAAQ,IAAI,UAAU,MAAtB;EACE,KAAK,OACH,QAAO,EAAE,MAAM,IAAI,UAAU,MAAM;EAErC,KAAK,QACH,QAAO;GACL,MAAM,IAAI,UAAU;GACpB,MAAM,cAAc,IAAI;GACzB;EACH,KAAK;AACH,wBAAqB,IAAI;AACzB,WAAS,IAAI,UAAoC,KAAK,MAAtD;IACE,KAAK;IACL,KAAK;IACL,KAAK,UACH,QAAO;KACL,MAAM,IAAI,UAAU;KACpB,YACE,SACG,IAAI,UAAoC,KAAK,KAAK,MAAM,GAAG,EAC5D,GACD,IAAI;KACR;IAEH,QACE,OAAM,IAAI,MAAM,gCAAgC;;EAGtD,KAAK;AACH,wBAAqB,IAAI;AACzB,UAAO,IAAI,UAAU;;;AAGzB,OAAM,IAAI,MAAM,uCAAuC;;AAGzD,MAAM,0BACJ,QACA,UACA,SACoC;CACpC,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,GAAG;AAC5C,QAAO;EACL,KAAKA,oCAAa;EAClB,KAAK;EACL,KAAK,MAAM;EACX,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACN;;AAGH,MAAM,wBAAwB,OAC5B,QACA,UACA,cACA,MACA,SACkB;CAClB,MAAM,MAAM,MAAM,OAAO,OAAO,UAC9B,OACA,cACA,YAAY,aAAa,IAAI,EAC7B,OACA,CAAC,OAAO,CACT;CAED,MAAM,SAAS;EAAE,KAAK,SAAS,IAAI;EAAE,KAAK,aAAa;EAAK;CAC5D,MAAM,UAAU,uBAAuB,QAAQ,UAAU,KAAK;AAE9D,MAAK,IAAI,aAAa,SAAS;AAC/B,MAAK,IACH,yBACA,yDACD;CAED,MAAM,QAAQ,GAAGC,uCAAgBC,2CAAoB,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,GAAGD,uCAAgBC,2CAAoB,KAAK,UAAU,QAAQ,CAAC,CAAC;CAC9I,MAAM,YAAYD,uCAChB,MAAM,OAAO,OAAO,KAClB,YAAY,IAAI,EAChB,KACAC,2CAAoB,MAAM,CAC3B,CACF;AAED,MAAK,IAAI,oBAAoB,GAAG,MAAM,GAAG,YAAY;;AAGvD,MAAa,aAAa,OACxB,UACA,cACA,QACA,QACA,SACA,MACA,qBACkB;AAClB,SAAQ,MAAR;EACE,KAAK,WAAW,yBAAyB,CAAC,CAAC;AAEzC,WAAQ,gBAAgB,SAAS,KAAK,GAAG,SAAS,GAAG,gBAAgB,KAAK;AAC1E;EAGF,KAAK,WAAW,wBAAwB,CAAC,CAAC;AACxC,QAAK,IAAI,aAAa,SAAS;AAC/B,OAAI,OAAO,iBAAiB,SAC1B,MAAK,IAAI,iBAAiB,aAAa;AAEzC;EAGF,KAAK,WAAW,uBACd,CAAC,CAAC,UACF,CAAC,CAAC,SACD,OAAO,iBAAiB,YAAY,cAAc,QAAQ;AAU3D,SAAM,sBACJ,QACA,UAVA,OAAO,iBAAiB,WACpB;IACE,GAAGD,uCAAgBC,2CAAoB,aAAa,CAAC;IACrD,KAAK;IACL,KAAK;IACN,GACD,cAMJ,MACA,oBAAoB,EACrB;AACD;EAGF,KAAK,WAAW,qBACd,OAAO,iBAAiB,YACxB,aAAa,QAAQ,SACrB,CAAC,CAAC,UACF,CAAC,CAAC;AACF,SAAM,sBACJ,QACA,UACA,cACA,MACA,oBAAoB,EACrB;AACD;EAGF,QACE,OAAM,IAAI,MAAM,uCAAuC;;;;;;ACzP7D,MAAM,2BAA2B;AAEjC,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,uBACP,UACA,UACwE;AACxE,KAAI,SAAS,cAAc,UAAa,SAAS,cAAc,KAC7D,OAAM,IAAI,yBACR,GAAG,SAAmB,gEACvB;;AAIL,MAAM,aAAa,OACjB,OACA,UAAuB,EAAE,KACH;AACtB,KAAI;AACF,SAAO,MAAM,MAAM,OAAO,QAAQ;UAC3B,GAAG;;AAEV,QAAM,IAAI,mBACP,EAAU,WAAW,2BACvB;;;AAIL,MAAM,kBAAkB,OAAgB,QAA8B;AACpE,KAAI;AACF,SAAO,MAAM,IAAI,MAAM;UAChB,GAAG;AACV,QAAM,IAAI;;GAER,yCAA0C,EAAU,UAAU,KAAM,EAAU,YAAY;GAC3F;;;;;;AAOL,IAAa,sBAAb,MAAa,oBAAoB;CAuB/B,YACE,cACA,UACA,SACA;yBAdwB;2BAEE;6BAIE;+BAEE;AAQ9B,mBAAiB;;AAEjB,OAAK,eAAe,GAAG,CAAC,aAAa,WAAW,WAAW,GAAG,aAAa,KAAK,aAAa,SAAS,IAAI,GAAG,aAAa,MAAM,GAAG,GAAG,GAAG;AACzI,OAAK,WAAW;AAChB,OAAK,eAAe,SAAS;AAC7B,OAAK,aAAa,SAAS,oBAAoB;AAC/C,OAAK,0BAA0B,SAAS,2BAA2B;AAEnE,MAAI,SAAS,kBACX,MAAK,oBAAoB,QAAQ;AAGnC,MAAI,SAAS,sBACX,MAAK,wBAAwB,QAAQ;;;;;;;;;;;;;;;CAiBzC,MAAM,iBAAiB,QAA8C;EACnE,MAAM,cAAc,IAAI,iBAAiB;AAEzC,cAAY,IAAI,aAAa,KAAK,SAAS;AAE3C,MAAI,OAAO,YACT,aAAY,IAAI,gBAAgB,OAAO,YAAY;AAGrD,MAAI,OAAO,WACT,aAAY,IAAI,eAAe,OAAO,WAAW;EAGnD,MAAM,SAASC,2CAAoB,OAAO,OAAO,IAAI,EAAE;AAEvD,MAAI,OAAO,SAAS,EAClB,aAAY,IAAI,SAAS,OAAO,KAAK,IAAI,CAAC;AAG5C,MAAI,OAAO,gBAAgB,OAAO,aAAa,SAAS,EACtD,aAAY,IAAI,iBAAiB,OAAO,aAAa;AAGvD,OACG,CAAC,OAAO,gBAAgB,OAAO,aAAa,WAAW,MACxD,CAAC,OAAO,WAER,aAAY,IAAI,iBAAiB,OAAO;AAG1C,MAAI,OAAO,kBACT,aAAY,IAAI,sBAAsB,OAAO,kBAAkB;AAGjE,MAAI,OAAO,UACT,aAAY,IAAI,cAAc,OAAO,UAAU;AAGjD,MAAI,OAAO,QACT,aAAY,IAAI,WAAW,OAAO,QAAQ;AAG5C,MAAI,OAAO,aACT,aAAY,IAAI,iBAAiB,OAAO,aAAa;AAGvD,MAAI,OAAO,aAAa,OAAO,UAAU,SAAS,EAChD,aAAY,IAAI,cAAc,OAAO,UAAU,KAAK,IAAI,CAAC;AAG3D,MAAI,OAAO,MACT,aAAY,IAAI,SAAS,OAAO,MAAM;AAGxC,MAAI,OAAO,UACT,aAAY,IAAI,cAAc,OAAO,UAAU;AAGjD,MAAI,OAAO,QACT,aAAY,IAAI,WAAW,OAAO,QAAQ;AAG5C,MAAI,OAAO,OAAO,WAAW,SAC3B,aAAY,IAAI,WAAW,OAAO,OAAO,UAAU,CAAC;AAGtD,MAAI,OAAO,OACT,aAAY,IAAI,UAAU,OAAO,OAAO;EAG1C,MAAM,WAAWA,2CAAoB,OAAO,SAAS,IAAI,EAAE;AAE3D,MAAI,SAAS,SAAS,EACpB,MAAK,MAAM,KAAK,SACd,aAAY,OAAO,YAAY,EAAE;AAIrC,MAAI,OAAO,eAAe;AACxB,eAAY,IAAI,kBAAkB,OAAO,cAAc;AACvD,eAAY,IACV,yBACA,OAAO,uBAAuB,OAC/B;;AAGH,MAAI,OAAO,MACT,aAAY,IAAI,SAAS,OAAO,MAAM;EAGxC,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,yBAAyB;AAE1D,SAAO,GAAG,SAAS,uBAAuB,GAAG,YAAY,UAAU;;;;;;;;;;;;;;CAerE,MAAM,YAAY,eAAe,OAAgC;AAC/D,MAAI,CAAC,gBAAgB,KAAK,YAAY,KAAK,sBAAsBC,4BAAK,CACpE,QAAO,KAAK;AAGd,OAAK,WAAW;EAEhB,MAAM,WAAW,MAAM,WACrB,GAAG,KAAK,aAAa,mCACtB;AAED,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,0DAA0D,SAAS,SACpE;EAGH,MAAM,WAAW,MAAM,gBAAgC,SAAS;AAEhE,OAAK,WAAW;AAChB,OAAK,sBAAsBA,4BAAK,GAAG,KAAK;AAExC,SAAO;;;;;;;;;;;;;;CAeT,MAAM,QAAQ,eAAe,OAAsB;AACjD,MAAI,CAAC,gBAAgB,KAAK,QAAQ,KAAK,kBAAkBA,4BAAK,CAC5D,QAAO,KAAK;AAGd,OAAK,OAAO;EAEZ,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,WAAW;EAE5C,MAAM,WAAW,MAAM,WAAW,SAAS,SAAS;AAEpD,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,sDAAsD,SAAS,SAChE;EAEH,MAAM,OAAO,MAAM,gBAAsB,SAAS;AAElD,OAAK,OAAO;AACZ,OAAK,kBAAkBA,4BAAK,GAAG,KAAK;AAEpC,SAAO;;;;;;;;;;;;;;;CAgBT,MAAM,2BACJ,QACsB;EACtB,MAAM,OAAO,IAAI,iBAAiB;AAElC,OAAK,IAAI,aAAa,KAAK,SAAS;AAEpC,MAAI,OAAO,YACT,MAAK,IAAI,gBAAgB,OAAO,YAAY;EAG9C,MAAM,SAASD,2CAAoB,OAAO,OAAO,IAAI,EAAE;AAEvD,MAAI,OAAO,SAAS,EAClB,MAAK,IAAI,SAAS,OAAO,KAAK,IAAI,CAAC;AAGrC,MAAI,OAAO,gBAAgB,OAAO,aAAa,SAAS,EACtD,MAAK,IAAI,iBAAiB,OAAO,aAAa;MAE9C,MAAK,IAAI,iBAAiB,OAAO;AAGnC,MAAI,OAAO,kBACT,MAAK,IAAI,sBAAsB,OAAO,kBAAkB;AAG1D,MAAI,OAAO,UACT,MAAK,IAAI,cAAc,OAAO,UAAU;AAG1C,MAAI,OAAO,QACT,MAAK,IAAI,WAAW,OAAO,QAAQ;AAGrC,MAAI,OAAO,aACT,MAAK,IAAI,iBAAiB,OAAO,aAAa;AAGhD,MAAI,OAAO,aAAa,OAAO,UAAU,SAAS,EAChD,MAAK,IAAI,cAAc,OAAO,UAAU,KAAK,IAAI,CAAC;AAGpD,MAAI,OAAO,MACT,MAAK,IAAI,SAAS,OAAO,MAAM;AAGjC,MAAI,OAAO,UACT,MAAK,IAAI,cAAc,OAAO,UAAU;AAG1C,MAAI,OAAO,QACT,MAAK,IAAI,WAAW,OAAO,QAAQ;AAGrC,MAAI,OAAO,OAAO,WAAW,SAC3B,MAAK,IAAI,WAAW,OAAO,OAAO,UAAU,CAAC;AAG/C,MAAI,OAAO,OACT,MAAK,IAAI,UAAU,OAAO,OAAO;EAGnC,MAAM,WAAWA,2CAAoB,OAAO,SAAS,IAAI,EAAE;AAE3D,MAAI,SAAS,SAAS,EACpB,MAAK,MAAM,KAAK,SACd,MAAK,OAAO,YAAY,EAAE;AAI9B,MAAI,OAAO,eAAe;AACxB,QAAK,IAAI,kBAAkB,OAAO,cAAc;AAChD,QAAK,IAAI,yBAAyB,OAAO,uBAAuB,OAAO;;AAGzE,MAAI,OAAO,MACT,MAAK,IAAI,SAAS,OAAO,MAAM;EAGjC,MAAM,UAAU;GACd,gBAAgB;GAChB,QAAQ;GACT;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,wCAAwC;EAEzE,MAAM,WAAW,MAAM,WACrB,SAAS,uCACT;GACE,MAAM,KAAK,UAAU;GACrB,QAAQ;GACR;GACD,CACF;AAED,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,sBAC3B,kBAAkB,qBAChB,sCACH;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,gFAAgF,SAAS,SAC1F;AAGH,SAAO,MAAM,gBAA6B,SAAS;;;;;;;;;;;;;;;;;;;CAoBrD,MAAM,SAAS,aAAgD;AAC7D,MAAI,CAAC,YAAY,MAAM,CAAC,OACtB,OAAM,IAAI,yBACR,iDACD;EAGH,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,oBAAoB;EAErD,MAAM,WAAW,MAAM,WAAW,SAAS,mBAAmB;GAC5D,QAAQ;GACR,SAAS,EACP,eAAe,UAAU,eAC1B;GACF,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,SAAS,QAAQ,IAAI,mBAAmB;AAElE,OAAI,mBAAmB;IACrB,MAAM,aAAa,kBAAkB,KAAK,kBAAkB;IAC5D,MAAM,QAAQ,aAAa,WAAW,KAAK;IAE3C,MAAM,iBAAiB,8BAA8B,KACnD,kBACD;AAMD,UAAM,IAAI,iBAAiB,OAJF,iBACrB,eAAe,KACf,gCAE+C;;;AAIvD,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,0DAA0D,SAAS,SACpE;AAGH,SAAO,MAAM,gBAAkC,SAAS;;;;;;;;;;;;;;;CAgB1D,MAAM,cAAc,QAA+C;EACjE,MAAM,cAAc,IAAI,iBAAiB;AAEzC,cAAY,IAAI,aAAa,KAAK,SAAS;AAE3C,MAAI,OAAO,QACT,aAAY,IAAI,iBAAiB,OAAO,QAAQ;AAGlD,MAAI,OAAO,uBAAuB;AAChC,eAAY,IAAI,4BAA4B,OAAO,sBAAsB;AAEzE,OAAI,OAAO,MACT,aAAY,IAAI,SAAS,OAAO,MAAM;;EAI1C,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,uBAAuB;AAExD,SAAO,GAAG,SAAS,qBAAqB,GAAG,YAAY,UAAU;;;;;;;;;;;;;;;;;;;CAoBnE,MAAM,0BACJ,MACA,aACA,cACA,UACiB;EACjB,MAAM,OAAO,IAAI,iBAAiB;AAElC,OAAK,IAAI,cAAc,qBAAqB;AAC5C,OAAK,IAAI,QAAQ,KAAK;AACtB,OAAK,IAAI,gBAAgB,YAAY;AAErC,MAAI,aACF,MAAK,IAAI,iBAAiB,aAAa;EAGzC,MAAM,YAAYA,2CAAoB,SAAS,IAAI,EAAE;AAErD,MAAI,UAAU,SAAS,EACrB,MAAK,MAAM,KAAK,UACd,MAAK,OAAO,YAAY,EAAE;EAI9B,MAAM,UAAU;GACd,gBAAgB;GAChB,QAAQ;GACT;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,iBAAiB;EAElD,MAAM,WAAW,MAAM,WAAW,SAAS,gBAAgB;GACzD,QAAQ;GACR,MAAM,KAAK,UAAU;GACrB;GACD,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,qBAC3B,kBAAkB,qBAAqB,kCACxC;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,+DAA+D,SAAS,SACzE;AAGH,SAAO,MAAM,gBAAwB,SAAS;;;;;;;;;;;;;;;;;CAkBhD,MAAM,aACJ,cACA,SACiB;EACjB,MAAM,OAAO,IAAI,iBAAiB;AAElC,OAAK,IAAI,cAAc,gBAAgB;AACvC,OAAK,IAAI,iBAAiB,aAAa;EAEvC,MAAM,SAASA,2CAAoB,SAAS,OAAO,IAAI,EAAE;AAEzD,MAAI,OAAO,SAAS,EAClB,MAAK,IAAI,SAAS,OAAO,KAAK,IAAI,CAAC;EAGrC,MAAM,WAAWA,2CAAoB,SAAS,SAAS,IAAI,EAAE;AAE7D,MAAI,SAAS,SAAS,EACpB,MAAK,MAAM,KAAK,SACd,MAAK,OAAO,YAAY,EAAE;EAI9B,MAAM,UAAU;GACd,gBAAgB;GAChB,QAAQ;GACT;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,iBAAiB;EAElD,MAAM,WAAW,MAAM,WAAW,SAAS,gBAAgB;GACzD,QAAQ;GACR,MAAM,KAAK,UAAU;GACrB;GACD,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,wBAC3B,kBAAkB,qBAAqB,6BACxC;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,uEAAuE,SAAS,SACjF;AAGH,SAAO,MAAM,gBAAwB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BhD,MAAM,aACJ,MACA,aACA,iBACA,UACA,SAC2B;EAC3B,MAAM,SAAS,MAAM,KAAK,0BACxB,MACA,aACA,SAAS,cACT,SACD;EAED,MAAM,wBACJ,OAAO,OAAO,eAAe,WACzBC,4BAAK,GAAG,OAAO,aACf;AAEN,MAAI,CAAC,sBACH,OAAM,IAAI,yBAAyB,sCAAsC;AAG3E,MAAI,CAAC,OAAO,MACV,OAAM,IAAI,yBAAyB,mCAAmC;EAGxE,IAAI;AAEJ,MAAI,SAAS,iBAAiB,OAAO,OAAO,SAAS,SAAS,CAC5D,YAAW,MAAM,KAAK,SAAS,OAAO,aAAa;EAGrD,IAAI,gBAAwC,EAAE;AAE9C,MAAI,OAAO,SACT,KAAI,SAAS,mBAAmB,MAAM;GACpC,MAAM,OAAO,SAAS,QAAS,MAAM,KAAK,SAAS;AAEnD,mBAAgB,MAAM,KAAK,gBACzB,OAAO,UACP,KAAK,MACL,SAAS,oBAAoB,GAC7B,SAAS,yBAAyB,GAClC,SAAS,eACT,SAAS,aACV;QAED,iBAAgB,oBAAoB,UAAU,OAAO,SAAS;AAIlE,GAAC,SAAS,yBAAyB,wBAAwB,SAAQ,MAAK;AAEtE,UAAO,cAAc;IACrB;EAEF,MAAM,UAA4B;GAChC,MAAMC,mCAAY,QAAW,eAAe,UAAU,KAAK;GAC3D,SAAS,OAAO;GAChB,cAAc,OAAO;GACrB,kBAAkB;GAClB,cAAc,CACZ;IACE,QAAQ,OAAO;IACf,aAAa,OAAO;IACpB;IACA;IACA;IACD,CACF;GACF;AAED,QAAM,SAAS,oBAAoB,SAAS,eAAe,SAAS;AAEpE,SAAO;;;;;;;;;;;;;;;;;;;;;;;CAwBT,MAAM,gBACJ,aACA,SACA,SAC2B;AAC3B,MAAI,CAAC,YAAY,QAAQ,SAAS,SAAS,CACzC,OAAM,IAAI,yBACR,8CACD;EAGH,MAAM,WAAW,MAAM,KAAK,SAAS,YAAY,YAAY;EAE7D,MAAM,gBACJ,QAAQ,WAAW,SAAS,oBACxB,oBAAoB,UAAU,QAAQ,QAAQ,GAC9C;AAGN,UAAQ,OAAOA,mCACb,QAAQ,MACR,eACA,UACA,SAAS,kBACV;AAED,QAAM,SAAS,oBAAoB,SAAS,QAAW,SAAS;AAEhE,SAAO;;;;;;;;;;;;;;;;;;;;;;;CAwBT,MAAM,eACJ,SACA,SAC2B;AAC3B,MAAI,CAAC,QAAQ,aACX,OAAM,IAAI,yBACR,yCACD;EAGH,MAAM,SAAS,MAAM,KAAK,aACxB,QAAQ,cACR,SAAS,oBACV;EAED,MAAM,wBACJ,OAAO,OAAO,eAAe,WACzBD,4BAAK,GAAG,OAAO,aACf;AAEN,MAAI,CAAC,sBACH,OAAM,IAAI,yBAAyB,sCAAsC;AAG3E,MAAI,CAAC,OAAO,MACV,OAAM,IAAI,yBAAyB,mCAAmC;EAGxE,IAAI;AAEJ,MAAI,SAAS,iBAAiB,OAAO,OAAO,SAAS,SAAS,CAC5D,YAAW,MAAM,KAAK,SAAS,OAAO,aAAa;EAGrD,IAAI,gBAAwC,EAAE;AAE9C,MAAI,OAAO,SACT,KAAI,SAAS,mBAAmB,MAAM;GACpC,MAAM,OAAO,SAAS,QAAS,MAAM,KAAK,SAAS;AAEnD,mBAAgB,MAAM,KAAK,gBACzB,OAAO,UACP,KAAK,MACL,SAAS,oBAAoB,GAC7B,SAAS,yBAAyB,EACnC;QAED,iBAAgB,oBAAoB,UAAU,OAAO,SAAS;WAEvD,QAAQ,QACjB,iBAAgB,oBAAoB,UAAU,QAAQ,QAAQ;AAGhE,GAAC,SAAS,yBAAyB,wBAAwB,SAAQ,MAAK;AAEtE,UAAO,cAAc;IACrB;EAEF,MAAM,WAAW,SAAS,qBAAqB;EAC/C,IAAI,SAAS,SAAS,qBAAqB;AAE3C,MAAI,CAAC,YAAY,CAAC,OAChB,UAAS,QAAQ;EAGnB,MAAM,cAAcE,iCAAU,QAAQ,cAAc,UAAU,OAAO;EAErE,MAAM,OAAOD,mCACX,QAAQ,MACR,eACA,UACA,SAAS,kBACV;EAED,MAAM,YACJ,QAAQ,cAAc,QAAO,MAAK,MAAM,YAAY,IAAI,EAAE;AAE5D,YAAU,KAAK;GACb,QAAQ,OAAO;GACf,aAAa,OAAO;GACpB;GACA;GACA,iBAAiB;GAClB,CAAC;EAEF,MAAM,iBAAmC;GACvC,GAAG;GACH;GACA,SAAS,OAAO,YAAY,QAAQ;GACpC,cAAc,OAAO,iBAAiB,QAAQ;GAC9C,cAAc;GACf;AAED,QAAM,SAAS,oBAAoB,gBAAgB,eAAe,SAAS;AAE3E,SAAO;;;;;;;;;;;;;;;;;;CAmBT,MAAM,YAAY,OAAe,WAAmC;AAClE,MAAI,CAAC,MAAM,MAAM,CAAC,OAChB,OAAM,IAAI,yBAAyB,gBAAgB;AAGrD,MACE,aACA,cAAc,kBACd,cAAc,gBAEd,OAAM,IAAI,yBACR,2DACD;EAGH,MAAM,OAAO,IAAI,iBAAiB;AAClC,OAAK,IAAI,SAAS,MAAM;AACxB,MAAI,UACF,MAAK,IAAI,mBAAmB,UAAU;EAGxC,MAAM,UAAU,EACd,gBAAgB,qCACjB;AAED,QAAM,WACJ,KAAK,UACL,KAAK,cACL,KAAK,YACL,KAAK,cACL,SACA,MACA,yBACD;EAED,MAAM,WAAW,MAAM,KAAK,aAAa;AAEzC,yBAAuB,UAAU,sBAAsB;EAEvD,MAAM,WAAW,MAAM,WAAW,SAAS,qBAAqB;GAC9D,QAAQ;GACR,MAAM,KAAK,UAAU;GACrB;GACD,CAAC;AAEF,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,oBAAoB,MAAM,gBAAgB,SAAS;AAEzD,SAAM,IAAI,iBACR,kBAAkB,SAAS,qBAC3B,kBAAkB,qBAAqB,0BACxC;;AAGH,MAAI,SAAS,WAAW,IACtB,OAAM,IAAI,mBACR,sEAAsE,SAAS,SAChF;;;;;;;;;;;;;;;;;CAmBL,MAAM,gBACJ,SACA,MACA,WACA,gBACA,QACA,OACwB;AACxB,MAAI,OAAO,YAAY,YAAY,QAAQ,MAAM,CAAC,WAAW,EAC3D,OAAM,IAAI,oBACR,4CACD;EAGH,MAAM,EACJ,GAAG,iBACH,GAAG,SACH,GAAG,kBACH,WACE,QAAQ,MAAM,IAAI;AAEtB,MAAI,WAAW,EACb,OAAM,IAAI,oBACR,qDACD;EAGH,IAAI;AACJ,MAAI;AACF,YAAS,KAAK,MAAME,uCAAgB,gBAAgB,CAAC;UAC/C;AACN,SAAM,IAAI,oBAAoB,6BAA6B;;AAG7D,MACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,OAAO,CAErB,OAAM,IAAI,oBAAoB,wCAAwC;AAGxE,MAAI,KAAK,4BAA4B,OAAO,IAC1C,OAAM,IAAI,oBAAoB,sBAAsB;AAGtD,MAAI,OAAO,SAAS,OAClB,OAAM,IAAI,oBAAoB,2CAAyC;EAGzE,MAAM,SAASA,uCAAgB,iBAAiB;EAEhD,MAAM,YAAY,IAAI,WAAW,OAAO,OAAO;AAE/C,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IACjC,WAAU,KAAK,OAAO,WAAW,EAAE;EAGrC,MAAM,MAAM,MAAMC,qDAA8B,MAAM,OAAO;EAE7D,MAAM,QAAQ,GAAG,gBAAgB,GAAG;AASpC,MAAI,CAPa,MAAM,OAAO,OAAO,OACnC,YAAY,IAAI,EAChB,KACA,WACAC,2CAAoB,MAAM,CAC3B,CAGC,OAAM,IAAI,oBAAoB,oCAAoC;EAGpE,IAAI;AAEJ,MAAI;AACF,YAAS,KAAK,MAAMF,uCAAgB,QAAQ,CAAC;UACvC;AACN,SAAM,IAAI,oBAAoB,8BAA8B;;AAG9D,MACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,OAAO,CAErB,OAAM,IAAI,oBAAoB,yCAAyC;AAGzE,OAAK,OAAO,SAAS,UAAU,OAAO,UAAU,MAC9C,OAAM,IAAI,oBAAoB,iBAAiB;EAGjD,MAAM,UAAUH,4BAAK,GAAG;;AAGxB,MAAI,OAAO,QAAQ,QAAW;AAC5B,OAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,oBACR,sDACD;AAGH,OAAI,OAAO,OAAO,UAAU,eAC1B,OAAM,IAAI,oBACR,8EACD;;;AAKL,MAAI,OAAO,QAAQ,QACjB;OAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,oBACR,gDACD;;AAIL,MACE,OAAO,OAAO,cAAc,YAC5B,OAAO,WAAW,YAClB,OAAO,YAAY,SAAS,QAE5B,OAAM,IAAI,oBACR,mEACD;AAGH,MAAI,OAAO,QAAQ,KAAK,aACtB,OAAM,IAAI,oBAAoB,iBAAiB;AAGjD,MAAI,OAAO,QAAQ,QAAW;AAC5B,OAAI,OAAO,OAAO,QAAQ,SACxB,OAAM,IAAI,oBACR,iDACD;AAGH,OAAI,OAAO,MAAM,UAAU,eACzB,OAAM,IAAI,oBACR,wEACD;;AAML,MAAI,EAFa,MAAM,QAAQ,OAAO,IAAI,GAAG,OAAO,MAAM,CAAC,OAAO,IAAI,EAExD,SAAS,KAAK,SAAS,CACnC,OAAM,IAAI,oBAAoB,yBAAyB;AAGzD,SAAO;;;;;;;;;;;;;;CAeT,OAAO,UAAU,KAA4B;AAC3C,MAAI;GACF,MAAM,GAAG,WAAW,IAAI,MAAM,IAAI;AAElC,OAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,oBAAoB,+BAA+B;GAG/D,MAAM,UAAUG,uCAAgB,QAAQ;AAExC,OAAI,CAAC,QAAQ,WAAW,IAAI,CAC1B,OAAM,IAAI,oBAAoB,2BAA2B;AAG3D,UAAO,KAAK,MAAM,QAAQ;WACnB,GAAG;AACV,OAAI,aAAa,uBACf,OAAM;AAGR,SAAM,IAAI,oBACR,6CACD"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as SecurityAlgorithms, C as Prompt, D as RefreshSessionOptions, E as RefreshGrantOptions, M as UserinfoResponse, O as ResponseModes, S as ParResponse, T as RefetchUserInfoOptions, _ as JwsHeaderParameters, a as Authenticators, b as MonoCloudUser, c as ClientAuthMethod, d as EndSessionParameters, f as Group, g as Jwks, h as Jwk, i as AuthenticateOptions, j as Tokens, k as ResponseTypes, l as CodeChallengeMethod, m as IssuerMetadata, n as Address, o as AuthorizationParams, p as IdTokenClaims, r as AuthState, s as CallbackParams, t as AccessToken, u as DisplayOptions, v as MonoCloudClientOptions, w as PushedAuthorizationParams, x as OnSessionCreating, y as MonoCloudSession } from "./types-
|
|
1
|
+
import { A as SecurityAlgorithms, C as Prompt, D as RefreshSessionOptions, E as RefreshGrantOptions, M as UserinfoResponse, O as ResponseModes, S as ParResponse, T as RefetchUserInfoOptions, _ as JwsHeaderParameters, a as Authenticators, b as MonoCloudUser, c as ClientAuthMethod, d as EndSessionParameters, f as Group, g as Jwks, h as Jwk, i as AuthenticateOptions, j as Tokens, k as ResponseTypes, l as CodeChallengeMethod, m as IssuerMetadata, n as Address, o as AuthorizationParams, p as IdTokenClaims, r as AuthState, s as CallbackParams, t as AccessToken, u as DisplayOptions, v as MonoCloudClientOptions, w as PushedAuthorizationParams, x as OnSessionCreating, y as MonoCloudSession } from "./types-DmlJMcTH.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors/monocloud-auth-base-error.d.ts
|
|
4
4
|
/**
|
|
@@ -217,7 +217,7 @@ declare class MonoCloudOidcClient {
|
|
|
217
217
|
authenticate(code: string, redirectUri: string, requestedScopes: string, resource?: string, options?: AuthenticateOptions): Promise<MonoCloudSession>;
|
|
218
218
|
/**
|
|
219
219
|
* Refetches user information for an existing session using the userinfo endpoint.
|
|
220
|
-
* Updates the session's user object with the latest user information
|
|
220
|
+
* Updates the session's user object with the latest user information.
|
|
221
221
|
*
|
|
222
222
|
* @param accessToken - Access token used to fetch the userinfo.
|
|
223
223
|
* @param session - The current MonoCloudSession.
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { decodeBase64Url, encodeBase64Url, findToken, getPublicSigKeyFromIssuerJwks, now, parseSpaceSeparated, randomBytes, stringToArrayBuffer } from "./utils/internal.mjs";
|
|
1
|
+
import { decodeBase64Url, encodeBase64Url, findToken, getPublicSigKeyFromIssuerJwks, now, parseSpaceSeparated, profileSync, randomBytes, stringToArrayBuffer } from "./utils/internal.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors/monocloud-auth-base-error.ts
|
|
4
4
|
/**
|
|
@@ -608,10 +608,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
608
608
|
delete idTokenClaims[x];
|
|
609
609
|
});
|
|
610
610
|
const session = {
|
|
611
|
-
user:
|
|
612
|
-
...idTokenClaims,
|
|
613
|
-
...userinfo ?? {}
|
|
614
|
-
},
|
|
611
|
+
user: profileSync(void 0, idTokenClaims, userinfo, true),
|
|
615
612
|
idToken: tokens.id_token,
|
|
616
613
|
refreshToken: tokens.refresh_token,
|
|
617
614
|
authorizedScopes: requestedScopes,
|
|
@@ -628,7 +625,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
628
625
|
}
|
|
629
626
|
/**
|
|
630
627
|
* Refetches user information for an existing session using the userinfo endpoint.
|
|
631
|
-
* Updates the session's user object with the latest user information
|
|
628
|
+
* Updates the session's user object with the latest user information.
|
|
632
629
|
*
|
|
633
630
|
* @param accessToken - Access token used to fetch the userinfo.
|
|
634
631
|
* @param session - The current MonoCloudSession.
|
|
@@ -650,10 +647,8 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
650
647
|
async refetchUserInfo(accessToken, session, options) {
|
|
651
648
|
if (!accessToken.scopes?.includes("openid")) throw new MonoCloudValidationError("Fetching userinfo requires the openid scope");
|
|
652
649
|
const userinfo = await this.userinfo(accessToken.accessToken);
|
|
653
|
-
session.
|
|
654
|
-
|
|
655
|
-
...userinfo
|
|
656
|
-
};
|
|
650
|
+
const idTokenClaims = session.idToken && options?.strictProfileSync ? MonoCloudOidcClient.decodeJwt(session.idToken) : void 0;
|
|
651
|
+
session.user = profileSync(session.user, idTokenClaims, userinfo, options?.strictProfileSync);
|
|
657
652
|
await options?.onSessionCreating?.(session, void 0, userinfo);
|
|
658
653
|
return session;
|
|
659
654
|
}
|
|
@@ -691,6 +686,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
691
686
|
const jwks = options?.jwks ?? await this.getJwks();
|
|
692
687
|
idTokenClaims = await this.validateIdToken(tokens.id_token, jwks.keys, options?.idTokenClockSkew ?? 0, options?.idTokenClockTolerance ?? 0);
|
|
693
688
|
} else idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);
|
|
689
|
+
else if (session.idToken) idTokenClaims = MonoCloudOidcClient.decodeJwt(session.idToken);
|
|
694
690
|
(options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach((x) => {
|
|
695
691
|
delete idTokenClaims[x];
|
|
696
692
|
});
|
|
@@ -698,11 +694,7 @@ var MonoCloudOidcClient = class MonoCloudOidcClient {
|
|
|
698
694
|
let scopes = options?.refreshGrantOptions?.scopes;
|
|
699
695
|
if (!resource && !scopes) scopes = session.authorizedScopes;
|
|
700
696
|
const accessToken = findToken(session.accessTokens, resource, scopes);
|
|
701
|
-
const user =
|
|
702
|
-
...session.user,
|
|
703
|
-
...idTokenClaims,
|
|
704
|
-
...userinfo ?? {}
|
|
705
|
-
};
|
|
697
|
+
const user = profileSync(session.user, idTokenClaims, userinfo, options?.strictProfileSync);
|
|
706
698
|
const newTokens = session.accessTokens?.filter((t) => t !== accessToken) ?? [];
|
|
707
699
|
newTokens.push({
|
|
708
700
|
scopes: tokens.scope,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/errors/monocloud-auth-base-error.ts","../src/errors/monocloud-op-error.ts","../src/errors/monocloud-http-error.ts","../src/errors/monocloud-token-error.ts","../src/errors/monocloud-validation-error.ts","../src/client-auth.ts","../src/monocloud-oidc-client.ts"],"sourcesContent":["/**\n * Base class for all MonoCloud authentication errors.\n *\n * All errors thrown by the MonoCloud SDK extend this class, allowing applications to safely detect and handle MonoCloud-specific failures using `instanceof`.\n *\n * @category Error Classes\n */\nexport class MonoCloudAuthBaseError extends Error {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * OAuth error returned by the authorization server during an authentication or token request.\n *\n * These errors correspond to standard OAuth / OpenID Connect error responses such as `invalid_request`, `access_denied`, or `invalid_grant`.\n *\n * @category Error Classes\n */\nexport class MonoCloudOPError extends MonoCloudAuthBaseError {\n /** OAuth error code returned by the authorization server. */\n error: string;\n\n /** Human-readable description of the error. */\n errorDescription?: string;\n\n constructor(error: string, errorDescription?: string) {\n super(error);\n this.error = error;\n this.errorDescription = errorDescription;\n }\n}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a request to the MonoCloud authorization server fails.\n *\n * This error typically indicates a network failure, an unexpected HTTP response, or an unsuccessful response returned by the authorization server.\n *\n * @category Error Classes\n */\nexport class MonoCloudHttpError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a token operation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudTokenError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when validation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudValidationError extends MonoCloudAuthBaseError {}\n","import {\n encodeBase64Url,\n randomBytes,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { ClientAuthMethod, Jwk } from './types';\n\nconst algToSubtle = (\n alg?: string\n): HmacImportParams | RsaHashedImportParams | EcKeyImportParams => {\n switch (alg) {\n case 'HS256':\n case 'HS384':\n case 'HS512':\n return { name: 'HMAC', hash: `SHA-${alg.slice(-3)}` };\n case 'PS256':\n case 'PS384':\n case 'PS512':\n return { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n case 'RS256':\n case 'RS384':\n case 'RS512':\n return { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n case 'ES256':\n case 'ES384':\n return { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n case 'ES512':\n return { name: 'ECDSA', namedCurve: 'P-521' };\n /* v8 ignore next */\n default:\n throw new Error('unsupported JWS algorithm');\n }\n};\n\nconst psAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'PS256';\n case 'SHA-384':\n return 'PS384';\n case 'SHA-512':\n return 'PS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst rsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'RS256';\n case 'SHA-384':\n return 'RS384';\n case 'SHA-512':\n return 'RS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst esAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as EcKeyAlgorithm).namedCurve) {\n case 'P-256':\n return 'ES256';\n case 'P-384':\n return 'ES384';\n case 'P-521':\n return 'ES512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported EcKeyAlgorithm namedCurve');\n }\n};\n\nconst hsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as HmacKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'HS256';\n case 'SHA-384':\n return 'HS384';\n case 'SHA-512':\n return 'HS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported HMAC Algorithm hash');\n }\n};\n\nconst keyToJws = (key: CryptoKey): string => {\n switch (key.algorithm.name) {\n case 'HMAC':\n return hsAlg(key);\n case 'RSA-PSS':\n return psAlg(key);\n case 'RSASSA-PKCS1-v1_5':\n return rsAlg(key);\n case 'ECDSA':\n return esAlg(key);\n /* v8 ignore next */\n default:\n throw new Error('unsupported CryptoKey algorithm name');\n }\n};\n\nconst checkRsaKeyAlgorithm = (key: CryptoKey): void => {\n const { algorithm } = key as CryptoKey & { algorithm: RsaHashedKeyAlgorithm };\n\n /* v8 ignore if -- @preserve */\n if (\n typeof algorithm.modulusLength !== 'number' ||\n algorithm.modulusLength < 2048\n ) {\n throw new Error(`Unsupported ${algorithm.name} modulusLength`);\n }\n};\n\nconst ecdsaHashName = (key: CryptoKey): string => {\n const { algorithm } = key as CryptoKey & { algorithm: EcKeyAlgorithm };\n switch (algorithm.namedCurve) {\n case 'P-256':\n return 'SHA-256';\n case 'P-384':\n return 'SHA-384';\n case 'P-521':\n return 'SHA-512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported ECDSA namedCurve');\n }\n};\n\nexport const keyToSubtle = (\n key: CryptoKey\n): AlgorithmIdentifier | RsaPssParams | EcdsaParams => {\n switch (key.algorithm.name) {\n case 'HMAC': {\n return { name: key.algorithm.name };\n }\n case 'ECDSA':\n return {\n name: key.algorithm.name,\n hash: ecdsaHashName(key),\n } as EcdsaParams;\n case 'RSA-PSS': {\n checkRsaKeyAlgorithm(key);\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256': // Fall through\n case 'SHA-384': // Fall through\n case 'SHA-512':\n return {\n name: key.algorithm.name,\n saltLength:\n parseInt(\n (key.algorithm as RsaHashedKeyAlgorithm).hash.name.slice(-3),\n 10\n ) >> 3,\n } as RsaPssParams;\n /* v8 ignore next */\n default:\n throw new Error('unsupported RSA-PSS hash name');\n }\n }\n case 'RSASSA-PKCS1-v1_5':\n checkRsaKeyAlgorithm(key);\n return key.algorithm.name;\n }\n /* v8 ignore next -- @preserve */\n throw new Error('unsupported CryptoKey algorithm name');\n};\n\nconst clientAssertionPayload = (\n issuer: string,\n clientId: string,\n skew: number\n): Record<string, number | string> => {\n const now = Math.floor(Date.now() / 1000) + skew;\n return {\n jti: randomBytes(),\n aud: issuer,\n exp: now + 60,\n iat: now,\n nbf: now,\n iss: clientId,\n sub: clientId,\n };\n};\n\nconst jwtAssertionGenerator = async (\n issuer: string,\n clientId: string,\n clientSecret: Jwk,\n body: URLSearchParams,\n skew: number\n): Promise<void> => {\n const key = await crypto.subtle.importKey(\n 'jwk',\n clientSecret as JsonWebKey,\n algToSubtle(clientSecret.alg),\n false,\n ['sign']\n );\n\n const header = { alg: keyToJws(key), kid: clientSecret.kid };\n const payload = clientAssertionPayload(issuer, clientId, skew);\n\n body.set('client_id', clientId);\n body.set(\n 'client_assertion_type',\n 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\n );\n\n const input = `${encodeBase64Url(stringToArrayBuffer(JSON.stringify(header)))}.${encodeBase64Url(stringToArrayBuffer(JSON.stringify(payload)))}`;\n const signature = encodeBase64Url(\n await crypto.subtle.sign(\n keyToSubtle(key),\n key,\n stringToArrayBuffer(input) as BufferSource\n )\n );\n\n body.set('client_assertion', `${input}.${signature}`);\n};\n\nexport const clientAuth = async (\n clientId: string,\n clientSecret?: string | Jwk,\n method?: ClientAuthMethod,\n issuer?: string,\n headers?: Record<string, string>,\n body?: URLSearchParams,\n jwtAssertionSkew?: number\n): Promise<void> => {\n switch (true) {\n case method === 'client_secret_basic' && !!headers: {\n // eslint-disable-next-line no-param-reassign\n headers.authorization = `Basic ${btoa(`${clientId}:${clientSecret ?? ''}`)}`;\n break;\n }\n\n case method === 'client_secret_post' && !!body: {\n body.set('client_id', clientId);\n if (typeof clientSecret === 'string') {\n body.set('client_secret', clientSecret);\n }\n break;\n }\n\n case method === 'client_secret_jwt' &&\n !!issuer &&\n !!body &&\n (typeof clientSecret === 'string' || clientSecret?.kty === 'oct'): {\n const cs =\n typeof clientSecret === 'string'\n ? {\n k: encodeBase64Url(stringToArrayBuffer(clientSecret)),\n kty: 'oct',\n alg: 'HS256',\n }\n : clientSecret;\n\n await jwtAssertionGenerator(\n issuer,\n clientId,\n cs,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n case method === 'private_key_jwt' &&\n typeof clientSecret === 'object' &&\n clientSecret.kty !== 'oct' &&\n !!issuer &&\n !!body: {\n await jwtAssertionGenerator(\n issuer,\n clientId,\n clientSecret,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n default:\n throw new Error('Invalid Client Authentication Method');\n }\n};\n","import {\n decodeBase64Url,\n findToken,\n getPublicSigKeyFromIssuerJwks,\n now,\n parseSpaceSeparated,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { clientAuth, keyToSubtle } from './client-auth';\nimport {\n AccessToken,\n AuthenticateOptions,\n AuthorizationParams,\n ClientAuthMethod,\n EndSessionParameters,\n IdTokenClaims,\n IssuerMetadata,\n Jwk,\n Jwks,\n SecurityAlgorithms,\n JwsHeaderParameters,\n MonoCloudClientOptions,\n MonoCloudSession,\n MonoCloudUser,\n ParResponse,\n PushedAuthorizationParams,\n RefetchUserInfoOptions,\n RefreshGrantOptions,\n RefreshSessionOptions,\n Tokens,\n UserinfoResponse,\n} from './types';\nimport { MonoCloudOPError } from './errors/monocloud-op-error';\nimport { MonoCloudHttpError } from './errors/monocloud-http-error';\nimport { MonoCloudValidationError } from './errors/monocloud-validation-error';\nimport { MonoCloudTokenError } from './errors/monocloud-token-error';\nimport { MonoCloudAuthBaseError } from './errors/monocloud-auth-base-error';\n\nconst JWT_ASSERTION_CLOCK_SKEW = 5;\n\nconst FILTER_ID_TOKEN_CLAIMS = [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n];\n\nfunction assertMetadataProperty<K extends keyof IssuerMetadata>(\n metadata: IssuerMetadata,\n property: K\n): asserts metadata is IssuerMetadata & Required<Pick<IssuerMetadata, K>> {\n if (metadata[property] === undefined || metadata[property] === null) {\n throw new MonoCloudValidationError(\n `${property as string} endpoint is required but not available in the issuer metadata`\n );\n }\n}\n\nconst innerFetch = async (\n input: string,\n reqInit: RequestInit = {}\n): Promise<Response> => {\n try {\n return await fetch(input, reqInit);\n } catch (e) {\n /* v8 ignore next -- @preserve */\n throw new MonoCloudHttpError(\n (e as any).message ?? 'Unexpected Network Error'\n );\n }\n};\n\nconst deserializeJson = async <T = any>(res: Response): Promise<T> => {\n try {\n return await res.json();\n } catch (e) {\n throw new MonoCloudHttpError(\n /* v8 ignore next -- @preserve */\n `Failed to parse response body as JSON ${(e as any).message ? `: ${(e as any).message}` : ''}`\n );\n }\n};\n\n/**\n * @category Classes\n */\nexport class MonoCloudOidcClient {\n private readonly tenantDomain: string;\n\n private readonly clientId: string;\n\n private readonly clientSecret?: string | Jwk;\n\n private readonly authMethod: ClientAuthMethod;\n\n private readonly idTokenSigningAlgorithm: SecurityAlgorithms;\n\n private jwks?: Jwks;\n\n private jwksCacheExpiry = 0;\n\n private jwksCacheDuration = 300;\n\n private metadata?: IssuerMetadata;\n\n private metadataCacheExpiry = 0;\n\n private metadataCacheDuration = 300;\n\n constructor(\n tenantDomain: string,\n clientId: string,\n options?: MonoCloudClientOptions\n ) {\n // eslint-disable-next-line no-param-reassign\n tenantDomain ??= '';\n /* v8 ignore next -- @preserve */\n this.tenantDomain = `${!tenantDomain.startsWith('https://') ? 'https://' : ''}${tenantDomain.endsWith('/') ? tenantDomain.slice(0, -1) : tenantDomain}`;\n this.clientId = clientId;\n this.clientSecret = options?.clientSecret;\n this.authMethod = options?.clientAuthMethod ?? 'client_secret_basic';\n this.idTokenSigningAlgorithm = options?.idTokenSigningAlgorithm ?? 'RS256';\n\n if (options?.jwksCacheDuration) {\n this.jwksCacheDuration = options.jwksCacheDuration;\n }\n\n if (options?.metadataCacheDuration) {\n this.metadataCacheDuration = options.metadataCacheDuration;\n }\n }\n\n /**\n * Generates an authorization URL with specified parameters.\n *\n * If no values are provided for `responseType`, or `codeChallengeMethod`, they default to `code`, and `S256`, respectively.\n *\n * @param params - Authorization URL parameters.\n *\n * @returns Tenant's authorization URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authorizationUrl(params: AuthorizationParams): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n queryParams.set('redirect_uri', params.redirectUri);\n }\n\n if (params.requestUri) {\n queryParams.set('request_uri', params.requestUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n queryParams.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n queryParams.set('response_type', params.responseType);\n }\n\n if (\n (!params.responseType || params.responseType.length === 0) &&\n !params.requestUri\n ) {\n queryParams.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n queryParams.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n queryParams.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n queryParams.set('request', params.request);\n }\n\n if (params.responseMode) {\n queryParams.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n queryParams.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n queryParams.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n queryParams.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n queryParams.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n queryParams.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n queryParams.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n queryParams.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n queryParams.set('code_challenge', params.codeChallenge);\n queryParams.set(\n 'code_challenge_method',\n params.codeChallengeMethod ?? 'S256'\n );\n }\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'authorization_endpoint');\n\n return `${metadata.authorization_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Fetches the authorization server metadata from the .well-known endpoint.\n * The metadata is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh metadata from the server.\n *\n * @returns The issuer metadata for the tenant, retrieved from the OpenID Connect discovery endpoint.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getMetadata(forceRefresh = false): Promise<IssuerMetadata> {\n if (!forceRefresh && this.metadata && this.metadataCacheExpiry > now()) {\n return this.metadata;\n }\n\n this.metadata = undefined;\n\n const response = await innerFetch(\n `${this.tenantDomain}/.well-known/openid-configuration`\n );\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching metadata. Unexpected status code: ${response.status}`\n );\n }\n\n const metadata = await deserializeJson<IssuerMetadata>(response);\n\n this.metadata = metadata;\n this.metadataCacheExpiry = now() + this.metadataCacheDuration;\n\n return metadata;\n }\n\n /**\n * Fetches the JSON Web Keys used to sign the ID token.\n * The JWKS is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh set of JWKS from the server.\n *\n * @returns The JSON Web Key Set containing the public keys for token verification.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getJwks(forceRefresh = false): Promise<Jwks> {\n if (!forceRefresh && this.jwks && this.jwksCacheExpiry > now()) {\n return this.jwks;\n }\n\n this.jwks = undefined;\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'jwks_uri');\n\n const response = await innerFetch(metadata.jwks_uri);\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching JWKS. Unexpected status code: ${response.status}`\n );\n }\n const jwks = await deserializeJson<Jwks>(response);\n\n this.jwks = jwks;\n this.jwksCacheExpiry = now() + this.jwksCacheDuration;\n\n return jwks;\n }\n\n /**\n * Performs a pushed authorization request.\n *\n * @param params - Authorization Parameters.\n *\n * @returns Response from Pushed Authorization Request (PAR) endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the request is invalid.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async pushedAuthorizationRequest(\n params: PushedAuthorizationParams\n ): Promise<ParResponse> {\n const body = new URLSearchParams();\n\n body.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n body.set('redirect_uri', params.redirectUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n body.set('response_type', params.responseType);\n } else {\n body.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n body.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n body.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n body.set('request', params.request);\n }\n\n if (params.responseMode) {\n body.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n body.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n body.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n body.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n body.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n body.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n body.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n body.set('code_challenge', params.codeChallenge);\n body.set('code_challenge_method', params.codeChallengeMethod ?? 'S256');\n }\n\n if (params.state) {\n body.set('state', params.state);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'pushed_authorization_request_endpoint');\n\n const response = await innerFetch(\n metadata.pushed_authorization_request_endpoint,\n {\n body: body.toString(),\n method: 'POST',\n headers,\n }\n );\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'par_request_failed',\n standardBodyError.error_description ??\n 'Pushed Authorization Request Failed'\n );\n }\n\n if (response.status !== 201) {\n throw new MonoCloudHttpError(\n `Error while performing pushed authorization request. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<ParResponse>(response);\n }\n\n /**\n * Fetches userinfo associated with the provided access token.\n *\n * @param accessToken - A valid access token used to retrieve userinfo.\n *\n * @returns The authenticated user's claims.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error (e.g., 'invalid_token') in the 'WWW-Authenticate' header\n * following a 401 Unauthorized response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n * @throws {@link MonoCloudValidationError} - When the access token is invalid.\n *\n */\n async userinfo(accessToken: string): Promise<UserinfoResponse> {\n if (!accessToken.trim().length) {\n throw new MonoCloudValidationError(\n 'Access token is required for fetching userinfo'\n );\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'userinfo_endpoint');\n\n const response = await innerFetch(metadata.userinfo_endpoint, {\n method: 'GET',\n headers: {\n authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (response.status === 401) {\n const authenticateError = response.headers.get('WWW-Authenticate');\n\n if (authenticateError) {\n const errorMatch = /error=\"([^\"]+)\"/.exec(authenticateError);\n const error = errorMatch ? errorMatch[1] : 'userinfo_failed';\n\n const errorDescMatch = /error_description=\"([^\"]+)\"/.exec(\n authenticateError\n );\n\n const errorDescription = errorDescMatch\n ? errorDescMatch[1]\n : 'Userinfo authentication error';\n\n throw new MonoCloudOPError(error, errorDescription);\n }\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching userinfo. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<UserinfoResponse>(response);\n }\n\n /**\n * Generates OpenID end session URL for signing out.\n *\n * Note - The `state` is added only when `postLogoutRedirectUri` is present.\n *\n * @param params - Parameters to build end session URL.\n *\n * @returns Tenant's end session URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async endSessionUrl(params: EndSessionParameters): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.idToken) {\n queryParams.set('id_token_hint', params.idToken);\n }\n\n if (params.postLogoutRedirectUri) {\n queryParams.set('post_logout_redirect_uri', params.postLogoutRedirectUri);\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'end_session_endpoint');\n\n return `${metadata.end_session_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Exchanges an authorization code for tokens.\n *\n * @param code - The authorization code received from the authorization server.\n * @param redirectUri - The redirect URI used in the initial authorization request.\n * @param codeVerifier - Code verifier for PKCE.\n * @param resource - Space-separated list of resources the access token should be scoped to.\n *\n * @returns Tokens obtained by exchanging an authorization code at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async exchangeAuthorizationCode(\n code: string,\n redirectUri: string,\n codeVerifier?: string,\n resource?: string\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'authorization_code');\n body.set('code', code);\n body.set('redirect_uri', redirectUri);\n\n if (codeVerifier) {\n body.set('code_verifier', codeVerifier);\n }\n\n const resources = parseSpaceSeparated(resource) ?? [];\n\n if (resources.length > 0) {\n for (const r of resources) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'code_grant_failed',\n standardBodyError.error_description ?? 'Authorization code grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Exchanges a refresh token for new tokens.\n *\n * @param refreshToken - The refresh token used to request new tokens.\n * @param options - Refresh grant options.\n *\n * @returns Tokens obtained by exchanging a refresh token at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshGrant(\n refreshToken: string,\n options?: RefreshGrantOptions\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'refresh_token');\n body.set('refresh_token', refreshToken);\n\n const scopes = parseSpaceSeparated(options?.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n const resource = parseSpaceSeparated(options?.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'refresh_grant_failed',\n standardBodyError.error_description ?? 'Refresh token grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing refresh token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Generates a session with user and tokens by exchanging authorization code from callback params.\n *\n * @param code - The authorization code received from the callback.\n * @param redirectUri - The redirect URI that was used in the authorization request.\n * @param requestedScopes - A space-separated list of scopes originally requested via the `/authorize` endpoint.\n * This is stored in the session to ensure the correct access token can be identified and refreshed during `refreshSession()`.\n * @param resource - A space-separated list of resource indicators originally requested via the `/authorize` endpoint.\n * Used alongside scopes to uniquely identify and refresh the specific access token associated with these resources.\n * @param options - Options for authenticating a user with authorization code.\n *\n * @returns The user's session containing authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain the openid scope,\n * or if 'expires_in' or 'scope' is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized.\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authenticate(\n code: string,\n redirectUri: string,\n requestedScopes: string,\n resource?: string,\n options?: AuthenticateOptions\n ): Promise<MonoCloudSession> {\n const tokens = await this.exchangeAuthorizationCode(\n code,\n redirectUri,\n options?.codeVerifier,\n resource\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0,\n options?.idTokenMaxAge,\n options?.idTokenNonce\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const session: MonoCloudSession = {\n user: {\n ...idTokenClaims,\n ...(userinfo ?? {}),\n } as MonoCloudUser,\n idToken: tokens.id_token,\n refreshToken: tokens.refresh_token,\n authorizedScopes: requestedScopes,\n accessTokens: [\n {\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes,\n },\n ],\n };\n\n await options?.onSessionCreating?.(session, idTokenClaims, userinfo);\n\n return session;\n }\n\n /**\n * Refetches user information for an existing session using the userinfo endpoint.\n * Updates the session's user object with the latest user information while preserving existing properties.\n *\n * @param accessToken - Access token used to fetch the userinfo.\n * @param session - The current MonoCloudSession.\n * @param options - Userinfo refetch options.\n *\n * @returns Updated session with the latest userinfo.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain openid scope\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refetchUserInfo(\n accessToken: AccessToken,\n session: MonoCloudSession,\n options?: RefetchUserInfoOptions\n ): Promise<MonoCloudSession> {\n if (!accessToken.scopes?.includes('openid')) {\n throw new MonoCloudValidationError(\n 'Fetching userinfo requires the openid scope'\n );\n }\n\n const userinfo = await this.userinfo(accessToken.accessToken);\n\n // eslint-disable-next-line no-param-reassign\n session.user = { ...session.user, ...userinfo };\n\n await options?.onSessionCreating?.(session, undefined, userinfo);\n\n return session;\n }\n\n /**\n * Refreshes an existing session using the refresh token.\n * This function requests new tokens using the refresh token and optionally updates user information.\n *\n * @param session - The current MonoCloudSession containing the refresh token.\n * @param options - Session refresh options.\n *\n * @returns User's session containing refreshed authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - If the refresh token is not present in the session,\n * or if 'expires_in' or 'scope' (including the openid scope) is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshSession(\n session: MonoCloudSession,\n options?: RefreshSessionOptions\n ): Promise<MonoCloudSession> {\n if (!session.refreshToken) {\n throw new MonoCloudValidationError(\n 'Session does not contain refresh token'\n );\n }\n\n const tokens = await this.refreshGrant(\n session.refreshToken,\n options?.refreshGrantOptions\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const resource = options?.refreshGrantOptions?.resource;\n let scopes = options?.refreshGrantOptions?.scopes;\n\n if (!resource && !scopes) {\n scopes = session.authorizedScopes;\n }\n\n const accessToken = findToken(session.accessTokens, resource, scopes);\n\n const user =\n Object.keys(idTokenClaims).length === 0 && !userinfo\n ? session.user\n : ({\n ...session.user,\n ...idTokenClaims,\n ...(userinfo ?? {}),\n } as MonoCloudUser);\n\n const newTokens =\n session.accessTokens?.filter(t => t !== accessToken) ?? [];\n\n newTokens.push({\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes: scopes,\n });\n\n const updatedSession: MonoCloudSession = {\n ...session,\n user,\n idToken: tokens.id_token ?? session.idToken,\n refreshToken: tokens.refresh_token ?? session.refreshToken,\n accessTokens: newTokens,\n };\n\n await options?.onSessionCreating?.(updatedSession, idTokenClaims, userinfo);\n\n return updatedSession;\n }\n\n /**\n * Revokes an access token or refresh token, rendering it invalid for future use.\n *\n * @param token - The token string to be revoked.\n * @param tokenType - Hint about the token type ('access_token' or 'refresh_token').\n *\n * @returns If token revocation succeeded.\n *\n * @throws {@link MonoCloudValidationError} - If token is invalid or unsupported token type\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n */\n async revokeToken(token: string, tokenType?: string): Promise<void> {\n if (!token.trim().length) {\n throw new MonoCloudValidationError('Invalid token');\n }\n\n if (\n tokenType &&\n tokenType !== 'access_token' &&\n tokenType !== 'refresh_token'\n ) {\n throw new MonoCloudValidationError(\n 'Only access_token and refresh_token types are supported.'\n );\n }\n\n const body = new URLSearchParams();\n body.set('token', token);\n if (tokenType) {\n body.set('token_type_hint', tokenType);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'revocation_endpoint');\n\n const response = await innerFetch(metadata.revocation_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'revocation_failed',\n standardBodyError.error_description ?? 'Token revocation failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing revocation request. Unexpected status code: ${response.status}`\n );\n }\n }\n\n /**\n * Validates an ID Token.\n *\n * @param idToken - The ID Token JWT string to validate.\n * @param jwks - Array of JSON Web Keys (JWK) used to verify the token's signature.\n * @param clockSkew - Number of seconds to adjust the current time to account for clock differences.\n * @param clockTolerance - Additional time tolerance in seconds for time-based claim validation.\n * @param maxAge - Maximum authentication age in seconds.\n * @param nonce - Nonce value to validate against the token's nonce claim.\n *\n * @returns Validated ID Token claims.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n */\n async validateIdToken(\n idToken: string,\n jwks: Jwk[],\n clockSkew: number,\n clockTolerance: number,\n maxAge?: number,\n nonce?: string\n ): Promise<IdTokenClaims> {\n if (typeof idToken !== 'string' || idToken.trim().length === 0) {\n throw new MonoCloudTokenError(\n 'ID Token must be a valid non-empty string'\n );\n }\n\n const {\n 0: protectedHeader,\n 1: payload,\n 2: encodedSignature,\n length,\n } = idToken.split('.');\n\n if (length !== 3) {\n throw new MonoCloudTokenError(\n 'ID Token must have a header, payload and signature'\n );\n }\n\n let header: JwsHeaderParameters;\n try {\n header = JSON.parse(decodeBase64Url(protectedHeader));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Header');\n }\n\n if (\n header === null ||\n typeof header !== 'object' ||\n Array.isArray(header)\n ) {\n throw new MonoCloudTokenError('JWT Header must be a top level object');\n }\n\n if (this.idTokenSigningAlgorithm !== header.alg) {\n throw new MonoCloudTokenError('Invalid signing alg');\n }\n\n if (header.crit !== undefined) {\n throw new MonoCloudTokenError('Unexpected JWT \"crit\" header parameter');\n }\n\n const binary = decodeBase64Url(encodedSignature);\n\n const signature = new Uint8Array(binary.length);\n\n for (let i = 0; i < binary.length; i++) {\n signature[i] = binary.charCodeAt(i);\n }\n\n const key = await getPublicSigKeyFromIssuerJwks(jwks, header);\n\n const input = `${protectedHeader}.${payload}`;\n\n const verified = await crypto.subtle.verify(\n keyToSubtle(key),\n key,\n signature,\n stringToArrayBuffer(input) as BufferSource\n );\n\n if (!verified) {\n throw new MonoCloudTokenError('JWT signature verification failed');\n }\n\n let claims: IdTokenClaims;\n\n try {\n claims = JSON.parse(decodeBase64Url(payload));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Payload');\n }\n\n if (\n claims === null ||\n typeof claims !== 'object' ||\n Array.isArray(claims)\n ) {\n throw new MonoCloudTokenError('JWT Payload must be a top level object');\n }\n\n if ((claims.nonce || nonce) && claims.nonce !== nonce) {\n throw new MonoCloudTokenError('Nonce mismatch');\n }\n\n const current = now() + clockSkew;\n\n /* v8 ignore else -- @preserve */\n if (claims.exp !== undefined) {\n if (typeof claims.exp !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim type'\n );\n }\n\n if (claims.exp <= current - clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim value, timestamp is <= now()'\n );\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (claims.iat !== undefined) {\n if (typeof claims.iat !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"iat\" (issued at) claim type'\n );\n }\n }\n\n if (\n typeof claims.auth_time === 'number' &&\n typeof maxAge === 'number' &&\n claims.auth_time + maxAge < current\n ) {\n throw new MonoCloudTokenError(\n 'Too much time has elapsed since the last End-User authentication'\n );\n }\n\n if (claims.iss !== this.tenantDomain) {\n throw new MonoCloudTokenError('Invalid Issuer');\n }\n\n if (claims.nbf !== undefined) {\n if (typeof claims.nbf !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim type'\n );\n }\n\n if (claims.nbf > current + clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim value, timestamp is > now()'\n );\n }\n }\n\n const audience = Array.isArray(claims.aud) ? claims.aud : [claims.aud];\n\n if (!audience.includes(this.clientId)) {\n throw new MonoCloudTokenError('Invalid audience claim');\n }\n\n return claims;\n }\n\n /**\n * Decodes the payload of a JSON Web Token (JWT) and returns it as an object.\n *\n * >Note: THIS METHOD DOES NOT VERIFY JWT TOKENS.\n *\n * @param jwt - JWT to decode.\n *\n * @returns Decoded payload.\n *\n * @throws {@link MonoCloudTokenError} - If decoding fails\n *\n */\n static decodeJwt(jwt: string): IdTokenClaims {\n try {\n const [, payload] = jwt.split('.');\n\n if (!payload?.trim()) {\n throw new MonoCloudTokenError('JWT does not contain payload');\n }\n\n const decoded = decodeBase64Url(payload);\n\n if (!decoded.startsWith('{')) {\n throw new MonoCloudTokenError('Payload is not an object');\n }\n\n return JSON.parse(decoded) as IdTokenClaims;\n } catch (e) {\n if (e instanceof MonoCloudAuthBaseError) {\n throw e;\n }\n\n throw new MonoCloudTokenError(\n 'Could not parse payload. Malformed payload'\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/errors/monocloud-auth-base-error.ts","../src/errors/monocloud-op-error.ts","../src/errors/monocloud-http-error.ts","../src/errors/monocloud-token-error.ts","../src/errors/monocloud-validation-error.ts","../src/client-auth.ts","../src/monocloud-oidc-client.ts"],"sourcesContent":["/**\n * Base class for all MonoCloud authentication errors.\n *\n * All errors thrown by the MonoCloud SDK extend this class, allowing applications to safely detect and handle MonoCloud-specific failures using `instanceof`.\n *\n * @category Error Classes\n */\nexport class MonoCloudAuthBaseError extends Error {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * OAuth error returned by the authorization server during an authentication or token request.\n *\n * These errors correspond to standard OAuth / OpenID Connect error responses such as `invalid_request`, `access_denied`, or `invalid_grant`.\n *\n * @category Error Classes\n */\nexport class MonoCloudOPError extends MonoCloudAuthBaseError {\n /** OAuth error code returned by the authorization server. */\n error: string;\n\n /** Human-readable description of the error. */\n errorDescription?: string;\n\n constructor(error: string, errorDescription?: string) {\n super(error);\n this.error = error;\n this.errorDescription = errorDescription;\n }\n}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a request to the MonoCloud authorization server fails.\n *\n * This error typically indicates a network failure, an unexpected HTTP response, or an unsuccessful response returned by the authorization server.\n *\n * @category Error Classes\n */\nexport class MonoCloudHttpError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when a token operation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudTokenError extends MonoCloudAuthBaseError {}\n","import { MonoCloudAuthBaseError } from './monocloud-auth-base-error';\n\n/**\n * Error thrown when validation fails.\n *\n * @category Error Classes\n */\nexport class MonoCloudValidationError extends MonoCloudAuthBaseError {}\n","import {\n encodeBase64Url,\n randomBytes,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { ClientAuthMethod, Jwk } from './types';\n\nconst algToSubtle = (\n alg?: string\n): HmacImportParams | RsaHashedImportParams | EcKeyImportParams => {\n switch (alg) {\n case 'HS256':\n case 'HS384':\n case 'HS512':\n return { name: 'HMAC', hash: `SHA-${alg.slice(-3)}` };\n case 'PS256':\n case 'PS384':\n case 'PS512':\n return { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n case 'RS256':\n case 'RS384':\n case 'RS512':\n return { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n case 'ES256':\n case 'ES384':\n return { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n case 'ES512':\n return { name: 'ECDSA', namedCurve: 'P-521' };\n /* v8 ignore next */\n default:\n throw new Error('unsupported JWS algorithm');\n }\n};\n\nconst psAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'PS256';\n case 'SHA-384':\n return 'PS384';\n case 'SHA-512':\n return 'PS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst rsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'RS256';\n case 'SHA-384':\n return 'RS384';\n case 'SHA-512':\n return 'RS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported RsaHashedKeyAlgorithm hash name');\n }\n};\n\nconst esAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as EcKeyAlgorithm).namedCurve) {\n case 'P-256':\n return 'ES256';\n case 'P-384':\n return 'ES384';\n case 'P-521':\n return 'ES512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported EcKeyAlgorithm namedCurve');\n }\n};\n\nconst hsAlg = (key: CryptoKey): string => {\n switch ((key.algorithm as HmacKeyAlgorithm).hash.name) {\n case 'SHA-256':\n return 'HS256';\n case 'SHA-384':\n return 'HS384';\n case 'SHA-512':\n return 'HS512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported HMAC Algorithm hash');\n }\n};\n\nconst keyToJws = (key: CryptoKey): string => {\n switch (key.algorithm.name) {\n case 'HMAC':\n return hsAlg(key);\n case 'RSA-PSS':\n return psAlg(key);\n case 'RSASSA-PKCS1-v1_5':\n return rsAlg(key);\n case 'ECDSA':\n return esAlg(key);\n /* v8 ignore next */\n default:\n throw new Error('unsupported CryptoKey algorithm name');\n }\n};\n\nconst checkRsaKeyAlgorithm = (key: CryptoKey): void => {\n const { algorithm } = key as CryptoKey & { algorithm: RsaHashedKeyAlgorithm };\n\n /* v8 ignore if -- @preserve */\n if (\n typeof algorithm.modulusLength !== 'number' ||\n algorithm.modulusLength < 2048\n ) {\n throw new Error(`Unsupported ${algorithm.name} modulusLength`);\n }\n};\n\nconst ecdsaHashName = (key: CryptoKey): string => {\n const { algorithm } = key as CryptoKey & { algorithm: EcKeyAlgorithm };\n switch (algorithm.namedCurve) {\n case 'P-256':\n return 'SHA-256';\n case 'P-384':\n return 'SHA-384';\n case 'P-521':\n return 'SHA-512';\n /* v8 ignore next */\n default:\n throw new Error('unsupported ECDSA namedCurve');\n }\n};\n\nexport const keyToSubtle = (\n key: CryptoKey\n): AlgorithmIdentifier | RsaPssParams | EcdsaParams => {\n switch (key.algorithm.name) {\n case 'HMAC': {\n return { name: key.algorithm.name };\n }\n case 'ECDSA':\n return {\n name: key.algorithm.name,\n hash: ecdsaHashName(key),\n } as EcdsaParams;\n case 'RSA-PSS': {\n checkRsaKeyAlgorithm(key);\n switch ((key.algorithm as RsaHashedKeyAlgorithm).hash.name) {\n case 'SHA-256': // Fall through\n case 'SHA-384': // Fall through\n case 'SHA-512':\n return {\n name: key.algorithm.name,\n saltLength:\n parseInt(\n (key.algorithm as RsaHashedKeyAlgorithm).hash.name.slice(-3),\n 10\n ) >> 3,\n } as RsaPssParams;\n /* v8 ignore next */\n default:\n throw new Error('unsupported RSA-PSS hash name');\n }\n }\n case 'RSASSA-PKCS1-v1_5':\n checkRsaKeyAlgorithm(key);\n return key.algorithm.name;\n }\n /* v8 ignore next -- @preserve */\n throw new Error('unsupported CryptoKey algorithm name');\n};\n\nconst clientAssertionPayload = (\n issuer: string,\n clientId: string,\n skew: number\n): Record<string, number | string> => {\n const now = Math.floor(Date.now() / 1000) + skew;\n return {\n jti: randomBytes(),\n aud: issuer,\n exp: now + 60,\n iat: now,\n nbf: now,\n iss: clientId,\n sub: clientId,\n };\n};\n\nconst jwtAssertionGenerator = async (\n issuer: string,\n clientId: string,\n clientSecret: Jwk,\n body: URLSearchParams,\n skew: number\n): Promise<void> => {\n const key = await crypto.subtle.importKey(\n 'jwk',\n clientSecret as JsonWebKey,\n algToSubtle(clientSecret.alg),\n false,\n ['sign']\n );\n\n const header = { alg: keyToJws(key), kid: clientSecret.kid };\n const payload = clientAssertionPayload(issuer, clientId, skew);\n\n body.set('client_id', clientId);\n body.set(\n 'client_assertion_type',\n 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\n );\n\n const input = `${encodeBase64Url(stringToArrayBuffer(JSON.stringify(header)))}.${encodeBase64Url(stringToArrayBuffer(JSON.stringify(payload)))}`;\n const signature = encodeBase64Url(\n await crypto.subtle.sign(\n keyToSubtle(key),\n key,\n stringToArrayBuffer(input) as BufferSource\n )\n );\n\n body.set('client_assertion', `${input}.${signature}`);\n};\n\nexport const clientAuth = async (\n clientId: string,\n clientSecret?: string | Jwk,\n method?: ClientAuthMethod,\n issuer?: string,\n headers?: Record<string, string>,\n body?: URLSearchParams,\n jwtAssertionSkew?: number\n): Promise<void> => {\n switch (true) {\n case method === 'client_secret_basic' && !!headers: {\n // eslint-disable-next-line no-param-reassign\n headers.authorization = `Basic ${btoa(`${clientId}:${clientSecret ?? ''}`)}`;\n break;\n }\n\n case method === 'client_secret_post' && !!body: {\n body.set('client_id', clientId);\n if (typeof clientSecret === 'string') {\n body.set('client_secret', clientSecret);\n }\n break;\n }\n\n case method === 'client_secret_jwt' &&\n !!issuer &&\n !!body &&\n (typeof clientSecret === 'string' || clientSecret?.kty === 'oct'): {\n const cs =\n typeof clientSecret === 'string'\n ? {\n k: encodeBase64Url(stringToArrayBuffer(clientSecret)),\n kty: 'oct',\n alg: 'HS256',\n }\n : clientSecret;\n\n await jwtAssertionGenerator(\n issuer,\n clientId,\n cs,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n case method === 'private_key_jwt' &&\n typeof clientSecret === 'object' &&\n clientSecret.kty !== 'oct' &&\n !!issuer &&\n !!body: {\n await jwtAssertionGenerator(\n issuer,\n clientId,\n clientSecret,\n body,\n jwtAssertionSkew ?? 0\n );\n break;\n }\n\n default:\n throw new Error('Invalid Client Authentication Method');\n }\n};\n","import {\n decodeBase64Url,\n findToken,\n profileSync,\n getPublicSigKeyFromIssuerJwks,\n now,\n parseSpaceSeparated,\n stringToArrayBuffer,\n} from './utils/internal';\nimport { clientAuth, keyToSubtle } from './client-auth';\nimport {\n AccessToken,\n AuthenticateOptions,\n AuthorizationParams,\n ClientAuthMethod,\n EndSessionParameters,\n IdTokenClaims,\n IssuerMetadata,\n Jwk,\n Jwks,\n SecurityAlgorithms,\n JwsHeaderParameters,\n MonoCloudClientOptions,\n MonoCloudSession,\n MonoCloudUser,\n ParResponse,\n PushedAuthorizationParams,\n RefetchUserInfoOptions,\n RefreshGrantOptions,\n RefreshSessionOptions,\n Tokens,\n UserinfoResponse,\n} from './types';\nimport { MonoCloudOPError } from './errors/monocloud-op-error';\nimport { MonoCloudHttpError } from './errors/monocloud-http-error';\nimport { MonoCloudValidationError } from './errors/monocloud-validation-error';\nimport { MonoCloudTokenError } from './errors/monocloud-token-error';\nimport { MonoCloudAuthBaseError } from './errors/monocloud-auth-base-error';\n\nconst JWT_ASSERTION_CLOCK_SKEW = 5;\n\nconst FILTER_ID_TOKEN_CLAIMS = [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n];\n\nfunction assertMetadataProperty<K extends keyof IssuerMetadata>(\n metadata: IssuerMetadata,\n property: K\n): asserts metadata is IssuerMetadata & Required<Pick<IssuerMetadata, K>> {\n if (metadata[property] === undefined || metadata[property] === null) {\n throw new MonoCloudValidationError(\n `${property as string} endpoint is required but not available in the issuer metadata`\n );\n }\n}\n\nconst innerFetch = async (\n input: string,\n reqInit: RequestInit = {}\n): Promise<Response> => {\n try {\n return await fetch(input, reqInit);\n } catch (e) {\n /* v8 ignore next -- @preserve */\n throw new MonoCloudHttpError(\n (e as any).message ?? 'Unexpected Network Error'\n );\n }\n};\n\nconst deserializeJson = async <T = any>(res: Response): Promise<T> => {\n try {\n return await res.json();\n } catch (e) {\n throw new MonoCloudHttpError(\n /* v8 ignore next -- @preserve */\n `Failed to parse response body as JSON ${(e as any).message ? `: ${(e as any).message}` : ''}`\n );\n }\n};\n\n/**\n * @category Classes\n */\nexport class MonoCloudOidcClient {\n private readonly tenantDomain: string;\n\n private readonly clientId: string;\n\n private readonly clientSecret?: string | Jwk;\n\n private readonly authMethod: ClientAuthMethod;\n\n private readonly idTokenSigningAlgorithm: SecurityAlgorithms;\n\n private jwks?: Jwks;\n\n private jwksCacheExpiry = 0;\n\n private jwksCacheDuration = 300;\n\n private metadata?: IssuerMetadata;\n\n private metadataCacheExpiry = 0;\n\n private metadataCacheDuration = 300;\n\n constructor(\n tenantDomain: string,\n clientId: string,\n options?: MonoCloudClientOptions\n ) {\n // eslint-disable-next-line no-param-reassign\n tenantDomain ??= '';\n /* v8 ignore next -- @preserve */\n this.tenantDomain = `${!tenantDomain.startsWith('https://') ? 'https://' : ''}${tenantDomain.endsWith('/') ? tenantDomain.slice(0, -1) : tenantDomain}`;\n this.clientId = clientId;\n this.clientSecret = options?.clientSecret;\n this.authMethod = options?.clientAuthMethod ?? 'client_secret_basic';\n this.idTokenSigningAlgorithm = options?.idTokenSigningAlgorithm ?? 'RS256';\n\n if (options?.jwksCacheDuration) {\n this.jwksCacheDuration = options.jwksCacheDuration;\n }\n\n if (options?.metadataCacheDuration) {\n this.metadataCacheDuration = options.metadataCacheDuration;\n }\n }\n\n /**\n * Generates an authorization URL with specified parameters.\n *\n * If no values are provided for `responseType`, or `codeChallengeMethod`, they default to `code`, and `S256`, respectively.\n *\n * @param params - Authorization URL parameters.\n *\n * @returns Tenant's authorization URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authorizationUrl(params: AuthorizationParams): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n queryParams.set('redirect_uri', params.redirectUri);\n }\n\n if (params.requestUri) {\n queryParams.set('request_uri', params.requestUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n queryParams.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n queryParams.set('response_type', params.responseType);\n }\n\n if (\n (!params.responseType || params.responseType.length === 0) &&\n !params.requestUri\n ) {\n queryParams.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n queryParams.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n queryParams.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n queryParams.set('request', params.request);\n }\n\n if (params.responseMode) {\n queryParams.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n queryParams.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n queryParams.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n queryParams.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n queryParams.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n queryParams.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n queryParams.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n queryParams.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n queryParams.set('code_challenge', params.codeChallenge);\n queryParams.set(\n 'code_challenge_method',\n params.codeChallengeMethod ?? 'S256'\n );\n }\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'authorization_endpoint');\n\n return `${metadata.authorization_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Fetches the authorization server metadata from the .well-known endpoint.\n * The metadata is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh metadata from the server.\n *\n * @returns The issuer metadata for the tenant, retrieved from the OpenID Connect discovery endpoint.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getMetadata(forceRefresh = false): Promise<IssuerMetadata> {\n if (!forceRefresh && this.metadata && this.metadataCacheExpiry > now()) {\n return this.metadata;\n }\n\n this.metadata = undefined;\n\n const response = await innerFetch(\n `${this.tenantDomain}/.well-known/openid-configuration`\n );\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching metadata. Unexpected status code: ${response.status}`\n );\n }\n\n const metadata = await deserializeJson<IssuerMetadata>(response);\n\n this.metadata = metadata;\n this.metadataCacheExpiry = now() + this.metadataCacheDuration;\n\n return metadata;\n }\n\n /**\n * Fetches the JSON Web Keys used to sign the ID token.\n * The JWKS is cached for 1 minute.\n *\n * @param forceRefresh - If `true`, bypasses the cache and fetches fresh set of JWKS from the server.\n *\n * @returns The JSON Web Key Set containing the public keys for token verification.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async getJwks(forceRefresh = false): Promise<Jwks> {\n if (!forceRefresh && this.jwks && this.jwksCacheExpiry > now()) {\n return this.jwks;\n }\n\n this.jwks = undefined;\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'jwks_uri');\n\n const response = await innerFetch(metadata.jwks_uri);\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching JWKS. Unexpected status code: ${response.status}`\n );\n }\n const jwks = await deserializeJson<Jwks>(response);\n\n this.jwks = jwks;\n this.jwksCacheExpiry = now() + this.jwksCacheDuration;\n\n return jwks;\n }\n\n /**\n * Performs a pushed authorization request.\n *\n * @param params - Authorization Parameters.\n *\n * @returns Response from Pushed Authorization Request (PAR) endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the request is invalid.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async pushedAuthorizationRequest(\n params: PushedAuthorizationParams\n ): Promise<ParResponse> {\n const body = new URLSearchParams();\n\n body.set('client_id', this.clientId);\n\n if (params.redirectUri) {\n body.set('redirect_uri', params.redirectUri);\n }\n\n const scopes = parseSpaceSeparated(params.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n if (params.responseType && params.responseType.length > 0) {\n body.set('response_type', params.responseType);\n } else {\n body.set('response_type', 'code');\n }\n\n if (params.authenticatorHint) {\n body.set('authenticator_hint', params.authenticatorHint);\n }\n\n if (params.loginHint) {\n body.set('login_hint', params.loginHint);\n }\n\n if (params.request) {\n body.set('request', params.request);\n }\n\n if (params.responseMode) {\n body.set('response_mode', params.responseMode);\n }\n\n if (params.acrValues && params.acrValues.length > 0) {\n body.set('acr_values', params.acrValues.join(' '));\n }\n\n if (params.nonce) {\n body.set('nonce', params.nonce);\n }\n\n if (params.uiLocales) {\n body.set('ui_locales', params.uiLocales);\n }\n\n if (params.display) {\n body.set('display', params.display);\n }\n\n if (typeof params.maxAge === 'number') {\n body.set('max_age', params.maxAge.toString());\n }\n\n if (params.prompt) {\n body.set('prompt', params.prompt);\n }\n\n const resource = parseSpaceSeparated(params.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n if (params.codeChallenge) {\n body.set('code_challenge', params.codeChallenge);\n body.set('code_challenge_method', params.codeChallengeMethod ?? 'S256');\n }\n\n if (params.state) {\n body.set('state', params.state);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'pushed_authorization_request_endpoint');\n\n const response = await innerFetch(\n metadata.pushed_authorization_request_endpoint,\n {\n body: body.toString(),\n method: 'POST',\n headers,\n }\n );\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'par_request_failed',\n standardBodyError.error_description ??\n 'Pushed Authorization Request Failed'\n );\n }\n\n if (response.status !== 201) {\n throw new MonoCloudHttpError(\n `Error while performing pushed authorization request. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<ParResponse>(response);\n }\n\n /**\n * Fetches userinfo associated with the provided access token.\n *\n * @param accessToken - A valid access token used to retrieve userinfo.\n *\n * @returns The authenticated user's claims.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error (e.g., 'invalid_token') in the 'WWW-Authenticate' header\n * following a 401 Unauthorized response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n * @throws {@link MonoCloudValidationError} - When the access token is invalid.\n *\n */\n async userinfo(accessToken: string): Promise<UserinfoResponse> {\n if (!accessToken.trim().length) {\n throw new MonoCloudValidationError(\n 'Access token is required for fetching userinfo'\n );\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'userinfo_endpoint');\n\n const response = await innerFetch(metadata.userinfo_endpoint, {\n method: 'GET',\n headers: {\n authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (response.status === 401) {\n const authenticateError = response.headers.get('WWW-Authenticate');\n\n if (authenticateError) {\n const errorMatch = /error=\"([^\"]+)\"/.exec(authenticateError);\n const error = errorMatch ? errorMatch[1] : 'userinfo_failed';\n\n const errorDescMatch = /error_description=\"([^\"]+)\"/.exec(\n authenticateError\n );\n\n const errorDescription = errorDescMatch\n ? errorDescMatch[1]\n : 'Userinfo authentication error';\n\n throw new MonoCloudOPError(error, errorDescription);\n }\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while fetching userinfo. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<UserinfoResponse>(response);\n }\n\n /**\n * Generates OpenID end session URL for signing out.\n *\n * Note - The `state` is added only when `postLogoutRedirectUri` is present.\n *\n * @param params - Parameters to build end session URL.\n *\n * @returns Tenant's end session URL.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async endSessionUrl(params: EndSessionParameters): Promise<string> {\n const queryParams = new URLSearchParams();\n\n queryParams.set('client_id', this.clientId);\n\n if (params.idToken) {\n queryParams.set('id_token_hint', params.idToken);\n }\n\n if (params.postLogoutRedirectUri) {\n queryParams.set('post_logout_redirect_uri', params.postLogoutRedirectUri);\n\n if (params.state) {\n queryParams.set('state', params.state);\n }\n }\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'end_session_endpoint');\n\n return `${metadata.end_session_endpoint}?${queryParams.toString()}`;\n }\n\n /**\n * Exchanges an authorization code for tokens.\n *\n * @param code - The authorization code received from the authorization server.\n * @param redirectUri - The redirect URI used in the initial authorization request.\n * @param codeVerifier - Code verifier for PKCE.\n * @param resource - Space-separated list of resources the access token should be scoped to.\n *\n * @returns Tokens obtained by exchanging an authorization code at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async exchangeAuthorizationCode(\n code: string,\n redirectUri: string,\n codeVerifier?: string,\n resource?: string\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'authorization_code');\n body.set('code', code);\n body.set('redirect_uri', redirectUri);\n\n if (codeVerifier) {\n body.set('code_verifier', codeVerifier);\n }\n\n const resources = parseSpaceSeparated(resource) ?? [];\n\n if (resources.length > 0) {\n for (const r of resources) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'code_grant_failed',\n standardBodyError.error_description ?? 'Authorization code grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Exchanges a refresh token for new tokens.\n *\n * @param refreshToken - The refresh token used to request new tokens.\n * @param options - Refresh grant options.\n *\n * @returns Tokens obtained by exchanging a refresh token at the token endpoint.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshGrant(\n refreshToken: string,\n options?: RefreshGrantOptions\n ): Promise<Tokens> {\n const body = new URLSearchParams();\n\n body.set('grant_type', 'refresh_token');\n body.set('refresh_token', refreshToken);\n\n const scopes = parseSpaceSeparated(options?.scopes) ?? [];\n\n if (scopes.length > 0) {\n body.set('scope', scopes.join(' '));\n }\n\n const resource = parseSpaceSeparated(options?.resource) ?? [];\n\n if (resource.length > 0) {\n for (const r of resource) {\n body.append('resource', r);\n }\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'token_endpoint');\n\n const response = await innerFetch(metadata.token_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'refresh_grant_failed',\n standardBodyError.error_description ?? 'Refresh token grant failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing refresh token grant. Unexpected status code: ${response.status}`\n );\n }\n\n return await deserializeJson<Tokens>(response);\n }\n\n /**\n * Generates a session with user and tokens by exchanging authorization code from callback params.\n *\n * @param code - The authorization code received from the callback.\n * @param redirectUri - The redirect URI that was used in the authorization request.\n * @param requestedScopes - A space-separated list of scopes originally requested via the `/authorize` endpoint.\n * This is stored in the session to ensure the correct access token can be identified and refreshed during `refreshSession()`.\n * @param resource - A space-separated list of resource indicators originally requested via the `/authorize` endpoint.\n * Used alongside scopes to uniquely identify and refresh the specific access token associated with these resources.\n * @param options - Options for authenticating a user with authorization code.\n *\n * @returns The user's session containing authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain the openid scope,\n * or if 'expires_in' or 'scope' is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized.\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async authenticate(\n code: string,\n redirectUri: string,\n requestedScopes: string,\n resource?: string,\n options?: AuthenticateOptions\n ): Promise<MonoCloudSession> {\n const tokens = await this.exchangeAuthorizationCode(\n code,\n redirectUri,\n options?.codeVerifier,\n resource\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0,\n options?.idTokenMaxAge,\n options?.idTokenNonce\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const session: MonoCloudSession = {\n user: profileSync(undefined, idTokenClaims, userinfo, true),\n idToken: tokens.id_token,\n refreshToken: tokens.refresh_token,\n authorizedScopes: requestedScopes,\n accessTokens: [\n {\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes,\n },\n ],\n };\n\n await options?.onSessionCreating?.(session, idTokenClaims, userinfo);\n\n return session;\n }\n\n /**\n * Refetches user information for an existing session using the userinfo endpoint.\n * Updates the session's user object with the latest user information.\n *\n * @param accessToken - Access token used to fetch the userinfo.\n * @param session - The current MonoCloudSession.\n * @param options - Userinfo refetch options.\n *\n * @returns Updated session with the latest userinfo.\n *\n * @throws {@link MonoCloudValidationError} - When the token scope does not contain openid scope\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refetchUserInfo(\n accessToken: AccessToken,\n session: MonoCloudSession,\n options?: RefetchUserInfoOptions\n ): Promise<MonoCloudSession> {\n if (!accessToken.scopes?.includes('openid')) {\n throw new MonoCloudValidationError(\n 'Fetching userinfo requires the openid scope'\n );\n }\n\n const userinfo = await this.userinfo(accessToken.accessToken);\n\n const idTokenClaims =\n session.idToken && options?.strictProfileSync\n ? MonoCloudOidcClient.decodeJwt(session.idToken)\n : undefined;\n\n // eslint-disable-next-line no-param-reassign\n session.user = profileSync(\n session.user,\n idTokenClaims,\n userinfo,\n options?.strictProfileSync\n );\n\n await options?.onSessionCreating?.(session, undefined, userinfo);\n\n return session;\n }\n\n /**\n * Refreshes an existing session using the refresh token.\n * This function requests new tokens using the refresh token and optionally updates user information.\n *\n * @param session - The current MonoCloudSession containing the refresh token.\n * @param options - Session refresh options.\n *\n * @returns User's session containing refreshed authentication tokens and user information.\n *\n * @throws {@link MonoCloudValidationError} - If the refresh token is not present in the session,\n * or if 'expires_in' or 'scope' (including the openid scope) is missing from the token response.\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n *\n */\n async refreshSession(\n session: MonoCloudSession,\n options?: RefreshSessionOptions\n ): Promise<MonoCloudSession> {\n if (!session.refreshToken) {\n throw new MonoCloudValidationError(\n 'Session does not contain refresh token'\n );\n }\n\n const tokens = await this.refreshGrant(\n session.refreshToken,\n options?.refreshGrantOptions\n );\n\n const accessTokenExpiration =\n typeof tokens.expires_in === 'number'\n ? now() + tokens.expires_in\n : undefined;\n\n if (!accessTokenExpiration) {\n throw new MonoCloudValidationError(\"Missing required 'expires_in' field\");\n }\n\n if (!tokens.scope) {\n throw new MonoCloudValidationError(\"Missing or invalid 'scope' field\");\n }\n\n let userinfo: MonoCloudUser | undefined;\n\n if (options?.fetchUserInfo && tokens.scope?.includes('openid')) {\n userinfo = await this.userinfo(tokens.access_token);\n }\n\n let idTokenClaims: Partial<IdTokenClaims> = {};\n\n if (tokens.id_token) {\n if (options?.validateIdToken ?? true) {\n const jwks = options?.jwks ?? (await this.getJwks());\n\n idTokenClaims = await this.validateIdToken(\n tokens.id_token,\n jwks.keys,\n options?.idTokenClockSkew ?? 0,\n options?.idTokenClockTolerance ?? 0\n );\n } else {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(tokens.id_token);\n }\n } else if (session.idToken) {\n idTokenClaims = MonoCloudOidcClient.decodeJwt(session.idToken);\n }\n\n (options?.filteredIdTokenClaims ?? FILTER_ID_TOKEN_CLAIMS).forEach(x => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete idTokenClaims[x];\n });\n\n const resource = options?.refreshGrantOptions?.resource;\n let scopes = options?.refreshGrantOptions?.scopes;\n\n if (!resource && !scopes) {\n scopes = session.authorizedScopes;\n }\n\n const accessToken = findToken(session.accessTokens, resource, scopes);\n\n const user = profileSync(\n session.user,\n idTokenClaims,\n userinfo,\n options?.strictProfileSync\n );\n\n const newTokens =\n session.accessTokens?.filter(t => t !== accessToken) ?? [];\n\n newTokens.push({\n scopes: tokens.scope,\n accessToken: tokens.access_token,\n accessTokenExpiration,\n resource,\n requestedScopes: scopes,\n });\n\n const updatedSession: MonoCloudSession = {\n ...session,\n user,\n idToken: tokens.id_token ?? session.idToken,\n refreshToken: tokens.refresh_token ?? session.refreshToken,\n accessTokens: newTokens,\n };\n\n await options?.onSessionCreating?.(updatedSession, idTokenClaims, userinfo);\n\n return updatedSession;\n }\n\n /**\n * Revokes an access token or refresh token, rendering it invalid for future use.\n *\n * @param token - The token string to be revoked.\n * @param tokenType - Hint about the token type ('access_token' or 'refresh_token').\n *\n * @returns If token revocation succeeded.\n *\n * @throws {@link MonoCloudValidationError} - If token is invalid or unsupported token type\n *\n * @throws {@link MonoCloudOPError} - When the OpenID Provider returns a standardized\n * OAuth 2.0 error response.\n *\n * @throws {@link MonoCloudHttpError} - Thrown if there is a network error during the request or\n * unexpected status code during the request or a serialization error while processing the response.\n */\n async revokeToken(token: string, tokenType?: string): Promise<void> {\n if (!token.trim().length) {\n throw new MonoCloudValidationError('Invalid token');\n }\n\n if (\n tokenType &&\n tokenType !== 'access_token' &&\n tokenType !== 'refresh_token'\n ) {\n throw new MonoCloudValidationError(\n 'Only access_token and refresh_token types are supported.'\n );\n }\n\n const body = new URLSearchParams();\n body.set('token', token);\n if (tokenType) {\n body.set('token_type_hint', tokenType);\n }\n\n const headers = {\n 'content-type': 'application/x-www-form-urlencoded',\n };\n\n await clientAuth(\n this.clientId,\n this.clientSecret,\n this.authMethod,\n this.tenantDomain,\n headers,\n body,\n JWT_ASSERTION_CLOCK_SKEW\n );\n\n const metadata = await this.getMetadata();\n\n assertMetadataProperty(metadata, 'revocation_endpoint');\n\n const response = await innerFetch(metadata.revocation_endpoint, {\n method: 'POST',\n body: body.toString(),\n headers,\n });\n\n if (response.status === 400) {\n const standardBodyError = await deserializeJson(response);\n\n throw new MonoCloudOPError(\n standardBodyError.error ?? 'revocation_failed',\n standardBodyError.error_description ?? 'Token revocation failed'\n );\n }\n\n if (response.status !== 200) {\n throw new MonoCloudHttpError(\n `Error while performing revocation request. Unexpected status code: ${response.status}`\n );\n }\n }\n\n /**\n * Validates an ID Token.\n *\n * @param idToken - The ID Token JWT string to validate.\n * @param jwks - Array of JSON Web Keys (JWK) used to verify the token's signature.\n * @param clockSkew - Number of seconds to adjust the current time to account for clock differences.\n * @param clockTolerance - Additional time tolerance in seconds for time-based claim validation.\n * @param maxAge - Maximum authentication age in seconds.\n * @param nonce - Nonce value to validate against the token's nonce claim.\n *\n * @returns Validated ID Token claims.\n *\n * @throws {@link MonoCloudTokenError} - If ID Token validation fails\n *\n */\n async validateIdToken(\n idToken: string,\n jwks: Jwk[],\n clockSkew: number,\n clockTolerance: number,\n maxAge?: number,\n nonce?: string\n ): Promise<IdTokenClaims> {\n if (typeof idToken !== 'string' || idToken.trim().length === 0) {\n throw new MonoCloudTokenError(\n 'ID Token must be a valid non-empty string'\n );\n }\n\n const {\n 0: protectedHeader,\n 1: payload,\n 2: encodedSignature,\n length,\n } = idToken.split('.');\n\n if (length !== 3) {\n throw new MonoCloudTokenError(\n 'ID Token must have a header, payload and signature'\n );\n }\n\n let header: JwsHeaderParameters;\n try {\n header = JSON.parse(decodeBase64Url(protectedHeader));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Header');\n }\n\n if (\n header === null ||\n typeof header !== 'object' ||\n Array.isArray(header)\n ) {\n throw new MonoCloudTokenError('JWT Header must be a top level object');\n }\n\n if (this.idTokenSigningAlgorithm !== header.alg) {\n throw new MonoCloudTokenError('Invalid signing alg');\n }\n\n if (header.crit !== undefined) {\n throw new MonoCloudTokenError('Unexpected JWT \"crit\" header parameter');\n }\n\n const binary = decodeBase64Url(encodedSignature);\n\n const signature = new Uint8Array(binary.length);\n\n for (let i = 0; i < binary.length; i++) {\n signature[i] = binary.charCodeAt(i);\n }\n\n const key = await getPublicSigKeyFromIssuerJwks(jwks, header);\n\n const input = `${protectedHeader}.${payload}`;\n\n const verified = await crypto.subtle.verify(\n keyToSubtle(key),\n key,\n signature,\n stringToArrayBuffer(input) as BufferSource\n );\n\n if (!verified) {\n throw new MonoCloudTokenError('JWT signature verification failed');\n }\n\n let claims: IdTokenClaims;\n\n try {\n claims = JSON.parse(decodeBase64Url(payload));\n } catch {\n throw new MonoCloudTokenError('Failed to parse JWT Payload');\n }\n\n if (\n claims === null ||\n typeof claims !== 'object' ||\n Array.isArray(claims)\n ) {\n throw new MonoCloudTokenError('JWT Payload must be a top level object');\n }\n\n if ((claims.nonce || nonce) && claims.nonce !== nonce) {\n throw new MonoCloudTokenError('Nonce mismatch');\n }\n\n const current = now() + clockSkew;\n\n /* v8 ignore else -- @preserve */\n if (claims.exp !== undefined) {\n if (typeof claims.exp !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim type'\n );\n }\n\n if (claims.exp <= current - clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"exp\" (expiration time) claim value, timestamp is <= now()'\n );\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (claims.iat !== undefined) {\n if (typeof claims.iat !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"iat\" (issued at) claim type'\n );\n }\n }\n\n if (\n typeof claims.auth_time === 'number' &&\n typeof maxAge === 'number' &&\n claims.auth_time + maxAge < current\n ) {\n throw new MonoCloudTokenError(\n 'Too much time has elapsed since the last End-User authentication'\n );\n }\n\n if (claims.iss !== this.tenantDomain) {\n throw new MonoCloudTokenError('Invalid Issuer');\n }\n\n if (claims.nbf !== undefined) {\n if (typeof claims.nbf !== 'number') {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim type'\n );\n }\n\n if (claims.nbf > current + clockTolerance) {\n throw new MonoCloudTokenError(\n 'Unexpected JWT \"nbf\" (not before) claim value, timestamp is > now()'\n );\n }\n }\n\n const audience = Array.isArray(claims.aud) ? claims.aud : [claims.aud];\n\n if (!audience.includes(this.clientId)) {\n throw new MonoCloudTokenError('Invalid audience claim');\n }\n\n return claims;\n }\n\n /**\n * Decodes the payload of a JSON Web Token (JWT) and returns it as an object.\n *\n * >Note: THIS METHOD DOES NOT VERIFY JWT TOKENS.\n *\n * @param jwt - JWT to decode.\n *\n * @returns Decoded payload.\n *\n * @throws {@link MonoCloudTokenError} - If decoding fails\n *\n */\n static decodeJwt(jwt: string): IdTokenClaims {\n try {\n const [, payload] = jwt.split('.');\n\n if (!payload?.trim()) {\n throw new MonoCloudTokenError('JWT does not contain payload');\n }\n\n const decoded = decodeBase64Url(payload);\n\n if (!decoded.startsWith('{')) {\n throw new MonoCloudTokenError('Payload is not an object');\n }\n\n return JSON.parse(decoded) as IdTokenClaims;\n } catch (e) {\n if (e instanceof MonoCloudAuthBaseError) {\n throw e;\n }\n\n throw new MonoCloudTokenError(\n 'Could not parse payload. Malformed payload'\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
type ResponseTypes =
|
|
12
12
|
/**
|
|
13
|
-
* Authorization Code Flow (recommended). Returns an authorization code that is exchanged for tokens server-side.
|
|
13
|
+
* Authorization Code Flow (recommended). Returns an authorization code that is exchanged for tokens on the server-side.
|
|
14
14
|
*/
|
|
15
15
|
'code'
|
|
16
16
|
/**
|
|
@@ -512,7 +512,7 @@ type Group =
|
|
|
512
512
|
* Structured group representation.
|
|
513
513
|
*/
|
|
514
514
|
{
|
|
515
|
-
id: string;
|
|
515
|
+
/** Group identifier. */id: string; /** Group name. */
|
|
516
516
|
name: string;
|
|
517
517
|
}
|
|
518
518
|
/**
|
|
@@ -1112,6 +1112,13 @@ interface RefreshSessionOptions {
|
|
|
1112
1112
|
* List of ID token claims to remove before storing the session.
|
|
1113
1113
|
*/
|
|
1114
1114
|
filteredIdTokenClaims?: string[];
|
|
1115
|
+
/**
|
|
1116
|
+
* When enabled, replaces the existing session user profile with a freshly constructed profile
|
|
1117
|
+
* derived from the latest ID token and/or UserInfo response.
|
|
1118
|
+
*
|
|
1119
|
+
* @defaultValue false
|
|
1120
|
+
*/
|
|
1121
|
+
strictProfileSync?: boolean;
|
|
1115
1122
|
/**
|
|
1116
1123
|
* Callback invoked before a session is created or updated. Allows customization or enrichment of the session.
|
|
1117
1124
|
*/
|
|
@@ -1123,6 +1130,13 @@ interface RefreshSessionOptions {
|
|
|
1123
1130
|
* @category Types
|
|
1124
1131
|
*/
|
|
1125
1132
|
interface RefetchUserInfoOptions {
|
|
1133
|
+
/**
|
|
1134
|
+
* When enabled, replaces the existing session user profile with a new profile
|
|
1135
|
+
* constructed from the latest UserInfo response.
|
|
1136
|
+
*
|
|
1137
|
+
* @defaultValue false
|
|
1138
|
+
*/
|
|
1139
|
+
strictProfileSync?: boolean;
|
|
1126
1140
|
/**
|
|
1127
1141
|
* Callback invoked before a session is created or updated. Allows customization or enrichment of the session.
|
|
1128
1142
|
*/
|
|
@@ -1240,4 +1254,4 @@ idToken?: Partial<IdTokenClaims>,
|
|
|
1240
1254
|
userInfo?: UserinfoResponse) => Promise<void> | void;
|
|
1241
1255
|
//#endregion
|
|
1242
1256
|
export { SecurityAlgorithms as A, Prompt as C, RefreshSessionOptions as D, RefreshGrantOptions as E, UserinfoResponse as M, ResponseModes as O, ParResponse as S, RefetchUserInfoOptions as T, JwsHeaderParameters as _, Authenticators as a, MonoCloudUser as b, ClientAuthMethod as c, EndSessionParameters as d, Group as f, Jwks as g, Jwk as h, AuthenticateOptions as i, Tokens as j, ResponseTypes as k, CodeChallengeMethod as l, IssuerMetadata as m, Address as n, AuthorizationParams as o, IdTokenClaims as p, AuthState as r, CallbackParams as s, AccessToken as t, DisplayOptions as u, MonoCloudClientOptions as v, PushedAuthorizationParams as w, OnSessionCreating as x, MonoCloudSession as y };
|
|
1243
|
-
//# sourceMappingURL=types-
|
|
1257
|
+
//# sourceMappingURL=types-DmlJMcTH.d.mts.map
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as MonoCloudUser, p as IdTokenClaims, r as AuthState, s as CallbackParams, y as MonoCloudSession } from "../types-
|
|
1
|
+
import { b as MonoCloudUser, p as IdTokenClaims, r as AuthState, s as CallbackParams, y as MonoCloudSession } from "../types-DmlJMcTH.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utils/index.d.ts
|
|
4
4
|
/**
|
package/dist/utils/internal.cjs
CHANGED
|
@@ -339,6 +339,31 @@ const findToken = (tokens, resource, scopes) => {
|
|
|
339
339
|
const desiredScopes = parseSpaceSeparatedSet(scopes);
|
|
340
340
|
return tokens.find((t) => setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) && setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes)));
|
|
341
341
|
};
|
|
342
|
+
/**
|
|
343
|
+
* @ignore
|
|
344
|
+
* Builds the session user claims from existing claims and newly fetched claims.
|
|
345
|
+
*
|
|
346
|
+
* @param existingUser - Existing session user claims.
|
|
347
|
+
* @param idTokenClaims - Claims extracted from ID token.
|
|
348
|
+
* @param userinfoClaims - Claims fetched from UserInfo endpoint.
|
|
349
|
+
* @param strict - If `true`, creates claims from new inputs only (falls back to existing when none). If `false`, merges into existing claims.
|
|
350
|
+
*
|
|
351
|
+
* @returns Updated user claims for the session.
|
|
352
|
+
*/
|
|
353
|
+
const profileSync = (existingUser, idTokenClaims, userinfoClaims, strict = false) => {
|
|
354
|
+
const hasIdTokenClaims = !!idTokenClaims && Object.keys(idTokenClaims).length > 0;
|
|
355
|
+
const hasUserinfoClaims = !!userinfoClaims && Object.keys(userinfoClaims).length > 0;
|
|
356
|
+
if (!hasIdTokenClaims && !hasUserinfoClaims) return existingUser ?? {};
|
|
357
|
+
if (strict) return {
|
|
358
|
+
...idTokenClaims ?? {},
|
|
359
|
+
...userinfoClaims ?? {}
|
|
360
|
+
};
|
|
361
|
+
return {
|
|
362
|
+
...existingUser ?? {},
|
|
363
|
+
...idTokenClaims ?? {},
|
|
364
|
+
...userinfoClaims ?? {}
|
|
365
|
+
};
|
|
366
|
+
};
|
|
342
367
|
|
|
343
368
|
//#endregion
|
|
344
369
|
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
@@ -358,6 +383,7 @@ exports.isSameHost = isSameHost;
|
|
|
358
383
|
exports.now = now;
|
|
359
384
|
exports.parseSpaceSeparated = parseSpaceSeparated;
|
|
360
385
|
exports.parseSpaceSeparatedSet = parseSpaceSeparatedSet;
|
|
386
|
+
exports.profileSync = profileSync;
|
|
361
387
|
exports.randomBytes = randomBytes;
|
|
362
388
|
exports.removeTrailingSlash = removeTrailingSlash;
|
|
363
389
|
exports.setsEqual = setsEqual;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.cjs","names":[],"sources":["../../src/utils/internal.ts"],"sourcesContent":["import type {\n AccessToken,\n Jwk,\n SecurityAlgorithms,\n JwsHeaderParameters,\n} from '../types';\n\n/**\n * @ignore\n * Converts a string to a Base64URL encoded string.\n *\n * @param input - The string to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const toB64Url = (input: string): string =>\n input.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\n/**\n * @ignore\n * Parses a string value into a boolean.\n *\n * @param value - The string value to parse.\n *\n * @returns `true` if \"true\", `false` if \"false\", otherwise `undefined`.\n */\nexport const getBoolean = (value?: string): boolean | undefined => {\n const v = value?.toLowerCase()?.trim();\n\n if (v === 'true') {\n return true;\n }\n\n if (v === 'false') {\n return false;\n }\n\n return undefined;\n};\n\n/**\n * @ignore\n * Parses a string value into a number.\n *\n * @param value - The string value to parse.\n *\n * @returns The parsed number, or `undefined` if empty or invalid.\n */\nexport const getNumber = (value?: string): number | undefined => {\n const v = value?.trim();\n\n if (v === undefined || v.length === 0) {\n return undefined;\n }\n\n const p = parseInt(v, 10);\n\n return Number.isNaN(p) ? undefined : p;\n};\n\n/**\n * @ignore\n * Ensures that a string has a leading forward slash.\n *\n * @param val - The string to check.\n *\n * @returns The string with a leading slash.\n */\nexport const ensureLeadingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.startsWith('/') ? v : `/${v}`;\n};\n\n/**\n * @ignore\n * Removes a trailing forward slash from a string.\n *\n * @param val - The string to check.\n *\n * @returns The string without a trailing slash.\n */\nexport const removeTrailingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.endsWith('/') ? v.substring(0, v.length - 1) : v;\n};\n\n/**\n * @ignore\n * Checks if a value is present (not null, undefined, or an empty string).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is present, `false` otherwise.\n */\nexport const isPresent = (value?: string | number | boolean): boolean => {\n if (typeof value === 'boolean' || typeof value === 'number') {\n return true;\n }\n const v = value?.trim();\n return v !== undefined && v !== null && v.length > 0;\n};\n\n/**\n * @ignore\n * Checks if a URL is an absolute URL (starts with http:// or https://).\n *\n * @param url - The URL to check.\n *\n * @returns `true` if absolute, `false` otherwise.\n */\nexport const isAbsoluteUrl = (url: string): boolean =>\n (url?.startsWith('http://') || url?.startsWith('https://')) ?? false;\n\n/**\n * @ignore\n * Checks if two URLs have the same origin (host and port).\n *\n * @param url - The first URL.\n * @param urlToCheck - The second URL to compare against.\n *\n * @returns `true` if they share the same origin, `false` otherwise.\n */\nexport const isSameHost = (url: string, urlToCheck: string): boolean => {\n try {\n const u = new URL(url);\n const u2 = new URL(urlToCheck);\n\n return u.origin === u2.origin;\n } catch {\n return false;\n }\n};\n\n/**\n * @ignore\n * Converts a string to a Uint8Array using TextEncoder.\n *\n * @param str - The string to convert.\n *\n * @returns A Uint8Array representation of the string.\n */\nexport const stringToArrayBuffer = (str: string): Uint8Array => {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n};\n\n/**\n * @ignore\n * Converts an ArrayBuffer to a string using TextDecoder.\n *\n * @param buffer - The buffer to convert.\n *\n * @returns The decoded string.\n */\nexport const arrayBufferToString = (buffer: ArrayBuffer): string => {\n const decoder = new TextDecoder();\n return decoder.decode(buffer);\n};\n\n/**\n * @ignore\n * Converts a Base64URL string back to a standard Base64 string with padding.\n *\n * @param input - The Base64URL string.\n *\n * @returns A standard Base64 string.\n */\nexport const fromB64Url = (input: string): string => {\n let str = input;\n if (str.length % 4 !== 0) {\n str += '==='.slice(0, 4 - (str.length % 4));\n }\n\n str = str.replace(/-/g, '+').replace(/_/g, '/');\n\n return str;\n};\n\n/**\n * @ignore\n * Decodes a Base64URL encoded string.\n *\n * @param input - The Base64URL string to decode.\n *\n * @returns The decoded plaintext string.\n */\nexport const decodeBase64Url = (input: string): string =>\n atob(fromB64Url(input).replace(/\\s/g, ''));\n\n/**\n * @ignore\n * Converts a Uint8Array to a Base64URL encoded string.\n *\n * @param buffer - The buffer to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const arrayBufferToBase64 = (buffer: Uint8Array): string => {\n const bytes = new Uint8Array(buffer);\n const binary = bytes.reduce(\n (acc, byte) => acc + String.fromCharCode(byte),\n ''\n );\n return btoa(binary).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Gets the current Unix timestamp in seconds.\n *\n * @returns The current timestamp.\n */\nexport const now = (): number => Math.ceil(Date.now() / 1000);\n\nconst SUPPORTED_JWS_ALGS: SecurityAlgorithms[] = [\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512',\n];\n\n/**\n * Retrieves a public CryptoKey from a JWK set based on the JWS header.\n *\n * @param jwks - The set of JSON Web Keys.\n * @param header - The JWS header containing the algorithm and key ID.\n *\n * @returns A promise that resolves to the CryptoKey.\n *\n * @throws If no applicable key or multiple keys are found or the algorithm is unsupported.\n */\nexport const getPublicSigKeyFromIssuerJwks = async (\n jwks: Jwk[],\n header: JwsHeaderParameters\n): Promise<CryptoKey> => {\n const { alg, kid } = header;\n\n if (!SUPPORTED_JWS_ALGS.includes(alg)) {\n throw new Error('unsupported JWS \"alg\" identifier');\n }\n\n let kty: string;\n switch (alg.slice(0, 2)) {\n case 'RS': // Fall through\n case 'PS':\n kty = 'RSA';\n break;\n case 'ES':\n kty = 'EC';\n break;\n }\n\n const candidates = jwks.filter(jwk => {\n // filter keys based on the mapping of signature algorithms to Key Type\n if (jwk.kty !== kty) {\n return false;\n }\n\n // filter keys based on the JWK Key ID in the header\n if (kid !== undefined && kid !== jwk.kid) {\n return false;\n }\n\n // filter keys based on the key's declared Algorithm\n if (jwk.alg !== undefined && alg !== jwk.alg) {\n return false;\n }\n\n // filter keys based on the key's declared Public Key Use\n if (jwk.use !== undefined && jwk.use !== 'sig') {\n return false;\n }\n\n // filter keys based on the key's declared Key Operations\n if (jwk.key_ops?.includes('verify') === false) {\n return false;\n }\n\n // filter keys based on alg-specific key requirements\n switch (true) {\n case alg === 'ES256' && jwk.crv !== 'P-256': // Fall through\n case alg === 'ES384' && jwk.crv !== 'P-384': // Fall through\n case alg === 'ES512' && jwk.crv !== 'P-521': // Fall through\n return false;\n }\n\n return true;\n });\n\n const { 0: jwk, length } = candidates;\n\n if (length !== 1) {\n throw new Error(\n 'error when selecting a JWT verification key, multiple applicable keys found, a \"kid\" JWT Header Parameter is required'\n );\n }\n\n let algorithm:\n | RsaHashedImportParams\n | EcKeyImportParams\n | AlgorithmIdentifier;\n\n switch (alg) {\n case 'PS256': // Fall through\n case 'PS384': // Fall through\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'RS256': // Fall through\n case 'RS384': // Fall through\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'ES256': // Fall through\n case 'ES384':\n algorithm = { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n break;\n case 'ES512':\n algorithm = { name: 'ECDSA', namedCurve: 'P-521' };\n break;\n }\n\n const { ext, key_ops, use, ...k } = jwk;\n\n const key = await crypto.subtle.importKey('jwk', k, algorithm, true, [\n 'verify',\n ]);\n\n if (key.type !== 'public') {\n throw new Error('jwks_uri must only contain public keys');\n }\n\n return key;\n};\n\nconst CHUNK_SIZE = 0x8000;\n\n/**\n * @ignore\n * Encodes a Uint8Array or ArrayBuffer into a Base64URL string using chunked processing.\n *\n * @param input - The data to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const encodeBase64Url = (input: Uint8Array | ArrayBuffer): string => {\n if (input instanceof ArrayBuffer) {\n // eslint-disable-next-line no-param-reassign\n input = new Uint8Array(input);\n }\n\n const arr = [];\n for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {\n arr.push(\n String.fromCharCode.apply(\n null,\n Array.from(new Uint8Array(input.slice(i, i + CHUNK_SIZE)))\n )\n );\n }\n return btoa(arr.join(''))\n .replace(/=/g, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Generates a random Base64URL encoded string.\n *\n * @param length - The number of random bytes to generate.\n *\n * @returns A random Base64URL string.\n */\nexport const randomBytes = (length = 32): string =>\n encodeBase64Url(crypto.getRandomValues(new Uint8Array(length)));\n\n/**\n * @ignore\n * Checks if a value is a non-null, non-array JSON object.\n *\n * @param input - The value to check.\n *\n * @returns `true` if the value is a JSON object.\n */\nexport const isJsonObject = <T>(input: unknown): input is T => {\n if (input === null || typeof input !== 'object' || Array.isArray(input)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * @ignore\n * Parses a space-separated string into an array of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns An array of strings, or `undefined` if input is empty.\n */\nexport const parseSpaceSeparated = (s?: string): string[] | undefined =>\n s\n ?.split(/\\s+/)\n .map(x => x.trim())\n .filter(Boolean);\n\n/**\n * @ignore\n * Parses a space-separated string into a Set of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns A Set containing the unique strings.\n */\nexport const parseSpaceSeparatedSet = (s?: string): Set<string> => {\n if (!s) {\n return new Set();\n }\n\n return new Set(parseSpaceSeparated(s));\n};\n\n/**\n * @ignore\n * Compares two Sets for equality.\n *\n * @param a - The first Set.\n * @param b - The second Set.\n * @param strict - If `true`, requires both sets to be the same size. Defaults to `true`.\n *\n * @returns `true` if the sets are equal.\n */\nexport const setsEqual = (\n a: Set<string>,\n b: Set<string>,\n strict = true\n): boolean => {\n if (strict && a.size !== b.size) {\n return false;\n }\n\n for (const v of a) {\n if (!b.has(v)) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Finds a specific access token in an array based on resource and scopes.\n *\n * @param tokens - The array of access tokens.\n * @param resource - Space-separated resource indicators.\n * @param scopes - Space-separated scopes.\n *\n * @returns The matching AccessToken, or `undefined` if not found.\n */\nexport const findToken = (\n tokens?: AccessToken[],\n resource?: string,\n scopes?: string\n): AccessToken | undefined => {\n if (!Array.isArray(tokens) || tokens.length === 0) {\n return undefined;\n }\n\n const desiredResource = parseSpaceSeparatedSet(resource);\n const desiredScopes = parseSpaceSeparatedSet(scopes);\n\n return tokens.find(\n t =>\n setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) &&\n setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes))\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal.cjs","names":[],"sources":["../../src/utils/internal.ts"],"sourcesContent":["import type {\n AccessToken,\n IdTokenClaims,\n Jwk,\n MonoCloudUser,\n SecurityAlgorithms,\n JwsHeaderParameters,\n} from '../types';\n\n/**\n * @ignore\n * Converts a string to a Base64URL encoded string.\n *\n * @param input - The string to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const toB64Url = (input: string): string =>\n input.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\n/**\n * @ignore\n * Parses a string value into a boolean.\n *\n * @param value - The string value to parse.\n *\n * @returns `true` if \"true\", `false` if \"false\", otherwise `undefined`.\n */\nexport const getBoolean = (value?: string): boolean | undefined => {\n const v = value?.toLowerCase()?.trim();\n\n if (v === 'true') {\n return true;\n }\n\n if (v === 'false') {\n return false;\n }\n\n return undefined;\n};\n\n/**\n * @ignore\n * Parses a string value into a number.\n *\n * @param value - The string value to parse.\n *\n * @returns The parsed number, or `undefined` if empty or invalid.\n */\nexport const getNumber = (value?: string): number | undefined => {\n const v = value?.trim();\n\n if (v === undefined || v.length === 0) {\n return undefined;\n }\n\n const p = parseInt(v, 10);\n\n return Number.isNaN(p) ? undefined : p;\n};\n\n/**\n * @ignore\n * Ensures that a string has a leading forward slash.\n *\n * @param val - The string to check.\n *\n * @returns The string with a leading slash.\n */\nexport const ensureLeadingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.startsWith('/') ? v : `/${v}`;\n};\n\n/**\n * @ignore\n * Removes a trailing forward slash from a string.\n *\n * @param val - The string to check.\n *\n * @returns The string without a trailing slash.\n */\nexport const removeTrailingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.endsWith('/') ? v.substring(0, v.length - 1) : v;\n};\n\n/**\n * @ignore\n * Checks if a value is present (not null, undefined, or an empty string).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is present, `false` otherwise.\n */\nexport const isPresent = (value?: string | number | boolean): boolean => {\n if (typeof value === 'boolean' || typeof value === 'number') {\n return true;\n }\n const v = value?.trim();\n return v !== undefined && v !== null && v.length > 0;\n};\n\n/**\n * @ignore\n * Checks if a URL is an absolute URL (starts with http:// or https://).\n *\n * @param url - The URL to check.\n *\n * @returns `true` if absolute, `false` otherwise.\n */\nexport const isAbsoluteUrl = (url: string): boolean =>\n (url?.startsWith('http://') || url?.startsWith('https://')) ?? false;\n\n/**\n * @ignore\n * Checks if two URLs have the same origin (host and port).\n *\n * @param url - The first URL.\n * @param urlToCheck - The second URL to compare against.\n *\n * @returns `true` if they share the same origin, `false` otherwise.\n */\nexport const isSameHost = (url: string, urlToCheck: string): boolean => {\n try {\n const u = new URL(url);\n const u2 = new URL(urlToCheck);\n\n return u.origin === u2.origin;\n } catch {\n return false;\n }\n};\n\n/**\n * @ignore\n * Converts a string to a Uint8Array using TextEncoder.\n *\n * @param str - The string to convert.\n *\n * @returns A Uint8Array representation of the string.\n */\nexport const stringToArrayBuffer = (str: string): Uint8Array => {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n};\n\n/**\n * @ignore\n * Converts an ArrayBuffer to a string using TextDecoder.\n *\n * @param buffer - The buffer to convert.\n *\n * @returns The decoded string.\n */\nexport const arrayBufferToString = (buffer: ArrayBuffer): string => {\n const decoder = new TextDecoder();\n return decoder.decode(buffer);\n};\n\n/**\n * @ignore\n * Converts a Base64URL string back to a standard Base64 string with padding.\n *\n * @param input - The Base64URL string.\n *\n * @returns A standard Base64 string.\n */\nexport const fromB64Url = (input: string): string => {\n let str = input;\n if (str.length % 4 !== 0) {\n str += '==='.slice(0, 4 - (str.length % 4));\n }\n\n str = str.replace(/-/g, '+').replace(/_/g, '/');\n\n return str;\n};\n\n/**\n * @ignore\n * Decodes a Base64URL encoded string.\n *\n * @param input - The Base64URL string to decode.\n *\n * @returns The decoded plaintext string.\n */\nexport const decodeBase64Url = (input: string): string =>\n atob(fromB64Url(input).replace(/\\s/g, ''));\n\n/**\n * @ignore\n * Converts a Uint8Array to a Base64URL encoded string.\n *\n * @param buffer - The buffer to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const arrayBufferToBase64 = (buffer: Uint8Array): string => {\n const bytes = new Uint8Array(buffer);\n const binary = bytes.reduce(\n (acc, byte) => acc + String.fromCharCode(byte),\n ''\n );\n return btoa(binary).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Gets the current Unix timestamp in seconds.\n *\n * @returns The current timestamp.\n */\nexport const now = (): number => Math.ceil(Date.now() / 1000);\n\nconst SUPPORTED_JWS_ALGS: SecurityAlgorithms[] = [\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512',\n];\n\n/**\n * Retrieves a public CryptoKey from a JWK set based on the JWS header.\n *\n * @param jwks - The set of JSON Web Keys.\n * @param header - The JWS header containing the algorithm and key ID.\n *\n * @returns A promise that resolves to the CryptoKey.\n *\n * @throws If no applicable key or multiple keys are found or the algorithm is unsupported.\n */\nexport const getPublicSigKeyFromIssuerJwks = async (\n jwks: Jwk[],\n header: JwsHeaderParameters\n): Promise<CryptoKey> => {\n const { alg, kid } = header;\n\n if (!SUPPORTED_JWS_ALGS.includes(alg)) {\n throw new Error('unsupported JWS \"alg\" identifier');\n }\n\n let kty: string;\n switch (alg.slice(0, 2)) {\n case 'RS': // Fall through\n case 'PS':\n kty = 'RSA';\n break;\n case 'ES':\n kty = 'EC';\n break;\n }\n\n const candidates = jwks.filter(jwk => {\n // filter keys based on the mapping of signature algorithms to Key Type\n if (jwk.kty !== kty) {\n return false;\n }\n\n // filter keys based on the JWK Key ID in the header\n if (kid !== undefined && kid !== jwk.kid) {\n return false;\n }\n\n // filter keys based on the key's declared Algorithm\n if (jwk.alg !== undefined && alg !== jwk.alg) {\n return false;\n }\n\n // filter keys based on the key's declared Public Key Use\n if (jwk.use !== undefined && jwk.use !== 'sig') {\n return false;\n }\n\n // filter keys based on the key's declared Key Operations\n if (jwk.key_ops?.includes('verify') === false) {\n return false;\n }\n\n // filter keys based on alg-specific key requirements\n switch (true) {\n case alg === 'ES256' && jwk.crv !== 'P-256': // Fall through\n case alg === 'ES384' && jwk.crv !== 'P-384': // Fall through\n case alg === 'ES512' && jwk.crv !== 'P-521': // Fall through\n return false;\n }\n\n return true;\n });\n\n const { 0: jwk, length } = candidates;\n\n if (length !== 1) {\n throw new Error(\n 'error when selecting a JWT verification key, multiple applicable keys found, a \"kid\" JWT Header Parameter is required'\n );\n }\n\n let algorithm:\n | RsaHashedImportParams\n | EcKeyImportParams\n | AlgorithmIdentifier;\n\n switch (alg) {\n case 'PS256': // Fall through\n case 'PS384': // Fall through\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'RS256': // Fall through\n case 'RS384': // Fall through\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'ES256': // Fall through\n case 'ES384':\n algorithm = { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n break;\n case 'ES512':\n algorithm = { name: 'ECDSA', namedCurve: 'P-521' };\n break;\n }\n\n const { ext, key_ops, use, ...k } = jwk;\n\n const key = await crypto.subtle.importKey('jwk', k, algorithm, true, [\n 'verify',\n ]);\n\n if (key.type !== 'public') {\n throw new Error('jwks_uri must only contain public keys');\n }\n\n return key;\n};\n\nconst CHUNK_SIZE = 0x8000;\n\n/**\n * @ignore\n * Encodes a Uint8Array or ArrayBuffer into a Base64URL string using chunked processing.\n *\n * @param input - The data to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const encodeBase64Url = (input: Uint8Array | ArrayBuffer): string => {\n if (input instanceof ArrayBuffer) {\n // eslint-disable-next-line no-param-reassign\n input = new Uint8Array(input);\n }\n\n const arr = [];\n for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {\n arr.push(\n String.fromCharCode.apply(\n null,\n Array.from(new Uint8Array(input.slice(i, i + CHUNK_SIZE)))\n )\n );\n }\n return btoa(arr.join(''))\n .replace(/=/g, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Generates a random Base64URL encoded string.\n *\n * @param length - The number of random bytes to generate.\n *\n * @returns A random Base64URL string.\n */\nexport const randomBytes = (length = 32): string =>\n encodeBase64Url(crypto.getRandomValues(new Uint8Array(length)));\n\n/**\n * @ignore\n * Checks if a value is a non-null, non-array JSON object.\n *\n * @param input - The value to check.\n *\n * @returns `true` if the value is a JSON object.\n */\nexport const isJsonObject = <T>(input: unknown): input is T => {\n if (input === null || typeof input !== 'object' || Array.isArray(input)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * @ignore\n * Parses a space-separated string into an array of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns An array of strings, or `undefined` if input is empty.\n */\nexport const parseSpaceSeparated = (s?: string): string[] | undefined =>\n s\n ?.split(/\\s+/)\n .map(x => x.trim())\n .filter(Boolean);\n\n/**\n * @ignore\n * Parses a space-separated string into a Set of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns A Set containing the unique strings.\n */\nexport const parseSpaceSeparatedSet = (s?: string): Set<string> => {\n if (!s) {\n return new Set();\n }\n\n return new Set(parseSpaceSeparated(s));\n};\n\n/**\n * @ignore\n * Compares two Sets for equality.\n *\n * @param a - The first Set.\n * @param b - The second Set.\n * @param strict - If `true`, requires both sets to be the same size. Defaults to `true`.\n *\n * @returns `true` if the sets are equal.\n */\nexport const setsEqual = (\n a: Set<string>,\n b: Set<string>,\n strict = true\n): boolean => {\n if (strict && a.size !== b.size) {\n return false;\n }\n\n for (const v of a) {\n if (!b.has(v)) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Finds a specific access token in an array based on resource and scopes.\n *\n * @param tokens - The array of access tokens.\n * @param resource - Space-separated resource indicators.\n * @param scopes - Space-separated scopes.\n *\n * @returns The matching AccessToken, or `undefined` if not found.\n */\nexport const findToken = (\n tokens?: AccessToken[],\n resource?: string,\n scopes?: string\n): AccessToken | undefined => {\n if (!Array.isArray(tokens) || tokens.length === 0) {\n return undefined;\n }\n\n const desiredResource = parseSpaceSeparatedSet(resource);\n const desiredScopes = parseSpaceSeparatedSet(scopes);\n\n return tokens.find(\n t =>\n setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) &&\n setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes))\n );\n};\n\n/**\n * @ignore\n * Builds the session user claims from existing claims and newly fetched claims.\n *\n * @param existingUser - Existing session user claims.\n * @param idTokenClaims - Claims extracted from ID token.\n * @param userinfoClaims - Claims fetched from UserInfo endpoint.\n * @param strict - If `true`, creates claims from new inputs only (falls back to existing when none). If `false`, merges into existing claims.\n *\n * @returns Updated user claims for the session.\n */\nexport const profileSync = (\n existingUser?: MonoCloudUser,\n idTokenClaims?: Partial<IdTokenClaims>,\n userinfoClaims?: Partial<MonoCloudUser>,\n strict = false\n): MonoCloudUser => {\n const hasIdTokenClaims =\n !!idTokenClaims && Object.keys(idTokenClaims).length > 0;\n const hasUserinfoClaims =\n !!userinfoClaims && Object.keys(userinfoClaims).length > 0;\n\n if (!hasIdTokenClaims && !hasUserinfoClaims) {\n return existingUser ?? ({} as MonoCloudUser);\n }\n\n if (strict) {\n return {\n ...(idTokenClaims ?? {}),\n ...(userinfoClaims ?? {}),\n } as MonoCloudUser;\n }\n\n return {\n ...(existingUser ?? {}),\n ...(idTokenClaims ?? {}),\n ...(userinfoClaims ?? {}),\n } as MonoCloudUser;\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as JwsHeaderParameters, h as Jwk, t as AccessToken } from "../types-
|
|
1
|
+
import { _ as JwsHeaderParameters, b as MonoCloudUser, h as Jwk, p as IdTokenClaims, t as AccessToken } from "../types-DmlJMcTH.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utils/internal.d.ts
|
|
4
4
|
/**
|
|
@@ -203,6 +203,18 @@ declare const setsEqual: (a: Set<string>, b: Set<string>, strict?: boolean) => b
|
|
|
203
203
|
* @returns The matching AccessToken, or `undefined` if not found.
|
|
204
204
|
*/
|
|
205
205
|
declare const findToken: (tokens?: AccessToken[], resource?: string, scopes?: string) => AccessToken | undefined;
|
|
206
|
+
/**
|
|
207
|
+
* @ignore
|
|
208
|
+
* Builds the session user claims from existing claims and newly fetched claims.
|
|
209
|
+
*
|
|
210
|
+
* @param existingUser - Existing session user claims.
|
|
211
|
+
* @param idTokenClaims - Claims extracted from ID token.
|
|
212
|
+
* @param userinfoClaims - Claims fetched from UserInfo endpoint.
|
|
213
|
+
* @param strict - If `true`, creates claims from new inputs only (falls back to existing when none). If `false`, merges into existing claims.
|
|
214
|
+
*
|
|
215
|
+
* @returns Updated user claims for the session.
|
|
216
|
+
*/
|
|
217
|
+
declare const profileSync: (existingUser?: MonoCloudUser, idTokenClaims?: Partial<IdTokenClaims>, userinfoClaims?: Partial<MonoCloudUser>, strict?: boolean) => MonoCloudUser;
|
|
206
218
|
//#endregion
|
|
207
|
-
export { arrayBufferToBase64, arrayBufferToString, decodeBase64Url, encodeBase64Url, ensureLeadingSlash, findToken, fromB64Url, getBoolean, getNumber, getPublicSigKeyFromIssuerJwks, isAbsoluteUrl, isJsonObject, isPresent, isSameHost, now, parseSpaceSeparated, parseSpaceSeparatedSet, randomBytes, removeTrailingSlash, setsEqual, stringToArrayBuffer, toB64Url };
|
|
219
|
+
export { arrayBufferToBase64, arrayBufferToString, decodeBase64Url, encodeBase64Url, ensureLeadingSlash, findToken, fromB64Url, getBoolean, getNumber, getPublicSigKeyFromIssuerJwks, isAbsoluteUrl, isJsonObject, isPresent, isSameHost, now, parseSpaceSeparated, parseSpaceSeparatedSet, profileSync, randomBytes, removeTrailingSlash, setsEqual, stringToArrayBuffer, toB64Url };
|
|
208
220
|
//# sourceMappingURL=internal.d.mts.map
|
package/dist/utils/internal.mjs
CHANGED
|
@@ -337,7 +337,32 @@ const findToken = (tokens, resource, scopes) => {
|
|
|
337
337
|
const desiredScopes = parseSpaceSeparatedSet(scopes);
|
|
338
338
|
return tokens.find((t) => setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) && setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes)));
|
|
339
339
|
};
|
|
340
|
+
/**
|
|
341
|
+
* @ignore
|
|
342
|
+
* Builds the session user claims from existing claims and newly fetched claims.
|
|
343
|
+
*
|
|
344
|
+
* @param existingUser - Existing session user claims.
|
|
345
|
+
* @param idTokenClaims - Claims extracted from ID token.
|
|
346
|
+
* @param userinfoClaims - Claims fetched from UserInfo endpoint.
|
|
347
|
+
* @param strict - If `true`, creates claims from new inputs only (falls back to existing when none). If `false`, merges into existing claims.
|
|
348
|
+
*
|
|
349
|
+
* @returns Updated user claims for the session.
|
|
350
|
+
*/
|
|
351
|
+
const profileSync = (existingUser, idTokenClaims, userinfoClaims, strict = false) => {
|
|
352
|
+
const hasIdTokenClaims = !!idTokenClaims && Object.keys(idTokenClaims).length > 0;
|
|
353
|
+
const hasUserinfoClaims = !!userinfoClaims && Object.keys(userinfoClaims).length > 0;
|
|
354
|
+
if (!hasIdTokenClaims && !hasUserinfoClaims) return existingUser ?? {};
|
|
355
|
+
if (strict) return {
|
|
356
|
+
...idTokenClaims ?? {},
|
|
357
|
+
...userinfoClaims ?? {}
|
|
358
|
+
};
|
|
359
|
+
return {
|
|
360
|
+
...existingUser ?? {},
|
|
361
|
+
...idTokenClaims ?? {},
|
|
362
|
+
...userinfoClaims ?? {}
|
|
363
|
+
};
|
|
364
|
+
};
|
|
340
365
|
|
|
341
366
|
//#endregion
|
|
342
|
-
export { arrayBufferToBase64, arrayBufferToString, decodeBase64Url, encodeBase64Url, ensureLeadingSlash, findToken, fromB64Url, getBoolean, getNumber, getPublicSigKeyFromIssuerJwks, isAbsoluteUrl, isJsonObject, isPresent, isSameHost, now, parseSpaceSeparated, parseSpaceSeparatedSet, randomBytes, removeTrailingSlash, setsEqual, stringToArrayBuffer, toB64Url };
|
|
367
|
+
export { arrayBufferToBase64, arrayBufferToString, decodeBase64Url, encodeBase64Url, ensureLeadingSlash, findToken, fromB64Url, getBoolean, getNumber, getPublicSigKeyFromIssuerJwks, isAbsoluteUrl, isJsonObject, isPresent, isSameHost, now, parseSpaceSeparated, parseSpaceSeparatedSet, profileSync, randomBytes, removeTrailingSlash, setsEqual, stringToArrayBuffer, toB64Url };
|
|
343
368
|
//# sourceMappingURL=internal.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.mjs","names":[],"sources":["../../src/utils/internal.ts"],"sourcesContent":["import type {\n AccessToken,\n Jwk,\n SecurityAlgorithms,\n JwsHeaderParameters,\n} from '../types';\n\n/**\n * @ignore\n * Converts a string to a Base64URL encoded string.\n *\n * @param input - The string to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const toB64Url = (input: string): string =>\n input.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\n/**\n * @ignore\n * Parses a string value into a boolean.\n *\n * @param value - The string value to parse.\n *\n * @returns `true` if \"true\", `false` if \"false\", otherwise `undefined`.\n */\nexport const getBoolean = (value?: string): boolean | undefined => {\n const v = value?.toLowerCase()?.trim();\n\n if (v === 'true') {\n return true;\n }\n\n if (v === 'false') {\n return false;\n }\n\n return undefined;\n};\n\n/**\n * @ignore\n * Parses a string value into a number.\n *\n * @param value - The string value to parse.\n *\n * @returns The parsed number, or `undefined` if empty or invalid.\n */\nexport const getNumber = (value?: string): number | undefined => {\n const v = value?.trim();\n\n if (v === undefined || v.length === 0) {\n return undefined;\n }\n\n const p = parseInt(v, 10);\n\n return Number.isNaN(p) ? undefined : p;\n};\n\n/**\n * @ignore\n * Ensures that a string has a leading forward slash.\n *\n * @param val - The string to check.\n *\n * @returns The string with a leading slash.\n */\nexport const ensureLeadingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.startsWith('/') ? v : `/${v}`;\n};\n\n/**\n * @ignore\n * Removes a trailing forward slash from a string.\n *\n * @param val - The string to check.\n *\n * @returns The string without a trailing slash.\n */\nexport const removeTrailingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.endsWith('/') ? v.substring(0, v.length - 1) : v;\n};\n\n/**\n * @ignore\n * Checks if a value is present (not null, undefined, or an empty string).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is present, `false` otherwise.\n */\nexport const isPresent = (value?: string | number | boolean): boolean => {\n if (typeof value === 'boolean' || typeof value === 'number') {\n return true;\n }\n const v = value?.trim();\n return v !== undefined && v !== null && v.length > 0;\n};\n\n/**\n * @ignore\n * Checks if a URL is an absolute URL (starts with http:// or https://).\n *\n * @param url - The URL to check.\n *\n * @returns `true` if absolute, `false` otherwise.\n */\nexport const isAbsoluteUrl = (url: string): boolean =>\n (url?.startsWith('http://') || url?.startsWith('https://')) ?? false;\n\n/**\n * @ignore\n * Checks if two URLs have the same origin (host and port).\n *\n * @param url - The first URL.\n * @param urlToCheck - The second URL to compare against.\n *\n * @returns `true` if they share the same origin, `false` otherwise.\n */\nexport const isSameHost = (url: string, urlToCheck: string): boolean => {\n try {\n const u = new URL(url);\n const u2 = new URL(urlToCheck);\n\n return u.origin === u2.origin;\n } catch {\n return false;\n }\n};\n\n/**\n * @ignore\n * Converts a string to a Uint8Array using TextEncoder.\n *\n * @param str - The string to convert.\n *\n * @returns A Uint8Array representation of the string.\n */\nexport const stringToArrayBuffer = (str: string): Uint8Array => {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n};\n\n/**\n * @ignore\n * Converts an ArrayBuffer to a string using TextDecoder.\n *\n * @param buffer - The buffer to convert.\n *\n * @returns The decoded string.\n */\nexport const arrayBufferToString = (buffer: ArrayBuffer): string => {\n const decoder = new TextDecoder();\n return decoder.decode(buffer);\n};\n\n/**\n * @ignore\n * Converts a Base64URL string back to a standard Base64 string with padding.\n *\n * @param input - The Base64URL string.\n *\n * @returns A standard Base64 string.\n */\nexport const fromB64Url = (input: string): string => {\n let str = input;\n if (str.length % 4 !== 0) {\n str += '==='.slice(0, 4 - (str.length % 4));\n }\n\n str = str.replace(/-/g, '+').replace(/_/g, '/');\n\n return str;\n};\n\n/**\n * @ignore\n * Decodes a Base64URL encoded string.\n *\n * @param input - The Base64URL string to decode.\n *\n * @returns The decoded plaintext string.\n */\nexport const decodeBase64Url = (input: string): string =>\n atob(fromB64Url(input).replace(/\\s/g, ''));\n\n/**\n * @ignore\n * Converts a Uint8Array to a Base64URL encoded string.\n *\n * @param buffer - The buffer to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const arrayBufferToBase64 = (buffer: Uint8Array): string => {\n const bytes = new Uint8Array(buffer);\n const binary = bytes.reduce(\n (acc, byte) => acc + String.fromCharCode(byte),\n ''\n );\n return btoa(binary).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Gets the current Unix timestamp in seconds.\n *\n * @returns The current timestamp.\n */\nexport const now = (): number => Math.ceil(Date.now() / 1000);\n\nconst SUPPORTED_JWS_ALGS: SecurityAlgorithms[] = [\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512',\n];\n\n/**\n * Retrieves a public CryptoKey from a JWK set based on the JWS header.\n *\n * @param jwks - The set of JSON Web Keys.\n * @param header - The JWS header containing the algorithm and key ID.\n *\n * @returns A promise that resolves to the CryptoKey.\n *\n * @throws If no applicable key or multiple keys are found or the algorithm is unsupported.\n */\nexport const getPublicSigKeyFromIssuerJwks = async (\n jwks: Jwk[],\n header: JwsHeaderParameters\n): Promise<CryptoKey> => {\n const { alg, kid } = header;\n\n if (!SUPPORTED_JWS_ALGS.includes(alg)) {\n throw new Error('unsupported JWS \"alg\" identifier');\n }\n\n let kty: string;\n switch (alg.slice(0, 2)) {\n case 'RS': // Fall through\n case 'PS':\n kty = 'RSA';\n break;\n case 'ES':\n kty = 'EC';\n break;\n }\n\n const candidates = jwks.filter(jwk => {\n // filter keys based on the mapping of signature algorithms to Key Type\n if (jwk.kty !== kty) {\n return false;\n }\n\n // filter keys based on the JWK Key ID in the header\n if (kid !== undefined && kid !== jwk.kid) {\n return false;\n }\n\n // filter keys based on the key's declared Algorithm\n if (jwk.alg !== undefined && alg !== jwk.alg) {\n return false;\n }\n\n // filter keys based on the key's declared Public Key Use\n if (jwk.use !== undefined && jwk.use !== 'sig') {\n return false;\n }\n\n // filter keys based on the key's declared Key Operations\n if (jwk.key_ops?.includes('verify') === false) {\n return false;\n }\n\n // filter keys based on alg-specific key requirements\n switch (true) {\n case alg === 'ES256' && jwk.crv !== 'P-256': // Fall through\n case alg === 'ES384' && jwk.crv !== 'P-384': // Fall through\n case alg === 'ES512' && jwk.crv !== 'P-521': // Fall through\n return false;\n }\n\n return true;\n });\n\n const { 0: jwk, length } = candidates;\n\n if (length !== 1) {\n throw new Error(\n 'error when selecting a JWT verification key, multiple applicable keys found, a \"kid\" JWT Header Parameter is required'\n );\n }\n\n let algorithm:\n | RsaHashedImportParams\n | EcKeyImportParams\n | AlgorithmIdentifier;\n\n switch (alg) {\n case 'PS256': // Fall through\n case 'PS384': // Fall through\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'RS256': // Fall through\n case 'RS384': // Fall through\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'ES256': // Fall through\n case 'ES384':\n algorithm = { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n break;\n case 'ES512':\n algorithm = { name: 'ECDSA', namedCurve: 'P-521' };\n break;\n }\n\n const { ext, key_ops, use, ...k } = jwk;\n\n const key = await crypto.subtle.importKey('jwk', k, algorithm, true, [\n 'verify',\n ]);\n\n if (key.type !== 'public') {\n throw new Error('jwks_uri must only contain public keys');\n }\n\n return key;\n};\n\nconst CHUNK_SIZE = 0x8000;\n\n/**\n * @ignore\n * Encodes a Uint8Array or ArrayBuffer into a Base64URL string using chunked processing.\n *\n * @param input - The data to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const encodeBase64Url = (input: Uint8Array | ArrayBuffer): string => {\n if (input instanceof ArrayBuffer) {\n // eslint-disable-next-line no-param-reassign\n input = new Uint8Array(input);\n }\n\n const arr = [];\n for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {\n arr.push(\n String.fromCharCode.apply(\n null,\n Array.from(new Uint8Array(input.slice(i, i + CHUNK_SIZE)))\n )\n );\n }\n return btoa(arr.join(''))\n .replace(/=/g, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Generates a random Base64URL encoded string.\n *\n * @param length - The number of random bytes to generate.\n *\n * @returns A random Base64URL string.\n */\nexport const randomBytes = (length = 32): string =>\n encodeBase64Url(crypto.getRandomValues(new Uint8Array(length)));\n\n/**\n * @ignore\n * Checks if a value is a non-null, non-array JSON object.\n *\n * @param input - The value to check.\n *\n * @returns `true` if the value is a JSON object.\n */\nexport const isJsonObject = <T>(input: unknown): input is T => {\n if (input === null || typeof input !== 'object' || Array.isArray(input)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * @ignore\n * Parses a space-separated string into an array of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns An array of strings, or `undefined` if input is empty.\n */\nexport const parseSpaceSeparated = (s?: string): string[] | undefined =>\n s\n ?.split(/\\s+/)\n .map(x => x.trim())\n .filter(Boolean);\n\n/**\n * @ignore\n * Parses a space-separated string into a Set of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns A Set containing the unique strings.\n */\nexport const parseSpaceSeparatedSet = (s?: string): Set<string> => {\n if (!s) {\n return new Set();\n }\n\n return new Set(parseSpaceSeparated(s));\n};\n\n/**\n * @ignore\n * Compares two Sets for equality.\n *\n * @param a - The first Set.\n * @param b - The second Set.\n * @param strict - If `true`, requires both sets to be the same size. Defaults to `true`.\n *\n * @returns `true` if the sets are equal.\n */\nexport const setsEqual = (\n a: Set<string>,\n b: Set<string>,\n strict = true\n): boolean => {\n if (strict && a.size !== b.size) {\n return false;\n }\n\n for (const v of a) {\n if (!b.has(v)) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Finds a specific access token in an array based on resource and scopes.\n *\n * @param tokens - The array of access tokens.\n * @param resource - Space-separated resource indicators.\n * @param scopes - Space-separated scopes.\n *\n * @returns The matching AccessToken, or `undefined` if not found.\n */\nexport const findToken = (\n tokens?: AccessToken[],\n resource?: string,\n scopes?: string\n): AccessToken | undefined => {\n if (!Array.isArray(tokens) || tokens.length === 0) {\n return undefined;\n }\n\n const desiredResource = parseSpaceSeparatedSet(resource);\n const desiredScopes = parseSpaceSeparatedSet(scopes);\n\n return tokens.find(\n t =>\n setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) &&\n setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes))\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal.mjs","names":[],"sources":["../../src/utils/internal.ts"],"sourcesContent":["import type {\n AccessToken,\n IdTokenClaims,\n Jwk,\n MonoCloudUser,\n SecurityAlgorithms,\n JwsHeaderParameters,\n} from '../types';\n\n/**\n * @ignore\n * Converts a string to a Base64URL encoded string.\n *\n * @param input - The string to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const toB64Url = (input: string): string =>\n input.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\n/**\n * @ignore\n * Parses a string value into a boolean.\n *\n * @param value - The string value to parse.\n *\n * @returns `true` if \"true\", `false` if \"false\", otherwise `undefined`.\n */\nexport const getBoolean = (value?: string): boolean | undefined => {\n const v = value?.toLowerCase()?.trim();\n\n if (v === 'true') {\n return true;\n }\n\n if (v === 'false') {\n return false;\n }\n\n return undefined;\n};\n\n/**\n * @ignore\n * Parses a string value into a number.\n *\n * @param value - The string value to parse.\n *\n * @returns The parsed number, or `undefined` if empty or invalid.\n */\nexport const getNumber = (value?: string): number | undefined => {\n const v = value?.trim();\n\n if (v === undefined || v.length === 0) {\n return undefined;\n }\n\n const p = parseInt(v, 10);\n\n return Number.isNaN(p) ? undefined : p;\n};\n\n/**\n * @ignore\n * Ensures that a string has a leading forward slash.\n *\n * @param val - The string to check.\n *\n * @returns The string with a leading slash.\n */\nexport const ensureLeadingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.startsWith('/') ? v : `/${v}`;\n};\n\n/**\n * @ignore\n * Removes a trailing forward slash from a string.\n *\n * @param val - The string to check.\n *\n * @returns The string without a trailing slash.\n */\nexport const removeTrailingSlash = (val?: string): string => {\n const v = val?.trim();\n\n if (!v) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return v!;\n }\n\n return v.endsWith('/') ? v.substring(0, v.length - 1) : v;\n};\n\n/**\n * @ignore\n * Checks if a value is present (not null, undefined, or an empty string).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is present, `false` otherwise.\n */\nexport const isPresent = (value?: string | number | boolean): boolean => {\n if (typeof value === 'boolean' || typeof value === 'number') {\n return true;\n }\n const v = value?.trim();\n return v !== undefined && v !== null && v.length > 0;\n};\n\n/**\n * @ignore\n * Checks if a URL is an absolute URL (starts with http:// or https://).\n *\n * @param url - The URL to check.\n *\n * @returns `true` if absolute, `false` otherwise.\n */\nexport const isAbsoluteUrl = (url: string): boolean =>\n (url?.startsWith('http://') || url?.startsWith('https://')) ?? false;\n\n/**\n * @ignore\n * Checks if two URLs have the same origin (host and port).\n *\n * @param url - The first URL.\n * @param urlToCheck - The second URL to compare against.\n *\n * @returns `true` if they share the same origin, `false` otherwise.\n */\nexport const isSameHost = (url: string, urlToCheck: string): boolean => {\n try {\n const u = new URL(url);\n const u2 = new URL(urlToCheck);\n\n return u.origin === u2.origin;\n } catch {\n return false;\n }\n};\n\n/**\n * @ignore\n * Converts a string to a Uint8Array using TextEncoder.\n *\n * @param str - The string to convert.\n *\n * @returns A Uint8Array representation of the string.\n */\nexport const stringToArrayBuffer = (str: string): Uint8Array => {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n};\n\n/**\n * @ignore\n * Converts an ArrayBuffer to a string using TextDecoder.\n *\n * @param buffer - The buffer to convert.\n *\n * @returns The decoded string.\n */\nexport const arrayBufferToString = (buffer: ArrayBuffer): string => {\n const decoder = new TextDecoder();\n return decoder.decode(buffer);\n};\n\n/**\n * @ignore\n * Converts a Base64URL string back to a standard Base64 string with padding.\n *\n * @param input - The Base64URL string.\n *\n * @returns A standard Base64 string.\n */\nexport const fromB64Url = (input: string): string => {\n let str = input;\n if (str.length % 4 !== 0) {\n str += '==='.slice(0, 4 - (str.length % 4));\n }\n\n str = str.replace(/-/g, '+').replace(/_/g, '/');\n\n return str;\n};\n\n/**\n * @ignore\n * Decodes a Base64URL encoded string.\n *\n * @param input - The Base64URL string to decode.\n *\n * @returns The decoded plaintext string.\n */\nexport const decodeBase64Url = (input: string): string =>\n atob(fromB64Url(input).replace(/\\s/g, ''));\n\n/**\n * @ignore\n * Converts a Uint8Array to a Base64URL encoded string.\n *\n * @param buffer - The buffer to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const arrayBufferToBase64 = (buffer: Uint8Array): string => {\n const bytes = new Uint8Array(buffer);\n const binary = bytes.reduce(\n (acc, byte) => acc + String.fromCharCode(byte),\n ''\n );\n return btoa(binary).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Gets the current Unix timestamp in seconds.\n *\n * @returns The current timestamp.\n */\nexport const now = (): number => Math.ceil(Date.now() / 1000);\n\nconst SUPPORTED_JWS_ALGS: SecurityAlgorithms[] = [\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512',\n];\n\n/**\n * Retrieves a public CryptoKey from a JWK set based on the JWS header.\n *\n * @param jwks - The set of JSON Web Keys.\n * @param header - The JWS header containing the algorithm and key ID.\n *\n * @returns A promise that resolves to the CryptoKey.\n *\n * @throws If no applicable key or multiple keys are found or the algorithm is unsupported.\n */\nexport const getPublicSigKeyFromIssuerJwks = async (\n jwks: Jwk[],\n header: JwsHeaderParameters\n): Promise<CryptoKey> => {\n const { alg, kid } = header;\n\n if (!SUPPORTED_JWS_ALGS.includes(alg)) {\n throw new Error('unsupported JWS \"alg\" identifier');\n }\n\n let kty: string;\n switch (alg.slice(0, 2)) {\n case 'RS': // Fall through\n case 'PS':\n kty = 'RSA';\n break;\n case 'ES':\n kty = 'EC';\n break;\n }\n\n const candidates = jwks.filter(jwk => {\n // filter keys based on the mapping of signature algorithms to Key Type\n if (jwk.kty !== kty) {\n return false;\n }\n\n // filter keys based on the JWK Key ID in the header\n if (kid !== undefined && kid !== jwk.kid) {\n return false;\n }\n\n // filter keys based on the key's declared Algorithm\n if (jwk.alg !== undefined && alg !== jwk.alg) {\n return false;\n }\n\n // filter keys based on the key's declared Public Key Use\n if (jwk.use !== undefined && jwk.use !== 'sig') {\n return false;\n }\n\n // filter keys based on the key's declared Key Operations\n if (jwk.key_ops?.includes('verify') === false) {\n return false;\n }\n\n // filter keys based on alg-specific key requirements\n switch (true) {\n case alg === 'ES256' && jwk.crv !== 'P-256': // Fall through\n case alg === 'ES384' && jwk.crv !== 'P-384': // Fall through\n case alg === 'ES512' && jwk.crv !== 'P-521': // Fall through\n return false;\n }\n\n return true;\n });\n\n const { 0: jwk, length } = candidates;\n\n if (length !== 1) {\n throw new Error(\n 'error when selecting a JWT verification key, multiple applicable keys found, a \"kid\" JWT Header Parameter is required'\n );\n }\n\n let algorithm:\n | RsaHashedImportParams\n | EcKeyImportParams\n | AlgorithmIdentifier;\n\n switch (alg) {\n case 'PS256': // Fall through\n case 'PS384': // Fall through\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'RS256': // Fall through\n case 'RS384': // Fall through\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n break;\n case 'ES256': // Fall through\n case 'ES384':\n algorithm = { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n break;\n case 'ES512':\n algorithm = { name: 'ECDSA', namedCurve: 'P-521' };\n break;\n }\n\n const { ext, key_ops, use, ...k } = jwk;\n\n const key = await crypto.subtle.importKey('jwk', k, algorithm, true, [\n 'verify',\n ]);\n\n if (key.type !== 'public') {\n throw new Error('jwks_uri must only contain public keys');\n }\n\n return key;\n};\n\nconst CHUNK_SIZE = 0x8000;\n\n/**\n * @ignore\n * Encodes a Uint8Array or ArrayBuffer into a Base64URL string using chunked processing.\n *\n * @param input - The data to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const encodeBase64Url = (input: Uint8Array | ArrayBuffer): string => {\n if (input instanceof ArrayBuffer) {\n // eslint-disable-next-line no-param-reassign\n input = new Uint8Array(input);\n }\n\n const arr = [];\n for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {\n arr.push(\n String.fromCharCode.apply(\n null,\n Array.from(new Uint8Array(input.slice(i, i + CHUNK_SIZE)))\n )\n );\n }\n return btoa(arr.join(''))\n .replace(/=/g, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Generates a random Base64URL encoded string.\n *\n * @param length - The number of random bytes to generate.\n *\n * @returns A random Base64URL string.\n */\nexport const randomBytes = (length = 32): string =>\n encodeBase64Url(crypto.getRandomValues(new Uint8Array(length)));\n\n/**\n * @ignore\n * Checks if a value is a non-null, non-array JSON object.\n *\n * @param input - The value to check.\n *\n * @returns `true` if the value is a JSON object.\n */\nexport const isJsonObject = <T>(input: unknown): input is T => {\n if (input === null || typeof input !== 'object' || Array.isArray(input)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * @ignore\n * Parses a space-separated string into an array of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns An array of strings, or `undefined` if input is empty.\n */\nexport const parseSpaceSeparated = (s?: string): string[] | undefined =>\n s\n ?.split(/\\s+/)\n .map(x => x.trim())\n .filter(Boolean);\n\n/**\n * @ignore\n * Parses a space-separated string into a Set of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns A Set containing the unique strings.\n */\nexport const parseSpaceSeparatedSet = (s?: string): Set<string> => {\n if (!s) {\n return new Set();\n }\n\n return new Set(parseSpaceSeparated(s));\n};\n\n/**\n * @ignore\n * Compares two Sets for equality.\n *\n * @param a - The first Set.\n * @param b - The second Set.\n * @param strict - If `true`, requires both sets to be the same size. Defaults to `true`.\n *\n * @returns `true` if the sets are equal.\n */\nexport const setsEqual = (\n a: Set<string>,\n b: Set<string>,\n strict = true\n): boolean => {\n if (strict && a.size !== b.size) {\n return false;\n }\n\n for (const v of a) {\n if (!b.has(v)) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Finds a specific access token in an array based on resource and scopes.\n *\n * @param tokens - The array of access tokens.\n * @param resource - Space-separated resource indicators.\n * @param scopes - Space-separated scopes.\n *\n * @returns The matching AccessToken, or `undefined` if not found.\n */\nexport const findToken = (\n tokens?: AccessToken[],\n resource?: string,\n scopes?: string\n): AccessToken | undefined => {\n if (!Array.isArray(tokens) || tokens.length === 0) {\n return undefined;\n }\n\n const desiredResource = parseSpaceSeparatedSet(resource);\n const desiredScopes = parseSpaceSeparatedSet(scopes);\n\n return tokens.find(\n t =>\n setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) &&\n setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes))\n );\n};\n\n/**\n * @ignore\n * Builds the session user claims from existing claims and newly fetched claims.\n *\n * @param existingUser - Existing session user claims.\n * @param idTokenClaims - Claims extracted from ID token.\n * @param userinfoClaims - Claims fetched from UserInfo endpoint.\n * @param strict - If `true`, creates claims from new inputs only (falls back to existing when none). If `false`, merges into existing claims.\n *\n * @returns Updated user claims for the session.\n */\nexport const profileSync = (\n existingUser?: MonoCloudUser,\n idTokenClaims?: Partial<IdTokenClaims>,\n userinfoClaims?: Partial<MonoCloudUser>,\n strict = false\n): MonoCloudUser => {\n const hasIdTokenClaims =\n !!idTokenClaims && Object.keys(idTokenClaims).length > 0;\n const hasUserinfoClaims =\n !!userinfoClaims && Object.keys(userinfoClaims).length > 0;\n\n if (!hasIdTokenClaims && !hasUserinfoClaims) {\n return existingUser ?? ({} as MonoCloudUser);\n }\n\n if (strict) {\n return {\n ...(idTokenClaims ?? {}),\n ...(userinfoClaims ?? {}),\n } as MonoCloudUser;\n }\n\n return {\n ...(existingUser ?? {}),\n ...(idTokenClaims ?? {}),\n ...(userinfoClaims ?? {}),\n } as MonoCloudUser;\n};\n"],"mappings":"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"}
|