@bedrock/vc-delivery 7.18.0 → 7.18.2

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/lib/issue.js CHANGED
@@ -197,6 +197,11 @@ function _getIssueZcap({
197
197
  }
198
198
 
199
199
  async function _issue({workflow, exchange, issueRequests, mediaType} = {}) {
200
+ if(issueRequests.length === 0) {
201
+ // no issue requests means nothing to issue or store
202
+ return {credentials: [], storedCredentials: [], exchangeChanged: false};
203
+ }
204
+
200
205
  // create zcap client for issuing VCs
201
206
  const {zcapClient, zcaps} = await getZcapClient({workflow});
202
207
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
2
+ * Copyright (c) 2022-2026 Digital Bazaar, Inc.
3
3
  */
4
4
  import * as bedrock from '@bedrock/core';
5
5
  import {
@@ -16,8 +16,6 @@ const VALIDATORS = {
16
16
  presentationSubmission: null
17
17
  };
18
18
 
19
- const VC_CONTEXT_2 = 'https://www.w3.org/ns/credentials/v2';
20
-
21
19
  bedrock.events.on('bedrock.init', () => {
22
20
  VALIDATORS.presentation = compile({schema: verifiablePresentationSchema()});
23
21
  VALIDATORS.presentationSubmission = compile({
@@ -33,11 +31,14 @@ export async function parse({
33
31
  const {
34
32
  responseMode, parsed, protectedHeader,
35
33
  recipientPublicJwk, recipientPublicJwkThumbprint,
36
- vpTokenMediaType
34
+ vpTokenMediaType,
35
+ envelope, presentation, mdocOptions
37
36
  } = await oid4vp.verifier.parseAuthorizationResponse({
38
37
  body,
39
- getDecryptParameters() {
40
- return _getDecryptParameters({exchange, clientProfileId});
38
+ getDecryptParameters({mdocOptions} = {}) {
39
+ return _getDecryptParameters({
40
+ exchange, clientProfileId, authorizationRequest, mdocOptions
41
+ });
41
42
  },
42
43
  authorizationRequest
43
44
  });
@@ -48,22 +49,8 @@ export async function parse({
48
49
  _validate(VALIDATORS.presentationSubmission, presentationSubmission);
49
50
  }
50
51
 
51
- // obtain `presentation` and optional `envelope` from parsed `vpToken`
52
- const {vpToken} = parsed;
53
- let presentation;
54
- let envelope;
55
-
56
- if(vpTokenMediaType !== 'application/vp') {
57
- // `vp_token` contains some enveloped format
58
- presentation = {
59
- '@context': VC_CONTEXT_2,
60
- id: `data:${vpTokenMediaType},${vpToken}`,
61
- type: 'EnvelopedVerifiablePresentation'
62
- };
63
- envelope = {mediaType: vpTokenMediaType};
64
- } else {
65
- // simplest case: `vpToken` is a VP; validate it against basic schema
66
- presentation = vpToken;
52
+ // validate `presentation` against basic schema
53
+ if(vpTokenMediaType === 'application/vp') {
67
54
  _validate(VALIDATORS.presentation, presentation);
68
55
  }
69
56
 
@@ -74,7 +61,8 @@ export async function parse({
74
61
  envelope,
75
62
  protectedHeader,
76
63
  recipientPublicJwk,
77
- recipientPublicJwkThumbprint
64
+ recipientPublicJwkThumbprint,
65
+ mdocOptions
78
66
  };
79
67
  } catch(cause) {
80
68
  throw new BedrockError(
@@ -89,12 +77,28 @@ export async function parse({
89
77
  }
90
78
  }
91
79
 
92
- function _getDecryptParameters({exchange, clientProfileId}) {
80
+ function _getDecryptParameters({
81
+ exchange, clientProfileId, authorizationRequest, mdocOptions
82
+ }) {
93
83
  // get private key agreement keys in JWT format
94
84
  const {keyAgreementKeyPairs} = exchange.secrets?.oid4vp?.clientProfiles
95
85
  ?.[clientProfileId ?? 'default'] ?? {};
96
86
  const keys = keyAgreementKeyPairs.map(({privateKeyJwk}) => privateKeyJwk);
97
- return {keys};
87
+
88
+ // include decryption AAD info if `response_mode` calls for it
89
+ let getInfo;
90
+ if(authorizationRequest.response_mode === 'dc_api') {
91
+ // include `recipientPublicJwk` in expected mdoc handover
92
+ getInfo = ({recipientPublicJwk}) => {
93
+ const handover = {
94
+ ...mdocOptions?.expectedHandover,
95
+ recipientPublicJwk
96
+ };
97
+ return oid4vp.mdl.encodeSessionTranscript({handover});
98
+ };
99
+ }
100
+
101
+ return {keys, getInfo};
98
102
  }
99
103
 
100
104
  function _validate(validator, data) {
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
2
+ * Copyright (c) 2022-2026 Digital Bazaar, Inc.
3
3
  */
4
4
  import * as bedrock from '@bedrock/core';
5
5
  import {
@@ -199,52 +199,9 @@ export async function processAuthorizationResponse({req, clientProfileId}) {
199
199
  expectedDomain = verifyPresentationOptions.domain;
200
200
 
201
201
  const {envelope} = parseResponseResult;
202
- if(envelope?.mediaType === 'application/mdoc-vp-token' ||
203
- // deprecated
204
- envelope?.mediaType === 'application/mdl-vp-token') {
205
- // generate `handover` for mdoc verification
206
- let handover;
207
-
208
- // common `handover` parameters:
209
- const origin = authorizationRequest?.expected_origins?.[0] ??
210
- new URL(authorizationRequest.response_uri).origin;
211
- const nonce = authorizationRequest.nonce;
212
-
213
- // `direct_post.jwt` => ISO18013-7 Annex B
214
- // FIXME: same response mode is also used for OID4VP 1.0 with
215
- // `OpenID4VPHandover` for non-Annex-B; this is not yet supported
216
- // https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-invocation-via-redirects
217
- const {responseMode} = parseResponseResult;
218
- if(responseMode === 'direct_post.jwt') {
219
- handover = {
220
- type: 'AnnexBHandover',
221
- // per ISO 18013-7 B the `mdocGeneratedNonce` is base64url-encoded
222
- // and put into the `apu` protected header parameter, so parse that
223
- // here and convert it to a UTF-8 string instead
224
- mdocGeneratedNonce: Buffer
225
- .from(parseResponseResult.protectedHeader?.apu ?? '', 'base64url')
226
- .toString('utf8'),
227
- clientId: authorizationRequest.client_id,
228
- responseUri: authorizationRequest.response_uri,
229
- verifierGeneratedNonce: nonce
230
- };
231
- } else if(responseMode === 'dc_api') {
232
- // `dc_api` => ISO18013-7 Annex C
233
- handover = {
234
- type: 'dcapi',
235
- origin,
236
- nonce,
237
- recipientPublicJwk: parseResponseResult.recipientPublicJwk
238
- };
239
- } else if(responseMode === 'dc_api.jwt') {
240
- // `dc_api.jwt` => ISO18013-7 Annex D
241
- handover = {
242
- type: 'OpenID4VPDCAPIHandover',
243
- origin,
244
- nonce,
245
- jwkThumbprint: parseResponseResult.recipientPublicJwkThumbprint
246
- };
247
- }
202
+ if(parseResponseResult?.mdocOptions) {
203
+ // get expected `handover` for mdoc verification
204
+ const {expectedHandover: handover} = parseResponseResult.mdocOptions;
248
205
 
249
206
  // handle deprecated `mdl` option; `mdoc` is preferred
250
207
  const mdocKey = envelope.mediaType === 'application/mdoc-vp-token' ?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrock/vc-delivery",
3
- "version": "7.18.0",
3
+ "version": "7.18.2",
4
4
  "type": "module",
5
5
  "description": "Bedrock Verifiable Credential Delivery",
6
6
  "main": "./lib/index.js",
@@ -40,7 +40,7 @@
40
40
  "@digitalbazaar/ed25519-signature-2020": "^5.4.0",
41
41
  "@digitalbazaar/ezcap": "^4.1.0",
42
42
  "@digitalbazaar/http-client": "^4.4.0",
43
- "@digitalbazaar/oid4-client": "^5.14.0",
43
+ "@digitalbazaar/oid4-client": "^5.15.0",
44
44
  "@digitalbazaar/vc": "^7.2.0",
45
45
  "@digitalbazaar/webkms-client": "^14.2.0",
46
46
  "assert-plus": "^1.0.0",
@@ -547,6 +547,8 @@ const oid4vpClientProfile = {
547
547
  required: ['x5c'],
548
548
  additionalProperties: false,
549
549
  properties: {
550
+ // FIXME: consider adding `privateKeyJwk` as an alternative to using
551
+ // a zcap for a WebKMS key
550
552
  x5c: {
551
553
  type: 'array',
552
554
  minItems: 1,
@@ -999,6 +1001,13 @@ export function openIdAuthorizationResponseBody() {
999
1001
  not: {
1000
1002
  required: ['presentation_submission', 'vp_token', 'state']
1001
1003
  }
1004
+ }, {
1005
+ // for response_mode == 'dc_api'
1006
+ required: ['Response'],
1007
+ // cannot also use any other params
1008
+ not: {
1009
+ required: ['presentation_submission', 'vp_token', 'state']
1010
+ }
1002
1011
  }],
1003
1012
  properties: {
1004
1013
  // is a JSON string in the x-www-form-urlencoded body
@@ -1027,6 +1036,10 @@ export function openIdAuthorizationResponseBody() {
1027
1036
  // must be an encrypted JWT
1028
1037
  type: 'string'
1029
1038
  },
1039
+ Response: {
1040
+ // must be an HPKE encrypted mdoc device response (ISO 18013-7 Annex C)
1041
+ type: 'string'
1042
+ },
1030
1043
  state: {
1031
1044
  type: 'string'
1032
1045
  }