@cheqd/studio 3.3.0 → 3.4.0-develop.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.
Files changed (55) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +7 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/controllers/api/accreditation.d.ts +227 -0
  5. package/dist/controllers/api/accreditation.d.ts.map +1 -0
  6. package/dist/controllers/api/accreditation.js +667 -0
  7. package/dist/controllers/api/accreditation.js.map +1 -0
  8. package/dist/controllers/validator/index.d.ts +1 -1
  9. package/dist/controllers/validator/index.d.ts.map +1 -1
  10. package/dist/controllers/validator/index.js +1 -1
  11. package/dist/controllers/validator/index.js.map +1 -1
  12. package/dist/helpers/helpers.d.ts +3 -0
  13. package/dist/helpers/helpers.d.ts.map +1 -1
  14. package/dist/helpers/helpers.js +17 -0
  15. package/dist/helpers/helpers.js.map +1 -1
  16. package/dist/middleware/auth/routes/api/accreditation-auth.d.ts +5 -0
  17. package/dist/middleware/auth/routes/api/accreditation-auth.d.ts.map +1 -0
  18. package/dist/middleware/auth/routes/api/accreditation-auth.js +21 -0
  19. package/dist/middleware/auth/routes/api/accreditation-auth.js.map +1 -0
  20. package/dist/middleware/authentication.d.ts.map +1 -1
  21. package/dist/middleware/authentication.js +2 -0
  22. package/dist/middleware/authentication.js.map +1 -1
  23. package/dist/services/api/accreditation.d.ts +11 -0
  24. package/dist/services/api/accreditation.d.ts.map +1 -0
  25. package/dist/services/api/accreditation.js +116 -0
  26. package/dist/services/api/accreditation.js.map +1 -0
  27. package/dist/services/api/credentials.d.ts +1 -1
  28. package/dist/services/api/credentials.d.ts.map +1 -1
  29. package/dist/services/api/credentials.js +10 -2
  30. package/dist/services/api/credentials.js.map +1 -1
  31. package/dist/services/connectors/resource.d.ts +22 -0
  32. package/dist/services/connectors/resource.d.ts.map +1 -0
  33. package/dist/services/connectors/resource.js +38 -0
  34. package/dist/services/connectors/resource.js.map +1 -0
  35. package/dist/services/w3c-credential.d.ts +1 -0
  36. package/dist/services/w3c-credential.d.ts.map +1 -1
  37. package/dist/services/w3c-credential.js +2 -0
  38. package/dist/services/w3c-credential.js.map +1 -1
  39. package/dist/static/swagger-api.json +616 -0
  40. package/dist/types/accreditation.d.ts +84 -0
  41. package/dist/types/accreditation.d.ts.map +1 -0
  42. package/dist/types/accreditation.js +23 -0
  43. package/dist/types/accreditation.js.map +1 -0
  44. package/dist/types/constants.d.ts.map +1 -1
  45. package/dist/types/constants.js +1 -1
  46. package/dist/types/constants.js.map +1 -1
  47. package/dist/types/credential.d.ts +10 -4
  48. package/dist/types/credential.d.ts.map +1 -1
  49. package/dist/types/credential.js +5 -1
  50. package/dist/types/credential.js.map +1 -1
  51. package/dist/types/swagger-api-types.d.ts +233 -0
  52. package/dist/types/swagger-api-types.d.ts.map +1 -1
  53. package/dist/types/swagger-api-types.js +233 -0
  54. package/dist/types/swagger-api-types.js.map +1 -1
  55. package/package.json +21 -21
