@verii/server-credentialagent 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 (395) hide show
  1. package/.localdev.e2e.env +40 -0
  2. package/.localdev.env +41 -0
  3. package/.standalone.env +5 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +1 -0
  6. package/README.md +19 -0
  7. package/docker/compose.yml +33 -0
  8. package/e2e/README.md +12 -0
  9. package/e2e/org-registration-and-issuing.e2e.test.js +624 -0
  10. package/jest.config.js +20 -0
  11. package/migrate-mongo.config.js +36 -0
  12. package/migrations/20210317133137-add-index-to-offers-repo.js +57 -0
  13. package/migrations/20210416145639-add-index-to-revocation-list.js +27 -0
  14. package/migrations/20210719120225-add_unique_did_index_to_tenant.js +45 -0
  15. package/migrations/20230524053029-add-vendorUserIdMappings-index.js +32 -0
  16. package/migrations/20230616111907-add-configuration-type-index.js +32 -0
  17. package/package.json +108 -0
  18. package/src/assets/public/favicon.ico +0 -0
  19. package/src/assets/public/logo192.png +0 -0
  20. package/src/assets/public/logo512.png +0 -0
  21. package/src/assets/public/manifest.json +28 -0
  22. package/src/assets/templates/app-redirect.hbs +16 -0
  23. package/src/config/config.js +44 -0
  24. package/src/config/core-config.js +143 -0
  25. package/src/config/holder-config.js +104 -0
  26. package/src/config/index.js +22 -0
  27. package/src/config/operator-config.js +64 -0
  28. package/src/controllers/autoload-holder-api-controllers.js +30 -0
  29. package/src/controllers/autoload-operator-api-controllers.js +31 -0
  30. package/src/controllers/autoload-root-api-controller.js +30 -0
  31. package/src/controllers/autoload-saasoperator-api-controllers.js +31 -0
  32. package/src/controllers/holder/autohooks.js +55 -0
  33. package/src/controllers/holder/get-exchange-progress/autohooks.js +27 -0
  34. package/src/controllers/holder/get-exchange-progress/controller.js +50 -0
  35. package/src/controllers/holder/inspect/autohooks.js +35 -0
  36. package/src/controllers/holder/inspect/get-presentation-request/controller.js +100 -0
  37. package/src/controllers/holder/inspect/schemas/holder-disclosure.schema.json +73 -0
  38. package/src/controllers/holder/inspect/schemas/index.js +33 -0
  39. package/src/controllers/holder/inspect/schemas/presentation-definition.v1.schema.json +461 -0
  40. package/src/controllers/holder/inspect/schemas/presentation-request.schema.json +279 -0
  41. package/src/controllers/holder/inspect/schemas/presentation-submission.schema.json +41 -0
  42. package/src/controllers/holder/inspect/schemas/siop-presentation-submission.schema.json +74 -0
  43. package/src/controllers/holder/inspect/schemas/velocity-presentation-submission.response.200.schema.json +36 -0
  44. package/src/controllers/holder/inspect/schemas/velocity-presentation-submission.schema.json +34 -0
  45. package/src/controllers/holder/inspect/submit-presentation/controller.js +89 -0
  46. package/src/controllers/holder/issue/autohooks.js +23 -0
  47. package/src/controllers/holder/issue/get-credential-manifest/controller.js +193 -0
  48. package/src/controllers/holder/issue/offers/autohooks.js +35 -0
  49. package/src/controllers/holder/issue/offers/controller.js +164 -0
  50. package/src/controllers/holder/issue/offers/credential-offers/controller.js +460 -0
  51. package/src/controllers/holder/issue/submit-identification/autohooks.js +37 -0
  52. package/src/controllers/holder/issue/submit-identification/controller.js +63 -0
  53. package/src/controllers/holder/oauth/autohooks.js +19 -0
  54. package/src/controllers/holder/oauth/controller.js +140 -0
  55. package/src/controllers/index.js +22 -0
  56. package/src/controllers/operator/tenants/_tenantId/autohooks.js +40 -0
  57. package/src/controllers/operator/tenants/_tenantId/check-credentials/autohooks.js +24 -0
  58. package/src/controllers/operator/tenants/_tenantId/check-credentials/controller-v0.8.js +200 -0
  59. package/src/controllers/operator/tenants/_tenantId/check-credentials/schemas/index.js +19 -0
  60. package/src/controllers/operator/tenants/_tenantId/check-credentials/schemas/vendor-credential.schema.json +244 -0
  61. package/src/controllers/operator/tenants/_tenantId/controller-v0.8.js +221 -0
  62. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/autohooks.js +30 -0
  63. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/controller-v0.8.js +271 -0
  64. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/autohooks.js +45 -0
  65. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/controller-v0.8.js +199 -0
  66. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/add-feed.schema.js +14 -0
  67. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/feed.schema.json +27 -0
  68. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/index.js +25 -0
  69. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/modify-feed-update-body.schema.js +18 -0
  70. package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/modify-feed.schema.json +19 -0
  71. package/src/controllers/operator/tenants/_tenantId/disclosures/autohooks.js +34 -0
  72. package/src/controllers/operator/tenants/_tenantId/disclosures/controller-v0.8.js +100 -0
  73. package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/agent-disclosure-presentation-definition.schema.json +404 -0
  74. package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/agent-disclosure.schema.js +24 -0
  75. package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/index.js +29 -0
  76. package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/new-agent-disclosure.schema.json +166 -0
  77. package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/update-agent-disclosure.schema.js +20 -0
  78. package/src/controllers/operator/tenants/_tenantId/exchanges/_exchangeId/autohooks.js +30 -0
  79. package/src/controllers/operator/tenants/_tenantId/exchanges/_exchangeId/controller-v0.8.js +73 -0
  80. package/src/controllers/operator/tenants/_tenantId/exchanges/autohooks.js +19 -0
  81. package/src/controllers/operator/tenants/_tenantId/exchanges/controller-v0.8.js +150 -0
  82. package/src/controllers/operator/tenants/_tenantId/exchanges/schemas/get-exchange.response.body.json +147 -0
  83. package/src/controllers/operator/tenants/_tenantId/exchanges/schemas/index.js +21 -0
  84. package/src/controllers/operator/tenants/_tenantId/issued-credentials/autohooks.js +27 -0
  85. package/src/controllers/operator/tenants/_tenantId/issued-credentials/controller-v0.8.js +303 -0
  86. package/src/controllers/operator/tenants/_tenantId/issued-credentials/schemas/index.js +23 -0
  87. package/src/controllers/operator/tenants/_tenantId/issued-credentials/schemas/issued-credential.schema.json +115 -0
  88. package/src/controllers/operator/tenants/_tenantId/issued-credentials/schemas/revoke-credentials.schema.json +18 -0
  89. package/src/controllers/operator/tenants/_tenantId/keys/controller-v0.8.js +168 -0
  90. package/src/controllers/operator/tenants/_tenantId/offer-data/controller-v0.8.js +78 -0
  91. package/src/controllers/operator/tenants/_tenantId/offers/autohooks.js +34 -0
  92. package/src/controllers/operator/tenants/_tenantId/offers/controller-v0.8.js +253 -0
  93. package/src/controllers/operator/tenants/_tenantId/offers/schemas/index.js +23 -0
  94. package/src/controllers/operator/tenants/_tenantId/offers/schemas/new-vendor-offer.schema.js +47 -0
  95. package/src/controllers/operator/tenants/_tenantId/offers/schemas/vendor-offer.schema.json +56 -0
  96. package/src/controllers/operator/tenants/_tenantId/users/autohooks.js +24 -0
  97. package/src/controllers/operator/tenants/_tenantId/users/controller-v0.8.js +92 -0
  98. package/src/controllers/operator/tenants/_tenantId/users/schemas/index.js +23 -0
  99. package/src/controllers/operator/tenants/_tenantId/users/schemas/new-user.schema.json +13 -0
  100. package/src/controllers/operator/tenants/_tenantId/users/schemas/user.schema.json +16 -0
  101. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/autohooks.js +34 -0
  102. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/controller-v0.8.js +110 -0
  103. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/Credential.schema.js +18 -0
  104. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/IssueCredentialOptions.schema.json +42 -0
  105. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/IssueCredentialRequest.schema.json +13 -0
  106. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/IssueCredentialResponse.schema.json +19 -0
  107. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/LinkedDataProof.schema.json +43 -0
  108. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/VerifiableCredential.schema.js +16 -0
  109. package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/index.js +31 -0
  110. package/src/controllers/operator/tenants/autohooks.js +65 -0
  111. package/src/controllers/operator/tenants/controller-v0.8.js +167 -0
  112. package/src/controllers/operator/tenants/schemas/index.js +41 -0
  113. package/src/controllers/operator/tenants/schemas/modify-secret.schema.json +11 -0
  114. package/src/controllers/operator/tenants/schemas/modify-tenant-v0.8.schema.json +44 -0
  115. package/src/controllers/operator/tenants/schemas/new-tenant-v0.8.schema.json +19 -0
  116. package/src/controllers/operator/tenants/schemas/new-tenant.response.200.schema.json +7 -0
  117. package/src/controllers/operator/tenants/schemas/secret-key-metadata.schema.json +31 -0
  118. package/src/controllers/operator/tenants/schemas/secret-key.schema.json +29 -0
  119. package/src/controllers/operator/tenants/schemas/secret-kid.schema.json +13 -0
  120. package/src/controllers/operator/tenants/schemas/secret-new-tenant-v0.8.schema.json +28 -0
  121. package/src/controllers/operator/tenants/schemas/secret-tenant-key-v0.8.schema.json +13 -0
  122. package/src/controllers/operator/tenants/schemas/tenant-key-v0.8.schema.json +14 -0
  123. package/src/controllers/operator/tenants/schemas/tenant-v0.8.schema.json +62 -0
  124. package/src/controllers/root/autohooks.js +23 -0
  125. package/src/controllers/root/controller.js +173 -0
  126. package/src/controllers/saasoperator/groups/_id/autohooks.js +9 -0
  127. package/src/controllers/saasoperator/groups/_id/controller.js +121 -0
  128. package/src/controllers/saasoperator/groups/autohooks.js +19 -0
  129. package/src/controllers/saasoperator/groups/controller.js +65 -0
  130. package/src/controllers/saasoperator/groups/schemas/group.schema.js +17 -0
  131. package/src/controllers/saasoperator/groups/schemas/index.js +4 -0
  132. package/src/controllers/saasoperator/groups/schemas/new-group.schema.js +13 -0
  133. package/src/entities/common/domains/get-json-at-path.js +28 -0
  134. package/src/entities/common/domains/index.js +17 -0
  135. package/src/entities/common/index.js +17 -0
  136. package/src/entities/credentials/domains/credential-format.js +22 -0
  137. package/src/entities/credentials/domains/index.js +19 -0
  138. package/src/entities/credentials/index.js +17 -0
  139. package/src/entities/deep-links/domains/extract-did.js +11 -0
  140. package/src/entities/deep-links/domains/index.js +20 -0
  141. package/src/entities/deep-links/domains/velocity-protocol-uri-to-http-uri.js +32 -0
  142. package/src/entities/deep-links/index.js +19 -0
  143. package/src/entities/disclosures/domains/assert-disclosure-active.js +21 -0
  144. package/src/entities/disclosures/domains/compute-disclosure-configuration-type.js +29 -0
  145. package/src/entities/disclosures/domains/constants.js +61 -0
  146. package/src/entities/disclosures/domains/errors.js +34 -0
  147. package/src/entities/disclosures/domains/get-disclosure-configuration-type.js +60 -0
  148. package/src/entities/disclosures/domains/index.js +32 -0
  149. package/src/entities/disclosures/domains/is-issuing-disclosure.js +23 -0
  150. package/src/entities/disclosures/domains/parse-body-to-disclosure.js +17 -0
  151. package/src/entities/disclosures/domains/validate-by-identification-method.js +69 -0
  152. package/src/entities/disclosures/domains/validate-commercial-entity.js +26 -0
  153. package/src/entities/disclosures/domains/validate-disclosure-by-configuration-type.js +47 -0
  154. package/src/entities/disclosures/domains/validate-disclosure-default-issuing.js +77 -0
  155. package/src/entities/disclosures/domains/validate-disclosure.js +37 -0
  156. package/src/entities/disclosures/domains/validate-feed.js +16 -0
  157. package/src/entities/disclosures/domains/validate-presentation-definition.js +54 -0
  158. package/src/entities/disclosures/domains/validate-vendor-endpoint.js +22 -0
  159. package/src/entities/disclosures/domains/validate-vendor-webhook.js +18 -0
  160. package/src/entities/disclosures/factories/disclosure-factory.js +94 -0
  161. package/src/entities/disclosures/factories/index.js +19 -0
  162. package/src/entities/disclosures/index.js +22 -0
  163. package/src/entities/disclosures/orchestrators/get-disclosure.js +18 -0
  164. package/src/entities/disclosures/orchestrators/index.js +20 -0
  165. package/src/entities/disclosures/orchestrators/update-disclosure-configuration-type.js +32 -0
  166. package/src/entities/disclosures/repos/index.js +20 -0
  167. package/src/entities/disclosures/repos/repo.js +118 -0
  168. package/src/entities/disclosures/repos/set-configuration-type.js +33 -0
  169. package/src/entities/exchanges/adapters/index.js +17 -0
  170. package/src/entities/exchanges/adapters/sign-exchange-response.js +45 -0
  171. package/src/entities/exchanges/domains/build-exchange-progress.js +56 -0
  172. package/src/entities/exchanges/domains/constants.js +24 -0
  173. package/src/entities/exchanges/domains/ensure-exchange-state-valid.js +35 -0
  174. package/src/entities/exchanges/domains/errors.js +33 -0
  175. package/src/entities/exchanges/domains/index.js +25 -0
  176. package/src/entities/exchanges/domains/states.js +43 -0
  177. package/src/entities/exchanges/domains/types.js +31 -0
  178. package/src/entities/exchanges/factories/disclosure-exchange-factory.js +46 -0
  179. package/src/entities/exchanges/factories/index.js +20 -0
  180. package/src/entities/exchanges/factories/offer-exchange-factory.js +48 -0
  181. package/src/entities/exchanges/index.js +23 -0
  182. package/src/entities/exchanges/orchestrators/build-exchange-request-deep-link.js +50 -0
  183. package/src/entities/exchanges/orchestrators/index.js +19 -0
  184. package/src/entities/exchanges/repos/exchange-repo-projections.js +45 -0
  185. package/src/entities/exchanges/repos/exchange-state-repo-extension.js +76 -0
  186. package/src/entities/exchanges/repos/index.js +20 -0
  187. package/src/entities/exchanges/repos/repo.js +44 -0
  188. package/src/entities/feeds/factories/feed-factory.js +47 -0
  189. package/src/entities/feeds/factories/index.js +19 -0
  190. package/src/entities/feeds/index.js +20 -0
  191. package/src/entities/feeds/repos/index.js +19 -0
  192. package/src/entities/feeds/repos/repo.js +95 -0
  193. package/src/entities/groups/domains/format-group.js +11 -0
  194. package/src/entities/groups/domains/index.js +3 -0
  195. package/src/entities/groups/factories/group-factory.js +40 -0
  196. package/src/entities/groups/factories/index.js +19 -0
  197. package/src/entities/groups/index.js +22 -0
  198. package/src/entities/groups/orchestrators/find-group-or-error.js +16 -0
  199. package/src/entities/groups/orchestrators/index.js +6 -0
  200. package/src/entities/groups/orchestrators/validate-did.js +24 -0
  201. package/src/entities/groups/orchestrators/validate-group-by-user.js +16 -0
  202. package/src/entities/groups/orchestrators/validate-group.js +39 -0
  203. package/src/entities/groups/repos/delete-tenant-extension.js +13 -0
  204. package/src/entities/groups/repos/index.js +19 -0
  205. package/src/entities/groups/repos/repo.js +38 -0
  206. package/src/entities/groups/repos/update-or-error-extension.js +46 -0
  207. package/src/entities/index.js +37 -0
  208. package/src/entities/keys/domains/constants.js +37 -0
  209. package/src/entities/keys/domains/index.js +21 -0
  210. package/src/entities/keys/domains/is-matching-private-key-kid.js +41 -0
  211. package/src/entities/keys/domains/validate-key.js +62 -0
  212. package/src/entities/keys/factories/index.js +19 -0
  213. package/src/entities/keys/factories/key-factory.js +56 -0
  214. package/src/entities/keys/index.js +22 -0
  215. package/src/entities/keys/orchestrators/index.js +3 -0
  216. package/src/entities/keys/orchestrators/validate-did-doc-keys.js +69 -0
  217. package/src/entities/metadata-list-allocations/index.js +19 -0
  218. package/src/entities/metadata-list-allocations/repos/index.js +19 -0
  219. package/src/entities/metadata-list-allocations/repos/repo.js +40 -0
  220. package/src/entities/notifications/domains/index.js +19 -0
  221. package/src/entities/notifications/domains/notification-types.js +25 -0
  222. package/src/entities/notifications/index.js +19 -0
  223. package/src/entities/offers/domains/build-clean-pii-filter.js +35 -0
  224. package/src/entities/offers/domains/build-deeplink-url.js +120 -0
  225. package/src/entities/offers/domains/build-offer.js +88 -0
  226. package/src/entities/offers/domains/build-qr-code-url.js +37 -0
  227. package/src/entities/offers/domains/constants.js +32 -0
  228. package/src/entities/offers/domains/filter-object-ids.js +34 -0
  229. package/src/entities/offers/domains/generate-issuing-challenge.js +26 -0
  230. package/src/entities/offers/domains/generate-link-code.js +35 -0
  231. package/src/entities/offers/domains/index.js +31 -0
  232. package/src/entities/offers/domains/post-validation-offers-handler.js +31 -0
  233. package/src/entities/offers/domains/prepare-linked-credentials-for-holder.js +36 -0
  234. package/src/entities/offers/domains/resolve-subject.js +142 -0
  235. package/src/entities/offers/domains/validate-offer-commercial-entity.js +24 -0
  236. package/src/entities/offers/domains/validate-offer.js +90 -0
  237. package/src/entities/offers/factories/index.js +19 -0
  238. package/src/entities/offers/factories/offer-factory.js +119 -0
  239. package/src/entities/offers/index.js +22 -0
  240. package/src/entities/offers/orchestrators/create-verifiable-credentials.js +131 -0
  241. package/src/entities/offers/orchestrators/finalize-exchange.js +44 -0
  242. package/src/entities/offers/orchestrators/index.js +23 -0
  243. package/src/entities/offers/orchestrators/load-credential-refs.js +57 -0
  244. package/src/entities/offers/orchestrators/load-credential-types-map.js +44 -0
  245. package/src/entities/offers/orchestrators/prepare-offers.js +35 -0
  246. package/src/entities/offers/orchestrators/trigger-issued-credentials-webhook.js +63 -0
  247. package/src/entities/offers/repos/clean-pii-extension.js +85 -0
  248. package/src/entities/offers/repos/index.js +20 -0
  249. package/src/entities/offers/repos/issued-credential-projection.js +44 -0
  250. package/src/entities/offers/repos/repo.js +177 -0
  251. package/src/entities/presentations/domains/build-identity-doc.js +120 -0
  252. package/src/entities/presentations/domains/build-request-response-schema.js +46 -0
  253. package/src/entities/presentations/domains/build-vendor-data.js +31 -0
  254. package/src/entities/presentations/domains/check-payment-requirement.js +30 -0
  255. package/src/entities/presentations/domains/errors.js +28 -0
  256. package/src/entities/presentations/domains/extract-fields-from-id-credential.js +35 -0
  257. package/src/entities/presentations/domains/index.js +26 -0
  258. package/src/entities/presentations/domains/merge-credential-check-results.js +24 -0
  259. package/src/entities/presentations/domains/validate-presentation.js +128 -0
  260. package/src/entities/presentations/index.js +20 -0
  261. package/src/entities/presentations/orchestrators/create-presentation-request.js +148 -0
  262. package/src/entities/presentations/orchestrators/deduplicate-disclosure-exchange.js +52 -0
  263. package/src/entities/presentations/orchestrators/handle-presentation-submission.js +47 -0
  264. package/src/entities/presentations/orchestrators/index.js +20 -0
  265. package/src/entities/presentations/orchestrators/match-identity-on-exchange.js +114 -0
  266. package/src/entities/presentations/orchestrators/share-identification-credentials.js +110 -0
  267. package/src/entities/presentations/orchestrators/share-presentation.js +234 -0
  268. package/src/entities/push-delegate/get-push-delegate.js +37 -0
  269. package/src/entities/push-delegate/index.js +17 -0
  270. package/src/entities/redirect/index.js +3 -0
  271. package/src/entities/redirect/orchestrators/index.js +3 -0
  272. package/src/entities/redirect/orchestrators/load-org-info.js +40 -0
  273. package/src/entities/revocation-list-allocations/index.js +19 -0
  274. package/src/entities/revocation-list-allocations/repos/index.js +19 -0
  275. package/src/entities/revocation-list-allocations/repos/repo.js +40 -0
  276. package/src/entities/schemas/index.js +19 -0
  277. package/src/entities/schemas/orchestrators/index.js +19 -0
  278. package/src/entities/schemas/orchestrators/load-schema-validation.js +73 -0
  279. package/src/entities/tenants/domains/build-service-ids.js +27 -0
  280. package/src/entities/tenants/domains/extract-service.js +27 -0
  281. package/src/entities/tenants/domains/index.js +21 -0
  282. package/src/entities/tenants/domains/validate-service-ids.js +35 -0
  283. package/src/entities/tenants/factories/index.js +19 -0
  284. package/src/entities/tenants/factories/tenant-factory.js +37 -0
  285. package/src/entities/tenants/index.js +22 -0
  286. package/src/entities/tenants/orchestrators/add-primary-address-to-tenant.js +47 -0
  287. package/src/entities/tenants/orchestrators/create-tenant.js +91 -0
  288. package/src/entities/tenants/orchestrators/index.js +22 -0
  289. package/src/entities/tenants/orchestrators/refresh-tenant-dids.js +146 -0
  290. package/src/entities/tenants/orchestrators/set-tenant-default-issuing-disclosure.js +31 -0
  291. package/src/entities/tenants/repos/index.js +20 -0
  292. package/src/entities/tenants/repos/insert-tenant-extension.js +33 -0
  293. package/src/entities/tenants/repos/repo.js +52 -0
  294. package/src/entities/tenants/repos/tenant-default-projection.js +33 -0
  295. package/src/entities/tokens/adapters/access-token.js +49 -0
  296. package/src/entities/tokens/adapters/index.js +19 -0
  297. package/src/entities/tokens/index.js +19 -0
  298. package/src/entities/users/factories/index.js +19 -0
  299. package/src/entities/users/factories/user-factory.js +36 -0
  300. package/src/entities/users/index.js +20 -0
  301. package/src/entities/users/repos/add-anonymous-user-repo-extension.js +23 -0
  302. package/src/entities/users/repos/find-or-insert-vendor-user-repo-extension.js +30 -0
  303. package/src/entities/users/repos/index.js +19 -0
  304. package/src/entities/users/repos/repo.js +50 -0
  305. package/src/fetchers/index.js +20 -0
  306. package/src/fetchers/operator/identify-fetcher.js +36 -0
  307. package/src/fetchers/operator/index.js +21 -0
  308. package/src/fetchers/operator/inspection-fetcher.js +35 -0
  309. package/src/fetchers/operator/issuing-fetcher.js +50 -0
  310. package/src/fetchers/operator/webhook-auth-header.js +45 -0
  311. package/src/fetchers/push-gateway/generate-push-gateway-token.js +40 -0
  312. package/src/fetchers/push-gateway/index.js +19 -0
  313. package/src/fetchers/push-gateway/push-fetcher.js +39 -0
  314. package/src/index.js +19 -0
  315. package/src/init-holder-server.js +108 -0
  316. package/src/init-operator-server.js +101 -0
  317. package/src/init-server.js +120 -0
  318. package/src/main-holder.js +18 -0
  319. package/src/main-operator.js +19 -0
  320. package/src/main.js +18 -0
  321. package/src/plugins/autoload-repos.js +28 -0
  322. package/src/plugins/disclosure-loader-plugin.js +56 -0
  323. package/src/plugins/ensure-disclosure-active-plugin.js +30 -0
  324. package/src/plugins/ensure-disclosure-configuration-type-plugin.js +29 -0
  325. package/src/plugins/ensure-tenant-default-issuing-disclosure-id-plugin.js +60 -0
  326. package/src/plugins/ensure-tenant-primary-address-plugin.js +44 -0
  327. package/src/plugins/exchange-error-handler-plugin.js +51 -0
  328. package/src/plugins/exchange-loader-plugin.js +50 -0
  329. package/src/plugins/group-loader-plugin.js +51 -0
  330. package/src/plugins/index.js +32 -0
  331. package/src/plugins/kms-plugin.js +57 -0
  332. package/src/plugins/tenant-loader-plugin.js +91 -0
  333. package/src/plugins/validate-cao-plugin.js +81 -0
  334. package/src/plugins/vendor-routes-auth-plugin.js +24 -0
  335. package/src/plugins/verify-access-token-plugin.js +88 -0
  336. package/src/standalone.js +24 -0
  337. package/src/start-app-server.js +38 -0
  338. package/test/combined/app-redirect.test.js +199 -0
  339. package/test/combined/helpers/credentialagent-build-fastify.js +29 -0
  340. package/test/combined/helpers/index.js +22 -0
  341. package/test/combined/helpers/nock-registrar-app-schema-name.js +50 -0
  342. package/test/combined/helpers/nock-registrar-get-organization-diddoc.js +26 -0
  343. package/test/combined/helpers/nock-registrar-get-organization-verified-profile.js +33 -0
  344. package/test/combined/manifest.json.test.js +55 -0
  345. package/test/combined/root-controller.test.js +42 -0
  346. package/test/combined/schemas/education-degree.schema.json +166 -0
  347. package/test/combined/schemas/employment-current-v1.1.schema.json +253 -0
  348. package/test/combined/schemas/open-badge-credential.schema.json +1285 -0
  349. package/test/combined/schemas/past-employment-position-with-uri-id.schema.js +22 -0
  350. package/test/combined/schemas/past-employment-position.schema.json +148 -0
  351. package/test/combined/schemas/will-always-validate.json +10 -0
  352. package/test/combined/validate-cao-plugin.test.js +155 -0
  353. package/test/get-push-delegate.test.js +54 -0
  354. package/test/helpers/jwt-vc-expectation.js +109 -0
  355. package/test/holder/build-request-response-schema.test.js +55 -0
  356. package/test/holder/credential-manifest-controller.test.js +3192 -0
  357. package/test/holder/e2e-issuing-controller.test.js +425 -0
  358. package/test/holder/get-exchange-progress-controller.test.js +521 -0
  359. package/test/holder/get-presentation-request.test.js +906 -0
  360. package/test/holder/helpers/credential-type-metadata.js +98 -0
  361. package/test/holder/helpers/credentialagent-holder-build-fastify.js +32 -0
  362. package/test/holder/helpers/generate-presentation.js +441 -0
  363. package/test/holder/helpers/generate-test-access-token.js +54 -0
  364. package/test/holder/helpers/jwt-access-token-expectation.js +32 -0
  365. package/test/holder/helpers/jwt-vc-expectation.js +115 -0
  366. package/test/holder/issuing-controller.test.js +7076 -0
  367. package/test/holder/oauth-token-controller.test.js +412 -0
  368. package/test/holder/presentation-submission.test.js +2365 -0
  369. package/test/holder/submit-identification.test.js +4815 -0
  370. package/test/operator/check-credentials-controller-v0.8.test.js +832 -0
  371. package/test/operator/credentials-revoke.test.js +536 -0
  372. package/test/operator/disclosures-controller-v0.8.test.js +4157 -0
  373. package/test/operator/exchanges-controller-v0.8.test.js +414 -0
  374. package/test/operator/exchanges-id-controller-v0.8.test.js +162 -0
  375. package/test/operator/feeds-controller-v0.8.test.js +659 -0
  376. package/test/operator/generate-push-gateway-token.test.js +116 -0
  377. package/test/operator/groups-controller.test.js +145 -0
  378. package/test/operator/groups-id-controller.test.js +287 -0
  379. package/test/operator/helpers/create-test-org-doc.js +60 -0
  380. package/test/operator/helpers/credentialagent-operator-build-fastify.js +32 -0
  381. package/test/operator/helpers/find-kms-key.js +31 -0
  382. package/test/operator/helpers/generate-primary-and-add-operator-to-primary.js +63 -0
  383. package/test/operator/helpers/init-agent-kms.js +22 -0
  384. package/test/operator/issued-credentials-controller-v0.8.test.js +398 -0
  385. package/test/operator/keys-controller-v0.8.test.js +1130 -0
  386. package/test/operator/offer-data-controller-v0.8.test.js +253 -0
  387. package/test/operator/offers-controller-v0.8.test.js +3026 -0
  388. package/test/operator/set-configuration-type-modifier.test.js +75 -0
  389. package/test/operator/swagger.test.js +37 -0
  390. package/test/operator/tenant-controller-v0.8.test.js +730 -0
  391. package/test/operator/tenant-loader-plugin.test.js +96 -0
  392. package/test/operator/tenants-controller-v0.8.test.js +2093 -0
  393. package/test/operator/users-controller-v0.8.test.js +137 -0
  394. package/test/operator/vc-api-credentials.test.js +963 -0
  395. package/verification.env +28 -0
