@sd-jwt/sd-jwt-vc 0.24.0-alpha-20261029093248 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -418,6 +418,7 @@ var SDJwtVcInstance = class extends SDJwtInstance {
418
418
  "exp",
419
419
  "cnf",
420
420
  "vct",
421
+ "vct#integrity",
421
422
  "status"
422
423
  ];
423
424
  if (disclosureFrame._sd.filter((key) => reservedNames.includes(String(key))).length > 0) throw new SDJWTException("Cannot disclose protected field");
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["z"],"sources":["../src/sd-jwt-vc-type-metadata-format.ts","../src/type-metadata-verification.ts","../src/sd-jwt-vc-instance.ts"],"sourcesContent":["import { z } from 'zod'\n\nexport const BackgroundImageSchema = z.looseObject({\n /** REQUIRED. A URI pointing to the background image. */\n uri: z.string(),\n /** OPTIONAL. An \"integrity metadata\" string as described in Section 7. */\n 'uri#integrity': z.string().optional(),\n})\nexport type BackgroundImage = z.infer<typeof BackgroundImageSchema>\n\n/**\n * Logo metadata used in rendering a credential.\n */\nexport const LogoSchema = z.looseObject({\n /** REQUIRED. A URI pointing to the logo image. */\n uri: z.string(),\n /** OPTIONAL. An \"integrity metadata\" string as described in Section 7. */\n 'uri#integrity': z.string().optional(),\n /** OPTIONAL. A string containing alternative text for the logo image. */\n alt_text: z.string().optional(),\n})\n\nexport type Logo = z.infer<typeof LogoSchema>\n\n/**\n * The simple rendering method is intended for applications that do not support SVG.\n */\nexport const SimpleRenderingSchema = z.looseObject({\n /** OPTIONAL. Logo metadata to display for the credential. */\n logo: LogoSchema.optional(),\n /** OPTIONAL. RGB color value for the credential background (e.g., \"#FFFFFF\"). */\n background_color: z.string().optional(),\n /** OPTIONAL. RGB color value for the credential text (e.g., \"#000000\"). */\n text_color: z.string().optional(),\n /** OPTIONAL. An object containing information about the background image to be displayed for the type. */\n background_image: BackgroundImageSchema.optional(),\n})\n\nexport type SimpleRendering = z.infer<typeof SimpleRenderingSchema>\n\n/** Enum of valid values for rendering orientation. */\nexport const OrientationSchema = z.enum(['portrait', 'landscape'])\n\n/** Enum of valid values for rendering color schemes. */\nexport const ColorSchemeSchema = z.enum(['light', 'dark'])\n\n/** Enum of valid values for rendering contrast. */\nexport const ContrastSchema = z.enum(['normal', 'high'])\n\n/**\n * Properties that describe the display preferences for an SVG template rendering.\n */\nexport const SvgTemplatePropertiesSchema = z.looseObject({\n /** OPTIONAL. Orientation optimized for the template. */\n orientation: OrientationSchema.optional(),\n /** OPTIONAL. Color scheme optimized for the template. */\n color_scheme: ColorSchemeSchema.optional(),\n /** OPTIONAL. Contrast level optimized for the template. */\n contrast: ContrastSchema.optional(),\n})\n\nexport type SvgTemplateProperties = z.infer<typeof SvgTemplatePropertiesSchema>\n\n/**\n * SVG rendering metadata containing URI and optional integrity and properties.\n */\nexport const SvgTemplateRenderingSchema = z.looseObject({\n /** REQUIRED. A URI pointing to the SVG template. */\n uri: z.string(),\n /** OPTIONAL. An \"integrity metadata\" string as described in Section 7. */\n 'uri#integrity': z.string().optional(),\n /** REQUIRED if more than one SVG template is present. */\n properties: SvgTemplatePropertiesSchema.optional(),\n})\n\nexport type SvgTemplateRendering = z.infer<typeof SvgTemplateRenderingSchema>\n\n/**\n * Rendering metadata, either simple or SVG-based, for a credential.\n */\nexport const RenderingSchema = z\n .looseObject({\n /** OPTIONAL. Simple rendering metadata. */\n simple: SimpleRenderingSchema.optional(),\n /** OPTIONAL. Array of SVG template rendering objects. */\n svg_templates: z.array(SvgTemplateRenderingSchema).optional(),\n /**\n * OPTIONAL. Array of SVG template rendering objects.\n * @deprecated use `svg_templates` (plural) instead.\n */\n svg_template: z.array(SvgTemplateRenderingSchema).optional(),\n })\n .transform(({ svg_template, svg_templates, ...rest }) => ({\n ...rest,\n svg_templates: svg_templates ?? svg_template,\n }))\n\nexport type Rendering = z.infer<typeof RenderingSchema>\n\n/**\n * Display metadata associated with a credential type.\n */\nexport const DisplaySchema = z\n .looseObject({\n /**\n * Language tag according to RFC 5646 (e.g., \"en\", \"de\").\n * @deprecated - use `locale` instead\n */\n lang: z.string().optional(),\n\n /**\n * REQUIRED (preferred). Language tag according to RFC 5646.\n * Alias for `lang` - either `lang` or `locale` must be provided.\n */\n locale: z.string().optional(),\n\n /** REQUIRED. Human-readable name for the credential type. */\n name: z.string(),\n /** OPTIONAL. Description of the credential type for end users. */\n description: z.string().optional(),\n /** OPTIONAL. Rendering information (simple or SVG) for the credential. */\n rendering: RenderingSchema.optional(),\n })\n .transform(({ lang, locale, ...rest }) => ({\n ...rest,\n locale: locale ?? lang,\n }))\n .refine(({ locale }) => locale !== undefined, {\n message: 'Either locale (preferred) or lang (spec name, deprecated) MUST be defined on claim display entry.',\n })\n\nexport type Display = z.infer<typeof DisplaySchema>\n\n/**\n * Claim path within the credential's JSON structure.\n * Example: [\"address\", \"street_address\"]\n */\nexport const ClaimPathSchema = z.array(z.string().nullable())\n\nexport type ClaimPath = z.infer<typeof ClaimPathSchema>\n\n/**\n * Display metadata for a specific claim.\n */\nexport const ClaimDisplaySchema = z\n .looseObject({\n /**\n * Language tag according to RFC 5646.\n * @deprecated - use `locale` instead\n */\n lang: z.string().optional(),\n\n /**\n * REQUIRED (preferred). Language tag according to RFC 5646.\n * Alias for `lang` - either `lang` or `locale` must be provided.\n */\n locale: z.string().optional(),\n\n /** REQUIRED. Human-readable label for the claim. */\n label: z.string().optional(),\n\n /**\n * Human-readable label for the claim.\n * @deprecated - use `label` instead\n */\n name: z.string().optional(),\n\n /** OPTIONAL. Description of the claim for end users. */\n description: z.string().optional(),\n })\n .transform(({ lang, name, label, locale, ...rest }) => ({\n ...rest,\n locale: locale ?? lang,\n label: label ?? name,\n }))\n .refine(({ locale }) => locale !== undefined, {\n message: 'Either locale (preferred) or lang (deprecated) MUST be defined on claim display entry.',\n })\n .refine(({ label }) => label !== undefined, {\n message: 'Either label (preferred) or name (deprecated) MUST be defined on claim display entry.',\n })\n\nexport type ClaimDisplay = z.infer<typeof ClaimDisplaySchema>\n\n/**\n * Indicates whether a claim is selectively disclosable.\n */\nexport const ClaimSelectiveDisclosureSchema = z.enum(['always', 'allowed', 'never'])\n\nexport type ClaimSelectiveDisclosure = z.infer<typeof ClaimSelectiveDisclosureSchema>\n\n/**\n * Metadata for individual claims in the credential type.\n */\nexport const ClaimSchema = z.looseObject({\n /**\n * REQUIRED. Array of one or more paths to the claim in the credential subject.\n * Each path is an array of strings (or null for array elements).\n */\n path: ClaimPathSchema,\n /** OPTIONAL. Display metadata in multiple languages. */\n display: z.array(ClaimDisplaySchema).optional(),\n /** OPTIONAL. Controls whether the claim must, may, or must not be selectively disclosed. */\n sd: ClaimSelectiveDisclosureSchema.optional(),\n /**\n * OPTIONAL. A boolean indicating whether the claim must be present in the Unsecured Payload\n * of the SD-JWT VC. Default is false if not specified.\n */\n mandatory: z.boolean().optional(),\n /**\n * OPTIONAL. Unique string identifier for referencing the claim in an SVG template.\n * Must consist of alphanumeric characters or underscores and must not start with a digit.\n */\n svg_id: z.string().optional(),\n})\n\nexport type Claim = z.infer<typeof ClaimSchema>\n\n/**\n * Type metadata for a specific Verifiable Credential (VC) type.\n * Reference: https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-13.html#name-type-metadata-format\n */\nexport const TypeMetadataFormatSchema = z.looseObject({\n /** REQUIRED. A URI uniquely identifying the credential type. */\n vct: z.string(),\n /** OPTIONAL. Human-readable name for developers. */\n name: z.string().optional(),\n /** OPTIONAL. Human-readable description for developers. */\n description: z.string().optional(),\n /** OPTIONAL. URI of another type that this one extends. */\n extends: z.string().optional(),\n /** OPTIONAL. Integrity metadata for the 'extends' field. */\n 'extends#integrity': z.string().optional(),\n /** OPTIONAL. Array of localized display metadata for the type. */\n display: z.array(DisplaySchema).optional(),\n /** OPTIONAL. Array of claim metadata. */\n claims: z.array(ClaimSchema).optional(),\n})\n\n/**\n * The resolved type metadata. If you just want to use the type metadata, you should use `typeMetadata`.\n * In case additional processing is needed (e.g. for extensions in type metadata), you can use the `typeMetadataChain`\n */\nexport type ResolvedTypeMetadata = {\n /**\n * The merged type metadata based on the resolved `vct` document and all `extends` values.\n */\n mergedTypeMetadata: TypeMetadataFormat\n\n /**\n * The original type metadata documents, ordered from the extending type to the last extended type.\n */\n typeMetadataChain: [TypeMetadataFormat, ...TypeMetadataFormat[]]\n\n /**\n * The vct values present in the type metadata chain. This can be used for matching against e.g.\n * DCQL queries which can query an underlying type.\n */\n vctValues: [string, ...string[]]\n}\n\nexport type TypeMetadataFormat = z.infer<typeof TypeMetadataFormatSchema>\n","import { type Disclosure, SD_DIGEST, SD_LIST_KEY } from '@sd-jwt/core'\nimport type { Claim, ClaimPath, TypeMetadataFormat } from './sd-jwt-vc-type-metadata-format'\n\nexport type TypeMetadataVerificationResult = {\n extraClaims: ClaimPath[]\n missingMandatoryClaims: ClaimPath[]\n undisclosedMandatoryClaims: ClaimPath[]\n invalidNonSelectivelyDisclosableClaims: ClaimPath[]\n invalidSelectivelyDisclosableClaims: ClaimPath[]\n}\n\nconst REGISTERED_CLAIMS = ['iss', 'nbf', 'exp', 'iat', 'sub', 'cnf', 'vct', 'vct#integrity', 'status']\n\ntype PresentClaim = {\n path: Array<string | number>\n isSd: boolean\n}\n\nexport function claimPathsEqual(path1: ClaimPath, path2: ClaimPath): boolean {\n if (path1.length !== path2.length) return false\n return path1.every((seg, idx) => seg === path2[idx])\n}\n\nfunction segmentsMatch(claimPath: ClaimPath, presentPath: Array<string | number>, length: number): boolean {\n for (let i = 0; i < length; i++) {\n const seg = claimPath[i]\n if (seg === null ? typeof presentPath[i] !== 'number' : seg !== presentPath[i]) return false\n }\n return true\n}\n\nfunction claimPathMatches(claimPath: ClaimPath, presentPath: Array<string | number>): boolean {\n return claimPath.length === presentPath.length && segmentsMatch(claimPath, presentPath, claimPath.length)\n}\n\nfunction isArrayElementDigest(value: unknown): value is { [SD_LIST_KEY]: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 1 &&\n typeof (value as Record<string, unknown>)[SD_LIST_KEY] === 'string'\n )\n}\n\nfunction collectPresentClaims(payload: Record<string, unknown>, disclosures: Record<string, Disclosure>) {\n const claims: PresentClaim[] = []\n\n const visit = (node: unknown, path: Array<string | number>) => {\n if (typeof node !== 'object' || node === null) return\n\n if (Array.isArray(node)) {\n node.forEach((element, index) => {\n if (isArrayElementDigest(element)) {\n const disclosure = disclosures[element[SD_LIST_KEY]]\n if (!disclosure) return\n claims.push({ path: [...path, index], isSd: true })\n visit(disclosure.value, [...path, index])\n } else {\n claims.push({ path: [...path, index], isSd: false })\n visit(element, [...path, index])\n }\n })\n return\n }\n\n const record = node as Record<string, unknown>\n for (const [key, value] of Object.entries(record)) {\n if (key === SD_DIGEST || (path.length === 0 && key === '_sd_alg')) continue\n claims.push({ path: [...path, key], isSd: false })\n visit(value, [...path, key])\n }\n\n const digests = Array.isArray(record[SD_DIGEST]) ? record[SD_DIGEST] : []\n for (const digest of digests) {\n const disclosure = typeof digest === 'string' ? disclosures[digest] : undefined\n if (!disclosure || typeof disclosure.key !== 'string') continue\n claims.push({ path: [...path, disclosure.key], isSd: true })\n visit(disclosure.value, [...path, disclosure.key])\n }\n }\n\n visit(payload, [])\n return claims\n}\n\ntype ClaimStatus = 'present' | 'missing' | 'undisclosed'\n\nfunction childEntries(node: unknown, segment: string | null, disclosures: Record<string, Disclosure>) {\n const present: Array<{ index: string | number; value: unknown }> = []\n let hidden = false\n\n if (segment === null) {\n if (!Array.isArray(node)) return { present, hidden }\n node.forEach((element, index) => {\n if (!isArrayElementDigest(element)) {\n present.push({ index, value: element })\n return\n }\n const disclosure = disclosures[element[SD_LIST_KEY]]\n if (disclosure) present.push({ index, value: disclosure.value })\n else hidden = true\n })\n return { present, hidden }\n }\n\n if (typeof node !== 'object' || node === null || Array.isArray(node)) return { present, hidden }\n const record = node as Record<string, unknown>\n // biome-ignore lint/suspicious/noPrototypeBuiltins: `Object.hasOwn` is not in the ES2020 lib this package targets\n if (segment !== SD_DIGEST && Object.prototype.hasOwnProperty.call(record, segment)) {\n present.push({ index: segment, value: record[segment] })\n }\n\n const digests = Array.isArray(record[SD_DIGEST]) ? record[SD_DIGEST] : []\n for (const digest of digests) {\n const disclosure = typeof digest === 'string' ? disclosures[digest] : undefined\n if (!disclosure) hidden = true\n else if (disclosure.key === segment) present.push({ index: segment, value: disclosure.value })\n }\n return { present, hidden }\n}\n\nfunction mandatoryClaimStatus(\n claim: Claim,\n metadataClaims: Claim[],\n packedPayload: Record<string, unknown>,\n disclosures: Record<string, Disclosure>\n): ClaimStatus {\n const sdOf = (length: number) =>\n metadataClaims.find((mc) => claimPathsEqual(mc.path, claim.path.slice(0, length)))?.sd\n\n const walk = (node: unknown, depth: number): ClaimStatus => {\n if (depth === claim.path.length) return 'present'\n\n const segment = claim.path[depth]\n const { present, hidden } = childEntries(node, segment, disclosures)\n let status: ClaimStatus = 'present'\n for (const child of present) {\n const childStatus = walk(child.value, depth + 1)\n if (childStatus === 'missing') return 'missing'\n if (childStatus === 'undisclosed') status = 'undisclosed'\n }\n\n if (segment === null) {\n if (!Array.isArray(node)) return 'missing'\n return present.length === 0 && hidden ? 'undisclosed' : status\n }\n if (present.length > 0) return status\n\n return hidden && sdOf(depth + 1) !== 'never' ? 'undisclosed' : 'missing'\n }\n\n return walk(packedPayload, 0)\n}\n\nfunction toCanonicalClaimPath(path: Array<string | number>): ClaimPath {\n return path.map((seg) => (typeof seg === 'number' ? null : seg))\n}\n\nfunction createClaimPathSet() {\n const paths = new Map<string, ClaimPath>()\n return {\n add: (path: ClaimPath) => paths.set(JSON.stringify(path), path),\n values: () => Array.from(paths.values()),\n }\n}\n\n/**\n * Verifies the claims of an SD-JWT VC against type metadata.\n *\n * @param typeMetadata The type metadata to verify against. When it extends other type metadata, pass the merged\n * type metadata of the resolved chain.\n * @param packedPayload The payload of the SD-JWT VC as issued, with the `_sd` digests still in place. The payload\n * returned by `verify` is unpacked and cannot be used here.\n * @param disclosures The disclosures of the SD-JWT VC, keyed by their digest.\n */\nexport function verifyClaimsAgainstTypeMetadata(\n typeMetadata: TypeMetadataFormat,\n packedPayload: Record<string, unknown>,\n disclosures: Record<string, Disclosure>\n): TypeMetadataVerificationResult {\n const metadataClaims = typeMetadata.claims ?? []\n const presentClaims = collectPresentClaims(packedPayload, disclosures)\n\n const extraClaims = createClaimPathSet()\n const missingMandatoryClaims = createClaimPathSet()\n const undisclosedMandatoryClaims = createClaimPathSet()\n const invalidNonSelectivelyDisclosableClaims = createClaimPathSet()\n const invalidSelectivelyDisclosableClaims = createClaimPathSet()\n\n const hasDeclaredChildren = (claimPath: ClaimPath) =>\n metadataClaims.some(\n (mc) => mc.path.length > claimPath.length && claimPathsEqual(mc.path.slice(0, claimPath.length), claimPath)\n )\n\n const isCovered = (path: Array<string | number>) => {\n if (REGISTERED_CLAIMS.includes(String(path[0])) && !metadataClaims.some((mc) => mc.path[0] === path[0])) {\n return true\n }\n\n return metadataClaims.some(\n (mc) =>\n (path.length < mc.path.length && segmentsMatch(mc.path, path, path.length)) ||\n (path.length > mc.path.length && segmentsMatch(mc.path, path, mc.path.length) && !hasDeclaredChildren(mc.path))\n )\n }\n\n for (const presentClaim of presentClaims) {\n const matchingMetadataClaims = metadataClaims.filter((mc) => claimPathMatches(mc.path, presentClaim.path))\n\n if (matchingMetadataClaims.length === 0) {\n if (typeMetadata.claims && !isCovered(presentClaim.path)) extraClaims.add(toCanonicalClaimPath(presentClaim.path))\n continue\n }\n\n for (const metadataClaim of matchingMetadataClaims) {\n if (metadataClaim.sd === 'always' && !presentClaim.isSd) {\n invalidNonSelectivelyDisclosableClaims.add(metadataClaim.path)\n } else if (metadataClaim.sd === 'never' && presentClaim.isSd) {\n invalidSelectivelyDisclosableClaims.add(metadataClaim.path)\n }\n }\n }\n\n for (const metadataClaim of metadataClaims) {\n if (!metadataClaim.mandatory) continue\n const status = mandatoryClaimStatus(metadataClaim, metadataClaims, packedPayload, disclosures)\n if (status === 'missing') missingMandatoryClaims.add(metadataClaim.path)\n else if (status === 'undisclosed') undisclosedMandatoryClaims.add(metadataClaim.path)\n }\n\n const extraClaimPaths = extraClaims.values()\n return {\n extraClaims: extraClaimPaths.filter(\n (path) =>\n !extraClaimPaths.some(\n (other) => other.length < path.length && claimPathsEqual(other, path.slice(0, other.length))\n )\n ),\n missingMandatoryClaims: missingMandatoryClaims.values(),\n undisclosedMandatoryClaims: undisclosedMandatoryClaims.values(),\n invalidNonSelectivelyDisclosableClaims: invalidNonSelectivelyDisclosableClaims.values(),\n invalidSelectivelyDisclosableClaims: invalidSelectivelyDisclosableClaims.values(),\n }\n}\n","import { base64, isMediaType, secondsToDate } from '@owf/identity-common'\nimport {\n getListFromStatusListJWT,\n MediaTypes,\n SLException,\n type StatusListJWTHeaderParameters,\n type StatusListJWTPayload,\n StatusType,\n verifyStatusListJwtClaims,\n verifyStatusListJwtHeader,\n} from '@owf/token-status-list'\nimport {\n createHashMapping,\n type Disclosure,\n type DisclosureFrame,\n ensureError,\n getJwtTimeValidationOptions,\n getSDAlgAndPayload,\n Jwt,\n type SafeVerifyResult,\n SDJWTException,\n SDJwt,\n SDJwtInstance,\n unpackObj,\n type VerificationError,\n type VerificationErrorCode,\n type VerifierOptions,\n} from '@sd-jwt/core'\nimport z from 'zod'\nimport type {\n SDJWTVCConfig,\n StatusInvalidErrorDetails,\n StatusListFetcher,\n StatusListVerificationErrorDetails,\n StatusValidator,\n StatusValidatorContext,\n} from './sd-jwt-vc-config'\nimport type { SdJwtVcPayload } from './sd-jwt-vc-payload'\nimport {\n type Claim,\n type ResolvedTypeMetadata,\n type TypeMetadataFormat,\n TypeMetadataFormatSchema,\n} from './sd-jwt-vc-type-metadata-format'\nimport {\n claimPathsEqual,\n type TypeMetadataVerificationResult,\n verifyClaimsAgainstTypeMetadata,\n} from './type-metadata-verification'\nimport type { VerificationResult } from './verification-result'\n\n// SRI hash algorithms, ordered from weakest to strongest\nconst SRI_ALGORITHMS = ['sha256', 'sha384', 'sha512']\n\nexport class SDJwtVcInstance<T = unknown> extends SDJwtInstance<SdJwtVcPayload, T> {\n /**\n * The type of the SD-JWT-VC set in the header.typ field.\n */\n protected type = 'dc+sd-jwt'\n\n protected userConfig: SDJWTVCConfig<T> = {}\n\n constructor(userConfig?: SDJWTVCConfig<T>) {\n super(userConfig)\n if (userConfig) {\n this.userConfig = userConfig\n }\n }\n\n /**\n * Validates if the disclosure frame attempts to selectively disclose protected SD-JWT-VC claims.\n * @param disclosureFrame\n */\n protected validateDisclosureFrame(disclosureFrame?: DisclosureFrame<SdJwtVcPayload>): void {\n if (disclosureFrame?._sd && Array.isArray(disclosureFrame._sd) && disclosureFrame._sd.length > 0) {\n const reservedNames = ['iss', 'nbf', 'exp', 'cnf', 'vct', 'status']\n const reservedNamesInDisclosureFrame = disclosureFrame._sd.filter((key) => reservedNames.includes(String(key)))\n if (reservedNamesInDisclosureFrame.length > 0) {\n throw new SDJWTException('Cannot disclose protected field')\n }\n }\n }\n\n /**\n * Fetches the status list from the uri with a timeout of 10 seconds.\n * @param uri The URI to fetch from.\n * @returns A promise that resolves to a compact JWT.\n */\n private async statusListFetcher(uri: string): Promise<string> {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), 10000)\n\n try {\n const response = await fetch(uri, {\n signal: controller.signal,\n headers: { Accept: MediaTypes.StatusListJwt },\n })\n if (!response.ok) {\n throw new Error(`Error fetching status list: ${response.status} ${await response.text()}`)\n }\n\n // according to the spec the content type should be application/statuslist+jwt\n if (!isMediaType(response.headers.get('content-type'), MediaTypes.StatusListJwt)) {\n throw new Error('Invalid content type')\n }\n\n return response.text()\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n /**\n * Validates the status, throws an error if the status is not 0.\n * @param status\n * @param context where the status was read from\n * @returns\n */\n private async statusValidator(status: number, { uri, idx }: StatusValidatorContext): Promise<void> {\n if (status !== StatusType.Valid) {\n const details: StatusInvalidErrorDetails = { uri, idx, status }\n throw new SDJWTException('Status is not valid', { details, code: 'STATUS_INVALID' })\n }\n return Promise.resolve()\n }\n\n /**\n * Verifies the SD-JWT-VC. It will validate the signature, the keybindings when required, the status, and the VCT.\n * @param currentDate current time in seconds\n */\n async verify(encodedSDJwt: string, options?: T & VerifierOptions) {\n // Call the parent class's verify method\n const result: VerificationResult = await super.verify(encodedSDJwt, options).then((res) => {\n return {\n payload: res.payload as SdJwtVcPayload,\n header: res.header,\n kb: res.kb,\n }\n })\n\n await this.verifyStatus(result, options)\n if (this.userConfig.loadTypeMetadataFormat) {\n const resolvedTypeMetadata = await this.fetchVct(result)\n result.typeMetadata = resolvedTypeMetadata\n if (resolvedTypeMetadata) {\n result.typeMetadataVerification = await this.checkTypeMetadata(\n await this.decodeForTypeMetadata(encodedSDJwt),\n resolvedTypeMetadata,\n { validateDisclosures: false }\n )\n }\n }\n return result\n }\n\n /**\n * Safe verification that collects all errors instead of failing fast.\n * Returns a result object with either the verified data or an array of all errors.\n * This includes SD-JWT-VC specific validations like status and VCT metadata.\n *\n * @param encodedSDJwt - The encoded SD-JWT-VC to verify\n * @param options - Verification options\n * @returns A SafeVerifyResult containing either success data or collected errors\n */\n async safeVerify(encodedSDJwt: string, options?: T & VerifierOptions): Promise<SafeVerifyResult<VerificationResult>> {\n const errors: VerificationError[] = []\n\n // Helper to add errors\n const addError = (code: VerificationErrorCode, message: string, details?: unknown) => {\n errors.push({ code, message, details })\n }\n\n // First, call the parent's safeVerify to get base verification results\n const baseResult = await super.safeVerify(encodedSDJwt, options)\n\n // Collect errors from base verification\n if (!baseResult.success) {\n errors.push(...baseResult.errors)\n }\n\n // Build partial result for additional verifications\n let result: VerificationResult | undefined\n if (baseResult.success) {\n result = {\n payload: baseResult.data.payload as SdJwtVcPayload,\n header: baseResult.data.header,\n kb: baseResult.data.kb as VerificationResult['kb'],\n }\n } else {\n // Try to extract payload even if verification failed for status/vct checks\n try {\n const { payload, header } = await SDJwt.extractJwt<Record<string, unknown>, SdJwtVcPayload>(encodedSDJwt)\n if (payload) {\n result = {\n payload,\n header,\n kb: undefined,\n }\n }\n } catch {\n // Cannot extract payload, skip additional checks\n }\n }\n\n // Verify status (if payload is available)\n if (result) {\n try {\n await this.verifyStatus(result, options)\n } catch (e) {\n const error = ensureError(e)\n // A failure that carries a code (e.g. STATUS_INVALID from the status validator) keeps it;\n // problems with the status list itself are wrapped without one\n if (error instanceof SDJWTException && error.code) {\n addError(error.code, error.message, error)\n } else {\n addError('STATUS_VERIFICATION_FAILED', `Status verification failed: ${error.message}`, error)\n }\n }\n\n // Verify VCT metadata (if configured)\n if (this.userConfig.loadTypeMetadataFormat) {\n try {\n const resolvedTypeMetadata = await this.fetchVct(result)\n if (result) {\n result.typeMetadata = resolvedTypeMetadata\n if (resolvedTypeMetadata && baseResult.success) {\n result.typeMetadataVerification = await this.checkTypeMetadata(\n await this.decodeForTypeMetadata(encodedSDJwt),\n resolvedTypeMetadata,\n { validateDisclosures: false }\n )\n }\n }\n } catch (e) {\n const error = ensureError(e)\n if (error instanceof SDJWTException && error.code) {\n addError(error.code, error.message, error)\n } else {\n addError('VCT_VERIFICATION_FAILED', `VCT verification failed: ${error.message}`, error)\n }\n }\n }\n }\n\n // Return result\n if (errors.length > 0) {\n return { success: false, errors }\n }\n\n if (!result) {\n return {\n success: false,\n errors: [\n {\n code: 'INVALID_SD_JWT',\n message: 'Failed to construct verification result',\n },\n ],\n }\n }\n\n return {\n success: true,\n data: result,\n }\n }\n\n /**\n * Verifies the claims of an SD-JWT VC against its type metadata.\n *\n * @param encodedSDJwt The encoded SD-JWT VC or presentation.\n * @param typeMetadata The type metadata to verify against. Type metadata that extends other type metadata is\n * resolved first. When not provided, the type metadata of the SD-JWT VC is fetched.\n * @returns The claims that do not conform to the type metadata.\n * @throws SDJWTException when the type metadata cannot be resolved, describes a different vct, or the disclosures\n * are invalid.\n */\n async verifyTypeMetadata(\n encodedSDJwt: string,\n typeMetadata?: ResolvedTypeMetadata | TypeMetadataFormat\n ): Promise<TypeMetadataVerificationResult> {\n const sdjwt = await this.decodeForTypeMetadata(encodedSDJwt)\n\n // Fetched type metadata is checked against the vct in fetchSingleVct\n if (typeMetadata) {\n const vct = sdjwt.jwt?.payload?.vct\n const metadataVct = isResolvedTypeMetadata(typeMetadata) ? typeMetadata.vctValues[0] : typeMetadata.vct\n if (vct !== metadataVct) {\n throw new SDJWTException(`Type metadata vct '${metadataVct}' does not match the vct '${vct}' of the SD-JWT VC`)\n }\n }\n\n const resolvedMetadata = typeMetadata\n ? await this.toResolvedTypeMetadata(typeMetadata)\n : await this.getVct(encodedSDJwt)\n if (!resolvedMetadata) {\n throw new SDJWTException('Type metadata not found or could not be resolved')\n }\n\n return this.checkTypeMetadata(sdjwt, resolvedMetadata, { validateDisclosures: true })\n }\n\n private async decodeForTypeMetadata(encodedSDJwt: string) {\n if (!this.userConfig.hasher) {\n throw new SDJWTException('Hasher not found')\n }\n const sdjwt = await SDJwt.fromEncode(encodedSDJwt, this.userConfig.hasher)\n if (!sdjwt.jwt?.payload) {\n throw new SDJWTException('Invalid SD JWT: missing payload')\n }\n return sdjwt\n }\n\n private async checkTypeMetadata(\n sdjwt: SDJwt,\n resolvedMetadata: ResolvedTypeMetadata,\n { validateDisclosures }: { validateDisclosures: boolean }\n ): Promise<TypeMetadataVerificationResult> {\n const hasher = this.userConfig.hasher\n if (!hasher || !sdjwt.jwt?.payload) {\n throw new SDJWTException('Invalid SD JWT: missing payload')\n }\n\n const { _sd_alg, payload } = getSDAlgAndPayload(sdjwt.jwt.payload)\n const disclosures = await createHashMapping(sdjwt.disclosures ?? [], { hasher, alg: _sd_alg })\n if (validateDisclosures) assertDisclosuresReferenced(payload, disclosures)\n\n return verifyClaimsAgainstTypeMetadata(resolvedMetadata.mergedTypeMetadata, payload, disclosures)\n }\n\n private async toResolvedTypeMetadata(\n typeMetadata: ResolvedTypeMetadata | TypeMetadataFormat\n ): Promise<ResolvedTypeMetadata> {\n if (isResolvedTypeMetadata(typeMetadata)) return typeMetadata\n if (typeMetadata.extends) return this.resolveVctExtendsChain(typeMetadata)\n return { mergedTypeMetadata: typeMetadata, typeMetadataChain: [typeMetadata], vctValues: [typeMetadata.vct] }\n }\n\n /**\n * 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.\n *\n * It may return `undefined` if the fetcher returned an undefined value (instead of throwing an error).\n *\n * @param encodedSDJwt\n * @returns\n */\n async getVct(encodedSDJwt: string): Promise<ResolvedTypeMetadata | undefined> {\n // Call the parent class's verify method\n const { payload, header } = await SDJwt.extractJwt<Record<string, unknown>, SdJwtVcPayload>(encodedSDJwt)\n\n if (!payload) {\n throw new SDJWTException('JWT payload is missing')\n }\n\n const result: VerificationResult = {\n payload,\n header,\n kb: undefined,\n }\n\n return this.fetchVct(result)\n }\n\n /**\n * Validates the integrity of the response if the integrity is passed. If the integrity does not match, an error is thrown.\n * @param integrity\n * @param response\n */\n private async validateIntegrity(response: Response, url: string, integrity?: string) {\n if (!integrity) return\n\n // validate the integrity of the response according to https://www.w3.org/TR/SRI/\n // only the strongest algorithm in the metadata is checked, any of its values may match\n const entries = integrity\n .split(/\\s+/)\n .map((entry) => {\n const [alg, value] = entry.split('?')[0].split(/-(.*)/s)\n return { alg, value }\n })\n .filter((entry) => SRI_ALGORITHMS.includes(entry.alg) && entry.value)\n if (entries.length === 0) {\n throw new SDJWTException(`Integrity check for ${url} failed: no supported algorithm in ${integrity}`)\n }\n const alg = entries.reduce((strongest, entry) =>\n SRI_ALGORITHMS.indexOf(entry.alg) > SRI_ALGORITHMS.indexOf(strongest.alg) ? entry : strongest\n ).alg\n const expected = entries.filter((entry) => entry.alg === alg).map((entry) => entry.value)\n\n if (!this.userConfig.hasher) {\n throw new SDJWTException('Hasher not found')\n }\n const arrayBuffer = await response.arrayBuffer()\n const hash = base64.encode(await this.userConfig.hasher(arrayBuffer, alg))\n if (!expected.includes(hash)) {\n throw new Error(`Integrity check for ${url} failed: is ${hash}, but expected ${expected.join(' or ')}`)\n }\n }\n\n /**\n * Fetches the content from the url with a timeout of 10 seconds.\n * @param url\n * @returns\n */\n private async fetchWithIntegrity(url: string, integrity?: string): Promise<unknown> {\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(this.userConfig.timeout ?? 10000),\n })\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(`Error fetching ${url}: ${response.status} ${response.statusText} - ${errorText}`)\n }\n await this.validateIntegrity(response.clone(), url, integrity)\n const data = await response.json()\n\n return data\n } catch (e) {\n const error = ensureError(e)\n if (error.name === 'TimeoutError') {\n throw new Error(`Request to ${url} timed out`)\n }\n throw error\n }\n }\n\n /**\n * Verifies the VCT of the SD-JWT-VC. Returns the type metadata format.\n * Resolves the full extends chain according to spec sections 6.4, 8.2, and 9.5.\n * @param result\n * @returns\n */\n private async fetchVct(result: VerificationResult): Promise<ResolvedTypeMetadata | undefined> {\n const typeMetadataFormat = await this.fetchSingleVct(result.payload.vct, result.payload['vct#integrity'])\n\n if (!typeMetadataFormat) return undefined\n\n // If there's no extends\n if (!typeMetadataFormat.extends) {\n return {\n mergedTypeMetadata: typeMetadataFormat,\n typeMetadataChain: [typeMetadataFormat],\n vctValues: [typeMetadataFormat.vct],\n }\n }\n\n // Resolve the full VCT chain if extends is present\n return this.resolveVctExtendsChain(typeMetadataFormat)\n }\n\n /**\n * Validates that extending claim metadata respects the constraints from spec section 9.5.1.\n * @param baseClaim The base claim metadata\n * @param extendingClaim The extending claim metadata\n * @throws SDJWTException if validation fails\n */\n private validateClaimExtension(baseClaim: Claim, extendingClaim: Claim): void {\n // Validate 'sd' property constraints (section 9.5.1)\n if (baseClaim.sd && extendingClaim.sd) {\n // Cannot change from 'always' or 'never' to a different value\n if ((baseClaim.sd === 'always' || baseClaim.sd === 'never') && baseClaim.sd !== extendingClaim.sd) {\n const pathStr = JSON.stringify(extendingClaim.path)\n throw new SDJWTException(\n `Cannot change 'sd' property from '${baseClaim.sd}' to '${extendingClaim.sd}' for claim at path ${pathStr}`\n )\n }\n }\n }\n\n /**\n * Merges two type metadata formats, with the extending metadata overriding the base metadata.\n * According to spec section 9.5:\n * - All claim metadata from the extended type are inherited\n * - The child type can add new claims or properties\n * - If the child type defines claim metadata with the same path as the extended type,\n * the child type's object will override the corresponding object from the extended type\n * According to spec section 9.5.1:\n * - sd property can only be changed from 'allowed' (or omitted) to 'always' or 'never'\n * - sd property cannot be changed from 'always' or 'never' to a different value\n * According to spec section 8.2:\n * - If the extending type defines its own display property, the original display metadata is ignored\n * Note: The spec also mentions 'mandatory' property constraints, but this is not currently\n * defined in the Claim type and will be validated when that property is added to the type.\n * @param base The base type metadata format\n * @param extending The extending type metadata format\n * @returns The merged type metadata format\n */\n private mergeTypeMetadata(base: TypeMetadataFormat, extending: TypeMetadataFormat): TypeMetadataFormat {\n // Start with a shallow copy of the extending metadata\n // All properties that don't have explicit processing logic for merging\n // will only be shallow copied, and the extending metadata will take precedence.\n const merged: TypeMetadataFormat = { ...extending }\n\n // Merge claims arrays if both exist\n if (base.claims || extending.claims) {\n const baseClaims = base.claims ?? []\n const extendingClaims = extending.claims ?? []\n\n // Validate extending claims that override base claims\n for (const extendingClaim of extendingClaims) {\n const matchingBaseClaim = baseClaims.find((baseClaim) => claimPathsEqual(baseClaim.path, extendingClaim.path))\n\n if (matchingBaseClaim) {\n this.validateClaimExtension(matchingBaseClaim, extendingClaim)\n }\n }\n\n // Build final claims array preserving order\n // Start with base claims, replacing any that are overridden\n const mergedClaims: typeof baseClaims = []\n const extendedClaimsWithoutBase = [...extendingClaims]\n\n // Add base claims, replacing with extending version if path matches\n for (const baseClaim of baseClaims) {\n const extendingClaimIndex = extendedClaimsWithoutBase.findIndex((extendingClaim) =>\n claimPathsEqual(baseClaim.path, extendingClaim.path)\n )\n const extendingClaim = extendingClaimIndex !== -1 ? extendedClaimsWithoutBase[extendingClaimIndex] : undefined\n\n // Remove item from the array\n if (extendingClaim) {\n extendedClaimsWithoutBase.splice(extendingClaimIndex, 1)\n }\n\n // Prefer extending claim, otherwise use base claim\n mergedClaims.push(extendingClaim ?? baseClaim)\n }\n\n // Add all remaining claims at the end\n mergedClaims.push(...extendedClaimsWithoutBase)\n\n merged.claims = mergedClaims\n }\n\n // Handle display metadata (section 8.2)\n // If extending type doesn't define display, inherit from base\n if (!extending.display && base.display) {\n merged.display = base.display\n }\n\n return merged\n }\n\n /**\n * Resolves the full VCT chain by recursively fetching extended type metadata.\n * Implements security considerations from spec section 10.3 for circular dependencies.\n * @param vct The VCT URI to resolve\n * @param integrity Optional integrity metadata for the VCT\n * @param depth Current depth in the chain\n * @param visitedVcts Set of already visited VCT URIs to detect circular dependencies\n * @returns The fully resolved and merged type metadata format\n */\n private async resolveVctExtendsChain(\n parentTypeMetadata: TypeMetadataFormat,\n // We start at one, as the base is already fetched when this method is first called\n depth: number = 1,\n // By default include the parent vct, in case of the first call\n visitedVcts: Set<string> = new Set([parentTypeMetadata.vct])\n ): Promise<ResolvedTypeMetadata> {\n const maxDepth = this.userConfig.maxVctExtendsDepth ?? 5\n\n // Check max depth (security consideration from spec section 10.3)\n if (maxDepth !== -1 && depth > maxDepth) {\n throw new SDJWTException(`Maximum VCT extends depth of ${maxDepth} exceeded`)\n }\n\n if (!parentTypeMetadata.extends) {\n throw new SDJWTException(\n `Type metadata for vct '${parentTypeMetadata.vct}' has no 'extends' field. Unable to resolve extended type metadata document.`\n )\n }\n\n // Check for circular dependencies (security consideration from spec section 10.3)\n if (visitedVcts.has(parentTypeMetadata.extends)) {\n throw new SDJWTException(`Circular dependency detected in VCT extends chain: ${parentTypeMetadata.extends}`)\n }\n\n // Mark this VCT as visited\n visitedVcts.add(parentTypeMetadata.extends)\n\n const extendedTypeMetadata = await this.fetchSingleVct(\n parentTypeMetadata.extends,\n parentTypeMetadata['extends#integrity']\n )\n\n // While top-level vct MAY return null (meaning there's no vct type metadata)\n // The extends value ALWAYS must resolve to a value. A custom user provided resolver\n // can return a minimal on-demand type metadata document if it wants to support this use case\n if (!extendedTypeMetadata) {\n throw new SDJWTException(\n `Resolving VCT extends value '${parentTypeMetadata.extends}' resulted in an undefined result.`\n )\n }\n\n let resolvedTypeMetadata: ResolvedTypeMetadata\n\n // If this type extends another, recursively resolve the chain\n // We MUST first process the lower level document before processing\n // the higher level document\n if (extendedTypeMetadata.extends) {\n resolvedTypeMetadata = await this.resolveVctExtendsChain(extendedTypeMetadata, depth + 1, visitedVcts)\n } else {\n resolvedTypeMetadata = {\n mergedTypeMetadata: extendedTypeMetadata,\n typeMetadataChain: [extendedTypeMetadata],\n vctValues: [extendedTypeMetadata.vct],\n }\n }\n\n const mergedTypeMetadata = this.mergeTypeMetadata(resolvedTypeMetadata.mergedTypeMetadata, parentTypeMetadata)\n\n return {\n mergedTypeMetadata: mergedTypeMetadata,\n typeMetadataChain: [parentTypeMetadata, ...resolvedTypeMetadata.typeMetadataChain],\n vctValues: [parentTypeMetadata.vct, ...resolvedTypeMetadata.vctValues],\n }\n }\n\n /**\n * Fetches and verifies the VCT Metadata for a VCT value.\n * @param result\n * @returns\n */\n private async fetchSingleVct(vct: string, integrity?: string): Promise<TypeMetadataFormat | undefined> {\n const fetcher = this.userConfig.vctFetcher ?? ((uri, integrity) => this.fetchWithIntegrity(uri, integrity))\n\n // Data may be undefined\n const data = await fetcher(vct, integrity)\n if (!data) return undefined\n\n const validated = TypeMetadataFormatSchema.safeParse(data)\n if (!validated.success) {\n throw new SDJWTException(`Invalid VCT type metadata for vct '${vct}':\\n${z.prettifyError(validated.error)}`)\n }\n\n // The vct values of a resolved chain are read from the documents, so a document describing\n // another type would let whoever hosts it choose the types a credential matches.\n if (validated.data.vct !== vct) {\n throw new SDJWTException(\n `Type metadata fetched for vct '${vct}' describes vct '${validated.data.vct}'. The vct of the type metadata must match.`\n )\n }\n\n return validated.data\n }\n\n /**\n * Verifies the status of the SD-JWT-VC.\n * @param result\n * @param options\n */\n private async verifyStatus(result: VerificationResult, options?: T & VerifierOptions): Promise<void> {\n if (options?.disableStatusVerification) {\n return\n }\n\n if (result.payload.status) {\n //checks if a status field is present in the payload based on https://www.ietf.org/archive/id/draft-ietf-oauth-status-list-02.html\n if (result.payload.status.status_list) {\n const { uri, idx } = result.payload.status.status_list\n // fetch the status list from the uri\n const fetcher: StatusListFetcher = this.userConfig.statusListFetcher ?? this.statusListFetcher.bind(this)\n // fetch the status list from the uri\n const statusListJWT = await fetcher(uri)\n\n const slJWT = Jwt.fromEncode<StatusListJWTHeaderParameters, StatusListJWTPayload>(statusListJWT)\n // check that the token is a Status List Token before its signature is verified\n verifyStatusListJwtHeader(slJWT.header ?? {})\n // check if the status list has a valid signature. Falls back to the verifier of the SD-JWT-VC.\n const statusListVerifier = this.userConfig.statusVerifier ?? this.userConfig.verifier\n if (!statusListVerifier) {\n throw new SDJWTException('Verifier not found for status list JWT')\n }\n // The status list verifier gets the verification options, e.g. to resolve the key of the status list\n // issuer. Only the time options are applied to the claims of the Status List Token.\n await slJWT\n .verify((data, sig) => statusListVerifier(data, sig, options), getJwtTimeValidationOptions(options))\n .catch((err: unknown) => {\n const details: StatusListVerificationErrorDetails = { uri }\n // The original exception stays reachable as `cause`, e.g. a JwtTimeClaimException with the\n // exp the status list token was rejected for.\n throw Object.assign(\n new SLException(`Status List JWT verification failed: ${ensureError(err).message}`, details),\n { cause: err }\n )\n })\n\n // check the claims required for a Status List Token, e.g. that `sub` matches the referenced uri\n verifyStatusListJwtClaims(slJWT.payload as StatusListJWTPayload, {\n uri,\n now: options?.currentDate !== undefined ? secondsToDate(options.currentDate) : undefined,\n skewSeconds: options?.skewSeconds,\n })\n\n // get the status list from the status list JWT\n const statusList = getListFromStatusListJWT(statusListJWT)\n const status = statusList.getStatus(idx)\n\n // validate the status\n const statusValidator: StatusValidator = this.userConfig.statusValidator ?? this.statusValidator.bind(this)\n await statusValidator(status, { uri, idx })\n }\n }\n }\n\n public config(newConfig: SDJWTVCConfig<T>) {\n super.config(newConfig)\n }\n}\n\nfunction isResolvedTypeMetadata(\n typeMetadata: ResolvedTypeMetadata | TypeMetadataFormat\n): typeMetadata is ResolvedTypeMetadata {\n const candidate = typeMetadata as Partial<ResolvedTypeMetadata>\n return (\n Array.isArray(candidate.typeMetadataChain) &&\n Array.isArray(candidate.vctValues) &&\n typeof candidate.mergedTypeMetadata === 'object' &&\n candidate.mergedTypeMetadata !== null\n )\n}\n\nfunction assertDisclosuresReferenced(payload: Record<string, unknown>, disclosures: Record<string, Disclosure>) {\n unpackObj(payload, disclosures)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["z"],"sources":["../src/sd-jwt-vc-type-metadata-format.ts","../src/type-metadata-verification.ts","../src/sd-jwt-vc-instance.ts"],"sourcesContent":["import { z } from 'zod'\n\nexport const BackgroundImageSchema = z.looseObject({\n /** REQUIRED. A URI pointing to the background image. */\n uri: z.string(),\n /** OPTIONAL. An \"integrity metadata\" string as described in Section 7. */\n 'uri#integrity': z.string().optional(),\n})\nexport type BackgroundImage = z.infer<typeof BackgroundImageSchema>\n\n/**\n * Logo metadata used in rendering a credential.\n */\nexport const LogoSchema = z.looseObject({\n /** REQUIRED. A URI pointing to the logo image. */\n uri: z.string(),\n /** OPTIONAL. An \"integrity metadata\" string as described in Section 7. */\n 'uri#integrity': z.string().optional(),\n /** OPTIONAL. A string containing alternative text for the logo image. */\n alt_text: z.string().optional(),\n})\n\nexport type Logo = z.infer<typeof LogoSchema>\n\n/**\n * The simple rendering method is intended for applications that do not support SVG.\n */\nexport const SimpleRenderingSchema = z.looseObject({\n /** OPTIONAL. Logo metadata to display for the credential. */\n logo: LogoSchema.optional(),\n /** OPTIONAL. RGB color value for the credential background (e.g., \"#FFFFFF\"). */\n background_color: z.string().optional(),\n /** OPTIONAL. RGB color value for the credential text (e.g., \"#000000\"). */\n text_color: z.string().optional(),\n /** OPTIONAL. An object containing information about the background image to be displayed for the type. */\n background_image: BackgroundImageSchema.optional(),\n})\n\nexport type SimpleRendering = z.infer<typeof SimpleRenderingSchema>\n\n/** Enum of valid values for rendering orientation. */\nexport const OrientationSchema = z.enum(['portrait', 'landscape'])\n\n/** Enum of valid values for rendering color schemes. */\nexport const ColorSchemeSchema = z.enum(['light', 'dark'])\n\n/** Enum of valid values for rendering contrast. */\nexport const ContrastSchema = z.enum(['normal', 'high'])\n\n/**\n * Properties that describe the display preferences for an SVG template rendering.\n */\nexport const SvgTemplatePropertiesSchema = z.looseObject({\n /** OPTIONAL. Orientation optimized for the template. */\n orientation: OrientationSchema.optional(),\n /** OPTIONAL. Color scheme optimized for the template. */\n color_scheme: ColorSchemeSchema.optional(),\n /** OPTIONAL. Contrast level optimized for the template. */\n contrast: ContrastSchema.optional(),\n})\n\nexport type SvgTemplateProperties = z.infer<typeof SvgTemplatePropertiesSchema>\n\n/**\n * SVG rendering metadata containing URI and optional integrity and properties.\n */\nexport const SvgTemplateRenderingSchema = z.looseObject({\n /** REQUIRED. A URI pointing to the SVG template. */\n uri: z.string(),\n /** OPTIONAL. An \"integrity metadata\" string as described in Section 7. */\n 'uri#integrity': z.string().optional(),\n /** REQUIRED if more than one SVG template is present. */\n properties: SvgTemplatePropertiesSchema.optional(),\n})\n\nexport type SvgTemplateRendering = z.infer<typeof SvgTemplateRenderingSchema>\n\n/**\n * Rendering metadata, either simple or SVG-based, for a credential.\n */\nexport const RenderingSchema = z\n .looseObject({\n /** OPTIONAL. Simple rendering metadata. */\n simple: SimpleRenderingSchema.optional(),\n /** OPTIONAL. Array of SVG template rendering objects. */\n svg_templates: z.array(SvgTemplateRenderingSchema).optional(),\n /**\n * OPTIONAL. Array of SVG template rendering objects.\n * @deprecated use `svg_templates` (plural) instead.\n */\n svg_template: z.array(SvgTemplateRenderingSchema).optional(),\n })\n .transform(({ svg_template, svg_templates, ...rest }) => ({\n ...rest,\n svg_templates: svg_templates ?? svg_template,\n }))\n\nexport type Rendering = z.infer<typeof RenderingSchema>\n\n/**\n * Display metadata associated with a credential type.\n */\nexport const DisplaySchema = z\n .looseObject({\n /**\n * Language tag according to RFC 5646 (e.g., \"en\", \"de\").\n * @deprecated - use `locale` instead\n */\n lang: z.string().optional(),\n\n /**\n * REQUIRED (preferred). Language tag according to RFC 5646.\n * Alias for `lang` - either `lang` or `locale` must be provided.\n */\n locale: z.string().optional(),\n\n /** REQUIRED. Human-readable name for the credential type. */\n name: z.string(),\n /** OPTIONAL. Description of the credential type for end users. */\n description: z.string().optional(),\n /** OPTIONAL. Rendering information (simple or SVG) for the credential. */\n rendering: RenderingSchema.optional(),\n })\n .transform(({ lang, locale, ...rest }) => ({\n ...rest,\n locale: locale ?? lang,\n }))\n .refine(({ locale }) => locale !== undefined, {\n message: 'Either locale (preferred) or lang (spec name, deprecated) MUST be defined on claim display entry.',\n })\n\nexport type Display = z.infer<typeof DisplaySchema>\n\n/**\n * Claim path within the credential's JSON structure.\n * Example: [\"address\", \"street_address\"]\n */\nexport const ClaimPathSchema = z.array(z.string().nullable())\n\nexport type ClaimPath = z.infer<typeof ClaimPathSchema>\n\n/**\n * Display metadata for a specific claim.\n */\nexport const ClaimDisplaySchema = z\n .looseObject({\n /**\n * Language tag according to RFC 5646.\n * @deprecated - use `locale` instead\n */\n lang: z.string().optional(),\n\n /**\n * REQUIRED (preferred). Language tag according to RFC 5646.\n * Alias for `lang` - either `lang` or `locale` must be provided.\n */\n locale: z.string().optional(),\n\n /** REQUIRED. Human-readable label for the claim. */\n label: z.string().optional(),\n\n /**\n * Human-readable label for the claim.\n * @deprecated - use `label` instead\n */\n name: z.string().optional(),\n\n /** OPTIONAL. Description of the claim for end users. */\n description: z.string().optional(),\n })\n .transform(({ lang, name, label, locale, ...rest }) => ({\n ...rest,\n locale: locale ?? lang,\n label: label ?? name,\n }))\n .refine(({ locale }) => locale !== undefined, {\n message: 'Either locale (preferred) or lang (deprecated) MUST be defined on claim display entry.',\n })\n .refine(({ label }) => label !== undefined, {\n message: 'Either label (preferred) or name (deprecated) MUST be defined on claim display entry.',\n })\n\nexport type ClaimDisplay = z.infer<typeof ClaimDisplaySchema>\n\n/**\n * Indicates whether a claim is selectively disclosable.\n */\nexport const ClaimSelectiveDisclosureSchema = z.enum(['always', 'allowed', 'never'])\n\nexport type ClaimSelectiveDisclosure = z.infer<typeof ClaimSelectiveDisclosureSchema>\n\n/**\n * Metadata for individual claims in the credential type.\n */\nexport const ClaimSchema = z.looseObject({\n /**\n * REQUIRED. Array of one or more paths to the claim in the credential subject.\n * Each path is an array of strings (or null for array elements).\n */\n path: ClaimPathSchema,\n /** OPTIONAL. Display metadata in multiple languages. */\n display: z.array(ClaimDisplaySchema).optional(),\n /** OPTIONAL. Controls whether the claim must, may, or must not be selectively disclosed. */\n sd: ClaimSelectiveDisclosureSchema.optional(),\n /**\n * OPTIONAL. A boolean indicating whether the claim must be present in the Unsecured Payload\n * of the SD-JWT VC. Default is false if not specified.\n */\n mandatory: z.boolean().optional(),\n /**\n * OPTIONAL. Unique string identifier for referencing the claim in an SVG template.\n * Must consist of alphanumeric characters or underscores and must not start with a digit.\n */\n svg_id: z.string().optional(),\n})\n\nexport type Claim = z.infer<typeof ClaimSchema>\n\n/**\n * Type metadata for a specific Verifiable Credential (VC) type.\n * Reference: https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-13.html#name-type-metadata-format\n */\nexport const TypeMetadataFormatSchema = z.looseObject({\n /** REQUIRED. A URI uniquely identifying the credential type. */\n vct: z.string(),\n /** OPTIONAL. Human-readable name for developers. */\n name: z.string().optional(),\n /** OPTIONAL. Human-readable description for developers. */\n description: z.string().optional(),\n /** OPTIONAL. URI of another type that this one extends. */\n extends: z.string().optional(),\n /** OPTIONAL. Integrity metadata for the 'extends' field. */\n 'extends#integrity': z.string().optional(),\n /** OPTIONAL. Array of localized display metadata for the type. */\n display: z.array(DisplaySchema).optional(),\n /** OPTIONAL. Array of claim metadata. */\n claims: z.array(ClaimSchema).optional(),\n})\n\n/**\n * The resolved type metadata. If you just want to use the type metadata, you should use `typeMetadata`.\n * In case additional processing is needed (e.g. for extensions in type metadata), you can use the `typeMetadataChain`\n */\nexport type ResolvedTypeMetadata = {\n /**\n * The merged type metadata based on the resolved `vct` document and all `extends` values.\n */\n mergedTypeMetadata: TypeMetadataFormat\n\n /**\n * The original type metadata documents, ordered from the extending type to the last extended type.\n */\n typeMetadataChain: [TypeMetadataFormat, ...TypeMetadataFormat[]]\n\n /**\n * The vct values present in the type metadata chain. This can be used for matching against e.g.\n * DCQL queries which can query an underlying type.\n */\n vctValues: [string, ...string[]]\n}\n\nexport type TypeMetadataFormat = z.infer<typeof TypeMetadataFormatSchema>\n","import { type Disclosure, SD_DIGEST, SD_LIST_KEY } from '@sd-jwt/core'\nimport type { Claim, ClaimPath, TypeMetadataFormat } from './sd-jwt-vc-type-metadata-format'\n\nexport type TypeMetadataVerificationResult = {\n extraClaims: ClaimPath[]\n missingMandatoryClaims: ClaimPath[]\n undisclosedMandatoryClaims: ClaimPath[]\n invalidNonSelectivelyDisclosableClaims: ClaimPath[]\n invalidSelectivelyDisclosableClaims: ClaimPath[]\n}\n\nconst REGISTERED_CLAIMS = ['iss', 'nbf', 'exp', 'iat', 'sub', 'cnf', 'vct', 'vct#integrity', 'status']\n\ntype PresentClaim = {\n path: Array<string | number>\n isSd: boolean\n}\n\nexport function claimPathsEqual(path1: ClaimPath, path2: ClaimPath): boolean {\n if (path1.length !== path2.length) return false\n return path1.every((seg, idx) => seg === path2[idx])\n}\n\nfunction segmentsMatch(claimPath: ClaimPath, presentPath: Array<string | number>, length: number): boolean {\n for (let i = 0; i < length; i++) {\n const seg = claimPath[i]\n if (seg === null ? typeof presentPath[i] !== 'number' : seg !== presentPath[i]) return false\n }\n return true\n}\n\nfunction claimPathMatches(claimPath: ClaimPath, presentPath: Array<string | number>): boolean {\n return claimPath.length === presentPath.length && segmentsMatch(claimPath, presentPath, claimPath.length)\n}\n\nfunction isArrayElementDigest(value: unknown): value is { [SD_LIST_KEY]: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 1 &&\n typeof (value as Record<string, unknown>)[SD_LIST_KEY] === 'string'\n )\n}\n\nfunction collectPresentClaims(payload: Record<string, unknown>, disclosures: Record<string, Disclosure>) {\n const claims: PresentClaim[] = []\n\n const visit = (node: unknown, path: Array<string | number>) => {\n if (typeof node !== 'object' || node === null) return\n\n if (Array.isArray(node)) {\n node.forEach((element, index) => {\n if (isArrayElementDigest(element)) {\n const disclosure = disclosures[element[SD_LIST_KEY]]\n if (!disclosure) return\n claims.push({ path: [...path, index], isSd: true })\n visit(disclosure.value, [...path, index])\n } else {\n claims.push({ path: [...path, index], isSd: false })\n visit(element, [...path, index])\n }\n })\n return\n }\n\n const record = node as Record<string, unknown>\n for (const [key, value] of Object.entries(record)) {\n if (key === SD_DIGEST || (path.length === 0 && key === '_sd_alg')) continue\n claims.push({ path: [...path, key], isSd: false })\n visit(value, [...path, key])\n }\n\n const digests = Array.isArray(record[SD_DIGEST]) ? record[SD_DIGEST] : []\n for (const digest of digests) {\n const disclosure = typeof digest === 'string' ? disclosures[digest] : undefined\n if (!disclosure || typeof disclosure.key !== 'string') continue\n claims.push({ path: [...path, disclosure.key], isSd: true })\n visit(disclosure.value, [...path, disclosure.key])\n }\n }\n\n visit(payload, [])\n return claims\n}\n\ntype ClaimStatus = 'present' | 'missing' | 'undisclosed'\n\nfunction childEntries(node: unknown, segment: string | null, disclosures: Record<string, Disclosure>) {\n const present: Array<{ index: string | number; value: unknown }> = []\n let hidden = false\n\n if (segment === null) {\n if (!Array.isArray(node)) return { present, hidden }\n node.forEach((element, index) => {\n if (!isArrayElementDigest(element)) {\n present.push({ index, value: element })\n return\n }\n const disclosure = disclosures[element[SD_LIST_KEY]]\n if (disclosure) present.push({ index, value: disclosure.value })\n else hidden = true\n })\n return { present, hidden }\n }\n\n if (typeof node !== 'object' || node === null || Array.isArray(node)) return { present, hidden }\n const record = node as Record<string, unknown>\n // biome-ignore lint/suspicious/noPrototypeBuiltins: `Object.hasOwn` is not in the ES2020 lib this package targets\n if (segment !== SD_DIGEST && Object.prototype.hasOwnProperty.call(record, segment)) {\n present.push({ index: segment, value: record[segment] })\n }\n\n const digests = Array.isArray(record[SD_DIGEST]) ? record[SD_DIGEST] : []\n for (const digest of digests) {\n const disclosure = typeof digest === 'string' ? disclosures[digest] : undefined\n if (!disclosure) hidden = true\n else if (disclosure.key === segment) present.push({ index: segment, value: disclosure.value })\n }\n return { present, hidden }\n}\n\nfunction mandatoryClaimStatus(\n claim: Claim,\n metadataClaims: Claim[],\n packedPayload: Record<string, unknown>,\n disclosures: Record<string, Disclosure>\n): ClaimStatus {\n const sdOf = (length: number) =>\n metadataClaims.find((mc) => claimPathsEqual(mc.path, claim.path.slice(0, length)))?.sd\n\n const walk = (node: unknown, depth: number): ClaimStatus => {\n if (depth === claim.path.length) return 'present'\n\n const segment = claim.path[depth]\n const { present, hidden } = childEntries(node, segment, disclosures)\n let status: ClaimStatus = 'present'\n for (const child of present) {\n const childStatus = walk(child.value, depth + 1)\n if (childStatus === 'missing') return 'missing'\n if (childStatus === 'undisclosed') status = 'undisclosed'\n }\n\n if (segment === null) {\n if (!Array.isArray(node)) return 'missing'\n return present.length === 0 && hidden ? 'undisclosed' : status\n }\n if (present.length > 0) return status\n\n return hidden && sdOf(depth + 1) !== 'never' ? 'undisclosed' : 'missing'\n }\n\n return walk(packedPayload, 0)\n}\n\nfunction toCanonicalClaimPath(path: Array<string | number>): ClaimPath {\n return path.map((seg) => (typeof seg === 'number' ? null : seg))\n}\n\nfunction createClaimPathSet() {\n const paths = new Map<string, ClaimPath>()\n return {\n add: (path: ClaimPath) => paths.set(JSON.stringify(path), path),\n values: () => Array.from(paths.values()),\n }\n}\n\n/**\n * Verifies the claims of an SD-JWT VC against type metadata.\n *\n * @param typeMetadata The type metadata to verify against. When it extends other type metadata, pass the merged\n * type metadata of the resolved chain.\n * @param packedPayload The payload of the SD-JWT VC as issued, with the `_sd` digests still in place. The payload\n * returned by `verify` is unpacked and cannot be used here.\n * @param disclosures The disclosures of the SD-JWT VC, keyed by their digest.\n */\nexport function verifyClaimsAgainstTypeMetadata(\n typeMetadata: TypeMetadataFormat,\n packedPayload: Record<string, unknown>,\n disclosures: Record<string, Disclosure>\n): TypeMetadataVerificationResult {\n const metadataClaims = typeMetadata.claims ?? []\n const presentClaims = collectPresentClaims(packedPayload, disclosures)\n\n const extraClaims = createClaimPathSet()\n const missingMandatoryClaims = createClaimPathSet()\n const undisclosedMandatoryClaims = createClaimPathSet()\n const invalidNonSelectivelyDisclosableClaims = createClaimPathSet()\n const invalidSelectivelyDisclosableClaims = createClaimPathSet()\n\n const hasDeclaredChildren = (claimPath: ClaimPath) =>\n metadataClaims.some(\n (mc) => mc.path.length > claimPath.length && claimPathsEqual(mc.path.slice(0, claimPath.length), claimPath)\n )\n\n const isCovered = (path: Array<string | number>) => {\n if (REGISTERED_CLAIMS.includes(String(path[0])) && !metadataClaims.some((mc) => mc.path[0] === path[0])) {\n return true\n }\n\n return metadataClaims.some(\n (mc) =>\n (path.length < mc.path.length && segmentsMatch(mc.path, path, path.length)) ||\n (path.length > mc.path.length && segmentsMatch(mc.path, path, mc.path.length) && !hasDeclaredChildren(mc.path))\n )\n }\n\n for (const presentClaim of presentClaims) {\n const matchingMetadataClaims = metadataClaims.filter((mc) => claimPathMatches(mc.path, presentClaim.path))\n\n if (matchingMetadataClaims.length === 0) {\n if (typeMetadata.claims && !isCovered(presentClaim.path)) extraClaims.add(toCanonicalClaimPath(presentClaim.path))\n continue\n }\n\n for (const metadataClaim of matchingMetadataClaims) {\n if (metadataClaim.sd === 'always' && !presentClaim.isSd) {\n invalidNonSelectivelyDisclosableClaims.add(metadataClaim.path)\n } else if (metadataClaim.sd === 'never' && presentClaim.isSd) {\n invalidSelectivelyDisclosableClaims.add(metadataClaim.path)\n }\n }\n }\n\n for (const metadataClaim of metadataClaims) {\n if (!metadataClaim.mandatory) continue\n const status = mandatoryClaimStatus(metadataClaim, metadataClaims, packedPayload, disclosures)\n if (status === 'missing') missingMandatoryClaims.add(metadataClaim.path)\n else if (status === 'undisclosed') undisclosedMandatoryClaims.add(metadataClaim.path)\n }\n\n const extraClaimPaths = extraClaims.values()\n return {\n extraClaims: extraClaimPaths.filter(\n (path) =>\n !extraClaimPaths.some(\n (other) => other.length < path.length && claimPathsEqual(other, path.slice(0, other.length))\n )\n ),\n missingMandatoryClaims: missingMandatoryClaims.values(),\n undisclosedMandatoryClaims: undisclosedMandatoryClaims.values(),\n invalidNonSelectivelyDisclosableClaims: invalidNonSelectivelyDisclosableClaims.values(),\n invalidSelectivelyDisclosableClaims: invalidSelectivelyDisclosableClaims.values(),\n }\n}\n","import { base64, isMediaType, secondsToDate } from '@owf/identity-common'\nimport {\n getListFromStatusListJWT,\n MediaTypes,\n SLException,\n type StatusListJWTHeaderParameters,\n type StatusListJWTPayload,\n StatusType,\n verifyStatusListJwtClaims,\n verifyStatusListJwtHeader,\n} from '@owf/token-status-list'\nimport {\n createHashMapping,\n type Disclosure,\n type DisclosureFrame,\n ensureError,\n getJwtTimeValidationOptions,\n getSDAlgAndPayload,\n Jwt,\n type SafeVerifyResult,\n SDJWTException,\n SDJwt,\n SDJwtInstance,\n unpackObj,\n type VerificationError,\n type VerificationErrorCode,\n type VerifierOptions,\n} from '@sd-jwt/core'\nimport z from 'zod'\nimport type {\n SDJWTVCConfig,\n StatusInvalidErrorDetails,\n StatusListFetcher,\n StatusListVerificationErrorDetails,\n StatusValidator,\n StatusValidatorContext,\n} from './sd-jwt-vc-config'\nimport type { SdJwtVcPayload } from './sd-jwt-vc-payload'\nimport {\n type Claim,\n type ResolvedTypeMetadata,\n type TypeMetadataFormat,\n TypeMetadataFormatSchema,\n} from './sd-jwt-vc-type-metadata-format'\nimport {\n claimPathsEqual,\n type TypeMetadataVerificationResult,\n verifyClaimsAgainstTypeMetadata,\n} from './type-metadata-verification'\nimport type { VerificationResult } from './verification-result'\n\n// SRI hash algorithms, ordered from weakest to strongest\nconst SRI_ALGORITHMS = ['sha256', 'sha384', 'sha512']\n\nexport class SDJwtVcInstance<T = unknown> extends SDJwtInstance<SdJwtVcPayload, T> {\n /**\n * The type of the SD-JWT-VC set in the header.typ field.\n */\n protected type = 'dc+sd-jwt'\n\n protected userConfig: SDJWTVCConfig<T> = {}\n\n constructor(userConfig?: SDJWTVCConfig<T>) {\n super(userConfig)\n if (userConfig) {\n this.userConfig = userConfig\n }\n }\n\n /**\n * Validates if the disclosure frame attempts to selectively disclose protected SD-JWT-VC claims.\n * @param disclosureFrame\n */\n protected validateDisclosureFrame(disclosureFrame?: DisclosureFrame<SdJwtVcPayload>): void {\n if (disclosureFrame?._sd && Array.isArray(disclosureFrame._sd) && disclosureFrame._sd.length > 0) {\n const reservedNames = ['iss', 'nbf', 'exp', 'cnf', 'vct', 'vct#integrity', 'status']\n const reservedNamesInDisclosureFrame = disclosureFrame._sd.filter((key) => reservedNames.includes(String(key)))\n if (reservedNamesInDisclosureFrame.length > 0) {\n throw new SDJWTException('Cannot disclose protected field')\n }\n }\n }\n\n /**\n * Fetches the status list from the uri with a timeout of 10 seconds.\n * @param uri The URI to fetch from.\n * @returns A promise that resolves to a compact JWT.\n */\n private async statusListFetcher(uri: string): Promise<string> {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), 10000)\n\n try {\n const response = await fetch(uri, {\n signal: controller.signal,\n headers: { Accept: MediaTypes.StatusListJwt },\n })\n if (!response.ok) {\n throw new Error(`Error fetching status list: ${response.status} ${await response.text()}`)\n }\n\n // according to the spec the content type should be application/statuslist+jwt\n if (!isMediaType(response.headers.get('content-type'), MediaTypes.StatusListJwt)) {\n throw new Error('Invalid content type')\n }\n\n return response.text()\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n /**\n * Validates the status, throws an error if the status is not 0.\n * @param status\n * @param context where the status was read from\n * @returns\n */\n private async statusValidator(status: number, { uri, idx }: StatusValidatorContext): Promise<void> {\n if (status !== StatusType.Valid) {\n const details: StatusInvalidErrorDetails = { uri, idx, status }\n throw new SDJWTException('Status is not valid', { details, code: 'STATUS_INVALID' })\n }\n return Promise.resolve()\n }\n\n /**\n * Verifies the SD-JWT-VC. It will validate the signature, the keybindings when required, the status, and the VCT.\n * @param currentDate current time in seconds\n */\n async verify(encodedSDJwt: string, options?: T & VerifierOptions) {\n // Call the parent class's verify method\n const result: VerificationResult = await super.verify(encodedSDJwt, options).then((res) => {\n return {\n payload: res.payload as SdJwtVcPayload,\n header: res.header,\n kb: res.kb,\n }\n })\n\n await this.verifyStatus(result, options)\n if (this.userConfig.loadTypeMetadataFormat) {\n const resolvedTypeMetadata = await this.fetchVct(result)\n result.typeMetadata = resolvedTypeMetadata\n if (resolvedTypeMetadata) {\n result.typeMetadataVerification = await this.checkTypeMetadata(\n await this.decodeForTypeMetadata(encodedSDJwt),\n resolvedTypeMetadata,\n { validateDisclosures: false }\n )\n }\n }\n return result\n }\n\n /**\n * Safe verification that collects all errors instead of failing fast.\n * Returns a result object with either the verified data or an array of all errors.\n * This includes SD-JWT-VC specific validations like status and VCT metadata.\n *\n * @param encodedSDJwt - The encoded SD-JWT-VC to verify\n * @param options - Verification options\n * @returns A SafeVerifyResult containing either success data or collected errors\n */\n async safeVerify(encodedSDJwt: string, options?: T & VerifierOptions): Promise<SafeVerifyResult<VerificationResult>> {\n const errors: VerificationError[] = []\n\n // Helper to add errors\n const addError = (code: VerificationErrorCode, message: string, details?: unknown) => {\n errors.push({ code, message, details })\n }\n\n // First, call the parent's safeVerify to get base verification results\n const baseResult = await super.safeVerify(encodedSDJwt, options)\n\n // Collect errors from base verification\n if (!baseResult.success) {\n errors.push(...baseResult.errors)\n }\n\n // Build partial result for additional verifications\n let result: VerificationResult | undefined\n if (baseResult.success) {\n result = {\n payload: baseResult.data.payload as SdJwtVcPayload,\n header: baseResult.data.header,\n kb: baseResult.data.kb as VerificationResult['kb'],\n }\n } else {\n // Try to extract payload even if verification failed for status/vct checks\n try {\n const { payload, header } = await SDJwt.extractJwt<Record<string, unknown>, SdJwtVcPayload>(encodedSDJwt)\n if (payload) {\n result = {\n payload,\n header,\n kb: undefined,\n }\n }\n } catch {\n // Cannot extract payload, skip additional checks\n }\n }\n\n // Verify status (if payload is available)\n if (result) {\n try {\n await this.verifyStatus(result, options)\n } catch (e) {\n const error = ensureError(e)\n // A failure that carries a code (e.g. STATUS_INVALID from the status validator) keeps it;\n // problems with the status list itself are wrapped without one\n if (error instanceof SDJWTException && error.code) {\n addError(error.code, error.message, error)\n } else {\n addError('STATUS_VERIFICATION_FAILED', `Status verification failed: ${error.message}`, error)\n }\n }\n\n // Verify VCT metadata (if configured)\n if (this.userConfig.loadTypeMetadataFormat) {\n try {\n const resolvedTypeMetadata = await this.fetchVct(result)\n if (result) {\n result.typeMetadata = resolvedTypeMetadata\n if (resolvedTypeMetadata && baseResult.success) {\n result.typeMetadataVerification = await this.checkTypeMetadata(\n await this.decodeForTypeMetadata(encodedSDJwt),\n resolvedTypeMetadata,\n { validateDisclosures: false }\n )\n }\n }\n } catch (e) {\n const error = ensureError(e)\n if (error instanceof SDJWTException && error.code) {\n addError(error.code, error.message, error)\n } else {\n addError('VCT_VERIFICATION_FAILED', `VCT verification failed: ${error.message}`, error)\n }\n }\n }\n }\n\n // Return result\n if (errors.length > 0) {\n return { success: false, errors }\n }\n\n if (!result) {\n return {\n success: false,\n errors: [\n {\n code: 'INVALID_SD_JWT',\n message: 'Failed to construct verification result',\n },\n ],\n }\n }\n\n return {\n success: true,\n data: result,\n }\n }\n\n /**\n * Verifies the claims of an SD-JWT VC against its type metadata.\n *\n * @param encodedSDJwt The encoded SD-JWT VC or presentation.\n * @param typeMetadata The type metadata to verify against. Type metadata that extends other type metadata is\n * resolved first. When not provided, the type metadata of the SD-JWT VC is fetched.\n * @returns The claims that do not conform to the type metadata.\n * @throws SDJWTException when the type metadata cannot be resolved, describes a different vct, or the disclosures\n * are invalid.\n */\n async verifyTypeMetadata(\n encodedSDJwt: string,\n typeMetadata?: ResolvedTypeMetadata | TypeMetadataFormat\n ): Promise<TypeMetadataVerificationResult> {\n const sdjwt = await this.decodeForTypeMetadata(encodedSDJwt)\n\n // Fetched type metadata is checked against the vct in fetchSingleVct\n if (typeMetadata) {\n const vct = sdjwt.jwt?.payload?.vct\n const metadataVct = isResolvedTypeMetadata(typeMetadata) ? typeMetadata.vctValues[0] : typeMetadata.vct\n if (vct !== metadataVct) {\n throw new SDJWTException(`Type metadata vct '${metadataVct}' does not match the vct '${vct}' of the SD-JWT VC`)\n }\n }\n\n const resolvedMetadata = typeMetadata\n ? await this.toResolvedTypeMetadata(typeMetadata)\n : await this.getVct(encodedSDJwt)\n if (!resolvedMetadata) {\n throw new SDJWTException('Type metadata not found or could not be resolved')\n }\n\n return this.checkTypeMetadata(sdjwt, resolvedMetadata, { validateDisclosures: true })\n }\n\n private async decodeForTypeMetadata(encodedSDJwt: string) {\n if (!this.userConfig.hasher) {\n throw new SDJWTException('Hasher not found')\n }\n const sdjwt = await SDJwt.fromEncode(encodedSDJwt, this.userConfig.hasher)\n if (!sdjwt.jwt?.payload) {\n throw new SDJWTException('Invalid SD JWT: missing payload')\n }\n return sdjwt\n }\n\n private async checkTypeMetadata(\n sdjwt: SDJwt,\n resolvedMetadata: ResolvedTypeMetadata,\n { validateDisclosures }: { validateDisclosures: boolean }\n ): Promise<TypeMetadataVerificationResult> {\n const hasher = this.userConfig.hasher\n if (!hasher || !sdjwt.jwt?.payload) {\n throw new SDJWTException('Invalid SD JWT: missing payload')\n }\n\n const { _sd_alg, payload } = getSDAlgAndPayload(sdjwt.jwt.payload)\n const disclosures = await createHashMapping(sdjwt.disclosures ?? [], { hasher, alg: _sd_alg })\n if (validateDisclosures) assertDisclosuresReferenced(payload, disclosures)\n\n return verifyClaimsAgainstTypeMetadata(resolvedMetadata.mergedTypeMetadata, payload, disclosures)\n }\n\n private async toResolvedTypeMetadata(\n typeMetadata: ResolvedTypeMetadata | TypeMetadataFormat\n ): Promise<ResolvedTypeMetadata> {\n if (isResolvedTypeMetadata(typeMetadata)) return typeMetadata\n if (typeMetadata.extends) return this.resolveVctExtendsChain(typeMetadata)\n return { mergedTypeMetadata: typeMetadata, typeMetadataChain: [typeMetadata], vctValues: [typeMetadata.vct] }\n }\n\n /**\n * 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.\n *\n * It may return `undefined` if the fetcher returned an undefined value (instead of throwing an error).\n *\n * @param encodedSDJwt\n * @returns\n */\n async getVct(encodedSDJwt: string): Promise<ResolvedTypeMetadata | undefined> {\n // Call the parent class's verify method\n const { payload, header } = await SDJwt.extractJwt<Record<string, unknown>, SdJwtVcPayload>(encodedSDJwt)\n\n if (!payload) {\n throw new SDJWTException('JWT payload is missing')\n }\n\n const result: VerificationResult = {\n payload,\n header,\n kb: undefined,\n }\n\n return this.fetchVct(result)\n }\n\n /**\n * Validates the integrity of the response if the integrity is passed. If the integrity does not match, an error is thrown.\n * @param integrity\n * @param response\n */\n private async validateIntegrity(response: Response, url: string, integrity?: string) {\n if (!integrity) return\n\n // validate the integrity of the response according to https://www.w3.org/TR/SRI/\n // only the strongest algorithm in the metadata is checked, any of its values may match\n const entries = integrity\n .split(/\\s+/)\n .map((entry) => {\n const [alg, value] = entry.split('?')[0].split(/-(.*)/s)\n return { alg, value }\n })\n .filter((entry) => SRI_ALGORITHMS.includes(entry.alg) && entry.value)\n if (entries.length === 0) {\n throw new SDJWTException(`Integrity check for ${url} failed: no supported algorithm in ${integrity}`)\n }\n const alg = entries.reduce((strongest, entry) =>\n SRI_ALGORITHMS.indexOf(entry.alg) > SRI_ALGORITHMS.indexOf(strongest.alg) ? entry : strongest\n ).alg\n const expected = entries.filter((entry) => entry.alg === alg).map((entry) => entry.value)\n\n if (!this.userConfig.hasher) {\n throw new SDJWTException('Hasher not found')\n }\n const arrayBuffer = await response.arrayBuffer()\n const hash = base64.encode(await this.userConfig.hasher(arrayBuffer, alg))\n if (!expected.includes(hash)) {\n throw new Error(`Integrity check for ${url} failed: is ${hash}, but expected ${expected.join(' or ')}`)\n }\n }\n\n /**\n * Fetches the content from the url with a timeout of 10 seconds.\n * @param url\n * @returns\n */\n private async fetchWithIntegrity(url: string, integrity?: string): Promise<unknown> {\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(this.userConfig.timeout ?? 10000),\n })\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(`Error fetching ${url}: ${response.status} ${response.statusText} - ${errorText}`)\n }\n await this.validateIntegrity(response.clone(), url, integrity)\n const data = await response.json()\n\n return data\n } catch (e) {\n const error = ensureError(e)\n if (error.name === 'TimeoutError') {\n throw new Error(`Request to ${url} timed out`)\n }\n throw error\n }\n }\n\n /**\n * Verifies the VCT of the SD-JWT-VC. Returns the type metadata format.\n * Resolves the full extends chain according to spec sections 6.4, 8.2, and 9.5.\n * @param result\n * @returns\n */\n private async fetchVct(result: VerificationResult): Promise<ResolvedTypeMetadata | undefined> {\n const typeMetadataFormat = await this.fetchSingleVct(result.payload.vct, result.payload['vct#integrity'])\n\n if (!typeMetadataFormat) return undefined\n\n // If there's no extends\n if (!typeMetadataFormat.extends) {\n return {\n mergedTypeMetadata: typeMetadataFormat,\n typeMetadataChain: [typeMetadataFormat],\n vctValues: [typeMetadataFormat.vct],\n }\n }\n\n // Resolve the full VCT chain if extends is present\n return this.resolveVctExtendsChain(typeMetadataFormat)\n }\n\n /**\n * Validates that extending claim metadata respects the constraints from spec section 9.5.1.\n * @param baseClaim The base claim metadata\n * @param extendingClaim The extending claim metadata\n * @throws SDJWTException if validation fails\n */\n private validateClaimExtension(baseClaim: Claim, extendingClaim: Claim): void {\n // Validate 'sd' property constraints (section 9.5.1)\n if (baseClaim.sd && extendingClaim.sd) {\n // Cannot change from 'always' or 'never' to a different value\n if ((baseClaim.sd === 'always' || baseClaim.sd === 'never') && baseClaim.sd !== extendingClaim.sd) {\n const pathStr = JSON.stringify(extendingClaim.path)\n throw new SDJWTException(\n `Cannot change 'sd' property from '${baseClaim.sd}' to '${extendingClaim.sd}' for claim at path ${pathStr}`\n )\n }\n }\n }\n\n /**\n * Merges two type metadata formats, with the extending metadata overriding the base metadata.\n * According to spec section 9.5:\n * - All claim metadata from the extended type are inherited\n * - The child type can add new claims or properties\n * - If the child type defines claim metadata with the same path as the extended type,\n * the child type's object will override the corresponding object from the extended type\n * According to spec section 9.5.1:\n * - sd property can only be changed from 'allowed' (or omitted) to 'always' or 'never'\n * - sd property cannot be changed from 'always' or 'never' to a different value\n * According to spec section 8.2:\n * - If the extending type defines its own display property, the original display metadata is ignored\n * Note: The spec also mentions 'mandatory' property constraints, but this is not currently\n * defined in the Claim type and will be validated when that property is added to the type.\n * @param base The base type metadata format\n * @param extending The extending type metadata format\n * @returns The merged type metadata format\n */\n private mergeTypeMetadata(base: TypeMetadataFormat, extending: TypeMetadataFormat): TypeMetadataFormat {\n // Start with a shallow copy of the extending metadata\n // All properties that don't have explicit processing logic for merging\n // will only be shallow copied, and the extending metadata will take precedence.\n const merged: TypeMetadataFormat = { ...extending }\n\n // Merge claims arrays if both exist\n if (base.claims || extending.claims) {\n const baseClaims = base.claims ?? []\n const extendingClaims = extending.claims ?? []\n\n // Validate extending claims that override base claims\n for (const extendingClaim of extendingClaims) {\n const matchingBaseClaim = baseClaims.find((baseClaim) => claimPathsEqual(baseClaim.path, extendingClaim.path))\n\n if (matchingBaseClaim) {\n this.validateClaimExtension(matchingBaseClaim, extendingClaim)\n }\n }\n\n // Build final claims array preserving order\n // Start with base claims, replacing any that are overridden\n const mergedClaims: typeof baseClaims = []\n const extendedClaimsWithoutBase = [...extendingClaims]\n\n // Add base claims, replacing with extending version if path matches\n for (const baseClaim of baseClaims) {\n const extendingClaimIndex = extendedClaimsWithoutBase.findIndex((extendingClaim) =>\n claimPathsEqual(baseClaim.path, extendingClaim.path)\n )\n const extendingClaim = extendingClaimIndex !== -1 ? extendedClaimsWithoutBase[extendingClaimIndex] : undefined\n\n // Remove item from the array\n if (extendingClaim) {\n extendedClaimsWithoutBase.splice(extendingClaimIndex, 1)\n }\n\n // Prefer extending claim, otherwise use base claim\n mergedClaims.push(extendingClaim ?? baseClaim)\n }\n\n // Add all remaining claims at the end\n mergedClaims.push(...extendedClaimsWithoutBase)\n\n merged.claims = mergedClaims\n }\n\n // Handle display metadata (section 8.2)\n // If extending type doesn't define display, inherit from base\n if (!extending.display && base.display) {\n merged.display = base.display\n }\n\n return merged\n }\n\n /**\n * Resolves the full VCT chain by recursively fetching extended type metadata.\n * Implements security considerations from spec section 10.3 for circular dependencies.\n * @param vct The VCT URI to resolve\n * @param integrity Optional integrity metadata for the VCT\n * @param depth Current depth in the chain\n * @param visitedVcts Set of already visited VCT URIs to detect circular dependencies\n * @returns The fully resolved and merged type metadata format\n */\n private async resolveVctExtendsChain(\n parentTypeMetadata: TypeMetadataFormat,\n // We start at one, as the base is already fetched when this method is first called\n depth: number = 1,\n // By default include the parent vct, in case of the first call\n visitedVcts: Set<string> = new Set([parentTypeMetadata.vct])\n ): Promise<ResolvedTypeMetadata> {\n const maxDepth = this.userConfig.maxVctExtendsDepth ?? 5\n\n // Check max depth (security consideration from spec section 10.3)\n if (maxDepth !== -1 && depth > maxDepth) {\n throw new SDJWTException(`Maximum VCT extends depth of ${maxDepth} exceeded`)\n }\n\n if (!parentTypeMetadata.extends) {\n throw new SDJWTException(\n `Type metadata for vct '${parentTypeMetadata.vct}' has no 'extends' field. Unable to resolve extended type metadata document.`\n )\n }\n\n // Check for circular dependencies (security consideration from spec section 10.3)\n if (visitedVcts.has(parentTypeMetadata.extends)) {\n throw new SDJWTException(`Circular dependency detected in VCT extends chain: ${parentTypeMetadata.extends}`)\n }\n\n // Mark this VCT as visited\n visitedVcts.add(parentTypeMetadata.extends)\n\n const extendedTypeMetadata = await this.fetchSingleVct(\n parentTypeMetadata.extends,\n parentTypeMetadata['extends#integrity']\n )\n\n // While top-level vct MAY return null (meaning there's no vct type metadata)\n // The extends value ALWAYS must resolve to a value. A custom user provided resolver\n // can return a minimal on-demand type metadata document if it wants to support this use case\n if (!extendedTypeMetadata) {\n throw new SDJWTException(\n `Resolving VCT extends value '${parentTypeMetadata.extends}' resulted in an undefined result.`\n )\n }\n\n let resolvedTypeMetadata: ResolvedTypeMetadata\n\n // If this type extends another, recursively resolve the chain\n // We MUST first process the lower level document before processing\n // the higher level document\n if (extendedTypeMetadata.extends) {\n resolvedTypeMetadata = await this.resolveVctExtendsChain(extendedTypeMetadata, depth + 1, visitedVcts)\n } else {\n resolvedTypeMetadata = {\n mergedTypeMetadata: extendedTypeMetadata,\n typeMetadataChain: [extendedTypeMetadata],\n vctValues: [extendedTypeMetadata.vct],\n }\n }\n\n const mergedTypeMetadata = this.mergeTypeMetadata(resolvedTypeMetadata.mergedTypeMetadata, parentTypeMetadata)\n\n return {\n mergedTypeMetadata: mergedTypeMetadata,\n typeMetadataChain: [parentTypeMetadata, ...resolvedTypeMetadata.typeMetadataChain],\n vctValues: [parentTypeMetadata.vct, ...resolvedTypeMetadata.vctValues],\n }\n }\n\n /**\n * Fetches and verifies the VCT Metadata for a VCT value.\n * @param result\n * @returns\n */\n private async fetchSingleVct(vct: string, integrity?: string): Promise<TypeMetadataFormat | undefined> {\n const fetcher = this.userConfig.vctFetcher ?? ((uri, integrity) => this.fetchWithIntegrity(uri, integrity))\n\n // Data may be undefined\n const data = await fetcher(vct, integrity)\n if (!data) return undefined\n\n const validated = TypeMetadataFormatSchema.safeParse(data)\n if (!validated.success) {\n throw new SDJWTException(`Invalid VCT type metadata for vct '${vct}':\\n${z.prettifyError(validated.error)}`)\n }\n\n // The vct values of a resolved chain are read from the documents, so a document describing\n // another type would let whoever hosts it choose the types a credential matches.\n if (validated.data.vct !== vct) {\n throw new SDJWTException(\n `Type metadata fetched for vct '${vct}' describes vct '${validated.data.vct}'. The vct of the type metadata must match.`\n )\n }\n\n return validated.data\n }\n\n /**\n * Verifies the status of the SD-JWT-VC.\n * @param result\n * @param options\n */\n private async verifyStatus(result: VerificationResult, options?: T & VerifierOptions): Promise<void> {\n if (options?.disableStatusVerification) {\n return\n }\n\n if (result.payload.status) {\n //checks if a status field is present in the payload based on https://www.ietf.org/archive/id/draft-ietf-oauth-status-list-02.html\n if (result.payload.status.status_list) {\n const { uri, idx } = result.payload.status.status_list\n // fetch the status list from the uri\n const fetcher: StatusListFetcher = this.userConfig.statusListFetcher ?? this.statusListFetcher.bind(this)\n // fetch the status list from the uri\n const statusListJWT = await fetcher(uri)\n\n const slJWT = Jwt.fromEncode<StatusListJWTHeaderParameters, StatusListJWTPayload>(statusListJWT)\n // check that the token is a Status List Token before its signature is verified\n verifyStatusListJwtHeader(slJWT.header ?? {})\n // check if the status list has a valid signature. Falls back to the verifier of the SD-JWT-VC.\n const statusListVerifier = this.userConfig.statusVerifier ?? this.userConfig.verifier\n if (!statusListVerifier) {\n throw new SDJWTException('Verifier not found for status list JWT')\n }\n // The status list verifier gets the verification options, e.g. to resolve the key of the status list\n // issuer. Only the time options are applied to the claims of the Status List Token.\n await slJWT\n .verify((data, sig) => statusListVerifier(data, sig, options), getJwtTimeValidationOptions(options))\n .catch((err: unknown) => {\n const details: StatusListVerificationErrorDetails = { uri }\n // The original exception stays reachable as `cause`, e.g. a JwtTimeClaimException with the\n // exp the status list token was rejected for.\n throw Object.assign(\n new SLException(`Status List JWT verification failed: ${ensureError(err).message}`, details),\n { cause: err }\n )\n })\n\n // check the claims required for a Status List Token, e.g. that `sub` matches the referenced uri\n verifyStatusListJwtClaims(slJWT.payload as StatusListJWTPayload, {\n uri,\n now: options?.currentDate !== undefined ? secondsToDate(options.currentDate) : undefined,\n skewSeconds: options?.skewSeconds,\n })\n\n // get the status list from the status list JWT\n const statusList = getListFromStatusListJWT(statusListJWT)\n const status = statusList.getStatus(idx)\n\n // validate the status\n const statusValidator: StatusValidator = this.userConfig.statusValidator ?? this.statusValidator.bind(this)\n await statusValidator(status, { uri, idx })\n }\n }\n }\n\n public config(newConfig: SDJWTVCConfig<T>) {\n super.config(newConfig)\n }\n}\n\nfunction isResolvedTypeMetadata(\n typeMetadata: ResolvedTypeMetadata | TypeMetadataFormat\n): typeMetadata is ResolvedTypeMetadata {\n const candidate = typeMetadata as Partial<ResolvedTypeMetadata>\n return (\n Array.isArray(candidate.typeMetadataChain) &&\n Array.isArray(candidate.vctValues) &&\n typeof candidate.mergedTypeMetadata === 'object' &&\n candidate.mergedTypeMetadata !== null\n )\n}\n\nfunction assertDisclosuresReferenced(payload: Record<string, unknown>, disclosures: Record<string, Disclosure>) {\n unpackObj(payload, disclosures)\n}\n"],"mappings":";;;;;AAEA,MAAa,wBAAwBA,IAAE,YAAY;;CAEjD,KAAKA,IAAE,OAAO;;CAEd,iBAAiBA,IAAE,OAAO,CAAC,CAAC,SAAS;AACvC,CAAC;;;;AAMD,MAAa,aAAaA,IAAE,YAAY;;CAEtC,KAAKA,IAAE,OAAO;;CAEd,iBAAiBA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAErC,UAAUA,IAAE,OAAO,CAAC,CAAC,SAAS;AAChC,CAAC;;;;AAOD,MAAa,wBAAwBA,IAAE,YAAY;;CAEjD,MAAM,WAAW,SAAS;;CAE1B,kBAAkBA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAEtC,YAAYA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAEhC,kBAAkB,sBAAsB,SAAS;AACnD,CAAC;;AAKD,MAAa,oBAAoBA,IAAE,KAAK,CAAC,YAAY,WAAW,CAAC;;AAGjE,MAAa,oBAAoBA,IAAE,KAAK,CAAC,SAAS,MAAM,CAAC;;AAGzD,MAAa,iBAAiBA,IAAE,KAAK,CAAC,UAAU,MAAM,CAAC;;;;AAKvD,MAAa,8BAA8BA,IAAE,YAAY;;CAEvD,aAAa,kBAAkB,SAAS;;CAExC,cAAc,kBAAkB,SAAS;;CAEzC,UAAU,eAAe,SAAS;AACpC,CAAC;;;;AAOD,MAAa,6BAA6BA,IAAE,YAAY;;CAEtD,KAAKA,IAAE,OAAO;;CAEd,iBAAiBA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAErC,YAAY,4BAA4B,SAAS;AACnD,CAAC;;;;AAOD,MAAa,kBAAkBA,IAC5B,YAAY;;CAEX,QAAQ,sBAAsB,SAAS;;CAEvC,eAAeA,IAAE,MAAM,0BAA0B,CAAC,CAAC,SAAS;;;;;CAK5D,cAAcA,IAAE,MAAM,0BAA0B,CAAC,CAAC,SAAS;AAC7D,CAAC,CAAC,CACD,WAAW,EAAE,cAAc,eAAe,GAAG,YAAY;CACxD,GAAG;CACH,eAAe,iBAAiB;AAClC,EAAE;;;;AAOJ,MAAa,gBAAgBA,IAC1B,YAAY;;;;;CAKX,MAAMA,IAAE,OAAO,CAAC,CAAC,SAAS;;;;;CAM1B,QAAQA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAG5B,MAAMA,IAAE,OAAO;;CAEf,aAAaA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAEjC,WAAW,gBAAgB,SAAS;AACtC,CAAC,CAAC,CACD,WAAW,EAAE,MAAM,QAAQ,GAAG,YAAY;CACzC,GAAG;CACH,QAAQ,UAAU;AACpB,EAAE,CAAC,CACF,QAAQ,EAAE,aAAa,WAAW,KAAA,GAAW,EAC5C,SAAS,oGACX,CAAC;;;;;AAQH,MAAa,kBAAkBA,IAAE,MAAMA,IAAE,OAAO,CAAC,CAAC,SAAS,CAAC;;;;AAO5D,MAAa,qBAAqBA,IAC/B,YAAY;;;;;CAKX,MAAMA,IAAE,OAAO,CAAC,CAAC,SAAS;;;;;CAM1B,QAAQA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAG5B,OAAOA,IAAE,OAAO,CAAC,CAAC,SAAS;;;;;CAM3B,MAAMA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAG1B,aAAaA,IAAE,OAAO,CAAC,CAAC,SAAS;AACnC,CAAC,CAAC,CACD,WAAW,EAAE,MAAM,MAAM,OAAO,QAAQ,GAAG,YAAY;CACtD,GAAG;CACH,QAAQ,UAAU;CAClB,OAAO,SAAS;AAClB,EAAE,CAAC,CACF,QAAQ,EAAE,aAAa,WAAW,KAAA,GAAW,EAC5C,SAAS,yFACX,CAAC,CAAC,CACD,QAAQ,EAAE,YAAY,UAAU,KAAA,GAAW,EAC1C,SAAS,wFACX,CAAC;;;;AAOH,MAAa,iCAAiCA,IAAE,KAAK;CAAC;CAAU;CAAW;AAAO,CAAC;;;;AAOnF,MAAa,cAAcA,IAAE,YAAY;;;;;CAKvC,MAAM;;CAEN,SAASA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;;CAE9C,IAAI,+BAA+B,SAAS;;;;;CAK5C,WAAWA,IAAE,QAAQ,CAAC,CAAC,SAAS;;;;;CAKhC,QAAQA,IAAE,OAAO,CAAC,CAAC,SAAS;AAC9B,CAAC;;;;;AAQD,MAAa,2BAA2BA,IAAE,YAAY;;CAEpD,KAAKA,IAAE,OAAO;;CAEd,MAAMA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAE1B,aAAaA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAEjC,SAASA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAE7B,qBAAqBA,IAAE,OAAO,CAAC,CAAC,SAAS;;CAEzC,SAASA,IAAE,MAAM,aAAa,CAAC,CAAC,SAAS;;CAEzC,QAAQA,IAAE,MAAM,WAAW,CAAC,CAAC,SAAS;AACxC,CAAC;;;AClOD,MAAM,oBAAoB;CAAC;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAiB;AAAQ;AAOrG,SAAgB,gBAAgB,OAAkB,OAA2B;CAC3E,IAAI,MAAM,WAAW,MAAM,QAAQ,OAAO;CAC1C,OAAO,MAAM,OAAO,KAAK,QAAQ,QAAQ,MAAM,IAAI;AACrD;AAEA,SAAS,cAAc,WAAsB,aAAqC,QAAyB;CACzG,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;EAC/B,MAAM,MAAM,UAAU;EACtB,IAAI,QAAQ,OAAO,OAAO,YAAY,OAAO,WAAW,QAAQ,YAAY,IAAI,OAAO;CACzF;CACA,OAAO;AACT;AAEA,SAAS,iBAAiB,WAAsB,aAA8C;CAC5F,OAAO,UAAU,WAAW,YAAY,UAAU,cAAc,WAAW,aAAa,UAAU,MAAM;AAC1G;AAEA,SAAS,qBAAqB,OAAoD;CAChF,OACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,KAC9B,OAAQ,MAAkC,iBAAiB;AAE/D;AAEA,SAAS,qBAAqB,SAAkC,aAAyC;CACvG,MAAM,SAAyB,CAAC;CAEhC,MAAM,SAAS,MAAe,SAAiC;EAC7D,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;EAE/C,IAAI,MAAM,QAAQ,IAAI,GAAG;GACvB,KAAK,SAAS,SAAS,UAAU;IAC/B,IAAI,qBAAqB,OAAO,GAAG;KACjC,MAAM,aAAa,YAAY,QAAQ;KACvC,IAAI,CAAC,YAAY;KACjB,OAAO,KAAK;MAAE,MAAM,CAAC,GAAG,MAAM,KAAK;MAAG,MAAM;KAAK,CAAC;KAClD,MAAM,WAAW,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC;IAC1C,OAAO;KACL,OAAO,KAAK;MAAE,MAAM,CAAC,GAAG,MAAM,KAAK;MAAG,MAAM;KAAM,CAAC;KACnD,MAAM,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC;IACjC;GACF,CAAC;GACD;EACF;EAEA,MAAM,SAAS;EACf,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;GACjD,IAAI,QAAQ,aAAc,KAAK,WAAW,KAAK,QAAQ,WAAY;GACnE,OAAO,KAAK;IAAE,MAAM,CAAC,GAAG,MAAM,GAAG;IAAG,MAAM;GAAM,CAAC;GACjD,MAAM,OAAO,CAAC,GAAG,MAAM,GAAG,CAAC;EAC7B;EAEA,MAAM,UAAU,MAAM,QAAQ,OAAO,UAAU,IAAI,OAAO,aAAa,CAAC;EACxE,KAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,aAAa,OAAO,WAAW,WAAW,YAAY,UAAU,KAAA;GACtE,IAAI,CAAC,cAAc,OAAO,WAAW,QAAQ,UAAU;GACvD,OAAO,KAAK;IAAE,MAAM,CAAC,GAAG,MAAM,WAAW,GAAG;IAAG,MAAM;GAAK,CAAC;GAC3D,MAAM,WAAW,OAAO,CAAC,GAAG,MAAM,WAAW,GAAG,CAAC;EACnD;CACF;CAEA,MAAM,SAAS,CAAC,CAAC;CACjB,OAAO;AACT;AAIA,SAAS,aAAa,MAAe,SAAwB,aAAyC;CACpG,MAAM,UAA6D,CAAC;CACpE,IAAI,SAAS;CAEb,IAAI,YAAY,MAAM;EACpB,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO;GAAE;GAAS;EAAO;EACnD,KAAK,SAAS,SAAS,UAAU;GAC/B,IAAI,CAAC,qBAAqB,OAAO,GAAG;IAClC,QAAQ,KAAK;KAAE;KAAO,OAAO;IAAQ,CAAC;IACtC;GACF;GACA,MAAM,aAAa,YAAY,QAAQ;GACvC,IAAI,YAAY,QAAQ,KAAK;IAAE;IAAO,OAAO,WAAW;GAAM,CAAC;QAC1D,SAAS;EAChB,CAAC;EACD,OAAO;GAAE;GAAS;EAAO;CAC3B;CAEA,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG,OAAO;EAAE;EAAS;CAAO;CAC/F,MAAM,SAAS;CAEf,IAAI,YAAY,aAAa,OAAO,UAAU,eAAe,KAAK,QAAQ,OAAO,GAC/E,QAAQ,KAAK;EAAE,OAAO;EAAS,OAAO,OAAO;CAAS,CAAC;CAGzD,MAAM,UAAU,MAAM,QAAQ,OAAO,UAAU,IAAI,OAAO,aAAa,CAAC;CACxE,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,aAAa,OAAO,WAAW,WAAW,YAAY,UAAU,KAAA;EACtE,IAAI,CAAC,YAAY,SAAS;OACrB,IAAI,WAAW,QAAQ,SAAS,QAAQ,KAAK;GAAE,OAAO;GAAS,OAAO,WAAW;EAAM,CAAC;CAC/F;CACA,OAAO;EAAE;EAAS;CAAO;AAC3B;AAEA,SAAS,qBACP,OACA,gBACA,eACA,aACa;CACb,MAAM,QAAQ,WACZ,eAAe,MAAM,OAAO,gBAAgB,GAAG,MAAM,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE;CAEtF,MAAM,QAAQ,MAAe,UAA+B;EAC1D,IAAI,UAAU,MAAM,KAAK,QAAQ,OAAO;EAExC,MAAM,UAAU,MAAM,KAAK;EAC3B,MAAM,EAAE,SAAS,WAAW,aAAa,MAAM,SAAS,WAAW;EACnE,IAAI,SAAsB;EAC1B,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,cAAc,KAAK,MAAM,OAAO,QAAQ,CAAC;GAC/C,IAAI,gBAAgB,WAAW,OAAO;GACtC,IAAI,gBAAgB,eAAe,SAAS;EAC9C;EAEA,IAAI,YAAY,MAAM;GACpB,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO;GACjC,OAAO,QAAQ,WAAW,KAAK,SAAS,gBAAgB;EAC1D;EACA,IAAI,QAAQ,SAAS,GAAG,OAAO;EAE/B,OAAO,UAAU,KAAK,QAAQ,CAAC,MAAM,UAAU,gBAAgB;CACjE;CAEA,OAAO,KAAK,eAAe,CAAC;AAC9B;AAEA,SAAS,qBAAqB,MAAyC;CACrE,OAAO,KAAK,KAAK,QAAS,OAAO,QAAQ,WAAW,OAAO,GAAI;AACjE;AAEA,SAAS,qBAAqB;CAC5B,MAAM,wBAAQ,IAAI,IAAuB;CACzC,OAAO;EACL,MAAM,SAAoB,MAAM,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;EAC9D,cAAc,MAAM,KAAK,MAAM,OAAO,CAAC;CACzC;AACF;;;;;;;;;;AAWA,SAAgB,gCACd,cACA,eACA,aACgC;CAChC,MAAM,iBAAiB,aAAa,UAAU,CAAC;CAC/C,MAAM,gBAAgB,qBAAqB,eAAe,WAAW;CAErE,MAAM,cAAc,mBAAmB;CACvC,MAAM,yBAAyB,mBAAmB;CAClD,MAAM,6BAA6B,mBAAmB;CACtD,MAAM,yCAAyC,mBAAmB;CAClE,MAAM,sCAAsC,mBAAmB;CAE/D,MAAM,uBAAuB,cAC3B,eAAe,MACZ,OAAO,GAAG,KAAK,SAAS,UAAU,UAAU,gBAAgB,GAAG,KAAK,MAAM,GAAG,UAAU,MAAM,GAAG,SAAS,CAC5G;CAEF,MAAM,aAAa,SAAiC;EAClD,IAAI,kBAAkB,SAAS,OAAO,KAAK,EAAE,CAAC,KAAK,CAAC,eAAe,MAAM,OAAO,GAAG,KAAK,OAAO,KAAK,EAAE,GACpG,OAAO;EAGT,OAAO,eAAe,MACnB,OACE,KAAK,SAAS,GAAG,KAAK,UAAU,cAAc,GAAG,MAAM,MAAM,KAAK,MAAM,KACxE,KAAK,SAAS,GAAG,KAAK,UAAU,cAAc,GAAG,MAAM,MAAM,GAAG,KAAK,MAAM,KAAK,CAAC,oBAAoB,GAAG,IAAI,CACjH;CACF;CAEA,KAAK,MAAM,gBAAgB,eAAe;EACxC,MAAM,yBAAyB,eAAe,QAAQ,OAAO,iBAAiB,GAAG,MAAM,aAAa,IAAI,CAAC;EAEzG,IAAI,uBAAuB,WAAW,GAAG;GACvC,IAAI,aAAa,UAAU,CAAC,UAAU,aAAa,IAAI,GAAG,YAAY,IAAI,qBAAqB,aAAa,IAAI,CAAC;GACjH;EACF;EAEA,KAAK,MAAM,iBAAiB,wBAC1B,IAAI,cAAc,OAAO,YAAY,CAAC,aAAa,MACjD,uCAAuC,IAAI,cAAc,IAAI;OACxD,IAAI,cAAc,OAAO,WAAW,aAAa,MACtD,oCAAoC,IAAI,cAAc,IAAI;CAGhE;CAEA,KAAK,MAAM,iBAAiB,gBAAgB;EAC1C,IAAI,CAAC,cAAc,WAAW;EAC9B,MAAM,SAAS,qBAAqB,eAAe,gBAAgB,eAAe,WAAW;EAC7F,IAAI,WAAW,WAAW,uBAAuB,IAAI,cAAc,IAAI;OAClE,IAAI,WAAW,eAAe,2BAA2B,IAAI,cAAc,IAAI;CACtF;CAEA,MAAM,kBAAkB,YAAY,OAAO;CAC3C,OAAO;EACL,aAAa,gBAAgB,QAC1B,SACC,CAAC,gBAAgB,MACd,UAAU,MAAM,SAAS,KAAK,UAAU,gBAAgB,OAAO,KAAK,MAAM,GAAG,MAAM,MAAM,CAAC,CAC7F,CACJ;EACA,wBAAwB,uBAAuB,OAAO;EACtD,4BAA4B,2BAA2B,OAAO;EAC9D,wCAAwC,uCAAuC,OAAO;EACtF,qCAAqC,oCAAoC,OAAO;CAClF;AACF;;;AChMA,MAAM,iBAAiB;CAAC;CAAU;CAAU;AAAQ;AAEpD,IAAa,kBAAb,cAAkD,cAAiC;CAQjF,YAAY,YAA+B;EACzC,MAAM,UAAU;EALD,KAAA,OAAA;EAEwB,KAAA,aAAA,CAAC;EAIxC,IAAI,YACF,KAAK,aAAa;CAEtB;;;;;CAMA,wBAAkC,iBAAyD;EACzF,IAAI,iBAAiB,OAAO,MAAM,QAAQ,gBAAgB,GAAG,KAAK,gBAAgB,IAAI,SAAS,GAAG;GAChG,MAAM,gBAAgB;IAAC;IAAO;IAAO;IAAO;IAAO;IAAO;IAAiB;GAAQ;GAEnF,IADuC,gBAAgB,IAAI,QAAQ,QAAQ,cAAc,SAAS,OAAO,GAAG,CAAC,CAC5E,CAAC,CAAC,SAAS,GAC1C,MAAM,IAAI,eAAe,iCAAiC;EAE9D;CACF;;;;;;CAOA,MAAc,kBAAkB,KAA8B;EAC5D,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,YAAY,iBAAiB,WAAW,MAAM,GAAG,GAAK;EAE5D,IAAI;GACF,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,QAAQ,WAAW;IACnB,SAAS,EAAE,QAAQ,WAAW,cAAc;GAC9C,CAAC;GACD,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,+BAA+B,SAAS,OAAO,GAAG,MAAM,SAAS,KAAK,GAAG;GAI3F,IAAI,CAAC,YAAY,SAAS,QAAQ,IAAI,cAAc,GAAG,WAAW,aAAa,GAC7E,MAAM,IAAI,MAAM,sBAAsB;GAGxC,OAAO,SAAS,KAAK;EACvB,UAAU;GACR,aAAa,SAAS;EACxB;CACF;;;;;;;CAQA,MAAc,gBAAgB,QAAgB,EAAE,KAAK,OAA8C;EACjG,IAAI,WAAW,WAAW,OAExB,MAAM,IAAI,eAAe,uBAAuB;GAAE,SAAA;IADL;IAAK;IAAK;GACC;GAAG,MAAM;EAAiB,CAAC;EAErF,OAAO,QAAQ,QAAQ;CACzB;;;;;CAMA,MAAM,OAAO,cAAsB,SAA+B;EAEhE,MAAM,SAA6B,MAAM,MAAM,OAAO,cAAc,OAAO,CAAC,CAAC,MAAM,QAAQ;GACzF,OAAO;IACL,SAAS,IAAI;IACb,QAAQ,IAAI;IACZ,IAAI,IAAI;GACV;EACF,CAAC;EAED,MAAM,KAAK,aAAa,QAAQ,OAAO;EACvC,IAAI,KAAK,WAAW,wBAAwB;GAC1C,MAAM,uBAAuB,MAAM,KAAK,SAAS,MAAM;GACvD,OAAO,eAAe;GACtB,IAAI,sBACF,OAAO,2BAA2B,MAAM,KAAK,kBAC3C,MAAM,KAAK,sBAAsB,YAAY,GAC7C,sBACA,EAAE,qBAAqB,MAAM,CAC/B;EAEJ;EACA,OAAO;CACT;;;;;;;;;;CAWA,MAAM,WAAW,cAAsB,SAA8E;EACnH,MAAM,SAA8B,CAAC;EAGrC,MAAM,YAAY,MAA6B,SAAiB,YAAsB;GACpF,OAAO,KAAK;IAAE;IAAM;IAAS;GAAQ,CAAC;EACxC;EAGA,MAAM,aAAa,MAAM,MAAM,WAAW,cAAc,OAAO;EAG/D,IAAI,CAAC,WAAW,SACd,OAAO,KAAK,GAAG,WAAW,MAAM;EAIlC,IAAI;EACJ,IAAI,WAAW,SACb,SAAS;GACP,SAAS,WAAW,KAAK;GACzB,QAAQ,WAAW,KAAK;GACxB,IAAI,WAAW,KAAK;EACtB;OAGA,IAAI;GACF,MAAM,EAAE,SAAS,WAAW,MAAM,MAAM,WAAoD,YAAY;GACxG,IAAI,SACF,SAAS;IACP;IACA;IACA,IAAI,KAAA;GACN;EAEJ,QAAQ,CAER;EAIF,IAAI,QAAQ;GACV,IAAI;IACF,MAAM,KAAK,aAAa,QAAQ,OAAO;GACzC,SAAS,GAAG;IACV,MAAM,QAAQ,YAAY,CAAC;IAG3B,IAAI,iBAAiB,kBAAkB,MAAM,MAC3C,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK;SAEzC,SAAS,8BAA8B,+BAA+B,MAAM,WAAW,KAAK;GAEhG;GAGA,IAAI,KAAK,WAAW,wBAClB,IAAI;IACF,MAAM,uBAAuB,MAAM,KAAK,SAAS,MAAM;IACvD,IAAI,QAAQ;KACV,OAAO,eAAe;KACtB,IAAI,wBAAwB,WAAW,SACrC,OAAO,2BAA2B,MAAM,KAAK,kBAC3C,MAAM,KAAK,sBAAsB,YAAY,GAC7C,sBACA,EAAE,qBAAqB,MAAM,CAC/B;IAEJ;GACF,SAAS,GAAG;IACV,MAAM,QAAQ,YAAY,CAAC;IAC3B,IAAI,iBAAiB,kBAAkB,MAAM,MAC3C,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK;SAEzC,SAAS,2BAA2B,4BAA4B,MAAM,WAAW,KAAK;GAE1F;EAEJ;EAGA,IAAI,OAAO,SAAS,GAClB,OAAO;GAAE,SAAS;GAAO;EAAO;EAGlC,IAAI,CAAC,QACH,OAAO;GACL,SAAS;GACT,QAAQ,CACN;IACE,MAAM;IACN,SAAS;GACX,CACF;EACF;EAGF,OAAO;GACL,SAAS;GACT,MAAM;EACR;CACF;;;;;;;;;;;CAYA,MAAM,mBACJ,cACA,cACyC;EACzC,MAAM,QAAQ,MAAM,KAAK,sBAAsB,YAAY;EAG3D,IAAI,cAAc;GAChB,MAAM,MAAM,MAAM,KAAK,SAAS;GAChC,MAAM,cAAc,uBAAuB,YAAY,IAAI,aAAa,UAAU,KAAK,aAAa;GACpG,IAAI,QAAQ,aACV,MAAM,IAAI,eAAe,sBAAsB,YAAY,4BAA4B,IAAI,mBAAmB;EAElH;EAEA,MAAM,mBAAmB,eACrB,MAAM,KAAK,uBAAuB,YAAY,IAC9C,MAAM,KAAK,OAAO,YAAY;EAClC,IAAI,CAAC,kBACH,MAAM,IAAI,eAAe,kDAAkD;EAG7E,OAAO,KAAK,kBAAkB,OAAO,kBAAkB,EAAE,qBAAqB,KAAK,CAAC;CACtF;CAEA,MAAc,sBAAsB,cAAsB;EACxD,IAAI,CAAC,KAAK,WAAW,QACnB,MAAM,IAAI,eAAe,kBAAkB;EAE7C,MAAM,QAAQ,MAAM,MAAM,WAAW,cAAc,KAAK,WAAW,MAAM;EACzE,IAAI,CAAC,MAAM,KAAK,SACd,MAAM,IAAI,eAAe,iCAAiC;EAE5D,OAAO;CACT;CAEA,MAAc,kBACZ,OACA,kBACA,EAAE,uBACuC;EACzC,MAAM,SAAS,KAAK,WAAW;EAC/B,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,SACzB,MAAM,IAAI,eAAe,iCAAiC;EAG5D,MAAM,EAAE,SAAS,YAAY,mBAAmB,MAAM,IAAI,OAAO;EACjE,MAAM,cAAc,MAAM,kBAAkB,MAAM,eAAe,CAAC,GAAG;GAAE;GAAQ,KAAK;EAAQ,CAAC;EAC7F,IAAI,qBAAqB,4BAA4B,SAAS,WAAW;EAEzE,OAAO,gCAAgC,iBAAiB,oBAAoB,SAAS,WAAW;CAClG;CAEA,MAAc,uBACZ,cAC+B;EAC/B,IAAI,uBAAuB,YAAY,GAAG,OAAO;EACjD,IAAI,aAAa,SAAS,OAAO,KAAK,uBAAuB,YAAY;EACzE,OAAO;GAAE,oBAAoB;GAAc,mBAAmB,CAAC,YAAY;GAAG,WAAW,CAAC,aAAa,GAAG;EAAE;CAC9G;;;;;;;;;CAUA,MAAM,OAAO,cAAiE;EAE5E,MAAM,EAAE,SAAS,WAAW,MAAM,MAAM,WAAoD,YAAY;EAExG,IAAI,CAAC,SACH,MAAM,IAAI,eAAe,wBAAwB;EAGnD,MAAM,SAA6B;GACjC;GACA;GACA,IAAI,KAAA;EACN;EAEA,OAAO,KAAK,SAAS,MAAM;CAC7B;;;;;;CAOA,MAAc,kBAAkB,UAAoB,KAAa,WAAoB;EACnF,IAAI,CAAC,WAAW;EAIhB,MAAM,UAAU,UACb,MAAM,KAAK,CAAC,CACZ,KAAK,UAAU;GACd,MAAM,CAAC,KAAK,SAAS,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,QAAQ;GACvD,OAAO;IAAE;IAAK;GAAM;EACtB,CAAC,CAAC,CACD,QAAQ,UAAU,eAAe,SAAS,MAAM,GAAG,KAAK,MAAM,KAAK;EACtE,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,eAAe,uBAAuB,IAAI,qCAAqC,WAAW;EAEtG,MAAM,MAAM,QAAQ,QAAQ,WAAW,UACrC,eAAe,QAAQ,MAAM,GAAG,IAAI,eAAe,QAAQ,UAAU,GAAG,IAAI,QAAQ,SACtF,CAAC,CAAC;EACF,MAAM,WAAW,QAAQ,QAAQ,UAAU,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,UAAU,MAAM,KAAK;EAExF,IAAI,CAAC,KAAK,WAAW,QACnB,MAAM,IAAI,eAAe,kBAAkB;EAE7C,MAAM,cAAc,MAAM,SAAS,YAAY;EAC/C,MAAM,OAAO,OAAO,OAAO,MAAM,KAAK,WAAW,OAAO,aAAa,GAAG,CAAC;EACzE,IAAI,CAAC,SAAS,SAAS,IAAI,GACzB,MAAM,IAAI,MAAM,uBAAuB,IAAI,cAAc,KAAK,iBAAiB,SAAS,KAAK,MAAM,GAAG;CAE1G;;;;;;CAOA,MAAc,mBAAmB,KAAa,WAAsC;EAClF,IAAI;GACF,MAAM,WAAW,MAAM,MAAM,KAAK,EAChC,QAAQ,YAAY,QAAQ,KAAK,WAAW,WAAW,GAAK,EAC9D,CAAC;GACD,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,YAAY,MAAM,SAAS,KAAK;IACtC,MAAM,IAAI,MAAM,kBAAkB,IAAI,IAAI,SAAS,OAAO,GAAG,SAAS,WAAW,KAAK,WAAW;GACnG;GACA,MAAM,KAAK,kBAAkB,SAAS,MAAM,GAAG,KAAK,SAAS;GAG7D,OAAO,MAFY,SAAS,KAAK;EAGnC,SAAS,GAAG;GACV,MAAM,QAAQ,YAAY,CAAC;GAC3B,IAAI,MAAM,SAAS,gBACjB,MAAM,IAAI,MAAM,cAAc,IAAI,WAAW;GAE/C,MAAM;EACR;CACF;;;;;;;CAQA,MAAc,SAAS,QAAuE;EAC5F,MAAM,qBAAqB,MAAM,KAAK,eAAe,OAAO,QAAQ,KAAK,OAAO,QAAQ,gBAAgB;EAExG,IAAI,CAAC,oBAAoB,OAAO,KAAA;EAGhC,IAAI,CAAC,mBAAmB,SACtB,OAAO;GACL,oBAAoB;GACpB,mBAAmB,CAAC,kBAAkB;GACtC,WAAW,CAAC,mBAAmB,GAAG;EACpC;EAIF,OAAO,KAAK,uBAAuB,kBAAkB;CACvD;;;;;;;CAQA,uBAA+B,WAAkB,gBAA6B;EAE5E,IAAI,UAAU,MAAM,eAAe,IAE5B;QAAA,UAAU,OAAO,YAAY,UAAU,OAAO,YAAY,UAAU,OAAO,eAAe,IAAI;IACjG,MAAM,UAAU,KAAK,UAAU,eAAe,IAAI;IAClD,MAAM,IAAI,eACR,qCAAqC,UAAU,GAAG,QAAQ,eAAe,GAAG,sBAAsB,SACpG;GACF;;CAEJ;;;;;;;;;;;;;;;;;;;CAoBA,kBAA0B,MAA0B,WAAmD;EAIrG,MAAM,SAA6B,EAAE,GAAG,UAAU;EAGlD,IAAI,KAAK,UAAU,UAAU,QAAQ;GACnC,MAAM,aAAa,KAAK,UAAU,CAAC;GACnC,MAAM,kBAAkB,UAAU,UAAU,CAAC;GAG7C,KAAK,MAAM,kBAAkB,iBAAiB;IAC5C,MAAM,oBAAoB,WAAW,MAAM,cAAc,gBAAgB,UAAU,MAAM,eAAe,IAAI,CAAC;IAE7G,IAAI,mBACF,KAAK,uBAAuB,mBAAmB,cAAc;GAEjE;GAIA,MAAM,eAAkC,CAAC;GACzC,MAAM,4BAA4B,CAAC,GAAG,eAAe;GAGrD,KAAK,MAAM,aAAa,YAAY;IAClC,MAAM,sBAAsB,0BAA0B,WAAW,mBAC/D,gBAAgB,UAAU,MAAM,eAAe,IAAI,CACrD;IACA,MAAM,iBAAiB,wBAAwB,KAAK,0BAA0B,uBAAuB,KAAA;IAGrG,IAAI,gBACF,0BAA0B,OAAO,qBAAqB,CAAC;IAIzD,aAAa,KAAK,kBAAkB,SAAS;GAC/C;GAGA,aAAa,KAAK,GAAG,yBAAyB;GAE9C,OAAO,SAAS;EAClB;EAIA,IAAI,CAAC,UAAU,WAAW,KAAK,SAC7B,OAAO,UAAU,KAAK;EAGxB,OAAO;CACT;;;;;;;;;;CAWA,MAAc,uBACZ,oBAEA,QAAgB,GAEhB,8BAA2B,IAAI,IAAI,CAAC,mBAAmB,GAAG,CAAC,GAC5B;EAC/B,MAAM,WAAW,KAAK,WAAW,sBAAsB;EAGvD,IAAI,aAAa,MAAM,QAAQ,UAC7B,MAAM,IAAI,eAAe,gCAAgC,SAAS,UAAU;EAG9E,IAAI,CAAC,mBAAmB,SACtB,MAAM,IAAI,eACR,0BAA0B,mBAAmB,IAAI,6EACnD;EAIF,IAAI,YAAY,IAAI,mBAAmB,OAAO,GAC5C,MAAM,IAAI,eAAe,sDAAsD,mBAAmB,SAAS;EAI7G,YAAY,IAAI,mBAAmB,OAAO;EAE1C,MAAM,uBAAuB,MAAM,KAAK,eACtC,mBAAmB,SACnB,mBAAmB,oBACrB;EAKA,IAAI,CAAC,sBACH,MAAM,IAAI,eACR,gCAAgC,mBAAmB,QAAQ,mCAC7D;EAGF,IAAI;EAKJ,IAAI,qBAAqB,SACvB,uBAAuB,MAAM,KAAK,uBAAuB,sBAAsB,QAAQ,GAAG,WAAW;OAErG,uBAAuB;GACrB,oBAAoB;GACpB,mBAAmB,CAAC,oBAAoB;GACxC,WAAW,CAAC,qBAAqB,GAAG;EACtC;EAKF,OAAO;GACL,oBAHyB,KAAK,kBAAkB,qBAAqB,oBAAoB,kBAGpD;GACrC,mBAAmB,CAAC,oBAAoB,GAAG,qBAAqB,iBAAiB;GACjF,WAAW,CAAC,mBAAmB,KAAK,GAAG,qBAAqB,SAAS;EACvE;CACF;;;;;;CAOA,MAAc,eAAe,KAAa,WAA6D;EAIrG,MAAM,OAAO,OAHG,KAAK,WAAW,gBAAgB,KAAK,cAAc,KAAK,mBAAmB,KAAK,SAAS,GAAA,CAG9E,KAAK,SAAS;EACzC,IAAI,CAAC,MAAM,OAAO,KAAA;EAElB,MAAM,YAAY,yBAAyB,UAAU,IAAI;EACzD,IAAI,CAAC,UAAU,SACb,MAAM,IAAI,eAAe,sCAAsC,IAAI,MAAM,EAAE,cAAc,UAAU,KAAK,GAAG;EAK7G,IAAI,UAAU,KAAK,QAAQ,KACzB,MAAM,IAAI,eACR,kCAAkC,IAAI,mBAAmB,UAAU,KAAK,IAAI,4CAC9E;EAGF,OAAO,UAAU;CACnB;;;;;;CAOA,MAAc,aAAa,QAA4B,SAA8C;EACnG,IAAI,SAAS,2BACX;EAGF,IAAI,OAAO,QAAQ,QAEb;OAAA,OAAO,QAAQ,OAAO,aAAa;IACrC,MAAM,EAAE,KAAK,QAAQ,OAAO,QAAQ,OAAO;IAI3C,MAAM,gBAAgB,OAFa,KAAK,WAAW,qBAAqB,KAAK,kBAAkB,KAAK,IAAI,EAAA,CAEpE,GAAG;IAEvC,MAAM,QAAQ,IAAI,WAAgE,aAAa;IAE/F,0BAA0B,MAAM,UAAU,CAAC,CAAC;IAE5C,MAAM,qBAAqB,KAAK,WAAW,kBAAkB,KAAK,WAAW;IAC7E,IAAI,CAAC,oBACH,MAAM,IAAI,eAAe,wCAAwC;IAInE,MAAM,MACH,QAAQ,MAAM,QAAQ,mBAAmB,MAAM,KAAK,OAAO,GAAG,4BAA4B,OAAO,CAAC,CAAC,CACnG,OAAO,QAAiB;KACvB,MAAM,UAA8C,EAAE,IAAI;KAG1D,MAAM,OAAO,OACX,IAAI,YAAY,wCAAwC,YAAY,GAAG,CAAC,CAAC,WAAW,OAAO,GAC3F,EAAE,OAAO,IAAI,CACf;IACF,CAAC;IAGH,0BAA0B,MAAM,SAAiC;KAC/D;KACA,KAAK,SAAS,gBAAgB,KAAA,IAAY,cAAc,QAAQ,WAAW,IAAI,KAAA;KAC/E,aAAa,SAAS;IACxB,CAAC;IAID,MAAM,SADa,yBAAyB,aACpB,CAAC,CAAC,UAAU,GAAG;IAIvC,OADyC,KAAK,WAAW,mBAAmB,KAAK,gBAAgB,KAAK,IAAI,EAAA,CACpF,QAAQ;KAAE;KAAK;IAAI,CAAC;GAC5C;;CAEJ;CAEA,OAAc,WAA6B;EACzC,MAAM,OAAO,SAAS;CACxB;AACF;AAEA,SAAS,uBACP,cACsC;CACtC,MAAM,YAAY;CAClB,OACE,MAAM,QAAQ,UAAU,iBAAiB,KACzC,MAAM,QAAQ,UAAU,SAAS,KACjC,OAAO,UAAU,uBAAuB,YACxC,UAAU,uBAAuB;AAErC;AAEA,SAAS,4BAA4B,SAAkC,aAAyC;CAC9G,UAAU,SAAS,WAAW;AAChC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sd-jwt/sd-jwt-vc",
3
- "version": "0.24.0-alpha-20261029093248",
3
+ "version": "0.24.0",
4
4
  "description": "SD-JWT VC (draft-ietf-oauth-sd-jwt-vc) implementation in TypeScript",
5
5
  "files": [
6
6
  "dist"
@@ -24,9 +24,9 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "zod": "^4.6.7",
27
- "@owf/identity-common": "^0.6.1-alpha-20261029093248",
28
- "@owf/token-status-list": "^0.6.1-alpha-20261029093248",
29
- "@sd-jwt/core": "0.24.0-alpha-20261029093248"
27
+ "@owf/identity-common": "^0.6.1",
28
+ "@owf/token-status-list": "^0.6.1",
29
+ "@sd-jwt/core": "0.24.0"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsdown src/index.ts --format esm --dts --sourcemap"