@@ -0,0 +1,667 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { StatusCodes } from 'http-status-codes';
8
+ import { v4 } from 'uuid';
9
+ import { AccreditationRequestType, DIDAccreditationTypes } from '../../types/accreditation.js';
10
+ import { CredentialConnectors } from '../../types/credential.js';
11
+ import { OperationCategoryNameEnum, OperationNameEnum } from '../../types/constants.js';
12
+ import { IdentityServiceStrategySetup } from '../../services/identity/index.js';
13
+ import { AccreditationService } from '../../services/api/accreditation.js';
14
+ import { Credentials } from '../../services/api/credentials.js';
15
+ import { eventTracker } from '../../services/track/tracker.js';
16
+ import { body, query } from '../validator/index.js';
17
+ import { validate } from '../validator/decorator.js';
18
+ import { constructDidUrl, parseDidFromDidUrl } from '../../helpers/helpers.js';
19
+ export class AccreditationController {
20
+ static issueValidator = [
21
+ query('accreditationType')
22
+ .exists()
23
+ .isIn([
24
+ AccreditationRequestType.authorize,
25
+ AccreditationRequestType.accredit,
26
+ AccreditationRequestType.attest,
27
+ ])
28
+ .bail(),
29
+ body('accreditationName').exists().isString().withMessage('accreditationName is required').bail(),
30
+ body('issuerDid').exists().isDID().bail(),
31
+ body('subjectDid').exists().isDID().bail(),
32
+ body('schemas').exists().isArray().withMessage('schemas must be a array').bail(),
33
+ body('schemas.*.url').isString().withMessage('schema urls must be a string').bail(),
34
+ body('schemas.*.type')
35
+ .custom((value) => typeof value === 'string' || (Array.isArray(value) && typeof value[0] === 'string'))
36
+ .withMessage('schema type must be a string'),
37
+ body('parentAccreditation').optional().isString().withMessage('parentAccreditation must be a string').bail(),
38
+ body('rootAuthorization').optional().isString().withMessage('rootAuthorization must be a string').bail(),
39
+ body('trustFramework').optional().isString().withMessage('trustFramework must be a string').bail(),
40
+ body('trustFrameworkId').optional().isString().withMessage('trustFrameworkId must be a string').bail(),
41
+ query('accreditationType')
42
+ .custom((value, { req }) => {
43
+ const { parentAccreditation, rootAuthorization, trustFramework, trustFrameworkId } = req.body;
44
+ const hasParentOrRoot = parentAccreditation || rootAuthorization;
45
+ if (!hasParentOrRoot &&
46
+ (value === AccreditationRequestType.accredit || value === AccreditationRequestType.attest)) {
47
+ throw new Error('parentAccreditation or rootAuthorization is required');
48
+ }
49
+ if (hasParentOrRoot && value === AccreditationRequestType.authorize) {
50
+ throw new Error('parentAccreditation or rootAuthorization is not required for an authorize operation');
51
+ }
52
+ const hasTrustFramework = trustFramework && trustFrameworkId;
53
+ if (!hasTrustFramework && value === AccreditationRequestType.authorize) {
54
+ throw new Error('trustFramework and trustFrameworkId are required for an authorize operation');
55
+ }
56
+ return true;
57
+ })
58
+ .bail(),
59
+ body('accreditationName').exists().isString(),
60
+ ];
61
+ static verifyValidator = [
62
+ body('did').optional().isDID().bail(),
63
+ body('didUrl')
64
+ .optional()
65
+ .isString()
66
+ .custom((value) => value.includes('/resources/') || value.includes('?resourceName'))
67
+ .withMessage('didUrls should point to a unique DID Linked Resource')
68
+ .bail(),
69
+ body('resourceId').optional().isUUID().withMessage('resourceId should be a string').bail(),
70
+ body('resourceName').optional().isString().withMessage('resourceName should be a string').bail(),
71
+ body('resourceType').optional().isString().withMessage('resourceType should be a string').bail(),
72
+ body('schemas').optional().isArray().withMessage('schemas must be a array').bail(),
73
+ body('schemas.*.url').isString().withMessage('schema urls must be a string').bail(),
74
+ body('schemas.*.type')
75
+ .custom((value) => typeof value === 'string' || (Array.isArray(value) && typeof value[0] === 'string'))
76
+ .withMessage('schema type must be a string'),
77
+ body('did')
78
+ .custom((value, { req }) => {
79
+ const { didUrl, resourceId, resourceName, resourceType } = req.body;
80
+ if (!value && !didUrl) {
81
+ throw new Error('Either "did" or "didUrl" is required');
82
+ }
83
+ // If did is provided, ensure either resourceId or both resourceName and resourceType are provided
84
+ if (value && !(resourceId || (resourceName && resourceType))) {
85
+ throw new Error('Either "resourceId" or both "resourceName" and "resourceType" are required');
86
+ }
87
+ return true;
88
+ })
89
+ .bail(),
90
+ body('subjectDid').exists().isDID().bail(),
91
+ query('verifyStatus')
92
+ .optional()
93
+ .isBoolean()
94
+ .withMessage('verifyStatus should be a boolean value')
95
+ .toBoolean()
96
+ .bail(),
97
+ query('allowDeactivatedDid')
98
+ .optional()
99
+ .isBoolean()
100
+ .withMessage('allowDeactivatedDid should be a boolean value')
101
+ .toBoolean()
102
+ .bail(),
103
+ query('policies').optional().isObject().withMessage('Verification policies should be an object').bail(),
104
+ ];
105
+ static publishValidator = [
106
+ query('publish').optional().isBoolean().withMessage('publish should be a boolean value').toBoolean().bail(),
107
+ ];
108
+ /**
109
+ * @openapi
110
+ *
111
+ * /trust-registry/accreditation/issue:
112
+ * post:
113
+ * tags: [ Trust Registry ]
114
+ * summary: Publish a verifiable accreditation for a DID.
115
+ * description: Generate and publish a Verifiable Accreditation for a subject DID as a DID Linked resource.
116
+ * operationId: accredit-issue
117
+ * parameters:
118
+ * - in: query
119
+ * name: accreditationType
120
+ * description: Select the type of accreditation to be issued.
121
+ * schema:
122
+ * type: string
123
+ * enum:
124
+ * - authorize
125
+ * - accredit
126
+ * - attest
127
+ * required: true
128
+ * requestBody:
129
+ * content:
130
+ * application/x-www-form-urlencoded:
131
+ * schema:
132
+ * $ref: '#/components/schemas/AccreditationIssueRequest'
133
+ * application/json:
134
+ * schema:
135
+ * $ref: '#/components/schemas/AccreditationIssueRequest'
136
+ * responses:
137
+ * 200:
138
+ * description: The request was successful.
139
+ * content:
140
+ * application/json:
141
+ * schema:
142
+ * $ref: '#/components/schemas/Credential'
143
+ * 400:
144
+ * $ref: '#/components/schemas/InvalidRequest'
145
+ * 401:
146
+ * $ref: '#/components/schemas/UnauthorizedError'
147
+ * 500:
148
+ * $ref: '#/components/schemas/InternalError'
149
+ */
150
+ async issue(request, response) {
151
+ // Get strategy e.g. postgres or local
152
+ const identityServiceStrategySetup = new IdentityServiceStrategySetup();
153
+ // Extract did from params
154
+ const { accreditationType } = request.query;
155
+ // Handles string input instead of an array
156
+ if (typeof request.body.type === 'string') {
157
+ request.body.type = [request.body.type];
158
+ }
159
+ if (typeof request.body['@context'] === 'string') {
160
+ request.body['@context'] = [request.body['@context']];
161
+ }
162
+ const { issuerDid, subjectDid, schemas, type, parentAccreditation, rootAuthorization, trustFramework, trustFrameworkId, attributes, accreditationName, format, credentialStatus, } = request.body;
163
+ try {
164
+ // Validate issuer DID
165
+ const resolvedResult = await identityServiceStrategySetup.agent.resolve(issuerDid);
166
+ // check if DID-Document is resolved
167
+ const body = await resolvedResult.json();
168
+ if (!body?.didDocument) {
169
+ return response.status(StatusCodes.BAD_REQUEST).send({
170
+ error: `DID ${issuerDid} is not resolved because of error from resolver: ${body.didResolutionMetadata.error}.`,
171
+ });
172
+ }
173
+ if (body.didDocumentMetadata.deactivated) {
174
+ return response.status(StatusCodes.BAD_REQUEST).send({
175
+ error: `${issuerDid} is deactivated`,
176
+ });
177
+ }
178
+ // Validate subject DID
179
+ const res = await identityServiceStrategySetup.agent.resolve(subjectDid);
180
+ const subjectDidRes = await res.json();
181
+ if (!subjectDidRes?.didDocument) {
182
+ return response.status(StatusCodes.BAD_REQUEST).send({
183
+ error: `DID ${subjectDid} is not resolved because of error from resolver: ${body.didResolutionMetadata.error}.`,
184
+ });
185
+ }
186
+ if (subjectDidRes.didDocumentMetadata.deactivated) {
187
+ return response.status(StatusCodes.BAD_REQUEST).send({
188
+ error: `${subjectDid} is deactivated`,
189
+ });
190
+ }
191
+ const resourceId = v4();
192
+ const accreditedFor = schemas.map(({ url, type }) => ({
193
+ schemaId: url,
194
+ type,
195
+ }));
196
+ // construct credential request
197
+ const credentialRequest = {
198
+ subjectDid,
199
+ attributes: {
200
+ ...attributes,
201
+ accreditedFor,
202
+ id: subjectDid,
203
+ },
204
+ issuerDid,
205
+ format: format || 'jwt',
206
+ connector: CredentialConnectors.Resource, // resource connector
207
+ credentialId: resourceId,
208
+ credentialName: accreditationName,
209
+ credentialStatus,
210
+ };
211
+ let resourceType;
212
+ switch (accreditationType) {
213
+ case AccreditationRequestType.authorize:
214
+ resourceType = DIDAccreditationTypes.VerifiableAuthorisationForTrustChain;
215
+ credentialRequest.type = [...(type || []), resourceType];
216
+ credentialRequest.termsOfUse = {
217
+ type: resourceType,
218
+ trustFramework,
219
+ trustFrameworkId,
220
+ };
221
+ break;
222
+ case AccreditationRequestType.accredit:
223
+ resourceType = DIDAccreditationTypes.VerifiableAccreditationToAccredit;
224
+ credentialRequest.type = [...(type || []), resourceType];
225
+ credentialRequest.termsOfUse = {
226
+ type: resourceType,
227
+ parentAccreditation,
228
+ rootAuthorization,
229
+ };
230
+ break;
231
+ case AccreditationRequestType.attest:
232
+ resourceType = DIDAccreditationTypes.VerifiableAccreditationToAttest;
233
+ credentialRequest.type = [...(type || []), resourceType];
234
+ credentialRequest.termsOfUse = {
235
+ type: resourceType,
236
+ parentAccreditation,
237
+ rootAuthorization,
238
+ };
239
+ break;
240
+ }
241
+ // validate parent and root accreditations
242
+ if (accreditationType === AccreditationRequestType.accredit ||
243
+ accreditationType === AccreditationRequestType.attest) {
244
+ const result = await AccreditationService.instance.verify_accreditation(issuerDid, parentAccreditation, accreditedFor, true, false, response.locals.customer, rootAuthorization);
245
+ if (result.success === false) {
246
+ return response.status(result.status).send({
247
+ error: `Invalid Request: Root Authorization or parent Accreditation is not valid: ${result.error}`,
248
+ });
249
+ }
250
+ }
251
+ // issue accreditation
252
+ const accreditation = await Credentials.instance.issue_credential(credentialRequest, response.locals.customer);
253
+ // Track operation
254
+ const trackInfo = {
255
+ category: OperationCategoryNameEnum.CREDENTIAL,
256
+ name: OperationNameEnum.CREDENTIAL_ISSUE,
257
+ customer: response.locals.customer,
258
+ user: response.locals.user,
259
+ data: {
260
+ did: issuerDid,
261
+ },
262
+ };
263
+ eventTracker.emit('track', trackInfo);
264
+ return response.status(StatusCodes.OK).json({
265
+ didUrls: [
266
+ `${issuerDid}/resources/${resourceId}`,
267
+ `${issuerDid}?resourceName=${accreditationName}&resourceType=${credentialRequest.type}`,
268
+ ],
269
+ accreditation,
270
+ });
271
+ }
272
+ catch (error) {
273
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
274
+ error: `Internal error: ${error?.message || error}`,
275
+ });
276
+ }
277
+ }
278
+ /**
279
+ * @openapi
280
+ *
281
+ * /trust-registry/accreditation/verify:
282
+ * post:
283
+ * tags: [ Trust Registry ]
284
+ * summary: Verify a verifiable accreditation for a DID.
285
+ * description: Generate and publish a Verifiable Accreditation for a subject DID as a DID Linked resource.
286
+ * operationId: accredit-verify
287
+ * parameters:
288
+ * - in: query
289
+ * name: verifyStatus
290
+ * description: If set to `true` the verification will also check the status of the accreditation. Requires the VC to have a `credentialStatus` property.
291
+ * schema:
292
+ * type: boolean
293
+ * default: false
294
+ * - in: query
295
+ * name: allowDeactivatedDid
296
+ * description: If set to `true` allow to verify accreditation which based on deactivated DID.
297
+ * schema:
298
+ * type: boolean
299
+ * default: false
300
+ * requestBody:
301
+ * content:
302
+ * application/x-www-form-urlencoded:
303
+ * schema:
304
+ * $ref: '#/components/schemas/AccreditationVerifyRequest'
305
+ * application/json:
306
+ * schema:
307
+ * $ref: '#/components/schemas/AccreditationVerifyRequest'
308
+ * responses:
309
+ * 200:
310
+ * description: The request was successful.
311
+ * content:
312
+ * application/json:
313
+ * schema:
314
+ * $ref: '#/components/schemas/Credential'
315
+ * 400:
316
+ * $ref: '#/components/schemas/InvalidRequest'
317
+ * 401:
318
+ * $ref: '#/components/schemas/UnauthorizedError'
319
+ * 500:
320
+ * $ref: '#/components/schemas/InternalError'
321
+ */
322
+ async verify(request, response) {
323
+ // Extract did from params
324
+ let { verifyStatus = false, allowDeactivatedDid = false } = request.query;
325
+ const { policies, subjectDid, schemas } = request.body;
326
+ // construct didUrl
327
+ const didUrl = constructDidUrl(request.body);
328
+ if (!didUrl) {
329
+ return response.status(400).json({
330
+ error: `Invalid Request: Either didUrl or did with resource attributes are required`,
331
+ });
332
+ }
333
+ try {
334
+ const accreditedFor = schemas?.map(({ url, type }) => ({
335
+ schemaId: url,
336
+ type,
337
+ }));
338
+ const result = await AccreditationService.instance.verify_accreditation(subjectDid, didUrl, accreditedFor, verifyStatus, allowDeactivatedDid, response.locals.customer, undefined, policies);
339
+ // Track operation
340
+ const trackInfo = {
341
+ category: OperationCategoryNameEnum.CREDENTIAL,
342
+ name: OperationNameEnum.CREDENTIAL_VERIFY,
343
+ customer: response.locals.customer,
344
+ user: response.locals.user,
345
+ data: {
346
+ did: parseDidFromDidUrl(didUrl),
347
+ },
348
+ };
349
+ eventTracker.emit('track', trackInfo);
350
+ if (result.success) {
351
+ return response.status(StatusCodes.OK).json(result.data);
352
+ }
353
+ else {
354
+ return response.status(result.status).json({ verified: false, error: result.error });
355
+ }
356
+ }
357
+ catch (error) {
358
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
359
+ error: `Internal error: ${error?.message || error}`,
360
+ });
361
+ }
362
+ }
363
+ /**
364
+ * @openapi
365
+ *
366
+ * /trust-registry/accreditation/revoke:
367
+ * post:
368
+ * tags: [ Trust Registry ]
369
+ * summary: Revoke a Verifiable Accreditation.
370
+ * description: This endpoint revokes a given Verifiable Accreditation. As input, it can take the didUrl as a string. The StatusList2021 resource should already be setup in the VC and `credentialStatus` property present in the VC.
371
+ * operationId: accredit-revoke
372
+ * parameters:
373
+ * - in: query
374
+ * name: publish
375
+ * description: Set whether the StatusList2021 resource should be published to the ledger or not. If set to `false`, the StatusList2021 publisher should manually publish the resource.
376
+ * required: true
377
+ * schema:
378
+ * type: boolean
379
+ * default: true
380
+ * requestBody:
381
+ * content:
382
+ * application/x-www-form-urlencoded:
383
+ * schema:
384
+ * $ref: '#/components/schemas/AccreditationRevokeRequest'
385
+ * application/json:
386
+ * schema:
387
+ * $ref: '#/components/schemas/AccreditationRevokeRequest'
388
+ * responses:
389
+ * 200:
390
+ * description: The request was successful.
391
+ * content:
392
+ * application/json:
393
+ * schema:
394
+ * $ref: '#/components/schemas/RevocationResult'
395
+ * 400:
396
+ * $ref: '#/components/schemas/InvalidRequest'
397
+ * 401:
398
+ * $ref: '#/components/schemas/UnauthorizedError'
399
+ * 500:
400
+ * $ref: '#/components/schemas/InternalError'
401
+ */
402
+ async revoke(request, response) {
403
+ // Get publish flag
404
+ const { publish } = request.query;
405
+ // Get symmetric key
406
+ const { symmetricKey, ...didUrlParams } = request.body;
407
+ // Get strategy e.g. postgres or local
408
+ const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
409
+ const didUrl = constructDidUrl(didUrlParams);
410
+ if (!didUrl) {
411
+ return response.status(400).json({
412
+ error: `Invalid Request: Either didUrl or did with resource attributes are required`,
413
+ });
414
+ }
415
+ try {
416
+ const res = await identityServiceStrategySetup.agent.resolve(didUrl);
417
+ const resource = await res.json();
418
+ if (resource.dereferencingMetadata) {
419
+ return {
420
+ success: false,
421
+ status: 404,
422
+ error: `DID URL ${didUrl} is not found`,
423
+ };
424
+ }
425
+ const accreditation = resource;
426
+ const result = await identityServiceStrategySetup.agent.revokeCredentials(accreditation, publish, response.locals.customer, symmetricKey);
427
+ // Track operation if revocation was successful and publish is true
428
+ // Otherwise the StatusList2021 publisher should manually publish the resource
429
+ // and it will be tracked there
430
+ if (!result.error && result.resourceMetadata && publish) {
431
+ // get issuer did
432
+ const issuerDid = typeof accreditation.issuer === 'string'
433
+ ? accreditation.issuer
434
+ : accreditation.issuer.id;
435
+ const trackInfo = {
436
+ category: OperationCategoryNameEnum.CREDENTIAL,
437
+ name: OperationNameEnum.CREDENTIAL_REVOKE,
438
+ customer: response.locals.customer,
439
+ user: response.locals.user,
440
+ data: {
441
+ did: issuerDid,
442
+ encrypted: result.statusList?.metadata?.encrypted,
443
+ resource: result.resourceMetadata,
444
+ symmetricKey: '',
445
+ },
446
+ };
447
+ // Track operation
448
+ eventTracker.emit('track', trackInfo);
449
+ }
450
+ // Return Ok response
451
+ return response.status(StatusCodes.OK).json(result);
452
+ }
453
+ catch (error) {
454
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
455
+ error: `Internal error: ${error?.message || error}`,
456
+ });
457
+ }
458
+ }
459
+ /**
460
+ * @openapi
461
+ *
462
+ * /trust-registry/accreditation/suspend:
463
+ * post:
464
+ * tags: [ Trust Registry ]
465
+ * summary: Suspend a Verifiable Accreditation.
466
+ * description: This endpoint suspends a given Verifiable Accreditation. As input, it can take the didUrl as a string. The StatusList2021 resource should already be setup in the VC and `credentialStatus` property present in the VC.
467
+ * operationId: accredit-suspend
468
+ * parameters:
469
+ * - in: query
470
+ * name: publish
471
+ * description: Set whether the StatusList2021 resource should be published to the ledger or not. If set to `false`, the StatusList2021 publisher should manually publish the resource.
472
+ * required: true
473
+ * schema:
474
+ * type: boolean
475
+ * default: true
476
+ * requestBody:
477
+ * content:
478
+ * application/x-www-form-urlencoded:
479
+ * schema:
480
+ * $ref: '#/components/schemas/AccreditationRevokeRequest'
481
+ * application/json:
482
+ * schema:
483
+ * $ref: '#/components/schemas/AccreditationRevokeRequest'
484
+ * responses:
485
+ * 200:
486
+ * description: The request was successful.
487
+ * content:
488
+ * application/json:
489
+ * schema:
490
+ * $ref: '#/components/schemas/RevocationResult'
491
+ * 400:
492
+ * $ref: '#/components/schemas/InvalidRequest'
493
+ * 401:
494
+ * $ref: '#/components/schemas/UnauthorizedError'
495
+ * 500:
496
+ * $ref: '#/components/schemas/InternalError'
497
+ */
498
+ async suspend(request, response) {
499
+ // Get publish flag
500
+ const { publish } = request.query;
501
+ // Get symmetric key
502
+ const { symmetricKey, ...didUrlParams } = request.body;
503
+ // Get strategy e.g. postgres or local
504
+ const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
505
+ const didUrl = constructDidUrl(didUrlParams);
506
+ if (!didUrl) {
507
+ return response.status(400).json({
508
+ error: `Invalid Request: Either didUrl or did with resource attributes are required`,
509
+ });
510
+ }
511
+ try {
512
+ const res = await identityServiceStrategySetup.agent.resolve(didUrl);
513
+ const resource = await res.json();
514
+ if (resource.dereferencingMetadata) {
515
+ return {
516
+ success: false,
517
+ status: 404,
518
+ error: `DID URL ${didUrl} is not found`,
519
+ };
520
+ }
521
+ const accreditation = resource;
522
+ const result = await identityServiceStrategySetup.agent.suspendCredentials(accreditation, publish, response.locals.customer, symmetricKey);
523
+ // Track operation if revocation was successful and publish is true
524
+ // Otherwise the StatusList2021 publisher should manually publish the resource
525
+ // and it will be tracked there
526
+ if (!result.error && result.resourceMetadata && publish) {
527
+ // get issuer did
528
+ const issuerDid = typeof accreditation.issuer === 'string'
529
+ ? accreditation.issuer
530
+ : accreditation.issuer.id;
531
+ const trackInfo = {
532
+ category: OperationCategoryNameEnum.CREDENTIAL,
533
+ name: OperationNameEnum.CREDENTIAL_SUSPEND,
534
+ customer: response.locals.customer,
535
+ user: response.locals.user,
536
+ data: {
537
+ did: issuerDid,
538
+ encrypted: result.statusList?.metadata?.encrypted,
539
+ resource: result.resourceMetadata,
540
+ symmetricKey: '',
541
+ },
542
+ };
543
+ // Track operation
544
+ eventTracker.emit('track', trackInfo);
545
+ }
546
+ // Return Ok response
547
+ return response.status(StatusCodes.OK).json(result);
548
+ }
549
+ catch (error) {
550
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
551
+ error: `Internal error: ${error?.message || error}`,
552
+ });
553
+ }
554
+ }
555
+ /**
556
+ * @openapi
557
+ *
558
+ * /trust-registry/accreditation/reinstate:
559
+ * post:
560
+ * tags: [ Trust Registry ]
561
+ * summary: Reinstate a Verifiable Accreditation.
562
+ * description: This endpoint reinstates a given Verifiable Accreditation. As input, it can take the didUrl as a string. The StatusList2021 resource should already be setup in the VC and `credentialStatus` property present in the VC.
563
+ * operationId: accredit-reinstate
564
+ * parameters:
565
+ * - in: query
566
+ * name: publish
567
+ * description: Set whether the StatusList2021 resource should be published to the ledger or not. If set to `false`, the StatusList2021 publisher should manually publish the resource.
568
+ * required: true
569
+ * schema:
570
+ * type: boolean
571
+ * default: true
572
+ * requestBody:
573
+ * content:
574
+ * application/x-www-form-urlencoded:
575
+ * schema:
576
+ * $ref: '#/components/schemas/AccreditationRevokeRequest'
577
+ * application/json:
578
+ * schema:
579
+ * $ref: '#/components/schemas/AccreditationRevokeRequest'
580
+ * responses:
581
+ * 200:
582
+ * description: The request was successful.
583
+ * content:
584
+ * application/json:
585
+ * schema:
586
+ * $ref: '#/components/schemas/RevocationResult'
587
+ * 400:
588
+ * $ref: '#/components/schemas/InvalidRequest'
589
+ * 401:
590
+ * $ref: '#/components/schemas/UnauthorizedError'
591
+ * 500:
592
+ * $ref: '#/components/schemas/InternalError'
593
+ */
594
+ async reinstate(request, response) {
595
+ // Get publish flag
596
+ const { publish } = request.query;
597
+ // Get symmetric key
598
+ const { symmetricKey, ...didUrlParams } = request.body;
599
+ // Get strategy e.g. postgres or local
600
+ const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
601
+ const didUrl = constructDidUrl(didUrlParams);
602
+ if (!didUrl) {
603
+ return response.status(400).json({
604
+ error: `Invalid Request: Either didUrl or did with resource attributes are required`,
605
+ });
606
+ }
607
+ try {
608
+ const res = await identityServiceStrategySetup.agent.resolve(didUrl);
609
+ const resource = await res.json();
610
+ if (resource.dereferencingMetadata) {
611
+ return {
612
+ success: false,
613
+ status: 404,
614
+ error: `DID URL ${didUrl} is not found`,
615
+ };
616
+ }
617
+ const accreditation = resource;
618
+ const result = await identityServiceStrategySetup.agent.reinstateCredentials(accreditation, publish, response.locals.customer, symmetricKey);
619
+ // Track operation if revocation was successful and publish is true
620
+ // Otherwise the StatusList2021 publisher should manually publish the resource
621
+ // and it will be tracked there
622
+ if (!result.error && result.resourceMetadata && publish) {
623
+ // get issuer did
624
+ const issuerDid = typeof accreditation.issuer === 'string'
625
+ ? accreditation.issuer
626
+ : accreditation.issuer.id;
627
+ const trackInfo = {
628
+ category: OperationCategoryNameEnum.CREDENTIAL,
629
+ name: OperationNameEnum.CREDENTIAL_UNSUSPEND,
630
+ customer: response.locals.customer,
631
+ user: response.locals.user,
632
+ data: {
633
+ did: issuerDid,
634
+ encrypted: result.statusList?.metadata?.encrypted || false,
635
+ resource: result.resourceMetadata,
636
+ symmetricKey: '',
637
+ },
638
+ };
639
+ // Track operation
640
+ eventTracker.emit('track', trackInfo);
641
+ }
642
+ // Return Ok response
643
+ return response.status(StatusCodes.OK).json(result);
644
+ }
645
+ catch (error) {
646
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
647
+ error: `Internal error: ${error?.message || error}`,
648
+ });
649
+ }
650
+ }
651
+ }
652
+ __decorate([
653
+ validate
654
+ ], AccreditationController.prototype, "issue", null);
655
+ __decorate([
656
+ validate
657
+ ], AccreditationController.prototype, "verify", null);
658
+ __decorate([
659
+ validate
660
+ ], AccreditationController.prototype, "revoke", null);
661
+ __decorate([
662
+ validate
663
+ ], AccreditationController.prototype, "suspend", null);
664
+ __decorate([
665
+ validate
666
+ ], AccreditationController.prototype, "reinstate", null);
667
+ //# sourceMappingURL=accreditation.js.map