@openid4vc/openid4vp 0.3.0-alpha-20250713113151 → 0.3.0-alpha-20250714090135

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.d.mts CHANGED
@@ -2,6 +2,7 @@ import * as zod from 'zod';
2
2
  import zod__default, { z } from 'zod';
3
3
  import * as _openid4vc_oauth2 from '@openid4vc/oauth2';
4
4
  import { Jwk, JwtSignerWithJwk, decodeJwt, CallbackContext, JwtPayload, JwtSigner, JweEncryptor, HashAlgorithm, JwkSet } from '@openid4vc/oauth2';
5
+ import { NonEmptyArray } from '@openid4vc/utils';
5
6
 
6
7
  declare const zOpenid4vpAuthorizationRequest: z.ZodObject<{
7
8
  response_type: z.ZodLiteral<"vp_token">;
@@ -21697,15 +21698,15 @@ type PexPresentationSubmission = z.infer<typeof zPexPresentationSubmission>;
21697
21698
  declare const zTransactionEntry: z.ZodObject<{
21698
21699
  type: z.ZodString;
21699
21700
  credential_ids: z.ZodArray<z.ZodString, "atleastone">;
21700
- transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21701
+ transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
21701
21702
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
21702
21703
  type: z.ZodString;
21703
21704
  credential_ids: z.ZodArray<z.ZodString, "atleastone">;
21704
- transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21705
+ transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
21705
21706
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
21706
21707
  type: z.ZodString;
21707
21708
  credential_ids: z.ZodArray<z.ZodString, "atleastone">;
21708
- transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21709
+ transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
21709
21710
  }, z.ZodTypeAny, "passthrough">>;
21710
21711
  type TransactionDataEntry = z.infer<typeof zTransactionEntry>;
21711
21712
 
@@ -21904,11 +21905,11 @@ declare function validateOpenid4vpAuthorizationResponsePayload(options: Validate
21904
21905
  interface TransactionDataHashesCredentials {
21905
21906
  /**
21906
21907
  * credentialId is the pex input descriptor id
21907
- * or dcql credential query id
21908
+ * or dcql credential query id.
21908
21909
  *
21909
21910
  * The values must be an array of transaction data hashes
21910
21911
  */
21911
- [credentialId: string]: {
21912
+ [credentialId: string]: NonEmptyArray<{
21912
21913
  /**
21913
21914
  * The hashes of the transaction data
21914
21915
  */
@@ -21919,7 +21920,7 @@ interface TransactionDataHashesCredentials {
21919
21920
  * is used.
21920
21921
  */
21921
21922
  transaction_data_hashes_alg?: string;
21922
- } | undefined;
21923
+ }> | undefined;
21923
21924
  }
21924
21925
  interface VerifyTransactionDataOptions {
21925
21926
  transactionData: string[];
@@ -21929,9 +21930,12 @@ interface VerifyTransactionDataOptions {
21929
21930
  interface VerifiedTransactionDataEntry {
21930
21931
  transactionDataEntry: ParsedTransactionDataEntry;
21931
21932
  credentialId: string;
21932
- hash: string;
21933
- hashAlg: HashAlgorithm;
21934
- credentialHashIndex: number;
21933
+ presentations: NonEmptyArray<{
21934
+ presentationIndex: number;
21935
+ hash: string;
21936
+ hashAlg: HashAlgorithm;
21937
+ credentialHashIndex: number;
21938
+ }>;
21935
21939
  }
21936
21940
 
21937
21941
  declare function parsePexVpToken(vpToken: unknown): [VpTokenPresentationEntry, ...VpTokenPresentationEntry[]];
@@ -31238,6 +31242,14 @@ declare class Openid4vpVerifier {
31238
31242
  parsePexVpToken(vpToken: unknown): [string | Record<string, any>, ...(string | Record<string, any>)[]];
31239
31243
  parseDcqlVpToken(vpToken: unknown): Record<string, [string | Record<string, any>, ...(string | Record<string, any>)[]]>;
31240
31244
  parseTransactionData(options: ParseTransactionDataOptions): ParsedTransactionDataEntry[];
31245
+ /**
31246
+ * Verify transaction data against submitted credentials.
31247
+ *
31248
+ * NOTE: this expects transaction data based authorization based on hashes. This is the method defined
31249
+ * for SD-JWT VC, but for mDOCs it's much more generic. If you're using transaction data with mDOCs based
31250
+ * on hashes, you can extract the values from the DeviceResponse, otherwise you must verify the transaction data
31251
+ * manually.
31252
+ */
31241
31253
  verifyTransactionData(options: Omit<VerifyTransactionDataOptions, 'callbacks'>): Promise<VerifiedTransactionDataEntry[]>;
31242
31254
  }
31243
31255
 
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as zod from 'zod';
2
2
  import zod__default, { z } from 'zod';
3
3
  import * as _openid4vc_oauth2 from '@openid4vc/oauth2';
4
4
  import { Jwk, JwtSignerWithJwk, decodeJwt, CallbackContext, JwtPayload, JwtSigner, JweEncryptor, HashAlgorithm, JwkSet } from '@openid4vc/oauth2';
5
+ import { NonEmptyArray } from '@openid4vc/utils';
5
6
 
6
7
  declare const zOpenid4vpAuthorizationRequest: z.ZodObject<{
7
8
  response_type: z.ZodLiteral<"vp_token">;
@@ -21697,15 +21698,15 @@ type PexPresentationSubmission = z.infer<typeof zPexPresentationSubmission>;
21697
21698
  declare const zTransactionEntry: z.ZodObject<{
21698
21699
  type: z.ZodString;
21699
21700
  credential_ids: z.ZodArray<z.ZodString, "atleastone">;
21700
- transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21701
+ transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
21701
21702
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
21702
21703
  type: z.ZodString;
21703
21704
  credential_ids: z.ZodArray<z.ZodString, "atleastone">;
21704
- transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21705
+ transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
21705
21706
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
21706
21707
  type: z.ZodString;
21707
21708
  credential_ids: z.ZodArray<z.ZodString, "atleastone">;
21708
- transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21709
+ transaction_data_hashes_alg: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
21709
21710
  }, z.ZodTypeAny, "passthrough">>;
21710
21711
  type TransactionDataEntry = z.infer<typeof zTransactionEntry>;
21711
21712
 
@@ -21904,11 +21905,11 @@ declare function validateOpenid4vpAuthorizationResponsePayload(options: Validate
21904
21905
  interface TransactionDataHashesCredentials {
21905
21906
  /**
21906
21907
  * credentialId is the pex input descriptor id
21907
- * or dcql credential query id
21908
+ * or dcql credential query id.
21908
21909
  *
21909
21910
  * The values must be an array of transaction data hashes
21910
21911
  */
21911
- [credentialId: string]: {
21912
+ [credentialId: string]: NonEmptyArray<{
21912
21913
  /**
21913
21914
  * The hashes of the transaction data
21914
21915
  */
@@ -21919,7 +21920,7 @@ interface TransactionDataHashesCredentials {
21919
21920
  * is used.
21920
21921
  */
21921
21922
  transaction_data_hashes_alg?: string;
21922
- } | undefined;
21923
+ }> | undefined;
21923
21924
  }
21924
21925
  interface VerifyTransactionDataOptions {
21925
21926
  transactionData: string[];
@@ -21929,9 +21930,12 @@ interface VerifyTransactionDataOptions {
21929
21930
  interface VerifiedTransactionDataEntry {
21930
21931
  transactionDataEntry: ParsedTransactionDataEntry;
21931
21932
  credentialId: string;
21932
- hash: string;
21933
- hashAlg: HashAlgorithm;
21934
- credentialHashIndex: number;
21933
+ presentations: NonEmptyArray<{
21934
+ presentationIndex: number;
21935
+ hash: string;
21936
+ hashAlg: HashAlgorithm;
21937
+ credentialHashIndex: number;
21938
+ }>;
21935
21939
  }
21936
21940
 
21937
21941
  declare function parsePexVpToken(vpToken: unknown): [VpTokenPresentationEntry, ...VpTokenPresentationEntry[]];
@@ -31238,6 +31242,14 @@ declare class Openid4vpVerifier {
31238
31242
  parsePexVpToken(vpToken: unknown): [string | Record<string, any>, ...(string | Record<string, any>)[]];
31239
31243
  parseDcqlVpToken(vpToken: unknown): Record<string, [string | Record<string, any>, ...(string | Record<string, any>)[]]>;
31240
31244
  parseTransactionData(options: ParseTransactionDataOptions): ParsedTransactionDataEntry[];
31245
+ /**
31246
+ * Verify transaction data against submitted credentials.
31247
+ *
31248
+ * NOTE: this expects transaction data based authorization based on hashes. This is the method defined
31249
+ * for SD-JWT VC, but for mDOCs it's much more generic. If you're using transaction data with mDOCs based
31250
+ * on hashes, you can extract the values from the DeviceResponse, otherwise you must verify the transaction data
31251
+ * manually.
31252
+ */
31241
31253
  verifyTransactionData(options: Omit<VerifyTransactionDataOptions, 'callbacks'>): Promise<VerifiedTransactionDataEntry[]>;
31242
31254
  }
31243
31255
 
package/dist/index.js CHANGED
@@ -811,10 +811,10 @@ function parseAuthorizationRequestVersion(request) {
811
811
  if (request.client_metadata?.vp_formats_supported?.mso_mdoc?.issuer_signed_alg_values || request.client_metadata?.vp_formats_supported?.mso_mdoc?.device_signed_alg_values) {
812
812
  requirements.push(["<", 28]);
813
813
  }
814
- if (request.client_metadata?.vp_formats) {
814
+ if (request.client_metadata?.vp_formats_supported) {
815
815
  requirements.push([">=", 27]);
816
816
  }
817
- if (request.client_metadata?.vp_formats_supported) {
817
+ if (request.client_metadata?.vp_formats) {
818
818
  requirements.push(["<", 27]);
819
819
  }
820
820
  if (request.client_id?.startsWith("openid_federation:") || request.client_id?.startsWith("decentralized_identifier:")) {
@@ -1400,7 +1400,8 @@ var import_zod14 = require("zod");
1400
1400
  var zTransactionEntry = import_zod14.z.object({
1401
1401
  type: import_zod14.z.string(),
1402
1402
  credential_ids: import_zod14.z.array(import_zod14.z.string()).nonempty(),
1403
- transaction_data_hashes_alg: import_zod14.z.array(import_zod14.z.string()).optional()
1403
+ // SD-JWT VC specific
1404
+ transaction_data_hashes_alg: import_zod14.z.array(import_zod14.z.string()).nonempty().optional()
1404
1405
  }).passthrough();
1405
1406
  var zTransactionData = import_zod14.z.array(zTransactionEntry);
1406
1407
 
@@ -2056,32 +2057,44 @@ async function verifyTransactionDataEntry({
2056
2057
  hashes[alg] = (0, import_utils25.encodeToBase64Url)(await callbacks.hash((0, import_utils25.decodeUtf8String)(entry.encoded), alg));
2057
2058
  }
2058
2059
  for (const credentialId of entry.transactionData.credential_ids) {
2059
- const transactionDataHashesCredential = credentials[credentialId];
2060
- if (!transactionDataHashesCredential) continue;
2061
- const alg = transactionDataHashesCredential.transaction_data_hashes_alg ?? "sha-256";
2062
- const hash = hashes[alg];
2063
- if (!allowedAlgs.includes(alg)) {
2064
- throw new import_oauth229.Oauth2ServerErrorResponseError({
2065
- error: import_oauth229.Oauth2ErrorCodes.InvalidTransactionData,
2066
- error_description: `Transaction data entry with index ${entry.transactionDataIndex} is hashed using alg '${alg}'. However transaction data only allows alg values ${allowedAlgs.join(", ")}.`
2067
- });
2068
- }
2069
- if (!hash) {
2070
- throw new import_oauth229.Oauth2ServerErrorResponseError({
2071
- error: import_oauth229.Oauth2ErrorCodes.InvalidTransactionData,
2072
- error_description: `Transaction data entry with index ${entry.transactionDataIndex} is hashed using unsupported alg '${alg}'. This library only supports verification of transaction data hashes using alg values ${Object.values(import_oauth229.HashAlgorithm).join(", ")}. Either verify the hashes outside of this library, or limit the allowed alg values to the ones supported by this library.`
2073
- });
2074
- }
2075
- const credentialHashIndex = transactionDataHashesCredential.transaction_data_hashes.indexOf(hash);
2076
- if (credentialHashIndex !== -1) {
2077
- return {
2078
- transactionDataEntry: entry,
2079
- credentialId,
2060
+ const transactionDataHashesCredentials = credentials[credentialId];
2061
+ if (!transactionDataHashesCredentials) continue;
2062
+ const presentations = [];
2063
+ for (const transactionDataHashesCredential of transactionDataHashesCredentials) {
2064
+ const alg = transactionDataHashesCredential.transaction_data_hashes_alg ?? "sha-256";
2065
+ const hash = hashes[alg];
2066
+ const presentationIndex = transactionDataHashesCredentials.indexOf(transactionDataHashesCredential);
2067
+ if (!allowedAlgs.includes(alg)) {
2068
+ throw new import_oauth229.Oauth2ServerErrorResponseError({
2069
+ error: import_oauth229.Oauth2ErrorCodes.InvalidTransactionData,
2070
+ error_description: `Transaction data entry with index ${entry.transactionDataIndex} for presentation ${credentialId} with index ${presentationIndex} is hashed using alg '${alg}'. However transaction data only allows alg values ${allowedAlgs.join(", ")}.`
2071
+ });
2072
+ }
2073
+ if (!hash) {
2074
+ throw new import_oauth229.Oauth2ServerErrorResponseError({
2075
+ error: import_oauth229.Oauth2ErrorCodes.InvalidTransactionData,
2076
+ error_description: `Transaction data entry with index ${entry.transactionDataIndex} for presentation ${credentialId} with index ${presentationIndex} is hashed using unsupported alg '${alg}'. This library only supports verification of transaction data hashes using alg values ${Object.values(import_oauth229.HashAlgorithm).join(", ")}. Either verify the hashes outside of this library, or limit the allowed alg values to the ones supported by this library.`
2077
+ });
2078
+ }
2079
+ const credentialHashIndex = transactionDataHashesCredential.transaction_data_hashes.indexOf(hash);
2080
+ if (credentialHashIndex === -1) {
2081
+ throw new import_oauth229.Oauth2ServerErrorResponseError({
2082
+ error: import_oauth229.Oauth2ErrorCodes.InvalidTransactionData,
2083
+ error_description: `Transaction data entry with index ${entry.transactionDataIndex} for presentation ${credentialId} with index ${presentationIndex} does not have a matching hash in the transaction_data_hashes`
2084
+ });
2085
+ }
2086
+ presentations.push({
2087
+ credentialHashIndex,
2080
2088
  hash,
2081
2089
  hashAlg: alg,
2082
- credentialHashIndex
2083
- };
2090
+ presentationIndex
2091
+ });
2084
2092
  }
2093
+ return {
2094
+ transactionDataEntry: entry,
2095
+ credentialId,
2096
+ presentations
2097
+ };
2085
2098
  }
2086
2099
  throw new import_oauth229.Oauth2ServerErrorResponseError({
2087
2100
  error: import_oauth229.Oauth2ErrorCodes.InvalidTransactionData,
@@ -2115,6 +2128,14 @@ var Openid4vpVerifier = class {
2115
2128
  parseTransactionData(options) {
2116
2129
  return parseTransactionData(options);
2117
2130
  }
2131
+ /**
2132
+ * Verify transaction data against submitted credentials.
2133
+ *
2134
+ * NOTE: this expects transaction data based authorization based on hashes. This is the method defined
2135
+ * for SD-JWT VC, but for mDOCs it's much more generic. If you're using transaction data with mDOCs based
2136
+ * on hashes, you can extract the values from the DeviceResponse, otherwise you must verify the transaction data
2137
+ * manually.
2138
+ */
2118
2139
  verifyTransactionData(options) {
2119
2140
  return verifyTransactionData({
2120
2141
  ...options,