@cheqd/studio 3.15.0-develop.1 → 3.15.0-develop.3

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 (138) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +4 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/controllers/api/accreditation.d.ts.map +1 -1
  5. package/dist/controllers/api/accreditation.js +36 -9
  6. package/dist/controllers/api/accreditation.js.map +1 -1
  7. package/dist/controllers/api/credential-status.d.ts +94 -0
  8. package/dist/controllers/api/credential-status.d.ts.map +1 -1
  9. package/dist/controllers/api/credential-status.js +220 -506
  10. package/dist/controllers/api/credential-status.js.map +1 -1
  11. package/dist/controllers/api/credential.d.ts +66 -0
  12. package/dist/controllers/api/credential.d.ts.map +1 -1
  13. package/dist/controllers/api/credential.js +117 -1
  14. package/dist/controllers/api/credential.js.map +1 -1
  15. package/dist/controllers/api/did.js.map +1 -1
  16. package/dist/controllers/api/key.d.ts +71 -1
  17. package/dist/controllers/api/key.d.ts.map +1 -1
  18. package/dist/controllers/api/key.js +113 -2
  19. package/dist/controllers/api/key.js.map +1 -1
  20. package/dist/controllers/api/presentation.js +22 -21
  21. package/dist/controllers/api/presentation.js.map +1 -1
  22. package/dist/controllers/api/providers.controller.js.map +1 -1
  23. package/dist/controllers/api/resource.js.map +1 -1
  24. package/dist/controllers/validator/did.js +1 -1
  25. package/dist/controllers/validator/did.js.map +1 -1
  26. package/dist/database/entities/issued-credential.entity.d.ts +10 -1
  27. package/dist/database/entities/issued-credential.entity.d.ts.map +1 -1
  28. package/dist/database/entities/issued-credential.entity.js +22 -0
  29. package/dist/database/entities/issued-credential.entity.js.map +1 -1
  30. package/dist/database/entities/status-registry.entity.d.ts +60 -0
  31. package/dist/database/entities/status-registry.entity.d.ts.map +1 -0
  32. package/dist/database/entities/status-registry.entity.js +145 -0
  33. package/dist/database/entities/status-registry.entity.js.map +1 -0
  34. package/dist/database/migrations/1761834657128-studio-migrations.d.ts +7 -0
  35. package/dist/database/migrations/1761834657128-studio-migrations.d.ts.map +1 -0
  36. package/dist/database/migrations/1761834657128-studio-migrations.js +14 -0
  37. package/dist/database/migrations/1761834657128-studio-migrations.js.map +1 -0
  38. package/dist/database/migrations/1762775396083-MigrateStatusLists.d.ts +25 -0
  39. package/dist/database/migrations/1762775396083-MigrateStatusLists.d.ts.map +1 -0
  40. package/dist/database/migrations/1762775396083-MigrateStatusLists.js +243 -0
  41. package/dist/database/migrations/1762775396083-MigrateStatusLists.js.map +1 -0
  42. package/dist/database/migrations/1762775500000-UpdateWriteCursors.d.ts +23 -0
  43. package/dist/database/migrations/1762775500000-UpdateWriteCursors.d.ts.map +1 -0
  44. package/dist/database/migrations/1762775500000-UpdateWriteCursors.js +181 -0
  45. package/dist/database/migrations/1762775500000-UpdateWriteCursors.js.map +1 -0
  46. package/dist/database/types/types.d.ts.map +1 -1
  47. package/dist/database/types/types.js +10 -0
  48. package/dist/database/types/types.js.map +1 -1
  49. package/dist/helpers/mailchimp.d.ts.map +1 -1
  50. package/dist/helpers/mailchimp.js +1 -3
  51. package/dist/helpers/mailchimp.js.map +1 -1
  52. package/dist/middleware/auth/routes/api/credential-status-auth.d.ts.map +1 -1
  53. package/dist/middleware/auth/routes/api/credential-status-auth.js +2 -0
  54. package/dist/middleware/auth/routes/api/credential-status-auth.js.map +1 -1
  55. package/dist/middleware/auth/routes/api/key-auth.d.ts.map +1 -1
  56. package/dist/middleware/auth/routes/api/key-auth.js +1 -0
  57. package/dist/middleware/auth/routes/api/key-auth.js.map +1 -1
  58. package/dist/services/api/credential-status.d.ts +107 -0
  59. package/dist/services/api/credential-status.d.ts.map +1 -0
  60. package/dist/services/api/credential-status.js +923 -0
  61. package/dist/services/api/credential-status.js.map +1 -0
  62. package/dist/services/api/credentials.d.ts +12 -0
  63. package/dist/services/api/credentials.d.ts.map +1 -1
  64. package/dist/services/api/credentials.js +330 -117
  65. package/dist/services/api/credentials.js.map +1 -1
  66. package/dist/services/connectors/resource.js.map +1 -1
  67. package/dist/services/identity/abstract.d.ts +1 -1
  68. package/dist/services/identity/abstract.d.ts.map +1 -1
  69. package/dist/services/identity/abstract.js +1 -1
  70. package/dist/services/identity/abstract.js.map +1 -1
  71. package/dist/services/identity/default.d.ts +1 -1
  72. package/dist/services/identity/default.d.ts.map +1 -1
  73. package/dist/services/identity/default.js +2 -2
  74. package/dist/services/identity/default.js.map +1 -1
  75. package/dist/services/identity/index.d.ts +1 -1
  76. package/dist/services/identity/index.d.ts.map +1 -1
  77. package/dist/services/identity/providers/studio/agent.d.ts +6 -6
  78. package/dist/services/identity/providers/studio/agent.d.ts.map +1 -1
  79. package/dist/services/identity/providers/studio/agent.js +11 -2
  80. package/dist/services/identity/providers/studio/agent.js.map +1 -1
  81. package/dist/services/identity/providers/studio/local.d.ts +3 -3
  82. package/dist/services/identity/providers/studio/postgres.d.ts +3 -3
  83. package/dist/services/identity/providers/studio/postgres.d.ts.map +1 -1
  84. package/dist/services/identity/providers/studio/postgres.js +0 -12
  85. package/dist/services/identity/providers/studio/postgres.js.map +1 -1
  86. package/dist/services/track/api/credential-status-subscriber.d.ts +4 -4
  87. package/dist/services/track/api/credential-status-subscriber.d.ts.map +1 -1
  88. package/dist/services/track/api/credential-status-subscriber.js +18 -1
  89. package/dist/services/track/api/credential-status-subscriber.js.map +1 -1
  90. package/dist/services/track/api/credential-subscriber.d.ts +4 -4
  91. package/dist/services/track/api/credential-subscriber.d.ts.map +1 -1
  92. package/dist/services/track/api/credential-subscriber.js.map +1 -1
  93. package/dist/services/track/api/did-subscriber.d.ts +4 -4
  94. package/dist/services/track/api/did-subscriber.d.ts.map +1 -1
  95. package/dist/services/track/api/did-subscriber.js.map +1 -1
  96. package/dist/services/track/api/key-subscriber.d.ts +4 -4
  97. package/dist/services/track/api/key-subscriber.d.ts.map +1 -1
  98. package/dist/services/track/api/key-subscriber.js.map +1 -1
  99. package/dist/services/track/api/presentation-subscriber.d.ts +4 -4
  100. package/dist/services/track/api/presentation-subscriber.d.ts.map +1 -1
  101. package/dist/services/track/api/presentation-subscriber.js.map +1 -1
  102. package/dist/services/track/api/resource-subscriber.d.ts +4 -4
  103. package/dist/services/track/api/resource-subscriber.d.ts.map +1 -1
  104. package/dist/services/track/api/resource-subscriber.js.map +1 -1
  105. package/dist/services/track/base.d.ts +2 -2
  106. package/dist/services/track/base.d.ts.map +1 -1
  107. package/dist/services/track/base.js.map +1 -1
  108. package/dist/services/track/operation-subscriber.d.ts +4 -4
  109. package/dist/services/track/operation-subscriber.d.ts.map +1 -1
  110. package/dist/services/track/operation-subscriber.js.map +1 -1
  111. package/dist/services/track/tracker.d.ts +2 -2
  112. package/dist/services/track/tracker.d.ts.map +1 -1
  113. package/dist/services/track/tracker.js.map +1 -1
  114. package/dist/services/track/types.d.ts +2 -2
  115. package/dist/services/track/types.d.ts.map +1 -1
  116. package/dist/static/swagger-api.json +684 -67
  117. package/dist/types/accreditation.d.ts +3 -0
  118. package/dist/types/accreditation.d.ts.map +1 -1
  119. package/dist/types/constants.d.ts +2 -0
  120. package/dist/types/constants.d.ts.map +1 -1
  121. package/dist/types/constants.js +2 -0
  122. package/dist/types/constants.js.map +1 -1
  123. package/dist/types/credential-status.d.ts +39 -1
  124. package/dist/types/credential-status.d.ts.map +1 -1
  125. package/dist/types/credential-status.js +7 -0
  126. package/dist/types/credential-status.js.map +1 -1
  127. package/dist/types/credential.d.ts +21 -3
  128. package/dist/types/credential.d.ts.map +1 -1
  129. package/dist/types/credential.js +5 -0
  130. package/dist/types/credential.js.map +1 -1
  131. package/dist/types/swagger-api-types.d.ts +242 -39
  132. package/dist/types/swagger-api-types.d.ts.map +1 -1
  133. package/dist/types/swagger-api-types.js +242 -39
  134. package/dist/types/swagger-api-types.js.map +1 -1
  135. package/dist/types/track.d.ts +8 -6
  136. package/dist/types/track.d.ts.map +1 -1
  137. package/dist/types/track.js.map +1 -1
  138. package/package.json +2 -2
