@sphereon/oid4vci-common
Version:
OpenID 4 Verifiable Credential Issuance Common Types
1,283 lines (1,263 loc) • 58.2 kB
JavaScript
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 __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
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
));
// lib/functions/randomBytes.cjs
var require_randomBytes = __commonJS({
"lib/functions/randomBytes.cjs"(exports, module) {
"use strict";
var MAX_BYTES = 65536;
var MAX_UINT32 = 4294967295;
var _global = typeof globalThis !== "undefined" ? globalThis : global;
var crypto = _global.crypto || _global.msCrypto;
if (!crypto) {
try {
crypto = __require("crypto");
} catch (err) {
throw Error("crypto module is not available");
}
}
function randomBytes2(size) {
if (size > MAX_UINT32) throw new Error("requested too many random bytes");
const bytes = Buffer.allocUnsafe(size);
if (size > 0) {
if (size > MAX_BYTES) {
for (let generated = 0; generated < size; generated += MAX_BYTES) {
crypto.getRandomValues(bytes.slice(generated, generated + MAX_BYTES));
}
} else {
crypto.getRandomValues(bytes);
}
}
return Uint8Array.from(bytes);
}
__name(randomBytes2, "randomBytes");
module.exports = randomBytes2;
}
});
// lib/index.ts
import { Loggers as Loggers4 } from "@sphereon/ssi-types";
// lib/functions/HttpUtils.ts
import { Loggers } from "@sphereon/ssi-types";
import fetch from "cross-fetch";
// lib/types/Generic.types.ts
var supportedOID4VCICredentialFormat = [
"jwt_vc_json",
"jwt_vc_json-ld",
"ldp_vc",
"dc+sd-jwt",
"jwt_vc",
"mso_mdoc"
];
var PRE_AUTH_CODE_LITERAL = "pre-authorized_code";
var PRE_AUTH_GRANT_LITERAL = "urn:ietf:params:oauth:grant-type:pre-authorized_code";
// lib/types/Authorization.types.ts
var AuthorizationChallengeError = /* @__PURE__ */ (function(AuthorizationChallengeError2) {
AuthorizationChallengeError2["invalid_request"] = "invalid_request";
AuthorizationChallengeError2["invalid_client"] = "invalid_client";
AuthorizationChallengeError2["unauthorized_client"] = "unauthorized_client";
AuthorizationChallengeError2["invalid_session"] = "invalid_session";
AuthorizationChallengeError2["invalid_scope"] = "invalid_scope";
AuthorizationChallengeError2["insufficient_authorization"] = "insufficient_authorization";
AuthorizationChallengeError2["redirect_to_web"] = "redirect_to_web";
return AuthorizationChallengeError2;
})({});
var GrantTypes = /* @__PURE__ */ (function(GrantTypes2) {
GrantTypes2["AUTHORIZATION_CODE"] = "authorization_code";
GrantTypes2["PRE_AUTHORIZED_CODE"] = "urn:ietf:params:oauth:grant-type:pre-authorized_code";
GrantTypes2["PASSWORD"] = "password";
return GrantTypes2;
})({});
var Encoding = /* @__PURE__ */ (function(Encoding2) {
Encoding2["FORM_URL_ENCODED"] = "application/x-www-form-urlencoded";
Encoding2["UTF_8"] = "UTF-8";
return Encoding2;
})({});
var ResponseType = /* @__PURE__ */ (function(ResponseType2) {
ResponseType2["AUTH_CODE"] = "code";
return ResponseType2;
})({});
var CodeChallengeMethod = /* @__PURE__ */ (function(CodeChallengeMethod2) {
CodeChallengeMethod2["plain"] = "plain";
CodeChallengeMethod2["S256"] = "S256";
return CodeChallengeMethod2;
})({});
var PARMode = /* @__PURE__ */ (function(PARMode2) {
PARMode2[PARMode2["REQUIRE"] = 0] = "REQUIRE";
PARMode2[PARMode2["AUTO"] = 1] = "AUTO";
PARMode2[PARMode2["NEVER"] = 2] = "NEVER";
return PARMode2;
})({});
var CreateRequestObjectMode = /* @__PURE__ */ (function(CreateRequestObjectMode2) {
CreateRequestObjectMode2[CreateRequestObjectMode2["NONE"] = 0] = "NONE";
CreateRequestObjectMode2[CreateRequestObjectMode2["REQUEST_OBJECT"] = 1] = "REQUEST_OBJECT";
CreateRequestObjectMode2[CreateRequestObjectMode2["REQUEST_URI"] = 2] = "REQUEST_URI";
return CreateRequestObjectMode2;
})({});
var AuthzFlowType = /* @__PURE__ */ (function(AuthzFlowType2) {
AuthzFlowType2["AUTHORIZATION_CODE_FLOW"] = "Authorization Code Flow";
AuthzFlowType2["PRE_AUTHORIZED_CODE_FLOW"] = "Pre-Authorized Code Flow";
return AuthzFlowType2;
})({});
(function(AuthzFlowType2) {
function valueOf(request) {
if (PRE_AUTH_CODE_LITERAL in request) {
return "Pre-Authorized Code Flow";
}
return "Authorization Code Flow";
}
__name(valueOf, "valueOf");
AuthzFlowType2.valueOf = valueOf;
})(AuthzFlowType || (AuthzFlowType = {}));
// lib/types/CredentialIssuance.types.ts
var JsonURIMode = /* @__PURE__ */ (function(JsonURIMode2) {
JsonURIMode2[JsonURIMode2["JSON_STRINGIFY"] = 0] = "JSON_STRINGIFY";
JsonURIMode2[JsonURIMode2["X_FORM_WWW_URLENCODED"] = 1] = "X_FORM_WWW_URLENCODED";
return JsonURIMode2;
})({});
var Alg = /* @__PURE__ */ (function(Alg2) {
Alg2["EdDSA"] = "EdDSA";
Alg2["ES256"] = "ES256";
Alg2["ES256K"] = "ES256K";
Alg2["PS256"] = "PS256";
Alg2["PS384"] = "PS384";
Alg2["PS512"] = "PS512";
Alg2["RS256"] = "RS256";
Alg2["RS384"] = "RS384";
Alg2["RS512"] = "RS512";
return Alg2;
})({});
// lib/types/v1_0_15.types.ts
var credentialIssuerMetadataFieldNamesV1_0_15 = [
"credential_issuer",
"credential_configurations_supported",
"credential_endpoint",
"nonce_endpoint",
"deferred_credential_endpoint",
"notification_endpoint",
"credential_response_encryption",
"batch_credential_issuance",
"authorization_servers",
"token_endpoint",
"display",
"credential_supplier_config",
"credential_identifiers_supported",
"signed_metadata",
"authorization_challenge_endpoint"
];
// lib/types/ServerMetadata.ts
var authorizationServerMetadataFieldNames = [
"issuer",
"authorization_endpoint",
"authorization_challenge_endpoint",
"token_endpoint",
"jwks_uri",
"registration_endpoint",
"scopes_supported",
"response_types_supported",
"response_modes_supported",
"grant_types_supported",
"token_endpoint_auth_methods_supported",
"token_endpoint_auth_signing_alg_values_supported",
"service_documentation",
"ui_locales_supported",
"op_policy_uri",
"op_tos_uri",
"revocation_endpoint",
"revocation_endpoint_auth_methods_supported",
"revocation_endpoint_auth_signing_alg_values_supported",
"introspection_endpoint",
"introspection_endpoint_auth_methods_supported",
"introspection_endpoint_auth_signing_alg_values_supported",
"code_challenge_methods_supported",
"signed_metadata"
];
var WellKnownEndpoints = /* @__PURE__ */ (function(WellKnownEndpoints2) {
WellKnownEndpoints2["OPENID_CONFIGURATION"] = "/.well-known/openid-configuration";
WellKnownEndpoints2["OAUTH_AS"] = "/.well-known/oauth-authorization-server";
WellKnownEndpoints2["OPENID4VCI_ISSUER"] = "/.well-known/openid-credential-issuer";
return WellKnownEndpoints2;
})({});
// lib/types/OpenID4VCIErrors.ts
var BAD_PARAMS = "Wrong parameters provided";
var URL_NOT_VALID = "Request url is not valid";
var JWS_NOT_VALID = "JWS is not valid";
var PROOF_CANT_BE_CONSTRUCTED = "Proof can't be constructed.";
var NO_JWT_PROVIDED = "No JWT provided";
var TYP_ERROR = 'Typ must be "openid4vci-proof+jwt"';
var ALG_ERROR = `Algorithm is a required field, you are free to use the signing algorithm of your choice or one of the following: ${Object.keys(Alg).join(", ")}`;
var KID_JWK_X5C_ERROR = "Only one must be present: x5c should not present when kid and/or jwk is already present";
var KID_DID_NO_DID_ERROR = "A DID value needs to be returned when kid is present";
var DID_NO_DIDDOC_ERROR = "A DID Document needs to be resolved when a DID is encountered";
var AUD_ERROR = "aud must be the URL of the credential issuer";
var IAT_ERROR = "iat must be the time at which the proof was issued";
var NONCE_ERROR = "nonce must be c_nonce provided by the credential issuer";
var JWT_VERIFY_CONFIG_ERROR = "JWT verify callback not configured correctly.";
var ISSUER_CONFIG_ERROR = "Issuer not configured correctly.";
var UNKNOWN_CLIENT_ERROR = "The client is not known by the issuer";
var NO_ISS_IN_AUTHORIZATION_CODE_CONTEXT = "iss missing in authorization-code context";
var ISS_PRESENT_IN_PRE_AUTHORIZED_CODE_CONTEXT = "iss should be omitted in pre-authorized-code context";
var ISS_MUST_BE_CLIENT_ID = "iss must be the client id";
var GRANTS_MUST_NOT_BE_UNDEFINED = "Grants must not be undefined";
var STATE_MISSING_ERROR = "issuer state or pre-authorized key not found";
var CREDENTIAL_MISSING_ERROR = "Credential must be present in response";
var UNSUPPORTED_GRANT_TYPE_ERROR = "unsupported grant_type";
var PRE_AUTHORIZED_CODE_REQUIRED_ERROR = "pre-authorized_code is required";
var USER_PIN_REQUIRED_ERROR = "User pin is required";
var USER_PIN_TX_CODE_SPEC_ERROR = "user_pin is mixed with tx_code, indicating a spec mismatch";
var USER_PIN_NOT_REQUIRED_ERROR = "User pin is not required";
var PIN_VALIDATION_ERROR = "PIN must consist the following amount of characters:";
var PIN_NOT_MATCH_ERROR = "PIN is invalid";
var INVALID_PRE_AUTHORIZED_CODE = "pre-authorized_code is invalid";
var EXPIRED_PRE_AUTHORIZED_CODE = "pre-authorized_code is expired";
var JWT_SIGNER_CALLBACK_REQUIRED_ERROR = "JWT signer callback function is required";
var STATE_MANAGER_REQUIRED_ERROR = "StateManager instance is required";
var NONCE_STATE_MANAGER_REQUIRED_ERROR = "NonceStateManager instance is required";
var ACCESS_TOKEN_ISSUER_REQUIRED_ERROR = "access token issuer is required";
var WRONG_METADATA_FORMAT = "Wrong metadata format";
// lib/types/OpenID4VCIVersions.types.ts
var OpenId4VCIVersion = /* @__PURE__ */ (function(OpenId4VCIVersion2) {
OpenId4VCIVersion2[OpenId4VCIVersion2["VER_1_0_15"] = 1015] = "VER_1_0_15";
OpenId4VCIVersion2[OpenId4VCIVersion2["VER_UNKNOWN"] = Number.MAX_VALUE] = "VER_UNKNOWN";
return OpenId4VCIVersion2;
})({});
var DefaultURISchemes = /* @__PURE__ */ (function(DefaultURISchemes2) {
DefaultURISchemes2["INITIATE_ISSUANCE"] = "openid-initiate-issuance";
DefaultURISchemes2["CREDENTIAL_OFFER"] = "openid-credential-offer";
return DefaultURISchemes2;
})({});
// lib/types/StateManager.types.ts
var IssueStatus = /* @__PURE__ */ (function(IssueStatus2) {
IssueStatus2["OFFER_CREATED"] = "OFFER_CREATED";
IssueStatus2["ACCESS_TOKEN_REQUESTED"] = "ACCESS_TOKEN_REQUESTED";
IssueStatus2["ACCESS_TOKEN_CREATED"] = "ACCESS_TOKEN_CREATED";
IssueStatus2["CREDENTIAL_REQUEST_RECEIVED"] = "CREDENTIAL_REQUEST_RECEIVED";
IssueStatus2["CREDENTIAL_ISSUED"] = "CREDENTIAL_ISSUED";
IssueStatus2["NOTIFICATION_CREDENTIAL_ACCEPTED"] = "NOTIFICATION_CREDENTIAL_ACCEPTED";
IssueStatus2["NOTIFICATION_CREDENTIAL_DELETED"] = "NOTIFICATION_CREDENTIAL_DELETED";
IssueStatus2["NOTIFICATION_CREDENTIAL_FAILURE"] = "NOTIFICATION_CREDENTIAL_FAILURE";
IssueStatus2["ERROR"] = "ERROR";
return IssueStatus2;
})({});
// lib/types/Token.types.ts
var TokenErrorResponse = /* @__PURE__ */ (function(TokenErrorResponse2) {
TokenErrorResponse2["invalid_request"] = "invalid_request";
TokenErrorResponse2["invalid_grant"] = "invalid_grant";
TokenErrorResponse2["invalid_client"] = "invalid_client";
TokenErrorResponse2["invalid_scope"] = "invalid_scope";
TokenErrorResponse2["invalid_dpop_proof"] = "invalid_dpop_proof";
return TokenErrorResponse2;
})({});
var TokenError = class _TokenError extends Error {
static {
__name(this, "TokenError");
}
_statusCode;
_responseError;
constructor(statusCode, responseError, message) {
super(message);
this._statusCode = statusCode;
this._responseError = responseError;
Object.setPrototypeOf(this, _TokenError.prototype);
}
get statusCode() {
return this._statusCode;
}
get responseError() {
return this._responseError;
}
getDescription() {
return this.message;
}
};
// lib/functions/HttpUtils.ts
var logger = Loggers.DEFAULT.get("sphereon:openid4vci:http");
var getJson = /* @__PURE__ */ __name(async (URL1, opts) => {
return await openIdFetch(URL1, void 0, {
method: "GET",
...opts
});
}, "getJson");
var formPost = /* @__PURE__ */ __name(async (url, body, opts) => {
return await post(url, body, opts?.contentType ? {
...opts
} : {
contentType: Encoding.FORM_URL_ENCODED,
...opts
});
}, "formPost");
var post = /* @__PURE__ */ __name(async (url, body, opts) => {
return await openIdFetch(url, body, {
method: "POST",
...opts
});
}, "post");
var openIdFetch = /* @__PURE__ */ __name(async (url, body, opts) => {
const headers = opts?.customHeaders ?? {};
if (opts?.bearerToken) {
headers["Authorization"] = `${headers.dpop ? "DPoP" : "Bearer"} ${typeof opts.bearerToken === "function" ? await opts.bearerToken() : opts.bearerToken}`;
}
const method = opts?.method ? opts.method : body ? "POST" : "GET";
const accept = opts?.accept ? opts.accept : "application/json";
headers["Accept"] = accept;
if (headers["Content-Type"]) {
if (opts?.contentType && opts.contentType !== headers["Content-Type"]) {
throw Error(`Mismatch in content-types from custom headers (${headers["Content-Type"]}) and supplied content type option (${opts.contentType})`);
}
} else {
if (opts?.contentType) {
headers["Content-Type"] = opts.contentType;
} else if (method !== "GET") {
headers["Content-Type"] = "application/json";
}
}
const payload = {
method,
headers,
body
};
logger.debug(`START fetching url: ${url}`);
if (body) {
logger.debug(`Body:\r
${typeof body == "string" ? body : JSON.stringify(body)}`);
}
logger.debug(`Headers:\r
${JSON.stringify(payload.headers)}`);
const origResponse = await fetch(url, payload);
const isJSONResponse = accept === "application/json" || origResponse.headers.get("Content-Type") === "application/json";
const success = origResponse && origResponse.status >= 200 && origResponse.status < 400;
const responseText = await origResponse.text();
const responseBody = isJSONResponse && responseText.includes("{") ? JSON.parse(responseText) : responseText;
logger.debug(`${success ? "success" : "error"} status: ${origResponse.status}, body:\r
${JSON.stringify(responseBody)}`);
if (!success && opts?.exceptionOnHttpErrorStatus) {
const error = JSON.stringify(responseBody);
throw new Error(error === "{}" ? '{"error": "not found"}' : error);
}
logger.debug(`END fetching url: ${url}`);
return {
origResponse,
successBody: success ? responseBody : void 0,
errorBody: !success ? responseBody : void 0
};
}, "openIdFetch");
var isValidURL = /* @__PURE__ */ __name((url) => {
const urlPattern = new RegExp("^(https?:\\/\\/)((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((localhost))|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+:]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$", "i");
return urlPattern.test(url);
}, "isValidURL");
var trimBoth = /* @__PURE__ */ __name((value, trim) => {
return trimEnd(trimStart(value, trim), trim);
}, "trimBoth");
var trimEnd = /* @__PURE__ */ __name((value, trim) => {
return value.endsWith(trim) ? value.substring(0, value.length - trim.length) : value;
}, "trimEnd");
var trimStart = /* @__PURE__ */ __name((value, trim) => {
return value.startsWith(trim) ? value.substring(trim.length) : value;
}, "trimStart");
var adjustUrl = /* @__PURE__ */ __name((urlOrPath, opts) => {
let url = typeof urlOrPath === "object" ? urlOrPath.toString() : urlOrPath;
if (opts?.append) {
url = trimEnd(url, "/") + "/" + trimStart(opts.append, "/");
}
if (opts?.prepend) {
if (opts.prepend.includes("://")) {
if (!url.startsWith(opts.prepend)) {
url = trimEnd(opts.prepend, "/") + "/" + trimStart(url, "/");
}
} else {
let host = "";
let path = url;
if (url.includes("://")) {
host = new URL(url).host;
path = new URL(url).pathname;
}
if (!path.startsWith(opts.prepend)) {
if (host && host !== "") {
url = trimEnd(host, "/");
}
url += trimEnd(url, "/") + "/" + trimBoth(opts.prepend, "/") + "/" + trimStart(path, "/");
}
}
}
if (opts?.stripSlashStart) {
url = trimStart(url, "/");
}
if (opts?.stripSlashEnd) {
url = trimEnd(url, "/");
}
if (typeof urlOrPath === "string") {
return url;
}
return new URL(url);
}, "adjustUrl");
// lib/functions/CredentialResponseUtil.ts
function isDeferredCredentialResponse(credentialResponse) {
const orig = credentialResponse.successBody;
return credentialResponse.origResponse.status % 200 <= 2 && !!orig && !orig.credentials && (!!orig.acceptance_token || !!orig.transaction_id);
}
__name(isDeferredCredentialResponse, "isDeferredCredentialResponse");
function assertNonFatalError(credentialResponse) {
if (credentialResponse.origResponse.status === 400 && credentialResponse.errorBody?.error) {
if (credentialResponse.errorBody.error === "invalid_transaction_id" || credentialResponse.errorBody.error.includes("acceptance_token")) {
throw Error("Invalid transaction id. Probably the deferred credential request expired");
}
}
}
__name(assertNonFatalError, "assertNonFatalError");
function isDeferredCredentialIssuancePending(credentialResponse) {
if (isDeferredCredentialResponse(credentialResponse)) {
return credentialResponse?.successBody?.transaction_id ?? !!credentialResponse?.successBody?.acceptance_token;
}
if (credentialResponse.origResponse.status === 400 && credentialResponse.errorBody?.error) {
if (credentialResponse.errorBody.error === "issuance_pending") {
return true;
} else if (credentialResponse.errorBody.error_description?.toLowerCase().includes("not available yet")) {
return true;
}
}
return false;
}
__name(isDeferredCredentialIssuancePending, "isDeferredCredentialIssuancePending");
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
__name(sleep, "sleep");
async function acquireDeferredCredential({ bearerToken, transactionId, deferredCredentialEndpoint, deferredCredentialIntervalInMS, deferredCredentialAwait }) {
let credentialResponse = await acquireDeferredCredentialImpl({
bearerToken,
transactionId,
deferredCredentialEndpoint
});
const DEFAULT_SLEEP_IN_MS = 5e3;
while (!credentialResponse.successBody?.credentials && deferredCredentialAwait) {
assertNonFatalError(credentialResponse);
const pending = isDeferredCredentialIssuancePending(credentialResponse);
console.log(`Issuance still pending?: ${pending}`);
if (!pending) {
return Promise.reject(Error(`Issuance isn't pending anymore: ${credentialResponse}`));
}
await sleep(deferredCredentialIntervalInMS ?? DEFAULT_SLEEP_IN_MS);
credentialResponse = await acquireDeferredCredentialImpl({
bearerToken,
transactionId,
deferredCredentialEndpoint
});
}
return credentialResponse;
}
__name(acquireDeferredCredential, "acquireDeferredCredential");
async function acquireDeferredCredentialImpl({ bearerToken, transactionId, deferredCredentialEndpoint }) {
const response = await post(deferredCredentialEndpoint, JSON.stringify(transactionId ? {
transaction_id: transactionId
} : ""), {
bearerToken
});
console.log(JSON.stringify(response, null, 2));
assertNonFatalError(response);
return {
...response,
access_token: bearerToken
};
}
__name(acquireDeferredCredentialImpl, "acquireDeferredCredentialImpl");
// lib/functions/CredentialOfferUtil.ts
import { Loggers as Loggers2, ObjectUtils } from "@sphereon/ssi-types";
import { jwtDecode } from "jwt-decode";
import { base64urlToString } from "@sphereon/oid4vc-common";
var logger2 = Loggers2.DEFAULT.get("sphereon:oid4vci:offer");
function determineSpecVersionFromURI(uri) {
let version = determineSpecVersionFromScheme(uri, OpenId4VCIVersion.VER_UNKNOWN) ?? OpenId4VCIVersion.VER_UNKNOWN;
if (version === OpenId4VCIVersion.VER_UNKNOWN) {
version = OpenId4VCIVersion.VER_1_0_15;
}
return version;
}
__name(determineSpecVersionFromURI, "determineSpecVersionFromURI");
function determineSpecVersionFromScheme(credentialOfferURI, openId4VCIVersion) {
const scheme = getScheme(credentialOfferURI);
const url = toUrlWithDummyBase(credentialOfferURI);
const qp = url.searchParams;
if (scheme === DefaultURISchemes.INITIATE_ISSUANCE) {
if (qp.has("credential_offer") || qp.has("credential_offer_uri")) {
return recordVersion(openId4VCIVersion, [
OpenId4VCIVersion.VER_1_0_15
], scheme);
}
return recordVersion(openId4VCIVersion, [
OpenId4VCIVersion.VER_UNKNOWN
], scheme);
}
if (scheme === DefaultURISchemes.CREDENTIAL_OFFER) {
if (qp.has("credential_offer_uri")) {
return recordVersion(openId4VCIVersion, [
OpenId4VCIVersion.VER_1_0_15
], scheme);
}
const rawParam = getParamValueLoose(qp, "credential_offer");
if (rawParam) {
const decoded = tryDecodeOffer(rawParam);
const version = sniffOfferVersion(decoded);
if (version !== OpenId4VCIVersion.VER_UNKNOWN) {
return recordVersion(openId4VCIVersion, [
version
], scheme);
}
}
return recordVersion(openId4VCIVersion, [
OpenId4VCIVersion.VER_UNKNOWN
], scheme);
}
return recordVersion(openId4VCIVersion, [
OpenId4VCIVersion.VER_UNKNOWN
], scheme);
}
__name(determineSpecVersionFromScheme, "determineSpecVersionFromScheme");
function toUrlWithDummyBase(uri) {
const normalized = uri.replace(/^openid-[^?]+:\/\//, "https://dummy/?");
return new URL(normalized);
}
__name(toUrlWithDummyBase, "toUrlWithDummyBase");
function getParamValueLoose(qp, key) {
if (qp.has(key)) return qp.get(key);
if (qp.has(`?${key}`)) return qp.get(`?${key}`);
return null;
}
__name(getParamValueLoose, "getParamValueLoose");
function tryDecodeOffer(input) {
let candidate = input;
try {
candidate = decodeURIComponent(candidate);
} catch {
}
if (!/[{}]/.test(candidate) && /^[A-Za-z0-9\-_]+$/.test(candidate)) {
try {
const b64 = candidate.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(candidate.length / 4) * 4, "=");
candidate = atob(b64);
} catch {
}
}
return candidate;
}
__name(tryDecodeOffer, "tryDecodeOffer");
function sniffOfferVersion(jsonLike) {
if (!jsonLike) return OpenId4VCIVersion.VER_UNKNOWN;
return OpenId4VCIVersion.VER_UNKNOWN;
}
__name(sniffOfferVersion, "sniffOfferVersion");
function getScheme(credentialOfferURI) {
if (!credentialOfferURI || !credentialOfferURI.includes("://")) {
throw Error("Invalid credential offer URI");
}
return credentialOfferURI.split("://")[0];
}
__name(getScheme, "getScheme");
function getIssuerFromCredentialOfferPayload(request) {
if (!request || !("issuer" in request) && !("credential_issuer" in request)) {
return void 0;
}
return "issuer" in request ? request.issuer : request["credential_issuer"];
}
__name(getIssuerFromCredentialOfferPayload, "getIssuerFromCredentialOfferPayload");
var getClientIdFromCredentialOfferPayload = /* @__PURE__ */ __name((credentialOffer) => {
if (!credentialOffer) {
return;
}
if ("client_id" in credentialOffer) {
return credentialOffer.client_id;
}
const state = getStateFromCredentialOfferPayload(credentialOffer);
if (state && isJWT(state)) {
const decoded = jwtDecode(state, {
header: false
});
if ("client_id" in decoded && typeof decoded.client_id === "string") {
return decoded.client_id;
}
}
return;
}, "getClientIdFromCredentialOfferPayload");
var isJWT = /* @__PURE__ */ __name((input) => {
if (!input) {
return false;
}
const noParts = input?.split(".").length;
return input?.startsWith("ey") && noParts === 3;
}, "isJWT");
var getStateFromCredentialOfferPayload = /* @__PURE__ */ __name((credentialOffer) => {
if ("grants" in credentialOffer) {
if (credentialOffer.grants?.authorization_code) {
return credentialOffer.grants.authorization_code.issuer_state;
} else if (credentialOffer.grants?.[PRE_AUTH_GRANT_LITERAL]) {
return credentialOffer.grants?.[PRE_AUTH_GRANT_LITERAL]?.[PRE_AUTH_CODE_LITERAL];
}
}
if ("op_state" in credentialOffer) {
return credentialOffer.op_state;
} else if (PRE_AUTH_CODE_LITERAL in credentialOffer) {
return credentialOffer[PRE_AUTH_CODE_LITERAL];
}
return;
}, "getStateFromCredentialOfferPayload");
function determineSpecVersionFromOffer(offer) {
if (isCredentialOfferV1_0_15(offer)) {
return OpenId4VCIVersion.VER_1_0_15;
}
return OpenId4VCIVersion.VER_UNKNOWN;
}
__name(determineSpecVersionFromOffer, "determineSpecVersionFromOffer");
function isCredentialOfferVersion(offer, min, max) {
if (max && max.valueOf() < min.valueOf()) {
throw Error(`Cannot have a max ${max.valueOf()} version smaller than the min version ${min.valueOf()}`);
}
const version = determineSpecVersionFromOffer(offer);
if (version.valueOf() < min.valueOf()) {
logger2.debug(`Credential offer version (${version.valueOf()}) is lower than minimum required version (${min.valueOf()})`);
return false;
} else if (max && version.valueOf() > max.valueOf()) {
logger2.debug(`Credential offer version (${version.valueOf()}) is higher than maximum required version (${max.valueOf()})`);
return false;
}
return true;
}
__name(isCredentialOfferVersion, "isCredentialOfferVersion");
function isCredentialOfferV1_0_15(offer) {
if (!offer) {
return false;
}
offer = normalizeOfferInput(offer);
if ("credential_issuer" in offer && "credential_configuration_ids" in offer) {
return Array.isArray(offer.credential_configuration_ids);
}
if ("credential_offer" in offer && offer["credential_offer"]) {
return isCredentialOfferV1_0_15(offer["credential_offer"]);
}
return "credential_offer_uri" in offer;
}
__name(isCredentialOfferV1_0_15, "isCredentialOfferV1_0_15");
async function toUniformCredentialOfferRequest(offer, opts) {
let version = opts?.version ?? determineSpecVersionFromOffer(offer);
let originalCredentialOffer = offer.credential_offer;
let credentialOfferURI;
if ("credential_offer_uri" in offer && offer?.credential_offer_uri !== void 0) {
credentialOfferURI = offer.credential_offer_uri;
if (opts?.resolve || opts?.resolve === void 0) {
VCI_LOG_COMMON.log(`Credential offer contained a URI. Will use that to get the credential offer payload: ${credentialOfferURI}`);
originalCredentialOffer = await resolveCredentialOfferURI(credentialOfferURI);
} else if (!originalCredentialOffer) {
throw Error(`Credential offer uri (${credentialOfferURI}) found, but resolution was explicitly disabled and credential_offer was supplied`);
}
version = determineSpecVersionFromOffer(originalCredentialOffer);
VCI_LOG_COMMON.log(`Offer URI payload determined to be of version ${version}`);
}
if (!originalCredentialOffer) {
throw Error("No credential offer available");
}
const payload = toUniformCredentialOfferPayload(originalCredentialOffer, {
...opts,
version
});
const supportedFlows = determineFlowType(payload, version);
return {
credential_offer: payload,
original_credential_offer: originalCredentialOffer,
...credentialOfferURI && {
credential_offer_uri: credentialOfferURI
},
supportedFlows,
version
};
}
__name(toUniformCredentialOfferRequest, "toUniformCredentialOfferRequest");
function isPreAuthCode(request) {
request = normalizeOfferInput(request);
const payload = "credential_offer" in request ? request.credential_offer : request;
return payload?.grants?.[PRE_AUTH_GRANT_LITERAL]?.[PRE_AUTH_CODE_LITERAL] !== void 0;
}
__name(isPreAuthCode, "isPreAuthCode");
async function assertedUniformCredentialOffer(origCredentialOffer, opts) {
const credentialOffer = JSON.parse(JSON.stringify(origCredentialOffer));
if (credentialOffer.credential_offer_uri && !credentialOffer.credential_offer) {
if (opts?.resolve === void 0 || opts.resolve) {
credentialOffer.credential_offer = await resolveCredentialOfferURI(credentialOffer.credential_offer_uri);
} else {
throw Error(`No credential_offer present, but we did get a URI, but resolution was explicitly disabled`);
}
}
if (!credentialOffer.credential_offer) {
throw Error(`No credential_offer present`);
}
credentialOffer.credential_offer = await toUniformCredentialOfferPayload(credentialOffer.credential_offer, {
version: credentialOffer.version
});
return credentialOffer;
}
__name(assertedUniformCredentialOffer, "assertedUniformCredentialOffer");
async function resolveCredentialOfferURI(uri) {
if (!uri) {
return void 0;
}
const response = await getJson(uri);
if (!response || !response.successBody) {
throw Error(`Could not get credential offer from uri: ${uri}: ${JSON.stringify(response?.errorBody)}`);
}
return response.successBody;
}
__name(resolveCredentialOfferURI, "resolveCredentialOfferURI");
function toUniformCredentialOfferPayload(rawOffer, opts) {
const offer = normalizeOfferInput(rawOffer);
const version = opts?.version ?? determineSpecVersionFromOffer(offer);
if (version >= OpenId4VCIVersion.VER_1_0_15) {
const orig = offer;
return {
...orig
};
}
throw Error(`Could not create uniform payload for version ${version}`);
}
__name(toUniformCredentialOfferPayload, "toUniformCredentialOfferPayload");
function determineFlowType(suppliedOffer, version) {
const payload = getCredentialOfferPayload(suppliedOffer);
const supportedFlows = [];
if (payload.grants?.authorization_code) {
supportedFlows.push(AuthzFlowType.AUTHORIZATION_CODE_FLOW);
}
if (payload.grants?.[PRE_AUTH_GRANT_LITERAL]?.[PRE_AUTH_CODE_LITERAL]) {
supportedFlows.push(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW);
}
return supportedFlows;
}
__name(determineFlowType, "determineFlowType");
function getCredentialOfferPayload(offer) {
offer = normalizeOfferInput(offer);
let payload;
if ("credential_offer" in offer && offer["credential_offer"]) {
payload = offer.credential_offer;
} else {
payload = offer;
}
return payload;
}
__name(getCredentialOfferPayload, "getCredentialOfferPayload");
function determineGrantTypes(offer) {
offer = normalizeOfferInput(offer);
let grants;
if ("grants" in offer && offer.grants) {
grants = offer.grants;
} else {
grants = getCredentialOfferPayload(offer).grants;
}
const types = [];
if (grants) {
if ("authorization_code" in grants) {
types.push(GrantTypes.AUTHORIZATION_CODE);
}
if (PRE_AUTH_GRANT_LITERAL in grants) {
types.push(GrantTypes.PRE_AUTHORIZED_CODE);
}
}
return types;
}
__name(determineGrantTypes, "determineGrantTypes");
function recordVersion(currentVersion, matchingVersion, key, allowUpgrade = true) {
matchingVersion = matchingVersion.sort().reverse();
if (currentVersion === OpenId4VCIVersion.VER_UNKNOWN) {
return matchingVersion[0];
} else if (matchingVersion.includes(currentVersion)) {
if (!allowUpgrade) {
return currentVersion;
}
return matchingVersion[0];
}
throw new Error(`Invalid param. Some keys have been used from version: ${currentVersion} version while '${key}' is used from version: ${JSON.stringify(matchingVersion)}`);
}
__name(recordVersion, "recordVersion");
function getCredentialConfigurationIdsFromOfferV1_0_15(offer) {
return offer.credential_configuration_ids ?? [];
}
__name(getCredentialConfigurationIdsFromOfferV1_0_15, "getCredentialConfigurationIdsFromOfferV1_0_15");
function normalizeOfferInput(input) {
if (typeof input !== "string") {
return input;
}
if (ObjectUtils.isString(input) && input.startsWith("ey")) {
const payload = base64urlToString(input);
return JSON.parse(payload);
}
try {
return JSON.parse(input);
} catch {
}
return input;
}
__name(normalizeOfferInput, "normalizeOfferInput");
// lib/functions/Encoding.ts
function convertJsonToURI(json, opts) {
if (typeof json === "string") {
return convertJsonToURI(JSON.parse(json), opts);
}
const results = [];
function encodeAndStripWhitespace(key) {
return encodeURIComponent(key.replace(" ", ""));
}
__name(encodeAndStripWhitespace, "encodeAndStripWhitespace");
let components;
if (opts?.mode === JsonURIMode.JSON_STRINGIFY) {
components = encodeAndStripWhitespace(JSON.stringify(json));
} else {
for (const [key, value] of Object.entries(json)) {
if (!value) {
continue;
}
if (!opts?.uriTypeProperties?.includes(key)) {
results.push(`${key}=${value}`);
continue;
}
if (opts?.arrayTypeProperties?.includes(key) && Array.isArray(value)) {
results.push(value.map((v) => `${encodeAndStripWhitespace(key)}=${customEncodeURIComponent(v, /\./g)}`).join("&"));
continue;
}
const isBool = typeof value == "boolean";
const isNumber = typeof value == "number";
const isString = typeof value == "string";
let encoded;
if (isBool || isNumber) {
encoded = `${encodeAndStripWhitespace(key)}=${value}`;
} else if (isString) {
encoded = `${encodeAndStripWhitespace(key)}=${customEncodeURIComponent(value, /\./g)}`;
} else {
encoded = `${encodeAndStripWhitespace(key)}=${customEncodeURIComponent(JSON.stringify(value), /\./g)}`;
}
results.push(encoded);
}
components = results.join("&");
}
if (opts?.baseUrl) {
if (opts.baseUrl.endsWith("=")) {
if (opts.param) {
throw Error("Cannot combine param with an url ending in =");
}
return `${opts.baseUrl}${components}`;
} else if (!opts.baseUrl.includes("?")) {
return `${opts.baseUrl}?${opts.param ? opts.param + "=" : ""}${components}`;
} else if (opts.baseUrl.endsWith("?")) {
return `${opts.baseUrl}${opts.param ? opts.param + "=" : ""}${components}`;
} else {
return `${opts.baseUrl}${opts.param ? "&" + opts.param : ""}=${components}`;
}
}
return components;
}
__name(convertJsonToURI, "convertJsonToURI");
function convertURIToJsonObject(uri, opts) {
if (!uri || opts?.requiredProperties && !opts.requiredProperties?.every((p) => uri.includes(p))) {
throw new Error(BAD_PARAMS);
}
const uriComponents = getURIComponentsAsArray(uri, opts?.arrayTypeProperties);
return decodeJsonProperties(uriComponents);
}
__name(convertURIToJsonObject, "convertURIToJsonObject");
function decodeJsonProperties(parts) {
const result = {};
for (const key in parts) {
const value = parts[key];
if (!value) {
continue;
}
if (Array.isArray(value)) {
result[decodeURIComponent(key)] = value.map((v) => decodeURIComponent(v));
continue;
}
const isBool = typeof value == "boolean";
const isNumber = typeof value == "number";
const isString = typeof value == "string";
const isObject = typeof value == "object";
if (isBool || isNumber) {
result[decodeURIComponent(key)] = value;
} else if (isString) {
const decoded = decodeURIComponent(value);
if (decoded.startsWith("{") && decoded.endsWith("}")) {
result[decodeURIComponent(key)] = JSON.parse(decoded);
} else {
result[decodeURIComponent(key)] = decoded;
}
} else if (isObject) {
result[decodeURIComponent(key)] = decodeJsonProperties(value);
}
}
return result;
}
__name(decodeJsonProperties, "decodeJsonProperties");
function getURIComponentsAsArray(uri, arrayTypes) {
const parts = uri.includes("?") ? uri.split("?")[1] : uri.includes("://") ? uri.split("://")[1] : uri;
const json = [];
const dict = parts.split("&");
for (const entry of dict) {
const pair = entry.split("=");
const p0 = pair[0];
const p1 = pair[1];
if (arrayTypes?.includes(p0)) {
const key = json[p0];
if (Array.isArray(key)) {
key.push(p1);
} else {
json[p0] = [
p1
];
}
continue;
}
json[p0] = p1;
}
return json;
}
__name(getURIComponentsAsArray, "getURIComponentsAsArray");
function customEncodeURIComponent(uriComponent, searchValue) {
return encodeURIComponent(uriComponent).replace(searchValue, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
}
__name(customEncodeURIComponent, "customEncodeURIComponent");
// lib/functions/TypeConversionUtils.ts
function isW3cCredentialSupported(supported) {
return [
"jwt_vc_json",
"jwt_vc_json-ld",
"ldp_vc",
"jwt_vc"
].includes(supported.format);
}
__name(isW3cCredentialSupported, "isW3cCredentialSupported");
var getNumberOrUndefined = /* @__PURE__ */ __name((input) => {
return input && !isNaN(+input) ? +input : void 0;
}, "getNumberOrUndefined");
function getTypesFromObject(subject) {
if (subject === void 0) {
return void 0;
} else if (typeof subject === "string") {
return [
subject
];
} else if ("credential_definition" in subject) {
return getTypesFromObject(subject.credential_definition);
} else if ("types" in subject && subject.types) {
return Array.isArray(subject.types) ? subject.types : [
subject.types
];
} else if ("type" in subject && subject.type) {
return Array.isArray(subject.type) ? subject.type : [
subject.type
];
} else if ("vct" in subject && subject.vct) {
return [
subject.vct
];
} else if ("doctype" in subject && subject.doctype) {
return [
subject.doctype
];
}
VCI_LOG_COMMON.warning("Could not deduce credential types. Probably a failure down the line will happen!");
return void 0;
}
__name(getTypesFromObject, "getTypesFromObject");
function getTypesFromAuthorizationDetails(authDetails, opts) {
const { configIdAsType = false } = {
...opts
};
if (typeof authDetails === "string") {
return [
authDetails
];
} else if ("types" in authDetails && Array.isArray(authDetails.types)) {
return authDetails.types;
} else if (configIdAsType && authDetails.credential_configuration_id) {
return [
authDetails.credential_configuration_id
];
}
return void 0;
}
__name(getTypesFromAuthorizationDetails, "getTypesFromAuthorizationDetails");
function getTypesFromCredentialSupported(credentialSupported, opts) {
let types = [];
if (credentialSupported.format === "jwt_vc_json" || credentialSupported.format === "jwt_vc" || credentialSupported.format === "jwt_vc_json-ld" || credentialSupported.format === "ldp_vc") {
types = getTypesFromObject(credentialSupported) ?? [];
} else if (credentialSupported.format === "dc+sd-jwt" || credentialSupported.format === "vc+sd-jwt") {
types = [
credentialSupported.vct
];
} else if (credentialSupported.format === "mso_mdoc") {
types = [
credentialSupported.doctype
];
}
if (!types || types.length === 0) {
throw Error("Could not deduce types from credential supported");
}
if (opts?.filterVerifiableCredential) {
return types.filter((type) => type !== "VerifiableCredential");
}
return types;
}
__name(getTypesFromCredentialSupported, "getTypesFromCredentialSupported");
// lib/functions/IssuerMetadataUtils.ts
function getSupportedCredentials(opts) {
const { version = OpenId4VCIVersion.VER_1_0_15, types } = opts ?? {};
if (types && Array.isArray(types)) {
return types.map((typeSet) => {
return getSupportedCredential({
...opts,
version,
types: typeSet
});
}).reduce((acc, result) => {
Object.assign(acc, result);
return acc;
}, {});
}
return getSupportedCredential(opts ? {
...opts,
types: void 0
} : void 0);
}
__name(getSupportedCredentials, "getSupportedCredentials");
function determineVersionsFromIssuerMetadata(issuerMetadata) {
const versions = /* @__PURE__ */ new Set();
if ("credential_configurations_supported" in issuerMetadata) {
versions.add(OpenId4VCIVersion.VER_1_0_15);
}
if (versions.size === 0) {
versions.add(OpenId4VCIVersion.VER_UNKNOWN);
}
return Array.from(versions).sort().reverse();
}
__name(determineVersionsFromIssuerMetadata, "determineVersionsFromIssuerMetadata");
function getSupportedCredential(opts) {
const { issuerMetadata, types, format, version = OpenId4VCIVersion.VER_1_0_15 } = opts ?? {};
let credentialConfigurationsV15 = void 0;
if (issuerMetadata?.credential_configurations_supported && version >= OpenId4VCIVersion.VER_1_0_15) {
credentialConfigurationsV15 = issuerMetadata.credential_configurations_supported;
}
if (!issuerMetadata || !issuerMetadata.credential_configurations_supported && !issuerMetadata.credentials_supported) {
VCI_LOG_COMMON.warning(`No credential issuer metadata or supported credentials found for issuer`);
if (version >= OpenId4VCIVersion.VER_1_0_15) {
return credentialConfigurationsV15 ?? {};
} else {
return [];
}
}
const normalizedTypes = Array.isArray(types) ? types : types ? [
types
] : [];
const normalizedFormats = Array.isArray(format) ? format : format ? [
format
] : [];
function filterMatchingConfig(config) {
let isTypeMatch = normalizedTypes.length === 0;
const types2 = getTypesFromObject(config);
if (!isTypeMatch) {
if (normalizedTypes.length === 1 && config.id === normalizedTypes[0]) {
isTypeMatch = true;
} else if (types2) {
isTypeMatch = normalizedTypes.every((type) => types2.includes(type));
} else {
const hasValidCredentialDefinition = isW3cCredentialSupported(config) && "credential_definition" in config && config.credential_definition && typeof config.credential_definition === "object" && "type" in config.credential_definition && Array.isArray(config.credential_definition.type);
if (hasValidCredentialDefinition) {
const credDef = config.credential_definition;
isTypeMatch = normalizedTypes.every((type) => credDef.type.includes(type));
} else if (isW3cCredentialSupported(config) && "type" in config && Array.isArray(config.type)) {
isTypeMatch = normalizedTypes.every((type) => config.type.includes(type));
} else if (isW3cCredentialSupported(config) && "types" in config && Array.isArray(config.types)) {
isTypeMatch = normalizedTypes.every((type) => config.types.includes(type));
}
}
}
const isFormatMatch = normalizedFormats.length === 0 || normalizedFormats.includes(config.format);
return isTypeMatch && isFormatMatch ? config : void 0;
}
__name(filterMatchingConfig, "filterMatchingConfig");
if (credentialConfigurationsV15) {
return Object.entries(credentialConfigurationsV15).reduce((filteredConfigs, [id, config]) => {
if (filterMatchingConfig(config)) {
filteredConfigs[id] = config;
if (!config.id) {
config.id = id;
}
}
return filteredConfigs;
}, {});
}
if (issuerMetadata.credentials_supported && Array.isArray(issuerMetadata.credentials_supported)) {
return issuerMetadata.credentials_supported.filter(filterMatchingConfig);
}
return version >= OpenId4VCIVersion.VER_1_0_15 ? {} : [];
}
__name(getSupportedCredential, "getSupportedCredential");
function getIssuerDisplays(metadata, opts) {
const matchedDisplays = metadata.display?.filter((item) => !opts?.prefLocales || opts.prefLocales.length === 0 || item.locale && opts.prefLocales.includes(item.locale) || !item.locale) ?? [];
return matchedDisplays.sort((item) => item.locale ? opts?.prefLocales.indexOf(item.locale) ?? 1 : Number.MAX_VALUE);
}
__name(getIssuerDisplays, "getIssuerDisplays");
function getIssuerName(url, credentialIssuerMetadata) {
if (credentialIssuerMetadata) {
const displays = credentialIssuerMetadata ? getIssuerDisplays(credentialIssuerMetadata) : [];
for (const display of displays) {
if (display.name) {
return display.name;
}
}
}
return url;
}
__name(getIssuerName, "getIssuerName");
// lib/functions/FormatUtils.ts
function isFormat(formatObject, format) {
return formatObject.format === format;
}
__name(isFormat, "isFormat");
function isNotFormat(formatObject, format) {
return formatObject.format !== format;
}
__name(isNotFormat, "isNotFormat");
var isUniformFormat = /* @__PURE__ */ __name((format) => {
return [
"jwt_vc_json",
"jwt_vc_json-ld",
"ldp_vc",
"dc+sd-jwt",
"mso_mdoc"
].includes(format);
}, "isUniformFormat");
function getUniformFormat(format) {
if (isUniformFormat(format)) {
return format;
}
if (format.toLocaleLowerCase() === "jwt_vc" || format.toLocaleLowerCase() === "jwt") {
return "jwt_vc";
}
if (format === "ldp_vc" || format === "ldp") {
return "ldp_vc";
}
throw new Error(`Invalid format: ${format}`);
}
__name(getUniformFormat, "getUniformFormat");
function getFormatForVersion(format, version) {
const uniformFormat = isUniformFormat(format) ? format : getUniformFormat(format);
return uniformFormat;
}
__name(getFormatForVersion, "getFormatForVersion");
// lib/functions/ProofUtil.ts
import { Loggers as Loggers3 } from "@sphereon/ssi-types";
import { jwtDecode as jwtDecode2 } from "jwt-decode";
var logger3 = Loggers3.DEFAULT.get("sphereon:oid4vci:common");
var createProofOfPossession = /* @__PURE__ */ __name(async (popMode, callbacks, jwtProps, existingJwt) => {
if (!callbacks.signCallback) {
logger3.debug(`no jwt signer callback or arguments supplied!`);
throw new Error(BAD_PARAMS);
}
const jwtPayload = createJWT(popMode, jwtProps, existingJwt);
const jwt = await callbacks.signCallback(jwtPayload, jwtPayload.header.kid, popMode === "pop");
const proof = {
proof_type: "jwt",
jwt
};
try {
partiallyValidateJWS(jwt);
if (callbacks.verifyCallback) {
logger3.debug(`Calling supplied verify callback....`);
await callbacks.verifyCallback({
jwt,
kid: jwtPayload.header.kid
});
logger3.debug(`Supplied verify callback return success result`);
}
} catch {
logger3.debug(`JWS was not valid`);
throw new Error(JWS_NOT_VALID);
}
logger3.debug(`Proof of Possession JWT:\r
${jwt}`);
return proof;
}, "createProofOfPossession");
var partiallyValidateJWS = /* @__PURE__ */ __name((jws) => {
if (jws.split(".").length !== 3 || !jws.startsWith("ey")) {
throw new Error(JWS_NOT_VALID);
}
}, "partiallyValidateJWS");
var isJWS = /* @__PURE__ */ __name((token) => {
try {
partiallyValidateJWS(token);
return true;
} catch (e) {
return false;
}
}, "isJWS");
var extractBearerToken = /* @__PURE__ */ __name((authorizationHeader) => {
return authorizationHeader ? /Bearer (.*)/i.exec(authorizationHeader)?.[1] : void 0;
}, "extractBearerToken");
var validateJWT = /* @__PURE__ */ __name(async (jwt, opts) => {
if (!jwt) {
throw Error("No JWT was supplied");
}
if (!opts?.accessTokenVerificationCallback) {
VCI_LOG_COMMON.warning(`No access token verification callback supplied. Access tokens will not be verified, except for a very basic check`);
partiallyValidateJWS(jwt);
const header = jwtDecode2(jwt, {
header: true
});
const payload = jwtDecode2(jwt, {
header: false
});
return {
jwt: {
header,
payload
},
...header,
...payload
};
} else {
return await opts.accessTokenVerificationCallback({
jwt,
kid: opts.kid
});
}
}, "validateJWT");
var createJWT = /* @__PURE__ */ __name((mode, jwtProps, existingJwt) => {
const aud = mode === "pop" ? getJwtProperty("aud", true, jwtProps?.issuer, existingJwt?.payload?.aud) : getJwtProperty("aud", false, jwtProps?.aud, existingJwt?.payload?.aud);
const iss = mode === "pop" ? getJwtProperty("iss", false, jwtProps?.clientId, existingJwt?.payload?.iss) : getJwtProperty("iss", false, jwtProps?.issuer, existingJwt?.payload?.iss);
const client_id = mode === "JWT" ? getJwtProperty("client_id", false, jwtProps?.clientId, existingJwt?.payload?.client_id) : void 0;
const jti = getJwtProperty("jti", false, jwtProps?.jti, existingJwt?.payload?.jti);
const typ = getJwtProperty("typ", true, jwtProps?.typ, existingJwt?.header?.typ, "openid4vci-proof+jwt");
const nonce = getJwtProperty("nonce", false, jwtProps?.nonce, existingJwt?.payload?.nonce);
const alg = getJwtProperty("alg", false, jwtProps?.alg, existingJwt?.header?.alg, "ES256");
const kid = getJwtProperty("kid", false, jwtProps?.kid, existingJwt?.header?.kid);
const jwk = get