@verii/endpoints-organizations-registrar 1.0.0-pre.1752076816

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 (259) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +1 -0
  3. package/README.md +3 -0
  4. package/package.json +86 -0
  5. package/src/config/abi.json +1 -0
  6. package/src/config/config.js +261 -0
  7. package/src/controllers/consents/autohooks.js +6 -0
  8. package/src/controllers/consents/controller.js +106 -0
  9. package/src/controllers/consents/schemas/consent-response.schema.js +45 -0
  10. package/src/controllers/did-web-host/controller.js +64 -0
  11. package/src/controllers/groups/autohooks.js +10 -0
  12. package/src/controllers/groups/controller.js +172 -0
  13. package/src/controllers/groups/schemas/group.schema.json +22 -0
  14. package/src/controllers/groups/schemas/index.js +7 -0
  15. package/src/controllers/groups/schemas/modify-group.schema.json +25 -0
  16. package/src/controllers/image_upload/controller.js +48 -0
  17. package/src/controllers/invitations/controller.js +79 -0
  18. package/src/controllers/organizations/_did/autohooks.js +16 -0
  19. package/src/controllers/organizations/_did/controller.js +617 -0
  20. package/src/controllers/organizations/_did/invitations/_invitationId/autohooks.js +16 -0
  21. package/src/controllers/organizations/_did/invitations/_invitationId/controller.js +217 -0
  22. package/src/controllers/organizations/_did/invitations/controller.js +197 -0
  23. package/src/controllers/organizations/_did/keys/controller.js +141 -0
  24. package/src/controllers/organizations/_did/services/controller.js +195 -0
  25. package/src/controllers/organizations/_did/signatories/controller.js +63 -0
  26. package/src/controllers/organizations/autohooks.js +65 -0
  27. package/src/controllers/organizations/controller.js +322 -0
  28. package/src/controllers/organizations/full/controller.js +285 -0
  29. package/src/controllers/organizations/plugins.js +21 -0
  30. package/src/controllers/organizations/schemas/add-key-body.schema.json +35 -0
  31. package/src/controllers/organizations/schemas/create-did-service.schema.json +70 -0
  32. package/src/controllers/organizations/schemas/did-key.schema.json +178 -0
  33. package/src/controllers/organizations/schemas/full-organization.schema.json +35 -0
  34. package/src/controllers/organizations/schemas/index.js +33 -0
  35. package/src/controllers/organizations/schemas/invitationCodeProperty.schema.json +3 -0
  36. package/src/controllers/organizations/schemas/organization-ids.schema.json +34 -0
  37. package/src/controllers/organizations/schemas/organization-kyb-profile-creation.schema.json +26 -0
  38. package/src/controllers/organizations/schemas/organization-profile-creation.schema.json +20 -0
  39. package/src/controllers/organizations/schemas/organization-profile-update.schema.json +19 -0
  40. package/src/controllers/organizations/schemas/organization-profile-verifiable-credential.schema.json +25 -0
  41. package/src/controllers/organizations/schemas/organization-registry-service-response.schema.json +26 -0
  42. package/src/controllers/organizations/schemas/organization-service.schema.json +34 -0
  43. package/src/controllers/organizations/schemas/organization-verified-profile.schema.json +123 -0
  44. package/src/controllers/organizations/schemas/organization.search-profile.query-params.schema.json +50 -0
  45. package/src/controllers/organizations/schemas/organization.search.query-params.schema.json +42 -0
  46. package/src/controllers/reference/controller.js +103 -0
  47. package/src/controllers/resolve-did/controller.js +45 -0
  48. package/src/controllers/resolve-did/resolve-did.js +30 -0
  49. package/src/controllers/resolve-did/schemas/did-doc.schema.json +155 -0
  50. package/src/controllers/resolve-did/schemas/did-proof.schema.json +44 -0
  51. package/src/controllers/resolve-did/schemas/index.js +26 -0
  52. package/src/controllers/resolve-did/schemas/public-key.schema.json +173 -0
  53. package/src/controllers/resolve-kid/controller.js +76 -0
  54. package/src/controllers/resolve-kid/public-key-formats.js +8 -0
  55. package/src/controllers/service-types/controller.js +81 -0
  56. package/src/controllers/setup_image_upload/controller.js +99 -0
  57. package/src/controllers/signatories/controller.js +43 -0
  58. package/src/controllers/users/autohooks.js +10 -0
  59. package/src/controllers/users/controller.js +221 -0
  60. package/src/controllers/users/schemas/base-user.schema.json +55 -0
  61. package/src/controllers/users/schemas/index.js +4 -0
  62. package/src/controllers/users/schemas/modify-user.schema.js +17 -0
  63. package/src/controllers/users/schemas/user.schema.js +20 -0
  64. package/src/entities/groups/domain/constants.js +21 -0
  65. package/src/entities/groups/domain/index.js +19 -0
  66. package/src/entities/groups/factories/groups-factory.js +48 -0
  67. package/src/entities/groups/factories/index.js +17 -0
  68. package/src/entities/groups/index.js +19 -0
  69. package/src/entities/groups/repo.js +122 -0
  70. package/src/entities/images/domain/constant.js +11 -0
  71. package/src/entities/images/domain/index.js +3 -0
  72. package/src/entities/images/extension/activate.extension.js +35 -0
  73. package/src/entities/images/extension/deactivate.extension.js +27 -0
  74. package/src/entities/images/extension/find-by-url.extension.js +24 -0
  75. package/src/entities/images/extension/index.js +5 -0
  76. package/src/entities/images/factories/images-factory.js +43 -0
  77. package/src/entities/images/factories/index.js +17 -0
  78. package/src/entities/images/index.js +5 -0
  79. package/src/entities/images/repo.js +43 -0
  80. package/src/entities/images/schema/image-metadata.schema.js +58 -0
  81. package/src/entities/images/schema/index.js +3 -0
  82. package/src/entities/index.js +31 -0
  83. package/src/entities/invitations/domains/build-invitation-url.js +14 -0
  84. package/src/entities/invitations/domains/get-given-family-name-from-name.js +20 -0
  85. package/src/entities/invitations/domains/index.js +7 -0
  86. package/src/entities/invitations/domains/init-invitation-emails.js +17 -0
  87. package/src/entities/invitations/domains/is-invitation-expired.js +5 -0
  88. package/src/entities/invitations/domains/validate-invitee-email.js +18 -0
  89. package/src/entities/invitations/factories/index.js +17 -0
  90. package/src/entities/invitations/factories/invitations-factory.js +51 -0
  91. package/src/entities/invitations/index.js +6 -0
  92. package/src/entities/invitations/orchestrators/accept-invitation.js +24 -0
  93. package/src/entities/invitations/orchestrators/index.js +4 -0
  94. package/src/entities/invitations/orchestrators/send-email-invitee.js +36 -0
  95. package/src/entities/invitations/repo.js +37 -0
  96. package/src/entities/invitations/schemas/add-invitation-body.js +122 -0
  97. package/src/entities/invitations/schemas/get-invitation-response-body.js +20 -0
  98. package/src/entities/invitations/schemas/index.js +5 -0
  99. package/src/entities/invitations/schemas/invitation-response-item-body.js +61 -0
  100. package/src/entities/kms/factories/index.js +17 -0
  101. package/src/entities/kms/factories/kms-factory.js +31 -0
  102. package/src/entities/monitors/index.js +17 -0
  103. package/src/entities/monitors/orchestrators/index.js +17 -0
  104. package/src/entities/monitors/orchestrators/monitors.js +230 -0
  105. package/src/entities/oauth/domain/constants.js +23 -0
  106. package/src/entities/oauth/domain/index.js +5 -0
  107. package/src/entities/oauth/domain/roles.js +92 -0
  108. package/src/entities/oauth/domain/scopes.js +35 -0
  109. package/src/entities/oauth/index.js +4 -0
  110. package/src/entities/oauth/orchestrators/auth0-provisioner.js +293 -0
  111. package/src/entities/oauth/orchestrators/index.js +3 -0
  112. package/src/entities/organization-keys/domains/build-organization-key.js +50 -0
  113. package/src/entities/organization-keys/domains/constants.js +30 -0
  114. package/src/entities/organization-keys/domains/extract-verification-method-from-byo-did-document.js +38 -0
  115. package/src/entities/organization-keys/domains/find-key-by-purpose.js +6 -0
  116. package/src/entities/organization-keys/domains/index.js +10 -0
  117. package/src/entities/organization-keys/domains/jwk-to-hex-key-transformer.js +13 -0
  118. package/src/entities/organization-keys/domains/map-key-response.js +29 -0
  119. package/src/entities/organization-keys/domains/validate-non-custodial-key.js +11 -0
  120. package/src/entities/organization-keys/domains/validate-organization-key.js +42 -0
  121. package/src/entities/organization-keys/factories/index.js +17 -0
  122. package/src/entities/organization-keys/factories/organization-keys-factory.js +55 -0
  123. package/src/entities/organization-keys/index.js +5 -0
  124. package/src/entities/organization-keys/orchestrators/add-key-to-did-doc.js +19 -0
  125. package/src/entities/organization-keys/orchestrators/add-key.js +155 -0
  126. package/src/entities/organization-keys/orchestrators/add-operator-keys.js +46 -0
  127. package/src/entities/organization-keys/orchestrators/delete-key.js +93 -0
  128. package/src/entities/organization-keys/orchestrators/get-key.js +39 -0
  129. package/src/entities/organization-keys/orchestrators/index.js +24 -0
  130. package/src/entities/organization-keys/orchestrators/resolve-verification-method-byo-did.js +28 -0
  131. package/src/entities/organization-keys/repos/repo.js +48 -0
  132. package/src/entities/organization-services/adapters/index.js +21 -0
  133. package/src/entities/organization-services/adapters/init-provision-auth0-client-grants.js +44 -0
  134. package/src/entities/organization-services/adapters/init-provision-auth0-clients.js +56 -0
  135. package/src/entities/organization-services/adapters/update-blockchain-permissions-from-permitted-services.js +118 -0
  136. package/src/entities/organization-services/domains/activate-services.js +12 -0
  137. package/src/entities/organization-services/domains/build-organizations-services.js +38 -0
  138. package/src/entities/organization-services/domains/build-public-services.js +19 -0
  139. package/src/entities/organization-services/domains/constants.js +32 -0
  140. package/src/entities/organization-services/domains/extract-cao-service-refs.js +10 -0
  141. package/src/entities/organization-services/domains/extract-service-endpoint-did.js +10 -0
  142. package/src/entities/organization-services/domains/get-service-consent-type.js +16 -0
  143. package/src/entities/organization-services/domains/get-service-types-from-categories.js +18 -0
  144. package/src/entities/organization-services/domains/index.js +17 -0
  145. package/src/entities/organization-services/domains/is-new-node-operator-service.js +25 -0
  146. package/src/entities/organization-services/domains/is-service-category.js +31 -0
  147. package/src/entities/organization-services/domains/normalize-service-endpoint.js +6 -0
  148. package/src/entities/organization-services/domains/select-activated-services.js +8 -0
  149. package/src/entities/organization-services/domains/transform-profile-service.js +88 -0
  150. package/src/entities/organization-services/domains/validate-cao-service-refs.js +25 -0
  151. package/src/entities/organization-services/domains/validate-service-credential-type.js +47 -0
  152. package/src/entities/organization-services/domains/validate-service-endpoint.js +35 -0
  153. package/src/entities/organization-services/domains/validate-service-fields-by-service-type.js +37 -0
  154. package/src/entities/organization-services/domains/validate-service-id-uniqueness.js +19 -0
  155. package/src/entities/organization-services/domains/validate-service-key-purposes.js +56 -0
  156. package/src/entities/organization-services/domains/validate-service-type.js +12 -0
  157. package/src/entities/organization-services/domains/validate-service.js +80 -0
  158. package/src/entities/organization-services/domains/validate-services-for-delete.js +32 -0
  159. package/src/entities/organization-services/index.js +5 -0
  160. package/src/entities/organization-services/orchestrators/add-service.js +106 -0
  161. package/src/entities/organization-services/orchestrators/delete-service.js +142 -0
  162. package/src/entities/organization-services/orchestrators/get-service.js +36 -0
  163. package/src/entities/organization-services/orchestrators/index.js +8 -0
  164. package/src/entities/organization-services/orchestrators/init-add-service-to-organization.js +141 -0
  165. package/src/entities/organization-services/orchestrators/load-cao-service-refs.js +56 -0
  166. package/src/entities/organization-services/orchestrators/update-service.js +103 -0
  167. package/src/entities/organizations/adapters/index.js +6 -0
  168. package/src/entities/organizations/adapters/init-organization-registrar-emails.js +215 -0
  169. package/src/entities/organizations/adapters/init-send-activation-emails-to-caos.js +89 -0
  170. package/src/entities/organizations/adapters/send-email-invitation-accepted-to-inviter.js +70 -0
  171. package/src/entities/organizations/adapters/send-email-notifications.js +212 -0
  172. package/src/entities/organizations/domains/build-custodied-did-web.js +12 -0
  173. package/src/entities/organizations/domains/build-full-organization-response.js +40 -0
  174. package/src/entities/organizations/domains/build-organization-modifications-on-service-change.js +82 -0
  175. package/src/entities/organizations/domains/build-profile-vc-url.js +8 -0
  176. package/src/entities/organizations/domains/build-profile-verifiable-credential.js +36 -0
  177. package/src/entities/organizations/domains/build-public-profile.js +9 -0
  178. package/src/entities/organizations/domains/constants.js +54 -0
  179. package/src/entities/organizations/domains/index.js +17 -0
  180. package/src/entities/organizations/domains/organization-vc-checks.js +49 -0
  181. package/src/entities/organizations/domains/parse-profile-to-csv.js +41 -0
  182. package/src/entities/organizations/domains/prepare-profile-vc.js +28 -0
  183. package/src/entities/organizations/domains/profile-name-normalization.js +5 -0
  184. package/src/entities/organizations/domains/validate-byo-did-keys.js +28 -0
  185. package/src/entities/organizations/domains/validate-profile-name.js +48 -0
  186. package/src/entities/organizations/domains/validate-profile-website.js +17 -0
  187. package/src/entities/organizations/domains/validate-update-profile.js +11 -0
  188. package/src/entities/organizations/factories/index.js +17 -0
  189. package/src/entities/organizations/factories/organizations-factory.js +180 -0
  190. package/src/entities/organizations/index.js +6 -0
  191. package/src/entities/organizations/orchestrators/add-primary-permissions.js +28 -0
  192. package/src/entities/organizations/orchestrators/build-custodied-organization.js +92 -0
  193. package/src/entities/organizations/orchestrators/build-non-custodied-organization.js +83 -0
  194. package/src/entities/organizations/orchestrators/index.js +6 -0
  195. package/src/entities/organizations/orchestrators/init-create-organization.js +221 -0
  196. package/src/entities/organizations/orchestrators/init-provision-group.js +48 -0
  197. package/src/entities/organizations/orchestrators/verify-profile-website-unique.js +15 -0
  198. package/src/entities/organizations/repos/find-caos-extension.js +49 -0
  199. package/src/entities/organizations/repos/index.js +17 -0
  200. package/src/entities/organizations/repos/repo.js +156 -0
  201. package/src/entities/organizations/repos/search-by-aggregation-extension.js +128 -0
  202. package/src/entities/organizations/repos/transform-did-filter.js +13 -0
  203. package/src/entities/organizations/repos/transform-organization-filter.js +106 -0
  204. package/src/entities/registrar-consents/constants.js +10 -0
  205. package/src/entities/registrar-consents/factories/index.js +17 -0
  206. package/src/entities/registrar-consents/factories/registrar-consents-factory.js +38 -0
  207. package/src/entities/registrar-consents/index.js +3 -0
  208. package/src/entities/registrar-consents/repos/registrar-consent-repo-extension.js +55 -0
  209. package/src/entities/registrar-consents/repos/repo.js +31 -0
  210. package/src/entities/signatories/domain/constants.js +12 -0
  211. package/src/entities/signatories/domain/index.js +4 -0
  212. package/src/entities/signatories/domain/organization-emails.js +29 -0
  213. package/src/entities/signatories/factories/index.js +17 -0
  214. package/src/entities/signatories/factories/signatory-status-factory.js +53 -0
  215. package/src/entities/signatories/index.js +5 -0
  216. package/src/entities/signatories/orchestrators/approve-reminder.js +24 -0
  217. package/src/entities/signatories/orchestrators/index.js +6 -0
  218. package/src/entities/signatories/orchestrators/reject-reminder.js +17 -0
  219. package/src/entities/signatories/orchestrators/send-reminders.js +102 -0
  220. package/src/entities/signatories/orchestrators/validate-auth-code.js +56 -0
  221. package/src/entities/signatories/repos/index.js +3 -0
  222. package/src/entities/signatories/repos/repo.js +35 -0
  223. package/src/entities/signatories/repos/signatory-status-state-repo-extension.js +124 -0
  224. package/src/entities/users/domains/constants.js +40 -0
  225. package/src/entities/users/domains/index.js +4 -0
  226. package/src/entities/users/domains/user-registrar-emails.js +52 -0
  227. package/src/entities/users/index.js +4 -0
  228. package/src/entities/users/orchestrators/create-auth0-user.js +60 -0
  229. package/src/entities/users/orchestrators/get-or-create-auth0-user.js +63 -0
  230. package/src/entities/users/orchestrators/index.js +22 -0
  231. package/src/entities/users/orchestrators/user-management.js +157 -0
  232. package/src/fetchers/index.js +19 -0
  233. package/src/fetchers/monitoring/index.js +9 -0
  234. package/src/fetchers/monitoring/monitor-add-to-page-fetcher.js +18 -0
  235. package/src/fetchers/monitoring/monitor-create-fetcher.js +23 -0
  236. package/src/fetchers/monitoring/monitor-delete-fetcher.js +6 -0
  237. package/src/fetchers/monitoring/monitor-get-all-fetcher.js +6 -0
  238. package/src/fetchers/monitoring/section-create-fetcher.js +16 -0
  239. package/src/fetchers/monitoring/section-get-all-fetcher.js +6 -0
  240. package/src/fetchers/monitoring/service-version-fetcher.js +6 -0
  241. package/src/helpers/init-permissions-contract.js +48 -0
  242. package/src/index.js +23 -0
  243. package/src/init-server.js +91 -0
  244. package/src/organizations-registrar-endpoints.js +68 -0
  245. package/src/plugins/authorization.js +233 -0
  246. package/src/plugins/index.js +4 -0
  247. package/src/plugins/pubsub-plugin.js +82 -0
  248. package/src/subscribers/notify-caos.js +63 -0
  249. package/src/subscribers/notify-inviters.js +42 -0
  250. package/src/subscribers/notify-monitoring.js +40 -0
  251. package/src/subscribers/notify-signatory.js +51 -0
  252. package/src/subscribers/notify-support-and-groups.js +95 -0
  253. package/src/templates/invitee-invitation-email-body.hbs +13 -0
  254. package/src/templates/invitee-invitation-email-subject.hbs +1 -0
  255. package/src/templates/signatory-approval-email-body.hbs +92 -0
  256. package/src/templates/support-organization-created-body.hbs +17 -0
  257. package/src/templates/support-organization-created-subject.hbs +1 -0
  258. package/src/templates/support-signatory-max-reminders-reached-email-body.hbs +6 -0
  259. package/src/templates/support-signatory-max-reminders-reached-email-subject.hbs +1 -0
