alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
1,210 lines • 125 kB
JavaScript
import { $context, $hook, $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive, z } from "alepha";
import { $cookie, AlephaServerCookies, ServerCookiesProvider } from "alepha/server/cookies";
import { DateTimeProvider } from "alepha/datetime";
import { InvalidCredentialsError, SecurityError, SecurityProvider, userAccountInfoSchema } from "alepha/security";
import { $logger } from "alepha/logger";
import { $route, BadRequestError } from "alepha/server";
import { ServerLinksProvider, apiRegistryResponseSchema } from "alepha/server/links";
//#region ../../../../node_modules/oauth4webapi/build/index.js
let USER_AGENT$1;
if (typeof navigator === "undefined" || !navigator.userAgent?.startsWith?.("Mozilla/5.0 ")) USER_AGENT$1 = `oauth4webapi/v3.8.5`;
function looseInstanceOf(input, expected) {
if (input == null) return false;
try {
return input instanceof expected || Object.getPrototypeOf(input)[Symbol.toStringTag] === expected.prototype[Symbol.toStringTag];
} catch {
return false;
}
}
const ERR_INVALID_ARG_VALUE$1 = "ERR_INVALID_ARG_VALUE";
const ERR_INVALID_ARG_TYPE$1 = "ERR_INVALID_ARG_TYPE";
function CodedTypeError$1(message, code, cause) {
const err = new TypeError(message, { cause });
Object.assign(err, { code });
return err;
}
const allowInsecureRequests$1 = Symbol();
const clockSkew = Symbol();
const clockTolerance = Symbol();
const customFetch$1 = Symbol();
const jweDecrypt = Symbol();
const encoder$1 = new TextEncoder();
const decoder$2 = new TextDecoder();
function buf(input) {
if (typeof input === "string") return encoder$1.encode(input);
return decoder$2.decode(input);
}
let encodeBase64Url;
if (Uint8Array.prototype.toBase64) encodeBase64Url = (input) => {
if (input instanceof ArrayBuffer) input = new Uint8Array(input);
return input.toBase64({
alphabet: "base64url",
omitPadding: true
});
};
else {
const CHUNK_SIZE = 32768;
encodeBase64Url = (input) => {
if (input instanceof ArrayBuffer) input = new Uint8Array(input);
const arr = [];
for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
return btoa(arr.join("")).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
};
}
let decodeBase64Url;
if (Uint8Array.fromBase64) decodeBase64Url = (input) => {
try {
return Uint8Array.fromBase64(input, { alphabet: "base64url" });
} catch (cause) {
throw CodedTypeError$1("The input to be decoded is not correctly encoded.", ERR_INVALID_ARG_VALUE$1, cause);
}
};
else decodeBase64Url = (input) => {
try {
const binary = atob(input.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, ""));
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return bytes;
} catch (cause) {
throw CodedTypeError$1("The input to be decoded is not correctly encoded.", ERR_INVALID_ARG_VALUE$1, cause);
}
};
function b64u(input) {
if (typeof input === "string") return decodeBase64Url(input);
return encodeBase64Url(input);
}
var UnsupportedOperationError = class extends Error {
code;
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
this.code = UNSUPPORTED_OPERATION;
Error.captureStackTrace?.(this, this.constructor);
}
};
var OperationProcessingError = class extends Error {
code;
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
if (options?.code) this.code = options?.code;
Error.captureStackTrace?.(this, this.constructor);
}
};
function OPE(message, code, cause) {
return new OperationProcessingError(message, {
code,
cause
});
}
function isJsonObject(input) {
if (input === null || typeof input !== "object" || Array.isArray(input)) return false;
return true;
}
function prepareHeaders(input) {
if (looseInstanceOf(input, Headers)) input = Object.fromEntries(input.entries());
const headers = new Headers(input ?? {});
if (USER_AGENT$1 && !headers.has("user-agent")) headers.set("user-agent", USER_AGENT$1);
if (headers.has("authorization")) throw CodedTypeError$1("\"options.headers\" must not include the \"authorization\" header name", ERR_INVALID_ARG_VALUE$1);
return headers;
}
function signal$1(url, value) {
if (value !== void 0) {
if (typeof value === "function") value = value(url.href);
if (!(value instanceof AbortSignal)) throw CodedTypeError$1("\"options.signal\" must return or be an instance of AbortSignal", ERR_INVALID_ARG_TYPE$1);
return value;
}
}
function replaceDoubleSlash(pathname) {
if (pathname.includes("//")) return pathname.replace("//", "/");
return pathname;
}
function prependWellKnown(url, wellKnown, allowTerminatingSlash = false) {
if (url.pathname === "/") url.pathname = wellKnown;
else url.pathname = replaceDoubleSlash(`${wellKnown}/${allowTerminatingSlash ? url.pathname : url.pathname.replace(/(\/)$/, "")}`);
return url;
}
function appendWellKnown(url, wellKnown) {
url.pathname = replaceDoubleSlash(`${url.pathname}/${wellKnown}`);
return url;
}
async function performDiscovery$1(input, urlName, transform, options) {
if (!(input instanceof URL)) throw CodedTypeError$1(`"${urlName}" must be an instance of URL`, ERR_INVALID_ARG_TYPE$1);
checkProtocol(input, options?.[allowInsecureRequests$1] !== true);
const url = transform(new URL(input.href));
const headers = prepareHeaders(options?.headers);
headers.set("accept", "application/json");
return (options?.[customFetch$1] || fetch)(url.href, {
body: void 0,
headers: Object.fromEntries(headers.entries()),
method: "GET",
redirect: "manual",
signal: signal$1(url, options?.signal)
});
}
async function discoveryRequest(issuerIdentifier, options) {
return performDiscovery$1(issuerIdentifier, "issuerIdentifier", (url) => {
switch (options?.algorithm) {
case void 0:
case "oidc":
appendWellKnown(url, ".well-known/openid-configuration");
break;
case "oauth2":
prependWellKnown(url, ".well-known/oauth-authorization-server");
break;
default: throw CodedTypeError$1("\"options.algorithm\" must be \"oidc\" (default), or \"oauth2\"", ERR_INVALID_ARG_VALUE$1);
}
return url;
}, options);
}
function assertNumber(input, allow0, it, code, cause) {
try {
if (typeof input !== "number" || !Number.isFinite(input)) throw CodedTypeError$1(`${it} must be a number`, ERR_INVALID_ARG_TYPE$1, cause);
if (input > 0) return;
if (allow0) {
if (input !== 0) throw CodedTypeError$1(`${it} must be a non-negative number`, ERR_INVALID_ARG_VALUE$1, cause);
return;
}
throw CodedTypeError$1(`${it} must be a positive number`, ERR_INVALID_ARG_VALUE$1, cause);
} catch (err) {
if (code) throw OPE(err.message, code, cause);
throw err;
}
}
function assertString$1(input, it, code, cause) {
try {
if (typeof input !== "string") throw CodedTypeError$1(`${it} must be a string`, ERR_INVALID_ARG_TYPE$1, cause);
if (input.length === 0) throw CodedTypeError$1(`${it} must not be empty`, ERR_INVALID_ARG_VALUE$1, cause);
} catch (err) {
if (code) throw OPE(err.message, code, cause);
throw err;
}
}
async function processDiscoveryResponse(expectedIssuerIdentifier, response) {
const expected = expectedIssuerIdentifier;
if (!(expected instanceof URL) && expected !== _nodiscoverycheck) throw CodedTypeError$1("\"expectedIssuerIdentifier\" must be an instance of URL", ERR_INVALID_ARG_TYPE$1);
if (!looseInstanceOf(response, Response)) throw CodedTypeError$1("\"response\" must be an instance of Response", ERR_INVALID_ARG_TYPE$1);
if (response.status !== 200) throw OPE("\"response\" is not a conform Authorization Server Metadata response (unexpected HTTP status code)", RESPONSE_IS_NOT_CONFORM, response);
assertReadableResponse(response);
const json = await getResponseJsonBody(response);
assertString$1(json.issuer, "\"response\" body \"issuer\" property", INVALID_RESPONSE, { body: json });
if (expected !== _nodiscoverycheck && new URL(json.issuer).href !== expected.href) throw OPE("\"response\" body \"issuer\" property does not match the expected value", JSON_ATTRIBUTE_COMPARISON, {
expected: expected.href,
body: json,
attribute: "issuer"
});
return json;
}
function assertApplicationJson(response) {
assertContentType(response, "application/json");
}
function notJson(response, ...types) {
let msg = "\"response\" content-type must be ";
if (types.length > 2) {
const last = types.pop();
msg += `${types.join(", ")}, or ${last}`;
} else if (types.length === 2) msg += `${types[0]} or ${types[1]}`;
else msg += types[0];
return OPE(msg, RESPONSE_IS_NOT_JSON, response);
}
function assertContentType(response, contentType) {
if (getContentType(response) !== contentType) throw notJson(response, contentType);
}
function randomBytes() {
return b64u(crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32)));
}
function generateRandomCodeVerifier() {
return randomBytes();
}
function generateRandomState() {
return randomBytes();
}
async function calculatePKCECodeChallenge$1(codeVerifier) {
assertString$1(codeVerifier, "codeVerifier");
return b64u(await crypto.subtle.digest("SHA-256", buf(codeVerifier)));
}
function getClockSkew(client) {
const skew = client?.[clockSkew];
return typeof skew === "number" && Number.isFinite(skew) ? skew : 0;
}
function getClockTolerance(client) {
const tolerance = client?.[clockTolerance];
return typeof tolerance === "number" && Number.isFinite(tolerance) && Math.sign(tolerance) !== -1 ? tolerance : 30;
}
function epochTime() {
return Math.floor(Date.now() / 1e3);
}
function assertAs(as) {
if (typeof as !== "object" || as === null) throw CodedTypeError$1("\"as\" must be an object", ERR_INVALID_ARG_TYPE$1);
assertString$1(as.issuer, "\"as.issuer\"");
}
function assertClient(client) {
if (typeof client !== "object" || client === null) throw CodedTypeError$1("\"client\" must be an object", ERR_INVALID_ARG_TYPE$1);
assertString$1(client.client_id, "\"client.client_id\"");
}
function ClientSecretPost$1(clientSecret) {
assertString$1(clientSecret, "\"clientSecret\"");
return (_as, client, body, _headers) => {
body.set("client_id", client.client_id);
body.set("client_secret", clientSecret);
};
}
function None$1() {
return (_as, client, body, _headers) => {
body.set("client_id", client.client_id);
};
}
const URLParse = URL.parse ? (url, base) => URL.parse(url, base) : (url, base) => {
try {
return new URL(url, base);
} catch {
return null;
}
};
function checkProtocol(url, enforceHttps) {
if (enforceHttps && url.protocol !== "https:") throw OPE("only requests to HTTPS are allowed", HTTP_REQUEST_FORBIDDEN, url);
if (url.protocol !== "https:" && url.protocol !== "http:") throw OPE("only HTTP and HTTPS requests are allowed", REQUEST_PROTOCOL_FORBIDDEN, url);
}
function validateEndpoint(value, endpoint, useMtlsAlias, enforceHttps) {
let url;
if (typeof value !== "string" || !(url = URLParse(value))) throw OPE(`authorization server metadata does not contain a valid ${useMtlsAlias ? `"as.mtls_endpoint_aliases.${endpoint}"` : `"as.${endpoint}"`}`, value === void 0 ? MISSING_SERVER_METADATA : INVALID_SERVER_METADATA, { attribute: useMtlsAlias ? `mtls_endpoint_aliases.${endpoint}` : endpoint });
checkProtocol(url, enforceHttps);
return url;
}
function resolveEndpoint(as, endpoint, useMtlsAlias, enforceHttps) {
if (useMtlsAlias && as.mtls_endpoint_aliases && endpoint in as.mtls_endpoint_aliases) return validateEndpoint(as.mtls_endpoint_aliases[endpoint], endpoint, useMtlsAlias, enforceHttps);
return validateEndpoint(as[endpoint], endpoint, useMtlsAlias, enforceHttps);
}
function isDPoPNonceError(err) {
if (err instanceof WWWAuthenticateChallengeError) {
const { 0: challenge, length } = err.cause;
return length === 1 && challenge.scheme === "dpop" && challenge.parameters.error === "use_dpop_nonce";
}
if (err instanceof ResponseBodyError) return err.error === "use_dpop_nonce";
return false;
}
var ResponseBodyError = class extends Error {
cause;
code;
error;
status;
error_description;
response;
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
this.code = RESPONSE_BODY_ERROR;
this.cause = options.cause;
this.error = options.cause.error;
this.status = options.response.status;
this.error_description = options.cause.error_description;
Object.defineProperty(this, "response", {
enumerable: false,
value: options.response
});
Error.captureStackTrace?.(this, this.constructor);
}
};
var AuthorizationResponseError = class extends Error {
cause;
code;
error;
error_description;
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
this.code = AUTHORIZATION_RESPONSE_ERROR;
this.cause = options.cause;
this.error = options.cause.get("error");
this.error_description = options.cause.get("error_description") ?? void 0;
Error.captureStackTrace?.(this, this.constructor);
}
};
var WWWAuthenticateChallengeError = class extends Error {
cause;
code;
response;
status;
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
this.code = WWW_AUTHENTICATE_CHALLENGE;
this.cause = options.cause;
this.status = options.response.status;
this.response = options.response;
Object.defineProperty(this, "response", { enumerable: false });
Error.captureStackTrace?.(this, this.constructor);
}
};
const schemeRE = /* @__PURE__ */ new RegExp("^[,\\s]*([a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+)");
const quotedParamRE = /* @__PURE__ */ new RegExp("^[,\\s]*([a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+)\\s*=\\s*\"((?:[^\"\\\\]|\\\\[\\s\\S])*)\"[,\\s]*(.*)");
const unquotedParamRE = /* @__PURE__ */ new RegExp("^[,\\s]*([a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+)\\s*=\\s*([a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+)[,\\s]*(.*)");
const token68ParamRE = /* @__PURE__ */ new RegExp("^([a-zA-Z0-9\\-\\._\\~\\+\\/]+={0,2})(?:$|[,\\s])(.*)");
function parseWwwAuthenticateChallenges(response) {
if (!looseInstanceOf(response, Response)) throw CodedTypeError$1("\"response\" must be an instance of Response", ERR_INVALID_ARG_TYPE$1);
const header = response.headers.get("www-authenticate");
if (header === null) return;
const challenges = [];
let rest = header;
while (rest) {
let match = rest.match(schemeRE);
const scheme = match?.["1"].toLowerCase();
if (!scheme) return;
const afterScheme = rest.substring(match[0].length);
if (afterScheme && !afterScheme.match(/^[\s,]/)) return;
const spaceMatch = afterScheme.match(/^\s+(.*)$/);
const hasParameters = !!spaceMatch;
rest = spaceMatch ? spaceMatch[1] : void 0;
const parameters = {};
let token68;
if (hasParameters) while (rest) {
let key;
let value;
if (match = rest.match(quotedParamRE)) {
[, key, value, rest] = match;
if (value.includes("\\")) try {
value = JSON.parse(`"${value}"`);
} catch {}
parameters[key.toLowerCase()] = value;
continue;
}
if (match = rest.match(unquotedParamRE)) {
[, key, value, rest] = match;
parameters[key.toLowerCase()] = value;
continue;
}
if (match = rest.match(token68ParamRE)) {
if (Object.keys(parameters).length) break;
[, token68, rest] = match;
break;
}
return;
}
else rest = afterScheme || void 0;
const challenge = {
scheme,
parameters
};
if (token68) challenge.token68 = token68;
challenges.push(challenge);
}
if (!challenges.length) return;
return challenges;
}
async function parseOAuthResponseErrorBody(response) {
if (response.status > 399 && response.status < 500) {
assertReadableResponse(response);
assertApplicationJson(response);
try {
const json = await response.clone().json();
if (isJsonObject(json) && typeof json.error === "string" && json.error.length) return json;
} catch {}
}
}
async function checkOAuthBodyError(response, expected, label) {
if (response.status !== expected) {
checkAuthenticationChallenges(response);
let err;
if (err = await parseOAuthResponseErrorBody(response)) {
await response.body?.cancel();
throw new ResponseBodyError("server responded with an error in the response body", {
cause: err,
response
});
}
throw OPE(`"response" is not a conform ${label} response (unexpected HTTP status code)`, RESPONSE_IS_NOT_CONFORM, response);
}
}
function assertDPoP(option) {
if (!branded.has(option)) throw CodedTypeError$1("\"options.DPoP\" is not a valid DPoPHandle", ERR_INVALID_ARG_VALUE$1);
}
function getContentType(input) {
return input.headers.get("content-type")?.split(";")[0];
}
async function authenticatedRequest(as, client, clientAuthentication, url, body, headers, options) {
await clientAuthentication(as, client, body, headers);
headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
return (options?.[customFetch$1] || fetch)(url.href, {
body,
headers: Object.fromEntries(headers.entries()),
method: "POST",
redirect: "manual",
signal: signal$1(url, options?.signal)
});
}
async function tokenEndpointRequest(as, client, clientAuthentication, grantType, parameters, options) {
const url = resolveEndpoint(as, "token_endpoint", client.use_mtls_endpoint_aliases, options?.[allowInsecureRequests$1] !== true);
parameters.set("grant_type", grantType);
const headers = prepareHeaders(options?.headers);
headers.set("accept", "application/json");
if (options?.DPoP !== void 0) {
assertDPoP(options.DPoP);
await options.DPoP.addProof(url, headers, "POST");
}
const response = await authenticatedRequest(as, client, clientAuthentication, url, parameters, headers, options);
options?.DPoP?.cacheNonce(response, url);
return response;
}
async function refreshTokenGrantRequest(as, client, clientAuthentication, refreshToken, options) {
assertAs(as);
assertClient(client);
assertString$1(refreshToken, "\"refreshToken\"");
const parameters = new URLSearchParams(options?.additionalParameters);
parameters.set("refresh_token", refreshToken);
return tokenEndpointRequest(as, client, clientAuthentication, "refresh_token", parameters, options);
}
const idTokenClaims = /* @__PURE__ */ new WeakMap();
const jwtRefs = /* @__PURE__ */ new WeakMap();
function getValidatedIdTokenClaims(ref) {
if (!ref.id_token) return;
const claims = idTokenClaims.get(ref);
if (!claims) throw CodedTypeError$1("\"ref\" was already garbage collected or did not resolve from the proper sources", ERR_INVALID_ARG_VALUE$1);
return claims;
}
async function processGenericAccessTokenResponse(as, client, response, additionalRequiredIdTokenClaims, decryptFn, recognizedTokenTypes) {
assertAs(as);
assertClient(client);
if (!looseInstanceOf(response, Response)) throw CodedTypeError$1("\"response\" must be an instance of Response", ERR_INVALID_ARG_TYPE$1);
await checkOAuthBodyError(response, 200, "Token Endpoint");
assertReadableResponse(response);
const json = await getResponseJsonBody(response);
assertString$1(json.access_token, "\"response\" body \"access_token\" property", INVALID_RESPONSE, { body: json });
assertString$1(json.token_type, "\"response\" body \"token_type\" property", INVALID_RESPONSE, { body: json });
json.token_type = json.token_type.toLowerCase();
if (json.expires_in !== void 0) {
let expiresIn = typeof json.expires_in !== "number" ? parseFloat(json.expires_in) : json.expires_in;
assertNumber(expiresIn, true, "\"response\" body \"expires_in\" property", INVALID_RESPONSE, { body: json });
json.expires_in = expiresIn;
}
if (json.refresh_token !== void 0) assertString$1(json.refresh_token, "\"response\" body \"refresh_token\" property", INVALID_RESPONSE, { body: json });
if (json.scope !== void 0 && typeof json.scope !== "string") throw OPE("\"response\" body \"scope\" property must be a string", INVALID_RESPONSE, { body: json });
if (json.id_token !== void 0) {
assertString$1(json.id_token, "\"response\" body \"id_token\" property", INVALID_RESPONSE, { body: json });
const requiredClaims = [
"aud",
"exp",
"iat",
"iss",
"sub"
];
if (client.require_auth_time === true) requiredClaims.push("auth_time");
if (client.default_max_age !== void 0) {
assertNumber(client.default_max_age, true, "\"client.default_max_age\"");
requiredClaims.push("auth_time");
}
if (additionalRequiredIdTokenClaims?.length) requiredClaims.push(...additionalRequiredIdTokenClaims);
const { claims, jwt } = await validateJwt(json.id_token, checkSigningAlgorithm.bind(void 0, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported, "RS256"), getClockSkew(client), getClockTolerance(client), decryptFn).then(validatePresence.bind(void 0, requiredClaims)).then(validateIssuer.bind(void 0, as)).then(validateAudience.bind(void 0, client.client_id));
if (Array.isArray(claims.aud) && claims.aud.length !== 1) {
if (claims.azp === void 0) throw OPE("ID Token \"aud\" (audience) claim includes additional untrusted audiences", JWT_CLAIM_COMPARISON, {
claims,
claim: "aud"
});
if (claims.azp !== client.client_id) throw OPE("unexpected ID Token \"azp\" (authorized party) claim value", JWT_CLAIM_COMPARISON, {
expected: client.client_id,
claims,
claim: "azp"
});
}
if (claims.auth_time !== void 0) assertNumber(claims.auth_time, true, "ID Token \"auth_time\" (authentication time)", INVALID_RESPONSE, { claims });
jwtRefs.set(response, jwt);
idTokenClaims.set(json, claims);
}
if (recognizedTokenTypes?.[json.token_type] !== void 0) recognizedTokenTypes[json.token_type](response, json);
else if (json.token_type !== "dpop" && json.token_type !== "bearer") throw new UnsupportedOperationError("unsupported `token_type` value", { cause: { body: json } });
return json;
}
function checkAuthenticationChallenges(response) {
let challenges;
if (challenges = parseWwwAuthenticateChallenges(response)) throw new WWWAuthenticateChallengeError("server responded with a challenge in the WWW-Authenticate HTTP Header", {
cause: challenges,
response
});
}
async function processRefreshTokenResponse(as, client, response, options) {
return processGenericAccessTokenResponse(as, client, response, void 0, options?.[jweDecrypt], options?.recognizedTokenTypes);
}
function validateAudience(expected, result) {
if (Array.isArray(result.claims.aud)) {
if (!result.claims.aud.includes(expected)) throw OPE("unexpected JWT \"aud\" (audience) claim value", JWT_CLAIM_COMPARISON, {
expected,
claims: result.claims,
claim: "aud"
});
} else if (result.claims.aud !== expected) throw OPE("unexpected JWT \"aud\" (audience) claim value", JWT_CLAIM_COMPARISON, {
expected,
claims: result.claims,
claim: "aud"
});
return result;
}
function validateIssuer(as, result) {
const expected = as[_expectedIssuer]?.(result) ?? as.issuer;
if (result.claims.iss !== expected) throw OPE("unexpected JWT \"iss\" (issuer) claim value", JWT_CLAIM_COMPARISON, {
expected,
claims: result.claims,
claim: "iss"
});
return result;
}
const branded = /* @__PURE__ */ new WeakSet();
function brand(searchParams) {
branded.add(searchParams);
return searchParams;
}
const nopkce = Symbol();
async function authorizationCodeGrantRequest(as, client, clientAuthentication, callbackParameters, redirectUri, codeVerifier, options) {
assertAs(as);
assertClient(client);
if (!branded.has(callbackParameters)) throw CodedTypeError$1("\"callbackParameters\" must be an instance of URLSearchParams obtained from \"validateAuthResponse()\", or \"validateJwtAuthResponse()", ERR_INVALID_ARG_VALUE$1);
assertString$1(redirectUri, "\"redirectUri\"");
const code = getURLSearchParameter(callbackParameters, "code");
if (!code) throw OPE("no authorization code in \"callbackParameters\"", INVALID_RESPONSE);
const parameters = new URLSearchParams(options?.additionalParameters);
parameters.set("redirect_uri", redirectUri);
parameters.set("code", code);
if (codeVerifier !== nopkce) {
assertString$1(codeVerifier, "\"codeVerifier\"");
parameters.set("code_verifier", codeVerifier);
}
return tokenEndpointRequest(as, client, clientAuthentication, "authorization_code", parameters, options);
}
const jwtClaimNames = {
aud: "audience",
c_hash: "code hash",
client_id: "client id",
exp: "expiration time",
iat: "issued at",
iss: "issuer",
jti: "jwt id",
nonce: "nonce",
s_hash: "state hash",
sub: "subject",
ath: "access token hash",
htm: "http method",
htu: "http uri",
cnf: "confirmation",
auth_time: "authentication time"
};
function validatePresence(required, result) {
for (const claim of required) if (result.claims[claim] === void 0) throw OPE(`JWT "${claim}" (${jwtClaimNames[claim]}) claim missing`, INVALID_RESPONSE, { claims: result.claims });
return result;
}
const expectNoNonce = Symbol();
const skipAuthTimeCheck = Symbol();
async function processAuthorizationCodeResponse(as, client, response, options) {
if (typeof options?.expectedNonce === "string" || typeof options?.maxAge === "number" || options?.requireIdToken) return processAuthorizationCodeOpenIDResponse(as, client, response, options.expectedNonce, options.maxAge, options[jweDecrypt], options.recognizedTokenTypes);
return processAuthorizationCodeOAuth2Response(as, client, response, options?.[jweDecrypt], options?.recognizedTokenTypes);
}
async function processAuthorizationCodeOpenIDResponse(as, client, response, expectedNonce, maxAge, decryptFn, recognizedTokenTypes) {
const additionalRequiredClaims = [];
switch (expectedNonce) {
case void 0:
expectedNonce = expectNoNonce;
break;
case expectNoNonce: break;
default:
assertString$1(expectedNonce, "\"expectedNonce\" argument");
additionalRequiredClaims.push("nonce");
}
maxAge ??= client.default_max_age;
switch (maxAge) {
case void 0:
maxAge = skipAuthTimeCheck;
break;
case skipAuthTimeCheck: break;
default:
assertNumber(maxAge, true, "\"maxAge\" argument");
additionalRequiredClaims.push("auth_time");
}
const result = await processGenericAccessTokenResponse(as, client, response, additionalRequiredClaims, decryptFn, recognizedTokenTypes);
assertString$1(result.id_token, "\"response\" body \"id_token\" property", INVALID_RESPONSE, { body: result });
const claims = getValidatedIdTokenClaims(result);
if (maxAge !== skipAuthTimeCheck) {
const now = epochTime() + getClockSkew(client);
const tolerance = getClockTolerance(client);
if (claims.auth_time + maxAge < now - tolerance) throw OPE("too much time has elapsed since the last End-User authentication", JWT_TIMESTAMP_CHECK, {
claims,
now,
tolerance,
claim: "auth_time"
});
}
if (expectedNonce === expectNoNonce) {
if (claims.nonce !== void 0) throw OPE("unexpected ID Token \"nonce\" claim value", JWT_CLAIM_COMPARISON, {
expected: void 0,
claims,
claim: "nonce"
});
} else if (claims.nonce !== expectedNonce) throw OPE("unexpected ID Token \"nonce\" claim value", JWT_CLAIM_COMPARISON, {
expected: expectedNonce,
claims,
claim: "nonce"
});
return result;
}
async function processAuthorizationCodeOAuth2Response(as, client, response, decryptFn, recognizedTokenTypes) {
const result = await processGenericAccessTokenResponse(as, client, response, void 0, decryptFn, recognizedTokenTypes);
const claims = getValidatedIdTokenClaims(result);
if (claims) {
if (client.default_max_age !== void 0) {
assertNumber(client.default_max_age, true, "\"client.default_max_age\"");
const now = epochTime() + getClockSkew(client);
const tolerance = getClockTolerance(client);
if (claims.auth_time + client.default_max_age < now - tolerance) throw OPE("too much time has elapsed since the last End-User authentication", JWT_TIMESTAMP_CHECK, {
claims,
now,
tolerance,
claim: "auth_time"
});
}
if (claims.nonce !== void 0) throw OPE("unexpected ID Token \"nonce\" claim value", JWT_CLAIM_COMPARISON, {
expected: void 0,
claims,
claim: "nonce"
});
}
return result;
}
const WWW_AUTHENTICATE_CHALLENGE = "OAUTH_WWW_AUTHENTICATE_CHALLENGE";
const RESPONSE_BODY_ERROR = "OAUTH_RESPONSE_BODY_ERROR";
const UNSUPPORTED_OPERATION = "OAUTH_UNSUPPORTED_OPERATION";
const AUTHORIZATION_RESPONSE_ERROR = "OAUTH_AUTHORIZATION_RESPONSE_ERROR";
const PARSE_ERROR = "OAUTH_PARSE_ERROR";
const INVALID_RESPONSE = "OAUTH_INVALID_RESPONSE";
const RESPONSE_IS_NOT_JSON = "OAUTH_RESPONSE_IS_NOT_JSON";
const RESPONSE_IS_NOT_CONFORM = "OAUTH_RESPONSE_IS_NOT_CONFORM";
const HTTP_REQUEST_FORBIDDEN = "OAUTH_HTTP_REQUEST_FORBIDDEN";
const REQUEST_PROTOCOL_FORBIDDEN = "OAUTH_REQUEST_PROTOCOL_FORBIDDEN";
const JWT_TIMESTAMP_CHECK = "OAUTH_JWT_TIMESTAMP_CHECK_FAILED";
const JWT_CLAIM_COMPARISON = "OAUTH_JWT_CLAIM_COMPARISON_FAILED";
const JSON_ATTRIBUTE_COMPARISON = "OAUTH_JSON_ATTRIBUTE_COMPARISON_FAILED";
const MISSING_SERVER_METADATA = "OAUTH_MISSING_SERVER_METADATA";
const INVALID_SERVER_METADATA = "OAUTH_INVALID_SERVER_METADATA";
function assertReadableResponse(response) {
if (response.bodyUsed) throw CodedTypeError$1("\"response\" body has been used already", ERR_INVALID_ARG_VALUE$1);
}
async function validateJwt(jws, checkAlg, clockSkew, clockTolerance, decryptJwt) {
let { 0: protectedHeader, 1: payload, length } = jws.split(".");
if (length === 5) if (decryptJwt !== void 0) {
jws = await decryptJwt(jws);
({0: protectedHeader, 1: payload, length} = jws.split("."));
} else throw new UnsupportedOperationError("JWE decryption is not configured", { cause: jws });
if (length !== 3) throw OPE("Invalid JWT", INVALID_RESPONSE, jws);
let header;
try {
header = JSON.parse(buf(b64u(protectedHeader)));
} catch (cause) {
throw OPE("failed to parse JWT Header body as base64url encoded JSON", PARSE_ERROR, cause);
}
if (!isJsonObject(header)) throw OPE("JWT Header must be a top level object", INVALID_RESPONSE, jws);
checkAlg(header);
if (header.crit !== void 0) throw new UnsupportedOperationError("no JWT \"crit\" header parameter extensions are supported", { cause: { header } });
let claims;
try {
claims = JSON.parse(buf(b64u(payload)));
} catch (cause) {
throw OPE("failed to parse JWT Payload body as base64url encoded JSON", PARSE_ERROR, cause);
}
if (!isJsonObject(claims)) throw OPE("JWT Payload must be a top level object", INVALID_RESPONSE, jws);
const now = epochTime() + clockSkew;
if (claims.exp !== void 0) {
if (typeof claims.exp !== "number") throw OPE("unexpected JWT \"exp\" (expiration time) claim type", INVALID_RESPONSE, { claims });
if (claims.exp <= now - clockTolerance) throw OPE("unexpected JWT \"exp\" (expiration time) claim value, expiration is past current timestamp", JWT_TIMESTAMP_CHECK, {
claims,
now,
tolerance: clockTolerance,
claim: "exp"
});
}
if (claims.iat !== void 0) {
if (typeof claims.iat !== "number") throw OPE("unexpected JWT \"iat\" (issued at) claim type", INVALID_RESPONSE, { claims });
}
if (claims.iss !== void 0) {
if (typeof claims.iss !== "string") throw OPE("unexpected JWT \"iss\" (issuer) claim type", INVALID_RESPONSE, { claims });
}
if (claims.nbf !== void 0) {
if (typeof claims.nbf !== "number") throw OPE("unexpected JWT \"nbf\" (not before) claim type", INVALID_RESPONSE, { claims });
if (claims.nbf > now + clockTolerance) throw OPE("unexpected JWT \"nbf\" (not before) claim value", JWT_TIMESTAMP_CHECK, {
claims,
now,
tolerance: clockTolerance,
claim: "nbf"
});
}
if (claims.aud !== void 0) {
if (typeof claims.aud !== "string" && !Array.isArray(claims.aud)) throw OPE("unexpected JWT \"aud\" (audience) claim type", INVALID_RESPONSE, { claims });
}
return {
header,
claims,
jwt: jws
};
}
async function consumeStream(request) {
if (request.bodyUsed) throw CodedTypeError$1("form_post Request instances must contain a readable body", ERR_INVALID_ARG_VALUE$1, { cause: request });
return request.text();
}
async function formPostResponse(request) {
if (request.method !== "POST") throw CodedTypeError$1("form_post responses are expected to use the POST method", ERR_INVALID_ARG_VALUE$1, { cause: request });
if (getContentType(request) !== "application/x-www-form-urlencoded") throw CodedTypeError$1("form_post responses are expected to use the application/x-www-form-urlencoded content-type", ERR_INVALID_ARG_VALUE$1, { cause: request });
return consumeStream(request);
}
function checkSigningAlgorithm(client, issuer, fallback, header) {
if (client !== void 0) {
if (typeof client === "string" ? header.alg !== client : !client.includes(header.alg)) throw OPE("unexpected JWT \"alg\" header parameter", INVALID_RESPONSE, {
header,
expected: client,
reason: "client configuration"
});
return;
}
if (Array.isArray(issuer)) {
if (!issuer.includes(header.alg)) throw OPE("unexpected JWT \"alg\" header parameter", INVALID_RESPONSE, {
header,
expected: issuer,
reason: "authorization server metadata"
});
return;
}
if (fallback !== void 0) {
if (typeof fallback === "string" ? header.alg !== fallback : typeof fallback === "function" ? !fallback(header.alg) : !fallback.includes(header.alg)) throw OPE("unexpected JWT \"alg\" header parameter", INVALID_RESPONSE, {
header,
expected: fallback,
reason: "default value"
});
return;
}
throw OPE("missing client or server configuration to verify used JWT \"alg\" header parameter", void 0, {
client,
issuer,
fallback
});
}
function getURLSearchParameter(parameters, name) {
const { 0: value, length } = parameters.getAll(name);
if (length > 1) throw OPE(`"${name}" parameter must be provided only once`, INVALID_RESPONSE);
return value;
}
const skipStateCheck = Symbol();
const expectNoState = Symbol();
function validateAuthResponse(as, client, parameters, expectedState) {
assertAs(as);
assertClient(client);
if (parameters instanceof URL) parameters = parameters.searchParams;
if (!(parameters instanceof URLSearchParams)) throw CodedTypeError$1("\"parameters\" must be an instance of URLSearchParams, or URL", ERR_INVALID_ARG_TYPE$1);
if (getURLSearchParameter(parameters, "response")) throw OPE("\"parameters\" contains a JARM response, use validateJwtAuthResponse() instead of validateAuthResponse()", INVALID_RESPONSE, { parameters });
const iss = getURLSearchParameter(parameters, "iss");
const state = getURLSearchParameter(parameters, "state");
if (!iss && as.authorization_response_iss_parameter_supported) throw OPE("response parameter \"iss\" (issuer) missing", INVALID_RESPONSE, { parameters });
if (iss && iss !== as.issuer) throw OPE("unexpected \"iss\" (issuer) response parameter value", INVALID_RESPONSE, {
expected: as.issuer,
parameters
});
switch (expectedState) {
case void 0:
case expectNoState:
if (state !== void 0) throw OPE("unexpected \"state\" response parameter encountered", INVALID_RESPONSE, {
expected: void 0,
parameters
});
break;
case skipStateCheck: break;
default:
assertString$1(expectedState, "\"expectedState\" argument");
if (state !== expectedState) throw OPE(state === void 0 ? "response parameter \"state\" missing" : "unexpected \"state\" response parameter value", INVALID_RESPONSE, {
expected: expectedState,
parameters
});
}
if (getURLSearchParameter(parameters, "error")) throw new AuthorizationResponseError("authorization response from the server is an error", { cause: parameters });
const id_token = getURLSearchParameter(parameters, "id_token");
const token = getURLSearchParameter(parameters, "token");
if (id_token !== void 0 || token !== void 0) throw new UnsupportedOperationError("implicit and hybrid flows are not supported");
return brand(new URLSearchParams(parameters));
}
async function getResponseJsonBody(response, check = assertApplicationJson) {
let json;
try {
json = await response.json();
} catch (cause) {
check(response);
throw OPE("failed to parse \"response\" body as JSON", PARSE_ERROR, cause);
}
if (!isJsonObject(json)) throw OPE("\"response\" body must be a top level object", INVALID_RESPONSE, { body: json });
return json;
}
const _nodiscoverycheck = Symbol();
const _expectedIssuer = Symbol();
//#endregion
//#region ../../../../node_modules/openid-client/build/index.js
let headers;
let USER_AGENT;
if (typeof navigator === "undefined" || !navigator.userAgent?.startsWith?.("Mozilla/5.0 ")) {
USER_AGENT = `openid-client/v6.8.4`;
headers = { "user-agent": USER_AGENT };
}
const int = (config) => {
return props.get(config);
};
let props;
let tbi;
function ClientSecretPost(clientSecret) {
if (clientSecret !== void 0) return ClientSecretPost$1(clientSecret);
tbi ||= /* @__PURE__ */ new WeakMap();
return (as, client, body, headers) => {
let auth;
if (!(auth = tbi.get(client))) {
assertString(client.client_secret, "\"metadata.client_secret\"");
auth = ClientSecretPost$1(client.client_secret);
tbi.set(client, auth);
}
return auth(as, client, body, headers);
};
}
function assertString(input, it) {
if (typeof input !== "string") throw CodedTypeError(`${it} must be a string`, ERR_INVALID_ARG_TYPE);
if (input.length === 0) throw CodedTypeError(`${it} must not be empty`, ERR_INVALID_ARG_VALUE);
}
function None() {
return None$1();
}
const customFetch = customFetch$1;
const ERR_INVALID_ARG_VALUE = "ERR_INVALID_ARG_VALUE";
const ERR_INVALID_ARG_TYPE = "ERR_INVALID_ARG_TYPE";
function CodedTypeError(message, code, cause) {
const err = new TypeError(message, { cause });
Object.assign(err, { code });
return err;
}
function calculatePKCECodeChallenge(codeVerifier) {
return calculatePKCECodeChallenge$1(codeVerifier);
}
function randomPKCECodeVerifier() {
return generateRandomCodeVerifier();
}
function randomState() {
return generateRandomState();
}
var ClientError = class extends Error {
code;
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
this.code = options?.code;
Error.captureStackTrace?.(this, this.constructor);
}
};
new TextDecoder();
function e(msg, cause, code) {
return new ClientError(msg, {
cause,
code
});
}
function errorHandler(err) {
if (err instanceof TypeError || err instanceof ClientError || err instanceof ResponseBodyError || err instanceof AuthorizationResponseError || err instanceof WWWAuthenticateChallengeError) throw err;
if (err instanceof OperationProcessingError) switch (err.code) {
case HTTP_REQUEST_FORBIDDEN: throw e("only requests to HTTPS are allowed", err, err.code);
case REQUEST_PROTOCOL_FORBIDDEN: throw e("only requests to HTTP or HTTPS are allowed", err, err.code);
case RESPONSE_IS_NOT_CONFORM: throw e("unexpected HTTP response status code", err.cause, err.code);
case RESPONSE_IS_NOT_JSON: throw e("unexpected response content-type", err.cause, err.code);
case PARSE_ERROR: throw e("parsing error occured", err, err.code);
case INVALID_RESPONSE: throw e("invalid response encountered", err, err.code);
case JWT_CLAIM_COMPARISON: throw e("unexpected JWT claim value encountered", err, err.code);
case JSON_ATTRIBUTE_COMPARISON: throw e("unexpected JSON attribute value encountered", err, err.code);
case JWT_TIMESTAMP_CHECK: throw e("JWT timestamp claim value failed validation", err, err.code);
default: throw e(err.message, err, err.code);
}
if (err instanceof UnsupportedOperationError) throw e("unsupported operation", err, err.code);
if (err instanceof DOMException) switch (err.name) {
case "OperationError": throw e("runtime operation error", err, UNSUPPORTED_OPERATION);
case "NotSupportedError": throw e("runtime unsupported operation", err, UNSUPPORTED_OPERATION);
case "TimeoutError": throw e("operation timed out", err, "OAUTH_TIMEOUT");
case "AbortError": throw e("operation aborted", err, "OAUTH_ABORT");
}
throw new ClientError("something went wrong", { cause: err });
}
function handleEntraId(server, as, options) {
if (server.origin === "https://login.microsoftonline.com" && (!options?.algorithm || options.algorithm === "oidc")) {
as[kEntraId] = true;
return true;
}
return false;
}
function handleB2Clogin(server, options) {
if (server.hostname.endsWith(".b2clogin.com") && (!options?.algorithm || options.algorithm === "oidc")) return true;
return false;
}
async function discovery(server, clientId, metadata, clientAuthentication, options) {
const instance = new Configuration(await performDiscovery(server, options), clientId, metadata, clientAuthentication);
let internals = int(instance);
if (options?.[customFetch]) internals.fetch = options[customFetch];
if (options?.timeout) internals.timeout = options.timeout;
if (options?.execute) for (const extension of options.execute) extension(instance);
return instance;
}
async function performDiscovery(server, options) {
if (!(server instanceof URL)) throw CodedTypeError("\"server\" must be an instance of URL", ERR_INVALID_ARG_TYPE);
const resolve = !server.href.includes("/.well-known/");
const timeout = options?.timeout ?? 30;
const signal = AbortSignal.timeout(timeout * 1e3);
const as = await (resolve ? discoveryRequest(server, {
algorithm: options?.algorithm,
[customFetch$1]: options?.[customFetch],
[allowInsecureRequests$1]: options?.execute?.includes(allowInsecureRequests),
signal,
headers: new Headers(headers)
}) : (options?.[customFetch] || fetch)((() => {
checkProtocol(server, options?.execute?.includes(allowInsecureRequests) ? false : true);
return server.href;
})(), {
headers: Object.fromEntries(new Headers({
accept: "application/json",
...headers
}).entries()),
body: void 0,
method: "GET",
redirect: "manual",
signal
})).then((response) => processDiscoveryResponse(_nodiscoverycheck, response)).catch(errorHandler);
if (resolve && new URL(as.issuer).href !== server.href) handleEntraId(server, as, options) || handleB2Clogin(server, options) || (() => {
throw new ClientError("discovered metadata issuer does not match the expected issuer", {
code: "OAUTH_JSON_ATTRIBUTE_COMPARISON_FAILED",
cause: {
expected: server.href,
body: as,
attribute: "issuer"
}
});
})();
return as;
}
function getServerHelpers(metadata) {
return { supportsPKCE: {
__proto__: null,
value(method = "S256") {
return metadata.code_challenge_methods_supported?.includes(method) === true;
}
} };
}
function addServerHelpers(metadata) {
Object.defineProperties(metadata, getServerHelpers(metadata));
}
const kEntraId = Symbol();
var Configuration = class {
constructor(server, clientId, metadata, clientAuthentication) {
if (typeof clientId !== "string" || !clientId.length) throw CodedTypeError("\"clientId\" must be a non-empty string", ERR_INVALID_ARG_TYPE);
if (typeof metadata === "string") metadata = { client_secret: metadata };
if (metadata?.client_id !== void 0 && clientId !== metadata.client_id) throw CodedTypeError("\"clientId\" and \"metadata.client_id\" must be the same", ERR_INVALID_ARG_VALUE);
const client = {
...structuredClone(metadata),
client_id: clientId
};
client[clockSkew] = metadata?.[clockSkew] ?? 0;
client[clockTolerance] = metadata?.[clockTolerance] ?? 30;
let auth;
if (clientAuthentication) auth = clientAuthentication;
else if (typeof client.client_secret === "string" && client.client_secret.length) auth = ClientSecretPost(client.client_secret);
else auth = None();
let c = Object.freeze(client);
const clone = structuredClone(server);
if (kEntraId in server) clone[_expectedIssuer] = ({ claims: { tid } }) => server.issuer.replace("{tenantid}", tid);
let as = Object.freeze(clone);
props ||= /* @__PURE__ */ new WeakMap();
props.set(this, {
__proto__: null,
as,
c,
auth,
tlsOnly: true,
jwksCache: {}
});
}
serverMetadata() {
const metadata = structuredClone(int(this).as);
addServerHelpers(metadata);
return metadata;
}
clientMetadata() {
return structuredClone(int(this).c);
}
get timeout() {
return int(this).timeout;
}
set timeout(value) {
int(this).timeout = value;
}
get [customFetch]() {
return int(this).fetch;
}
set [customFetch](value) {
int(this).fetch = value;
}
};
Object.freeze(Configuration.prototype);
function getHelpers(response) {
let exp = void 0;
if (response.expires_in !== void 0) {
const now = /* @__PURE__ */ new Date();
now.setSeconds(now.getSeconds() + response.expires_in);
exp = now.getTime();
}
return {
expiresIn: {
__proto__: null,
value() {
if (exp) {
const now = Date.now();
if (exp > now) return Math.floor((exp - now) / 1e3);
return 0;
}
}
},
claims: {
__proto__: null,
value() {
try {
return getValidatedIdTokenClaims(this);
} catch {
return;
}
}
}
};
}
function addHelpers(response) {
Object.defineProperties(response, getHelpers(response));
}
function allowInsecureRequests(config) {
int(config).tlsOnly = false;
}
function stripParams(url) {
url = new URL(url);
url.search = "";
url.hash = "";
return url.href;
}
function webInstanceOf(input, toStringTag) {
try {
return Object.getPrototypeOf(input)[Symbol.toStringTag] === toStringTag;
} catch {
return false;
}
}
async function authorizationCodeGrant(config, currentUrl, checks, tokenEndpointParameters, options) {
checkConfig(config);
if (options?.flag !== retry && !(currentUrl instanceof URL) && !webInstanceOf(currentUrl, "Request")) throw CodedTypeError("\"currentUrl\" must be an instance of URL, or Request", ERR_INVALID_ARG_TYPE);
let authResponse;
let redirectUri;
const { as, c, auth, fetch, tlsOnly, jarm, hybrid, nonRepudiation, timeout, decrypt, implicit } = int(config);
if (options?.flag === retry) {
authResponse = options.authResponse;
redirectUri = options.redirectUri;
} else {
if (!(currentUrl instanceof URL)) {
const request = currentUrl;
currentUrl = new URL(currentUrl.url);
switch (request.method) {
case "GET": break;
case "POST":
const params = new URLSearchParams(await formPostResponse(request));
if (hybrid) currentUrl.hash = params.toString();
else for (const [k, v] of params.entries()) currentUrl.searchParams.append(k, v);
break;
default: throw CodedTypeError("unexpected Request HTTP method", ERR_INVALID_ARG_VALUE);
}
}
redirectUri = stripParams(currentUrl);
switch (true) {
case !!jarm:
authResponse = await jarm(currentUrl, checks?.expectedState);
break;
case !!hybrid:
authResponse = await hybrid(currentUrl, checks?.expectedNonce, checks?.expectedState, checks?.maxAge);
break;
case !!implicit: throw new TypeError("authorizationCodeGrant() cannot be used by response_type=id_token clients");
default: try {
authResponse = validateAuthResponse(as, c, currentUrl.searchParams, checks?.expectedState);
} catch (err) {
errorHandler(err);
}
}
}
const response = await authorizationCodeGrantRequest(as, c, auth, authResponse, redirectUri, checks?.pkceCodeVerifier || nopkce, {
additionalParameters: tokenEndpointParameters,
[customFetch$1]: fetch,
[allowInsecureRequests$1]: !tlsOnly,
DPoP: options?.DPoP,
headers: new Headers(headers),
signal: signal(timeout)
}).catch(errorHandler);
if (typeof checks?.expectedNonce === "string" || typeof checks?.maxAge === "number") checks.idTokenExpected = true;
const p = processAuthorizationCodeResponse(as, c, response, {
expectedNonce: checks?.expectedNonce,
maxAge: checks?.maxAge,
requireIdToken: checks?.idTokenExpected,
[jweDecrypt]: decrypt
});
let result;
try {
result = await p;
} catch (err) {
if (retryable(err, options)) return authorizationCodeGrant(config, void 0, checks, tokenEndpointParameters, {
...options,
flag: retry,
authResponse,
redirectUri
});
errorHandler(err);
}
result.id_token && await nonRepudiation?.(response);
addHelpers(result);
return result;
}
async function refreshTokenGrant(config, refreshToken, parameters, options) {
checkConfig(config);
parameters = new URLSearchParams(parameters);
const { as, c, auth, fetch, tlsOnly, nonRepudiation, timeout, decrypt } = int(config);
const response = await refreshTokenGrantRequest(as, c, auth, refreshToken, {
[customFetch$1]: fetch,
[allowInsecureRequests$1]: !tlsOnly,
additionalParameters: parameters,
DPoP: options?.DPoP,
headers: new Headers(headers),
signal: signal(timeout)
}).catch(errorHandler);
const p = processRefreshTokenResponse(as, c, response, { [jweDecrypt]: decrypt });
let result;
try {
result = await p;
} catch (err) {
if (retryable(err, options)) return refreshTokenGrant(config, refreshToken, parameters, {
...options,
flag: retry
});
errorHandler(err);
}
result.id_token && await nonRepudiation?.(response);
addHelpers(result);
return result;
}
function buildAuthorizationUrl(config, parameters) {
checkConfig(config);
const { as, c, tlsOnly, hybrid, jarm, implicit } = int(config);
const authorizationEndpoint = resolveEndpoint(as, "authorization_endpoint", false, tlsOnly);
parameters = new URLSearchParams(parameters);
if (!parameters.has("client_id")) parameters.set("client_id", c.client_id);
if (!parameters.has("request_uri") && !parameters.has("request")) {
if (!parameters.has("response_type")) parameters.set("response_type", hybrid ? "code id_token" : implicit ? "id_token" : "code");
if (implicit && !parameters.has("nonce")) throw CodedTypeError("response_type=id_token clients must provide a nonce parameter in their authorization request parameters", ERR_INVALID_ARG_VALUE);
if (jarm) parameters.set("response_mode", "jwt");
}
for (const [k, v] of parameters.entries()) authorizationEndpoint.searchParams.append(k, v);
return authorizationEndpoint;
}
function buildEndSessionUrl(config, parameters) {
checkConfig(config);
const { as, c, tlsOnly } = int(config);
const endSessionEndpoint = resolveEndpoint(as, "end_session_endpoint", false, tlsOnly);
parameters = new URLSearchParams(parameters);
if (!parameters.has("client_id")) parameters.set("client_id", c.client_i