@digitalbazaar/oid4-client 5.3.0 → 5.4.1

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.
@@ -73,14 +73,26 @@ export function fromVpr({
73
73
  if(verifiablePresentationRequest.challenge) {
74
74
  authorizationRequest.nonce = verifiablePresentationRequest.challenge;
75
75
  }
76
- // only a single `DIDAuthentication` query is supported at this time; use
77
- // the last one
76
+ // any DID authentication queries must be merged to a single set of
77
+ // supported values for compatibility purposes
78
78
  const didAuthnQuery = [...groupMap.values()]
79
79
  .filter(g => g.has(DID_AUTHENTICATION))
80
80
  .map(g => g.get(DID_AUTHENTICATION))
81
- .at(-1);
82
- if(didAuthnQuery) {
83
- const [query] = didAuthnQuery;
81
+ .flat();
82
+ if(didAuthnQuery.length > 0) {
83
+ // merge the accepted envelopes and cryptosuites across DID authn queries
84
+ const cryptosuites = new Set();
85
+ const envelopes = new Set();
86
+ for(const query of didAuthnQuery) {
87
+ query.acceptedCryptosuites?.forEach(
88
+ ({cryptosuite}) => cryptosuites.add(cryptosuite));
89
+ query.acceptedEnvelopes?.forEach(envelope => envelopes.add(envelope));
90
+ }
91
+ // convert last DID authn query w/merged cryptosuites and envelopes
92
+ const query = structuredClone(didAuthnQuery.at(-1));
93
+ query.acceptedCryptosuites = [...cryptosuites].map(
94
+ cryptosuite => ({cryptosuite}));
95
+ query.acceptedEnvelopes = [...envelopes];
84
96
  const client_metadata = _fromDIDAuthenticationQuery({query, strict});
85
97
  if(client_metadata) {
86
98
  authorizationRequest.client_metadata = client_metadata;
@@ -258,37 +270,71 @@ function _strictCheckVprGroups({groupMap, queryFormats}) {
258
270
  }
259
271
 
260
272
  function _fromDIDAuthenticationQuery({query, strict = false}) {
273
+ const vp_formats = {};
274
+ const vp_formats_supported = {};
275
+ const client_metadata = {
276
+ require_signed_request_object: false,
277
+ vp_formats,
278
+ vp_formats_supported
279
+ };
280
+
261
281
  const cryptosuites = query.acceptedCryptosuites?.map(
262
282
  ({cryptosuite}) => cryptosuite);
263
- if(!(cryptosuites?.length > 0)) {
283
+ if(cryptosuites?.length > 0) {
284
+ // legacy (before OID4VP 1.0)
285
+ client_metadata.vp_formats.ldp_vp = {
286
+ proof_type: cryptosuites
287
+ };
288
+ // OID4VP 1.0+
289
+ vp_formats_supported.ldp_vc = {
290
+ proof_type_values: ['DataIntegrityProof'],
291
+ cryptosuite_values: cryptosuites
292
+ };
293
+ // compatibility with legacy cryptosuite
294
+ if(cryptosuites.includes('Ed25519Signature2020')) {
295
+ vp_formats_supported.ldp_vc
296
+ .proof_type_values.push('Ed25519Signature2020');
297
+ }
298
+ }
299
+
300
+ if(query.acceptedEnvelopes?.length > 0) {
301
+ for(const envelope of query.acceptedEnvelopes) {
302
+ if(envelope === 'application/jwt') {
303
+ // legacy (before OID4VP 1.0)
304
+ vp_formats.jwt_vp = vp_formats.jwt_vp_json = {
305
+ alg: ['EdDSA', 'Ed25519', 'ES256', 'ES384']
306
+ };
307
+ // OID4VP 1.0+
308
+ vp_formats_supported.jwt_vc_json = {};
309
+ } else if(envelope === 'application/mdl' ||
310
+ envelope === 'application/mdoc') {
311
+ // legacy (before OID4VP 1.0)
312
+ vp_formats.mso_mdoc = {
313
+ alg: ['EdDSA', 'ES256']
314
+ };
315
+ // OID4VP 1.0+
316
+ vp_formats_supported.mso_mdoc = {};
317
+ } else if(envelope === 'application/dc+sd-jwt') {
318
+ // legacy (before OID4VP 1.0)
319
+ vp_formats['dc+sd-jwt'] = {};
320
+ // OID4VP 1.0+
321
+ vp_formats_supported['dc+sd-jwt'] = {};
322
+ }
323
+ // ignore unknown envelope format
324
+ }
325
+ }
326
+
327
+ if(Object.keys(vp_formats_supported) === 0) {
264
328
  if(strict) {
265
329
  const error = new Error(
266
- '"query.acceptedCryptosuites" must be a non-array with specified ' +
267
- `cryptosuites to convert from a "${DID_AUTHENTICATION}" query.`);
330
+ '"query.acceptedCryptosuites" or "query.acceptedEnvelopes" must be a ' +
331
+ 'non-array with specified cryptosuites (or envelopes, respectively) ' +
332
+ `to convert from a "${DID_AUTHENTICATION}" query.`);
268
333
  error.name = 'NotSupportedError';
269
334
  throw error;
270
335
  }
271
336
  return;
272
337
  }
273
- const client_metadata = {
274
- require_signed_request_object: false,
275
- vp_formats: {
276
- ldp_vp: {
277
- proof_type: cryptosuites
278
- }
279
- },
280
- vp_formats_supported: {
281
- ldp_vc: {
282
- proof_type_values: ['DataIntegrityProof']
283
- },
284
- cryptosuite_values: cryptosuites
285
- }
286
- };
287
- // compatibility with legacy cryptosuite
288
- if(cryptosuites.includes('Ed25519Signature2020')) {
289
- client_metadata.vp_formats_supported.ldp_vc
290
- .proof_type_values.push('Ed25519Signature2020');
291
- }
292
338
 
293
339
  return client_metadata;
294
340
  }
@@ -297,9 +343,20 @@ function _toDIDAuthenticationQuery({client_metadata, strict = false}) {
297
343
  const {vp_formats_supported, vp_formats} = client_metadata;
298
344
  const proofTypes = vp_formats_supported?.ldp_vc?.cryptosuite_values ??
299
345
  vp_formats?.ldp_vp?.proof_type;
300
- if(!Array.isArray(proofTypes)) {
346
+ const envelopes = [];
347
+ if(vp_formats_supported?.jwt_vc_json || vp_formats_supported?.jwt_vp_json) {
348
+ envelopes.push('application/jwt');
349
+ }
350
+ if(vp_formats_supported?.mso_mdoc) {
351
+ envelopes.push('application/mdoc');
352
+ }
353
+ if(vp_formats_supported?.['dc+sd-jwt']) {
354
+ envelopes.push('application/dc+sd-jwt');
355
+ }
356
+ if(!(Array.isArray(proofTypes) || envelopes.length > 0)) {
301
357
  if(strict) {
302
358
  const error = new Error(
359
+ '"client_metadata.vp_formats_supported.ldp_vc.cryptosuite_values" or ' +
303
360
  '"client_metadata.vp_formats.ldp_vp.proof_type" must be an array to ' +
304
361
  `convert to "${DID_AUTHENTICATION}" query.`);
305
362
  error.name = 'NotSupportedError';
@@ -307,10 +364,14 @@ function _toDIDAuthenticationQuery({client_metadata, strict = false}) {
307
364
  }
308
365
  return;
309
366
  }
310
- return {
311
- type: DID_AUTHENTICATION,
312
- acceptedCryptosuites: proofTypes.map(cryptosuite => ({cryptosuite}))
313
- };
367
+ const query = {type: DID_AUTHENTICATION};
368
+ if(proofTypes) {
369
+ query.acceptedCryptosuites = proofTypes.map(cryptosuite => ({cryptosuite}));
370
+ }
371
+ if(envelopes.length > 0) {
372
+ query.acceptedEnvelopes = envelopes;
373
+ }
374
+ return query;
314
375
  }
315
376
 
316
377
  function _vprGroupsToQuery({groupMap}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalbazaar/oid4-client",
3
- "version": "5.3.0",
3
+ "version": "5.4.1",
4
4
  "description": "An OID4 (VC + VP) client",
5
5
  "homepage": "https://github.com/digitalbazaar/oid4-client",
6
6
  "author": {