@verii/server-credentialing-hub 2.0.0

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 (237) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +13 -0
  3. package/package.json +87 -0
  4. package/src/assets/templates/app-redirect.hbs +22 -0
  5. package/src/config/config.js +118 -0
  6. package/src/config/index.js +19 -0
  7. package/src/controllers/app-redirect/controller.js +85 -0
  8. package/src/controllers/openid4vc/autohooks.js +22 -0
  9. package/src/controllers/openid4vc/oauth-controller.js +96 -0
  10. package/src/controllers/openid4vc/openid4vc-metadata-controller.js +66 -0
  11. package/src/controllers/openid4vc/openid4vci-controller.js +125 -0
  12. package/src/controllers/openid4vp/autohooks.js +22 -0
  13. package/src/controllers/openid4vp/openid4vp-controller.js +177 -0
  14. package/src/controllers/operator/autohooks.js +31 -0
  15. package/src/controllers/operator/credentials/credentials-controller.js +212 -0
  16. package/src/controllers/operator/credentials/schemas/credential.schema.js +46 -0
  17. package/src/controllers/operator/credentials/schemas/index.js +7 -0
  18. package/src/controllers/operator/credentials/schemas/new-credential.schema.json +23 -0
  19. package/src/controllers/operator/depots/depots-controller.js +154 -0
  20. package/src/controllers/operator/depots/schemas/depot.schema.js +34 -0
  21. package/src/controllers/operator/depots/schemas/index.js +24 -0
  22. package/src/controllers/operator/depots/schemas/new-depot.schema.json +30 -0
  23. package/src/controllers/operator/issue-links/issue-links-controller.js +74 -0
  24. package/src/controllers/operator/issuer-services/issuer-services-controller.js +200 -0
  25. package/src/controllers/operator/issuer-services/schemas/index.js +7 -0
  26. package/src/controllers/operator/issuer-services/schemas/issuer-service.schema.js +26 -0
  27. package/src/controllers/operator/issuer-services/schemas/new-issuer-service.schema.js +137 -0
  28. package/src/controllers/operator/presentation-links/presentation-links-controller.js +76 -0
  29. package/src/controllers/operator/presentations/presentations-controller.js +174 -0
  30. package/src/controllers/operator/presentations/schemas/base-presentation.schema.js +39 -0
  31. package/src/controllers/operator/presentations/schemas/credential-verification.schema.js +83 -0
  32. package/src/controllers/operator/presentations/schemas/index.js +23 -0
  33. package/src/controllers/operator/presentations/schemas/presentation-verification.schema.js +42 -0
  34. package/src/controllers/operator/presentations/schemas/presentation.schema.js +53 -0
  35. package/src/controllers/operator/presentations/schemas/w3c-presentation.js +52 -0
  36. package/src/controllers/operator/relying-party-services/relying-party-services-controller.js +202 -0
  37. package/src/controllers/operator/relying-party-services/schemas/index.js +7 -0
  38. package/src/controllers/operator/relying-party-services/schemas/new-relying-party-service.schema.js +91 -0
  39. package/src/controllers/operator/relying-party-services/schemas/relying-party-service.schema.js +26 -0
  40. package/src/controllers/operator/tenants/schemas/index.js +33 -0
  41. package/src/controllers/operator/tenants/schemas/jwk.schema.json +56 -0
  42. package/src/controllers/operator/tenants/schemas/key-metadata.schema.json +12 -0
  43. package/src/controllers/operator/tenants/schemas/new-key-metadata.schema.json +42 -0
  44. package/src/controllers/operator/tenants/schemas/new-key.schema.json +12 -0
  45. package/src/controllers/operator/tenants/schemas/new-tenant.schema.json +33 -0
  46. package/src/controllers/operator/tenants/schemas/secret-key.schema.json +33 -0
  47. package/src/controllers/operator/tenants/schemas/tenant.schema.json +44 -0
  48. package/src/controllers/operator/tenants/tenants-controller.js +165 -0
  49. package/src/controllers/root-controller.js +43 -0
  50. package/src/controllers/vn-api/schemas/index.js +25 -0
  51. package/src/controllers/vn-api/schemas/presentation-submission.schema.json +41 -0
  52. package/src/controllers/vn-api/schemas/velocity-presentation-submission.response.200.schema.json +36 -0
  53. package/src/controllers/vn-api/schemas/velocity-presentation-submission.schema.json +31 -0
  54. package/src/controllers/vn-api/vn-api-presentation-controller.js +158 -0
  55. package/src/controllers/vn-api/vn-issuing-controller.js +295 -0
  56. package/src/entities/credential-types/fetchers/fetch-credential-type-descriptors.js +36 -0
  57. package/src/entities/credential-types/fetchers/index.js +19 -0
  58. package/src/entities/credential-types/index.js +19 -0
  59. package/src/entities/credentials/domain/canonicalize-credentials.js +70 -0
  60. package/src/entities/credentials/domain/credential-errors.js +25 -0
  61. package/src/entities/credentials/domain/credential-format.js +21 -0
  62. package/src/entities/credentials/domain/index.js +22 -0
  63. package/src/entities/credentials/domain/validate-credential.js +74 -0
  64. package/src/entities/credentials/facades/anchor-verii-credentials-facade.js +45 -0
  65. package/src/entities/credentials/facades/build-verii-issuer.js +44 -0
  66. package/src/entities/credentials/facades/index.js +22 -0
  67. package/src/entities/credentials/facades/issue-verii-credentials-facade.js +62 -0
  68. package/src/entities/credentials/facades/sign-verii-credentials-facade.js +56 -0
  69. package/src/entities/credentials/factories/credential-factory.js +53 -0
  70. package/src/entities/credentials/factories/index.js +19 -0
  71. package/src/entities/credentials/index.js +23 -0
  72. package/src/entities/credentials/orchestrators/create-credentials.js +118 -0
  73. package/src/entities/credentials/orchestrators/index.js +19 -0
  74. package/src/entities/credentials/repo/finders-extension.js +94 -0
  75. package/src/entities/credentials/repo/index.js +19 -0
  76. package/src/entities/credentials/repo/repo.js +62 -0
  77. package/src/entities/credentials/repo/update-issued-credential.js +60 -0
  78. package/src/entities/depots/domain/depot-errors.js +23 -0
  79. package/src/entities/depots/domain/index.js +20 -0
  80. package/src/entities/depots/domain/validate-depot.js +38 -0
  81. package/src/entities/depots/factories/depot-factory.js +50 -0
  82. package/src/entities/depots/factories/index.js +19 -0
  83. package/src/entities/depots/index.js +22 -0
  84. package/src/entities/depots/orchestrators/create-depot.js +31 -0
  85. package/src/entities/depots/orchestrators/delete-depot.js +43 -0
  86. package/src/entities/depots/orchestrators/index.js +20 -0
  87. package/src/entities/depots/repo/find-depot-by-preauth-code.js +30 -0
  88. package/src/entities/depots/repo/find-depots-extension.js +34 -0
  89. package/src/entities/depots/repo/index.js +19 -0
  90. package/src/entities/depots/repo/refresh-preauth-code.js +30 -0
  91. package/src/entities/depots/repo/repo.js +61 -0
  92. package/src/entities/exchanges/adapters/index.js +17 -0
  93. package/src/entities/exchanges/adapters/sign-exchange-response.js +37 -0
  94. package/src/entities/exchanges/domain/authorize-exchange.js +29 -0
  95. package/src/entities/exchanges/domain/build-exchange-event.js +19 -0
  96. package/src/entities/exchanges/domain/build-presentation-request.js +174 -0
  97. package/src/entities/exchanges/domain/exchange-errors.js +28 -0
  98. package/src/entities/exchanges/domain/exchange-protocols.js +29 -0
  99. package/src/entities/exchanges/domain/exchange-states.js +53 -0
  100. package/src/entities/exchanges/domain/exchange-types.js +22 -0
  101. package/src/entities/exchanges/domain/generate-issuing-challenge.js +48 -0
  102. package/src/entities/exchanges/domain/index.js +32 -0
  103. package/src/entities/exchanges/domain/validate-message-settings.js +33 -0
  104. package/src/entities/exchanges/domain/validate-new-exchange.js +25 -0
  105. package/src/entities/exchanges/domain/validate-preauth.js +45 -0
  106. package/src/entities/exchanges/domain/validate-referenced-service.js +33 -0
  107. package/src/entities/exchanges/domain/verify-issuing-challenge.js +42 -0
  108. package/src/entities/exchanges/domain/verify-proof-of-key-possession.js +128 -0
  109. package/src/entities/exchanges/factories/index.js +19 -0
  110. package/src/entities/exchanges/factories/init-exchange-factory.js +58 -0
  111. package/src/entities/exchanges/hooks/exchange-error-hook.js +30 -0
  112. package/src/entities/exchanges/hooks/index.js +17 -0
  113. package/src/entities/exchanges/index.js +24 -0
  114. package/src/entities/exchanges/orchestrators/authenticate.js +67 -0
  115. package/src/entities/exchanges/orchestrators/credential-offer-request.js +70 -0
  116. package/src/entities/exchanges/orchestrators/get-credential-manifest.js +84 -0
  117. package/src/entities/exchanges/orchestrators/get-presentation-request.js +114 -0
  118. package/src/entities/exchanges/orchestrators/index.js +24 -0
  119. package/src/entities/exchanges/orchestrators/issue-credentials.js +132 -0
  120. package/src/entities/exchanges/orchestrators/post-presentation.js +58 -0
  121. package/src/entities/exchanges/repo/exchange-state-repo-extension.js +78 -0
  122. package/src/entities/exchanges/repo/index.js +19 -0
  123. package/src/entities/exchanges/repo/repo.js +52 -0
  124. package/src/entities/issuer-services/domain/index.js +20 -0
  125. package/src/entities/issuer-services/domain/issuer-services-errors.js +23 -0
  126. package/src/entities/issuer-services/domain/validate-issuer-service.js +23 -0
  127. package/src/entities/issuer-services/factories/index.js +19 -0
  128. package/src/entities/issuer-services/factories/issuer-service-factory.js +44 -0
  129. package/src/entities/issuer-services/index.js +21 -0
  130. package/src/entities/issuer-services/repo/find-issuer-services-extension.js +30 -0
  131. package/src/entities/issuer-services/repo/index.js +19 -0
  132. package/src/entities/issuer-services/repo/repo.js +59 -0
  133. package/src/entities/keys/adapters/index.js +19 -0
  134. package/src/entities/keys/adapters/load-primary-account.js +39 -0
  135. package/src/entities/keys/domain/cih-key-purposes.js +23 -0
  136. package/src/entities/keys/domain/get-key-with-purpose.js +22 -0
  137. package/src/entities/keys/domain/index.js +22 -0
  138. package/src/entities/keys/domain/key-errors.js +25 -0
  139. package/src/entities/keys/domain/normalize-tenant-key.js +33 -0
  140. package/src/entities/keys/domain/validate-tenant-keys.js +78 -0
  141. package/src/entities/keys/factories/index.js +19 -0
  142. package/src/entities/keys/factories/key-factory.js +61 -0
  143. package/src/entities/keys/index.js +22 -0
  144. package/src/entities/keys/plugins/index.js +17 -0
  145. package/src/entities/keys/plugins/kms-plugin.js +61 -0
  146. package/src/entities/links/domain/build-deep-link-url.js +58 -0
  147. package/src/entities/links/domain/build-openid4vci-credential-offer-link.js +31 -0
  148. package/src/entities/links/domain/build-openid4vp-authorization-request-link.js +36 -0
  149. package/src/entities/links/domain/build-redirect-url.js +29 -0
  150. package/src/entities/links/domain/build-vn-api-issuing-link.js +54 -0
  151. package/src/entities/links/domain/build-vn-api-presentation-link.js +49 -0
  152. package/src/entities/links/domain/index.js +28 -0
  153. package/src/entities/links/domain/is-preauth-code-auth.js +19 -0
  154. package/src/entities/links/domain/link-errors.js +23 -0
  155. package/src/entities/links/domain/validate-issue-link.js +39 -0
  156. package/src/entities/links/domain/validate-presentation-link.js +39 -0
  157. package/src/entities/links/index.js +20 -0
  158. package/src/entities/links/orchestrators/index.js +17 -0
  159. package/src/entities/links/orchestrators/refresh-links.js +139 -0
  160. package/src/entities/openid4vci/domain/index.js +20 -0
  161. package/src/entities/openid4vci/domain/openid4vci-errors.js +24 -0
  162. package/src/entities/openid4vci/domain/to-credential-configuration-id.js +21 -0
  163. package/src/entities/openid4vci/index.js +21 -0
  164. package/src/entities/openid4vci/orchestrators/create-access-token.js +85 -0
  165. package/src/entities/openid4vci/orchestrators/create-credential.js +108 -0
  166. package/src/entities/openid4vci/orchestrators/get-authorization-server-metadata.js +22 -0
  167. package/src/entities/openid4vci/orchestrators/get-credential-issuer-metadata.js +22 -0
  168. package/src/entities/openid4vci/orchestrators/handle-notification.js +94 -0
  169. package/src/entities/openid4vci/orchestrators/index.js +24 -0
  170. package/src/entities/openid4vci/plugins/index.js +19 -0
  171. package/src/entities/openid4vci/plugins/openid4vci-plugin.js +427 -0
  172. package/src/entities/openid4vp/domain/index.js +21 -0
  173. package/src/entities/openid4vp/domain/openid4vp-request-id.js +47 -0
  174. package/src/entities/openid4vp/domain/presentation-request-expiry.js +37 -0
  175. package/src/entities/openid4vp/domain/wallet-metadata.js +30 -0
  176. package/src/entities/openid4vp/index.js +21 -0
  177. package/src/entities/openid4vp/orchestrators/create-authorization-request.js +183 -0
  178. package/src/entities/openid4vp/orchestrators/index.js +20 -0
  179. package/src/entities/openid4vp/orchestrators/post-authorization-response.js +353 -0
  180. package/src/entities/openid4vp/plugins/index.js +19 -0
  181. package/src/entities/openid4vp/plugins/openid4vp-plugin.js +174 -0
  182. package/src/entities/presentations/domain/index.js +20 -0
  183. package/src/entities/presentations/domain/presentation-format.js +20 -0
  184. package/src/entities/presentations/domain/validate-presentation.js +178 -0
  185. package/src/entities/presentations/factories/index.js +19 -0
  186. package/src/entities/presentations/factories/presentation-factory.js +96 -0
  187. package/src/entities/presentations/index.js +21 -0
  188. package/src/entities/presentations/orchestrators/index.js +19 -0
  189. package/src/entities/presentations/orchestrators/verify-presentation.js +131 -0
  190. package/src/entities/presentations/repo/add-verification.js +31 -0
  191. package/src/entities/presentations/repo/finders-extension.js +50 -0
  192. package/src/entities/presentations/repo/index.js +19 -0
  193. package/src/entities/presentations/repo/repo.js +58 -0
  194. package/src/entities/relying-party-services/factories/index.js +19 -0
  195. package/src/entities/relying-party-services/factories/relying-party-service-factory.js +43 -0
  196. package/src/entities/relying-party-services/index.js +20 -0
  197. package/src/entities/relying-party-services/repo/find-relying-party-services-extension.js +30 -0
  198. package/src/entities/relying-party-services/repo/index.js +19 -0
  199. package/src/entities/relying-party-services/repo/repo.js +55 -0
  200. package/src/entities/service-configurations/domain/canonicalize-service-configuration.js +12 -0
  201. package/src/entities/service-configurations/domain/index.js +22 -0
  202. package/src/entities/service-configurations/domain/service-configuration-errors.js +24 -0
  203. package/src/entities/service-configurations/domain/validate-service-configuration.js +31 -0
  204. package/src/entities/service-configurations/domain/validate-update-service-configuration.js +19 -0
  205. package/src/entities/service-configurations/index.js +20 -0
  206. package/src/entities/service-configurations/orchestrators/create-service-configuration.js +34 -0
  207. package/src/entities/service-configurations/orchestrators/delete-service-configuration.js +41 -0
  208. package/src/entities/service-configurations/orchestrators/index.js +21 -0
  209. package/src/entities/service-configurations/orchestrators/update-service-configuration.js +40 -0
  210. package/src/entities/tenants/adapters/index.js +20 -0
  211. package/src/entities/tenants/adapters/load-tenant-did-doc.js +47 -0
  212. package/src/entities/tenants/adapters/load-tenant-profile.js +40 -0
  213. package/src/entities/tenants/domain/index.js +20 -0
  214. package/src/entities/tenants/domain/tenant-errors.js +29 -0
  215. package/src/entities/tenants/domain/validate-new-tenant.js +49 -0
  216. package/src/entities/tenants/factories/index.js +19 -0
  217. package/src/entities/tenants/factories/tenant-factory.js +41 -0
  218. package/src/entities/tenants/index.js +24 -0
  219. package/src/entities/tenants/orchestrators/create-tenant.js +116 -0
  220. package/src/entities/tenants/orchestrators/delete-tenant.js +45 -0
  221. package/src/entities/tenants/orchestrators/find-tenants.js +22 -0
  222. package/src/entities/tenants/orchestrators/index.js +21 -0
  223. package/src/entities/tenants/plugins/index.js +3 -0
  224. package/src/entities/tenants/plugins/tenant-loader-plugin.js +64 -0
  225. package/src/entities/tenants/repo/index.js +19 -0
  226. package/src/entities/tenants/repo/insert-tenant-extension.js +36 -0
  227. package/src/entities/tenants/repo/repo.js +51 -0
  228. package/src/entities/tokens/domains/access-token.js +74 -0
  229. package/src/entities/tokens/domains/index.js +19 -0
  230. package/src/entities/tokens/index.js +19 -0
  231. package/src/index.js +3 -0
  232. package/src/init-server.js +88 -0
  233. package/src/main.js +25 -0
  234. package/src/schemas/index.js +20 -0
  235. package/src/schemas/oauth-error-response.schema.js +27 -0
  236. package/src/standalone.js +8 -0
  237. package/src/start-app-server.js +27 -0
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Copyright 2024 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 newError = require('http-errors');
18
+ const { isEmpty } = require('lodash/fp');
19
+ const { DepotErrors } = require('./depot-errors');
20
+
21
+ const validateDepot = (depot, service) => {
22
+ if (service == null) {
23
+ throw newError(400, DepotErrors.REFERENCED_SERVICE_NOT_FOUND, {
24
+ errorCode: DepotErrors.REFERENCED_SERVICE_NOT_FOUND,
25
+ });
26
+ }
27
+ if (
28
+ service.authMode === 'internal' &&
29
+ service.authMethods.includes('verifiable_presentation') &&
30
+ isEmpty(depot.authValues)
31
+ ) {
32
+ throw newError(400, DepotErrors.INVALID_AUTH_VALUES, {
33
+ errorCode: DepotErrors.INVALID_AUTH_VALUES,
34
+ });
35
+ }
36
+ };
37
+
38
+ module.exports = { validateDepot };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Copyright 2023 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 { register } = require('@spencejs/spence-factories');
18
+ const { nanoid } = require('nanoid');
19
+ const { ObjectId } = require('mongodb');
20
+ const { calcSha384 } = require('@verii/crypto');
21
+ const { depotRepoPlugin } = require('../repo');
22
+ const { initTenantFactory } = require('../../tenants');
23
+ const { initIssuerServiceFactory } = require('../../issuer-services');
24
+
25
+ const initDepotFactory = (app) =>
26
+ register(
27
+ 'depot',
28
+ depotRepoPlugin(app)({ config: app.config }),
29
+ async (overrides, { getOrBuild }) => {
30
+ const tenant = await getOrBuild('tenant', initTenantFactory(app));
31
+ const service = await getOrBuild(
32
+ 'service',
33
+ initIssuerServiceFactory(app),
34
+ );
35
+ const preauthCode = await getOrBuild('preauthCode', () => undefined);
36
+ const depot = {
37
+ tenantId: new ObjectId(tenant._id),
38
+ serviceId: new ObjectId(service._id),
39
+ preauthCodeHash:
40
+ preauthCode != null ? calcSha384(preauthCode) : undefined,
41
+ ...overrides(),
42
+ };
43
+ if (service.authMode) {
44
+ depot.userReference = nanoid();
45
+ }
46
+ return depot;
47
+ },
48
+ );
49
+
50
+ module.exports = { initDepotFactory };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright 2023 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 = {
18
+ ...require('./depot-factory'),
19
+ };
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright 2024 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 = {
18
+ ...require('./domain'),
19
+ ...require('./factories'),
20
+ ...require('./orchestrators'),
21
+ ...require('./repo'),
22
+ };
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright 2024 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 { ObjectId } = require('mongodb');
18
+ const { validateDepot } = require('../domain');
19
+
20
+ const createDepot = async (newDepot, serviceId, { repos }) => {
21
+ const service = await repos.issuerServices.findOne({
22
+ filter: { _id: serviceId },
23
+ });
24
+ validateDepot(newDepot, service);
25
+ return repos.depots.insert({
26
+ ...newDepot,
27
+ serviceId: new ObjectId(serviceId),
28
+ });
29
+ };
30
+
31
+ module.exports = { createDepot };
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Copyright 2024 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 { ObjectId } = require('mongodb');
18
+ const { isEmpty, map } = require('lodash/fp');
19
+ const newError = require('http-errors');
20
+ const { DepotErrors } = require('../domain');
21
+
22
+ const deleteDepot = async (depotId, serviceId, { repos }) => {
23
+ const credentials = await repos.credentials.findByDepotId({ depotId });
24
+ if (!isEmpty(credentials)) {
25
+ throw newError(
26
+ 400,
27
+ `Credentials(s) ${map('_id')(
28
+ credentials,
29
+ )} must be deleted before deleting depot ${depotId}`,
30
+ {
31
+ errorCode: DepotErrors.RELATED_CREDENTIAL_UNDELETED,
32
+ },
33
+ );
34
+ }
35
+ return repos.depots.delUsingFilter({
36
+ filter: {
37
+ _id: depotId,
38
+ serviceId: new ObjectId(serviceId),
39
+ },
40
+ });
41
+ };
42
+
43
+ module.exports = { deleteDepot };
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright 2024 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 = {
18
+ ...require('./create-depot'),
19
+ ...require('./delete-depot'),
20
+ };
@@ -0,0 +1,30 @@
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 { calcSha384 } = require('@verii/crypto');
18
+
19
+ const findDepotByPreauthCodeExtension = (parent) => ({
20
+ findDepotByPreauthCode: async (preauthCode) => {
21
+ const depot = await parent.findOne({
22
+ filter: {
23
+ preauthCodeHash: calcSha384(preauthCode),
24
+ },
25
+ });
26
+ return depot;
27
+ },
28
+ });
29
+
30
+ module.exports = { findDepotByPreauthCodeExtension };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright 2024 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 { isEmpty, map } = require('lodash/fp');
18
+ const { ObjectId } = require('mongodb');
19
+
20
+ const findDepotsExtension = (parent) => ({
21
+ findDepots: async (serviceId, depotIds) => {
22
+ const filter = {};
23
+ if (serviceId) {
24
+ filter.serviceId = new ObjectId(serviceId);
25
+ }
26
+ if (!isEmpty(depotIds)) {
27
+ filter._id = { $in: map((id) => new ObjectId(id), depotIds) };
28
+ }
29
+ return parent.find({ filter });
30
+ },
31
+ extensions: parent.extensions.concat(['findDepotsExtension']),
32
+ });
33
+
34
+ module.exports = { findDepotsExtension };
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright 2024 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 = {
18
+ depotRepoPlugin: require('./repo'),
19
+ };
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright 2024 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 { nanoid } = require('nanoid');
18
+ const { calcSha384 } = require('@verii/crypto');
19
+
20
+ const refreshPreauthCodeExtension = (parent) => ({
21
+ refreshPreauthCode: async (depotId) => {
22
+ const preauthCode = nanoid(16);
23
+ const depot = await parent.update(depotId, {
24
+ preauthCodeHash: calcSha384(preauthCode),
25
+ });
26
+ return { ...depot, preauthCode };
27
+ },
28
+ });
29
+
30
+ module.exports = { refreshPreauthCodeExtension };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Copyright 2023 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 {
18
+ repoFactory,
19
+ autoboxIdsExtension,
20
+ mongoDb,
21
+ } = require('@spencejs/spence-mongo-repos');
22
+ const { multitenantExtension } = require('@verii/spencer-mongo-extensions');
23
+ const { findDepotsExtension } = require('./find-depots-extension');
24
+ const { refreshPreauthCodeExtension } = require('./refresh-preauth-code');
25
+ const {
26
+ findDepotByPreauthCodeExtension,
27
+ } = require('./find-depot-by-preauth-code');
28
+
29
+ module.exports = (app, options, next = () => {}) => {
30
+ app.ready(async () => {
31
+ await mongoDb()
32
+ .collection('depots')
33
+ .createIndex({ tenantId: 1, preauthCodeHash: 1 });
34
+ });
35
+ next();
36
+ return repoFactory(
37
+ {
38
+ name: 'depots',
39
+ entityName: 'depot',
40
+ defaultProjection: {
41
+ _id: 1,
42
+ userReference: 1,
43
+ authValues: 1,
44
+ serviceId: 1,
45
+ messagingSettings: 1,
46
+ preauthCodeHash: 1,
47
+ tenantId: 1,
48
+ createdAt: 1,
49
+ updatedAt: 1,
50
+ },
51
+ extensions: [
52
+ autoboxIdsExtension,
53
+ multitenantExtension(),
54
+ findDepotsExtension,
55
+ findDepotByPreauthCodeExtension,
56
+ refreshPreauthCodeExtension,
57
+ ],
58
+ },
59
+ app,
60
+ );
61
+ };
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright 2024 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('./sign-exchange-response') };
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright 2024 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 { KeyPurposes } = require('@verii/crypto');
19
+ const { toDidUrl } = require('@verii/did-doc');
20
+
21
+ const signExchangeResponse = async (
22
+ credentialManifest,
23
+ options = {}, // eslint-disable-line default-param-last
24
+ { kms, tenant },
25
+ ) => {
26
+ const exchangesKey = tenant.keysByPurpose[KeyPurposes.EXCHANGES];
27
+ return kms.signJwt(credentialManifest, exchangesKey._id, {
28
+ jti: credentialManifest.id,
29
+ issuer: tenant.did,
30
+ kid: toDidUrl(tenant.did, exchangesKey.kidFragment),
31
+ nbf: new Date(),
32
+ expiresIn: '1w',
33
+ ...options,
34
+ });
35
+ };
36
+
37
+ module.exports = { signExchangeResponse };
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright 2024 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 newError = require('http-errors');
18
+
19
+ const authorizeExchange = (exchange, depotId) => {
20
+ if (
21
+ exchange == null ||
22
+ exchange.depotId == null ||
23
+ exchange.depotId.toString() !== depotId
24
+ ) {
25
+ throw newError(401, 'Unauthorized');
26
+ }
27
+ };
28
+
29
+ module.exports = { authorizeExchange };
@@ -0,0 +1,19 @@
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 buildExchangeEvent = (state) => ({ state, timestamp: new Date() });
18
+
19
+ module.exports = { buildExchangeEvent };
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Copyright 2023 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 { applyOverrides } = require('@verii/common-functions');
18
+ const { find, map, omit } = require('lodash/fp');
19
+
20
+ const DEFAULT_GROUP_ID = 'A';
21
+
22
+ const buildCredentialManifest = (
23
+ tenant,
24
+ issuerService,
25
+ exchange,
26
+ inputDescriptors,
27
+ outputDescriptors,
28
+ ) => {
29
+ const baseUrl = buildBaseUrl(tenant);
30
+ const overrides = {
31
+ output_descriptors: outputDescriptors,
32
+ issuer: { id: tenant.did },
33
+ 'metadata.submit_presentation_uri': `${baseUrl}/authenticate`,
34
+ 'metadata.check_offers_uri': `${baseUrl}/credential-offers`,
35
+ 'metadata.finalize_offers_uri': `${baseUrl}/issue-credentials`,
36
+ };
37
+
38
+ return buildBasePresentationRequest(
39
+ tenant,
40
+ issuerService,
41
+ exchange,
42
+ inputDescriptors,
43
+ {
44
+ rule: 'all',
45
+ from: DEFAULT_GROUP_ID,
46
+ min: issuerService.disclosureRequest?.types?.length,
47
+ },
48
+ overrides,
49
+ );
50
+ };
51
+
52
+ const buildPresentationRequest = (
53
+ tenant,
54
+ service,
55
+ exchange,
56
+ inputDescriptors,
57
+ ) => {
58
+ const baseUrl = buildBaseUrl(tenant);
59
+ return buildBasePresentationRequest(
60
+ tenant,
61
+ service,
62
+ exchange,
63
+ inputDescriptors,
64
+ {
65
+ rule: 'pick',
66
+ from: DEFAULT_GROUP_ID,
67
+ min: 1,
68
+ },
69
+ {
70
+ 'metadata.submit_presentation_uri': `${baseUrl}/presentation`,
71
+ 'metadata.auth_token_uri': `${baseUrl}/oauth/token`,
72
+ },
73
+ );
74
+ };
75
+
76
+ const buildBasePresentationRequest = (
77
+ tenant,
78
+ service,
79
+ exchange,
80
+ inputDescriptors,
81
+ submissionRequirements,
82
+ overrides,
83
+ ) => {
84
+ const presentationRequest = {
85
+ exchange_id: exchange._id,
86
+ metadata: buildMetadata(tenant, service),
87
+ presentation_definition: buildPresentationDefinition(
88
+ service,
89
+ exchange,
90
+ inputDescriptors,
91
+ submissionRequirements,
92
+ ),
93
+ };
94
+
95
+ return applyOverrides(presentationRequest, overrides);
96
+ };
97
+
98
+ const buildPresentationDefinition = (
99
+ service,
100
+ exchange,
101
+ rawInputDescriptors,
102
+ submissionRequirements,
103
+ ) => {
104
+ const id = `${exchange._id}.${service._id}`;
105
+ const format = {
106
+ jwt_vp: { alg: ['secp256k1'] }, // hardcoded
107
+ };
108
+
109
+ if (service.presentationDefinition) {
110
+ return buildConfiguredPresentationDefinition(service, id, format);
111
+ }
112
+
113
+ const inputDescriptors = buildInputDescriptors(
114
+ service.disclosureRequest?.types,
115
+ rawInputDescriptors,
116
+ );
117
+
118
+ return {
119
+ id,
120
+ purpose: service.disclosureRequest?.purpose ?? '',
121
+ name: service.description,
122
+ format,
123
+ input_descriptors: inputDescriptors,
124
+ submission_requirements: submissionRequirements.min
125
+ ? [submissionRequirements]
126
+ : [],
127
+ };
128
+ };
129
+
130
+ const buildConfiguredPresentationDefinition = (service, id, format) => {
131
+ const presentationDefinition = omit(['id'], service.presentationDefinition);
132
+ return {
133
+ purpose: service.presentationDefinition.purpose,
134
+ name: service.description,
135
+ format,
136
+ ...presentationDefinition,
137
+ // The presentation-definition id binds the eventual submission to this
138
+ // exchange and service, so caller-provided presentationDefinition.id is
139
+ // ignored.
140
+ id,
141
+ };
142
+ };
143
+
144
+ const buildBaseUrl = (tenant) =>
145
+ `${tenant.hostUrl}/vn-api/r/${encodeURI(tenant.did)}`;
146
+
147
+ const buildMetadata = (tenant, service) => {
148
+ const metadata = {
149
+ client_name: tenant.name,
150
+ logo_uri: tenant.logo,
151
+ tos_uri: service.termsUrl,
152
+ progress_uri: `${buildBaseUrl(tenant)}/get-exchange-progress`,
153
+ };
154
+
155
+ if (!service.authMode) {
156
+ metadata.feed = service.mode === 'feed';
157
+ }
158
+
159
+ metadata.max_retention_period =
160
+ service.disclosureRequest?.retentionPeriod ?? '';
161
+
162
+ return metadata;
163
+ };
164
+
165
+ const buildInputDescriptors = (types, rawInputDescriptors) =>
166
+ map(
167
+ ({ type }) => ({
168
+ ...find({ id: type }, rawInputDescriptors),
169
+ group: [DEFAULT_GROUP_ID],
170
+ }),
171
+ types,
172
+ );
173
+
174
+ module.exports = { buildPresentationRequest, buildCredentialManifest };