@@ -0,0 +1,38 @@
1
+ const { map, pick } = require('lodash/fp');
2
+ const { toRelativeServiceId } = require('@verii/did-doc');
3
+
4
+ const ImmutableOrganizationServiceProperties = [
5
+ 'id',
6
+ 'type',
7
+ 'invitationId',
8
+ 'createdAt',
9
+ 'updatedAt',
10
+ ];
11
+
12
+ const buildOrganizationServiceForUpdate = (updates, existingService) => {
13
+ return {
14
+ ...updates,
15
+ ...pick(ImmutableOrganizationServiceProperties, existingService),
16
+ };
17
+ };
18
+
19
+ const buildOrganizationService = (service, invitation) => {
20
+ const organizationService = {
21
+ ...service,
22
+ id: toRelativeServiceId(service.id),
23
+ };
24
+ if (invitation != null) {
25
+ // eslint-disable-next-line better-mutation/no-mutation
26
+ organizationService.invitationId = invitation._id;
27
+ }
28
+ return organizationService;
29
+ };
30
+
31
+ const buildOrganizationServices = (services, invitation) =>
32
+ map((service) => buildOrganizationService(service, invitation), services);
33
+
34
+ module.exports = {
35
+ buildOrganizationServices,
36
+ buildOrganizationService,
37
+ buildOrganizationServiceForUpdate,
38
+ };
@@ -0,0 +1,19 @@
1
+ const { map, pick } = require('lodash/fp');
2
+
3
+ const buildPublicService = pick([
4
+ 'id',
5
+ 'type',
6
+ 'serviceEndpoint',
7
+ 'credentialTypes',
8
+ 'logoUrl',
9
+ 'playStoreUrl',
10
+ 'appleAppStoreUrl',
11
+ 'appleAppId',
12
+ 'googlePlayId',
13
+ 'name',
14
+ 'supportedExchangeProtocols',
15
+ ]);
16
+
17
+ const buildPublicServices = map(buildPublicService);
18
+
19
+ module.exports = { buildPublicServices, buildPublicService };
@@ -0,0 +1,32 @@
1
+ const {
2
+ ServiceCategories,
3
+ ServiceTypesOfServiceCategory,
4
+ } = require('@verii/organizations-registry');
5
+
6
+ const didDocServiceFields = ['id', 'type', 'serviceEndpoint'];
7
+
8
+ const identityCategories = [
9
+ ...ServiceTypesOfServiceCategory[ServiceCategories.IdDocumentIssuer],
10
+ ...ServiceTypesOfServiceCategory[ServiceCategories.NotaryIdDocumentIssuer],
11
+ ...ServiceTypesOfServiceCategory[ServiceCategories.ContactIssuer],
12
+ ...ServiceTypesOfServiceCategory[ServiceCategories.NotaryContactIssuer],
13
+ ...ServiceTypesOfServiceCategory[ServiceCategories.IdentityIssuer],
14
+ ];
15
+
16
+ const NodeServiceCategories = [
17
+ ...ServiceTypesOfServiceCategory[ServiceCategories.NodeOperator],
18
+ ...ServiceTypesOfServiceCategory[ServiceCategories.CredentialAgentOperator],
19
+ ];
20
+
21
+ const OrganizationServiceErrorMessages = {
22
+ ORGANIZATION_SERVICE_NOT_FOUND: 'Organization service not found',
23
+ SERVICE_ID_CANNOT_BE_UPDATED: 'Service "id" property cannot be updated',
24
+ SERVICE_TYPE_CANNOT_BE_UPDATED: 'Service "type" property cannot be updated',
25
+ };
26
+
27
+ module.exports = {
28
+ didDocServiceFields,
29
+ identityCategories,
30
+ NodeServiceCategories,
31
+ OrganizationServiceErrorMessages,
32
+ };
@@ -0,0 +1,10 @@
1
+ const { flow, map, compact, uniq } = require('lodash/fp');
2
+ const { extractServiceEndpointDid } = require('./extract-service-endpoint-did');
3
+
4
+ const extractCaoServiceRefs = flow(
5
+ map(extractServiceEndpointDid),
6
+ compact,
7
+ uniq
8
+ );
9
+
10
+ module.exports = { extractCaoServiceRefs };
@@ -0,0 +1,10 @@
1
+ const { isDidUrlWithFragment } = require('@verii/did-doc');
2
+
3
+ const extractServiceEndpointDid = (service) => {
4
+ if (isDidUrlWithFragment(service.serviceEndpoint)) {
5
+ return service.serviceEndpoint;
6
+ }
7
+ return undefined;
8
+ };
9
+
10
+ module.exports = { extractServiceEndpointDid };
@@ -0,0 +1,16 @@
1
+ const { isCaoService, isNodeOperator } = require('./is-service-category');
2
+ const { ConsentTypes } = require('../../registrar-consents');
3
+
4
+ const getServiceConsentType = (service) => {
5
+ if (isCaoService(service)) {
6
+ return ConsentTypes.CAO;
7
+ }
8
+ if (isNodeOperator(service)) {
9
+ return ConsentTypes.NodeOperator;
10
+ }
11
+ return ConsentTypes.IssuerInspector;
12
+ };
13
+
14
+ module.exports = {
15
+ getServiceConsentType,
16
+ };
@@ -0,0 +1,18 @@
1
+ const { flatMap } = require('lodash/fp');
2
+ const {
3
+ ServiceTypesOfServiceCategory,
4
+ } = require('@verii/organizations-registry');
5
+
6
+ const serviceCategoriesToServiceTypes = flatMap(
7
+ (currentServiceCategory) =>
8
+ ServiceTypesOfServiceCategory[currentServiceCategory]
9
+ );
10
+
11
+ const getServiceTypesFromCategories = ({ filter } = {}) => {
12
+ const serviceCategories = filter?.serviceTypes;
13
+ return serviceCategories != null
14
+ ? serviceCategoriesToServiceTypes(serviceCategories)
15
+ : undefined;
16
+ };
17
+
18
+ module.exports = { getServiceTypesFromCategories };
@@ -0,0 +1,17 @@
1
+ module.exports = {
2
+ ...require('./activate-services'),
3
+ ...require('./build-organizations-services'),
4
+ ...require('./build-public-services'),
5
+ ...require('./get-service-types-from-categories'),
6
+ ...require('./get-service-consent-type'),
7
+ ...require('./extract-cao-service-refs'),
8
+ ...require('./extract-service-endpoint-did'),
9
+ ...require('./constants'),
10
+ ...require('./is-service-category'),
11
+ ...require('./is-new-node-operator-service'),
12
+ ...require('./normalize-service-endpoint'),
13
+ ...require('./select-activated-services'),
14
+ ...require('./transform-profile-service'),
15
+ ...require('./validate-service'),
16
+ ...require('./validate-services-for-delete'),
17
+ };
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright 2025 Velocity Team
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ const { isNodeOperator } = require('./is-service-category');
19
+
20
+ const isNewNodeOperatorService = (organization, newService) =>
21
+ isNodeOperator(newService) && isStakesAccountMissing(organization);
22
+
23
+ const isStakesAccountMissing = ({ ids }) => ids?.stakesAccountId == null;
24
+
25
+ module.exports = { isNewNodeOperatorService };
@@ -0,0 +1,31 @@
1
+ const { includes } = require('lodash/fp');
2
+
3
+ const {
4
+ ServiceTypeToCategoryMap,
5
+ ServiceCategories,
6
+ ServiceTypesOfServiceCategory,
7
+ IssuingAndInspectionCategories,
8
+ } = require('@verii/organizations-registry');
9
+
10
+ const isIssuingOrInspectionService = (service) =>
11
+ service?.type != null &&
12
+ includes(
13
+ ServiceTypeToCategoryMap[service.type],
14
+ IssuingAndInspectionCategories
15
+ );
16
+
17
+ const isCaoService = (service) =>
18
+ service != null &&
19
+ includes(
20
+ service.type,
21
+ ServiceTypesOfServiceCategory[ServiceCategories.CredentialAgentOperator]
22
+ );
23
+
24
+ const isNodeOperator = (service) =>
25
+ service != null &&
26
+ includes(
27
+ service.type,
28
+ ServiceTypesOfServiceCategory[ServiceCategories.NodeOperator]
29
+ );
30
+
31
+ module.exports = { isIssuingOrInspectionService, isCaoService, isNodeOperator };
@@ -0,0 +1,6 @@
1
+ const { trimEnd } = require('lodash');
2
+
3
+ const normalizeServiceEndpoint = (serviceEndpoint) =>
4
+ `${trimEnd(serviceEndpoint, '/')}`;
5
+
6
+ module.exports = { normalizeServiceEndpoint };
@@ -0,0 +1,8 @@
1
+ const { map, find } = require('lodash/fp');
2
+
3
+ const selectActivatedServices = (selectedServiceIds, services) =>
4
+ map((id) => find({ id }, services))(selectedServiceIds);
5
+
6
+ module.exports = {
7
+ selectActivatedServices,
8
+ };
@@ -0,0 +1,88 @@
1
+ const {
2
+ endsWith,
3
+ filter,
4
+ flow,
5
+ includes,
6
+ map,
7
+ isEmpty,
8
+ set,
9
+ } = require('lodash/fp');
10
+ const {
11
+ ServiceTypes,
12
+ ServiceTypesOfServiceCategory,
13
+ ServiceCategories,
14
+ } = require('@verii/organizations-registry');
15
+ const { isDidUrlWithFragment } = require('@verii/did-doc');
16
+ const { buildPublicServices } = require('./build-public-services');
17
+ const { normalizeServiceEndpoint } = require('./normalize-service-endpoint');
18
+
19
+ const transformServiceEndpoint = (service, caoServiceRefs) => {
20
+ if (!isDidUrlWithFragment(service.serviceEndpoint)) {
21
+ return service;
22
+ }
23
+ const caoServiceRef = caoServiceRefs[service.serviceEndpoint];
24
+ if (caoServiceRef?.caoService == null) {
25
+ return service;
26
+ }
27
+ return set(
28
+ 'serviceEndpoint',
29
+ caoServiceRef.caoService.serviceEndpoint,
30
+ service
31
+ );
32
+ };
33
+
34
+ const transformProfileService = (
35
+ organization,
36
+ services,
37
+ serviceTypes,
38
+ caoServiceRefs,
39
+ { query }
40
+ ) => {
41
+ const pipeline = [
42
+ buildPublicServices,
43
+ filter((service) => includes(service.id, organization.activatedServiceIds)),
44
+ ];
45
+ if (!isEmpty(serviceTypes)) {
46
+ pipeline.push(filter((service) => includes(service.type, serviceTypes)));
47
+ }
48
+ if (!query.noServiceEndpointTransform) {
49
+ pipeline.push(
50
+ map((service) => transformServiceEndpoint(service, caoServiceRefs))
51
+ );
52
+ const convertIssuerService = convertIssuer(organization.didDoc);
53
+ pipeline.push(map((service) => convertIssuerService(service)));
54
+ }
55
+
56
+ return flow(pipeline)(services);
57
+ };
58
+
59
+ const isLegacyIssuerService = (service) =>
60
+ [
61
+ ServiceTypes.IdDocumentIssuerType,
62
+ ServiceTypes.NotaryIdDocumentIssuerType,
63
+ ServiceTypes.ContactIssuerType,
64
+ ServiceTypes.NotaryContactIssuerType,
65
+ ServiceTypes.NotaryIssuerType,
66
+ ServiceTypes.IdentityIssuerType,
67
+ ...ServiceTypesOfServiceCategory[ServiceCategories.Issuer],
68
+ ].includes(service.type) &&
69
+ !endsWith('get-credential-manifest', service.serviceEndpoint);
70
+
71
+ const convertIssuer = (didDoc) => (service) => {
72
+ const normalizedEndpoint = normalizeServiceEndpoint(service.serviceEndpoint);
73
+ if (
74
+ isDidUrlWithFragment(service.serviceEndpoint) ||
75
+ !isLegacyIssuerService(service)
76
+ ) {
77
+ return {
78
+ ...service,
79
+ serviceEndpoint: normalizedEndpoint,
80
+ };
81
+ }
82
+ return {
83
+ ...service,
84
+ serviceEndpoint: `${normalizedEndpoint}/api/holder/v0.6/org/${didDoc.id}/issue/get-credential-manifest`,
85
+ };
86
+ };
87
+
88
+ module.exports = { transformProfileService, convertIssuer };
@@ -0,0 +1,25 @@
1
+ const newError = require('http-errors');
2
+ const { isDidUrlWithFragment } = require('@verii/did-doc');
3
+ const {
4
+ isIssuingOrInspectionService,
5
+ isCaoService,
6
+ } = require('./is-service-category');
7
+
8
+ const validateCaoServiceRefs = (service, caoServiceRefs) => {
9
+ if (!isDidUrlWithFragment(service.serviceEndpoint)) {
10
+ return;
11
+ }
12
+
13
+ const referencedService = caoServiceRefs[service.serviceEndpoint];
14
+
15
+ if (
16
+ isIssuingOrInspectionService(service) &&
17
+ !isCaoService(referencedService?.caoService)
18
+ ) {
19
+ throw newError(400, 'Service endpoint is not pointing to CAO', {
20
+ errorCode: 'service_endpoint_ref_not_found',
21
+ });
22
+ }
23
+ };
24
+
25
+ module.exports = { validateCaoServiceRefs };
@@ -0,0 +1,47 @@
1
+ const newError = require('http-errors');
2
+ const { difference, isEmpty } = require('lodash/fp');
3
+ const {
4
+ ServiceTypesOfServiceCategory,
5
+ ServiceCategories,
6
+ } = require('@verii/organizations-registry');
7
+ const { identityCategories } = require('./constants');
8
+
9
+ const validateServiceCredentialType = (
10
+ newService,
11
+ { registeredCredentialTypes, config: { idCredentialTypes } }
12
+ ) => {
13
+ const expectedCredentialTypes = computeExpectedCredentialTypes(
14
+ newService.type,
15
+ { registeredCredentialTypes, idCredentialTypes }
16
+ );
17
+ if (expectedCredentialTypes == null) {
18
+ return;
19
+ }
20
+
21
+ const unsupportedCredentialTypes = difference(
22
+ newService.credentialTypes,
23
+ expectedCredentialTypes
24
+ );
25
+ if (!isEmpty(unsupportedCredentialTypes)) {
26
+ throw newError.BadRequest(
27
+ `Cannot add issuer that issues unsupported credential types ${unsupportedCredentialTypes}`
28
+ );
29
+ }
30
+ };
31
+
32
+ const computeExpectedCredentialTypes = (
33
+ type,
34
+ { registeredCredentialTypes, idCredentialTypes }
35
+ ) => {
36
+ if (identityCategories.includes(type)) {
37
+ return idCredentialTypes;
38
+ }
39
+ if (ServiceTypesOfServiceCategory[ServiceCategories.Issuer].includes(type)) {
40
+ return difference(registeredCredentialTypes, idCredentialTypes);
41
+ }
42
+ return undefined;
43
+ };
44
+
45
+ module.exports = {
46
+ validateServiceCredentialType,
47
+ };
@@ -0,0 +1,35 @@
1
+ const newError = require('http-errors');
2
+ const { isEmpty } = require('lodash/fp');
3
+ const { isDidUrlWithFragment } = require('@verii/did-doc');
4
+ const { isIssuingOrInspectionService } = require('./is-service-category');
5
+
6
+ const validateServiceEndpoint = (
7
+ service,
8
+ issuingAndInspectionRequiresCaoServiceRef = false
9
+ ) => {
10
+ if (isEmpty(service.serviceEndpoint)) {
11
+ throw newError(400, 'Service must have a serviceEndpoint', {
12
+ errorCode: 'service_endpoint_required',
13
+ });
14
+ }
15
+
16
+ if (isIssuingOrInspectionService(service)) {
17
+ if (isDidUrlWithFragment(service.serviceEndpoint)) {
18
+ return;
19
+ }
20
+ if (issuingAndInspectionRequiresCaoServiceRef) {
21
+ throw newError(400, 'serviceEndpoint must be a did service reference', {
22
+ errorCode: 'service_endpoint_must_be_ref',
23
+ });
24
+ }
25
+ }
26
+
27
+ const url = new URL(service.serviceEndpoint);
28
+ if (url.protocol !== 'https:') {
29
+ throw newError(400, 'serviceEndpoint is invalid format', {
30
+ errorCode: 'service_endpoint_invalid',
31
+ });
32
+ }
33
+ };
34
+
35
+ module.exports = { validateServiceEndpoint };
@@ -0,0 +1,37 @@
1
+ const newError = require('http-errors');
2
+ const { ServiceTypes } = require('@verii/organizations-registry');
3
+
4
+ const buildMessage = (serviceType, fieldName) =>
5
+ `${serviceType} service type requires "${fieldName}"`;
6
+
7
+ const serviceTypeToRequiredFieldsMap = {
8
+ [ServiceTypes.HolderAppProviderType]: [
9
+ 'playStoreUrl',
10
+ 'appleAppStoreUrl',
11
+ 'appleAppId',
12
+ 'googlePlayId',
13
+ 'logoUrl',
14
+ 'name',
15
+ 'supportedExchangeProtocols',
16
+ ],
17
+ [ServiceTypes.WebWalletProviderType]: [
18
+ 'logoUrl',
19
+ 'name',
20
+ 'supportedExchangeProtocols',
21
+ ],
22
+ };
23
+
24
+ const validateServiceFieldsByServiceType = (service = {}) => {
25
+ if (!serviceTypeToRequiredFieldsMap[service.type]) {
26
+ return;
27
+ }
28
+ for (const requiredField of serviceTypeToRequiredFieldsMap[service.type]) {
29
+ if (!service[requiredField]) {
30
+ throw newError(400, buildMessage(service.type, requiredField));
31
+ }
32
+ }
33
+ };
34
+
35
+ module.exports = {
36
+ validateServiceFieldsByServiceType,
37
+ };
@@ -0,0 +1,19 @@
1
+ const newError = require('http-errors');
2
+ const { find } = require('lodash/fp');
3
+ const {
4
+ OrganizationRegistryErrorMessages,
5
+ } = require('@verii/organizations-registry');
6
+
7
+ const validateServiceIdUniqueness = (newService, existingServices = []) => {
8
+ const matchingService = find({ id: newService.id }, existingServices);
9
+
10
+ if (matchingService != null) {
11
+ throw newError.BadRequest(
12
+ OrganizationRegistryErrorMessages.SERVICE_ID_ALREADY_EXISTS
13
+ );
14
+ }
15
+ };
16
+
17
+ module.exports = {
18
+ validateServiceIdUniqueness,
19
+ };
@@ -0,0 +1,56 @@
1
+ const newError = require('http-errors');
2
+ const { includes, map, find, flow, compact } = require('lodash/fp');
3
+ const { KeyPurposes } = require('@verii/crypto');
4
+ const { ServiceTypes } = require('@verii/organizations-registry');
5
+
6
+ const validateServiceKeyPurposes = (registeredService, keys) => {
7
+ const requiredPurposes = requiredKeyPurposes[registeredService.type];
8
+
9
+ // gets a single key for each required purpose
10
+ const registeredKeys = flow(
11
+ map(findKeyWithRequiredPurpose(keys)),
12
+ compact
13
+ )(requiredPurposes);
14
+
15
+ // if the number of found keys doesnt equal the number required, then its an error
16
+ if (registeredKeys.length !== requiredPurposes.length) {
17
+ throw newError(400, 'No required purpose for service', {
18
+ code: 'required_key_missing_in_byo_did_doc',
19
+ });
20
+ }
21
+ };
22
+
23
+ const findKeyWithRequiredPurpose = (keys) => (requiredPurpose) =>
24
+ find((key) => includes(requiredPurpose, key.purposes), keys);
25
+
26
+ const keyPurposesCaoNode = [KeyPurposes.DLT_TRANSACTIONS];
27
+ const keyPurposesIssuing = [
28
+ KeyPurposes.DLT_TRANSACTIONS,
29
+ KeyPurposes.ISSUING_METADATA,
30
+ KeyPurposes.EXCHANGES,
31
+ ];
32
+ const keyPurposesRelyingParties = [
33
+ KeyPurposes.DLT_TRANSACTIONS,
34
+ KeyPurposes.EXCHANGES,
35
+ ];
36
+
37
+ const requiredKeyPurposes = {
38
+ // CAO and NODE
39
+ [ServiceTypes.CredentialAgentOperatorType]: keyPurposesCaoNode,
40
+ [ServiceTypes.NodeOperatorType]: keyPurposesCaoNode,
41
+ // ISSUING
42
+ [ServiceTypes.IdentityIssuerType]: keyPurposesIssuing,
43
+ [ServiceTypes.CareerIssuerType]: keyPurposesIssuing,
44
+ [ServiceTypes.NotaryIssuerType]: keyPurposesIssuing,
45
+ [ServiceTypes.ContactIssuerType]: keyPurposesIssuing,
46
+ [ServiceTypes.NotaryContactIssuerType]: keyPurposesIssuing,
47
+ [ServiceTypes.NotaryIdDocumentIssuerType]: keyPurposesIssuing,
48
+ [ServiceTypes.IdDocumentIssuerType]: keyPurposesIssuing,
49
+ // RELYING PARTIES
50
+ [ServiceTypes.HolderAppProviderType]: keyPurposesRelyingParties,
51
+ [ServiceTypes.InspectionType]: keyPurposesRelyingParties,
52
+ };
53
+
54
+ module.exports = {
55
+ validateServiceKeyPurposes,
56
+ };
@@ -0,0 +1,12 @@
1
+ const { isEmpty } = require('lodash/fp');
2
+ const newError = require('http-errors');
3
+
4
+ const validateServiceType = (service) => {
5
+ if (isEmpty(service.type)) {
6
+ throw newError(400, 'Service must have a type', {
7
+ errorCode: 'type_required',
8
+ });
9
+ }
10
+ };
11
+
12
+ module.exports = { validateServiceType };
@@ -0,0 +1,80 @@
1
+ const { forEach } = require('lodash/fp');
2
+ const { serviceExists } = require('@verii/did-doc');
3
+ const newError = require('http-errors');
4
+ const { validateServiceType } = require('./validate-service-type');
5
+ const { validateServiceEndpoint } = require('./validate-service-endpoint');
6
+ const {
7
+ validateServiceCredentialType,
8
+ } = require('./validate-service-credential-type');
9
+ const {
10
+ validateServiceFieldsByServiceType,
11
+ } = require('./validate-service-fields-by-service-type');
12
+ const { validateCaoServiceRefs } = require('./validate-cao-service-refs');
13
+ const {
14
+ validateServiceKeyPurposes,
15
+ } = require('./validate-service-key-purposes');
16
+ const {
17
+ validateServiceIdUniqueness,
18
+ } = require('./validate-service-id-uniqueness');
19
+
20
+ const validateService = (service, caoServiceRefs, context) => {
21
+ validateServiceType(service);
22
+ validateServiceEndpoint(service);
23
+ validateServiceCredentialType(service, context);
24
+ validateServiceFieldsByServiceType(service);
25
+ validateCaoServiceRefs(service, caoServiceRefs);
26
+ };
27
+
28
+ const validateServices = (services, caoServiceRefs, context) => {
29
+ forEach(
30
+ (service) => validateService(service, caoServiceRefs, context),
31
+ services
32
+ );
33
+ };
34
+
35
+ const validateAdditionalService = (
36
+ service,
37
+ existingServices,
38
+ caoServiceRefs,
39
+ context
40
+ ) => {
41
+ validateService(service, caoServiceRefs, context);
42
+ validateServiceIdUniqueness(service, existingServices);
43
+ };
44
+
45
+ const validateInviteeService = (service, caoServiceRefs, context) => {
46
+ try {
47
+ validateServiceType(service);
48
+ validateServiceEndpoint(service, true);
49
+ validateServiceCredentialType(service, context);
50
+ validateCaoServiceRefs(service, caoServiceRefs);
51
+ } catch (error) {
52
+ if (error.errorCode == null) {
53
+ // eslint-disable-next-line better-mutation/no-mutation
54
+ error.errorCode = 'invitee_service_invalid';
55
+ }
56
+ throw error;
57
+ }
58
+ };
59
+
60
+ const validateByoDidDocService = (didDoc, serviceId, keys) => {
61
+ const didDocService = serviceExists(didDoc, serviceId);
62
+ if (didDocService == null) {
63
+ throw newError.BadRequest(`Service with ID ${serviceId} does not exist`, {
64
+ didDoc,
65
+ serviceId,
66
+ });
67
+ }
68
+ validateServiceType(didDocService);
69
+ validateServiceEndpoint(didDocService);
70
+ validateServiceKeyPurposes(didDocService, keys);
71
+ return didDocService;
72
+ };
73
+
74
+ module.exports = {
75
+ validateAdditionalService,
76
+ validateService,
77
+ validateServices,
78
+ validateInviteeService,
79
+ validateByoDidDocService,
80
+ };