@bedrock/vc-delivery 4.1.2 → 4.3.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/lib/openId.js CHANGED
@@ -8,8 +8,10 @@ import {
8
8
  } from '@bedrock/validation';
9
9
  import {importJWK, SignJWT} from 'jose';
10
10
  import {
11
- openIdAuthorizationResponseBody, openIdBatchCredentialBody,
12
- openIdCredentialBody, openIdTokenBody,
11
+ openIdAuthorizationResponseBody,
12
+ openIdBatchCredentialBody,
13
+ openIdCredentialBody,
14
+ openIdTokenBody,
13
15
  presentationSubmission as presentationSubmissionSchema
14
16
  } from '../schemas/bedrock-vc-exchanger.js';
15
17
  import {verify, verifyDidProofJwt} from './verify.js';
@@ -63,7 +65,11 @@ export async function createRoutes({
63
65
  const routes = {
64
66
  // OID4VCI routes
65
67
  asMetadata: `/.well-known/oauth-authorization-server${exchangeRoute}`,
68
+ asMetadataDraftBug:
69
+ `${exchangeRoute}/.well-known/oauth-authorization-server`,
66
70
  ciMetadata: `/.well-known/openid-credential-issuer${exchangeRoute}`,
71
+ ciMetadataDraftBug:
72
+ `${exchangeRoute}/.well-known/openid-credential-issuer`,
67
73
  batchCredential: `${openIdRoute}/batch_credential`,
68
74
  credential: `${openIdRoute}/credential`,
69
75
  token: `${openIdRoute}/token`,
@@ -231,7 +237,7 @@ export async function createRoutes({
231
237
 
232
238
  {
233
239
  "format": "ldp_vc",
234
- "credential_description": {
240
+ "credential_definition": {
235
241
  "@context": [
236
242
  "https://www.w3.org/2018/credentials/v1",
237
243
  "https://www.w3.org/2018/credentials/examples/v1"
@@ -285,7 +291,7 @@ export async function createRoutes({
285
291
  {
286
292
  credential_requests: [{
287
293
  "format": "ldp_vc",
288
- "credential_description": {
294
+ "credential_definition": {
289
295
  "@context": [
290
296
  "https://www.w3.org/2018/credentials/v1",
291
297
  "https://www.w3.org/2018/credentials/examples/v1"
@@ -357,6 +363,57 @@ export async function createRoutes({
357
363
  {req, presentation, presentationSubmission});
358
364
  res.json(result);
359
365
  }));
366
+
367
+ /* Note: The following routes are served only because of an OID4VCI draft bug
368
+ that tells clients to generate `/.well-known` paths in an erroneous way and
369
+ some implementers have complied. */
370
+
371
+ // an authorization server meta data endpoint
372
+ // serves `.well-known` oauth2 AS config for each exchange; each config is
373
+ // based on the exchanger used to create the exchange
374
+ app.get(
375
+ routes.asMetadataDraftBug,
376
+ cors(),
377
+ getConfigMiddleware,
378
+ asyncHandler(async (req, res) => {
379
+ // generate well-known oauth2 issuer config
380
+ const {config: exchanger} = req.serviceObject;
381
+ const exchangeId = `${exchanger.id}/exchanges/${req.params.exchangeId}`;
382
+ // note that technically, we should not need to serve any credential
383
+ // issuer metadata, but we do for backwards compatibility purposes as
384
+ // previous versions of OID4VCI required it
385
+ const oauth2Config = {
386
+ issuer: exchangeId,
387
+ jwks_uri: `${exchangeId}/openid/jwks`,
388
+ token_endpoint: `${exchangeId}/openid/token`,
389
+ credential_endpoint: `${exchangeId}/openid/credential`,
390
+ batch_credential_endpoint: `${exchangeId}/openid/batch_credential`
391
+ // FIXME: add `credentials_supported`
392
+ };
393
+ res.json(oauth2Config);
394
+ }));
395
+
396
+ // a credential issuer meta data endpoint
397
+ // serves `.well-known` oauth2 AS / CI config for each exchange; each config
398
+ // is based on the exchanger used to create the exchange
399
+ app.get(
400
+ routes.ciMetadataDraftBug,
401
+ cors(),
402
+ getConfigMiddleware,
403
+ asyncHandler(async (req, res) => {
404
+ // generate well-known oauth2 issuer config
405
+ const {config: exchanger} = req.serviceObject;
406
+ const exchangeId = `${exchanger.id}/exchanges/${req.params.exchangeId}`;
407
+ const oauth2Config = {
408
+ issuer: exchangeId,
409
+ jwks_uri: `${exchangeId}/openid/jwks`,
410
+ token_endpoint: `${exchangeId}/openid/token`,
411
+ credential_endpoint: `${exchangeId}/openid/credential`,
412
+ batch_credential_endpoint: `${exchangeId}/openid/batch_credential`
413
+ // FIXME: add `credentials_supported`
414
+ };
415
+ res.json(oauth2Config);
416
+ }));
360
417
  }
361
418
 
362
419
  async function _createExchangeAccessToken({exchanger, exchangeRecord}) {
@@ -473,6 +530,11 @@ async function _processCredentialRequests({req, res, isBatchRequest}) {
473
530
  }
474
531
  credentialRequests = [req.body];
475
532
  }
533
+
534
+ // before asserting, normalize credential requests to use `type` instead of
535
+ // `types`; this is to allow for OID4VCI draft 20 implementers that followed
536
+ // the non-normative examples
537
+ _normalizeCredentialDefinitionTypes({credentialRequests});
476
538
  _assertCredentialRequests(
477
539
  {credentialRequests, expectedCredentialRequests});
478
540
 
@@ -777,3 +839,15 @@ function _validate(validator, data) {
777
839
  throw result.error;
778
840
  }
779
841
  }
842
+
843
+ function _normalizeCredentialDefinitionTypes({credentialRequests}) {
844
+ // normalize credential requests to use `type` instead of `types`
845
+ for(const cr of credentialRequests) {
846
+ if(cr?.credential_definition?.types) {
847
+ if(!cr?.credential_definition?.type) {
848
+ cr.credential_definition.type = cr.credential_definition.types;
849
+ }
850
+ delete cr.credential_definition.types;
851
+ }
852
+ }
853
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrock/vc-delivery",
3
- "version": "4.1.2",
3
+ "version": "4.3.0",
4
4
  "type": "module",
5
5
  "description": "Bedrock Verifiable Credential Delivery",
6
6
  "main": "./lib/index.js",
@@ -22,6 +22,14 @@ const credentialDefinition = {
22
22
  item: {
23
23
  type: 'string'
24
24
  }
25
+ },
26
+ // allow `types` to be flexible for OID4VCI draft 20 implementers
27
+ types: {
28
+ type: 'array',
29
+ minItems: 2,
30
+ item: {
31
+ type: 'string'
32
+ }
25
33
  }
26
34
  }
27
35
  };