@sd-jwt/sd-jwt-vc
Version:
sd-jwt draft 7 implementation in typescript
774 lines (769 loc) • 30.1 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __reflectGet = Reflect.get;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
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);
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/index.ts
var index_exports = {};
__export(index_exports, {
BackgroundImageSchema: () => BackgroundImageSchema,
ClaimDisplaySchema: () => ClaimDisplaySchema,
ClaimPathSchema: () => ClaimPathSchema,
ClaimSchema: () => ClaimSchema,
ClaimSelectiveDisclosureSchema: () => ClaimSelectiveDisclosureSchema,
ColorSchemeSchema: () => ColorSchemeSchema,
ContrastSchema: () => ContrastSchema,
DisplaySchema: () => DisplaySchema,
LogoSchema: () => LogoSchema,
OrientationSchema: () => OrientationSchema,
RenderingSchema: () => RenderingSchema,
SDJwtVcInstance: () => SDJwtVcInstance,
SimpleRenderingSchema: () => SimpleRenderingSchema,
SvgTemplatePropertiesSchema: () => SvgTemplatePropertiesSchema,
SvgTemplateRenderingSchema: () => SvgTemplateRenderingSchema,
TypeMetadataFormatSchema: () => TypeMetadataFormatSchema
});
module.exports = __toCommonJS(index_exports);
// src/sd-jwt-vc-instance.ts
var import_token_status_list = require("@owf/token-status-list");
var import_core = require("@sd-jwt/core");
var import_zod2 = __toESM(require("zod"));
// src/sd-jwt-vc-type-metadata-format.ts
var import_zod = require("zod");
var BackgroundImageSchema = import_zod.z.looseObject({
/** REQUIRED. A URI pointing to the background image. */
uri: import_zod.z.string(),
/** OPTIONAL. An "integrity metadata" string as described in Section 7. */
"uri#integrity": import_zod.z.string().optional()
});
var LogoSchema = import_zod.z.looseObject({
/** REQUIRED. A URI pointing to the logo image. */
uri: import_zod.z.string(),
/** OPTIONAL. An "integrity metadata" string as described in Section 7. */
"uri#integrity": import_zod.z.string().optional(),
/** OPTIONAL. A string containing alternative text for the logo image. */
alt_text: import_zod.z.string().optional()
});
var SimpleRenderingSchema = import_zod.z.looseObject({
/** OPTIONAL. Logo metadata to display for the credential. */
logo: LogoSchema.optional(),
/** OPTIONAL. RGB color value for the credential background (e.g., "#FFFFFF"). */
background_color: import_zod.z.string().optional(),
/** OPTIONAL. RGB color value for the credential text (e.g., "#000000"). */
text_color: import_zod.z.string().optional(),
/** OPTIONAL. An object containing information about the background image to be displayed for the type. */
background_image: BackgroundImageSchema.optional()
});
var OrientationSchema = import_zod.z.enum(["portrait", "landscape"]);
var ColorSchemeSchema = import_zod.z.enum(["light", "dark"]);
var ContrastSchema = import_zod.z.enum(["normal", "high"]);
var SvgTemplatePropertiesSchema = import_zod.z.looseObject({
/** OPTIONAL. Orientation optimized for the template. */
orientation: OrientationSchema.optional(),
/** OPTIONAL. Color scheme optimized for the template. */
color_scheme: ColorSchemeSchema.optional(),
/** OPTIONAL. Contrast level optimized for the template. */
contrast: ContrastSchema.optional()
});
var SvgTemplateRenderingSchema = import_zod.z.looseObject({
/** REQUIRED. A URI pointing to the SVG template. */
uri: import_zod.z.string(),
/** OPTIONAL. An "integrity metadata" string as described in Section 7. */
"uri#integrity": import_zod.z.string().optional(),
/** REQUIRED if more than one SVG template is present. */
properties: SvgTemplatePropertiesSchema.optional()
});
var RenderingSchema = import_zod.z.looseObject({
/** OPTIONAL. Simple rendering metadata. */
simple: SimpleRenderingSchema.optional(),
/** OPTIONAL. Array of SVG template rendering objects. */
svg_templates: import_zod.z.array(SvgTemplateRenderingSchema).optional(),
/**
* OPTIONAL. Array of SVG template rendering objects.
* @deprecated use `svg_templates` (plural) instead.
*/
svg_template: import_zod.z.array(SvgTemplateRenderingSchema).optional()
}).transform((_a) => {
var _b = _a, { svg_template, svg_templates } = _b, rest = __objRest(_b, ["svg_template", "svg_templates"]);
return __spreadProps(__spreadValues({}, rest), {
svg_templates: svg_templates != null ? svg_templates : svg_template
});
});
var DisplaySchema = import_zod.z.looseObject({
/**
* Language tag according to RFC 5646 (e.g., "en", "de").
* @deprecated - use `locale` instead
*/
lang: import_zod.z.string().optional(),
/**
* REQUIRED (preferred). Language tag according to RFC 5646.
* Alias for `lang` - either `lang` or `locale` must be provided.
*/
locale: import_zod.z.string().optional(),
/** REQUIRED. Human-readable name for the credential type. */
name: import_zod.z.string(),
/** OPTIONAL. Description of the credential type for end users. */
description: import_zod.z.string().optional(),
/** OPTIONAL. Rendering information (simple or SVG) for the credential. */
rendering: RenderingSchema.optional()
}).transform((_a) => {
var _b = _a, { lang, locale } = _b, rest = __objRest(_b, ["lang", "locale"]);
return __spreadProps(__spreadValues({}, rest), {
locale: locale != null ? locale : lang
});
}).refine(({ locale }) => locale !== void 0, {
message: "Either locale (preferred) or lang (spec name, deprecated) MUST be defined on claim display entry."
});
var ClaimPathSchema = import_zod.z.array(import_zod.z.string().nullable());
var ClaimDisplaySchema = import_zod.z.looseObject({
/**
* Language tag according to RFC 5646.
* @deprecated - use `locale` instead
*/
lang: import_zod.z.string().optional(),
/**
* REQUIRED (preferred). Language tag according to RFC 5646.
* Alias for `lang` - either `lang` or `locale` must be provided.
*/
locale: import_zod.z.string().optional(),
/** REQUIRED. Human-readable label for the claim. */
label: import_zod.z.string().optional(),
/**
* Human-readable label for the claim.
* @deprecated - use `label` instead
*/
name: import_zod.z.string().optional(),
/** OPTIONAL. Description of the claim for end users. */
description: import_zod.z.string().optional()
}).transform((_a) => {
var _b = _a, { lang, name, label, locale } = _b, rest = __objRest(_b, ["lang", "name", "label", "locale"]);
return __spreadProps(__spreadValues({}, rest), {
locale: locale != null ? locale : lang,
label: label != null ? label : name
});
}).refine(({ locale }) => locale !== void 0, {
message: "Either locale (preferred) or lang (deprecated) MUST be defined on claim display entry."
}).refine(({ label }) => label !== void 0, {
message: "Either label (preferred) or name (deprecated) MUST be defined on claim display entry."
});
var ClaimSelectiveDisclosureSchema = import_zod.z.enum([
"always",
"allowed",
"never"
]);
var ClaimSchema = import_zod.z.looseObject({
/**
* REQUIRED. Array of one or more paths to the claim in the credential subject.
* Each path is an array of strings (or null for array elements).
*/
path: ClaimPathSchema,
/** OPTIONAL. Display metadata in multiple languages. */
display: import_zod.z.array(ClaimDisplaySchema).optional(),
/** OPTIONAL. Controls whether the claim must, may, or must not be selectively disclosed. */
sd: ClaimSelectiveDisclosureSchema.optional(),
/**
* OPTIONAL. A boolean indicating whether the claim must be present in the Unsecured Payload
* of the SD-JWT VC. Default is false if not specified.
*/
mandatory: import_zod.z.boolean().optional(),
/**
* OPTIONAL. Unique string identifier for referencing the claim in an SVG template.
* Must consist of alphanumeric characters or underscores and must not start with a digit.
*/
svg_id: import_zod.z.string().optional()
});
var TypeMetadataFormatSchema = import_zod.z.looseObject({
/** REQUIRED. A URI uniquely identifying the credential type. */
vct: import_zod.z.string(),
/** OPTIONAL. Human-readable name for developers. */
name: import_zod.z.string().optional(),
/** OPTIONAL. Human-readable description for developers. */
description: import_zod.z.string().optional(),
/** OPTIONAL. URI of another type that this one extends. */
extends: import_zod.z.string().optional(),
/** OPTIONAL. Integrity metadata for the 'extends' field. */
"extends#integrity": import_zod.z.string().optional(),
/** OPTIONAL. Array of localized display metadata for the type. */
display: import_zod.z.array(DisplaySchema).optional(),
/** OPTIONAL. Array of claim metadata. */
claims: import_zod.z.array(ClaimSchema).optional()
});
// src/sd-jwt-vc-instance.ts
var SDJwtVcInstance = class _SDJwtVcInstance extends import_core.SDJwtInstance {
constructor(userConfig) {
super(userConfig);
/**
* The type of the SD-JWT-VC set in the header.typ field.
*/
this.type = "dc+sd-jwt";
this.userConfig = {};
if (userConfig) {
this.userConfig = userConfig;
}
}
/**
* Validates if the disclosure frame attempts to selectively disclose protected SD-JWT-VC claims.
* @param disclosureFrame
*/
validateDisclosureFrame(disclosureFrame) {
if ((disclosureFrame == null ? void 0 : disclosureFrame._sd) && Array.isArray(disclosureFrame._sd) && disclosureFrame._sd.length > 0) {
const reservedNames = ["iss", "nbf", "exp", "cnf", "vct", "status"];
const reservedNamesInDisclosureFrame = disclosureFrame._sd.filter(
(key) => reservedNames.includes(String(key))
);
if (reservedNamesInDisclosureFrame.length > 0) {
throw new import_core.SDJWTException("Cannot disclose protected field");
}
}
}
/**
* Fetches the status list from the uri with a timeout of 10 seconds.
* @param uri The URI to fetch from.
* @returns A promise that resolves to a compact JWT.
*/
statusListFetcher(uri) {
return __async(this, null, function* () {
var _a;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 1e4);
try {
const response = yield fetch(uri, {
signal: controller.signal,
headers: { Accept: "application/statuslist+jwt" }
});
if (!response.ok) {
throw new Error(
`Error fetching status list: ${response.status} ${yield response.text()}`
);
}
if (!((_a = response.headers.get("content-type")) == null ? void 0 : _a.includes("application/statuslist+jwt"))) {
throw new Error("Invalid content type");
}
return response.text();
} finally {
clearTimeout(timeoutId);
}
});
}
/**
* Validates the status, throws an error if the status is not 0.
* @param status
* @returns
*/
statusValidator(status) {
return __async(this, null, function* () {
if (status !== 0) throw new import_core.SDJWTException("Status is not valid");
return Promise.resolve();
});
}
/**
* Verifies the SD-JWT-VC. It will validate the signature, the keybindings when required, the status, and the VCT.
* @param currentDate current time in seconds
*/
verify(encodedSDJwt, options) {
return __async(this, null, function* () {
const result = yield __superGet(_SDJwtVcInstance.prototype, this, "verify").call(this, encodedSDJwt, options).then((res) => {
return {
payload: res.payload,
header: res.header,
kb: res.kb
};
});
yield this.verifyStatus(result, options);
if (this.userConfig.loadTypeMetadataFormat) {
const resolvedTypeMetadata = yield this.fetchVct(result);
result.typeMetadata = resolvedTypeMetadata;
}
return result;
});
}
/**
* Safe verification that collects all errors instead of failing fast.
* Returns a result object with either the verified data or an array of all errors.
* This includes SD-JWT-VC specific validations like status and VCT metadata.
*
* @param encodedSDJwt - The encoded SD-JWT-VC to verify
* @param options - Verification options
* @returns A SafeVerifyResult containing either success data or collected errors
*/
safeVerify(encodedSDJwt, options) {
return __async(this, null, function* () {
const errors = [];
const addError = (code, message, details) => {
errors.push({ code, message, details });
};
const baseResult = yield __superGet(_SDJwtVcInstance.prototype, this, "safeVerify").call(this, encodedSDJwt, options);
if (!baseResult.success) {
errors.push(...baseResult.errors);
}
let result;
if (baseResult.success) {
result = {
payload: baseResult.data.payload,
header: baseResult.data.header,
kb: baseResult.data.kb
};
} else {
try {
const { payload, header } = yield import_core.SDJwt.extractJwt(encodedSDJwt);
if (payload) {
result = {
payload,
header,
kb: void 0
};
}
} catch (e) {
}
}
if (result) {
try {
yield this.verifyStatus(result, options);
} catch (e) {
const error = (0, import_core.ensureError)(e);
const errorMessage = error.message;
if (errorMessage.includes("Status is not valid")) {
addError("STATUS_INVALID", errorMessage, error);
} else {
addError(
"STATUS_VERIFICATION_FAILED",
`Status verification failed: ${errorMessage}`,
error
);
}
}
if (this.userConfig.loadTypeMetadataFormat) {
try {
const resolvedTypeMetadata = yield this.fetchVct(result);
if (result) {
result.typeMetadata = resolvedTypeMetadata;
}
} catch (e) {
addError(
"VCT_VERIFICATION_FAILED",
`VCT verification failed: ${(0, import_core.ensureError)(e).message}`,
e
);
}
}
}
if (errors.length > 0) {
return { success: false, errors };
}
if (!result) {
return {
success: false,
errors: [
{
code: "INVALID_SD_JWT",
message: "Failed to construct verification result"
}
]
};
}
return {
success: true,
data: result
};
});
}
/**
* Gets VCT Metadata of the raw SD-JWT-VC. Returns the type metadata format. If the SD-JWT-VC is invalid or does not contain a vct claim, an error is thrown.
*
* It may return `undefined` if the fetcher returned an undefined value (instead of throwing an error).
*
* @param encodedSDJwt
* @returns
*/
getVct(encodedSDJwt) {
return __async(this, null, function* () {
const { payload, header } = yield import_core.SDJwt.extractJwt(encodedSDJwt);
if (!payload) {
throw new import_core.SDJWTException("JWT payload is missing");
}
const result = {
payload,
header,
kb: void 0
};
return this.fetchVct(result);
});
}
/**
* Validates the integrity of the response if the integrity is passed. If the integrity does not match, an error is thrown.
* @param integrity
* @param response
*/
validateIntegrity(response, url, integrity) {
return __async(this, null, function* () {
if (!integrity) return;
const arrayBuffer = yield response.arrayBuffer();
const alg = integrity.split("-")[0];
if (!this.userConfig.hasher) {
throw new import_core.SDJWTException("Hasher not found");
}
const hashBuffer = yield this.userConfig.hasher(arrayBuffer, alg);
const integrityHash = integrity.split("-")[1];
const hash = Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
if (hash !== integrityHash) {
throw new Error(
`Integrity check for ${url} failed: is ${hash}, but expected ${integrityHash}`
);
}
});
}
/**
* Fetches the content from the url with a timeout of 10 seconds.
* @param url
* @returns
*/
fetchWithIntegrity(url, integrity) {
return __async(this, null, function* () {
var _a;
try {
const response = yield fetch(url, {
signal: AbortSignal.timeout((_a = this.userConfig.timeout) != null ? _a : 1e4)
});
if (!response.ok) {
const errorText = yield response.text();
throw new Error(
`Error fetching ${url}: ${response.status} ${response.statusText} - ${errorText}`
);
}
yield this.validateIntegrity(response.clone(), url, integrity);
const data = yield response.json();
return data;
} catch (e) {
const error = (0, import_core.ensureError)(e);
if (error.name === "TimeoutError") {
throw new Error(`Request to ${url} timed out`);
}
throw error;
}
});
}
/**
* Verifies the VCT of the SD-JWT-VC. Returns the type metadata format.
* Resolves the full extends chain according to spec sections 6.4, 8.2, and 9.5.
* @param result
* @returns
*/
fetchVct(result) {
return __async(this, null, function* () {
const typeMetadataFormat = yield this.fetchSingleVct(
result.payload.vct,
result.payload["vct#integrity"]
);
if (!typeMetadataFormat) return void 0;
if (!typeMetadataFormat.extends) {
return {
mergedTypeMetadata: typeMetadataFormat,
typeMetadataChain: [typeMetadataFormat],
vctValues: [typeMetadataFormat.vct]
};
}
return this.resolveVctExtendsChain(typeMetadataFormat);
});
}
/**
* Checks if two claim paths are equal by comparing each element.
* @param path1 First claim path
* @param path2 Second claim path
* @returns True if paths are equal, false otherwise
*/
claimPathsEqual(path1, path2) {
if (path1.length !== path2.length) return false;
return path1.every((element, index) => element === path2[index]);
}
/**
* Validates that extending claim metadata respects the constraints from spec section 9.5.1.
* @param baseClaim The base claim metadata
* @param extendingClaim The extending claim metadata
* @throws SDJWTException if validation fails
*/
validateClaimExtension(baseClaim, extendingClaim) {
if (baseClaim.sd && extendingClaim.sd) {
if ((baseClaim.sd === "always" || baseClaim.sd === "never") && baseClaim.sd !== extendingClaim.sd) {
const pathStr = JSON.stringify(extendingClaim.path);
throw new import_core.SDJWTException(
`Cannot change 'sd' property from '${baseClaim.sd}' to '${extendingClaim.sd}' for claim at path ${pathStr}`
);
}
}
}
/**
* Merges two type metadata formats, with the extending metadata overriding the base metadata.
* According to spec section 9.5:
* - All claim metadata from the extended type are inherited
* - The child type can add new claims or properties
* - If the child type defines claim metadata with the same path as the extended type,
* the child type's object will override the corresponding object from the extended type
* According to spec section 9.5.1:
* - sd property can only be changed from 'allowed' (or omitted) to 'always' or 'never'
* - sd property cannot be changed from 'always' or 'never' to a different value
* According to spec section 8.2:
* - If the extending type defines its own display property, the original display metadata is ignored
* Note: The spec also mentions 'mandatory' property constraints, but this is not currently
* defined in the Claim type and will be validated when that property is added to the type.
* @param base The base type metadata format
* @param extending The extending type metadata format
* @returns The merged type metadata format
*/
mergeTypeMetadata(base, extending) {
var _a, _b;
const merged = __spreadValues({}, extending);
if (base.claims || extending.claims) {
const baseClaims = (_a = base.claims) != null ? _a : [];
const extendingClaims = (_b = extending.claims) != null ? _b : [];
for (const extendingClaim of extendingClaims) {
const matchingBaseClaim = baseClaims.find(
(baseClaim) => this.claimPathsEqual(baseClaim.path, extendingClaim.path)
);
if (matchingBaseClaim) {
this.validateClaimExtension(matchingBaseClaim, extendingClaim);
}
}
const mergedClaims = [];
const extendedClaimsWithoutBase = [...extendingClaims];
for (const baseClaim of baseClaims) {
const extendingClaimIndex = extendedClaimsWithoutBase.findIndex(
(extendingClaim2) => this.claimPathsEqual(baseClaim.path, extendingClaim2.path)
);
const extendingClaim = extendingClaimIndex !== -1 ? extendedClaimsWithoutBase[extendingClaimIndex] : void 0;
if (extendingClaim) {
extendedClaimsWithoutBase.splice(extendingClaimIndex, 1);
}
mergedClaims.push(extendingClaim != null ? extendingClaim : baseClaim);
}
mergedClaims.push(...extendedClaimsWithoutBase);
merged.claims = mergedClaims;
}
if (!extending.display && base.display) {
merged.display = base.display;
}
return merged;
}
/**
* Resolves the full VCT chain by recursively fetching extended type metadata.
* Implements security considerations from spec section 10.3 for circular dependencies.
* @param vct The VCT URI to resolve
* @param integrity Optional integrity metadata for the VCT
* @param depth Current depth in the chain
* @param visitedVcts Set of already visited VCT URIs to detect circular dependencies
* @returns The fully resolved and merged type metadata format
*/
resolveVctExtendsChain(_0) {
return __async(this, arguments, function* (parentTypeMetadata, depth = 1, visitedVcts = new Set(parentTypeMetadata.vct)) {
var _a;
const maxDepth = (_a = this.userConfig.maxVctExtendsDepth) != null ? _a : 5;
if (maxDepth !== -1 && depth > maxDepth) {
throw new import_core.SDJWTException(
`Maximum VCT extends depth of ${maxDepth} exceeded`
);
}
if (!parentTypeMetadata.extends) {
throw new import_core.SDJWTException(
`Type metadata for vct '${parentTypeMetadata.vct}' has no 'extends' field. Unable to resolve extended type metadata document.`
);
}
if (visitedVcts.has(parentTypeMetadata.extends)) {
throw new import_core.SDJWTException(
`Circular dependency detected in VCT extends chain: ${parentTypeMetadata.extends}`
);
}
visitedVcts.add(parentTypeMetadata.extends);
const extendedTypeMetadata = yield this.fetchSingleVct(
parentTypeMetadata.extends,
parentTypeMetadata["extends#integrity"]
);
if (!extendedTypeMetadata) {
throw new import_core.SDJWTException(
`Resolving VCT extends value '${parentTypeMetadata.extends}' resulted in an undefined result.`
);
}
let resolvedTypeMetadata;
if (extendedTypeMetadata.extends) {
resolvedTypeMetadata = yield this.resolveVctExtendsChain(
extendedTypeMetadata,
depth + 1,
visitedVcts
);
} else {
resolvedTypeMetadata = {
mergedTypeMetadata: extendedTypeMetadata,
typeMetadataChain: [extendedTypeMetadata],
vctValues: [extendedTypeMetadata.vct]
};
}
const mergedTypeMetadata = this.mergeTypeMetadata(
resolvedTypeMetadata.mergedTypeMetadata,
parentTypeMetadata
);
return {
mergedTypeMetadata,
typeMetadataChain: [
parentTypeMetadata,
...resolvedTypeMetadata.typeMetadataChain
],
vctValues: [parentTypeMetadata.vct, ...resolvedTypeMetadata.vctValues]
};
});
}
/**
* Fetches and verifies the VCT Metadata for a VCT value.
* @param result
* @returns
*/
fetchSingleVct(vct, integrity) {
return __async(this, null, function* () {
var _a;
const fetcher = (_a = this.userConfig.vctFetcher) != null ? _a : ((uri, integrity2) => this.fetchWithIntegrity(uri, integrity2));
const data = yield fetcher(vct, integrity);
if (!data) return void 0;
const validated = TypeMetadataFormatSchema.safeParse(data);
if (!validated.success) {
throw new import_core.SDJWTException(
`Invalid VCT type metadata for vct '${vct}':
${import_zod2.default.prettifyError(validated.error)}`
);
}
return validated.data;
});
}
/**
* Verifies the status of the SD-JWT-VC.
* @param result
* @param options
*/
verifyStatus(result, options) {
return __async(this, null, function* () {
var _a, _b, _c;
if (options == null ? void 0 : options.disableStatusVerification) {
return;
}
if (result.payload.status) {
if (result.payload.status.status_list) {
const fetcher = (_a = this.userConfig.statusListFetcher) != null ? _a : this.statusListFetcher.bind(this);
const statusListJWT = yield fetcher(
result.payload.status.status_list.uri
);
const slJWT = import_core.Jwt.fromEncode(statusListJWT);
if (!this.userConfig.verifier || !this.userConfig.statusVerifier) {
throw new import_core.SDJWTException("Verifier not found for status list JWT");
}
yield slJWT.verify(
(_b = this.userConfig.statusVerifier) != null ? _b : this.userConfig.verifier,
options
).catch((err) => {
throw new import_token_status_list.SLException(
`Status List JWT verification failed: ${err.message}`,
err.details
);
});
const statusList = (0, import_token_status_list.getListFromStatusListJWT)(statusListJWT);
const status = statusList.getStatus(
result.payload.status.status_list.idx
);
const statusValidator = (_c = this.userConfig.statusValidator) != null ? _c : this.statusValidator.bind(this);
yield statusValidator(status);
}
}
});
}
config(newConfig) {
super.config(newConfig);
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
BackgroundImageSchema,
ClaimDisplaySchema,
ClaimPathSchema,
ClaimSchema,
ClaimSelectiveDisclosureSchema,
ColorSchemeSchema,
ContrastSchema,
DisplaySchema,
LogoSchema,
OrientationSchema,
RenderingSchema,
SDJwtVcInstance,
SimpleRenderingSchema,
SvgTemplatePropertiesSchema,
SvgTemplateRenderingSchema,
TypeMetadataFormatSchema
});