@@ -5,16 +5,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { check, query } from '../validator/index.js';
8
- import { fromString } from 'uint8arrays';
9
- import { StatusCodes } from 'http-status-codes';
10
- import { IdentityServiceStrategySetup } from '../../services/identity/index.js';
11
- import { DefaultStatusActionPurposeMap, DefaultStatusActions, StatusListType, } from '../../types/credential-status.js';
8
+ import { DefaultStatusActions, StatusListType } from '../../types/credential-status.js';
12
9
  import { DefaultStatusListEncodings, DefaultStatusList2021StatusPurposeTypes, BitstringStatusPurposeTypes, } from '@cheqd/did-provider-cheqd';
13
- import { toNetwork } from '../../helpers/helpers.js';
14
- import { eventTracker } from '../../services/track/tracker.js';
15
- import { OperationCategoryNameEnum, OperationNameEnum } from '../../types/constants.js';
16
- import { FeeAnalyzer } from '../../helpers/fee-analyzer.js';
17
10
  import { validate } from '../validator/decorator.js';
11
+ import { CredentialStatusService } from '../../services/api/credential-status.js';
12
+ import { param } from 'express-validator';
18
13
  export class CredentialStatusController {
19
14
  static createUnencryptedValidator = [
20
15
  check('did').exists().withMessage('did: required').bail().isDID(),
@@ -509,6 +504,56 @@ export class CredentialStatusController {
509
504
  .withMessage(`statusPurpose: invalid statusPurpose, should be one of ${Object.keys(DefaultStatusList2021StatusPurposeTypes).join(', ')}`)
510
505
  .bail(),
511
506
  ];
507
+ static listValidator = [
508
+ query('did').optional().isDID().withMessage('did: should be a valid DID').bail(),
509
+ query('listType')
510
+ .optional()
511
+ .isString()
512
+ .withMessage('listType: should be a string')
513
+ .bail()
514
+ .isIn([StatusListType.Bitstring, StatusListType.StatusList2021])
515
+ .withMessage(`listType: invalid listType, should be one of [${Object.values(StatusListType)
516
+ .map((v) => `'${v}'`)
517
+ .join(', ')}]`)
518
+ .bail(),
519
+ query('statusListName')
520
+ .optional()
521
+ .isString()
522
+ .withMessage('statusListName: should be a string')
523
+ .bail()
524
+ .notEmpty()
525
+ .withMessage('statusListName: should be a non-empty string')
526
+ .bail(),
527
+ query('state')
528
+ .optional()
529
+ .isString()
530
+ .withMessage('state: should be a string')
531
+ .bail()
532
+ .isIn(['ACTIVE', 'STANDBY', 'FULL'])
533
+ .withMessage("state: invalid state, should be one of ['ACTIVE', 'STANDBY', 'FULL']")
534
+ .bail(),
535
+ query('credentialCategory')
536
+ .optional()
537
+ .isString()
538
+ .withMessage('credentialCategory: should be a string')
539
+ .bail()
540
+ .isIn(['credential', 'accreditation'])
541
+ .withMessage("credentialCategory: invalid category, should be one of ['credential', 'accreditation']")
542
+ .bail(),
543
+ query('deprecated').optional().isBoolean().withMessage('deprecated: should be a boolean').bail(),
544
+ ];
545
+ static fetchValidator = [
546
+ param('statusListId')
547
+ .exists()
548
+ .withMessage('statusListId: required')
549
+ .bail()
550
+ .isString()
551
+ .withMessage('statusListId: should be a string')
552
+ .bail()
553
+ .notEmpty()
554
+ .withMessage('statusListId: should be a non-empty string')
555
+ .bail(),
556
+ ];
512
557
  /**
513
558
  * @openapi
514
559
  *
@@ -579,84 +624,15 @@ export class CredentialStatusController {
579
624
  * $ref: '#/components/schemas/InternalError'
580
625
  */
581
626
  async createUnencryptedStatusList(request, response) {
582
- // collect request parameters - case: body
583
- const { did, encodedList, statusListName, alsoKnownAs, statusListVersion, length, encoding, statusSize: size, ttl, statusMessages, } = request.body;
584
- // collect request parameters - case: query
585
- const { listType, statusPurpose } = request.query;
586
- // define broadcast mode
587
- const data = encodedList ? fromString(encodedList, encoding) : undefined;
588
- // create agent
589
- const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
590
- try {
591
- // broadcast, if applicable
592
- if (data) {
593
- let result;
594
- if (listType === StatusListType.Bitstring) {
595
- result = await identityServiceStrategySetup.agent.broadcastBitstringStatusList(did, { data, name: statusListName, alsoKnownAs, version: statusListVersion }, response.locals.customer);
596
- }
597
- else {
598
- result = await identityServiceStrategySetup.agent.broadcastStatusList2021(did, { data, name: statusListName, alsoKnownAs, version: statusListVersion }, { encoding, statusPurpose }, response.locals.customer);
599
- }
600
- return response.status(StatusCodes.OK).json(result);
601
- }
602
- let result;
603
- // create unencrypted status list
604
- if (listType === StatusListType.Bitstring) {
605
- // create BitstringStatusList
606
- result = (await identityServiceStrategySetup.agent.createUnencryptedBitstringStatusList(did, {
607
- name: statusListName,
608
- alsoKnownAs,
609
- version: statusListVersion,
610
- }, {
611
- length,
612
- size,
613
- statusMessages,
614
- ttl,
615
- encoding,
616
- statusPurpose,
617
- }, response.locals.customer));
618
- }
619
- else {
620
- // create StatusList2021
621
- result = (await identityServiceStrategySetup.agent.createUnencryptedStatusList2021(did, {
622
- name: statusListName,
623
- alsoKnownAs,
624
- version: statusListVersion,
625
- }, {
626
- length,
627
- encoding,
628
- statusPurpose,
629
- }, response.locals.customer));
630
- }
631
- // handle error
632
- if (result.error) {
633
- return response.status(StatusCodes.BAD_REQUEST).json({
634
- ...result,
635
- error: result.error?.message || result.error.toString(),
636
- });
637
- }
638
- // Keep track of resources
639
- const trackInfo = {
640
- category: OperationCategoryNameEnum.CREDENTIAL_STATUS,
641
- name: OperationNameEnum.CREDENTIAL_STATUS_CREATE_UNENCRYPTED,
642
- customer: response.locals.customer,
643
- user: response.locals.user,
644
- data: {
645
- did,
646
- resource: result.resourceMetadata,
647
- encrypted: result.resource?.metadata?.encrypted,
648
- symmetricKey: '',
649
- },
650
- };
651
- // Track operation
652
- eventTracker.emit('track', trackInfo);
653
- return response.status(StatusCodes.OK).json({ ...result, encrypted: undefined });
627
+ const credentialStatusService = new CredentialStatusService();
628
+ const result = await credentialStatusService.createUnencryptedStatusList(request.body, request.query, response.locals.customer, response.locals.user);
629
+ if (result.success) {
630
+ return response.status(result.statusCode).json(result.data);
654
631
  }
655
- catch (error) {
656
- // return catch-all error
657
- return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
632
+ else {
633
+ return response.status(result.statusCode).json({
658
634
  created: false,
659
- error: `Internal error: ${error?.message || error}`,
635
+ error: result.error,
660
636
  });
661
637
  }
662
638
  }
@@ -730,80 +706,15 @@ export class CredentialStatusController {
730
706
  * $ref: '#/components/schemas/InternalError'
731
707
  */
732
708
  async createEncryptedStatusList(request, response) {
733
- // collect request parameters - case: body
734
- const { did, statusListName, alsoKnownAs, statusListVersion, length, statusSize: size, ttl, statusMessages, encoding, paymentConditions, feePaymentAddress, feePaymentAmount, feePaymentWindow, } = request.body;
735
- // collect request parameters - case: query
736
- const { listType, statusPurpose } = request.query;
737
- const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
738
- let result;
739
- try {
740
- // create encrypted status list
741
- if (listType === StatusListType.Bitstring) {
742
- // create BitstringStatusList
743
- result = (await identityServiceStrategySetup.agent.createEncryptedBitstringStatusList(did, {
744
- name: statusListName,
745
- alsoKnownAs,
746
- version: statusListVersion,
747
- }, {
748
- length,
749
- size,
750
- statusMessages,
751
- ttl,
752
- encoding,
753
- statusPurpose,
754
- paymentConditions,
755
- feePaymentAddress,
756
- feePaymentAmount,
757
- feePaymentWindow,
758
- }, response.locals.customer));
759
- }
760
- else {
761
- // create StatusList2021
762
- result = (await identityServiceStrategySetup.agent.createEncryptedStatusList2021(did, {
763
- name: statusListName,
764
- alsoKnownAs,
765
- version: statusListVersion,
766
- }, {
767
- length,
768
- encoding,
769
- statusPurpose,
770
- paymentConditions,
771
- feePaymentAddress,
772
- feePaymentAmount,
773
- feePaymentWindow,
774
- }, response.locals.customer));
775
- }
776
- // handle error
777
- if (result.error) {
778
- return response.status(StatusCodes.BAD_REQUEST).json({
779
- ...result,
780
- error: result.error?.message || result.error.toString(),
781
- });
782
- }
783
- // Keep track of resources
784
- // For now we decided not to store symmetricKey yet
785
- const trackInfo = {
786
- name: OperationNameEnum.CREDENTIAL_STATUS_CREATE_ENCRYPTED,
787
- category: OperationCategoryNameEnum.CREDENTIAL_STATUS,
788
- customer: response.locals.customer,
789
- user: response.locals.user,
790
- data: {
791
- did,
792
- resource: result.resourceMetadata,
793
- encrypted: true,
794
- symmetricKey: '',
795
- },
796
- feePaymentOptions: {},
797
- };
798
- // Track operation
799
- eventTracker.emit('track', trackInfo);
800
- return response.status(StatusCodes.OK).json({ ...result, encrypted: undefined });
709
+ const credentialStatusService = new CredentialStatusService();
710
+ const result = await credentialStatusService.createEncryptedStatusList(request.body, request.query, response.locals.customer, response.locals.user);
711
+ if (result.success) {
712
+ return response.status(result.statusCode).json(result.data);
801
713
  }
802
- catch (error) {
803
- // return catch-all error
804
- return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
714
+ else {
715
+ return response.status(result.statusCode).json({
805
716
  created: false,
806
- error: `Internal error: ${error?.message || error}`,
717
+ error: result.error,
807
718
  });
808
719
  }
809
720
  }
@@ -857,99 +768,15 @@ export class CredentialStatusController {
857
768
  * $ref: '#/components/schemas/InternalError'
858
769
  */
859
770
  async updateUnencryptedStatusList(request, response) {
860
- // collect request parameters - case: body
861
- const { did, statusListName, statusListVersion, indices } = request.body;
862
- // collect request parameters - case: query
863
- const { statusAction, listType } = request.query;
864
- // define identity service strategy setup
865
- const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
866
- // ensure unencrypted status list
867
- const unencrypted = await identityServiceStrategySetup.agent.searchStatusList(did, statusListName, listType, DefaultStatusActionPurposeMap[statusAction]);
868
- // handle error
869
- if (unencrypted.error) {
870
- // handle notFound error
871
- if (unencrypted.error === 'notFound') {
872
- return response.status(StatusCodes.NOT_FOUND).json({
873
- updated: false,
874
- error: `update: error: status list '${statusListName}' not found`,
875
- });
876
- }
877
- // handle generic error
878
- return response.status(StatusCodes.BAD_REQUEST).json({
879
- updated: false,
880
- error: `update: error: ${unencrypted.error}`,
881
- });
882
- }
883
- // validate unencrypted
884
- if (unencrypted.resource?.metadata?.encrypted)
885
- return response.status(StatusCodes.BAD_REQUEST).json({
886
- updated: false,
887
- error: `update: error: status list '${statusListName}' is encrypted`,
888
- });
889
- try {
890
- // update unencrypted status list
891
- const result = (await identityServiceStrategySetup.agent.updateUnencryptedStatusList(did, listType, {
892
- indices: typeof indices === 'number' ? [indices] : indices,
893
- statusListName,
894
- statusListVersion,
895
- statusAction,
896
- }, response.locals.customer));
897
- // enhance result
898
- result.updated = (function (that) {
899
- // validate result - case: revocation
900
- if (that?.revoked?.every((item) => !!item) &&
901
- that?.revoked?.length !== 0)
902
- return true;
903
- // validate result - case: suspension
904
- if (that?.suspended?.every((item) => !!item) &&
905
- that?.suspended?.length !== 0)
906
- return true;
907
- // validate result - case: unsuspension
908
- if (that?.unsuspended?.every((item) => !!item) &&
909
- that?.unsuspended?.length !== 0)
910
- return true;
911
- return false;
912
- })(result);
913
- // handle error
914
- if (result.error) {
915
- return response.status(StatusCodes.BAD_REQUEST).json({
916
- ...result,
917
- error: result.error?.message || result.error.toString(),
918
- });
919
- }
920
- // construct formatted response
921
- const formatted = {
922
- updated: true,
923
- revoked: result?.revoked || undefined,
924
- suspended: result?.suspended || undefined,
925
- unsuspended: result?.unsuspended || undefined,
926
- resource: result.statusList,
927
- resourceMetadata: result.resourceMetadata,
928
- };
929
- // track resource creation
930
- if (result.resourceMetadata) {
931
- const trackInfo = {
932
- category: OperationCategoryNameEnum.CREDENTIAL_STATUS,
933
- name: OperationNameEnum.CREDENTIAL_STATUS_UPDATE_UNENCRYPTED,
934
- customer: response.locals.customer,
935
- user: response.locals.user,
936
- data: {
937
- did,
938
- resource: result.resourceMetadata,
939
- encrypted: false,
940
- symmetricKey: '',
941
- },
942
- };
943
- // Track operation
944
- eventTracker.emit('track', trackInfo);
945
- }
946
- return response.status(StatusCodes.OK).json(formatted);
771
+ const credentialStatusService = new CredentialStatusService();
772
+ const result = await credentialStatusService.updateUnencryptedStatusList(request.body, request.query, response.locals.customer, response.locals.user);
773
+ if (result.success) {
774
+ return response.status(result.statusCode).json(result.data);
947
775
  }
948
- catch (error) {
949
- // return catch-all error
950
- return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
776
+ else {
777
+ return response.status(result.statusCode).json({
951
778
  updated: false,
952
- error: `Internal error: ${error?.message || error}`,
779
+ error: result.error,
953
780
  });
954
781
  }
955
782
  }
@@ -1003,105 +830,15 @@ export class CredentialStatusController {
1003
830
  * $ref: '#/components/schemas/InternalError'
1004
831
  */
1005
832
  async updateEncryptedStatusList(request, response) {
1006
- // collect request parameters - case: body
1007
- const { did, statusListName, statusListVersion, indices, symmetricKey, paymentConditions, feePaymentAddress, feePaymentAmount, feePaymentWindow, } = request.body;
1008
- // collect request parameters - case: query
1009
- const { statusAction, listType } = request.query;
1010
- // define identity service strategy setup
1011
- const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
1012
- // ensure encrypted status list
1013
- const encrypted = await identityServiceStrategySetup.agent.searchStatusList(did, statusListName, listType, DefaultStatusActionPurposeMap[statusAction]);
1014
- // handle error
1015
- if (encrypted.error) {
1016
- // handle notFound error
1017
- if (encrypted.error === 'notFound') {
1018
- return response.status(StatusCodes.NOT_FOUND).json({
1019
- updated: false,
1020
- error: `update: error: status list '${statusListName}' not found`,
1021
- });
1022
- }
1023
- // handle generic error
1024
- return response.status(StatusCodes.BAD_REQUEST).json({
1025
- updated: false,
1026
- error: `update: error: ${encrypted.error}`,
1027
- });
1028
- }
1029
- // validate encrypted
1030
- if (!encrypted.resource?.metadata?.encrypted)
1031
- return response.status(StatusCodes.BAD_REQUEST).json({
1032
- updated: false,
1033
- error: `update: error: status list '${statusListName}' is unencrypted`,
1034
- });
1035
- try {
1036
- // update encrypted status list
1037
- const result = (await identityServiceStrategySetup.agent.updateEncryptedStatusList(did, listType, {
1038
- indices: typeof indices === 'number' ? [indices] : indices,
1039
- statusListName,
1040
- statusListVersion,
1041
- statusAction,
1042
- paymentConditions,
1043
- symmetricKey,
1044
- feePaymentAddress,
1045
- feePaymentAmount,
1046
- feePaymentWindow,
1047
- }, response.locals.customer));
1048
- // enhance result
1049
- result.updated = (function (that) {
1050
- // validate result - case: revocation
1051
- if (that?.revoked?.every((item) => !!item) &&
1052
- that?.revoked?.length !== 0)
1053
- return true;
1054
- // validate result - case: suspension
1055
- if (that?.suspended?.every((item) => !!item) &&
1056
- that?.suspended?.length !== 0)
1057
- return true;
1058
- // validate result - case: unsuspension
1059
- if (that?.unsuspended?.every((item) => !!item) &&
1060
- that?.unsuspended?.length !== 0)
1061
- return true;
1062
- return false;
1063
- })(result);
1064
- // handle error
1065
- if (result.error)
1066
- return response.status(StatusCodes.BAD_REQUEST).json({
1067
- ...result,
1068
- error: result.error?.message || result.error.toString(),
1069
- });
1070
- // construct formatted response
1071
- const formatted = {
1072
- updated: true,
1073
- revoked: result?.revoked || undefined,
1074
- suspended: result?.suspended || undefined,
1075
- unsuspended: result?.unsuspended || undefined,
1076
- resource: result.statusList,
1077
- resourceMetadata: result.resourceMetadata,
1078
- symmetricKey: result.symmetricKey,
1079
- };
1080
- // track resource creation
1081
- if (result.resourceMetadata) {
1082
- const trackInfo = {
1083
- category: OperationCategoryNameEnum.CREDENTIAL_STATUS,
1084
- name: OperationNameEnum.CREDENTIAL_STATUS_UPDATE_ENCRYPTED,
1085
- customer: response.locals.customer,
1086
- user: response.locals.user,
1087
- data: {
1088
- did,
1089
- resource: result.resourceMetadata,
1090
- encrypted: true,
1091
- symmetricKey: '',
1092
- },
1093
- feePaymentOptions: {},
1094
- };
1095
- // Track operation
1096
- eventTracker.emit('track', trackInfo);
1097
- }
1098
- return response.status(StatusCodes.OK).json(formatted);
833
+ const credentialStatusService = new CredentialStatusService();
834
+ const result = await credentialStatusService.updateEncryptedStatusList(request.body, request.query, response.locals.customer, response.locals.user);
835
+ if (result.success) {
836
+ return response.status(result.statusCode).json(result.data);
1099
837
  }
1100
- catch (error) {
1101
- // return catch-all error
1102
- return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
838
+ else {
839
+ return response.status(result.statusCode).json({
1103
840
  updated: false,
1104
- error: `Internal error: ${error?.message || error}`,
841
+ error: result.error,
1105
842
  });
1106
843
  }
1107
844
  }
@@ -1157,144 +894,15 @@ export class CredentialStatusController {
1157
894
  * $ref: '#/components/schemas/InternalError'
1158
895
  */
1159
896
  async checkStatusList(request, response) {
1160
- const feePaymentOptions = [];
1161
- // Make the base body for tracking
1162
- const trackInfo = {
1163
- name: OperationNameEnum.CREDENTIAL_STATUS_CHECK,
1164
- category: OperationCategoryNameEnum.CREDENTIAL_STATUS,
1165
- customer: response.locals.customer,
1166
- user: response.locals.user,
1167
- successful: false,
1168
- };
1169
- // collect request parameters - case: body
1170
- const { did, statusListName, index, makeFeePayment, statusListCredential, statusSize, statusMessage } = request.body;
1171
- // collect request parameters - case: query
1172
- const { statusPurpose, listType } = request.query;
1173
- // define identity service strategy setup
1174
- const identityServiceStrategySetup = new IdentityServiceStrategySetup(response.locals.customer.customerId);
1175
- if (listType === StatusListType.Bitstring) {
1176
- if (!statusListCredential)
1177
- return response.status(StatusCodes.BAD_REQUEST).json({
1178
- checked: false,
1179
- error: `check: error: 'statusListCredential' is required for BitstringStatusList type`,
1180
- });
1181
- if (statusSize && statusSize > 1 && !statusMessage)
1182
- return response.status(StatusCodes.BAD_REQUEST).json({
1183
- checked: false,
1184
- error: `check: error: 'statusMessage' is required when 'statusSize' is greater than 1 for BitstringStatusList type`,
1185
- });
897
+ const credentialStatusService = new CredentialStatusService();
898
+ const result = await credentialStatusService.checkStatusList(request.body, request.query, response.locals.customer, response.locals.user);
899
+ if (result.success) {
900
+ return response.status(result.statusCode).json(result.data);
1186
901
  }
1187
- // ensure status list exists
1188
- const statusList = await identityServiceStrategySetup.agent.searchStatusList(did, statusListName, listType, statusPurpose);
1189
- // handle error
1190
- if (statusList.error) {
1191
- // handle notFound error
1192
- if (statusList.error === 'notFound') {
1193
- return response.status(StatusCodes.NOT_FOUND).json({
1194
- checked: false,
1195
- error: `check: error: status list '${statusListName}' not found`,
1196
- });
1197
- }
1198
- // handle generic error
1199
- return response.status(StatusCodes.BAD_REQUEST).json({
902
+ else {
903
+ return response.status(result.statusCode).json({
1200
904
  checked: false,
1201
- error: `check: error: ${statusList.error}`,
1202
- });
1203
- }
1204
- try {
1205
- // make fee payment, if defined
1206
- if (makeFeePayment && statusList?.resource?.metadata?.encrypted) {
1207
- // make fee payment
1208
- const feePaymentResult = await Promise.all(statusList?.resource?.metadata?.paymentConditions?.map(async (condition) => {
1209
- return await identityServiceStrategySetup.agent.remunerateStatusList2021({
1210
- feePaymentAddress: condition.feePaymentAddress,
1211
- feePaymentAmount: condition.feePaymentAmount,
1212
- feePaymentNetwork: toNetwork(did),
1213
- memo: 'Automated status check fee payment, orchestrated by CaaS.',
1214
- }, response.locals.customer);
1215
- }) || []);
1216
- // Track the operation
1217
- await Promise.all(feePaymentResult.map(async (result) => {
1218
- const portion = await FeeAnalyzer.getPaymentTrack(result, toNetwork(did));
1219
- feePaymentOptions.push(...portion);
1220
- }));
1221
- // handle error
1222
- if (feePaymentResult.some((result) => result.error)) {
1223
- // Track payment information even in case of error
1224
- trackInfo.data = {
1225
- did: did,
1226
- resource: statusList.resourceMetadata,
1227
- encrypted: statusList.resource?.metadata?.encrypted,
1228
- };
1229
- trackInfo.successful = false;
1230
- trackInfo.feePaymentOptions = feePaymentOptions;
1231
- // Track operation
1232
- eventTracker.emit('track', trackInfo);
1233
- return response.status(StatusCodes.BAD_REQUEST).json({
1234
- checked: false,
1235
- error: `check: payment: error: ${feePaymentResult.find((result) => result.error)?.error}`,
1236
- });
1237
- }
1238
- }
1239
- // check status list
1240
- let result;
1241
- if (listType === StatusListType.Bitstring) {
1242
- result = await identityServiceStrategySetup.agent.checkBitstringStatusList(did, {
1243
- id: statusListCredential + '#' + index,
1244
- type: 'BitstringStatusListEntry',
1245
- statusPurpose,
1246
- statusListIndex: index.toString(),
1247
- statusListCredential: statusListCredential || '',
1248
- statusSize: statusSize,
1249
- statusMessage: statusMessage,
1250
- }, response.locals.customer);
1251
- }
1252
- else {
1253
- result = await identityServiceStrategySetup.agent.checkStatusList2021(did, {
1254
- statusListIndex: index,
1255
- statusListName,
1256
- statusPurpose,
1257
- }, response.locals.customer);
1258
- }
1259
- // handle error
1260
- if ('error' in result && result.error) {
1261
- return response.status(StatusCodes.BAD_REQUEST).json(result);
1262
- }
1263
- (trackInfo.data = {
1264
- did: did,
1265
- resource: statusList.resourceMetadata,
1266
- encrypted: statusList.resource?.metadata?.encrypted,
1267
- }),
1268
- (trackInfo.successful = true);
1269
- trackInfo.feePaymentOptions = feePaymentOptions;
1270
- // Track operation
1271
- eventTracker.emit('track', trackInfo);
1272
- // return result
1273
- return response.status(StatusCodes.OK).json(result);
1274
- }
1275
- catch (error) {
1276
- // define error
1277
- const errorRef = error;
1278
- // handle doesn't meet condition
1279
- if (errorRef?.errorCode === 'NodeAccessControlConditionsReturnedNotAuthorized')
1280
- return response.status(StatusCodes.UNAUTHORIZED).json({
1281
- checked: false,
1282
- error: `check: error: ${errorRef?.message
1283
- ? 'unauthorized: decryption conditions are not met'
1284
- : error.toString()}`,
1285
- });
1286
- // handle incorrect access control conditions
1287
- if (errorRef?.errorCode === 'incorrect_access_control_conditions')
1288
- return response.status(StatusCodes.BAD_REQUEST).json({
1289
- checked: false,
1290
- error: `check: error: ${errorRef?.message
1291
- ? 'incorrect access control conditions'
1292
- : error.toString()}`,
1293
- });
1294
- // return catch-all error
1295
- return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
1296
- checked: false,
1297
- error: `Internal error: ${errorRef?.message || errorRef.toString()}`,
905
+ error: result.error,
1298
906
  });
1299
907
  }
1300
908
  }
@@ -1351,34 +959,134 @@ export class CredentialStatusController {
1351
959
  * $ref: '#/components/schemas/InternalError'
1352
960
  */
1353
961
  async searchStatusList(request, response) {
1354
- // collect request parameters - case: query
1355
- const { did, statusListName, listType, statusPurpose } = request.query;
1356
- try {
1357
- // search status list
1358
- const result = await new IdentityServiceStrategySetup().agent.searchStatusList(did, statusListName, listType, statusPurpose);
1359
- // handle error
1360
- if (result.error) {
1361
- // handle notFound error
1362
- if (result.error === 'notFound') {
1363
- return response.status(StatusCodes.NOT_FOUND).json({
1364
- found: false,
1365
- error: `search: error: status list '${statusListName}' not found`,
1366
- });
1367
- }
1368
- // handle generic error
1369
- return response.status(StatusCodes.BAD_REQUEST).json({
1370
- found: false,
1371
- error: `search: error: ${result.error}`,
1372
- });
1373
- }
1374
- // return result
1375
- return response.status(StatusCodes.OK).json(result);
962
+ const credentialStatusService = new CredentialStatusService();
963
+ const result = await credentialStatusService.searchStatusList(request.query);
964
+ if (result.success) {
965
+ return response.status(result.statusCode).json(result.data);
1376
966
  }
1377
- catch (error) {
1378
- // return catch-all error
1379
- return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
967
+ else {
968
+ return response.status(result.statusCode).json({
1380
969
  found: false,
1381
- error: `Internal error: ${error?.message || error}`,
970
+ error: result.error,
971
+ });
972
+ }
973
+ }
974
+ /**
975
+ * @openapi
976
+ *
977
+ * /credential-status/list:
978
+ * get:
979
+ * tags: [ Status Lists ]
980
+ * summary: List StatusList2021 or BitstringStatusList DID-Linked Resources created by the customer.
981
+ * parameters:
982
+ * - in: query
983
+ * name: did
984
+ * description: The DID of the issuer of the status list.
985
+ * schema:
986
+ * type: string
987
+ * - in: query
988
+ * name: listType
989
+ * description: The type of Status List.
990
+ * schema:
991
+ * type: string
992
+ * enum:
993
+ * - StatusList2021
994
+ * - BitstringStatusList
995
+ * - in: query
996
+ * name: statusListName
997
+ * description: The name of the Status List DID-Linked Resource.
998
+ * schema:
999
+ * type: string
1000
+ * - in: query
1001
+ * name: state
1002
+ * description: The state of the Status List DID-Linked Resource.
1003
+ * schema:
1004
+ * type: string
1005
+ * enum:
1006
+ * - ACTIVE
1007
+ * - STANDBY
1008
+ * - FULL
1009
+ * - in: query
1010
+ * name: credentialCategory
1011
+ * description: Filter status lists by credential category assigned for.
1012
+ * schema:
1013
+ * type: string
1014
+ * enum:
1015
+ * - credential
1016
+ * - accreditation
1017
+ * - in: query
1018
+ * name: deprecated
1019
+ * description: Filter status lists by deprecated status.
1020
+ * schema:
1021
+ * type: boolean
1022
+ * responses:
1023
+ * 200:
1024
+ * description: The request was successful.
1025
+ * content:
1026
+ * application/json:
1027
+ * schema:
1028
+ * $ref: '#/components/schemas/ListCredentialStatusRecordsResult'
1029
+ * 400:
1030
+ * $ref: '#/components/schemas/InvalidRequest'
1031
+ * 401:
1032
+ * $ref: '#/components/schemas/UnauthorizedError'
1033
+ * 500:
1034
+ * $ref: '#/components/schemas/InternalError'
1035
+ */
1036
+ async listStatusList(request, response) {
1037
+ const credentialStatusService = new CredentialStatusService();
1038
+ const result = await credentialStatusService.listStatusList(request.query, response.locals.customer);
1039
+ if (result.success) {
1040
+ return response.status(result.statusCode).json(result.data);
1041
+ }
1042
+ else {
1043
+ return response.status(result.statusCode).json({
1044
+ found: false,
1045
+ error: result.error,
1046
+ });
1047
+ }
1048
+ }
1049
+ /**
1050
+ * @openapi
1051
+ *
1052
+ * /credential-status/list/{statusListId}:
1053
+ * get:
1054
+ * tags: [ Status Lists ]
1055
+ * summary: Fetch StatusList2021 or BitstringStatusList DID-Linked Resource based on search criteria.
1056
+ * parameters:
1057
+ * - in: path
1058
+ * name: statusListId
1059
+ * description: The statusListId of the status list.
1060
+ * required: true
1061
+ * schema:
1062
+ * type: string
1063
+ * responses:
1064
+ * 200:
1065
+ * description: The request was successful.
1066
+ * content:
1067
+ * application/json:
1068
+ * schema:
1069
+ * $ref: '#/components/schemas/CredentialStatusRecordResult'
1070
+ * 400:
1071
+ * $ref: '#/components/schemas/InvalidRequest'
1072
+ * 401:
1073
+ * $ref: '#/components/schemas/UnauthorizedError'
1074
+ * 500:
1075
+ * $ref: '#/components/schemas/InternalError'
1076
+ */
1077
+ async fetchStatusList(request, response) {
1078
+ const credentialStatusService = new CredentialStatusService();
1079
+ const { statusListId } = request.params;
1080
+ const result = await credentialStatusService.getStatusList({
1081
+ statusListId,
1082
+ }, response.locals.customer);
1083
+ if (result.success) {
1084
+ return response.status(result.statusCode).json(result.data);
1085
+ }
1086
+ else {
1087
+ return response.status(result.statusCode).json({
1088
+ found: false,
1089
+ error: result.error,
1382
1090
  });
1383
1091
  }
1384
1092
  }
@@ -1401,4 +1109,10 @@ __decorate([
1401
1109
  __decorate([
1402
1110
  validate
1403
1111
  ], CredentialStatusController.prototype, "searchStatusList", null);
1112
+ __decorate([
1113
+ validate
1114
+ ], CredentialStatusController.prototype, "listStatusList", null);
1115
+ __decorate([
1116
+ validate
1117
+ ], CredentialStatusController.prototype, "fetchStatusList", null);
1404
1118
  //# sourceMappingURL=credential-status.js.map