@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,293 @@
1
+ const { ManagementClient } = require('auth0');
2
+ const { kebabCase, trim, map, join, includes } = require('lodash/fp');
3
+ const { nanoid } = require('nanoid');
4
+ const {
5
+ ServiceCategories,
6
+ ServiceTypesOfServiceCategory,
7
+ } = require('@verii/organizations-registry');
8
+ const { AuthClientTypes, RoleNames } = require('../domain');
9
+
10
+ const initRoleNameToRoleId = ({
11
+ auth0SuperuserRoleId,
12
+ auth0ClientAdminRoleId,
13
+ auth0ClientFinanceAdminRoleId,
14
+ auth0ClientSystemUserRoleId,
15
+ }) => {
16
+ return (roleName) => {
17
+ switch (roleName) {
18
+ case RoleNames.Superuser:
19
+ return auth0SuperuserRoleId;
20
+ case RoleNames.TokenWalletClientFinanceAdmin:
21
+ return auth0ClientFinanceAdminRoleId;
22
+ case RoleNames.TokenWalletClientSystemUser:
23
+ return auth0ClientSystemUserRoleId;
24
+ case RoleNames.RegistrarClientAdmin:
25
+ default:
26
+ return auth0ClientAdminRoleId;
27
+ }
28
+ };
29
+ };
30
+ const initAuth0Provisioner = ({
31
+ auth0Domain,
32
+ auth0ManagementApiAudience,
33
+ auth0ClientId,
34
+ auth0ClientSecret,
35
+ auth0Connection,
36
+ registrarAppUiUrl,
37
+ blockchainApiAudience,
38
+ auth0SuperuserRoleId,
39
+ auth0ClientAdminRoleId,
40
+ auth0ClientFinanceAdminRoleId,
41
+ auth0ClientSystemUserRoleId,
42
+ }) => {
43
+ const auth0ManagementClient = new ManagementClient({
44
+ domain: auth0Domain,
45
+ audience: auth0ManagementApiAudience,
46
+ clientId: auth0ClientId,
47
+ clientSecret: auth0ClientSecret,
48
+ });
49
+
50
+ const roleNameToRoleId = initRoleNameToRoleId({
51
+ auth0SuperuserRoleId,
52
+ auth0ClientAdminRoleId,
53
+ auth0ClientFinanceAdminRoleId,
54
+ auth0ClientSystemUserRoleId,
55
+ });
56
+
57
+ const setAuth0UserGroupId = async (did, { user }) => {
58
+ await auth0ManagementClient.users.update(
59
+ { id: user.sub },
60
+ {
61
+ app_metadata: { groupId: did },
62
+ }
63
+ );
64
+ };
65
+
66
+ const provisionAuth0SystemClient = async (
67
+ did,
68
+ profile,
69
+ service,
70
+ provisionClientGrant
71
+ ) => {
72
+ const clientDetails = buildClientDetails(did, profile, service);
73
+ if (clientDetails == null) {
74
+ return clientDetails;
75
+ }
76
+
77
+ const { name, description, clientType } = clientDetails;
78
+
79
+ const { data: auth0Client } = await auth0ManagementClient.clients.create({
80
+ name,
81
+ description,
82
+ logo_uri: trim(profile.logo),
83
+ app_type: 'non_interactive',
84
+ custom_login_page_on: false,
85
+ is_first_party: true,
86
+ is_token_endpoint_ip_header_trusted: true,
87
+ token_endpoint_auth_method: 'client_secret_post',
88
+ oidc_conformant: true,
89
+ grant_types: ['client_credentials'],
90
+ jwt_configuration: {
91
+ lifetime_in_seconds: 36000,
92
+ secret_encoded: true,
93
+ alg: 'RS256',
94
+ },
95
+ client_metadata: {
96
+ did,
97
+ service_id: service.id,
98
+ },
99
+ });
100
+
101
+ const response = {
102
+ type: 'auth0',
103
+ clientType,
104
+ serviceId: service.id,
105
+ clientId: auth0Client.client_id,
106
+ clientSecret: auth0Client.client_secret,
107
+ };
108
+
109
+ if (provisionClientGrant) {
110
+ const clientGrant = await provisionAuth0SystemClientGrants(
111
+ auth0Client.client_id,
112
+ service.type
113
+ );
114
+ response.clientGrantIds = [clientGrant.id];
115
+ }
116
+
117
+ return response;
118
+ };
119
+ const provisionAuth0SystemClientGrants = async (clientId, serviceType) => {
120
+ const clientGrantDetails = buildClientGrantDetails(serviceType);
121
+ if (clientGrantDetails == null) {
122
+ return clientGrantDetails;
123
+ }
124
+
125
+ const { audience, scope } = clientGrantDetails;
126
+ const { data: clientGrant } =
127
+ await auth0ManagementClient.clientGrants.create({
128
+ client_id: clientId,
129
+ audience,
130
+ scope,
131
+ });
132
+ return clientGrant;
133
+ };
134
+
135
+ const removeAuth0Client = async (authClient) => {
136
+ for (const clientGrantId of authClient.clientGrantIds ?? []) {
137
+ // eslint-disable-next-line no-await-in-loop
138
+ await auth0ManagementClient.clientGrants.delete({ id: clientGrantId });
139
+ }
140
+
141
+ await auth0ManagementClient.clients.delete({
142
+ client_id: authClient.clientId,
143
+ });
144
+ };
145
+
146
+ const removeAuth0Grants = async (authClient) => {
147
+ for (const clientGrantId of authClient.clientGrantIds ?? []) {
148
+ // eslint-disable-next-line no-await-in-loop
149
+ await auth0ManagementClient.clientGrants.delete({ id: clientGrantId });
150
+ }
151
+ };
152
+
153
+ const createAuth0User = async ({ user }) => {
154
+ const { data: createUserResult } = await auth0ManagementClient.users.create(
155
+ {
156
+ email: user.email,
157
+ given_name: user.givenName,
158
+ family_name: user.familyName,
159
+ password: nanoid(28),
160
+ verify_email: false,
161
+ email_verified: false,
162
+ connection: auth0Connection,
163
+ app_metadata: {
164
+ groupId: user.groupId,
165
+ },
166
+ }
167
+ );
168
+ return {
169
+ ...user,
170
+ id: createUserResult.user_id,
171
+ };
172
+ };
173
+
174
+ const getUsersByIds = async ({ userIds, fields = ['email'] }) => {
175
+ const query = join(
176
+ ' OR ',
177
+ map((userId) => `user_id:${userId}`, userIds)
178
+ );
179
+ const { data: users } = await auth0ManagementClient.getUsers({
180
+ search_engine: 'v3',
181
+ q: query,
182
+ fields: fields.join(','),
183
+ per_page: 25,
184
+ page: 0,
185
+ });
186
+ return users;
187
+ };
188
+
189
+ const addRoleToAuth0User = async ({ user, roleName }) => {
190
+ const { data: roles } = await auth0ManagementClient.users.assignRoles(
191
+ {
192
+ id: user.id,
193
+ },
194
+ {
195
+ roles: [roleNameToRoleId(roleName)],
196
+ }
197
+ );
198
+ return roles;
199
+ };
200
+
201
+ const createPasswordChangeTicket = async ({
202
+ user,
203
+ resultUrl = registrarAppUiUrl,
204
+ }) => {
205
+ const { data: ticket } = await auth0ManagementClient.tickets.changePassword(
206
+ {
207
+ user_id: user.id,
208
+ result_url: resultUrl,
209
+ mark_email_as_verified: true,
210
+ ttl_sec: 604800,
211
+ }
212
+ );
213
+ return ticket;
214
+ };
215
+
216
+ // See https://velocitycareerlabs.visualstudio.com/velocity/_wiki/wikis/velocity.wiki/171/Authentication?anchor=org-signup-instructions&_a=edit
217
+ const buildClientDetails = (did, profile, service) => {
218
+ if (
219
+ ServiceTypesOfServiceCategory[
220
+ ServiceCategories.CredentialAgentOperator
221
+ ].includes(service?.type)
222
+ ) {
223
+ return {
224
+ name: `${namePrefix(profile)}-${
225
+ AuthClientTypes.CAO_NODE_CLIENT
226
+ }-${did}${service.id}`,
227
+ description: `Credential Agent for "${profile.name}" permitted to issue and verify credentials`,
228
+ clientType: AuthClientTypes.CAO_NODE_CLIENT,
229
+ };
230
+ }
231
+
232
+ if (
233
+ ServiceTypesOfServiceCategory[ServiceCategories.NodeOperator].includes(
234
+ service?.type
235
+ )
236
+ ) {
237
+ return {
238
+ name: `${namePrefix(profile)}-${AuthClientTypes.NODE_OPERATOR}-${did}${
239
+ service.id
240
+ }`,
241
+ description: `Administrator for the Node operated by "${profile.name}"`,
242
+ clientType: AuthClientTypes.NODE_OPERATOR,
243
+ };
244
+ }
245
+
246
+ return undefined;
247
+ };
248
+
249
+ const buildClientGrantDetails = (serviceType) => {
250
+ if (
251
+ includes(
252
+ serviceType,
253
+ ServiceTypesOfServiceCategory[ServiceCategories.CredentialAgentOperator]
254
+ )
255
+ ) {
256
+ return {
257
+ scope: ['eth:*'],
258
+ audience: blockchainApiAudience,
259
+ };
260
+ }
261
+
262
+ if (
263
+ ServiceTypesOfServiceCategory[ServiceCategories.NodeOperator].includes(
264
+ serviceType
265
+ )
266
+ ) {
267
+ return {
268
+ scope: ['*:*'],
269
+ audience: blockchainApiAudience,
270
+ };
271
+ }
272
+
273
+ return undefined;
274
+ };
275
+
276
+ return {
277
+ provisionAuth0SystemClient,
278
+ provisionAuth0SystemClientGrants,
279
+ setAuth0UserGroupId,
280
+ removeAuth0Client,
281
+ createAuth0User,
282
+ addRoleToAuth0User,
283
+ createPasswordChangeTicket,
284
+ getUsersByIds,
285
+ removeAuth0Grants,
286
+ };
287
+ };
288
+
289
+ const namePrefix = (profile) => kebabCase(profile.name);
290
+
291
+ module.exports = {
292
+ initAuth0Provisioner,
293
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ ...require('./auth0-provisioner'),
3
+ };
@@ -0,0 +1,50 @@
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
+ const { omitBy, isNil, omit } = require('lodash/fp');
18
+ const { toRelativeKeyId } = require('@verii/did-doc');
19
+
20
+ const buildOrganizationKey = (organizationId, controller, spec) => {
21
+ const { purposes, algorithm, custodied, kmsKeyId, ...restOfSpec } = spec;
22
+ return omitBy(isNil, {
23
+ purposes,
24
+ algorithm,
25
+ controller,
26
+ organizationId,
27
+ custodied,
28
+ ...(restOfSpec.verificationMethod != null
29
+ ? buildFromVerificationMethod(restOfSpec)
30
+ : buildFromPublicKey(restOfSpec)),
31
+ ...(custodied ? { kmsKeyId } : {}),
32
+ });
33
+ };
34
+
35
+ const buildFromVerificationMethod = ({ verificationMethod }) => ({
36
+ id: toRelativeKeyId(verificationMethod.id),
37
+ publicKey: verificationMethod?.publicKeyJwk,
38
+ ...omit(['publicKeyJwk', 'id', 'purposes'], verificationMethod),
39
+ });
40
+
41
+ const buildFromPublicKey = ({ id, publicKey, ...rest }) => ({
42
+ id,
43
+ type: 'EcdsaSecp256k1VerificationKey2019',
44
+ publicKey,
45
+ ...rest,
46
+ });
47
+
48
+ module.exports = {
49
+ buildOrganizationKey,
50
+ };
@@ -0,0 +1,30 @@
1
+ // const KeyAlgorithms = {
2
+ // SECP256K1: 'SECP256K1',
3
+ // };
4
+ //
5
+ // const KeyEncodings = {
6
+ // HEX: 'hex',
7
+ // };
8
+
9
+ const KeyErrorMessages = {
10
+ UNRECOGNIZED_PURPOSE_DETECTED: 'Unrecognized purpose detected',
11
+ DUPLICATE_PURPOSE_DETECTED: 'Duplicate key purposes detected',
12
+ PUBLIC_KEY_MUST_BE_SPECIFIED_IF_ENCODING_IS_SPECIFIED:
13
+ 'publicKey must be specified if encoding is specified',
14
+ ENCODING_MUST_BE_SPECIFIED_IF_PUBLIC_KEY_IS_SPECIFIED:
15
+ 'encoding must be specified if publicKey is specified',
16
+ PUBLIC_KEY_ENCODING_DOES_NOT_MATCH_SPECIFIED_ENCODING:
17
+ 'publicKey encoding does not match specified encoding',
18
+ KEY_WITH_ID_FRAGMENT_ALREADY_EXISTS_TEMPLATE: ({ kidFragment }) =>
19
+ `Key with kidFragment ${kidFragment} already exists`,
20
+ PUBLIC_KEY_ALREADY_EXISTS_TEMPLATE: ({ publicKey }) =>
21
+ `publicKey ${publicKey} already exists`,
22
+ // UNRECOGNIZED_ALGORITHM: 'Unrecognized algorithm',
23
+ // UNRECOGNIZED_ENCODING: 'Unrecognized encoding',
24
+ };
25
+
26
+ module.exports = {
27
+ // KeyAlgorithms,
28
+ // KeyEncodings,
29
+ KeyErrorMessages,
30
+ };
@@ -0,0 +1,38 @@
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 { extractVerificationMethod } = require('@verii/did-doc');
19
+ const newError = require('http-errors');
20
+ const { isEmpty } = require('lodash/fp');
21
+
22
+ const extractVerificationMethodFromByoDID = ({ didDocument, kidFragment }) => {
23
+ const verificationMethod = extractVerificationMethod(
24
+ didDocument,
25
+ kidFragment
26
+ );
27
+ if (isEmpty(verificationMethod)) {
28
+ throw newError(400, 'Key not found in BYO DID', {
29
+ code: 'key_not_found_in_byo_did_doc',
30
+ });
31
+ }
32
+
33
+ return verificationMethod;
34
+ };
35
+
36
+ module.exports = {
37
+ extractVerificationMethodFromByoDID,
38
+ };
@@ -0,0 +1,6 @@
1
+ const { includes, find } = require('lodash/fp');
2
+
3
+ const findKeyByPurpose = (purpose, keys) =>
4
+ find((key) => includes(purpose, key.purposes), keys);
5
+
6
+ module.exports = { findKeyByPurpose };
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ ...require('./constants'),
3
+ ...require('./build-organization-key'),
4
+ ...require('./extract-verification-method-from-byo-did-document'),
5
+ ...require('./find-key-by-purpose'),
6
+ ...require('./jwk-to-hex-key-transformer'),
7
+ ...require('./map-key-response'),
8
+ ...require('./validate-non-custodial-key'),
9
+ ...require('./validate-organization-key'),
10
+ };
@@ -0,0 +1,13 @@
1
+ const { isEmpty } = require('lodash/fp');
2
+ const { hexFromJwk } = require('@verii/jwt');
3
+
4
+ const jwkToHexKeyTransformer = (key) => ({
5
+ ...key,
6
+ encoding: 'hex',
7
+ publicKey: hexFromJwk(key.publicKey, false),
8
+ ...(!isEmpty(key.key) ? { key: hexFromJwk(key.key) } : {}),
9
+ });
10
+
11
+ module.exports = {
12
+ jwkToHexKeyTransformer,
13
+ };
@@ -0,0 +1,29 @@
1
+ const { hexFromJwk } = require('@verii/jwt');
2
+ const { omit, isEmpty } = require('lodash/fp');
3
+
4
+ /* eslint-disable better-mutation/no-mutation */
5
+ const mapKeyResponse = (key, keyPair) => {
6
+ const response = omit(['publicKey'], key);
7
+ response.kidFragment = key.id;
8
+ response.didDocumentKey = {
9
+ id: key.id,
10
+ type: key.type,
11
+ controller: key.controller,
12
+ ...(key.type === 'JsonWebKey2020'
13
+ ? {
14
+ publicKeyJwk: key.publicKey,
15
+ }
16
+ : {
17
+ publicKeyMultibase: hexFromJwk(key.publicKey, false),
18
+ }),
19
+ };
20
+
21
+ if (!isEmpty(keyPair)) {
22
+ response.key = hexFromJwk(keyPair.privateKey);
23
+ response.encoding = 'hex';
24
+ }
25
+
26
+ return response;
27
+ };
28
+
29
+ module.exports = { mapKeyResponse };
@@ -0,0 +1,11 @@
1
+ const newError = require('http-errors');
2
+
3
+ const validateNonCustodialKey = (newKey) => {
4
+ if (!newKey.custodied && newKey.kidFragment == null) {
5
+ throw newError(400, 'Non custodial keys must specify kidFragment', {
6
+ code: 'kid_fragment_required',
7
+ });
8
+ }
9
+ };
10
+
11
+ module.exports = { validateNonCustodialKey };
@@ -0,0 +1,42 @@
1
+ const { all, includes, uniq, values } = require('lodash/fp');
2
+ const newError = require('http-errors');
3
+ const { KeyPurposes, isStringHex } = require('@verii/crypto');
4
+ const { KeyErrorMessages } = require('./constants');
5
+
6
+ const validKeyPurposes = values(KeyPurposes);
7
+
8
+ const arePurposesRecognized = (purposes) => {
9
+ return all((purpose) => includes(purpose, validKeyPurposes), purposes);
10
+ };
11
+
12
+ const containsDuplicatePurposes = (purposes) =>
13
+ !(uniq(purposes).length === purposes.length);
14
+
15
+ const validatePublicKeyAndEncoding = (key) => {
16
+ if (!key.publicKey) {
17
+ return;
18
+ }
19
+
20
+ if (!isStringHex(key.publicKey)) {
21
+ throw newError(
22
+ 400,
23
+ KeyErrorMessages.PUBLIC_KEY_ENCODING_DOES_NOT_MATCH_SPECIFIED_ENCODING
24
+ );
25
+ }
26
+ };
27
+
28
+ const validateOrganizationKey = (key) => {
29
+ const { purposes } = key;
30
+ if (!arePurposesRecognized(purposes)) {
31
+ throw newError(400, KeyErrorMessages.UNRECOGNIZED_PURPOSE_DETECTED);
32
+ }
33
+ if (containsDuplicatePurposes(purposes)) {
34
+ throw newError(400, KeyErrorMessages.DUPLICATE_PURPOSE_DETECTED);
35
+ }
36
+
37
+ validatePublicKeyAndEncoding(key);
38
+ };
39
+
40
+ module.exports = {
41
+ validateOrganizationKey,
42
+ };
@@ -0,0 +1,17 @@
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
+ module.exports = { ...require('./organization-keys-factory') };
@@ -0,0 +1,55 @@
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 { register } = require('@spencejs/spence-factories');
19
+ const { ObjectId } = require('mongodb');
20
+ const { KeyPurposes, KeyEncodings, KeyAlgorithms } = require('@verii/crypto');
21
+
22
+ const initOrganizationFactory = require('../../organizations/factories/organizations-factory');
23
+ const initKmsFactory = require('../../kms/factories/kms-factory');
24
+
25
+ const organizationKeysRepoPlugin = require('../repos/repo');
26
+
27
+ module.exports = (app) =>
28
+ register(
29
+ 'organizationKey',
30
+ organizationKeysRepoPlugin(app)({ config: app.config }),
31
+ async (overrides, { getOrBuild }) => {
32
+ const organization = await getOrBuild(
33
+ 'organization',
34
+ initOrganizationFactory(app)
35
+ );
36
+ const kmsEntry = await getOrBuild('kmsEntry', initKmsFactory(app));
37
+ return {
38
+ id: '#key-1',
39
+ purposes: [
40
+ KeyPurposes.DLT_TRANSACTIONS,
41
+ KeyPurposes.ISSUING_METADATA,
42
+ KeyPurposes.EXCHANGES,
43
+ ],
44
+ publicKey: kmsEntry.publicJwk,
45
+ kmsKeyId: new ObjectId(kmsEntry._id),
46
+ algorithm: KeyAlgorithms.SECP256K1,
47
+ encoding: KeyEncodings.HEX,
48
+ controller: organization.didDoc.id,
49
+ organizationId: new ObjectId(organization._id),
50
+ custodied: true,
51
+ type: 'EcdsaSecp256k1VerificationKey2019',
52
+ ...overrides(),
53
+ };
54
+ }
55
+ );
@@ -0,0 +1,5 @@
1
+ // TODO If we create a keys entity package, most of the stuff in this directory should probably be moved to there
2
+ module.exports = {
3
+ ...require('./domains'),
4
+ ...require('./orchestrators'),
5
+ };
@@ -0,0 +1,19 @@
1
+ const { first } = require('lodash/fp');
2
+ const { addKeysToDidDoc } = require('@verii/did-doc');
3
+
4
+ const addKeyToDidDoc = async (
5
+ { organization, kidFragment, publicKey },
6
+ { repos }
7
+ ) => {
8
+ const { didDoc, newVerificationMethods } = addKeysToDidDoc({
9
+ didDoc: organization.didDoc,
10
+ keys: [{ id: kidFragment, publicKey }],
11
+ });
12
+
13
+ await repos.organizations.update(organization._id, { didDoc });
14
+ return first(newVerificationMethods);
15
+ };
16
+
17
+ module.exports = {
18
+ addKeyToDidDoc,
19
+ };