@cheqd/studio 3.7.0-develop.1 → 3.8.0-develop.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.
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +3 -3
- package/dist/app.js.map +1 -1
- package/dist/controllers/api/accreditation.d.ts +6 -6
- package/dist/controllers/api/accreditation.d.ts.map +1 -1
- package/dist/controllers/api/accreditation.js +20 -16
- package/dist/controllers/api/accreditation.js.map +1 -1
- package/dist/controllers/api/credential-status.d.ts +103 -16
- package/dist/controllers/api/credential-status.d.ts.map +1 -1
- package/dist/controllers/api/credential-status.js +321 -61
- package/dist/controllers/api/credential-status.js.map +1 -1
- package/dist/controllers/api/credential.d.ts +33 -8
- package/dist/controllers/api/credential.d.ts.map +1 -1
- package/dist/controllers/api/credential.js +53 -30
- package/dist/controllers/api/credential.js.map +1 -1
- package/dist/controllers/api/did.d.ts.map +1 -1
- package/dist/controllers/api/did.js +8 -0
- package/dist/controllers/api/did.js.map +1 -1
- package/dist/controllers/validator/credential-status.d.ts.map +1 -1
- package/dist/controllers/validator/credential-status.js +19 -5
- package/dist/controllers/validator/credential-status.js.map +1 -1
- package/dist/controllers/validator/service-create-request.d.ts.map +1 -1
- package/dist/controllers/validator/service-create-request.js +16 -0
- package/dist/controllers/validator/service-create-request.js.map +1 -1
- package/dist/controllers/validator/service.d.ts.map +1 -1
- package/dist/controllers/validator/service.js +16 -0
- package/dist/controllers/validator/service.js.map +1 -1
- package/dist/database/entities/api.key.entity.js +1 -1
- package/dist/database/entities/payment.entity.d.ts.map +1 -1
- package/dist/database/entities/payment.entity.js +4 -1
- package/dist/database/entities/payment.entity.js.map +1 -1
- package/dist/database/entities/resource.entity.js.map +1 -1
- package/dist/database/entities/subscription.entity.js.map +1 -1
- package/dist/database/migrations/1750427001486-studio-migrations.d.ts +1 -1
- package/dist/database/migrations/1750427001486-studio-migrations.d.ts.map +1 -1
- package/dist/database/migrations/1750427001486-studio-migrations.js +0 -2
- package/dist/database/migrations/1750427001486-studio-migrations.js.map +1 -1
- package/dist/database/migrations/custom/1748331341024-Cleanup.d.ts +1 -1
- package/dist/database/migrations/custom/1748331341024-Cleanup.d.ts.map +1 -1
- package/dist/database/migrations/custom/1748331341024-Cleanup.js +1 -1
- package/dist/database/migrations/custom/1748331341024-Cleanup.js.map +1 -1
- package/dist/database/scripts/add-migration-to-types.js +6 -5
- package/dist/database/scripts/add-migration-to-types.js.map +1 -1
- package/dist/middleware/auth/auth-gaurd.js +1 -1
- package/dist/middleware/auth/auth-gaurd.js.map +1 -1
- package/dist/services/identity/abstract.d.ts +11 -8
- package/dist/services/identity/abstract.d.ts.map +1 -1
- package/dist/services/identity/abstract.js +15 -6
- package/dist/services/identity/abstract.js.map +1 -1
- package/dist/services/identity/agent.d.ts +10 -7
- package/dist/services/identity/agent.d.ts.map +1 -1
- package/dist/services/identity/agent.js +370 -139
- package/dist/services/identity/agent.js.map +1 -1
- package/dist/services/identity/default.d.ts +1 -1
- package/dist/services/identity/default.d.ts.map +1 -1
- package/dist/services/identity/default.js +2 -2
- package/dist/services/identity/default.js.map +1 -1
- package/dist/services/identity/index.d.ts +11 -8
- package/dist/services/identity/index.d.ts.map +1 -1
- package/dist/services/identity/index.js.map +1 -1
- package/dist/services/identity/local.d.ts +9 -6
- package/dist/services/identity/local.d.ts.map +1 -1
- package/dist/services/identity/local.js +18 -10
- package/dist/services/identity/local.js.map +1 -1
- package/dist/services/identity/postgres.d.ts +9 -6
- package/dist/services/identity/postgres.d.ts.map +1 -1
- package/dist/services/identity/postgres.js +24 -10
- package/dist/services/identity/postgres.js.map +1 -1
- package/dist/services/track/operation-subscriber.d.ts.map +1 -1
- package/dist/services/track/operation-subscriber.js +18 -16
- package/dist/services/track/operation-subscriber.js.map +1 -1
- package/dist/services/w3c-credential.d.ts +2 -2
- package/dist/services/w3c-credential.d.ts.map +1 -1
- package/dist/services/w3c-credential.js +2 -1
- package/dist/services/w3c-credential.js.map +1 -1
- package/dist/static/swagger-api.json +289 -43
- package/dist/types/accreditation.d.ts +11 -14
- package/dist/types/accreditation.d.ts.map +1 -1
- package/dist/types/accreditation.js +6 -0
- package/dist/types/accreditation.js.map +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/constants.js +1 -0
- package/dist/types/constants.js.map +1 -1
- package/dist/types/credential-status.d.ts +40 -8
- package/dist/types/credential-status.d.ts.map +1 -1
- package/dist/types/credential-status.js +11 -0
- package/dist/types/credential-status.js.map +1 -1
- package/dist/types/credential.d.ts +7 -10
- package/dist/types/credential.d.ts.map +1 -1
- package/dist/types/credential.js.map +1 -1
- package/dist/types/swagger-api-types.d.ts +62 -12
- package/dist/types/swagger-api-types.d.ts.map +1 -1
- package/dist/types/swagger-api-types.js +62 -12
- package/dist/types/swagger-api-types.js.map +1 -1
- package/dist/types/validation.d.ts +4 -0
- package/dist/types/validation.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -8,8 +8,8 @@ import { check, query } from '../validator/index.js';
|
|
|
8
8
|
import { fromString } from 'uint8arrays';
|
|
9
9
|
import { StatusCodes } from 'http-status-codes';
|
|
10
10
|
import { IdentityServiceStrategySetup } from '../../services/identity/index.js';
|
|
11
|
-
import { DefaultStatusActionPurposeMap, DefaultStatusActions, } from '../../types/credential-status.js';
|
|
12
|
-
import {
|
|
11
|
+
import { DefaultStatusActionPurposeMap, DefaultStatusActions, StatusListType, } from '../../types/credential-status.js';
|
|
12
|
+
import { DefaultStatusListEncodings, DefaultStatusList2021StatusPurposeTypes, BitstringStatusPurposeTypes, } from '@cheqd/did-provider-cheqd';
|
|
13
13
|
import { toNetwork } from '../../helpers/helpers.js';
|
|
14
14
|
import { eventTracker } from '../../services/track/tracker.js';
|
|
15
15
|
import { OperationCategoryNameEnum, OperationNameEnum } from '../../types/constants.js';
|
|
@@ -18,15 +18,69 @@ import { validate } from '../validator/decorator.js';
|
|
|
18
18
|
export class CredentialStatusController {
|
|
19
19
|
static createUnencryptedValidator = [
|
|
20
20
|
check('did').exists().withMessage('did: required').bail().isDID(),
|
|
21
|
-
check('
|
|
21
|
+
check('listType')
|
|
22
22
|
.exists()
|
|
23
|
-
.withMessage('
|
|
23
|
+
.withMessage('listType: required')
|
|
24
24
|
.bail()
|
|
25
25
|
.isString()
|
|
26
|
-
.withMessage('
|
|
26
|
+
.withMessage('listType: should be a string')
|
|
27
27
|
.bail()
|
|
28
|
-
.isIn(
|
|
29
|
-
.withMessage(`
|
|
28
|
+
.isIn([StatusListType.Bitstring, StatusListType.StatusList2021])
|
|
29
|
+
.withMessage(`listType: invalid listType, should be one of [${Object.values(StatusListType)
|
|
30
|
+
.map((v) => `'${v}'`)
|
|
31
|
+
.join(', ')}]`)
|
|
32
|
+
.bail(),
|
|
33
|
+
check('statusPurpose')
|
|
34
|
+
.exists()
|
|
35
|
+
.withMessage('statusPurpose: required')
|
|
36
|
+
.bail()
|
|
37
|
+
.custom((value, { req }) => {
|
|
38
|
+
const listType = req.query?.listType || req.body.listType;
|
|
39
|
+
let purposes = [];
|
|
40
|
+
// Normalize input to array
|
|
41
|
+
if (typeof value === 'string') {
|
|
42
|
+
purposes = value
|
|
43
|
+
.split(',')
|
|
44
|
+
.map((p) => p.trim())
|
|
45
|
+
.filter((p) => p);
|
|
46
|
+
}
|
|
47
|
+
else if (Array.isArray(value)) {
|
|
48
|
+
purposes = value;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new Error('statusPurpose: should be a string or array');
|
|
52
|
+
}
|
|
53
|
+
// Check if multiple purposes are allowed for this listType
|
|
54
|
+
if (purposes.length > 1 && listType === StatusListType.StatusList2021) {
|
|
55
|
+
throw new Error('statusPurpose: multiple values only allowed for BitstringStatusList');
|
|
56
|
+
}
|
|
57
|
+
// Validate array is not empty
|
|
58
|
+
if (purposes.length === 0) {
|
|
59
|
+
throw new Error('statusPurpose: cannot be empty');
|
|
60
|
+
}
|
|
61
|
+
if (listType === StatusListType.StatusList2021) {
|
|
62
|
+
const validPurposes = Object.keys(DefaultStatusList2021StatusPurposeTypes);
|
|
63
|
+
// Check for valid purposes
|
|
64
|
+
const invalidPurposes = purposes.filter((purpose) => !validPurposes.includes(purpose));
|
|
65
|
+
if (invalidPurposes.length > 0) {
|
|
66
|
+
throw new Error(`statusPurpose: invalid statusPurpose(s) "${invalidPurposes.join(', ')}", should be one of ${validPurposes.join(', ')}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const validPurposes = Object.keys(BitstringStatusPurposeTypes);
|
|
71
|
+
// Check for valid purposes
|
|
72
|
+
const invalidPurposes = purposes.filter((purpose) => !validPurposes.includes(purpose));
|
|
73
|
+
if (invalidPurposes.length > 0) {
|
|
74
|
+
throw new Error(`statusPurpose: invalid statusPurpose(s) "${invalidPurposes.join(', ')}", should be one of ${validPurposes.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Check for duplicates
|
|
78
|
+
const uniquePurposes = [...new Set(purposes)];
|
|
79
|
+
if (uniquePurposes.length !== purposes.length) {
|
|
80
|
+
throw new Error('statusPurpose: duplicate values not allowed');
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
})
|
|
30
84
|
.bail(),
|
|
31
85
|
check('statusListName')
|
|
32
86
|
.exists()
|
|
@@ -70,8 +124,56 @@ export class CredentialStatusController {
|
|
|
70
124
|
.bail(),
|
|
71
125
|
check('encoding')
|
|
72
126
|
.optional()
|
|
73
|
-
.
|
|
74
|
-
|
|
127
|
+
.custom((value, { req }) => {
|
|
128
|
+
const listType = req.query?.listType || req.body.listType;
|
|
129
|
+
if (listType === StatusListType.StatusList2021) {
|
|
130
|
+
if (!Object.values(DefaultStatusListEncodings).includes(value)) {
|
|
131
|
+
throw new Error(`encoding: invalid encoding, should be one of ${Object.keys(DefaultStatusListEncodings).join(', ')}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
if (value !== DefaultStatusListEncodings.base64url) {
|
|
136
|
+
throw new Error(`encoding: invalid encoding, should be base64url for BitstringStatusList`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
})
|
|
141
|
+
.bail(),
|
|
142
|
+
check('statusSize')
|
|
143
|
+
.optional()
|
|
144
|
+
.isNumeric()
|
|
145
|
+
.withMessage('statusSize: should be a number')
|
|
146
|
+
.bail()
|
|
147
|
+
.custom((value) => {
|
|
148
|
+
const val = parseInt(value.toString(), 10);
|
|
149
|
+
return !isNaN(val) && isFinite(val) && Number.isInteger(val);
|
|
150
|
+
})
|
|
151
|
+
.custom((value) => {
|
|
152
|
+
const val = parseInt(value.toString(), 10);
|
|
153
|
+
return val >= 1 && val <= 8;
|
|
154
|
+
})
|
|
155
|
+
.withMessage('statusSize: should be an integer between 1 and 8')
|
|
156
|
+
.bail(),
|
|
157
|
+
check('statusMessages')
|
|
158
|
+
.optional()
|
|
159
|
+
.isArray()
|
|
160
|
+
.withMessage('statusMessages: should be an array')
|
|
161
|
+
.bail()
|
|
162
|
+
.custom((value) => Array.isArray(value) && value.length > 0)
|
|
163
|
+
.withMessage('statusMessages: should be a non-empty array')
|
|
164
|
+
.bail()
|
|
165
|
+
.custom((value) => value.every((item) => typeof item?.status === 'string' && typeof item?.message === 'string'))
|
|
166
|
+
.withMessage('statusMessages: should be an array of objects with `status` and `message` properties of type string')
|
|
167
|
+
.bail()
|
|
168
|
+
.custom((value, { req }) => {
|
|
169
|
+
const sizeRaw = req.query?.statusSize || req.body?.statusSize;
|
|
170
|
+
const size = parseInt(sizeRaw?.toString(), 10);
|
|
171
|
+
if (isNaN(size) || size <= 1) {
|
|
172
|
+
return true; // If size is 1 or undefined, skip this check
|
|
173
|
+
}
|
|
174
|
+
return value.length === Math.pow(2, size);
|
|
175
|
+
})
|
|
176
|
+
.withMessage('statusMessages: array size must be 2^statusSize when statusSize > 1')
|
|
75
177
|
.bail(),
|
|
76
178
|
check('encodedList').optional().isString().withMessage('encodedList: should be a string').bail(),
|
|
77
179
|
];
|
|
@@ -160,6 +262,18 @@ export class CredentialStatusController {
|
|
|
160
262
|
];
|
|
161
263
|
static updateUnencryptedValidator = [
|
|
162
264
|
check('did').exists().withMessage('did: required').bail().isDID().bail(),
|
|
265
|
+
check('listType')
|
|
266
|
+
.exists()
|
|
267
|
+
.withMessage('listType: required')
|
|
268
|
+
.bail()
|
|
269
|
+
.isString()
|
|
270
|
+
.withMessage('listType: should be a string')
|
|
271
|
+
.bail()
|
|
272
|
+
.isIn([StatusListType.Bitstring, StatusListType.StatusList2021])
|
|
273
|
+
.withMessage(`listType: invalid listType, should be one of [${Object.values(StatusListType)
|
|
274
|
+
.map((v) => `'${v}'`)
|
|
275
|
+
.join(', ')}]`)
|
|
276
|
+
.bail(),
|
|
163
277
|
check('statusAction')
|
|
164
278
|
.exists()
|
|
165
279
|
.withMessage('statusAction: required')
|
|
@@ -343,6 +457,17 @@ export class CredentialStatusController {
|
|
|
343
457
|
.notEmpty()
|
|
344
458
|
.withMessage('statusListName: should be a non-empty string')
|
|
345
459
|
.bail(),
|
|
460
|
+
query('listType')
|
|
461
|
+
.exists()
|
|
462
|
+
.withMessage('listType: required')
|
|
463
|
+
.bail()
|
|
464
|
+
.isString()
|
|
465
|
+
.withMessage('listType: should be a string')
|
|
466
|
+
.bail()
|
|
467
|
+
.isIn([StatusListType.Bitstring, StatusListType.StatusList2021])
|
|
468
|
+
.withMessage(`listType: invalid listType, should be one of [${Object.values(StatusListType)
|
|
469
|
+
.map((v) => `'${v}'`)
|
|
470
|
+
.join(', ')}]`),
|
|
346
471
|
query('statusPurpose')
|
|
347
472
|
.exists()
|
|
348
473
|
.withMessage('statusPurpose: required')
|
|
@@ -363,18 +488,47 @@ export class CredentialStatusController {
|
|
|
363
488
|
* /credential-status/create/unencrypted:
|
|
364
489
|
* post:
|
|
365
490
|
* tags: [ Credential Status ]
|
|
366
|
-
* summary: Create an unencrypted StatusList2021 credential status list.
|
|
367
|
-
* description: This endpoint creates an unencrypted StatusList2021 credential status list. The StatusList is published as a DID-Linked Resource on ledger. As input, it can can take input parameters needed to create the status list via a form, or a pre-assembled status list in JSON format. Status lists can be created as either encrypted or unencrypted
|
|
491
|
+
* summary: Create an unencrypted StatusList2021 or BitstringStatusList credential status list.
|
|
492
|
+
* description: This endpoint creates an unencrypted StatusList2021 or BitstringStatusList credential status list. The StatusList is published as a DID-Linked Resource on ledger. As input, it can can take input parameters needed to create the status list via a form, or a pre-assembled status list in JSON format. Status lists can be created as either encrypted or unencrypted.
|
|
368
493
|
* parameters:
|
|
369
494
|
* - in: query
|
|
370
|
-
* name:
|
|
371
|
-
* description: The
|
|
495
|
+
* name: listType
|
|
496
|
+
* description: The type of Status List.
|
|
372
497
|
* required: true
|
|
373
498
|
* schema:
|
|
374
499
|
* type: string
|
|
375
500
|
* enum:
|
|
376
|
-
* -
|
|
377
|
-
* -
|
|
501
|
+
* - StatusList2021
|
|
502
|
+
* - BitstringStatusList
|
|
503
|
+
* - in: query
|
|
504
|
+
* name: statusPurpose
|
|
505
|
+
* description: |
|
|
506
|
+
* The purpose of the status list.
|
|
507
|
+
* - For StatusList2021: Single value (revocation or suspension)
|
|
508
|
+
* - For BitstringStatusList: Can accept multiple values as array of strings
|
|
509
|
+
*
|
|
510
|
+
* Once this is set, it cannot be changed. A new status list must be created to change the purpose.
|
|
511
|
+
* required: true
|
|
512
|
+
* schema:
|
|
513
|
+
* oneOf:
|
|
514
|
+
* - type: string
|
|
515
|
+
* enum:
|
|
516
|
+
* - revocation
|
|
517
|
+
* - suspension
|
|
518
|
+
* - type: array
|
|
519
|
+
* items:
|
|
520
|
+
* type: string
|
|
521
|
+
* enum: [revocation, suspension, message, refresh]
|
|
522
|
+
* examples:
|
|
523
|
+
* single_value:
|
|
524
|
+
* summary: Single purpose (StatusList2021)
|
|
525
|
+
* value: "revocation"
|
|
526
|
+
* multiple_values_array:
|
|
527
|
+
* summary: Multiple purposes as array (BitstringStatusList)
|
|
528
|
+
* value: ["revocation", "suspension", "message"]
|
|
529
|
+
* with_message:
|
|
530
|
+
* summary: Including message purpose
|
|
531
|
+
* value: ["revocation", "message"]
|
|
378
532
|
* requestBody:
|
|
379
533
|
* content:
|
|
380
534
|
* application/x-www-form-urlencoded:
|
|
@@ -399,9 +553,9 @@ export class CredentialStatusController {
|
|
|
399
553
|
*/
|
|
400
554
|
async createUnencryptedStatusList(request, response) {
|
|
401
555
|
// collect request parameters - case: body
|
|
402
|
-
const { did, encodedList, statusListName, alsoKnownAs, statusListVersion, length, encoding } = request.body;
|
|
556
|
+
const { did, encodedList, statusListName, alsoKnownAs, statusListVersion, length, encoding, statusSize: size, ttl, statusMessages, } = request.body;
|
|
403
557
|
// collect request parameters - case: query
|
|
404
|
-
const { statusPurpose } = request.query;
|
|
558
|
+
const { listType, statusPurpose } = request.query;
|
|
405
559
|
// define broadcast mode
|
|
406
560
|
const data = encodedList ? fromString(encodedList, encoding) : undefined;
|
|
407
561
|
// create agent
|
|
@@ -409,19 +563,44 @@ export class CredentialStatusController {
|
|
|
409
563
|
try {
|
|
410
564
|
// broadcast, if applicable
|
|
411
565
|
if (data) {
|
|
412
|
-
|
|
566
|
+
let result;
|
|
567
|
+
if (listType === StatusListType.Bitstring) {
|
|
568
|
+
result = await identityServiceStrategySetup.agent.broadcastBitstringStatusList(did, { data, name: statusListName, alsoKnownAs, version: statusListVersion }, response.locals.customer);
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
result = await identityServiceStrategySetup.agent.broadcastStatusList2021(did, { data, name: statusListName, alsoKnownAs, version: statusListVersion }, { encoding, statusPurpose }, response.locals.customer);
|
|
572
|
+
}
|
|
413
573
|
return response.status(StatusCodes.OK).json(result);
|
|
414
574
|
}
|
|
575
|
+
let result;
|
|
415
576
|
// create unencrypted status list
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
577
|
+
if (listType === StatusListType.Bitstring) {
|
|
578
|
+
// create BitstringStatusList
|
|
579
|
+
result = (await identityServiceStrategySetup.agent.createUnencryptedBitstringStatusList(did, {
|
|
580
|
+
name: statusListName,
|
|
581
|
+
alsoKnownAs,
|
|
582
|
+
version: statusListVersion,
|
|
583
|
+
}, {
|
|
584
|
+
length,
|
|
585
|
+
size,
|
|
586
|
+
statusMessages,
|
|
587
|
+
ttl,
|
|
588
|
+
encoding,
|
|
589
|
+
statusPurpose,
|
|
590
|
+
}, response.locals.customer));
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
// create StatusList2021
|
|
594
|
+
result = (await identityServiceStrategySetup.agent.createUnencryptedStatusList2021(did, {
|
|
595
|
+
name: statusListName,
|
|
596
|
+
alsoKnownAs,
|
|
597
|
+
version: statusListVersion,
|
|
598
|
+
}, {
|
|
599
|
+
length,
|
|
600
|
+
encoding,
|
|
601
|
+
statusPurpose,
|
|
602
|
+
}, response.locals.customer));
|
|
603
|
+
}
|
|
425
604
|
// handle error
|
|
426
605
|
if (result.error) {
|
|
427
606
|
return response.status(StatusCodes.BAD_REQUEST).json({
|
|
@@ -460,18 +639,47 @@ export class CredentialStatusController {
|
|
|
460
639
|
* /credential-status/create/encrypted:
|
|
461
640
|
* post:
|
|
462
641
|
* tags: [ Credential Status ]
|
|
463
|
-
* summary: Create an encrypted StatusList2021 credential status list.
|
|
464
|
-
* description: This endpoint creates an encrypted StatusList2021 credential status list. The StatusList is published as a DID-Linked Resource on ledger. As input, it can can take input parameters needed to create the status list via a form, or a pre-assembled status list in JSON format. Status lists can be created as either encrypted or unencrypted
|
|
642
|
+
* summary: Create an encrypted StatusList2021 or BitstringStatusList credential status list.
|
|
643
|
+
* description: This endpoint creates an encrypted StatusList2021 or BitstringStatusList credential status list. The StatusList is published as a DID-Linked Resource on ledger. As input, it can can take input parameters needed to create the status list via a form, or a pre-assembled status list in JSON format. Status lists can be created as either encrypted or unencrypted.
|
|
465
644
|
* parameters:
|
|
466
645
|
* - in: query
|
|
467
|
-
* name:
|
|
468
|
-
* description: The
|
|
646
|
+
* name: listType
|
|
647
|
+
* description: The type of Status List.
|
|
469
648
|
* required: true
|
|
470
649
|
* schema:
|
|
471
650
|
* type: string
|
|
472
651
|
* enum:
|
|
473
|
-
* -
|
|
474
|
-
* -
|
|
652
|
+
* - StatusList2021
|
|
653
|
+
* - BitstringStatusList
|
|
654
|
+
* - in: query
|
|
655
|
+
* name: statusPurpose
|
|
656
|
+
* description: |
|
|
657
|
+
* The purpose of the status list.
|
|
658
|
+
* - For StatusList2021: Single value (revocation or suspension)
|
|
659
|
+
* - For BitstringStatusList: Can accept multiple values as array of strings
|
|
660
|
+
*
|
|
661
|
+
* Once this is set, it cannot be changed. A new status list must be created to change the purpose.
|
|
662
|
+
* required: true
|
|
663
|
+
* schema:
|
|
664
|
+
* oneOf:
|
|
665
|
+
* - type: string
|
|
666
|
+
* enum:
|
|
667
|
+
* - revocation
|
|
668
|
+
* - suspension
|
|
669
|
+
* - type: array
|
|
670
|
+
* items:
|
|
671
|
+
* type: string
|
|
672
|
+
* enum: [revocation, suspension, message, refresh]
|
|
673
|
+
* examples:
|
|
674
|
+
* single_value:
|
|
675
|
+
* summary: Single purpose (StatusList2021)
|
|
676
|
+
* value: "revocation"
|
|
677
|
+
* multiple_values_array:
|
|
678
|
+
* summary: Multiple purposes as array (BitstringStatusList)
|
|
679
|
+
* value: ["revocation", "suspension", "message"]
|
|
680
|
+
* with_message:
|
|
681
|
+
* summary: Including message purpose
|
|
682
|
+
* value: ["revocation", "message"]
|
|
475
683
|
* requestBody:
|
|
476
684
|
* content:
|
|
477
685
|
* application/x-www-form-urlencoded:
|
|
@@ -496,25 +704,48 @@ export class CredentialStatusController {
|
|
|
496
704
|
*/
|
|
497
705
|
async createEncryptedStatusList(request, response) {
|
|
498
706
|
// collect request parameters - case: body
|
|
499
|
-
const { did, statusListName, alsoKnownAs, statusListVersion, length, encoding, paymentConditions, feePaymentAddress, feePaymentAmount, feePaymentWindow, } = request.body;
|
|
707
|
+
const { did, statusListName, alsoKnownAs, statusListVersion, length, statusSize: size, ttl, statusMessages, encoding, paymentConditions, feePaymentAddress, feePaymentAmount, feePaymentWindow, } = request.body;
|
|
500
708
|
// collect request parameters - case: query
|
|
501
|
-
const { statusPurpose } = request.query;
|
|
709
|
+
const { listType, statusPurpose } = request.query;
|
|
502
710
|
const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
|
|
711
|
+
let result;
|
|
503
712
|
try {
|
|
504
713
|
// create encrypted status list
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
714
|
+
if (listType === StatusListType.Bitstring) {
|
|
715
|
+
// create BitstringStatusList
|
|
716
|
+
result = (await identityServiceStrategySetup.agent.createEncryptedBitstringStatusList(did, {
|
|
717
|
+
name: statusListName,
|
|
718
|
+
alsoKnownAs,
|
|
719
|
+
version: statusListVersion,
|
|
720
|
+
}, {
|
|
721
|
+
length,
|
|
722
|
+
size,
|
|
723
|
+
statusMessages,
|
|
724
|
+
ttl,
|
|
725
|
+
encoding,
|
|
726
|
+
statusPurpose,
|
|
727
|
+
paymentConditions,
|
|
728
|
+
feePaymentAddress,
|
|
729
|
+
feePaymentAmount,
|
|
730
|
+
feePaymentWindow,
|
|
731
|
+
}, response.locals.customer));
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
// create StatusList2021
|
|
735
|
+
result = (await identityServiceStrategySetup.agent.createEncryptedStatusList2021(did, {
|
|
736
|
+
name: statusListName,
|
|
737
|
+
alsoKnownAs,
|
|
738
|
+
version: statusListVersion,
|
|
739
|
+
}, {
|
|
740
|
+
length,
|
|
741
|
+
encoding,
|
|
742
|
+
statusPurpose,
|
|
743
|
+
paymentConditions,
|
|
744
|
+
feePaymentAddress,
|
|
745
|
+
feePaymentAmount,
|
|
746
|
+
feePaymentWindow,
|
|
747
|
+
}, response.locals.customer));
|
|
748
|
+
}
|
|
518
749
|
// handle error
|
|
519
750
|
if (result.error) {
|
|
520
751
|
return response.status(StatusCodes.BAD_REQUEST).json({
|
|
@@ -555,9 +786,18 @@ export class CredentialStatusController {
|
|
|
555
786
|
* /credential-status/update/unencrypted:
|
|
556
787
|
* post:
|
|
557
788
|
* tags: [ Credential Status ]
|
|
558
|
-
* summary: Update an existing unencrypted StatusList2021 credential status list.
|
|
789
|
+
* summary: Update an existing unencrypted StatusList2021 or BitstringStatusList credential status list.
|
|
559
790
|
* parameters:
|
|
560
791
|
* - in: query
|
|
792
|
+
* name: listType
|
|
793
|
+
* description: The type of Status List.
|
|
794
|
+
* required: true
|
|
795
|
+
* schema:
|
|
796
|
+
* type: string
|
|
797
|
+
* enum:
|
|
798
|
+
* - StatusList2021
|
|
799
|
+
* - BitstringStatusList
|
|
800
|
+
* - in: query
|
|
561
801
|
* name: statusAction
|
|
562
802
|
* description: The update action to be performed on the unencrypted status list, can be revoke, suspend or reinstate
|
|
563
803
|
* required: true
|
|
@@ -593,11 +833,11 @@ export class CredentialStatusController {
|
|
|
593
833
|
// collect request parameters - case: body
|
|
594
834
|
const { did, statusListName, statusListVersion, indices } = request.body;
|
|
595
835
|
// collect request parameters - case: query
|
|
596
|
-
const { statusAction } = request.query;
|
|
836
|
+
const { statusAction, listType } = request.query;
|
|
597
837
|
// define identity service strategy setup
|
|
598
838
|
const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
|
|
599
839
|
// ensure unencrypted status list
|
|
600
|
-
const unencrypted = await identityServiceStrategySetup.agent.
|
|
840
|
+
const unencrypted = await identityServiceStrategySetup.agent.searchStatusList(did, statusListName, listType, DefaultStatusActionPurposeMap[statusAction]);
|
|
601
841
|
// handle error
|
|
602
842
|
if (unencrypted.error) {
|
|
603
843
|
// handle notFound error
|
|
@@ -621,7 +861,7 @@ export class CredentialStatusController {
|
|
|
621
861
|
});
|
|
622
862
|
try {
|
|
623
863
|
// update unencrypted status list
|
|
624
|
-
const result = (await identityServiceStrategySetup.agent.
|
|
864
|
+
const result = (await identityServiceStrategySetup.agent.updateUnencryptedStatusList(did, listType, {
|
|
625
865
|
indices: typeof indices === 'number' ? [indices] : indices,
|
|
626
866
|
statusListName,
|
|
627
867
|
statusListVersion,
|
|
@@ -692,9 +932,18 @@ export class CredentialStatusController {
|
|
|
692
932
|
* /credential-status/update/encrypted:
|
|
693
933
|
* post:
|
|
694
934
|
* tags: [ Credential Status ]
|
|
695
|
-
* summary: Update an existing encrypted StatusList2021 credential status list.
|
|
935
|
+
* summary: Update an existing encrypted StatusList2021 or BitstringStatusList credential status list.
|
|
696
936
|
* parameters:
|
|
697
937
|
* - in: query
|
|
938
|
+
* name: listType
|
|
939
|
+
* description: The type of Status List.
|
|
940
|
+
* required: true
|
|
941
|
+
* schema:
|
|
942
|
+
* type: string
|
|
943
|
+
* enum:
|
|
944
|
+
* - StatusList2021
|
|
945
|
+
* - BitstringStatusList
|
|
946
|
+
* - in: query
|
|
698
947
|
* name: statusAction
|
|
699
948
|
* description: The update action to be performed on the encrypted status list, can be revoke, suspend or reinstate
|
|
700
949
|
* required: true
|
|
@@ -730,11 +979,11 @@ export class CredentialStatusController {
|
|
|
730
979
|
// collect request parameters - case: body
|
|
731
980
|
const { did, statusListName, statusListVersion, indices, symmetricKey, paymentConditions, feePaymentAddress, feePaymentAmount, feePaymentWindow, } = request.body;
|
|
732
981
|
// collect request parameters - case: query
|
|
733
|
-
const { statusAction } = request.query;
|
|
982
|
+
const { statusAction, listType } = request.query;
|
|
734
983
|
// define identity service strategy setup
|
|
735
984
|
const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
|
|
736
985
|
// ensure encrypted status list
|
|
737
|
-
const encrypted = await identityServiceStrategySetup.agent.
|
|
986
|
+
const encrypted = await identityServiceStrategySetup.agent.searchStatusList(did, statusListName, listType, DefaultStatusActionPurposeMap[statusAction]);
|
|
738
987
|
// handle error
|
|
739
988
|
if (encrypted.error) {
|
|
740
989
|
// handle notFound error
|
|
@@ -758,7 +1007,7 @@ export class CredentialStatusController {
|
|
|
758
1007
|
});
|
|
759
1008
|
try {
|
|
760
1009
|
// update encrypted status list
|
|
761
|
-
const result = (await identityServiceStrategySetup.agent.
|
|
1010
|
+
const result = (await identityServiceStrategySetup.agent.updateEncryptedStatusList(did, listType, {
|
|
762
1011
|
indices: typeof indices === 'number' ? [indices] : indices,
|
|
763
1012
|
statusListName,
|
|
764
1013
|
statusListVersion,
|
|
@@ -886,7 +1135,7 @@ export class CredentialStatusController {
|
|
|
886
1135
|
// define identity service strategy setup
|
|
887
1136
|
const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
|
|
888
1137
|
// ensure status list
|
|
889
|
-
const statusList = await identityServiceStrategySetup.agent.
|
|
1138
|
+
const statusList = await identityServiceStrategySetup.agent.searchStatusList(did, statusListName, StatusListType.StatusList2021, statusPurpose);
|
|
890
1139
|
// handle error
|
|
891
1140
|
if (statusList.error) {
|
|
892
1141
|
// handle notFound error
|
|
@@ -991,7 +1240,7 @@ export class CredentialStatusController {
|
|
|
991
1240
|
* /credential-status/search:
|
|
992
1241
|
* get:
|
|
993
1242
|
* tags: [ Credential Status ]
|
|
994
|
-
* summary: Fetch StatusList2021 DID-Linked Resource based on search criteria.
|
|
1243
|
+
* summary: Fetch StatusList2021 or BitstringStatusList DID-Linked Resource based on search criteria.
|
|
995
1244
|
* parameters:
|
|
996
1245
|
* - in: query
|
|
997
1246
|
* name: did
|
|
@@ -1000,8 +1249,18 @@ export class CredentialStatusController {
|
|
|
1000
1249
|
* schema:
|
|
1001
1250
|
* type: string
|
|
1002
1251
|
* - in: query
|
|
1252
|
+
* name: listType
|
|
1253
|
+
* description: The type of Status List.
|
|
1254
|
+
* required: true
|
|
1255
|
+
* schema:
|
|
1256
|
+
* type: string
|
|
1257
|
+
* enum:
|
|
1258
|
+
* - StatusList2021
|
|
1259
|
+
* - BitstringStatusList
|
|
1260
|
+
* - in: query
|
|
1003
1261
|
* name: statusPurpose
|
|
1004
1262
|
* description: The purpose of the status list. Can be either revocation or suspension.
|
|
1263
|
+
* required: true
|
|
1005
1264
|
* schema:
|
|
1006
1265
|
* type: string
|
|
1007
1266
|
* enum:
|
|
@@ -1009,7 +1268,8 @@ export class CredentialStatusController {
|
|
|
1009
1268
|
* - suspension
|
|
1010
1269
|
* - in: query
|
|
1011
1270
|
* name: statusListName
|
|
1012
|
-
* description: The name of the
|
|
1271
|
+
* description: The name of the Status List DID-Linked Resource.
|
|
1272
|
+
* required: true
|
|
1013
1273
|
* schema:
|
|
1014
1274
|
* type: string
|
|
1015
1275
|
* responses:
|
|
@@ -1028,10 +1288,10 @@ export class CredentialStatusController {
|
|
|
1028
1288
|
*/
|
|
1029
1289
|
async searchStatusList(request, response) {
|
|
1030
1290
|
// collect request parameters - case: query
|
|
1031
|
-
const { did, statusListName, statusPurpose } = request.query;
|
|
1291
|
+
const { did, statusListName, listType, statusPurpose } = request.query;
|
|
1032
1292
|
try {
|
|
1033
1293
|
// search status list
|
|
1034
|
-
const result = await new IdentityServiceStrategySetup().agent.
|
|
1294
|
+
const result = await new IdentityServiceStrategySetup().agent.searchStatusList(did, statusListName, listType, statusPurpose);
|
|
1035
1295
|
// handle error
|
|
1036
1296
|
if (result.error) {
|
|
1037
1297
|
// handle notFound error
|