@sphereon/oid4vci-client
Version:
OpenID for Verifiable Credential Issuance (OpenID4VCI) client
1,151 lines (1,134 loc) • 136 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// lib/index.ts
var index_exports = {};
__export(index_exports, {
AccessTokenClient: () => AccessTokenClient,
CredentialOfferClient: () => CredentialOfferClient,
CredentialOfferClientV1_0_15: () => CredentialOfferClientV1_0_15,
CredentialRequestClient: () => CredentialRequestClient,
CredentialRequestClientBuilder: () => CredentialRequestClientBuilder,
CredentialRequestClientBuilderV1_0_15: () => CredentialRequestClientBuilderV1_0_15,
LOG: () => LOG2,
MetadataClient: () => MetadataClient,
MetadataClientV1_0_15: () => MetadataClientV1_0_15,
OpenID4VCIClient: () => OpenID4VCIClient,
OpenID4VCIClientV1_0_15: () => OpenID4VCIClientV1_0_15,
ProofOfPossessionBuilder: () => ProofOfPossessionBuilder,
acquireAuthorizationChallengeAuthCode: () => acquireAuthorizationChallengeAuthCode,
acquireAuthorizationChallengeAuthCodeUsingRequest: () => acquireAuthorizationChallengeAuthCodeUsingRequest,
buildProof: () => buildProof,
constructBaseResponse: () => constructBaseResponse,
createAuthorizationChallengeRequest: () => createAuthorizationChallengeRequest,
createAuthorizationRequestUrl: () => createAuthorizationRequestUrl,
createJwtBearerClientAssertion: () => createJwtBearerClientAssertion,
createSignedAuthRequestWhenNeeded: () => createSignedAuthRequestWhenNeeded,
generateMissingPKCEOpts: () => generateMissingPKCEOpts,
handleCredentialOfferUri: () => handleCredentialOfferUri,
isUriEncoded: () => isUriEncoded,
retrieveWellknown: () => retrieveWellknown,
sendAuthorizationChallengeRequest: () => sendAuthorizationChallengeRequest,
sendNotification: () => sendNotification
});
module.exports = __toCommonJS(index_exports);
var import_oid4vci_common20 = require("@sphereon/oid4vci-common");
// lib/AccessTokenClient.ts
var import_oid4vc_common3 = require("@sphereon/oid4vc-common");
var import_oid4vci_common9 = require("@sphereon/oid4vci-common");
var import_ssi_types4 = require("@sphereon/ssi-types");
// lib/functions/AuthorizationUtil.ts
var import_oid4vci_common = require("@sphereon/oid4vci-common");
var generateMissingPKCEOpts = /* @__PURE__ */ __name((pkce) => {
if (pkce.disabled) {
return pkce;
}
if (!pkce.codeChallengeMethod) {
pkce.codeChallengeMethod = import_oid4vci_common.CodeChallengeMethod.S256;
}
if (!pkce.codeVerifier) {
pkce.codeVerifier = (0, import_oid4vci_common.generateCodeVerifier)();
}
(0, import_oid4vci_common.assertValidCodeVerifier)(pkce.codeVerifier);
if (!pkce.codeChallenge) {
pkce.codeChallenge = (0, import_oid4vci_common.createCodeChallenge)(pkce.codeVerifier, pkce.codeChallengeMethod);
}
return pkce;
}, "generateMissingPKCEOpts");
// lib/functions/notifications.ts
var import_oid4vci_common3 = require("@sphereon/oid4vci-common");
// lib/types/index.ts
var import_oid4vci_common2 = require("@sphereon/oid4vci-common");
var import_ssi_types = require("@sphereon/ssi-types");
var LOG = import_oid4vci_common2.VCI_LOGGERS.options("sphereon:oid4vci:client", {
methods: [
import_ssi_types.LogMethod.EVENT,
import_ssi_types.LogMethod.DEBUG_PKG
]
}).get("sphereon:oid4vci:client");
// lib/functions/notifications.ts
async function sendNotification(credentialRequestOpts, request, accessToken) {
LOG.info(`Sending status notification event '${request.event}' for id ${request.notification_id}`);
if (!credentialRequestOpts.notificationEndpoint) {
throw Error(`Cannot send notification when no notification endpoint is provided`);
}
const token = accessToken ?? credentialRequestOpts.token;
const response = await (0, import_oid4vci_common3.post)(credentialRequestOpts.notificationEndpoint, JSON.stringify(request), {
...token && {
bearerToken: token
}
});
const error = response.errorBody?.error !== void 0;
const result = {
error,
response: error ? response.errorBody : void 0
};
if (error) {
LOG.warning(`Notification endpoint returned an error for event '${request.event}' and id ${request.notification_id}: ${response.errorBody}`);
} else {
LOG.debug(`Notification endpoint returned success for event '${request.event}' and id ${request.notification_id}`);
}
return result;
}
__name(sendNotification, "sendNotification");
// lib/functions/OpenIDUtils.ts
var import_oid4vci_common4 = require("@sphereon/oid4vci-common");
var import_ssi_types2 = require("@sphereon/ssi-types");
var logger = import_ssi_types2.Loggers.DEFAULT.get("sphereon:openid4vci:openid-utils");
var retrieveWellknown = /* @__PURE__ */ __name(async (host, endpointType, opts) => {
const result = await (0, import_oid4vci_common4.getJson)(`${host.endsWith("/") ? host.slice(0, -1) : host}${endpointType}`, {
exceptionOnHttpErrorStatus: opts?.errorOnNotFound
});
if (result.origResponse.status >= 400) {
logger.debug(`host ${host} with endpoint type ${endpointType} status: ${result.origResponse.status}, ${result.origResponse.statusText}`);
}
return result;
}, "retrieveWellknown");
// lib/functions/AccessTokenUtil.ts
var import_oid4vc_common = require("@sphereon/oid4vc-common");
var import_oid4vci_common6 = require("@sphereon/oid4vci-common");
// lib/ProofOfPossessionBuilder.ts
var import_oid4vci_common5 = require("@sphereon/oid4vci-common");
var ProofOfPossessionBuilder = class _ProofOfPossessionBuilder {
static {
__name(this, "ProofOfPossessionBuilder");
}
proof;
callbacks;
// private readonly version: OpenId4VCIVersion
mode = "pop";
kid;
jwk;
aud;
clientId;
issuer;
jwt;
alg;
jti;
cNonce;
typ;
constructor({ proof, callbacks, jwt, accessTokenResponse, version, mode = "pop" }) {
this.mode = mode;
this.proof = proof;
this.callbacks = callbacks;
if (jwt) {
this.withJwt(jwt);
} else {
this.withTyp(mode === "JWT" ? "JWT" : "openid4vci-proof+jwt");
}
if (accessTokenResponse) {
this.withAccessTokenResponse(accessTokenResponse);
}
}
static manual({ jwt, callbacks, version, mode = "JWT" }) {
return new _ProofOfPossessionBuilder({
callbacks,
jwt,
version,
mode
});
}
static fromJwt({ jwt, callbacks, version, mode = "pop" }) {
return new _ProofOfPossessionBuilder({
callbacks,
jwt,
version,
mode
});
}
static fromAccessTokenResponse({ accessTokenResponse, callbacks, version, mode = "pop" }) {
return new _ProofOfPossessionBuilder({
callbacks,
accessTokenResponse,
version,
mode
});
}
static fromProof(proof, version) {
return new _ProofOfPossessionBuilder({
proof,
version
});
}
withAud(aud) {
this.aud = aud;
return this;
}
withClientId(clientId) {
this.clientId = clientId;
return this;
}
withKid(kid) {
this.kid = kid;
return this;
}
withJWK(jwk) {
this.jwk = jwk;
return this;
}
withIssuer(issuer) {
this.issuer = issuer;
return this;
}
withAlg(alg) {
this.alg = alg;
return this;
}
withJti(jti) {
this.jti = jti;
return this;
}
withTyp(typ) {
if (this.mode === "pop") {
if (!!typ && typ !== "openid4vci-proof+jwt") {
throw Error(`typ must be openid4vci-proof+jwt for version 1.0.11 and up. Provided: ${typ}`);
}
} else {
if (!!typ && typ !== "JWT") {
throw Error(`typ must be jwt for version 1.0.10 and below. Provided: ${typ}`);
}
}
this.typ = typ;
return this;
}
withAccessTokenNonce(cNonce) {
this.cNonce = cNonce;
return this;
}
withAccessTokenResponse(accessToken) {
if (accessToken.c_nonce) {
this.withAccessTokenNonce(accessToken.c_nonce);
}
return this;
}
withEndpointMetadata(endpointMetadata) {
this.withIssuer(endpointMetadata.issuer);
return this;
}
withJwt(jwt) {
if (!jwt) {
throw new Error(import_oid4vci_common5.NO_JWT_PROVIDED);
}
this.jwt = jwt;
if (!jwt.header) {
throw Error(`No JWT header present`);
} else if (!jwt.payload) {
throw Error(`No JWT payload present`);
}
if (jwt.header.kid) {
this.withKid(jwt.header.kid);
}
if (jwt.header.typ) {
this.withTyp(jwt.header.typ);
}
if (!this.typ) {
this.withTyp("openid4vci-proof+jwt");
}
this.withAlg(jwt.header.alg);
if (Array.isArray(jwt.payload.aud)) {
throw Error("We cannot handle multiple aud values currently");
}
if (jwt.payload) {
if (jwt.payload.iss) this.mode === "pop" ? this.withClientId(jwt.payload.iss) : this.withIssuer(jwt.payload.iss);
if (jwt.payload.aud) this.mode === "pop" ? this.withIssuer(jwt.payload.aud) : this.withAud(jwt.payload.aud);
if (jwt.payload.jti) this.withJti(jwt.payload.jti);
if (jwt.payload.nonce) this.withAccessTokenNonce(jwt.payload.nonce);
}
return this;
}
async build() {
if (this.proof) {
return Promise.resolve(this.proof);
} else if (this.callbacks) {
return await (0, import_oid4vci_common5.createProofOfPossession)(this.mode, this.callbacks, {
typ: this.typ ?? (this.mode === "JWT" ? "JWT" : "openid4vci-proof+jwt"),
kid: this.kid,
jwk: this.jwk,
jti: this.jti,
alg: this.alg,
aud: this.aud,
issuer: this.issuer,
clientId: this.clientId,
...this.cNonce && {
nonce: this.cNonce
}
}, this.jwt);
}
throw new Error(import_oid4vci_common5.PROOF_CANT_BE_CONSTRUCTED);
}
};
// lib/functions/AccessTokenUtil.ts
var createJwtBearerClientAssertion = /* @__PURE__ */ __name(async (request, opts) => {
const { asOpts, credentialIssuer } = opts;
if (asOpts?.clientOpts?.clientAssertionType === "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") {
const { clientId = request.client_id, signCallbacks, alg } = asOpts.clientOpts;
let { kid } = asOpts.clientOpts;
if (!clientId) {
return Promise.reject(Error(`Not client_id supplied, but client-assertion jwt-bearer requested.`));
} else if (!kid) {
return Promise.reject(Error(`No kid supplied, but client-assertion jwt-bearer requested.`));
} else if (typeof signCallbacks?.signCallback !== "function") {
return Promise.reject(Error(`No sign callback supplied, but client-assertion jwt-bearer requested.`));
} else if (!credentialIssuer) {
return Promise.reject(Error(`No credential issuer supplied, but client-assertion jwt-bearer requested.`));
}
if (clientId.startsWith("http") && kid.includes("#")) {
kid = kid.split("#")[1];
}
const jwt = {
header: {
typ: "JWT",
kid,
alg: alg ?? "ES256"
},
payload: {
iss: clientId,
sub: clientId,
aud: credentialIssuer,
jti: (0, import_oid4vc_common.uuidv4)(),
exp: Math.floor(Date.now()) / 1e3 + 60,
iat: Math.floor(Date.now()) / 1e3 - 60
}
};
const pop = await ProofOfPossessionBuilder.fromJwt({
jwt,
callbacks: signCallbacks,
version: opts.version ?? import_oid4vci_common6.OpenId4VCIVersion.VER_1_0_15,
mode: "JWT"
}).build();
request.client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
request.client_assertion = pop.jwt;
}
}, "createJwtBearerClientAssertion");
// lib/functions/CredentialOfferCommons.ts
var import_oid4vci_common7 = require("@sphereon/oid4vci-common");
var import_cross_fetch = __toESM(require("cross-fetch"), 1);
function isUriEncoded(str) {
const pattern = /%[0-9A-F]{2}/i;
return pattern.test(str);
}
__name(isUriEncoded, "isUriEncoded");
async function handleCredentialOfferUri(uri) {
const uriObj = (0, import_oid4vci_common7.getURIComponentsAsArray)(uri);
const credentialOfferUri = decodeURIComponent(uriObj["credential_offer_uri"]);
const decodedUri = isUriEncoded(credentialOfferUri) ? decodeURIComponent(credentialOfferUri) : credentialOfferUri;
const response = await (0, import_cross_fetch.default)(decodedUri);
if (!(response && response.status >= 200 && response.status < 400)) {
return Promise.reject(Error(`the credential offer URI endpoint call was not successful. http code ${response.status} - reason ${response.statusText}`));
}
if (response.headers.get("Content-Type")?.startsWith("application/json") === false) {
return Promise.reject(Error("the credential offer URI endpoint did not return content type application/json"));
}
return {
credential_offer: (0, import_oid4vci_common7.decodeJsonProperties)(await response.json())
};
}
__name(handleCredentialOfferUri, "handleCredentialOfferUri");
function constructBaseResponse(request, scheme, baseUrl) {
const clientId = (0, import_oid4vci_common7.getClientIdFromCredentialOfferPayload)(request.credential_offer);
const grants = request.credential_offer?.grants;
return {
scheme,
baseUrl,
...clientId && {
clientId
},
...request,
...grants?.authorization_code?.issuer_state && {
issuerState: grants.authorization_code.issuer_state
},
...grants?.[import_oid4vci_common7.PRE_AUTH_GRANT_LITERAL]?.[import_oid4vci_common7.PRE_AUTH_CODE_LITERAL] && {
preAuthorizedCode: grants[import_oid4vci_common7.PRE_AUTH_GRANT_LITERAL][import_oid4vci_common7.PRE_AUTH_CODE_LITERAL]
},
...request.credential_offer?.grants?.[import_oid4vci_common7.PRE_AUTH_GRANT_LITERAL]?.tx_code && {
txCode: request.credential_offer.grants[import_oid4vci_common7.PRE_AUTH_GRANT_LITERAL].tx_code
}
};
}
__name(constructBaseResponse, "constructBaseResponse");
// lib/functions/dpopUtil.ts
var import_oid4vc_common2 = require("@sphereon/oid4vc-common");
function shouldRetryTokenRequestWithDPoPNonce(response) {
if (!response.errorBody || response.errorBody.error !== import_oid4vc_common2.dpopTokenRequestNonceError) {
return {
ok: false
};
}
const dPoPNonce = response.origResponse.headers.get("DPoP-Nonce");
if (!dPoPNonce) {
throw new Error("Missing required DPoP-Nonce header.");
}
return {
ok: true,
dpopNonce: dPoPNonce
};
}
__name(shouldRetryTokenRequestWithDPoPNonce, "shouldRetryTokenRequestWithDPoPNonce");
function shouldRetryResourceRequestWithDPoPNonce(response) {
if (!response.errorBody || response.origResponse.status !== 401) {
return {
ok: false
};
}
const wwwAuthenticateHeader = response.origResponse.headers.get("WWW-Authenticate");
if (!wwwAuthenticateHeader?.includes(import_oid4vc_common2.dpopTokenRequestNonceError)) {
return {
ok: false
};
}
const dPoPNonce = response.origResponse.headers.get("DPoP-Nonce");
if (!dPoPNonce) {
throw new Error("Missing required DPoP-Nonce header.");
}
return {
ok: true,
dpopNonce: dPoPNonce
};
}
__name(shouldRetryResourceRequestWithDPoPNonce, "shouldRetryResourceRequestWithDPoPNonce");
// lib/MetadataClientV1_0_15.ts
var import_oid4vci_common8 = require("@sphereon/oid4vci-common");
var import_ssi_types3 = require("@sphereon/ssi-types");
var logger2 = import_ssi_types3.Loggers.DEFAULT.get("sphereon:oid4vci:metadata");
var MetadataClientV1_0_15 = class _MetadataClientV1_0_15 {
static {
__name(this, "MetadataClientV1_0_15");
}
/**
* Retrieve metadata using the Initiation obtained from a previous step
*
* @param credentialOffer
*/
static async retrieveAllMetadataFromCredentialOffer(credentialOffer) {
return _MetadataClientV1_0_15.retrieveAllMetadataFromCredentialOfferRequest(credentialOffer.credential_offer);
}
/**
* Retrieve the metada using the initiation request obtained from a previous step
* @param request
*/
static async retrieveAllMetadataFromCredentialOfferRequest(request) {
const issuer = (0, import_oid4vci_common8.getIssuerFromCredentialOfferPayload)(request);
if (issuer) {
return _MetadataClientV1_0_15.retrieveAllMetadata(issuer);
}
throw new Error("can't retrieve metadata from CredentialOfferRequest. No issuer field is present");
}
/**
* Retrieve all metadata from an issuer
* @param issuer The issuer URL
* @param opts
*/
static async retrieveAllMetadata(issuer, opts) {
let token_endpoint;
let credential_endpoint;
let nonce_endpoint;
let deferred_credential_endpoint;
let notification_endpoint;
let authorization_endpoint;
let authorization_challenge_endpoint;
let authorizationServerType = "OID4VCI";
let authorization_servers = [
issuer
];
const oid4vciResponse = await _MetadataClientV1_0_15.retrieveOpenID4VCIServerMetadata(issuer, {
errorOnNotFound: false
});
let credentialIssuerMetadata = oid4vciResponse?.successBody;
if (credentialIssuerMetadata) {
logger2.debug(`Issuer ${issuer} OID4VCI well-known server metadata\r
${JSON.stringify(credentialIssuerMetadata)}`);
credential_endpoint = credentialIssuerMetadata.credential_endpoint;
nonce_endpoint = credentialIssuerMetadata.nonce_endpoint;
deferred_credential_endpoint = credentialIssuerMetadata.deferred_credential_endpoint;
notification_endpoint = credentialIssuerMetadata.notification_endpoint;
if (credentialIssuerMetadata.token_endpoint) {
token_endpoint = credentialIssuerMetadata.token_endpoint;
}
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
if (credentialIssuerMetadata.authorization_servers) {
authorization_servers = credentialIssuerMetadata.authorization_servers;
}
}
let response = await retrieveWellknown(authorization_servers[0], import_oid4vci_common8.WellKnownEndpoints.OPENID_CONFIGURATION, {
errorOnNotFound: false
});
let authMetadata = response.successBody;
if (authMetadata) {
logger2.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
authorizationServerType = "OIDC";
} else {
response = await retrieveWellknown(authorization_servers[0], import_oid4vci_common8.WellKnownEndpoints.OAUTH_AS, {
errorOnNotFound: false
});
authMetadata = response.successBody;
}
if (!authMetadata) {
if (!authorization_servers.includes(issuer)) {
throw Error(`Issuer ${issuer} provided a separate authorization server ${authorization_servers}, but that server did not provide metadata`);
}
} else {
logger2.debug(`Issuer ${issuer} has ${authorizationServerType} Server metadata in well-known location`);
if (!authMetadata.authorization_endpoint) {
console.warn(`Issuer ${issuer} of type ${authorizationServerType} has no authorization_endpoint! Will use ${authorization_endpoint}. This only works for pre-authorized flows`);
} else if (authorization_endpoint && authMetadata.authorization_endpoint !== authorization_endpoint) {
throw Error(`Credential issuer has a different authorization_endpoint (${authorization_endpoint}) from the Authorization Server (${authMetadata.authorization_endpoint})`);
}
authorization_endpoint = authMetadata.authorization_endpoint;
if (authorization_challenge_endpoint && authMetadata.authorization_challenge_endpoint !== authorization_challenge_endpoint) {
throw Error(`Credential issuer has a different authorization_challenge_endpoint (${authorization_challenge_endpoint}) from the Authorization Server (${authMetadata.authorization_challenge_endpoint})`);
}
authorization_challenge_endpoint = authMetadata.authorization_challenge_endpoint;
if (!authMetadata.token_endpoint) {
throw Error(`Authorization Server ${authorization_servers} did not provide a token_endpoint`);
} else if (token_endpoint && authMetadata.token_endpoint !== token_endpoint) {
throw Error(`Credential issuer has a different token_endpoint (${token_endpoint}) from the Authorization Server (${authMetadata.token_endpoint})`);
}
token_endpoint = authMetadata.token_endpoint;
if (authMetadata.credential_endpoint) {
if (credential_endpoint && authMetadata.credential_endpoint !== credential_endpoint) {
logger2.debug(`Credential issuer has a different credential_endpoint (${credential_endpoint}) from the Authorization Server (${authMetadata.credential_endpoint}). Will use the issuer value`);
} else {
credential_endpoint = authMetadata.credential_endpoint;
}
}
if (authMetadata.deferred_credential_endpoint) {
if (deferred_credential_endpoint && authMetadata.deferred_credential_endpoint !== deferred_credential_endpoint) {
logger2.debug(`Credential issuer has a different deferred_credential_endpoint (${deferred_credential_endpoint}) from the Authorization Server (${authMetadata.deferred_credential_endpoint}). Will use the issuer value`);
} else {
deferred_credential_endpoint = authMetadata.deferred_credential_endpoint;
}
}
if (authMetadata.notification_endpoint) {
if (notification_endpoint && authMetadata.notification_endpoint !== notification_endpoint) {
logger2.debug(`Credential issuer has a different notification_endpoint (${notification_endpoint}) from the Authorization Server (${authMetadata.notification_endpoint}). Will use the issuer value`);
} else {
notification_endpoint = authMetadata.notification_endpoint;
}
}
}
if (!authorization_endpoint) {
logger2.debug(`Issuer ${issuer} does not expose authorization_endpoint, so only pre-auth will be supported`);
}
if (!token_endpoint) {
logger2.debug(`Issuer ${issuer} does not have a token_endpoint listed in well-known locations!`);
if (opts?.errorOnNotFound) {
throw Error(`Could not deduce the token_endpoint for ${issuer}`);
} else {
token_endpoint = `${issuer}${issuer.endsWith("/") ? "token" : "/token"}`;
}
}
if (!credential_endpoint) {
logger2.debug(`Issuer ${issuer} does not have a credential_endpoint listed in well-known locations!`);
if (opts?.errorOnNotFound) {
throw Error(`Could not deduce the credential endpoint for ${issuer}`);
} else {
credential_endpoint = `${issuer}${issuer.endsWith("/") ? "credential" : "/credential"}`;
}
}
if (!credentialIssuerMetadata && authMetadata) {
credentialIssuerMetadata = authMetadata;
}
const ci = credentialIssuerMetadata ?? {};
const ciAuthorizationServers = Array.isArray(ci.authorization_servers) && ci.authorization_servers.length > 0 ? ci.authorization_servers : authorization_servers;
const v15CredentialIssuerMetadata = {
credential_issuer: ci.credential_issuer ?? issuer,
credential_endpoint,
authorization_servers: ciAuthorizationServers,
credential_configurations_supported: ci.credential_configurations_supported ?? {},
display: ci.display ?? [],
...nonce_endpoint && {
nonce_endpoint
},
...deferred_credential_endpoint && {
deferred_credential_endpoint
},
...notification_endpoint && {
notification_endpoint
}
};
logger2.debug(`Issuer ${issuer} token endpoint ${token_endpoint}, credential endpoint ${credential_endpoint}`);
return {
issuer,
token_endpoint,
credential_endpoint,
authorization_challenge_endpoint,
notification_endpoint,
authorizationServerType,
credentialIssuerMetadata: v15CredentialIssuerMetadata,
authorizationServerMetadata: authMetadata
};
}
/**
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
*
* @param issuerHost The issuer hostname
* @param opts
*/
static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
return retrieveWellknown(issuerHost, import_oid4vci_common8.WellKnownEndpoints.OPENID4VCI_ISSUER, {
errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
});
}
};
// lib/AccessTokenClient.ts
var AccessTokenClient = class _AccessTokenClient {
static {
__name(this, "AccessTokenClient");
}
async acquireAccessToken(opts) {
const { asOpts, pin, codeVerifier, code, redirectUri, metadata, createDPoPOpts } = opts;
const credentialOffer = opts.credentialOffer ? await (0, import_oid4vci_common9.assertedUniformCredentialOffer)(opts.credentialOffer) : void 0;
const pinMetadata = credentialOffer && this.getPinMetadata(credentialOffer.credential_offer);
const issuer = opts.credentialIssuer ?? (credentialOffer ? (0, import_oid4vci_common9.getIssuerFromCredentialOfferPayload)(credentialOffer.credential_offer) : metadata?.issuer);
if (!issuer) {
throw Error("Issuer required at this point");
}
const issuerOpts = {
issuer
};
return await this.acquireAccessTokenUsingRequest({
accessTokenRequest: await this.createAccessTokenRequest({
credentialOffer,
asOpts,
codeVerifier,
code,
redirectUri,
pin,
credentialIssuer: issuer,
metadata,
additionalParams: opts.additionalParams,
pinMetadata
}),
pinMetadata,
metadata,
asOpts,
issuerOpts,
createDPoPOpts
});
}
async acquireAccessTokenUsingRequest({ accessTokenRequest, pinMetadata, metadata, asOpts, issuerOpts, createDPoPOpts }) {
this.validate(accessTokenRequest, pinMetadata);
const requestTokenURL = _AccessTokenClient.determineTokenURL({
asOpts,
issuerOpts,
metadata: metadata ? metadata : issuerOpts?.fetchMetadata ? await MetadataClientV1_0_15.retrieveAllMetadata(issuerOpts.issuer, {
errorOnNotFound: false
}) : void 0
});
const useDpop = createDPoPOpts?.dPoPSigningAlgValuesSupported && createDPoPOpts.dPoPSigningAlgValuesSupported.length > 0;
let dPoP = useDpop ? await (0, import_oid4vc_common3.createDPoP)((0, import_oid4vc_common3.getCreateDPoPOptions)(createDPoPOpts, requestTokenURL)) : void 0;
let response = await this.sendAuthCode(requestTokenURL, accessTokenRequest, dPoP ? {
headers: {
dpop: dPoP
}
} : void 0);
let nextDPoPNonce = createDPoPOpts?.jwtPayloadProps.nonce;
const retryWithNonce = shouldRetryTokenRequestWithDPoPNonce(response);
if (retryWithNonce.ok && createDPoPOpts) {
createDPoPOpts.jwtPayloadProps.nonce = retryWithNonce.dpopNonce;
dPoP = await (0, import_oid4vc_common3.createDPoP)((0, import_oid4vc_common3.getCreateDPoPOptions)(createDPoPOpts, requestTokenURL));
response = await this.sendAuthCode(requestTokenURL, accessTokenRequest, dPoP ? {
headers: {
dpop: dPoP
}
} : void 0);
const successDPoPNonce = response.origResponse.headers.get("DPoP-Nonce");
nextDPoPNonce = successDPoPNonce ?? retryWithNonce.dpopNonce;
}
if (response.successBody && createDPoPOpts && response.successBody.token_type !== "DPoP") {
throw new Error("Invalid token type returned. Expected DPoP. Received: " + response.successBody.token_type);
}
return {
...response,
...nextDPoPNonce && {
params: {
dpop: {
dpopNonce: nextDPoPNonce
}
}
}
};
}
async createAccessTokenRequest(opts) {
const { asOpts, pin, codeVerifier, code, redirectUri } = opts;
const credentialOfferRequest = opts.credentialOffer ? await (0, import_oid4vci_common9.toUniformCredentialOfferRequest)(opts.credentialOffer) : void 0;
const request = {
...opts.additionalParams
};
if (asOpts?.clientOpts?.clientId) {
request.client_id = asOpts.clientOpts.clientId;
}
const credentialIssuer = opts.credentialIssuer ?? credentialOfferRequest?.credential_offer?.credential_issuer ?? opts.metadata?.issuer;
await createJwtBearerClientAssertion(request, {
...opts,
credentialIssuer
});
if (!credentialOfferRequest || credentialOfferRequest.supportedFlows.includes(import_oid4vci_common9.AuthzFlowType.AUTHORIZATION_CODE_FLOW)) {
request.grant_type = import_oid4vci_common9.GrantTypes.AUTHORIZATION_CODE;
request.code = code;
request.redirect_uri = redirectUri;
if (codeVerifier) {
request.code_verifier = codeVerifier;
}
return request;
}
if (credentialOfferRequest?.supportedFlows.includes(import_oid4vci_common9.AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)) {
this.assertAlphanumericPin(opts.pinMetadata, pin);
request.user_pin = pin;
request.tx_code = pin;
request.grant_type = import_oid4vci_common9.GrantTypes.PRE_AUTHORIZED_CODE;
request[import_oid4vci_common9.PRE_AUTH_CODE_LITERAL] = credentialOfferRequest?.credential_offer.grants?.[import_oid4vci_common9.PRE_AUTH_GRANT_LITERAL]?.[import_oid4vci_common9.PRE_AUTH_CODE_LITERAL];
return request;
}
throw new Error("Credential offer request follows neither pre-authorized code nor authorization code flow requirements.");
}
assertPreAuthorizedGrantType(grantType) {
if (import_oid4vci_common9.GrantTypes.PRE_AUTHORIZED_CODE !== grantType) {
throw new Error("grant type must be 'urn:ietf:params:oauth:grant-type:pre-authorized_code'");
}
}
assertAuthorizationGrantType(grantType) {
if (import_oid4vci_common9.GrantTypes.AUTHORIZATION_CODE !== grantType) {
throw new Error("grant type must be 'authorization_code'");
}
}
getPinMetadata(requestPayload) {
if (!requestPayload) {
throw new Error(import_oid4vci_common9.TokenErrorResponse.invalid_request);
}
const issuer = (0, import_oid4vci_common9.getIssuerFromCredentialOfferPayload)(requestPayload);
const grantDetails = requestPayload.grants?.[import_oid4vci_common9.PRE_AUTH_GRANT_LITERAL];
const isPinRequired = !!(grantDetails?.tx_code ?? false);
LOG.warning(`Pin required for issuer ${issuer}: ${isPinRequired}`);
return {
txCode: grantDetails?.tx_code,
isPinRequired
};
}
assertAlphanumericPin(pinMeta, pin) {
if (pinMeta && pinMeta.isPinRequired) {
let regex;
if (pinMeta.txCode) {
const { input_mode, length } = pinMeta.txCode;
if (input_mode === "numeric") {
regex = length ? new RegExp(`^\\d{1,${length}}$`) : /^\d+$/;
} else if (input_mode === "text") {
regex = length ? new RegExp(`^[a-zA-Z0-9]{1,${length}}$`) : /^[a-zA-Z0-9]+$/;
}
}
regex = regex || /^[a-zA-Z0-9]+$|^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+$/;
if (!pin || !regex.test(pin)) {
LOG.warning(`Pin is not valid. Expected format: ${pinMeta?.txCode?.input_mode || "alphanumeric"}, Length: up to ${pinMeta?.txCode?.length || "any number of"} characters`);
throw new Error("A valid pin must be present according to the specified transaction code requirements.");
}
} else if (pin) {
LOG.warning("Pin set, whilst not required");
throw new Error("Cannot set a pin when the pin is not required.");
}
}
assertNonEmptyPreAuthorizedCode(accessTokenRequest) {
if (!accessTokenRequest[import_oid4vci_common9.PRE_AUTH_CODE_LITERAL]) {
LOG.warning(`No pre-authorized code present, whilst it is required`, accessTokenRequest);
throw new Error("Pre-authorization must be proven by presenting the pre-authorized code. Code must be present.");
}
}
assertNonEmptyCodeVerifier(accessTokenRequest) {
if (!accessTokenRequest.code_verifier) {
LOG.warning("No code_verifier present, whilst it is required", accessTokenRequest);
throw new Error("Authorization flow requires the code_verifier to be present");
}
}
assertNonEmptyCode(accessTokenRequest) {
if (!accessTokenRequest.code) {
LOG.warning("No code present, whilst it is required");
throw new Error("Authorization flow requires the code to be present");
}
}
validate(accessTokenRequest, pinMeta) {
if (accessTokenRequest.grant_type === import_oid4vci_common9.GrantTypes.PRE_AUTHORIZED_CODE) {
this.assertPreAuthorizedGrantType(accessTokenRequest.grant_type);
this.assertNonEmptyPreAuthorizedCode(accessTokenRequest);
this.assertAlphanumericPin(pinMeta, accessTokenRequest.tx_code ?? accessTokenRequest.user_pin);
} else if (accessTokenRequest.grant_type === import_oid4vci_common9.GrantTypes.AUTHORIZATION_CODE) {
this.assertAuthorizationGrantType(accessTokenRequest.grant_type);
this.assertNonEmptyCodeVerifier(accessTokenRequest);
this.assertNonEmptyCode(accessTokenRequest);
} else {
this.throwNotSupportedFlow();
}
}
async sendAuthCode(requestTokenURL, accessTokenRequest, opts) {
return await (0, import_oid4vci_common9.formPost)(requestTokenURL, (0, import_oid4vci_common9.convertJsonToURI)(accessTokenRequest, {
mode: import_oid4vci_common9.JsonURIMode.X_FORM_WWW_URLENCODED
}), {
customHeaders: opts?.headers ? opts.headers : void 0
});
}
static determineTokenURL({ asOpts, issuerOpts, metadata }) {
if (!asOpts && !metadata?.token_endpoint && !issuerOpts) {
throw new Error("Cannot determine token URL if no issuer, metadata and no Authorization Server values are present");
}
let url;
if (asOpts && asOpts.as) {
url = this.creatTokenURLFromURL(asOpts.as, asOpts?.allowInsecureEndpoints, asOpts.tokenEndpoint);
} else if (metadata?.token_endpoint) {
url = metadata.token_endpoint;
} else {
if (!issuerOpts?.issuer) {
throw Error("Either authorization server options, a token endpoint or issuer options are required at this point");
}
url = this.creatTokenURLFromURL(issuerOpts.issuer, asOpts?.allowInsecureEndpoints, issuerOpts.tokenEndpoint);
}
if (!url || !import_ssi_types4.ObjectUtils.isString(url)) {
throw new Error("No authorization server token URL present. Cannot acquire access token");
}
LOG.debug(`Token endpoint determined to be ${url}`);
return url;
}
static creatTokenURLFromURL(url, allowInsecureEndpoints, tokenEndpoint) {
if (allowInsecureEndpoints !== true && url.startsWith("http:")) {
throw Error(`Unprotected token endpoints are not allowed ${url}. Use the 'allowInsecureEndpoints' param if you really need this for dev/testing!`);
}
const hostname = url.replace(/https?:\/\//, "").replace(/\/$/, "");
const endpoint = tokenEndpoint ? tokenEndpoint.startsWith("/") ? tokenEndpoint : tokenEndpoint.substring(1) : "/token";
const scheme = url.split("://")[0];
return `${scheme ? scheme + "://" : "https://"}${hostname}${endpoint}`;
}
throwNotSupportedFlow() {
LOG.warning(`Only pre-authorized or authorization code flows supported.`);
throw new Error("Only pre-authorized-code or authorization code flows are supported");
}
};
// lib/AuthorizationCodeClient.ts
var import_oid4vci_common11 = require("@sphereon/oid4vci-common");
var import_ssi_types6 = require("@sphereon/ssi-types");
// lib/MetadataClient.ts
var import_oid4vci_common10 = require("@sphereon/oid4vci-common");
var import_ssi_types5 = require("@sphereon/ssi-types");
var logger3 = import_ssi_types5.Loggers.DEFAULT.get("sphereon:oid4vci:metadata");
var MetadataClient = class _MetadataClient {
static {
__name(this, "MetadataClient");
}
/**
* Retrieve metadata using the Initiation obtained from a previous step
*
* @param credentialOffer
*/
static async retrieveAllMetadataFromCredentialOffer(credentialOffer) {
const openId4VCIVersion = (0, import_oid4vci_common10.determineSpecVersionFromOffer)(credentialOffer.credential_offer);
if (openId4VCIVersion >= import_oid4vci_common10.OpenId4VCIVersion.VER_1_0_15) {
return await MetadataClientV1_0_15.retrieveAllMetadataFromCredentialOffer(credentialOffer);
}
return Promise.reject(Error(`OpenId4VCIVersion ${openId4VCIVersion} is not supported in retrieveAllMetadataFromCredentialOffer`));
}
/**
* Retrieve the metada using the initiation request obtained from a previous step
* @param request
*/
static async retrieveAllMetadataFromCredentialOfferRequest(request) {
const issuer = (0, import_oid4vci_common10.getIssuerFromCredentialOfferPayload)(request);
if (issuer) {
const openId4VCIVersion = (0, import_oid4vci_common10.determineSpecVersionFromOffer)(request);
if (openId4VCIVersion >= import_oid4vci_common10.OpenId4VCIVersion.VER_1_0_15) {
return MetadataClientV1_0_15.retrieveAllMetadataFromCredentialOfferRequest(request);
} else {
return Promise.reject(Error(`OpenId4VCIVersion ${openId4VCIVersion} is not supported in retrieveAllMetadataFromCredentialOfferRequest`));
}
}
throw new Error("can't retrieve metadata from CredentialOfferRequest. No issuer field is present");
}
/**
* Retrieve all metadata from an issuer
* @param issuer The issuer URL
* @param opts
*/
static async retrieveAllMetadata(issuer, opts) {
let token_endpoint;
let credential_endpoint;
let deferred_credential_endpoint;
let authorization_endpoint;
let authorization_challenge_endpoint;
let authorizationServerType = "OID4VCI";
let authorization_servers = [
issuer
];
let authorization_server = void 0;
const oid4vciResponse = await _MetadataClient.retrieveOpenID4VCIServerMetadata(issuer, {
errorOnNotFound: false
});
let credentialIssuerMetadata = oid4vciResponse?.successBody;
if (credentialIssuerMetadata) {
logger3.debug(`Issuer ${issuer} OID4VCI well-known server metadata\r
${JSON.stringify(credentialIssuerMetadata)}`);
credential_endpoint = credentialIssuerMetadata.credential_endpoint;
deferred_credential_endpoint = credentialIssuerMetadata.deferred_credential_endpoint ? credentialIssuerMetadata.deferred_credential_endpoint : void 0;
if (credentialIssuerMetadata.token_endpoint) {
token_endpoint = credentialIssuerMetadata.token_endpoint;
}
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
if (credentialIssuerMetadata.authorization_servers) {
authorization_servers = credentialIssuerMetadata.authorization_servers;
} else if (credentialIssuerMetadata.authorization_server) {
authorization_server = credentialIssuerMetadata.authorization_server;
authorization_servers = [
authorization_server
];
}
} else {
throw new Error(`Issuer ${issuer} does not expose /.well-known/openid-credential-issuer`);
}
let response = await retrieveWellknown(authorization_servers[0], import_oid4vci_common10.WellKnownEndpoints.OPENID_CONFIGURATION, {
errorOnNotFound: false
});
let authMetadata = response.successBody;
if (authMetadata) {
logger3.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
authorizationServerType = "OIDC";
} else {
response = await retrieveWellknown(authorization_servers[0], import_oid4vci_common10.WellKnownEndpoints.OAUTH_AS, {
errorOnNotFound: false
});
authMetadata = response.successBody;
}
if (!authMetadata) {
if (!authorization_servers.includes(issuer)) {
throw Error(`Issuer ${issuer} provided a separate authorization server ${authorization_servers}, but that server did not provide metadata`);
}
} else {
if (!authorizationServerType) {
authorizationServerType = "OAuth 2.0";
}
logger3.debug(`Issuer ${issuer} has ${authorizationServerType} Server metadata in well-known location`);
if (!authMetadata.authorization_endpoint) {
console.warn(`Issuer ${issuer} of type ${authorizationServerType} has no authorization_endpoint! Will use ${authorization_endpoint}. This only works for pre-authorized flows`);
} else if (authorization_endpoint && authMetadata.authorization_endpoint !== authorization_endpoint) {
throw Error(`Credential issuer has a different authorization_endpoint (${authorization_endpoint}) from the Authorization Server (${authMetadata.authorization_endpoint})`);
}
authorization_endpoint = authMetadata.authorization_endpoint;
if (authorization_challenge_endpoint && authMetadata.authorization_challenge_endpoint !== authorization_challenge_endpoint) {
throw Error(`Credential issuer has a different authorization_challenge_endpoint (${authorization_challenge_endpoint}) from the Authorization Server (${authMetadata.authorization_challenge_endpoint})`);
}
authorization_challenge_endpoint = authMetadata.authorization_challenge_endpoint;
if (!authMetadata.token_endpoint) {
throw Error(`Authorization Server ${authorization_servers} did not provide a token_endpoint`);
} else if (token_endpoint && authMetadata.token_endpoint !== token_endpoint) {
throw Error(`Credential issuer has a different token_endpoint (${token_endpoint}) from the Authorization Server (${authMetadata.token_endpoint})`);
}
token_endpoint = authMetadata.token_endpoint;
if (authMetadata.credential_endpoint) {
if (credential_endpoint && authMetadata.credential_endpoint !== credential_endpoint) {
logger3.debug(`Credential issuer has a different credential_endpoint (${credential_endpoint}) from the Authorization Server (${authMetadata.credential_endpoint}). Will use the issuer value`);
} else {
credential_endpoint = authMetadata.credential_endpoint;
}
}
if (authMetadata.deferred_credential_endpoint) {
if (deferred_credential_endpoint && authMetadata.deferred_credential_endpoint !== deferred_credential_endpoint) {
logger3.debug(`Credential issuer has a different deferred_credential_endpoint (${deferred_credential_endpoint}) from the Authorization Server (${authMetadata.deferred_credential_endpoint}). Will use the issuer value`);
} else {
deferred_credential_endpoint = authMetadata.deferred_credential_endpoint;
}
}
}
if (!authorization_endpoint) {
logger3.debug(`Issuer ${issuer} does not expose authorization_endpoint, so only pre-auth will be supported`);
}
if (!token_endpoint) {
logger3.debug(`Issuer ${issuer} does not have a token_endpoint listed in well-known locations!`);
if (opts?.errorOnNotFound) {
throw Error(`Could not deduce the token_endpoint for ${issuer}`);
} else {
token_endpoint = `${issuer}${issuer.endsWith("/") ? "token" : "/token"}`;
}
}
if (!credential_endpoint) {
logger3.debug(`Issuer ${issuer} does not have a credential_endpoint listed in well-known locations!`);
if (opts?.errorOnNotFound) {
throw Error(`Could not deduce the credential endpoint for ${issuer}`);
} else {
credential_endpoint = `${issuer}${issuer.endsWith("/") ? "credential" : "/credential"}`;
}
}
if (!credentialIssuerMetadata && authMetadata) {
return Promise.reject(Error(`No /.well-known/openid-credential-issuer at ${issuer}.`));
}
logger3.debug(`Issuer ${issuer} token endpoint ${token_endpoint}, credential endpoint ${credential_endpoint}`);
return {
issuer,
token_endpoint,
credential_endpoint,
deferred_credential_endpoint,
nonce_endpoint: credentialIssuerMetadata.nonce_endpoint,
authorization_servers: authorization_server ? [
authorization_server
] : authorization_servers ?? [
issuer
],
authorization_endpoint,
authorization_challenge_endpoint,
authorizationServerType,
credentialIssuerMetadata,
authorizationServerMetadata: authMetadata
};
}
/**
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
*
* @param issuerHost The issuer hostname
* @param opts
*/
static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
return retrieveWellknown(issuerHost, import_oid4vci_common10.WellKnownEndpoints.OPENID4VCI_ISSUER, {
errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
});
}
};
// lib/AuthorizationCodeClient.ts
var logger4 = import_ssi_types6.Loggers.DEFAULT.get("sphereon:oid4vci");
async function createSignedAuthRequestWhenNeeded(requestObject, opts) {
if (opts.requestObjectMode === import_oid4vci_common11.CreateRequestObjectMode.REQUEST_URI) {
throw Error(`Request Object Mode ${opts.requestObjectMode} is not supported yet`);
} else if (opts.requestObjectMode === import_oid4vci_common11.CreateRequestObjectMode.REQUEST_OBJECT) {
if (typeof opts.signCallbacks?.signCallback !== "function") {
throw Error(`No request object sign callback found, whilst request object mode was set to ${opts.requestObjectMode}`);
} else if (!opts.kid) {
throw Error(`No kid found, whilst request object mode was set to ${opts.requestObjectMode}`);
}
let client_metadata;
if (opts.clientMetadata || opts.jwksUri) {
client_metadata = opts.clientMetadata ?? {};
if (opts.jwksUri) {
client_metadata["jwks_uri"] = opts.jwksUri;
}
}
let authorization_details = requestObject["authorization_details"];
if (typeof authorization_details === "string") {
authorization_details = JSON.parse(requestObject.authorization_details);
}
if (!requestObject.aud && opts.aud) {
requestObject.aud = opts.aud;
}
const iss = requestObject.iss ?? opts.iss ?? requestObject.client_id;
const jwt = {
header: {
alg: "ES256",
kid: opts.kid,
typ: "JWT"
},
payload: {
...requestObject,
iss,
authorization_details,
...client_metadata && {
client_metadata
}
}
};
const pop = await ProofOfPossessionBuilder.fromJwt({
jwt,
callbacks: opts.signCallbacks,
version: import_oid4vci_common11.OpenId4VCIVersion.VER_1_0_15,
mode: "JWT"
}).build();
requestObject["request"] = pop.jwt;
}
}
__name(createSignedAuthRequestWhenNeeded, "createSignedAuthRequestWhenNeeded");
function filterSupportedCredentials(credentialOffer, credentialsSupported) {
if (!credentialOffer.credential_configuration_ids || !credentialsSupported) {
return [];
}
return Object.entries(credentialsSupported).filter((entry) => credentialOffer.credential_configuration_ids?.includes(entry[0])).map((entry) => {
return {
...entry[1],
configuration_id: entry[0]
};
});
}
__name(filterSupportedCredentials, "filterSupportedCredentials");
var createAuthorizationRequestUrl = /* @__PURE__ */ __name(async ({ pkce, endpointMetadata, authorizationRequest, credentialOffer, credentialConfigurationSupported, clientId, version }) => {
function removeDisplayAndValueTypes(obj) {
if (Array.isArray(obj)) {
return obj.map((item) => removeDisplayAndValueTypes(item));
}
if (typeof obj !== "object" || obj === null) {
return obj;
}
const newObj = {
...obj
};
for (const prop in newObj) {
if ([
"display",
"value_type"
].includes(prop)) {
delete newObj[prop];
} else if (typeof newObj[prop] === "object" && newObj[prop] !== null) {
newObj[prop] = removeDisplayAndValueTypes(newObj[prop]);
}
}
return newObj;
}
__name(removeDisplayAndValueTypes, "removeDisplayAndValueTypes");
const { redirectUri, requestObjectOpts = {
requestObjectMode: import_oid4vci_common11.CreateRequestObjectMode.NONE
} } = authorizationRequest;
const client_id = clientId ?? authorizationRequest.clientId;
const authorizationMetadata = endpointMetadata.authorizationServerMetadata ?? endpointMetadata.credentialIssuerMetadata;
let { authorizationDetails } = authorizationRequest;
const parMode = authorizationMetadata?.require_pushed_authorization_requests ? import_oid4vci_common11.PARMode.REQUIRE : authorizationRequest.parMode ?? (client_id ? import_oid4vci_common11.PARMode.AUTO : import_oid4vci_common11.PARMode.NEVER);
if (!authorizationRequest.scope && !authorizationDetails) {
if (!credentialOffer) {
throw Error("Please provide a scope or authorization_details if no credential offer is present");
}
if ("credentials" in credentialOffer.credential_offer) {
throw new Error("CredentialOffer format is wrong.");
}
const ver = version ?? (0, import_oid4vci_common11.dete