@bedrock/vc-delivery 7.13.1 → 7.13.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/ExchangeProcessor.js +45 -34
- package/lib/oid4/oid4vci.js +22 -3
- package/lib/oid4/oid4vp.js +1 -1
- package/package.json +1 -1
package/lib/ExchangeProcessor.js
CHANGED
|
@@ -31,20 +31,22 @@ export class ExchangeProcessor {
|
|
|
31
31
|
* @param {object} options.workflow - The workflow.
|
|
32
32
|
* @param {object} options.exchangeRecord - The exchange record.
|
|
33
33
|
* @param {Function} [options.prepareStep] - The `prepareStep` handler.
|
|
34
|
-
* @param {Function} [options.
|
|
34
|
+
* @param {Function} [options.isStepComplete] - The `isStepComplete` handler.
|
|
35
35
|
* @param {Function} [options.issue] - The `issue` handler.
|
|
36
|
+
* @param {Function} [options.inputRequired] - The `inputRequired` handler.
|
|
36
37
|
* @param {Function} [options.verify] - The `verify` handler.
|
|
37
38
|
*
|
|
38
39
|
* @returns {ExchangeProcessor} An `ExchangeProcessor` instance.
|
|
39
40
|
*/
|
|
40
41
|
constructor({
|
|
41
|
-
workflow, exchangeRecord, prepareStep, inputRequired,
|
|
42
|
+
workflow, exchangeRecord, prepareStep, inputRequired, isStepComplete,
|
|
42
43
|
issue, verify
|
|
43
44
|
} = {}) {
|
|
44
45
|
this.workflow = workflow;
|
|
45
46
|
this.exchangeRecord = exchangeRecord;
|
|
46
47
|
this.prepareStep = prepareStep?.bind(this);
|
|
47
48
|
this.inputRequired = inputRequired?.bind(this);
|
|
49
|
+
this.isStepComplete = isStepComplete?.bind(this);
|
|
48
50
|
this.issue = issue ?? defaultIssue.bind(this);
|
|
49
51
|
this.verify = verify ?? defaultVerify.bind(this);
|
|
50
52
|
}
|
|
@@ -229,7 +231,9 @@ export class ExchangeProcessor {
|
|
|
229
231
|
async _tryProcess({
|
|
230
232
|
receivedPresentation, receivedPresentationRequest, retryState
|
|
231
233
|
} = {}) {
|
|
232
|
-
const {
|
|
234
|
+
const {
|
|
235
|
+
workflow, exchangeRecord, prepareStep, inputRequired, isStepComplete
|
|
236
|
+
} = this;
|
|
233
237
|
const {exchange, meta} = exchangeRecord;
|
|
234
238
|
|
|
235
239
|
// initialize exchange results
|
|
@@ -423,38 +427,52 @@ export class ExchangeProcessor {
|
|
|
423
427
|
// FIXME: implement
|
|
424
428
|
//if(response?.verifiablePresentation) {}
|
|
425
429
|
|
|
426
|
-
// 4.12.
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
430
|
+
// 4.12. Call subalgorithm `isStepComplete`, passing `workflow`,
|
|
431
|
+
// `exchange`, `step`, `receivedPresentation`, and
|
|
432
|
+
// `receivedPresentationRequest` to perform any protocol-specific
|
|
433
|
+
// behavior to determine if the step is complete. Set `stepComplete`
|
|
434
|
+
// to the result of `isStepComplete`, defaulting to `true`.
|
|
435
|
+
const stepComplete = await isStepComplete?.({
|
|
436
|
+
workflow, exchange, step,
|
|
437
|
+
receivedPresentation, receivedPresentationRequest
|
|
438
|
+
}) ?? true;
|
|
439
|
+
|
|
440
|
+
// 4.13. If `stepComplete` is `true`:
|
|
441
|
+
if(stepComplete) {
|
|
442
|
+
// 4.13.1. If `step.redirectUrl` is set:
|
|
443
|
+
if(step.redirectUrl) {
|
|
444
|
+
// 4.13.1.1. If `response` is `null` then set it to an empty object.
|
|
445
|
+
if(!response) {
|
|
446
|
+
response = {};
|
|
447
|
+
}
|
|
448
|
+
// 4.13.1.2. Set `response.redirectUrl` to `step.redirectUrl`.
|
|
449
|
+
response.redirectUrl = step.redirectUrl;
|
|
431
450
|
}
|
|
432
|
-
// 4.12.2. Set `response.redirectUrl` to `step.redirectUrl`.
|
|
433
|
-
response.redirectUrl = step.redirectUrl;
|
|
434
|
-
}
|
|
435
451
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
452
|
+
// 4.13.2. If `step.nextStep` is not set then set `exchange.state` to
|
|
453
|
+
// `complete`.
|
|
454
|
+
if(!step.nextStep) {
|
|
455
|
+
exchange.state = 'complete';
|
|
456
|
+
} else {
|
|
457
|
+
// 4.13.3. Otherwise, delete
|
|
458
|
+
// `exchange.variables.results[step.nextStep]` if it exists, and
|
|
459
|
+
// set `exchange.step` to `step.nextStep`.
|
|
460
|
+
delete exchange.variables.results[step.nextStep];
|
|
461
|
+
exchange.step = step.nextStep;
|
|
462
|
+
}
|
|
445
463
|
}
|
|
446
464
|
|
|
447
|
-
// 4.
|
|
465
|
+
// 4.14. Save the exchange (and call any non-blocking callback in
|
|
448
466
|
// the step).
|
|
449
467
|
await _updateExchange({workflow, exchange, meta, step});
|
|
450
468
|
|
|
451
|
-
// 4.
|
|
469
|
+
// 4.15. If `exchange.state` is `complete`, return `response` if it is
|
|
452
470
|
// not `null`, otherwise return an empty object.
|
|
453
471
|
if(exchange.state === 'complete') {
|
|
454
472
|
return response ?? {};
|
|
455
473
|
}
|
|
456
474
|
|
|
457
|
-
// 4.
|
|
475
|
+
// 4.16. Set `receivedPresentation` to `null`.
|
|
458
476
|
receivedPresentation = null;
|
|
459
477
|
}
|
|
460
478
|
} catch(e) {
|
|
@@ -489,14 +507,6 @@ async function _getStep({workflow, exchange}) {
|
|
|
489
507
|
workflow, exchange, stepName: currentStep
|
|
490
508
|
});
|
|
491
509
|
|
|
492
|
-
// if next step is the same as the current step, throw an error
|
|
493
|
-
if(step.nextStep === currentStep) {
|
|
494
|
-
throw new BedrockError('Cyclical step detected.', {
|
|
495
|
-
name: 'DataError',
|
|
496
|
-
details: {httpStatusCode: 500, public: true}
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
|
|
500
510
|
// if `step.nextStep` and `step.redirectUrl` and are both set, throw an error
|
|
501
511
|
if(step.nextStep && step.redirectUrl) {
|
|
502
512
|
throw new BedrockError(
|
|
@@ -547,10 +557,11 @@ async function _createVerifiablePresentationRequest({
|
|
|
547
557
|
}
|
|
548
558
|
response.verifiablePresentationRequest.challenge = challenge;
|
|
549
559
|
|
|
550
|
-
// 4. Set `exchange.variables.results[exchange.step]` to an object
|
|
551
|
-
// property `responsePresentationRequest`
|
|
552
|
-
// `response.verifiablePresentationRequest`.
|
|
560
|
+
// 4. Set `exchange.variables.results[exchange.step]` to an object, if it
|
|
561
|
+
// does not already exist, and set the property `responsePresentationRequest`
|
|
562
|
+
// to `response.verifiablePresentationRequest`.
|
|
553
563
|
exchange.variables.results[exchange.step] = {
|
|
564
|
+
...exchange.variables.results[exchange.step],
|
|
554
565
|
responsePresentationRequest: response.verifiablePresentationRequest
|
|
555
566
|
};
|
|
556
567
|
}
|
package/lib/oid4/oid4vci.js
CHANGED
|
@@ -430,6 +430,9 @@ async function _processExchange({
|
|
|
430
430
|
const exchangeProcessor = new ExchangeProcessor({
|
|
431
431
|
workflow, exchangeRecord,
|
|
432
432
|
async prepareStep({exchange, step}) {
|
|
433
|
+
// FIXME: handle OID4VCI 1.0+ credential request
|
|
434
|
+
|
|
435
|
+
// FIXME: OID4VCI Draft 13:
|
|
433
436
|
// validate body against expected credential requests
|
|
434
437
|
const {openId: {expectedCredentialRequests}} = exchange;
|
|
435
438
|
let credentialRequests;
|
|
@@ -437,7 +440,7 @@ async function _processExchange({
|
|
|
437
440
|
({credential_requests: credentialRequests} = req.body);
|
|
438
441
|
} else {
|
|
439
442
|
if(expectedCredentialRequests.length > 1) {
|
|
440
|
-
// FIXME: batch endpoint has been removed in OID4VCI 1.0
|
|
443
|
+
// FIXME: batch endpoint has been removed in OID4VCI 1.0+; if used,
|
|
441
444
|
// then it is for a legacy OID4VCI draft 13 request, so this should
|
|
442
445
|
// be reworked
|
|
443
446
|
throw new Error('batch_credential_endpoint must be used');
|
|
@@ -457,9 +460,15 @@ async function _processExchange({
|
|
|
457
460
|
|
|
458
461
|
// check to see if step supports OID4VP during OID4VCI
|
|
459
462
|
if(step.openId) {
|
|
460
|
-
//
|
|
463
|
+
// FIXME: either OID4VCI 1.1+ w/IAE (interactive authz endpoint) or
|
|
464
|
+
// OID4VCI-1.0/draft13+OID4VP will have received VP results which will
|
|
465
|
+
// be stored with this step; OID4VCI 1.0- does not have IAE so if this
|
|
466
|
+
// call is made, presume such a client and return an error with the
|
|
467
|
+
// OID4VP request, OID4VCI 1.1+ clients will know to use IAE instead
|
|
468
|
+
|
|
469
|
+
// if there is no verified presentation yet, request one
|
|
461
470
|
const {results} = exchange.variables;
|
|
462
|
-
if(!results[exchange.step]?.
|
|
471
|
+
if(!results[exchange.step]?.verifyPresentationResults?.verified) {
|
|
463
472
|
// note: only the "default" `clientProfileId` is supported at this
|
|
464
473
|
// time because there isn't presently a defined way to specify
|
|
465
474
|
// alternatives
|
|
@@ -520,6 +529,16 @@ async function _processExchange({
|
|
|
520
529
|
workflow, exchange, step, issueRequestsParams,
|
|
521
530
|
verifiablePresentation, format
|
|
522
531
|
});
|
|
532
|
+
},
|
|
533
|
+
isStepComplete({exchange}) {
|
|
534
|
+
// FIXME: check step's current `openId` results to see which issue
|
|
535
|
+
// requests have been processed; if any still exist, then the step is not
|
|
536
|
+
// yet complete
|
|
537
|
+
const {results} = exchange.variables;
|
|
538
|
+
if(!results[exchange.step]?.openId) {
|
|
539
|
+
// FIXME: implement
|
|
540
|
+
}
|
|
541
|
+
return true;
|
|
523
542
|
}
|
|
524
543
|
});
|
|
525
544
|
const response = await exchangeProcessor.process();
|
package/lib/oid4/oid4vp.js
CHANGED
|
@@ -175,7 +175,7 @@ export async function processAuthorizationResponse({req, clientProfileId}) {
|
|
|
175
175
|
},
|
|
176
176
|
inputRequired({step}) {
|
|
177
177
|
// indicate input always required to avoid automatically advancing
|
|
178
|
-
// to
|
|
178
|
+
// to issuance, but clear `step.verifiablePresentationRequest`
|
|
179
179
|
// to avoid overwriting previous value
|
|
180
180
|
delete step.verifiablePresentationRequest;
|
|
181
181
|
return true;
|