@bedrock/vc-delivery 7.9.0 → 7.10.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/index.js +5 -4
- package/lib/inviteRequest/http.js +1 -1
- package/lib/issue.js +82 -71
- package/lib/oid4/authorizationResponse.js +2 -2
- package/lib/oid4/http.js +4 -4
- package/lib/vcapi.js +4 -10
- package/package.json +1 -1
- package/schemas/bedrock-vc-workflow.js +295 -259
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import * as bedrock from '@bedrock/core';
|
|
5
5
|
import * as workflowSchemas from '../schemas/bedrock-vc-workflow.js';
|
|
@@ -33,9 +33,10 @@ async function _initService({serviceType, routePrefix}) {
|
|
|
33
33
|
const createConfigBody = structuredClone(schemas.createConfigBody);
|
|
34
34
|
const updateConfigBody = structuredClone(schemas.updateConfigBody);
|
|
35
35
|
const schemasToUpdate = [createConfigBody, updateConfigBody];
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
const credentialTemplates = workflowSchemas.credentialTemplates();
|
|
37
|
+
const steps = workflowSchemas.steps();
|
|
38
|
+
const initialStep = workflowSchemas.initialStep();
|
|
39
|
+
const issuerInstances = workflowSchemas.issuerInstances();
|
|
39
40
|
for(const schema of schemasToUpdate) {
|
|
40
41
|
// add config requirements to workflow configs
|
|
41
42
|
schema.properties.credentialTemplates = credentialTemplates;
|
package/lib/issue.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import * as bedrock from '@bedrock/core';
|
|
5
5
|
import {
|
|
@@ -15,92 +15,103 @@ const {util: {BedrockError}} = bedrock;
|
|
|
15
15
|
export async function issue({
|
|
16
16
|
workflow, exchange, step, format = 'application/vc'
|
|
17
17
|
} = {}) {
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if
|
|
22
|
-
|
|
18
|
+
// eval all issue requests for current step in exchange
|
|
19
|
+
const issueRequests = await _evalIssueRequests({workflow, exchange, step});
|
|
20
|
+
|
|
21
|
+
// return early if there is no explicit VP in step nor nothing to issue
|
|
22
|
+
if(!step?.verifiablePresentation && issueRequests.length === 0) {
|
|
23
23
|
return {response: {}};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
//
|
|
27
|
-
const
|
|
28
|
-
workflow, exchange, step, credentialTemplates
|
|
29
|
-
});
|
|
30
|
-
// issue all VCs
|
|
31
|
-
const vcs = await _issue({workflow, issueRequests, format});
|
|
26
|
+
// run all issue requests
|
|
27
|
+
const issuedVcs = await _issue({workflow, issueRequests, format});
|
|
32
28
|
|
|
33
|
-
// generate VP to return VCs
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
// generate VP to return VCs; use any explicitly defined VP from the step
|
|
30
|
+
// (which may include out-of-band issued VCs that are to be delivered)
|
|
31
|
+
const verifiablePresentation =
|
|
32
|
+
structuredClone(step?.verifiablePresentation) ?? createPresentation();
|
|
36
33
|
|
|
37
|
-
// add
|
|
38
|
-
if(
|
|
34
|
+
// add issued VCs to VP
|
|
35
|
+
if(issuedVcs.length > 0) {
|
|
36
|
+
let vcs = verifiablePresentation.verifiableCredential;
|
|
37
|
+
if(!vcs) {
|
|
38
|
+
vcs = issuedVcs;
|
|
39
|
+
} else if(Array.isArray(vcs)) {
|
|
40
|
+
vcs = [...vcs, ...issuedVcs];
|
|
41
|
+
} else {
|
|
42
|
+
vcs = [vcs, ...issuedVcs];
|
|
43
|
+
}
|
|
39
44
|
verifiablePresentation.verifiableCredential = vcs;
|
|
40
45
|
}
|
|
41
46
|
return {response: {verifiablePresentation}, format};
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
async function
|
|
45
|
-
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
49
|
+
async function _evalIssueRequests({workflow, exchange, step}) {
|
|
50
|
+
// evaluate all issue requests in parallel
|
|
51
|
+
const requests = await _getIssueRequests({workflow, exchange, step});
|
|
52
|
+
return Promise.all(requests.map(({typedTemplate, variables}) =>
|
|
53
|
+
evaluateTemplate({workflow, exchange, typedTemplate, variables})));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function _getIssueRequests({workflow, exchange, step}) {
|
|
57
|
+
// use any templates from workflow and variables from exchange to produce
|
|
58
|
+
// credentials to be issued; issue via the configured issuer instance
|
|
59
|
+
const {credentialTemplates = []} = workflow;
|
|
60
|
+
if(!(credentialTemplates.length > 0)) {
|
|
61
|
+
// no issue requests
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if(!step ||
|
|
66
|
+
(!step.issueRequests && Object.keys(workflow.steps).length === 1)) {
|
|
67
|
+
// backwards-compatibility: deprecated workflows with no step or a single
|
|
68
|
+
// step do not explicitly define `issueRequests` but instead use all
|
|
69
|
+
// templates for issue requests
|
|
70
|
+
return credentialTemplates.map(typedTemplate => ({typedTemplate}));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// resolve all issue request params in parallel
|
|
74
|
+
const variables = getTemplateVariables({workflow, exchange});
|
|
75
|
+
return Promise.all(step.issueRequests.map(async r => {
|
|
76
|
+
// find the typed template to use
|
|
77
|
+
let typedTemplate;
|
|
78
|
+
if(r.credentialTemplateIndex !== undefined) {
|
|
79
|
+
typedTemplate = credentialTemplates[r.credentialTemplateIndex];
|
|
80
|
+
} else if(r.credentialTemplateId !== undefined) {
|
|
81
|
+
typedTemplate = credentialTemplates.find(
|
|
82
|
+
t => t.id === r.credentialTemplateId);
|
|
83
|
+
}
|
|
84
|
+
if(typedTemplate === undefined) {
|
|
85
|
+
throw new BedrockError(
|
|
86
|
+
'Credential template ' +
|
|
87
|
+
`"${r.credentialTemplateIndex ?? r.credentialTemplateId}" not found.`, {
|
|
88
|
+
name: 'DataError',
|
|
89
|
+
details: {httpStatusCode: 500, public: true}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// allow different variables to be specified for the typed template
|
|
94
|
+
let vars = variables;
|
|
95
|
+
if(r.variables !== undefined) {
|
|
96
|
+
vars = typeof r.variables === 'string' ?
|
|
97
|
+
variables[r.variables] : r.variables;
|
|
98
|
+
if(!(vars && typeof vars === 'object')) {
|
|
65
99
|
throw new BedrockError(
|
|
66
|
-
|
|
67
|
-
`"${r.credentialTemplateIndex ?? r.credentialTemplateId}" ` +
|
|
68
|
-
'not found.', {
|
|
100
|
+
`Issue request variables "${r.variables}" not found or invalid.`, {
|
|
69
101
|
name: 'DataError',
|
|
70
102
|
details: {httpStatusCode: 500, public: true}
|
|
71
103
|
});
|
|
72
104
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
vars = r.variables;
|
|
81
|
-
}
|
|
82
|
-
if(!(vars && typeof vars === 'object')) {
|
|
83
|
-
throw new BedrockError(
|
|
84
|
-
`Issue request variables "${r.variables}" not found or invalid.`, {
|
|
85
|
-
name: 'DataError',
|
|
86
|
-
details: {httpStatusCode: 500, public: true}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
typedTemplate,
|
|
108
|
+
variables: {
|
|
109
|
+
// always include globals but allow local override
|
|
110
|
+
globals: variables.globals,
|
|
111
|
+
...vars
|
|
89
112
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
variables: {
|
|
93
|
-
// always include globals but allow local override
|
|
94
|
-
globals: variables.globals,
|
|
95
|
-
...vars
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// evaluate all issue requests
|
|
102
|
-
return Promise.all(params.map(({typedTemplate, variables}) =>
|
|
103
|
-
evaluateTemplate({workflow, exchange, typedTemplate, variables})));
|
|
113
|
+
};
|
|
114
|
+
}));
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
function _getIssueZcap({workflow, zcaps, format}) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import * as bedrock from '@bedrock/core';
|
|
5
5
|
import {
|
|
@@ -23,7 +23,7 @@ bedrock.events.on('bedrock.init', () => {
|
|
|
23
23
|
// create validators for x-www-form-urlencoded parsed data
|
|
24
24
|
VALIDATORS.presentation = compile({schema: verifiablePresentationSchema()});
|
|
25
25
|
VALIDATORS.presentationSubmission = compile({
|
|
26
|
-
schema: presentationSubmissionSchema
|
|
26
|
+
schema: presentationSubmissionSchema()
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
|
package/lib/oid4/http.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import * as oid4vci from './oid4vci.js';
|
|
5
5
|
import * as oid4vp from './oid4vp.js';
|
|
@@ -158,7 +158,7 @@ export async function createRoutes({
|
|
|
158
158
|
routes.token,
|
|
159
159
|
cors(),
|
|
160
160
|
urlencodedSmall,
|
|
161
|
-
validate({bodySchema: openIdTokenBody}),
|
|
161
|
+
validate({bodySchema: openIdTokenBody()}),
|
|
162
162
|
getConfigMiddleware,
|
|
163
163
|
getExchange,
|
|
164
164
|
asyncHandler(async (req, res) => {
|
|
@@ -177,7 +177,7 @@ export async function createRoutes({
|
|
|
177
177
|
app.post(
|
|
178
178
|
routes.credential,
|
|
179
179
|
cors(),
|
|
180
|
-
validate({bodySchema: openIdCredentialBody}),
|
|
180
|
+
validate({bodySchema: openIdCredentialBody()}),
|
|
181
181
|
getConfigMiddleware,
|
|
182
182
|
getExchange,
|
|
183
183
|
asyncHandler(async (req, res) => {
|
|
@@ -273,7 +273,7 @@ export async function createRoutes({
|
|
|
273
273
|
app.post(
|
|
274
274
|
routes.batchCredential,
|
|
275
275
|
cors(),
|
|
276
|
-
validate({bodySchema: openIdBatchCredentialBody}),
|
|
276
|
+
validate({bodySchema: openIdBatchCredentialBody()}),
|
|
277
277
|
getConfigMiddleware,
|
|
278
278
|
getExchange,
|
|
279
279
|
asyncHandler(async (req, res) => {
|
package/lib/vcapi.js
CHANGED
|
@@ -264,7 +264,7 @@ export async function processExchange({req, res, workflow, exchangeRecord}) {
|
|
|
264
264
|
|
|
265
265
|
// FIXME: remove this once the other FIXME below is implemented
|
|
266
266
|
// and provides support for issuance in non-last step
|
|
267
|
-
if(step.issueRequests?.length > 0) {
|
|
267
|
+
if(step.verifiablePresentation || step.issueRequests?.length > 0) {
|
|
268
268
|
throw new BedrockError(
|
|
269
269
|
'Invalid step detected; continuing exchanges currently must ' +
|
|
270
270
|
'only issue in the final step.', {
|
|
@@ -291,14 +291,8 @@ export async function processExchange({req, res, workflow, exchangeRecord}) {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
// FIXME: there may be VCs to issue during this step, do so before
|
|
294
|
-
// sending the VPR above
|
|
295
|
-
|
|
296
|
-
// next steps without VPRs are prohibited
|
|
297
|
-
throw new BedrockError(
|
|
298
|
-
'Invalid step detected; continuing exchanges must include VPRs.', {
|
|
299
|
-
name: 'DataError',
|
|
300
|
-
details: {httpStatusCode: 500, public: true}
|
|
301
|
-
});
|
|
294
|
+
// sending the VPR above and remove error that prevents continuing
|
|
295
|
+
// exchanges that issue
|
|
302
296
|
}
|
|
303
297
|
currentStep = step.nextStep;
|
|
304
298
|
}
|
|
@@ -432,6 +426,6 @@ async function _createProtocols({workflow, exchange, step}) {
|
|
|
432
426
|
|
|
433
427
|
function _supportsVcApi({workflow, step}) {
|
|
434
428
|
return step?.verifiablePresentationRequest ||
|
|
435
|
-
step?.
|
|
429
|
+
step?.verifiablePresentation ||
|
|
436
430
|
workflow?.credentialTemplates?.length > 0;
|
|
437
431
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import {MAX_ISSUER_INSTANCES} from '../lib/constants.js';
|
|
5
5
|
import {schemas} from '@bedrock/validation';
|
|
@@ -150,6 +150,21 @@ const jwkKeyPair = {
|
|
|
150
150
|
}
|
|
151
151
|
};
|
|
152
152
|
|
|
153
|
+
function verifiableOrEnvelopedCredentials() {
|
|
154
|
+
return {
|
|
155
|
+
anyOf: [
|
|
156
|
+
verifiableCredential(),
|
|
157
|
+
envelopedVerifiableCredential, {
|
|
158
|
+
type: 'array',
|
|
159
|
+
minItems: 1,
|
|
160
|
+
items: {
|
|
161
|
+
anyOf: [verifiableCredential(), envelopedVerifiableCredential]
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
153
168
|
export function verifiablePresentation() {
|
|
154
169
|
return {
|
|
155
170
|
title: 'Verifiable Presentation',
|
|
@@ -173,18 +188,7 @@ export function verifiablePresentation() {
|
|
|
173
188
|
type: 'string'
|
|
174
189
|
}
|
|
175
190
|
},
|
|
176
|
-
verifiableCredential:
|
|
177
|
-
anyOf: [
|
|
178
|
-
verifiableCredential(),
|
|
179
|
-
envelopedVerifiableCredential, {
|
|
180
|
-
type: 'array',
|
|
181
|
-
minItems: 1,
|
|
182
|
-
items: {
|
|
183
|
-
anyOf: [verifiableCredential(), envelopedVerifiableCredential]
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
]
|
|
187
|
-
},
|
|
191
|
+
verifiableCredential: verifiableOrEnvelopedCredentials(),
|
|
188
192
|
holder: idOrObjectWithId(),
|
|
189
193
|
proof: schemas.proof()
|
|
190
194
|
}
|
|
@@ -319,12 +323,14 @@ const typedTemplate = {
|
|
|
319
323
|
}
|
|
320
324
|
};
|
|
321
325
|
|
|
322
|
-
export
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
export function credentialTemplates() {
|
|
327
|
+
return {
|
|
328
|
+
title: 'Credential Templates',
|
|
329
|
+
type: 'array',
|
|
330
|
+
minItems: 1,
|
|
331
|
+
items: typedTemplate
|
|
332
|
+
};
|
|
333
|
+
}
|
|
328
334
|
|
|
329
335
|
// to be updated in specific locations with `properties` and `required`
|
|
330
336
|
const zcapReferenceIds = {
|
|
@@ -364,13 +370,15 @@ const issuerInstance = {
|
|
|
364
370
|
}
|
|
365
371
|
};
|
|
366
372
|
|
|
367
|
-
export
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
373
|
+
export function issuerInstances() {
|
|
374
|
+
return {
|
|
375
|
+
title: 'Issuer Instances',
|
|
376
|
+
type: 'array',
|
|
377
|
+
minItems: 1,
|
|
378
|
+
maxItems: MAX_ISSUER_INSTANCES,
|
|
379
|
+
items: issuerInstance
|
|
380
|
+
};
|
|
381
|
+
}
|
|
374
382
|
|
|
375
383
|
const issueRequestParameters = {
|
|
376
384
|
title: 'Issue Request Parameters',
|
|
@@ -493,168 +501,188 @@ const oid4vpClientProfile = {
|
|
|
493
501
|
}
|
|
494
502
|
};
|
|
495
503
|
|
|
496
|
-
export
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
};
|
|
504
|
-
|
|
505
|
-
const step = {
|
|
506
|
-
title: 'Exchange Step',
|
|
507
|
-
type: 'object',
|
|
508
|
-
minProperties: 1,
|
|
509
|
-
additionalProperties: false,
|
|
510
|
-
// step can either use a template so it will be generated using variables
|
|
511
|
-
// associated with the exchange, or static values can be provided
|
|
512
|
-
oneOf: [{
|
|
513
|
-
// `stepTemplate` must be present and nothing else
|
|
514
|
-
required: ['stepTemplate'],
|
|
515
|
-
not: {
|
|
516
|
-
required: [
|
|
517
|
-
'allowUnprotectedPresentation',
|
|
518
|
-
'callback',
|
|
519
|
-
'createChallenge',
|
|
520
|
-
'issueRequests',
|
|
521
|
-
'jwtDidProofRequest',
|
|
522
|
-
'nextStep',
|
|
523
|
-
'openId',
|
|
524
|
-
'presentationSchema',
|
|
525
|
-
'verifiablePresentationRequest'
|
|
526
|
-
]
|
|
527
|
-
}
|
|
528
|
-
}, {
|
|
529
|
-
// anything except `stepTemplate` can be used
|
|
530
|
-
not: {
|
|
531
|
-
required: ['stepTemplate']
|
|
504
|
+
export function oid4vpClientProfiles() {
|
|
505
|
+
return {
|
|
506
|
+
title: 'OID4VP Client Profiles',
|
|
507
|
+
type: 'object',
|
|
508
|
+
additionalProperties: false,
|
|
509
|
+
patternProperties: {
|
|
510
|
+
'^.*$': oid4vpClientProfile
|
|
532
511
|
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function step() {
|
|
516
|
+
return {
|
|
517
|
+
title: 'Exchange Step',
|
|
518
|
+
type: 'object',
|
|
519
|
+
minProperties: 1,
|
|
520
|
+
additionalProperties: false,
|
|
521
|
+
// step can either use a template so it will be generated using variables
|
|
522
|
+
// associated with the exchange, or static values can be provided
|
|
523
|
+
oneOf: [{
|
|
524
|
+
// `stepTemplate` must be present and nothing else
|
|
525
|
+
required: ['stepTemplate'],
|
|
526
|
+
not: {
|
|
527
|
+
required: [
|
|
528
|
+
'allowUnprotectedPresentation',
|
|
529
|
+
'callback',
|
|
530
|
+
'createChallenge',
|
|
531
|
+
'issueRequests',
|
|
532
|
+
'jwtDidProofRequest',
|
|
533
|
+
'nextStep',
|
|
534
|
+
'openId',
|
|
535
|
+
'presentationSchema',
|
|
536
|
+
'verifiablePresentation',
|
|
537
|
+
'verifiablePresentationRequest'
|
|
538
|
+
]
|
|
546
539
|
}
|
|
547
|
-
},
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
minItems: 1,
|
|
564
|
-
items: {
|
|
565
|
-
title: 'Accepted DID Method',
|
|
566
|
-
type: 'object',
|
|
567
|
-
additionalProperties: false,
|
|
568
|
-
properties: {
|
|
569
|
-
method: {
|
|
570
|
-
type: 'string'
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
},
|
|
575
|
-
allowedAlgorithms: {
|
|
576
|
-
title: 'Allowed JWT Algorithms',
|
|
577
|
-
type: 'array',
|
|
578
|
-
minItems: 1,
|
|
579
|
-
items: {
|
|
540
|
+
}, {
|
|
541
|
+
// anything except `stepTemplate` can be used
|
|
542
|
+
not: {
|
|
543
|
+
required: ['stepTemplate']
|
|
544
|
+
}
|
|
545
|
+
}],
|
|
546
|
+
properties: {
|
|
547
|
+
allowUnprotectedPresentation: {
|
|
548
|
+
type: 'boolean'
|
|
549
|
+
},
|
|
550
|
+
callback: {
|
|
551
|
+
type: 'object',
|
|
552
|
+
required: ['url'],
|
|
553
|
+
additionalProperties: false,
|
|
554
|
+
properties: {
|
|
555
|
+
url: {
|
|
580
556
|
type: 'string'
|
|
581
557
|
}
|
|
582
558
|
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
559
|
+
},
|
|
560
|
+
createChallenge: {
|
|
561
|
+
type: 'boolean'
|
|
562
|
+
},
|
|
563
|
+
// issue request parameters for VCs that are to be issued and delivered
|
|
564
|
+
// during this step
|
|
565
|
+
issueRequests: {
|
|
566
|
+
type: 'array',
|
|
567
|
+
minItems: 0,
|
|
568
|
+
items: issueRequestParameters
|
|
569
|
+
},
|
|
570
|
+
jwtDidProofRequest: {
|
|
595
571
|
type: 'object',
|
|
596
|
-
required: ['clientProfiles'],
|
|
597
572
|
additionalProperties: false,
|
|
598
573
|
properties: {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
574
|
+
acceptedMethods: {
|
|
575
|
+
title: 'Accepted DID Methods',
|
|
576
|
+
type: 'array',
|
|
577
|
+
minItems: 1,
|
|
578
|
+
items: {
|
|
579
|
+
title: 'Accepted DID Method',
|
|
580
|
+
type: 'object',
|
|
581
|
+
additionalProperties: false,
|
|
582
|
+
properties: {
|
|
583
|
+
method: {
|
|
584
|
+
type: 'string'
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
allowedAlgorithms: {
|
|
590
|
+
title: 'Allowed JWT Algorithms',
|
|
591
|
+
type: 'array',
|
|
592
|
+
minItems: 1,
|
|
593
|
+
items: {
|
|
594
|
+
type: 'string'
|
|
595
|
+
}
|
|
596
|
+
}
|
|
613
597
|
}
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
598
|
+
},
|
|
599
|
+
nextStep: {
|
|
600
|
+
type: 'string'
|
|
601
|
+
},
|
|
602
|
+
// required to support OID4VP
|
|
603
|
+
// (but can be provided by step template instead)
|
|
604
|
+
openId: {
|
|
605
|
+
// either a single top-level client profile is specified here or
|
|
606
|
+
// `clientProfiles` is specified with nested client profiles
|
|
607
|
+
oneOf: [{
|
|
608
|
+
oid4vpClientProfile
|
|
609
|
+
}, {
|
|
610
|
+
type: 'object',
|
|
611
|
+
required: ['clientProfiles'],
|
|
612
|
+
additionalProperties: false,
|
|
613
|
+
properties: {
|
|
614
|
+
clientProfiles: oid4vpClientProfiles()
|
|
615
|
+
}
|
|
616
|
+
}]
|
|
617
|
+
},
|
|
618
|
+
presentationSchema: {
|
|
619
|
+
type: 'object',
|
|
620
|
+
required: ['type', 'jsonSchema'],
|
|
621
|
+
additionalProperties: false,
|
|
622
|
+
properties: {
|
|
623
|
+
type: {
|
|
624
|
+
type: 'string'
|
|
625
|
+
},
|
|
626
|
+
jsonSchema: {
|
|
627
|
+
type: 'object'
|
|
628
|
+
}
|
|
625
629
|
}
|
|
626
630
|
},
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
631
|
+
stepTemplate: typedTemplate,
|
|
632
|
+
// the base verifiable presentation to use in this step; any VCs that
|
|
633
|
+
// are issued in this step (see: `issueRequests`) will be added to this
|
|
634
|
+
// VP, in which case any proofs on it will be invalidated; VCs that were
|
|
635
|
+
// previously issued but are to be delivered during this step can be
|
|
636
|
+
// present in `verifiablePresentation.verifiableCredential` and any newly
|
|
637
|
+
// issued ones will be appended to that field; if not present and any
|
|
638
|
+
// VCs are to be issued, this will be auto-generated
|
|
639
|
+
verifiablePresentation: verifiablePresentation(),
|
|
640
|
+
verifiablePresentationRequest: {
|
|
641
|
+
type: 'object'
|
|
642
|
+
},
|
|
643
|
+
verifyPresentationOptions: {
|
|
644
|
+
type: 'object',
|
|
645
|
+
properties: {
|
|
646
|
+
checks: {
|
|
647
|
+
type: 'object'
|
|
648
|
+
}
|
|
636
649
|
},
|
|
637
|
-
|
|
638
|
-
|
|
650
|
+
additionalProperties: true
|
|
651
|
+
},
|
|
652
|
+
verifyPresentationResultSchema: {
|
|
653
|
+
type: 'object',
|
|
654
|
+
required: ['type', 'jsonSchema'],
|
|
655
|
+
additionalProperties: false,
|
|
656
|
+
properties: {
|
|
657
|
+
type: {
|
|
658
|
+
type: 'string'
|
|
659
|
+
},
|
|
660
|
+
jsonSchema: {
|
|
661
|
+
type: 'object'
|
|
662
|
+
}
|
|
639
663
|
}
|
|
640
664
|
}
|
|
641
665
|
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
666
|
+
};
|
|
667
|
+
}
|
|
644
668
|
|
|
645
|
-
export
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
669
|
+
export function steps() {
|
|
670
|
+
return {
|
|
671
|
+
title: 'Exchange Steps',
|
|
672
|
+
type: 'object',
|
|
673
|
+
additionalProperties: false,
|
|
674
|
+
patternProperties: {
|
|
675
|
+
'^.*$': step()
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
}
|
|
653
679
|
|
|
654
|
-
export
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
680
|
+
export function initialStep() {
|
|
681
|
+
return {
|
|
682
|
+
title: 'Initial Exchange Step',
|
|
683
|
+
type: 'string'
|
|
684
|
+
};
|
|
685
|
+
}
|
|
658
686
|
|
|
659
687
|
export function useExchangeBody() {
|
|
660
688
|
return {
|
|
@@ -672,83 +700,89 @@ export function useExchangeBody() {
|
|
|
672
700
|
};
|
|
673
701
|
}
|
|
674
702
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
703
|
+
function openIdCredentialRequest() {
|
|
704
|
+
return {
|
|
705
|
+
title: 'OpenID Credential Request',
|
|
706
|
+
type: 'object',
|
|
707
|
+
additionalProperties: false,
|
|
708
|
+
required: ['credential_definition', 'format'],
|
|
709
|
+
properties: {
|
|
710
|
+
credential_definition: credentialDefinition,
|
|
711
|
+
format: {
|
|
712
|
+
type: 'string',
|
|
713
|
+
enum: ['di_vc', 'ldp_vc', 'jwt_vc_json-ld', 'jwt_vc_json']
|
|
714
|
+
},
|
|
715
|
+
did: {
|
|
716
|
+
type: 'string'
|
|
717
|
+
},
|
|
718
|
+
proof: {
|
|
719
|
+
title: 'DID Authn Proof JWT',
|
|
720
|
+
type: 'object',
|
|
721
|
+
additionalProperties: false,
|
|
722
|
+
required: ['proof_type', 'jwt'],
|
|
723
|
+
properties: {
|
|
724
|
+
proof_type: {
|
|
725
|
+
type: 'string',
|
|
726
|
+
enum: ['jwt']
|
|
727
|
+
},
|
|
728
|
+
jwt: {
|
|
729
|
+
type: 'string'
|
|
730
|
+
}
|
|
701
731
|
}
|
|
702
732
|
}
|
|
703
733
|
}
|
|
704
|
-
}
|
|
705
|
-
}
|
|
734
|
+
};
|
|
735
|
+
}
|
|
706
736
|
|
|
707
737
|
export const openIdCredentialBody = openIdCredentialRequest;
|
|
708
738
|
|
|
709
|
-
export
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
739
|
+
export function openIdBatchCredentialBody() {
|
|
740
|
+
return {
|
|
741
|
+
title: 'OpenID Batch Credential Request',
|
|
742
|
+
type: 'object',
|
|
743
|
+
additionalProperties: false,
|
|
744
|
+
required: ['credential_requests'],
|
|
745
|
+
properties: {
|
|
746
|
+
credential_requests: {
|
|
747
|
+
title: 'OpenID Credential Requests',
|
|
748
|
+
type: 'array',
|
|
749
|
+
minItems: 1,
|
|
750
|
+
items: openIdCredentialRequest()
|
|
751
|
+
}
|
|
720
752
|
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
753
|
+
};
|
|
754
|
+
}
|
|
723
755
|
|
|
724
|
-
export
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
756
|
+
export function openIdTokenBody() {
|
|
757
|
+
return {
|
|
758
|
+
title: 'OpenID Token Request',
|
|
759
|
+
type: 'object',
|
|
760
|
+
additionalProperties: false,
|
|
761
|
+
required: ['grant_type'],
|
|
762
|
+
properties: {
|
|
763
|
+
grant_type: {
|
|
764
|
+
type: 'string'
|
|
765
|
+
},
|
|
766
|
+
'pre-authorized_code': {
|
|
767
|
+
type: 'string'
|
|
768
|
+
},
|
|
769
|
+
// FIXME: there is no implementation for using these fields yet:
|
|
770
|
+
// user_pin: {
|
|
771
|
+
// type: 'string'
|
|
772
|
+
// },
|
|
773
|
+
// // params for `authorization_code` grant type
|
|
774
|
+
// code: {
|
|
775
|
+
// type: 'string'
|
|
776
|
+
// },
|
|
777
|
+
// verifier: {
|
|
778
|
+
// type: 'string'
|
|
779
|
+
// },
|
|
780
|
+
// redirect_uri: {
|
|
781
|
+
// type: 'string'
|
|
782
|
+
// }
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
}
|
|
752
786
|
|
|
753
787
|
const presentationDescriptor = {
|
|
754
788
|
title: 'Presentation Submission Descriptor',
|
|
@@ -771,26 +805,28 @@ const presentationDescriptor = {
|
|
|
771
805
|
}
|
|
772
806
|
};
|
|
773
807
|
|
|
774
|
-
export
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
808
|
+
export function presentationSubmission() {
|
|
809
|
+
return {
|
|
810
|
+
title: 'Presentation Submission',
|
|
811
|
+
type: 'object',
|
|
812
|
+
additionalProperties: false,
|
|
813
|
+
required: ['id', 'definition_id', 'descriptor_map'],
|
|
814
|
+
properties: {
|
|
815
|
+
id: {
|
|
816
|
+
type: 'string'
|
|
817
|
+
},
|
|
818
|
+
definition_id: {
|
|
819
|
+
type: 'string'
|
|
820
|
+
},
|
|
821
|
+
descriptor_map: {
|
|
822
|
+
title: 'Presentation Submission Descriptor Map',
|
|
823
|
+
type: 'array',
|
|
824
|
+
minItems: 0,
|
|
825
|
+
items: presentationDescriptor
|
|
826
|
+
}
|
|
791
827
|
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
828
|
+
};
|
|
829
|
+
}
|
|
794
830
|
|
|
795
831
|
export function openIdAuthorizationResponseBody() {
|
|
796
832
|
return {
|