@@ -0,0 +1,906 @@
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 nock = require('nock');
18
+ const { mongoDb } = require('@spencejs/spence-mongo-repos');
19
+ const { ObjectId } = require('mongodb');
20
+ const {
21
+ sampleOrganizationVerifiedProfile1,
22
+ sampleOrganizationProfile1,
23
+ samplePresentationDefinition,
24
+ } = require('@verii/sample-data');
25
+ const { jwtVerify } = require('@verii/jwt');
26
+ const { omit } = require('lodash/fp');
27
+ const { JWT_FORMAT } = require('@verii/test-regexes');
28
+ const { generateKeyPair, KeyPurposes } = require('@verii/crypto');
29
+ const { matchersWithOptions } = require('jest-json-schema');
30
+ const {
31
+ ExchangeTypes,
32
+ ExchangeStates,
33
+ ExchangeProtocols,
34
+ VendorEndpoint,
35
+ initDisclosureFactory,
36
+ initTenantFactory,
37
+ initKeysFactory,
38
+ } = require('../../src/entities');
39
+ const {
40
+ nockRegistrarGetOrganizationVerifiedProfile,
41
+ } = require('../combined/helpers/nock-registrar-get-organization-verified-profile');
42
+ const {
43
+ presentationRequestSchema,
44
+ presentationDefinitionV1Schema,
45
+ } = require('../../src/controllers/holder/inspect/schemas');
46
+ const buildFastify = require('./helpers/credentialagent-holder-build-fastify');
47
+ const { holderConfig } = require('../../src/config');
48
+
49
+ const agentUrl = 'http://localhost.test';
50
+ const tenantUrl = ({ tenantId }, suffix) =>
51
+ `/api/holder/v0.6/org/${tenantId}${suffix}`;
52
+ const inspectUrl = (tenantId, suffix) =>
53
+ `${tenantUrl({ tenantId }, `/inspect${suffix}`)}`;
54
+
55
+ expect.extend(
56
+ matchersWithOptions({
57
+ // Loading in a schema which is comprised only of definitions,
58
+ // which means specific test schemas need to be created.
59
+ // This is good for testing specific conditions for definition schemas.
60
+ schemas: [presentationDefinitionV1Schema],
61
+ })
62
+ );
63
+
64
+ describe('presentation request', () => {
65
+ let fastify;
66
+ let persistDisclosure;
67
+ let persistTenant;
68
+ let tenant;
69
+ let nonDidTenant;
70
+ let persistKey;
71
+ let disclosure;
72
+ let nonDisclosure;
73
+ let orgDidDoc;
74
+
75
+ beforeAll(async () => {
76
+ fastify = buildFastify();
77
+ await fastify.ready();
78
+ ({ persistDisclosure } = initDisclosureFactory(fastify));
79
+ ({ persistTenant } = initTenantFactory(fastify));
80
+ ({ persistKey } = initKeysFactory(fastify));
81
+ });
82
+
83
+ beforeEach(async () => {
84
+ jest.resetAllMocks();
85
+ nock.cleanAll();
86
+
87
+ await mongoDb().collection('disclosures').deleteMany({});
88
+ await mongoDb().collection('tenants').deleteMany({});
89
+ await mongoDb().collection('keys').deleteMany({});
90
+ await mongoDb().collection('exchanges').deleteMany({});
91
+ await mongoDb().collection('vendorUserIdMappings').deleteMany({});
92
+
93
+ const keyPair = generateKeyPair({
94
+ format: 'jwk',
95
+ });
96
+ tenant = await persistTenant();
97
+ orgDidDoc = {
98
+ id: tenant.did,
99
+ publicKey: [
100
+ { id: `${tenant.did}#key-1`, publicKeyJwk: keyPair.publicKey },
101
+ ],
102
+ service: [
103
+ {
104
+ id: `${tenant.did}#service-1`,
105
+ type: 'BasicProfileInformation',
106
+ ...sampleOrganizationProfile1,
107
+ },
108
+ ],
109
+ };
110
+ await persistKey({
111
+ tenant,
112
+ kidFragment: `#${orgDidDoc.publicKey[0].id.split('#')[1]}`,
113
+ keyPair,
114
+ });
115
+ await persistKey({
116
+ tenant,
117
+ kidFragment: '#ID1',
118
+ keyPair,
119
+ purposes: [KeyPurposes.DLT_TRANSACTIONS],
120
+ });
121
+
122
+ await persistKey({
123
+ tenant,
124
+ kidFragment: '#exchanges-1',
125
+ keyPair,
126
+ purposes: [KeyPurposes.EXCHANGES],
127
+ });
128
+ disclosure = await persistDisclosure({
129
+ tenant,
130
+ vendorEndpoint: VendorEndpoint.RECEIVE_CHECKED_CREDENTIALS,
131
+ });
132
+ nonDidTenant = await persistTenant();
133
+ nonDisclosure = await persistDisclosure({
134
+ tenant: nonDidTenant,
135
+ vendorEndpoint: VendorEndpoint.RECEIVE_CHECKED_CREDENTIALS,
136
+ });
137
+
138
+ nock('http://oracle.localhost.test')
139
+ .get('/api/v0.6/credential-types', () => {
140
+ return true;
141
+ })
142
+ .reply(
143
+ 200,
144
+ [
145
+ {
146
+ credentialType: 'Passport',
147
+ issuerCategory: 'ContactIssuer',
148
+ },
149
+ ],
150
+ { 'cache-control': 'max-age=3600' }
151
+ );
152
+ });
153
+
154
+ afterAll(async () => {
155
+ await fastify.close();
156
+ nock.cleanAll();
157
+ nock.restore();
158
+ });
159
+
160
+ const typesToInputDescriptors = {
161
+ PastEmploymentPosition: {
162
+ id: 'PastEmploymentPosition',
163
+ group: ['A'],
164
+ name: 'Past Role',
165
+ schema: [
166
+ {
167
+ uri: 'http://oracle.localhost.test/schemas/PastEmploymentPosition.json',
168
+ },
169
+ ],
170
+ },
171
+ CurrentEmploymentPosition: {
172
+ id: 'CurrentEmploymentPosition',
173
+ group: ['A'],
174
+ name: 'Current Role',
175
+ schema: [
176
+ {
177
+ uri: 'http://oracle.localhost.test/schemas/CurrentEmploymentPosition.json',
178
+ },
179
+ ],
180
+ },
181
+ };
182
+
183
+ describe('velocity api presentation request', () => {
184
+ it('should 404 if disclosure id cannot be found', async () => {
185
+ const q = { disclosureId: 'NOT_FOUND' };
186
+ const response = await fastify.injectJson({
187
+ method: 'GET',
188
+ url: inspectUrl(
189
+ tenant.did,
190
+ `/get-presentation-request?id=${q.disclosureId}`
191
+ ),
192
+ });
193
+ expect(response.statusCode).toEqual(404);
194
+ });
195
+ it('should 404 if tenant id can be found', async () => {
196
+ const q = { disclosureId: disclosure._id };
197
+ const response = await fastify.injectJson({
198
+ method: 'GET',
199
+ url: inspectUrl(
200
+ 'did:test:not-found',
201
+ `/get-presentation-request?id=${q.disclosureId}`
202
+ ),
203
+ });
204
+ expect(response.statusCode).toEqual(404);
205
+ });
206
+ it('should 500 if tenant did doc cannot be found', async () => {
207
+ const q = { disclosureId: disclosure._id };
208
+ const response = await fastify.injectJson({
209
+ method: 'GET',
210
+ url: inspectUrl(
211
+ tenant.did,
212
+ `/get-presentation-request?id=${q.disclosureId}`
213
+ ),
214
+ });
215
+ expect(response.statusCode).toEqual(500);
216
+ });
217
+ it('should 500 if tenant doesnt have a private key defined', async () => {
218
+ nockRegistrarGetOrganizationVerifiedProfile(
219
+ nonDidTenant.did,
220
+ sampleOrganizationVerifiedProfile1
221
+ );
222
+ nockRegistrarGetCredentialTypes();
223
+ const q = { disclosureId: nonDisclosure._id };
224
+ const response = await fastify.injectJson({
225
+ method: 'GET',
226
+ url: inspectUrl(
227
+ nonDidTenant.did,
228
+ `/get-presentation-request?id=${q.disclosureId}`
229
+ ),
230
+ });
231
+ expect(response.statusCode).toEqual(500);
232
+
233
+ const dbExchange = await mongoDb().collection('exchanges').findOne({});
234
+ expect(dbExchange).toEqual({
235
+ _id: expect.any(ObjectId),
236
+ type: ExchangeTypes.DISCLOSURE,
237
+ disclosureId: new ObjectId(nonDisclosure._id),
238
+ events: [
239
+ { state: ExchangeStates.NEW, timestamp: expect.any(Date) },
240
+ {
241
+ state: ExchangeStates.UNEXPECTED_ERROR,
242
+ timestamp: expect.any(Date),
243
+ },
244
+ ],
245
+ protocolMetadata: {
246
+ protocol: ExchangeProtocols.VNF_API,
247
+ },
248
+ err: `No key matching the filter {"tenantId":"${nonDidTenant._id}","purposes":"EXCHANGES"} was found`,
249
+ tenantId: new ObjectId(nonDidTenant._id),
250
+ createdAt: expect.any(Date),
251
+ updatedAt: expect.any(Date),
252
+ });
253
+ });
254
+ it('should 200 if many types are defined', async () => {
255
+ nockRegistrarGetOrganizationVerifiedProfile(
256
+ tenant.did,
257
+ sampleOrganizationVerifiedProfile1
258
+ );
259
+ nockRegistrarGetCredentialTypes();
260
+ const q = { disclosureId: disclosure._id };
261
+ const response = await fastify.injectJson({
262
+ method: 'GET',
263
+ url: inspectUrl(
264
+ tenant.did,
265
+ `/get-presentation-request?id=${q.disclosureId}`
266
+ ),
267
+ });
268
+ expect(response.statusCode).toEqual(200);
269
+ const { payload: responsePayload } = await jwtVerify(
270
+ response.json.presentation_request,
271
+ orgDidDoc.publicKey[0].publicKeyJwk
272
+ );
273
+ expect(responsePayload).toMatchSchema(presentationRequestSchema);
274
+ expect(responsePayload).toEqual({
275
+ exchange_id: expect.any(String),
276
+ metadata: {
277
+ client_name: sampleOrganizationProfile1.name,
278
+ logo_uri: sampleOrganizationProfile1.logo,
279
+ tos_uri: disclosure.termsUrl,
280
+ auth_token_uri: `${agentUrl}${tenantUrl(
281
+ { tenantId: tenant.did },
282
+ '/oauth/token'
283
+ )}`,
284
+ max_retention_period: disclosure.duration,
285
+ progress_uri: `${agentUrl}${tenantUrl(
286
+ { tenantId: tenant.did },
287
+ '/get-exchange-progress'
288
+ )}`,
289
+ submit_presentation_uri: `${agentUrl}${inspectUrl(
290
+ tenant.did,
291
+ '/submit-presentation'
292
+ )}`,
293
+ },
294
+ presentation_definition: {
295
+ id: `${responsePayload.exchange_id}.${disclosure._id}`,
296
+ name: disclosure.description,
297
+ purpose: disclosure.purpose,
298
+ format: {
299
+ jwt_vp: { alg: ['secp256k1'] },
300
+ },
301
+ input_descriptors: disclosure.types.map(
302
+ ({ type }) => typesToInputDescriptors[type]
303
+ ),
304
+ submission_requirements: [
305
+ {
306
+ from: 'A',
307
+ min: 1,
308
+ rule: 'pick',
309
+ },
310
+ ],
311
+ },
312
+ exp: expect.any(Number),
313
+ iat: expect.any(Number),
314
+ nbf: expect.any(Number),
315
+ iss: tenant.did,
316
+ });
317
+
318
+ const dbExchange = await mongoDb()
319
+ .collection('exchanges')
320
+ .findOne({ _id: new ObjectId(responsePayload.exchange_id) });
321
+ expect(dbExchange).toEqual({
322
+ _id: new ObjectId(responsePayload.exchange_id),
323
+ type: ExchangeTypes.DISCLOSURE,
324
+ tenantId: new ObjectId(tenant._id),
325
+ disclosureId: new ObjectId(disclosure._id),
326
+ protocolMetadata: {
327
+ protocol: ExchangeProtocols.VNF_API,
328
+ },
329
+ events: [{ state: ExchangeStates.NEW, timestamp: expect.any(Date) }],
330
+ createdAt: expect.any(Date),
331
+ updatedAt: expect.any(Date),
332
+ });
333
+ });
334
+ it('should 200, use presentationDefinition from disclosure and populate purpose from disclosure', async () => {
335
+ disclosure = await persistDisclosure({
336
+ tenant,
337
+ purpose: 'fooPurpose from disclosure',
338
+ presentationDefinition: {
339
+ ...omit(['purpose'], samplePresentationDefinition),
340
+ },
341
+ });
342
+ nockRegistrarGetOrganizationVerifiedProfile(
343
+ tenant.did,
344
+ sampleOrganizationVerifiedProfile1
345
+ );
346
+ nockRegistrarGetCredentialTypes();
347
+ const q = { disclosureId: disclosure._id };
348
+ const response = await fastify.injectJson({
349
+ method: 'GET',
350
+ url: inspectUrl(
351
+ tenant.did,
352
+ `/get-presentation-request?id=${q.disclosureId}`
353
+ ),
354
+ });
355
+ expect(response.statusCode).toEqual(200);
356
+ const { payload: responsePayload } = await jwtVerify(
357
+ response.json.presentation_request,
358
+ orgDidDoc.publicKey[0].publicKeyJwk
359
+ );
360
+ expect(responsePayload).toMatchSchema(presentationRequestSchema);
361
+ expect(responsePayload).toEqual({
362
+ exchange_id: expect.any(String),
363
+ metadata: {
364
+ client_name: sampleOrganizationProfile1.name,
365
+ logo_uri: sampleOrganizationProfile1.logo,
366
+ tos_uri: disclosure.termsUrl,
367
+ auth_token_uri: `${agentUrl}${tenantUrl(
368
+ { tenantId: tenant.did },
369
+ '/oauth/token'
370
+ )}`,
371
+ max_retention_period: disclosure.duration,
372
+ progress_uri: `${agentUrl}${tenantUrl(
373
+ { tenantId: tenant.did },
374
+ '/get-exchange-progress'
375
+ )}`,
376
+ submit_presentation_uri: `${agentUrl}${inspectUrl(
377
+ tenant.did,
378
+ '/submit-presentation'
379
+ )}`,
380
+ },
381
+ presentation_definition: {
382
+ id: `${responsePayload.exchange_id}.${disclosure._id}`,
383
+ purpose: 'fooPurpose from disclosure',
384
+ name: 'fooName',
385
+ format: {
386
+ jwt_vp: { alg: ['secp256k1'] },
387
+ },
388
+ input_descriptors: [
389
+ {
390
+ id: 'CurrentEmployment',
391
+ name: 'Current Employment',
392
+ schema: [
393
+ {
394
+ uri: 'https://example.com/employment-current-v1.1.schema.json',
395
+ },
396
+ ],
397
+ group: ['A'],
398
+ },
399
+ {
400
+ id: 'PastEmployment',
401
+ name: 'Past Employment',
402
+ schema: [
403
+ {
404
+ uri: 'https://example.com/employment-past-v1.1.schema.json',
405
+ },
406
+ ],
407
+ group: ['A'],
408
+ },
409
+ {
410
+ id: 'OpenBadge',
411
+ name: 'Badges',
412
+ schema: [
413
+ {
414
+ uri: 'https://example.com/open-badge-credential.schema.json',
415
+ },
416
+ ],
417
+ group: ['B'],
418
+ },
419
+ ],
420
+ submission_requirements: [
421
+ {
422
+ rule: 'all',
423
+ from: 'A',
424
+ min: 1,
425
+ },
426
+ ],
427
+ },
428
+ exp: expect.any(Number),
429
+ iat: expect.any(Number),
430
+ nbf: expect.any(Number),
431
+ iss: tenant.did,
432
+ });
433
+
434
+ const dbExchange = await mongoDb()
435
+ .collection('exchanges')
436
+ .findOne({ _id: new ObjectId(responsePayload.exchange_id) });
437
+ expect(dbExchange).toEqual({
438
+ _id: new ObjectId(responsePayload.exchange_id),
439
+ type: ExchangeTypes.DISCLOSURE,
440
+ tenantId: new ObjectId(tenant._id),
441
+ disclosureId: new ObjectId(disclosure._id),
442
+ protocolMetadata: {
443
+ protocol: ExchangeProtocols.VNF_API,
444
+ },
445
+ events: [{ state: ExchangeStates.NEW, timestamp: expect.any(Date) }],
446
+ createdAt: expect.any(Date),
447
+ updatedAt: expect.any(Date),
448
+ });
449
+ });
450
+ it('should 200 when route has tenantId', async () => {
451
+ disclosure = await persistDisclosure({
452
+ tenant,
453
+ purpose: 'fooPurpose from disclosure',
454
+ presentationDefinition: {
455
+ ...omit(['purpose'], samplePresentationDefinition),
456
+ },
457
+ });
458
+ nockRegistrarGetOrganizationVerifiedProfile(
459
+ tenant.did,
460
+ sampleOrganizationVerifiedProfile1
461
+ );
462
+ nockRegistrarGetCredentialTypes();
463
+ const q = { disclosureId: disclosure._id };
464
+ const response = await fastify.injectJson({
465
+ method: 'GET',
466
+ url: inspectUrl(
467
+ tenant._id,
468
+ `/get-presentation-request?id=${q.disclosureId}`
469
+ ),
470
+ });
471
+ expect(response.statusCode).toEqual(200);
472
+ });
473
+ it("should 200 when route has tenant's did alias", async () => {
474
+ const didAlias = 'did:aka:foo';
475
+ const customTenant = await persistTenant({ dids: [didAlias] });
476
+ const keyPair = generateKeyPair({
477
+ format: 'jwk',
478
+ });
479
+ await persistKey({
480
+ tenant: customTenant,
481
+ kidFragment: '#exchanges-1',
482
+ keyPair,
483
+ purposes: [KeyPurposes.EXCHANGES],
484
+ });
485
+ disclosure = await persistDisclosure({
486
+ tenant: customTenant,
487
+ purpose: 'fooPurpose from disclosure',
488
+ presentationDefinition: {
489
+ ...omit(['purpose'], samplePresentationDefinition),
490
+ },
491
+ });
492
+ nockRegistrarGetOrganizationVerifiedProfile(
493
+ customTenant.did,
494
+ sampleOrganizationVerifiedProfile1
495
+ );
496
+ nockRegistrarGetCredentialTypes();
497
+ const q = { disclosureId: disclosure._id };
498
+ const response = await fastify.injectJson({
499
+ method: 'GET',
500
+ url: inspectUrl(
501
+ didAlias,
502
+ `/get-presentation-request?id=${q.disclosureId}`
503
+ ),
504
+ });
505
+ expect(response.statusCode).toEqual(200);
506
+ });
507
+ it('should 200, use presentationDefinition from disclosure and override disclosure purpose ', async () => {
508
+ disclosure = await persistDisclosure({
509
+ tenant,
510
+ presentationDefinition: {
511
+ ...samplePresentationDefinition,
512
+ purpose: 'fooPurpose',
513
+ },
514
+ });
515
+ nockRegistrarGetOrganizationVerifiedProfile(
516
+ tenant.did,
517
+ sampleOrganizationVerifiedProfile1
518
+ );
519
+ nockRegistrarGetCredentialTypes();
520
+ const q = { disclosureId: disclosure._id };
521
+ const response = await fastify.injectJson({
522
+ method: 'GET',
523
+ url: inspectUrl(
524
+ tenant.did,
525
+ `/get-presentation-request?id=${q.disclosureId}`
526
+ ),
527
+ });
528
+ expect(response.statusCode).toEqual(200);
529
+ const { payload: responsePayload } = await jwtVerify(
530
+ response.json.presentation_request,
531
+ orgDidDoc.publicKey[0].publicKeyJwk
532
+ );
533
+ expect(responsePayload).toMatchSchema(presentationRequestSchema);
534
+ expect(responsePayload).toEqual({
535
+ exchange_id: expect.any(String),
536
+ metadata: {
537
+ client_name: sampleOrganizationProfile1.name,
538
+ logo_uri: sampleOrganizationProfile1.logo,
539
+ tos_uri: disclosure.termsUrl,
540
+ auth_token_uri: `${agentUrl}${tenantUrl(
541
+ { tenantId: tenant.did },
542
+ '/oauth/token'
543
+ )}`,
544
+ max_retention_period: disclosure.duration,
545
+ progress_uri: `${agentUrl}${tenantUrl(
546
+ { tenantId: tenant.did },
547
+ '/get-exchange-progress'
548
+ )}`,
549
+ submit_presentation_uri: `${agentUrl}${inspectUrl(
550
+ tenant.did,
551
+ '/submit-presentation'
552
+ )}`,
553
+ },
554
+ presentation_definition: {
555
+ id: `${responsePayload.exchange_id}.${disclosure._id}`,
556
+ purpose: 'fooPurpose',
557
+ name: 'fooName',
558
+ format: {
559
+ jwt_vp: { alg: ['secp256k1'] },
560
+ },
561
+ input_descriptors: [
562
+ {
563
+ id: 'CurrentEmployment',
564
+ name: 'Current Employment',
565
+ schema: [
566
+ {
567
+ uri: 'https://example.com/employment-current-v1.1.schema.json',
568
+ },
569
+ ],
570
+ group: ['A'],
571
+ },
572
+ {
573
+ id: 'PastEmployment',
574
+ name: 'Past Employment',
575
+ schema: [
576
+ {
577
+ uri: 'https://example.com/employment-past-v1.1.schema.json',
578
+ },
579
+ ],
580
+ group: ['A'],
581
+ },
582
+ {
583
+ id: 'OpenBadge',
584
+ name: 'Badges',
585
+ schema: [
586
+ {
587
+ uri: 'https://example.com/open-badge-credential.schema.json',
588
+ },
589
+ ],
590
+ group: ['B'],
591
+ },
592
+ ],
593
+ submission_requirements: [
594
+ {
595
+ rule: 'all',
596
+ from: 'A',
597
+ min: 1,
598
+ },
599
+ ],
600
+ },
601
+ exp: expect.any(Number),
602
+ iat: expect.any(Number),
603
+ nbf: expect.any(Number),
604
+ iss: tenant.did,
605
+ });
606
+
607
+ const dbExchange = await mongoDb()
608
+ .collection('exchanges')
609
+ .findOne({ _id: new ObjectId(responsePayload.exchange_id) });
610
+ expect(dbExchange).toEqual({
611
+ _id: new ObjectId(responsePayload.exchange_id),
612
+ type: ExchangeTypes.DISCLOSURE,
613
+ tenantId: new ObjectId(tenant._id),
614
+ disclosureId: new ObjectId(disclosure._id),
615
+ protocolMetadata: {
616
+ protocol: ExchangeProtocols.VNF_API,
617
+ },
618
+ events: [{ state: ExchangeStates.NEW, timestamp: expect.any(Date) }],
619
+ createdAt: expect.any(Date),
620
+ updatedAt: expect.any(Date),
621
+ });
622
+ });
623
+ it('should return 200 with stringified jwt if query parameter format is `json`', async () => {
624
+ nockRegistrarGetOrganizationVerifiedProfile(
625
+ tenant.did,
626
+ sampleOrganizationVerifiedProfile1
627
+ );
628
+ nockRegistrarGetCredentialTypes();
629
+ const q = { disclosureId: disclosure._id };
630
+ const response = await fastify.injectJson({
631
+ method: 'GET',
632
+ url: inspectUrl(
633
+ tenant.did,
634
+ `/get-presentation-request?id=${q.disclosureId}&format=json`
635
+ ),
636
+ });
637
+ expect(response.statusCode).toEqual(200);
638
+ expect(response.json).toEqual({
639
+ presentation_request: expect.anything(),
640
+ });
641
+ const parsedResponse = response.json.presentation_request;
642
+
643
+ expect(parsedResponse).toEqual({
644
+ exchange_id: expect.any(String),
645
+ metadata: {
646
+ client_name: sampleOrganizationProfile1.name,
647
+ logo_uri: sampleOrganizationProfile1.logo,
648
+ tos_uri: disclosure.termsUrl,
649
+ auth_token_uri: `${agentUrl}${tenantUrl(
650
+ { tenantId: tenant.did },
651
+ '/oauth/token'
652
+ )}`,
653
+ max_retention_period: disclosure.duration,
654
+ progress_uri: `${agentUrl}${tenantUrl(
655
+ { tenantId: tenant.did },
656
+ '/get-exchange-progress'
657
+ )}`,
658
+ submit_presentation_uri: `${agentUrl}${inspectUrl(
659
+ tenant.did,
660
+ '/submit-presentation'
661
+ )}`,
662
+ },
663
+ presentation_definition: {
664
+ id: `${parsedResponse.exchange_id}.${disclosure._id}`,
665
+ name: 'Clerk',
666
+ purpose: disclosure.purpose,
667
+ format: {
668
+ jwt_vp: { alg: ['secp256k1'] },
669
+ },
670
+ input_descriptors: disclosure.types.map(
671
+ ({ type }) => typesToInputDescriptors[type]
672
+ ),
673
+ submission_requirements: [
674
+ {
675
+ from: 'A',
676
+ min: 1,
677
+ rule: 'pick',
678
+ },
679
+ ],
680
+ },
681
+ });
682
+ });
683
+ it('should return 200 and ignore query parameter format `json` for production', async () => {
684
+ await fastify.close();
685
+ fastify = await buildFastify({ ...holderConfig, isProd: true });
686
+ nockRegistrarGetOrganizationVerifiedProfile(
687
+ tenant.did,
688
+ sampleOrganizationVerifiedProfile1
689
+ );
690
+ nockRegistrarGetCredentialTypes();
691
+ const q = { disclosureId: disclosure._id };
692
+ const response = await fastify.injectJson({
693
+ method: 'GET',
694
+ url: inspectUrl(
695
+ tenant.did,
696
+ `/get-presentation-request?id=${q.disclosureId}&format=json`
697
+ ),
698
+ });
699
+ expect(response.statusCode).toEqual(200);
700
+ expect(response.json.presentation_request).toEqual(
701
+ expect.stringMatching(JWT_FORMAT)
702
+ );
703
+ await fastify.close();
704
+ fastify = await buildFastify();
705
+ });
706
+ it('should 200 and include metadata commercialEntity fields if present on disclosure', async () => {
707
+ disclosure = await persistDisclosure({
708
+ tenant,
709
+ vendorEndpoint: VendorEndpoint.RECEIVE_CHECKED_CREDENTIALS,
710
+ commercialEntityName: 'fooCommercialEntityName',
711
+ commercialEntityLogo: 'fooCommercialEntityLogo',
712
+ });
713
+ nockRegistrarGetOrganizationVerifiedProfile(
714
+ tenant.did,
715
+ sampleOrganizationVerifiedProfile1
716
+ );
717
+ nockRegistrarGetCredentialTypes();
718
+ const q = { disclosureId: disclosure._id };
719
+ const response = await fastify.injectJson({
720
+ method: 'GET',
721
+ url: inspectUrl(
722
+ tenant.did,
723
+ `/get-presentation-request?id=${q.disclosureId}`
724
+ ),
725
+ });
726
+ expect(response.statusCode).toEqual(200);
727
+ const { payload: responsePayload } = await jwtVerify(
728
+ response.json.presentation_request,
729
+ orgDidDoc.publicKey[0].publicKeyJwk
730
+ );
731
+ expect(responsePayload).toMatchSchema(presentationRequestSchema);
732
+ expect(responsePayload).toEqual({
733
+ exchange_id: expect.any(String),
734
+ metadata: {
735
+ client_name: 'fooCommercialEntityName',
736
+ logo_uri: 'fooCommercialEntityLogo',
737
+ tos_uri: disclosure.termsUrl,
738
+ auth_token_uri: `${agentUrl}${tenantUrl(
739
+ { tenantId: tenant.did },
740
+ '/oauth/token'
741
+ )}`,
742
+ max_retention_period: disclosure.duration,
743
+ progress_uri: `${agentUrl}${tenantUrl(
744
+ { tenantId: tenant.did },
745
+ '/get-exchange-progress'
746
+ )}`,
747
+ submit_presentation_uri: `${agentUrl}${inspectUrl(
748
+ tenant.did,
749
+ '/submit-presentation'
750
+ )}`,
751
+ },
752
+ presentation_definition: {
753
+ id: `${responsePayload.exchange_id}.${disclosure._id}`,
754
+ name: disclosure.description,
755
+ purpose: disclosure.purpose,
756
+ format: {
757
+ jwt_vp: { alg: ['secp256k1'] },
758
+ },
759
+ input_descriptors: disclosure.types.map(
760
+ ({ type }) => typesToInputDescriptors[type]
761
+ ),
762
+ submission_requirements: [
763
+ {
764
+ from: 'A',
765
+ min: 1,
766
+ rule: 'pick',
767
+ },
768
+ ],
769
+ },
770
+ exp: expect.any(Number),
771
+ iat: expect.any(Number),
772
+ nbf: expect.any(Number),
773
+ iss: tenant.did,
774
+ });
775
+
776
+ const dbExchange = await mongoDb()
777
+ .collection('exchanges')
778
+ .findOne({ _id: new ObjectId(responsePayload.exchange_id) });
779
+ expect(dbExchange).toEqual({
780
+ _id: new ObjectId(responsePayload.exchange_id),
781
+ type: ExchangeTypes.DISCLOSURE,
782
+ tenantId: new ObjectId(tenant._id),
783
+ disclosureId: new ObjectId(disclosure._id),
784
+ protocolMetadata: {
785
+ protocol: ExchangeProtocols.VNF_API,
786
+ },
787
+ events: [{ state: ExchangeStates.NEW, timestamp: expect.any(Date) }],
788
+ createdAt: expect.any(Date),
789
+ updatedAt: expect.any(Date),
790
+ });
791
+ });
792
+ it('should 200 and include metadata feed field if present on disclosure', async () => {
793
+ disclosure = await persistDisclosure({
794
+ tenant,
795
+ feed: true,
796
+ });
797
+ nockRegistrarGetOrganizationVerifiedProfile(
798
+ tenant.did,
799
+ sampleOrganizationVerifiedProfile1
800
+ );
801
+ nockRegistrarGetCredentialTypes();
802
+
803
+ const q = { disclosureId: disclosure._id };
804
+ const response = await fastify.injectJson({
805
+ method: 'GET',
806
+ url: inspectUrl(
807
+ tenant.did,
808
+ `/get-presentation-request?id=${q.disclosureId}`
809
+ ),
810
+ });
811
+ expect(response.statusCode).toEqual(200);
812
+ const { payload: responsePayload } = await jwtVerify(
813
+ response.json.presentation_request,
814
+ orgDidDoc.publicKey[0].publicKeyJwk
815
+ );
816
+ expect(responsePayload).toMatchSchema(presentationRequestSchema);
817
+ expect(responsePayload).toEqual({
818
+ exchange_id: expect.any(String),
819
+ metadata: {
820
+ client_name: 'ACME Corp',
821
+ logo_uri: 'https://example.com/logo.png',
822
+ tos_uri: disclosure.termsUrl,
823
+ auth_token_uri: `${agentUrl}${tenantUrl(
824
+ { tenantId: tenant.did },
825
+ '/oauth/token'
826
+ )}`,
827
+ max_retention_period: disclosure.duration,
828
+ progress_uri: `${agentUrl}${tenantUrl(
829
+ { tenantId: tenant.did },
830
+ '/get-exchange-progress'
831
+ )}`,
832
+ submit_presentation_uri: `${agentUrl}${inspectUrl(
833
+ tenant.did,
834
+ '/submit-presentation'
835
+ )}`,
836
+ feed: true,
837
+ },
838
+ presentation_definition: {
839
+ id: `${responsePayload.exchange_id}.${disclosure._id}`,
840
+ name: disclosure.description,
841
+ purpose: disclosure.purpose,
842
+ format: {
843
+ jwt_vp: { alg: ['secp256k1'] },
844
+ },
845
+ input_descriptors: disclosure.types.map(
846
+ ({ type }) => typesToInputDescriptors[type]
847
+ ),
848
+ submission_requirements: [
849
+ {
850
+ from: 'A',
851
+ min: 1,
852
+ rule: 'pick',
853
+ },
854
+ ],
855
+ },
856
+ exp: expect.any(Number),
857
+ iat: expect.any(Number),
858
+ nbf: expect.any(Number),
859
+ iss: tenant.did,
860
+ });
861
+
862
+ const dbExchange = await mongoDb()
863
+ .collection('exchanges')
864
+ .findOne({ _id: new ObjectId(responsePayload.exchange_id) });
865
+ expect(dbExchange).toEqual({
866
+ _id: new ObjectId(responsePayload.exchange_id),
867
+ type: ExchangeTypes.DISCLOSURE,
868
+ tenantId: new ObjectId(tenant._id),
869
+ disclosureId: new ObjectId(disclosure._id),
870
+ protocolMetadata: {
871
+ protocol: ExchangeProtocols.VNF_API,
872
+ },
873
+ events: [{ state: ExchangeStates.NEW, timestamp: expect.any(Date) }],
874
+ createdAt: expect.any(Date),
875
+ updatedAt: expect.any(Date),
876
+ });
877
+ });
878
+ });
879
+ });
880
+
881
+ const nockRegistrarGetCredentialTypes = () =>
882
+ nock('http://oracle.localhost.test')
883
+ .get(
884
+ '/api/v0.6/credential-type-descriptors/PastEmploymentPosition?includeDisplay=false'
885
+ )
886
+ .reply(200, {
887
+ id: 'PastEmploymentPosition',
888
+ name: 'Past Role',
889
+ schema: [
890
+ {
891
+ uri: 'http://oracle.localhost.test/schemas/PastEmploymentPosition.json',
892
+ },
893
+ ],
894
+ })
895
+ .get(
896
+ '/api/v0.6/credential-type-descriptors/CurrentEmploymentPosition?includeDisplay=false'
897
+ )
898
+ .reply(200, {
899
+ id: 'CurrentEmploymentPosition',
900
+ name: 'Current Role',
901
+ schema: [
902
+ {
903
+ uri: 'http://oracle.localhost.test/schemas/CurrentEmploymentPosition.json',
904
+ },
905
+ ],
906
+ });