@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.
- package/.localdev.e2e.env +40 -0
- package/.localdev.env +41 -0
- package/.standalone.env +5 -0
- package/LICENSE +202 -0
- package/NOTICE +1 -0
- package/README.md +19 -0
- package/docker/compose.yml +33 -0
- package/e2e/README.md +12 -0
- package/e2e/org-registration-and-issuing.e2e.test.js +624 -0
- package/jest.config.js +20 -0
- package/migrate-mongo.config.js +36 -0
- package/migrations/20210317133137-add-index-to-offers-repo.js +57 -0
- package/migrations/20210416145639-add-index-to-revocation-list.js +27 -0
- package/migrations/20210719120225-add_unique_did_index_to_tenant.js +45 -0
- package/migrations/20230524053029-add-vendorUserIdMappings-index.js +32 -0
- package/migrations/20230616111907-add-configuration-type-index.js +32 -0
- package/package.json +108 -0
- package/src/assets/public/favicon.ico +0 -0
- package/src/assets/public/logo192.png +0 -0
- package/src/assets/public/logo512.png +0 -0
- package/src/assets/public/manifest.json +28 -0
- package/src/assets/templates/app-redirect.hbs +16 -0
- package/src/config/config.js +44 -0
- package/src/config/core-config.js +143 -0
- package/src/config/holder-config.js +104 -0
- package/src/config/index.js +22 -0
- package/src/config/operator-config.js +64 -0
- package/src/controllers/autoload-holder-api-controllers.js +30 -0
- package/src/controllers/autoload-operator-api-controllers.js +31 -0
- package/src/controllers/autoload-root-api-controller.js +30 -0
- package/src/controllers/autoload-saasoperator-api-controllers.js +31 -0
- package/src/controllers/holder/autohooks.js +55 -0
- package/src/controllers/holder/get-exchange-progress/autohooks.js +27 -0
- package/src/controllers/holder/get-exchange-progress/controller.js +50 -0
- package/src/controllers/holder/inspect/autohooks.js +35 -0
- package/src/controllers/holder/inspect/get-presentation-request/controller.js +100 -0
- package/src/controllers/holder/inspect/schemas/holder-disclosure.schema.json +73 -0
- package/src/controllers/holder/inspect/schemas/index.js +33 -0
- package/src/controllers/holder/inspect/schemas/presentation-definition.v1.schema.json +461 -0
- package/src/controllers/holder/inspect/schemas/presentation-request.schema.json +279 -0
- package/src/controllers/holder/inspect/schemas/presentation-submission.schema.json +41 -0
- package/src/controllers/holder/inspect/schemas/siop-presentation-submission.schema.json +74 -0
- package/src/controllers/holder/inspect/schemas/velocity-presentation-submission.response.200.schema.json +36 -0
- package/src/controllers/holder/inspect/schemas/velocity-presentation-submission.schema.json +34 -0
- package/src/controllers/holder/inspect/submit-presentation/controller.js +89 -0
- package/src/controllers/holder/issue/autohooks.js +23 -0
- package/src/controllers/holder/issue/get-credential-manifest/controller.js +193 -0
- package/src/controllers/holder/issue/offers/autohooks.js +35 -0
- package/src/controllers/holder/issue/offers/controller.js +164 -0
- package/src/controllers/holder/issue/offers/credential-offers/controller.js +460 -0
- package/src/controllers/holder/issue/submit-identification/autohooks.js +37 -0
- package/src/controllers/holder/issue/submit-identification/controller.js +63 -0
- package/src/controllers/holder/oauth/autohooks.js +19 -0
- package/src/controllers/holder/oauth/controller.js +140 -0
- package/src/controllers/index.js +22 -0
- package/src/controllers/operator/tenants/_tenantId/autohooks.js +40 -0
- package/src/controllers/operator/tenants/_tenantId/check-credentials/autohooks.js +24 -0
- package/src/controllers/operator/tenants/_tenantId/check-credentials/controller-v0.8.js +200 -0
- package/src/controllers/operator/tenants/_tenantId/check-credentials/schemas/index.js +19 -0
- package/src/controllers/operator/tenants/_tenantId/check-credentials/schemas/vendor-credential.schema.json +244 -0
- package/src/controllers/operator/tenants/_tenantId/controller-v0.8.js +221 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/autohooks.js +30 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/controller-v0.8.js +271 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/autohooks.js +45 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/controller-v0.8.js +199 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/add-feed.schema.js +14 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/feed.schema.json +27 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/index.js +25 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/modify-feed-update-body.schema.js +18 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/_id/feeds/schemas/modify-feed.schema.json +19 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/autohooks.js +34 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/controller-v0.8.js +100 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/agent-disclosure-presentation-definition.schema.json +404 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/agent-disclosure.schema.js +24 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/index.js +29 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/new-agent-disclosure.schema.json +166 -0
- package/src/controllers/operator/tenants/_tenantId/disclosures/schemas/update-agent-disclosure.schema.js +20 -0
- package/src/controllers/operator/tenants/_tenantId/exchanges/_exchangeId/autohooks.js +30 -0
- package/src/controllers/operator/tenants/_tenantId/exchanges/_exchangeId/controller-v0.8.js +73 -0
- package/src/controllers/operator/tenants/_tenantId/exchanges/autohooks.js +19 -0
- package/src/controllers/operator/tenants/_tenantId/exchanges/controller-v0.8.js +150 -0
- package/src/controllers/operator/tenants/_tenantId/exchanges/schemas/get-exchange.response.body.json +147 -0
- package/src/controllers/operator/tenants/_tenantId/exchanges/schemas/index.js +21 -0
- package/src/controllers/operator/tenants/_tenantId/issued-credentials/autohooks.js +27 -0
- package/src/controllers/operator/tenants/_tenantId/issued-credentials/controller-v0.8.js +303 -0
- package/src/controllers/operator/tenants/_tenantId/issued-credentials/schemas/index.js +23 -0
- package/src/controllers/operator/tenants/_tenantId/issued-credentials/schemas/issued-credential.schema.json +115 -0
- package/src/controllers/operator/tenants/_tenantId/issued-credentials/schemas/revoke-credentials.schema.json +18 -0
- package/src/controllers/operator/tenants/_tenantId/keys/controller-v0.8.js +168 -0
- package/src/controllers/operator/tenants/_tenantId/offer-data/controller-v0.8.js +78 -0
- package/src/controllers/operator/tenants/_tenantId/offers/autohooks.js +34 -0
- package/src/controllers/operator/tenants/_tenantId/offers/controller-v0.8.js +253 -0
- package/src/controllers/operator/tenants/_tenantId/offers/schemas/index.js +23 -0
- package/src/controllers/operator/tenants/_tenantId/offers/schemas/new-vendor-offer.schema.js +47 -0
- package/src/controllers/operator/tenants/_tenantId/offers/schemas/vendor-offer.schema.json +56 -0
- package/src/controllers/operator/tenants/_tenantId/users/autohooks.js +24 -0
- package/src/controllers/operator/tenants/_tenantId/users/controller-v0.8.js +92 -0
- package/src/controllers/operator/tenants/_tenantId/users/schemas/index.js +23 -0
- package/src/controllers/operator/tenants/_tenantId/users/schemas/new-user.schema.json +13 -0
- package/src/controllers/operator/tenants/_tenantId/users/schemas/user.schema.json +16 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/autohooks.js +34 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/controller-v0.8.js +110 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/Credential.schema.js +18 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/IssueCredentialOptions.schema.json +42 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/IssueCredentialRequest.schema.json +13 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/IssueCredentialResponse.schema.json +19 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/LinkedDataProof.schema.json +43 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/VerifiableCredential.schema.js +16 -0
- package/src/controllers/operator/tenants/_tenantId/vc-api/credentials/schemas/index.js +31 -0
- package/src/controllers/operator/tenants/autohooks.js +65 -0
- package/src/controllers/operator/tenants/controller-v0.8.js +167 -0
- package/src/controllers/operator/tenants/schemas/index.js +41 -0
- package/src/controllers/operator/tenants/schemas/modify-secret.schema.json +11 -0
- package/src/controllers/operator/tenants/schemas/modify-tenant-v0.8.schema.json +44 -0
- package/src/controllers/operator/tenants/schemas/new-tenant-v0.8.schema.json +19 -0
- package/src/controllers/operator/tenants/schemas/new-tenant.response.200.schema.json +7 -0
- package/src/controllers/operator/tenants/schemas/secret-key-metadata.schema.json +31 -0
- package/src/controllers/operator/tenants/schemas/secret-key.schema.json +29 -0
- package/src/controllers/operator/tenants/schemas/secret-kid.schema.json +13 -0
- package/src/controllers/operator/tenants/schemas/secret-new-tenant-v0.8.schema.json +28 -0
- package/src/controllers/operator/tenants/schemas/secret-tenant-key-v0.8.schema.json +13 -0
- package/src/controllers/operator/tenants/schemas/tenant-key-v0.8.schema.json +14 -0
- package/src/controllers/operator/tenants/schemas/tenant-v0.8.schema.json +62 -0
- package/src/controllers/root/autohooks.js +23 -0
- package/src/controllers/root/controller.js +173 -0
- package/src/controllers/saasoperator/groups/_id/autohooks.js +9 -0
- package/src/controllers/saasoperator/groups/_id/controller.js +121 -0
- package/src/controllers/saasoperator/groups/autohooks.js +19 -0
- package/src/controllers/saasoperator/groups/controller.js +65 -0
- package/src/controllers/saasoperator/groups/schemas/group.schema.js +17 -0
- package/src/controllers/saasoperator/groups/schemas/index.js +4 -0
- package/src/controllers/saasoperator/groups/schemas/new-group.schema.js +13 -0
- package/src/entities/common/domains/get-json-at-path.js +28 -0
- package/src/entities/common/domains/index.js +17 -0
- package/src/entities/common/index.js +17 -0
- package/src/entities/credentials/domains/credential-format.js +22 -0
- package/src/entities/credentials/domains/index.js +19 -0
- package/src/entities/credentials/index.js +17 -0
- package/src/entities/deep-links/domains/extract-did.js +11 -0
- package/src/entities/deep-links/domains/index.js +20 -0
- package/src/entities/deep-links/domains/velocity-protocol-uri-to-http-uri.js +32 -0
- package/src/entities/deep-links/index.js +19 -0
- package/src/entities/disclosures/domains/assert-disclosure-active.js +21 -0
- package/src/entities/disclosures/domains/compute-disclosure-configuration-type.js +29 -0
- package/src/entities/disclosures/domains/constants.js +61 -0
- package/src/entities/disclosures/domains/errors.js +34 -0
- package/src/entities/disclosures/domains/get-disclosure-configuration-type.js +60 -0
- package/src/entities/disclosures/domains/index.js +32 -0
- package/src/entities/disclosures/domains/is-issuing-disclosure.js +23 -0
- package/src/entities/disclosures/domains/parse-body-to-disclosure.js +17 -0
- package/src/entities/disclosures/domains/validate-by-identification-method.js +69 -0
- package/src/entities/disclosures/domains/validate-commercial-entity.js +26 -0
- package/src/entities/disclosures/domains/validate-disclosure-by-configuration-type.js +47 -0
- package/src/entities/disclosures/domains/validate-disclosure-default-issuing.js +77 -0
- package/src/entities/disclosures/domains/validate-disclosure.js +37 -0
- package/src/entities/disclosures/domains/validate-feed.js +16 -0
- package/src/entities/disclosures/domains/validate-presentation-definition.js +54 -0
- package/src/entities/disclosures/domains/validate-vendor-endpoint.js +22 -0
- package/src/entities/disclosures/domains/validate-vendor-webhook.js +18 -0
- package/src/entities/disclosures/factories/disclosure-factory.js +94 -0
- package/src/entities/disclosures/factories/index.js +19 -0
- package/src/entities/disclosures/index.js +22 -0
- package/src/entities/disclosures/orchestrators/get-disclosure.js +18 -0
- package/src/entities/disclosures/orchestrators/index.js +20 -0
- package/src/entities/disclosures/orchestrators/update-disclosure-configuration-type.js +32 -0
- package/src/entities/disclosures/repos/index.js +20 -0
- package/src/entities/disclosures/repos/repo.js +118 -0
- package/src/entities/disclosures/repos/set-configuration-type.js +33 -0
- package/src/entities/exchanges/adapters/index.js +17 -0
- package/src/entities/exchanges/adapters/sign-exchange-response.js +45 -0
- package/src/entities/exchanges/domains/build-exchange-progress.js +56 -0
- package/src/entities/exchanges/domains/constants.js +24 -0
- package/src/entities/exchanges/domains/ensure-exchange-state-valid.js +35 -0
- package/src/entities/exchanges/domains/errors.js +33 -0
- package/src/entities/exchanges/domains/index.js +25 -0
- package/src/entities/exchanges/domains/states.js +43 -0
- package/src/entities/exchanges/domains/types.js +31 -0
- package/src/entities/exchanges/factories/disclosure-exchange-factory.js +46 -0
- package/src/entities/exchanges/factories/index.js +20 -0
- package/src/entities/exchanges/factories/offer-exchange-factory.js +48 -0
- package/src/entities/exchanges/index.js +23 -0
- package/src/entities/exchanges/orchestrators/build-exchange-request-deep-link.js +50 -0
- package/src/entities/exchanges/orchestrators/index.js +19 -0
- package/src/entities/exchanges/repos/exchange-repo-projections.js +45 -0
- package/src/entities/exchanges/repos/exchange-state-repo-extension.js +76 -0
- package/src/entities/exchanges/repos/index.js +20 -0
- package/src/entities/exchanges/repos/repo.js +44 -0
- package/src/entities/feeds/factories/feed-factory.js +47 -0
- package/src/entities/feeds/factories/index.js +19 -0
- package/src/entities/feeds/index.js +20 -0
- package/src/entities/feeds/repos/index.js +19 -0
- package/src/entities/feeds/repos/repo.js +95 -0
- package/src/entities/groups/domains/format-group.js +11 -0
- package/src/entities/groups/domains/index.js +3 -0
- package/src/entities/groups/factories/group-factory.js +40 -0
- package/src/entities/groups/factories/index.js +19 -0
- package/src/entities/groups/index.js +22 -0
- package/src/entities/groups/orchestrators/find-group-or-error.js +16 -0
- package/src/entities/groups/orchestrators/index.js +6 -0
- package/src/entities/groups/orchestrators/validate-did.js +24 -0
- package/src/entities/groups/orchestrators/validate-group-by-user.js +16 -0
- package/src/entities/groups/orchestrators/validate-group.js +39 -0
- package/src/entities/groups/repos/delete-tenant-extension.js +13 -0
- package/src/entities/groups/repos/index.js +19 -0
- package/src/entities/groups/repos/repo.js +38 -0
- package/src/entities/groups/repos/update-or-error-extension.js +46 -0
- package/src/entities/index.js +37 -0
- package/src/entities/keys/domains/constants.js +37 -0
- package/src/entities/keys/domains/index.js +21 -0
- package/src/entities/keys/domains/is-matching-private-key-kid.js +41 -0
- package/src/entities/keys/domains/validate-key.js +62 -0
- package/src/entities/keys/factories/index.js +19 -0
- package/src/entities/keys/factories/key-factory.js +56 -0
- package/src/entities/keys/index.js +22 -0
- package/src/entities/keys/orchestrators/index.js +3 -0
- package/src/entities/keys/orchestrators/validate-did-doc-keys.js +69 -0
- package/src/entities/metadata-list-allocations/index.js +19 -0
- package/src/entities/metadata-list-allocations/repos/index.js +19 -0
- package/src/entities/metadata-list-allocations/repos/repo.js +40 -0
- package/src/entities/notifications/domains/index.js +19 -0
- package/src/entities/notifications/domains/notification-types.js +25 -0
- package/src/entities/notifications/index.js +19 -0
- package/src/entities/offers/domains/build-clean-pii-filter.js +35 -0
- package/src/entities/offers/domains/build-deeplink-url.js +120 -0
- package/src/entities/offers/domains/build-offer.js +88 -0
- package/src/entities/offers/domains/build-qr-code-url.js +37 -0
- package/src/entities/offers/domains/constants.js +32 -0
- package/src/entities/offers/domains/filter-object-ids.js +34 -0
- package/src/entities/offers/domains/generate-issuing-challenge.js +26 -0
- package/src/entities/offers/domains/generate-link-code.js +35 -0
- package/src/entities/offers/domains/index.js +31 -0
- package/src/entities/offers/domains/post-validation-offers-handler.js +31 -0
- package/src/entities/offers/domains/prepare-linked-credentials-for-holder.js +36 -0
- package/src/entities/offers/domains/resolve-subject.js +142 -0
- package/src/entities/offers/domains/validate-offer-commercial-entity.js +24 -0
- package/src/entities/offers/domains/validate-offer.js +90 -0
- package/src/entities/offers/factories/index.js +19 -0
- package/src/entities/offers/factories/offer-factory.js +119 -0
- package/src/entities/offers/index.js +22 -0
- package/src/entities/offers/orchestrators/create-verifiable-credentials.js +131 -0
- package/src/entities/offers/orchestrators/finalize-exchange.js +44 -0
- package/src/entities/offers/orchestrators/index.js +23 -0
- package/src/entities/offers/orchestrators/load-credential-refs.js +57 -0
- package/src/entities/offers/orchestrators/load-credential-types-map.js +44 -0
- package/src/entities/offers/orchestrators/prepare-offers.js +35 -0
- package/src/entities/offers/orchestrators/trigger-issued-credentials-webhook.js +63 -0
- package/src/entities/offers/repos/clean-pii-extension.js +85 -0
- package/src/entities/offers/repos/index.js +20 -0
- package/src/entities/offers/repos/issued-credential-projection.js +44 -0
- package/src/entities/offers/repos/repo.js +177 -0
- package/src/entities/presentations/domains/build-identity-doc.js +120 -0
- package/src/entities/presentations/domains/build-request-response-schema.js +46 -0
- package/src/entities/presentations/domains/build-vendor-data.js +31 -0
- package/src/entities/presentations/domains/check-payment-requirement.js +30 -0
- package/src/entities/presentations/domains/errors.js +28 -0
- package/src/entities/presentations/domains/extract-fields-from-id-credential.js +35 -0
- package/src/entities/presentations/domains/index.js +26 -0
- package/src/entities/presentations/domains/merge-credential-check-results.js +24 -0
- package/src/entities/presentations/domains/validate-presentation.js +128 -0
- package/src/entities/presentations/index.js +20 -0
- package/src/entities/presentations/orchestrators/create-presentation-request.js +148 -0
- package/src/entities/presentations/orchestrators/deduplicate-disclosure-exchange.js +52 -0
- package/src/entities/presentations/orchestrators/handle-presentation-submission.js +47 -0
- package/src/entities/presentations/orchestrators/index.js +20 -0
- package/src/entities/presentations/orchestrators/match-identity-on-exchange.js +114 -0
- package/src/entities/presentations/orchestrators/share-identification-credentials.js +110 -0
- package/src/entities/presentations/orchestrators/share-presentation.js +234 -0
- package/src/entities/push-delegate/get-push-delegate.js +37 -0
- package/src/entities/push-delegate/index.js +17 -0
- package/src/entities/redirect/index.js +3 -0
- package/src/entities/redirect/orchestrators/index.js +3 -0
- package/src/entities/redirect/orchestrators/load-org-info.js +40 -0
- package/src/entities/revocation-list-allocations/index.js +19 -0
- package/src/entities/revocation-list-allocations/repos/index.js +19 -0
- package/src/entities/revocation-list-allocations/repos/repo.js +40 -0
- package/src/entities/schemas/index.js +19 -0
- package/src/entities/schemas/orchestrators/index.js +19 -0
- package/src/entities/schemas/orchestrators/load-schema-validation.js +73 -0
- package/src/entities/tenants/domains/build-service-ids.js +27 -0
- package/src/entities/tenants/domains/extract-service.js +27 -0
- package/src/entities/tenants/domains/index.js +21 -0
- package/src/entities/tenants/domains/validate-service-ids.js +35 -0
- package/src/entities/tenants/factories/index.js +19 -0
- package/src/entities/tenants/factories/tenant-factory.js +37 -0
- package/src/entities/tenants/index.js +22 -0
- package/src/entities/tenants/orchestrators/add-primary-address-to-tenant.js +47 -0
- package/src/entities/tenants/orchestrators/create-tenant.js +91 -0
- package/src/entities/tenants/orchestrators/index.js +22 -0
- package/src/entities/tenants/orchestrators/refresh-tenant-dids.js +146 -0
- package/src/entities/tenants/orchestrators/set-tenant-default-issuing-disclosure.js +31 -0
- package/src/entities/tenants/repos/index.js +20 -0
- package/src/entities/tenants/repos/insert-tenant-extension.js +33 -0
- package/src/entities/tenants/repos/repo.js +52 -0
- package/src/entities/tenants/repos/tenant-default-projection.js +33 -0
- package/src/entities/tokens/adapters/access-token.js +49 -0
- package/src/entities/tokens/adapters/index.js +19 -0
- package/src/entities/tokens/index.js +19 -0
- package/src/entities/users/factories/index.js +19 -0
- package/src/entities/users/factories/user-factory.js +36 -0
- package/src/entities/users/index.js +20 -0
- package/src/entities/users/repos/add-anonymous-user-repo-extension.js +23 -0
- package/src/entities/users/repos/find-or-insert-vendor-user-repo-extension.js +30 -0
- package/src/entities/users/repos/index.js +19 -0
- package/src/entities/users/repos/repo.js +50 -0
- package/src/fetchers/index.js +20 -0
- package/src/fetchers/operator/identify-fetcher.js +36 -0
- package/src/fetchers/operator/index.js +21 -0
- package/src/fetchers/operator/inspection-fetcher.js +35 -0
- package/src/fetchers/operator/issuing-fetcher.js +50 -0
- package/src/fetchers/operator/webhook-auth-header.js +45 -0
- package/src/fetchers/push-gateway/generate-push-gateway-token.js +40 -0
- package/src/fetchers/push-gateway/index.js +19 -0
- package/src/fetchers/push-gateway/push-fetcher.js +39 -0
- package/src/index.js +19 -0
- package/src/init-holder-server.js +108 -0
- package/src/init-operator-server.js +101 -0
- package/src/init-server.js +120 -0
- package/src/main-holder.js +18 -0
- package/src/main-operator.js +19 -0
- package/src/main.js +18 -0
- package/src/plugins/autoload-repos.js +28 -0
- package/src/plugins/disclosure-loader-plugin.js +56 -0
- package/src/plugins/ensure-disclosure-active-plugin.js +30 -0
- package/src/plugins/ensure-disclosure-configuration-type-plugin.js +29 -0
- package/src/plugins/ensure-tenant-default-issuing-disclosure-id-plugin.js +60 -0
- package/src/plugins/ensure-tenant-primary-address-plugin.js +44 -0
- package/src/plugins/exchange-error-handler-plugin.js +51 -0
- package/src/plugins/exchange-loader-plugin.js +50 -0
- package/src/plugins/group-loader-plugin.js +51 -0
- package/src/plugins/index.js +32 -0
- package/src/plugins/kms-plugin.js +57 -0
- package/src/plugins/tenant-loader-plugin.js +91 -0
- package/src/plugins/validate-cao-plugin.js +81 -0
- package/src/plugins/vendor-routes-auth-plugin.js +24 -0
- package/src/plugins/verify-access-token-plugin.js +88 -0
- package/src/standalone.js +24 -0
- package/src/start-app-server.js +38 -0
- package/test/combined/app-redirect.test.js +199 -0
- package/test/combined/helpers/credentialagent-build-fastify.js +29 -0
- package/test/combined/helpers/index.js +22 -0
- package/test/combined/helpers/nock-registrar-app-schema-name.js +50 -0
- package/test/combined/helpers/nock-registrar-get-organization-diddoc.js +26 -0
- package/test/combined/helpers/nock-registrar-get-organization-verified-profile.js +33 -0
- package/test/combined/manifest.json.test.js +55 -0
- package/test/combined/root-controller.test.js +42 -0
- package/test/combined/schemas/education-degree.schema.json +166 -0
- package/test/combined/schemas/employment-current-v1.1.schema.json +253 -0
- package/test/combined/schemas/open-badge-credential.schema.json +1285 -0
- package/test/combined/schemas/past-employment-position-with-uri-id.schema.js +22 -0
- package/test/combined/schemas/past-employment-position.schema.json +148 -0
- package/test/combined/schemas/will-always-validate.json +10 -0
- package/test/combined/validate-cao-plugin.test.js +155 -0
- package/test/get-push-delegate.test.js +54 -0
- package/test/helpers/jwt-vc-expectation.js +109 -0
- package/test/holder/build-request-response-schema.test.js +55 -0
- package/test/holder/credential-manifest-controller.test.js +3192 -0
- package/test/holder/e2e-issuing-controller.test.js +425 -0
- package/test/holder/get-exchange-progress-controller.test.js +521 -0
- package/test/holder/get-presentation-request.test.js +906 -0
- package/test/holder/helpers/credential-type-metadata.js +98 -0
- package/test/holder/helpers/credentialagent-holder-build-fastify.js +32 -0
- package/test/holder/helpers/generate-presentation.js +441 -0
- package/test/holder/helpers/generate-test-access-token.js +54 -0
- package/test/holder/helpers/jwt-access-token-expectation.js +32 -0
- package/test/holder/helpers/jwt-vc-expectation.js +115 -0
- package/test/holder/issuing-controller.test.js +7076 -0
- package/test/holder/oauth-token-controller.test.js +412 -0
- package/test/holder/presentation-submission.test.js +2365 -0
- package/test/holder/submit-identification.test.js +4815 -0
- package/test/operator/check-credentials-controller-v0.8.test.js +832 -0
- package/test/operator/credentials-revoke.test.js +536 -0
- package/test/operator/disclosures-controller-v0.8.test.js +4157 -0
- package/test/operator/exchanges-controller-v0.8.test.js +414 -0
- package/test/operator/exchanges-id-controller-v0.8.test.js +162 -0
- package/test/operator/feeds-controller-v0.8.test.js +659 -0
- package/test/operator/generate-push-gateway-token.test.js +116 -0
- package/test/operator/groups-controller.test.js +145 -0
- package/test/operator/groups-id-controller.test.js +287 -0
- package/test/operator/helpers/create-test-org-doc.js +60 -0
- package/test/operator/helpers/credentialagent-operator-build-fastify.js +32 -0
- package/test/operator/helpers/find-kms-key.js +31 -0
- package/test/operator/helpers/generate-primary-and-add-operator-to-primary.js +63 -0
- package/test/operator/helpers/init-agent-kms.js +22 -0
- package/test/operator/issued-credentials-controller-v0.8.test.js +398 -0
- package/test/operator/keys-controller-v0.8.test.js +1130 -0
- package/test/operator/offer-data-controller-v0.8.test.js +253 -0
- package/test/operator/offers-controller-v0.8.test.js +3026 -0
- package/test/operator/set-configuration-type-modifier.test.js +75 -0
- package/test/operator/swagger.test.js +37 -0
- package/test/operator/tenant-controller-v0.8.test.js +730 -0
- package/test/operator/tenant-loader-plugin.test.js +96 -0
- package/test/operator/tenants-controller-v0.8.test.js +2093 -0
- package/test/operator/users-controller-v0.8.test.js +137 -0
- package/test/operator/vc-api-credentials.test.js +963 -0
- package/verification.env +28 -0
|
@@ -0,0 +1,2093 @@
|
|
|
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
|
+
// eslint-disable-next-line import/order
|
|
18
|
+
const nock = require('nock');
|
|
19
|
+
const { mongoDb } = require('@spencejs/spence-mongo-repos');
|
|
20
|
+
const { ObjectId } = require('mongodb');
|
|
21
|
+
const { first, last, omit } = require('lodash/fp');
|
|
22
|
+
const {
|
|
23
|
+
ISO_DATETIME_FORMAT,
|
|
24
|
+
OBJECT_ID_FORMAT,
|
|
25
|
+
} = require('@verii/test-regexes');
|
|
26
|
+
const { errorResponseMatcher } = require('@verii/tests-helpers');
|
|
27
|
+
const { toEthereumAddress } = require('@verii/blockchain-functions');
|
|
28
|
+
const { rootPrivateKey } = require('@verii/sample-data');
|
|
29
|
+
const { KeyPurposes, generateKeyPair, decrypt } = require('@verii/crypto');
|
|
30
|
+
const {
|
|
31
|
+
deployTestPermissionsContract,
|
|
32
|
+
} = require('@verii/contract-permissions/test/helpers/deploy-test-permissions-contract');
|
|
33
|
+
const { hexFromJwk, publicKeyFromPrivateKey } = require('@verii/jwt');
|
|
34
|
+
const { jwkFromSecp256k1Key } = require('@verii/jwt');
|
|
35
|
+
const buildFastify = require('./helpers/credentialagent-operator-build-fastify');
|
|
36
|
+
const { createOrgDoc } = require('./helpers/create-test-org-doc');
|
|
37
|
+
const {
|
|
38
|
+
generatePrimaryAndAddOperatorToPrimary,
|
|
39
|
+
} = require('./helpers/generate-primary-and-add-operator-to-primary');
|
|
40
|
+
const {
|
|
41
|
+
nockRegistrarGetOrganizationDidDoc,
|
|
42
|
+
} = require('../combined/helpers/nock-registrar-get-organization-diddoc');
|
|
43
|
+
const {
|
|
44
|
+
initTenantFactory,
|
|
45
|
+
tenantRepoPlugin,
|
|
46
|
+
initGroupsFactory,
|
|
47
|
+
initOfferFactory,
|
|
48
|
+
initOfferExchangeFactory,
|
|
49
|
+
initDisclosureFactory,
|
|
50
|
+
initUserFactory,
|
|
51
|
+
} = require('../../src/entities');
|
|
52
|
+
const { initFindKmsKey } = require('./helpers/find-kms-key');
|
|
53
|
+
|
|
54
|
+
const testUrl = '/operator-api/v0.8/tenants';
|
|
55
|
+
|
|
56
|
+
describe('Tenants management Test suite', () => {
|
|
57
|
+
let fastify;
|
|
58
|
+
let persistTenant;
|
|
59
|
+
let persistGroup;
|
|
60
|
+
let persistDisclosure;
|
|
61
|
+
let persistOffer;
|
|
62
|
+
let persistOfferExchange;
|
|
63
|
+
let persistVendorUserIdMapping;
|
|
64
|
+
let orgDoc;
|
|
65
|
+
let orgKey;
|
|
66
|
+
let orgPublicKey;
|
|
67
|
+
let primaryAddress;
|
|
68
|
+
let tenantRepo;
|
|
69
|
+
let findKmsKey;
|
|
70
|
+
|
|
71
|
+
beforeAll(async () => {
|
|
72
|
+
fastify = buildFastify();
|
|
73
|
+
await fastify.ready();
|
|
74
|
+
|
|
75
|
+
({ persistTenant } = initTenantFactory(fastify));
|
|
76
|
+
({ persistGroup } = initGroupsFactory(fastify));
|
|
77
|
+
({ persistOffer } = initOfferFactory(fastify));
|
|
78
|
+
({ persistDisclosure } = initDisclosureFactory(fastify));
|
|
79
|
+
({ persistOfferExchange } = initOfferExchangeFactory(fastify));
|
|
80
|
+
({ persistVendorUserIdMapping } = initUserFactory(fastify));
|
|
81
|
+
|
|
82
|
+
const deployedContract = await deployTestPermissionsContract(
|
|
83
|
+
rootPrivateKey,
|
|
84
|
+
fastify.config.rpcUrl
|
|
85
|
+
);
|
|
86
|
+
fastify.config.permissionsContractAddress =
|
|
87
|
+
await deployedContract.getAddress();
|
|
88
|
+
tenantRepo = tenantRepoPlugin(fastify)();
|
|
89
|
+
findKmsKey = initFindKmsKey(fastify);
|
|
90
|
+
({ orgDoc, orgKey, orgPublicKey } = await createOrgDoc());
|
|
91
|
+
|
|
92
|
+
primaryAddress = await generatePrimaryAndAddOperatorToPrimary(
|
|
93
|
+
toEthereumAddress(orgPublicKey),
|
|
94
|
+
{
|
|
95
|
+
config: fastify.config,
|
|
96
|
+
log: fastify.log,
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}, 10000);
|
|
100
|
+
|
|
101
|
+
beforeEach(async () => {
|
|
102
|
+
nock.cleanAll();
|
|
103
|
+
await mongoDb().collection('tenants').deleteMany({});
|
|
104
|
+
await mongoDb().collection('keys').deleteMany({});
|
|
105
|
+
await mongoDb().collection('groups').deleteMany({});
|
|
106
|
+
nockRegistrarGetOrganizationDidDoc(orgDoc.id, orgDoc);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
afterAll(async () => {
|
|
110
|
+
await fastify.close();
|
|
111
|
+
nock.cleanAll();
|
|
112
|
+
nock.restore();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('Tenant Creation tests', () => {
|
|
116
|
+
it('should HTTP 404 when DID not found when trying to create', async () => {
|
|
117
|
+
const { orgDoc: orgDoc2, orgKey: orgKey2 } = await createOrgDoc();
|
|
118
|
+
nockRegistrarGetOrganizationDidDoc(orgDoc2.id, {});
|
|
119
|
+
|
|
120
|
+
const payload = {
|
|
121
|
+
did: orgDoc2.id,
|
|
122
|
+
serviceIds: [`${orgDoc2.id}#test-service`],
|
|
123
|
+
keys: [
|
|
124
|
+
{
|
|
125
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
126
|
+
algorithm: 'SECP256K1',
|
|
127
|
+
encoding: 'hex',
|
|
128
|
+
kidFragment: first(orgDoc2.assertionMethod),
|
|
129
|
+
key: orgKey2,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const response = await fastify.injectJson({
|
|
135
|
+
method: 'POST',
|
|
136
|
+
url: testUrl,
|
|
137
|
+
payload,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(response.statusCode).toEqual(404);
|
|
141
|
+
expect(response.json).toEqual(
|
|
142
|
+
errorResponseMatcher({
|
|
143
|
+
error: 'Not Found',
|
|
144
|
+
errorCode: 'did_not_found',
|
|
145
|
+
message: 'DID not found on the Velocity network registrar.',
|
|
146
|
+
statusCode: 404,
|
|
147
|
+
})
|
|
148
|
+
);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should HTTP 404 when registrar return 500', async () => {
|
|
152
|
+
const { orgDoc: orgDoc2, orgKey: orgKey2 } = await createOrgDoc();
|
|
153
|
+
nock('http://oracle.localhost.test')
|
|
154
|
+
.get(`/api/v0.6/resolve-did/${orgDoc2.id}`)
|
|
155
|
+
.reply(404, {});
|
|
156
|
+
const payload = {
|
|
157
|
+
did: orgDoc2.id,
|
|
158
|
+
serviceIds: [`${orgDoc2.id}#test-service`],
|
|
159
|
+
keys: [
|
|
160
|
+
{
|
|
161
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
162
|
+
algorithm: 'SECP256K1',
|
|
163
|
+
encoding: 'hex',
|
|
164
|
+
kidFragment: first(orgDoc2.assertionMethod),
|
|
165
|
+
key: orgKey2,
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const response = await fastify.injectJson({
|
|
171
|
+
method: 'POST',
|
|
172
|
+
url: testUrl,
|
|
173
|
+
payload,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
expect(response.statusCode).toEqual(404);
|
|
177
|
+
expect(response.json).toEqual(
|
|
178
|
+
errorResponseMatcher({
|
|
179
|
+
error: 'Not Found',
|
|
180
|
+
errorCode: 'did_not_found',
|
|
181
|
+
message: 'DID not found on the Velocity network registrar.',
|
|
182
|
+
statusCode: 404,
|
|
183
|
+
})
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should HTTP 409 and not create additional tenant', async () => {
|
|
188
|
+
await persistTenant({
|
|
189
|
+
did: orgDoc.id,
|
|
190
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const payload = {
|
|
194
|
+
did: orgDoc.id,
|
|
195
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const response = await fastify.injectJson({
|
|
199
|
+
method: 'POST',
|
|
200
|
+
url: testUrl,
|
|
201
|
+
payload,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(response.statusCode).toEqual(409);
|
|
205
|
+
expect(response.json).toEqual({
|
|
206
|
+
code: '11000',
|
|
207
|
+
statusCode: 409,
|
|
208
|
+
error: 'Conflict',
|
|
209
|
+
message: expect.stringMatching(/duplicate key/gi),
|
|
210
|
+
});
|
|
211
|
+
const tenantDocumentsCount = await mongoDb()
|
|
212
|
+
.collection('tenants')
|
|
213
|
+
.countDocuments();
|
|
214
|
+
expect(tenantDocumentsCount).toEqual(1);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should HTTP 400 and not create tenant or keys when no key purpose is provided', async () => {
|
|
218
|
+
const payload = {
|
|
219
|
+
did: orgDoc.id,
|
|
220
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
221
|
+
keys: [
|
|
222
|
+
{
|
|
223
|
+
purposes: [],
|
|
224
|
+
algorithm: 'SECP256K1',
|
|
225
|
+
encoding: 'hex',
|
|
226
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
227
|
+
key: orgKey,
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
231
|
+
algorithm: 'SECP256K1',
|
|
232
|
+
encoding: 'hex',
|
|
233
|
+
kidFragment: `${first(orgDoc.assertionMethod)}2`,
|
|
234
|
+
key: orgKey,
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const response = await fastify.injectJson({
|
|
240
|
+
method: 'POST',
|
|
241
|
+
url: testUrl,
|
|
242
|
+
payload,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
expect(response.statusCode).toEqual(400);
|
|
246
|
+
expect(response.json).toEqual(
|
|
247
|
+
errorResponseMatcher({
|
|
248
|
+
error: 'Bad Request',
|
|
249
|
+
errorCode: 'request_validation_failed',
|
|
250
|
+
message: 'body/keys/0/purposes must NOT have fewer than 1 items',
|
|
251
|
+
statusCode: 400,
|
|
252
|
+
})
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const tenantDocumentsCount = await mongoDb()
|
|
256
|
+
.collection('tenants')
|
|
257
|
+
.countDocuments();
|
|
258
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
259
|
+
|
|
260
|
+
const keyDocumentsCount = await mongoDb()
|
|
261
|
+
.collection('keys')
|
|
262
|
+
.countDocuments();
|
|
263
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it('should HTTP 400 and not create tenant or keys when a key purpose is not recognized', async () => {
|
|
267
|
+
const payload = {
|
|
268
|
+
did: orgDoc.id,
|
|
269
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
270
|
+
keys: [
|
|
271
|
+
{
|
|
272
|
+
purposes: ['unrecognized-purpose'],
|
|
273
|
+
algorithm: 'SECP256K1',
|
|
274
|
+
encoding: 'hex',
|
|
275
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
276
|
+
key: orgKey,
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
280
|
+
algorithm: 'SECP256K1',
|
|
281
|
+
encoding: 'hex',
|
|
282
|
+
kidFragment: `${first(orgDoc.assertionMethod)}2`,
|
|
283
|
+
key: orgKey,
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const response = await fastify.injectJson({
|
|
289
|
+
method: 'POST',
|
|
290
|
+
url: testUrl,
|
|
291
|
+
payload,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
expect(response.statusCode).toEqual(400);
|
|
295
|
+
expect(response.json).toEqual(
|
|
296
|
+
errorResponseMatcher({
|
|
297
|
+
error: 'Bad Request',
|
|
298
|
+
errorCode: 'missing_error_code',
|
|
299
|
+
message: 'Unrecognized purpose detected',
|
|
300
|
+
statusCode: 400,
|
|
301
|
+
})
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
const tenantDocumentsCount = await mongoDb()
|
|
305
|
+
.collection('tenants')
|
|
306
|
+
.countDocuments();
|
|
307
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
308
|
+
|
|
309
|
+
const keyDocumentsCount = await mongoDb()
|
|
310
|
+
.collection('keys')
|
|
311
|
+
.countDocuments();
|
|
312
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it('should HTTP 400 and not create tenant or keys when a key purpose is duplicated', async () => {
|
|
316
|
+
const payload = {
|
|
317
|
+
did: orgDoc.id,
|
|
318
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
319
|
+
keys: [
|
|
320
|
+
{
|
|
321
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
322
|
+
algorithm: 'SECP256K1',
|
|
323
|
+
encoding: 'hex',
|
|
324
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
325
|
+
key: orgKey,
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
329
|
+
algorithm: 'SECP256K1',
|
|
330
|
+
encoding: 'hex',
|
|
331
|
+
kidFragment: `${first(orgDoc.assertionMethod)}2`,
|
|
332
|
+
key: orgKey,
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const response = await fastify.injectJson({
|
|
338
|
+
method: 'POST',
|
|
339
|
+
url: testUrl,
|
|
340
|
+
payload,
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
expect(response.statusCode).toEqual(400);
|
|
344
|
+
expect(response.json).toEqual(
|
|
345
|
+
errorResponseMatcher({
|
|
346
|
+
error: 'Bad Request',
|
|
347
|
+
errorCode: 'missing_error_code',
|
|
348
|
+
message: 'Duplicate key purposes detected',
|
|
349
|
+
statusCode: 400,
|
|
350
|
+
})
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
const tenantDocumentsCount = await mongoDb()
|
|
354
|
+
.collection('tenants')
|
|
355
|
+
.countDocuments();
|
|
356
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
357
|
+
|
|
358
|
+
const keyDocumentsCount = await mongoDb()
|
|
359
|
+
.collection('keys')
|
|
360
|
+
.countDocuments();
|
|
361
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('should HTTP 400 and not create tenant or keys when a key algorithm is not recognized', async () => {
|
|
365
|
+
const payload = {
|
|
366
|
+
did: orgDoc.id,
|
|
367
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
368
|
+
keys: [
|
|
369
|
+
{
|
|
370
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
371
|
+
algorithm: 'unrecognized-algorithm',
|
|
372
|
+
encoding: 'hex',
|
|
373
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
374
|
+
key: orgKey,
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const response = await fastify.injectJson({
|
|
380
|
+
method: 'POST',
|
|
381
|
+
url: testUrl,
|
|
382
|
+
payload,
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
expect(response.statusCode).toEqual(400);
|
|
386
|
+
expect(response.json).toEqual(
|
|
387
|
+
errorResponseMatcher({
|
|
388
|
+
error: 'Bad Request',
|
|
389
|
+
errorCode: 'missing_error_code',
|
|
390
|
+
message: 'Unrecognized algorithm',
|
|
391
|
+
statusCode: 400,
|
|
392
|
+
})
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
const tenantDocumentsCount = await mongoDb()
|
|
396
|
+
.collection('tenants')
|
|
397
|
+
.countDocuments();
|
|
398
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
399
|
+
|
|
400
|
+
const keyDocumentsCount = await mongoDb()
|
|
401
|
+
.collection('keys')
|
|
402
|
+
.countDocuments();
|
|
403
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it('should HTTP 400 and not create tenant or keys when a key encoding is not recognized', async () => {
|
|
407
|
+
const payload = {
|
|
408
|
+
did: orgDoc.id,
|
|
409
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
410
|
+
keys: [
|
|
411
|
+
{
|
|
412
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
413
|
+
algorithm: 'SECP256K1',
|
|
414
|
+
encoding: 'unrecognized-encoding',
|
|
415
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
416
|
+
key: orgKey,
|
|
417
|
+
},
|
|
418
|
+
],
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const response = await fastify.injectJson({
|
|
422
|
+
method: 'POST',
|
|
423
|
+
url: testUrl,
|
|
424
|
+
payload,
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
expect(response.statusCode).toEqual(400);
|
|
428
|
+
expect(response.json).toEqual(
|
|
429
|
+
errorResponseMatcher({
|
|
430
|
+
error: 'Bad Request',
|
|
431
|
+
errorCode: 'missing_error_code',
|
|
432
|
+
message: 'Unrecognized encoding',
|
|
433
|
+
statusCode: 400,
|
|
434
|
+
})
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
const tenantDocumentsCount = await mongoDb()
|
|
438
|
+
.collection('tenants')
|
|
439
|
+
.countDocuments();
|
|
440
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
441
|
+
|
|
442
|
+
const keyDocumentsCount = await mongoDb()
|
|
443
|
+
.collection('keys')
|
|
444
|
+
.countDocuments();
|
|
445
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should HTTP 400 and not create tenant or keys when a kid fragment is duplicated', async () => {
|
|
449
|
+
const payload = {
|
|
450
|
+
did: orgDoc.id,
|
|
451
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
452
|
+
keys: [
|
|
453
|
+
{
|
|
454
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
455
|
+
algorithm: 'SECP256K1',
|
|
456
|
+
encoding: 'hex',
|
|
457
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
458
|
+
key: orgKey,
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
purposes: ['ISSUING_METADATA'],
|
|
462
|
+
algorithm: 'SECP256K1',
|
|
463
|
+
encoding: 'hex',
|
|
464
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
465
|
+
key: orgKey,
|
|
466
|
+
},
|
|
467
|
+
],
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
const response = await fastify.injectJson({
|
|
471
|
+
method: 'POST',
|
|
472
|
+
url: testUrl,
|
|
473
|
+
payload,
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
expect(response.statusCode).toEqual(400);
|
|
477
|
+
expect(response.json).toEqual(
|
|
478
|
+
errorResponseMatcher({
|
|
479
|
+
error: 'Bad Request',
|
|
480
|
+
errorCode: 'missing_error_code',
|
|
481
|
+
message: 'Duplicate kid fragments purposes detected',
|
|
482
|
+
statusCode: 400,
|
|
483
|
+
})
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
const tenantDocumentsCount = await mongoDb()
|
|
487
|
+
.collection('tenants')
|
|
488
|
+
.countDocuments();
|
|
489
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
490
|
+
|
|
491
|
+
const keyDocumentsCount = await mongoDb()
|
|
492
|
+
.collection('keys')
|
|
493
|
+
.countDocuments();
|
|
494
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it('should HTTP 400 and not create tenant or keys when a key service is not found on document', async () => {
|
|
498
|
+
const serviceId = `${orgDoc.id}#not-a-service`;
|
|
499
|
+
const payload = {
|
|
500
|
+
did: orgDoc.id,
|
|
501
|
+
serviceIds: [serviceId],
|
|
502
|
+
keys: [
|
|
503
|
+
{
|
|
504
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
505
|
+
algorithm: 'SECP256K1',
|
|
506
|
+
encoding: 'hex',
|
|
507
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
508
|
+
key: orgKey,
|
|
509
|
+
},
|
|
510
|
+
],
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
const response = await fastify.injectJson({
|
|
514
|
+
method: 'POST',
|
|
515
|
+
url: testUrl,
|
|
516
|
+
payload,
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
expect(response.statusCode).toEqual(400);
|
|
520
|
+
expect(response.json).toEqual(
|
|
521
|
+
errorResponseMatcher({
|
|
522
|
+
error: 'Bad Request',
|
|
523
|
+
errorCode: 'missing_error_code',
|
|
524
|
+
message: `ServiceId ${serviceId} is not on did document for did: ${orgDoc.id}`,
|
|
525
|
+
statusCode: 400,
|
|
526
|
+
})
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
const tenantDocumentsCount = await mongoDb()
|
|
530
|
+
.collection('tenants')
|
|
531
|
+
.countDocuments();
|
|
532
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
533
|
+
|
|
534
|
+
const keyDocumentsCount = await mongoDb()
|
|
535
|
+
.collection('keys')
|
|
536
|
+
.countDocuments();
|
|
537
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it('should HTTP 400 and not create tenant or keys when a private key does not match with public key on document', async () => {
|
|
541
|
+
const payload = {
|
|
542
|
+
did: orgDoc.id,
|
|
543
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
544
|
+
keys: [
|
|
545
|
+
{
|
|
546
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
547
|
+
algorithm: 'SECP256K1',
|
|
548
|
+
encoding: 'hex',
|
|
549
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
550
|
+
key: 'non-matching-key',
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
const response = await fastify.injectJson({
|
|
556
|
+
method: 'POST',
|
|
557
|
+
url: testUrl,
|
|
558
|
+
payload,
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
expect(response.statusCode).toEqual(400);
|
|
562
|
+
expect(response.json).toEqual(
|
|
563
|
+
errorResponseMatcher({
|
|
564
|
+
error: 'Bad Request',
|
|
565
|
+
errorCode: 'missing_error_code',
|
|
566
|
+
message: 'Private key not matched to document',
|
|
567
|
+
statusCode: 400,
|
|
568
|
+
})
|
|
569
|
+
);
|
|
570
|
+
|
|
571
|
+
const tenantDocumentsCount = await mongoDb()
|
|
572
|
+
.collection('tenants')
|
|
573
|
+
.countDocuments();
|
|
574
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
575
|
+
|
|
576
|
+
const keyDocumentsCount = await mongoDb()
|
|
577
|
+
.collection('keys')
|
|
578
|
+
.countDocuments();
|
|
579
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
it('should 400 if webhookUrl is not uri', async () => {
|
|
583
|
+
const payload = {
|
|
584
|
+
did: orgDoc.id,
|
|
585
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
586
|
+
keys: [],
|
|
587
|
+
webhookUrl: 'customUrl',
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
const response = await fastify.injectJson({
|
|
591
|
+
method: 'POST',
|
|
592
|
+
url: testUrl,
|
|
593
|
+
payload,
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
expect(response.statusCode).toEqual(400);
|
|
597
|
+
expect(response.json).toEqual(
|
|
598
|
+
errorResponseMatcher({
|
|
599
|
+
error: 'Bad Request',
|
|
600
|
+
errorCode: 'request_validation_failed',
|
|
601
|
+
message: 'body/webhookUrl must match format "uri"',
|
|
602
|
+
statusCode: 400,
|
|
603
|
+
})
|
|
604
|
+
);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it('should 400 if webhookAuth type is not a bearer', async () => {
|
|
608
|
+
const payload = {
|
|
609
|
+
did: orgDoc.id,
|
|
610
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
611
|
+
keys: [],
|
|
612
|
+
webhookAuth: {
|
|
613
|
+
type: 'foo',
|
|
614
|
+
bearerToken: 'secret',
|
|
615
|
+
},
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const response = await fastify.injectJson({
|
|
619
|
+
method: 'POST',
|
|
620
|
+
url: testUrl,
|
|
621
|
+
payload,
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
expect(response.statusCode).toEqual(400);
|
|
625
|
+
expect(response.json).toEqual(
|
|
626
|
+
errorResponseMatcher({
|
|
627
|
+
error: 'Bad Request',
|
|
628
|
+
errorCode: 'request_validation_failed',
|
|
629
|
+
message:
|
|
630
|
+
'body/webhookAuth/type must be equal to one of the allowed values',
|
|
631
|
+
statusCode: 400,
|
|
632
|
+
})
|
|
633
|
+
);
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it('should 200 and create a tenant db document and no key db document when creating tenant with no keys', async () => {
|
|
637
|
+
const payload = {
|
|
638
|
+
did: orgDoc.id,
|
|
639
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
640
|
+
keys: [],
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
const response = await fastify.injectJson({
|
|
644
|
+
method: 'POST',
|
|
645
|
+
url: testUrl,
|
|
646
|
+
payload,
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
expect(response.statusCode).toEqual(201);
|
|
650
|
+
expect(response.json).toEqual({
|
|
651
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
652
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
const tenantFromDb = await mongoDb()
|
|
656
|
+
.collection('tenants')
|
|
657
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
658
|
+
expect(tenantFromDb).toEqual({
|
|
659
|
+
_id: new ObjectId(response.json.id),
|
|
660
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
661
|
+
did: orgDoc.id,
|
|
662
|
+
dids: [orgDoc.id, ...orgDoc.alsoKnownAs],
|
|
663
|
+
createdAt: expect.any(Date),
|
|
664
|
+
updatedAt: expect.any(Date),
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
const keyDocumentsCount = await mongoDb()
|
|
668
|
+
.collection('keys')
|
|
669
|
+
.countDocuments();
|
|
670
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
it('should 201 create a tenant with webhookAuth', async () => {
|
|
674
|
+
const payload = {
|
|
675
|
+
did: orgDoc.id,
|
|
676
|
+
serviceIds: ['#test-service'],
|
|
677
|
+
keys: [],
|
|
678
|
+
webhookAuth: {
|
|
679
|
+
type: 'bearer',
|
|
680
|
+
bearerToken: 'secret',
|
|
681
|
+
},
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
const response = await fastify.injectJson({
|
|
685
|
+
method: 'POST',
|
|
686
|
+
url: testUrl,
|
|
687
|
+
payload,
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
const updatedTenant = await tenantRepo.findOne(
|
|
691
|
+
new ObjectId(response.json.id)
|
|
692
|
+
);
|
|
693
|
+
|
|
694
|
+
expect(response.statusCode).toEqual(201);
|
|
695
|
+
expect(response.json).toEqual({
|
|
696
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
697
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
698
|
+
});
|
|
699
|
+
expect(
|
|
700
|
+
decrypt(
|
|
701
|
+
updatedTenant.webhookAuth.bearerToken,
|
|
702
|
+
fastify.config.mongoSecret
|
|
703
|
+
)
|
|
704
|
+
).toEqual('secret');
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
it('should 201 create a tenant when relative serviceIds are supplied', async () => {
|
|
708
|
+
const payload = {
|
|
709
|
+
did: orgDoc.id,
|
|
710
|
+
serviceIds: ['#test-service'],
|
|
711
|
+
keys: [],
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
const response = await fastify.injectJson({
|
|
715
|
+
method: 'POST',
|
|
716
|
+
url: testUrl,
|
|
717
|
+
payload,
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
expect(response.statusCode).toEqual(201);
|
|
721
|
+
expect(response.json).toEqual({
|
|
722
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
723
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
it('should 201 and create a tenant and key db documents when creating tenant with a key with 1 purpose', async () => {
|
|
728
|
+
const payload = {
|
|
729
|
+
did: orgDoc.id,
|
|
730
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
731
|
+
keys: [
|
|
732
|
+
{
|
|
733
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
734
|
+
algorithm: 'SECP256K1',
|
|
735
|
+
encoding: 'hex',
|
|
736
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
737
|
+
key: orgKey,
|
|
738
|
+
},
|
|
739
|
+
],
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
const response = await fastify.injectJson({
|
|
743
|
+
method: 'POST',
|
|
744
|
+
url: testUrl,
|
|
745
|
+
payload,
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
expect(response.statusCode).toEqual(201);
|
|
749
|
+
expect(response.json).toEqual({
|
|
750
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
751
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
const tenantFromDb = await mongoDb()
|
|
755
|
+
.collection('tenants')
|
|
756
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
757
|
+
expect(tenantFromDb).toEqual({
|
|
758
|
+
_id: new ObjectId(response.json.id),
|
|
759
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
760
|
+
did: orgDoc.id,
|
|
761
|
+
dids: [orgDoc.id, ...orgDoc.alsoKnownAs],
|
|
762
|
+
primaryAddress,
|
|
763
|
+
createdAt: expect.any(Date),
|
|
764
|
+
updatedAt: expect.any(Date),
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
expect(
|
|
768
|
+
await findKmsKey({ tenantId: new ObjectId(response.json.id) })
|
|
769
|
+
).toEqual({
|
|
770
|
+
_id: expect.any(ObjectId),
|
|
771
|
+
key: jwkFromSecp256k1Key(orgKey),
|
|
772
|
+
kidFragment: last(orgDoc.assertionMethod),
|
|
773
|
+
});
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
it('should 201 and create a tenant and do not lookup primaryAddress for tenant if key with DLT_TRANSACTION does not exist', async () => {
|
|
777
|
+
const payload = {
|
|
778
|
+
did: orgDoc.id,
|
|
779
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
780
|
+
keys: [
|
|
781
|
+
{
|
|
782
|
+
purposes: [KeyPurposes.ISSUING_METADATA],
|
|
783
|
+
algorithm: 'SECP256K1',
|
|
784
|
+
encoding: 'hex',
|
|
785
|
+
kidFragment: first(orgDoc.assertionMethod),
|
|
786
|
+
key: orgKey,
|
|
787
|
+
},
|
|
788
|
+
],
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
const response = await fastify.injectJson({
|
|
792
|
+
method: 'POST',
|
|
793
|
+
url: testUrl,
|
|
794
|
+
payload,
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
expect(response.statusCode).toEqual(201);
|
|
798
|
+
expect(response.json).toEqual({
|
|
799
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
800
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
const tenantFromDb = await mongoDb()
|
|
804
|
+
.collection('tenants')
|
|
805
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
806
|
+
expect(tenantFromDb).toEqual({
|
|
807
|
+
_id: new ObjectId(response.json.id),
|
|
808
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
809
|
+
did: orgDoc.id,
|
|
810
|
+
dids: [orgDoc.id, ...orgDoc.alsoKnownAs],
|
|
811
|
+
createdAt: expect.any(Date),
|
|
812
|
+
updatedAt: expect.any(Date),
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
describe('Tenant Retrieving tests', () => {
|
|
818
|
+
it('should return empty array if there is not tenants', async () => {
|
|
819
|
+
const response = await fastify.injectJson({
|
|
820
|
+
method: 'GET',
|
|
821
|
+
url: testUrl,
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
expect(response.statusCode).toEqual(200);
|
|
825
|
+
expect(response.json).toEqual([]);
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
it('should return all tenants if user admin', async () => {
|
|
829
|
+
await persistTenant();
|
|
830
|
+
await persistTenant();
|
|
831
|
+
await persistTenant();
|
|
832
|
+
const response = await fastify.injectJson({
|
|
833
|
+
method: 'GET',
|
|
834
|
+
url: testUrl,
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
expect(response.statusCode).toEqual(200);
|
|
838
|
+
expect(response.json).toHaveLength(3);
|
|
839
|
+
});
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
describe('Tenant with group tests', () => {
|
|
843
|
+
describe('Tenant creation', () => {
|
|
844
|
+
it('should 404 if group not exists', async () => {
|
|
845
|
+
const payload = {
|
|
846
|
+
did: orgDoc.id,
|
|
847
|
+
serviceIds: ['#test-service'],
|
|
848
|
+
keys: [],
|
|
849
|
+
webhookAuth: {
|
|
850
|
+
type: 'bearer',
|
|
851
|
+
bearerToken: 'secret',
|
|
852
|
+
},
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
const groupId = 'no';
|
|
856
|
+
|
|
857
|
+
const response = await fastify.injectJson({
|
|
858
|
+
method: 'POST',
|
|
859
|
+
url: testUrl,
|
|
860
|
+
payload,
|
|
861
|
+
headers: {
|
|
862
|
+
'x-override-auth-user-group-id': groupId,
|
|
863
|
+
},
|
|
864
|
+
});
|
|
865
|
+
expect(response.statusCode).toEqual(404);
|
|
866
|
+
expect(response.json).toEqual(
|
|
867
|
+
errorResponseMatcher({
|
|
868
|
+
error: 'Not Found',
|
|
869
|
+
errorCode: 'group_does_not_exist',
|
|
870
|
+
message: 'Group does not exist',
|
|
871
|
+
statusCode: 404,
|
|
872
|
+
})
|
|
873
|
+
);
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
describe('Tenant Retrieving', () => {
|
|
878
|
+
it('should return tenants from the group', async () => {
|
|
879
|
+
const groupId = 'secret';
|
|
880
|
+
await persistTenant();
|
|
881
|
+
const tenant = await persistTenant();
|
|
882
|
+
const tenant2 = await persistTenant();
|
|
883
|
+
|
|
884
|
+
await persistGroup({ _id: groupId, dids: [tenant.did] });
|
|
885
|
+
await persistGroup({ _id: 'on-oiu', dids: [tenant2.did] });
|
|
886
|
+
|
|
887
|
+
const response = await fastify.injectJson({
|
|
888
|
+
method: 'GET',
|
|
889
|
+
url: testUrl,
|
|
890
|
+
headers: {
|
|
891
|
+
'x-override-auth-user-group-id': groupId,
|
|
892
|
+
},
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
expect(response.statusCode).toEqual(200);
|
|
896
|
+
expect(response.json).toHaveLength(1);
|
|
897
|
+
expect(response.json).toEqual([
|
|
898
|
+
{ ...omit(['_id'], tenant), id: tenant._id },
|
|
899
|
+
]);
|
|
900
|
+
});
|
|
901
|
+
});
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
describe('Did web document', () => {
|
|
905
|
+
const getDidWebDoc = (key, did = 'did:web:123') => ({
|
|
906
|
+
'@context': [
|
|
907
|
+
'https://www.w3.org/ns/did/v1',
|
|
908
|
+
'https://w3id.org/security/suites/jws-2020/v1',
|
|
909
|
+
],
|
|
910
|
+
id: did,
|
|
911
|
+
authentication: [key.id],
|
|
912
|
+
assertionMethod: [key.id],
|
|
913
|
+
verificationMethod: [key],
|
|
914
|
+
publicKey: [key],
|
|
915
|
+
service: [
|
|
916
|
+
{
|
|
917
|
+
id: '#test-service',
|
|
918
|
+
type: 'VlcCareerIssuer_v1',
|
|
919
|
+
serviceEndpoint: 'https://agent.samplevendor.com/acme',
|
|
920
|
+
},
|
|
921
|
+
],
|
|
922
|
+
});
|
|
923
|
+
let keyPair;
|
|
924
|
+
|
|
925
|
+
beforeAll(async () => {
|
|
926
|
+
keyPair = await generateKeyPair({ format: 'jwk' });
|
|
927
|
+
orgKey = keyPair.privateKey;
|
|
928
|
+
orgDoc = getDidWebDoc(
|
|
929
|
+
{
|
|
930
|
+
id: 'did:web:123%3A3000#key-0',
|
|
931
|
+
type: 'JsonWebKey2020',
|
|
932
|
+
controller: 'did:web:123',
|
|
933
|
+
publicKeyJwk: keyPair.publicKey,
|
|
934
|
+
},
|
|
935
|
+
'did:web:123%3A3000'
|
|
936
|
+
);
|
|
937
|
+
orgPublicKey = hexFromJwk(keyPair.publicKey, false);
|
|
938
|
+
|
|
939
|
+
primaryAddress = await generatePrimaryAndAddOperatorToPrimary(
|
|
940
|
+
toEthereumAddress(orgPublicKey),
|
|
941
|
+
{
|
|
942
|
+
config: fastify.config,
|
|
943
|
+
log: fastify.log,
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
}, 10000);
|
|
947
|
+
|
|
948
|
+
beforeEach(async () => {
|
|
949
|
+
nockRegistrarGetOrganizationDidDoc('did:web:123', orgDoc);
|
|
950
|
+
});
|
|
951
|
+
|
|
952
|
+
it('should HTTP 404 when DID not found when trying to create', async () => {
|
|
953
|
+
const { orgDoc: orgDoc2, orgKey: orgKey2 } = await createOrgDoc();
|
|
954
|
+
nockRegistrarGetOrganizationDidDoc(orgDoc2.id, {});
|
|
955
|
+
|
|
956
|
+
const payload = {
|
|
957
|
+
did: orgDoc2.id,
|
|
958
|
+
serviceIds: [`${orgDoc2.id}#test-service`],
|
|
959
|
+
keys: [
|
|
960
|
+
{
|
|
961
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
962
|
+
algorithm: 'SECP256K1',
|
|
963
|
+
encoding: 'hex',
|
|
964
|
+
kidFragment: first(orgDoc2.assertionMethod),
|
|
965
|
+
key: orgKey2,
|
|
966
|
+
},
|
|
967
|
+
],
|
|
968
|
+
};
|
|
969
|
+
|
|
970
|
+
const response = await fastify.injectJson({
|
|
971
|
+
method: 'POST',
|
|
972
|
+
url: testUrl,
|
|
973
|
+
payload,
|
|
974
|
+
});
|
|
975
|
+
|
|
976
|
+
expect(response.statusCode).toEqual(404);
|
|
977
|
+
expect(response.json).toEqual(
|
|
978
|
+
errorResponseMatcher({
|
|
979
|
+
error: 'Not Found',
|
|
980
|
+
errorCode: 'did_not_found',
|
|
981
|
+
message: 'DID not found on the Velocity network registrar.',
|
|
982
|
+
statusCode: 404,
|
|
983
|
+
})
|
|
984
|
+
);
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
it('should HTTP 404 when registrar return 500', async () => {
|
|
988
|
+
const { orgDoc: orgDoc2, orgKey: orgKey2 } = await createOrgDoc();
|
|
989
|
+
nock('http://oracle.localhost.test')
|
|
990
|
+
.get(`/api/v0.6/resolve-did/${orgDoc2.id}`)
|
|
991
|
+
.reply(404, {});
|
|
992
|
+
const payload = {
|
|
993
|
+
did: orgDoc2.id,
|
|
994
|
+
serviceIds: [`${orgDoc2.id}#test-service`],
|
|
995
|
+
keys: [
|
|
996
|
+
{
|
|
997
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
998
|
+
algorithm: 'SECP256K1',
|
|
999
|
+
encoding: 'hex',
|
|
1000
|
+
kidFragment: '#key-0',
|
|
1001
|
+
key: orgKey2,
|
|
1002
|
+
},
|
|
1003
|
+
],
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
const response = await fastify.injectJson({
|
|
1007
|
+
method: 'POST',
|
|
1008
|
+
url: testUrl,
|
|
1009
|
+
payload,
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
expect(response.statusCode).toEqual(404);
|
|
1013
|
+
expect(response.json).toEqual(
|
|
1014
|
+
errorResponseMatcher({
|
|
1015
|
+
error: 'Not Found',
|
|
1016
|
+
errorCode: 'did_not_found',
|
|
1017
|
+
message: 'DID not found on the Velocity network registrar.',
|
|
1018
|
+
statusCode: 404,
|
|
1019
|
+
})
|
|
1020
|
+
);
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
it('should HTTP 409 and not create additional tenant', async () => {
|
|
1024
|
+
await persistTenant({
|
|
1025
|
+
did: orgDoc.id,
|
|
1026
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
const payload = {
|
|
1030
|
+
did: orgDoc.id,
|
|
1031
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
const response = await fastify.injectJson({
|
|
1035
|
+
method: 'POST',
|
|
1036
|
+
url: testUrl,
|
|
1037
|
+
payload,
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
expect(response.statusCode).toEqual(409);
|
|
1041
|
+
expect(response.json).toEqual({
|
|
1042
|
+
code: '11000',
|
|
1043
|
+
statusCode: 409,
|
|
1044
|
+
error: 'Conflict',
|
|
1045
|
+
message: expect.stringMatching(/duplicate key/gi),
|
|
1046
|
+
});
|
|
1047
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1048
|
+
.collection('tenants')
|
|
1049
|
+
.countDocuments();
|
|
1050
|
+
expect(tenantDocumentsCount).toEqual(1);
|
|
1051
|
+
});
|
|
1052
|
+
|
|
1053
|
+
it('should HTTP 400 and not create tenant or keys when no key purpose is provided', async () => {
|
|
1054
|
+
const payload = {
|
|
1055
|
+
did: orgDoc.id,
|
|
1056
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1057
|
+
keys: [
|
|
1058
|
+
{
|
|
1059
|
+
purposes: [],
|
|
1060
|
+
algorithm: 'SECP256K1',
|
|
1061
|
+
encoding: 'hex',
|
|
1062
|
+
kidFragment: '#key-0',
|
|
1063
|
+
key: orgKey,
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1067
|
+
algorithm: 'SECP256K1',
|
|
1068
|
+
encoding: 'hex',
|
|
1069
|
+
kidFragment: '#key-0',
|
|
1070
|
+
key: orgKey,
|
|
1071
|
+
},
|
|
1072
|
+
],
|
|
1073
|
+
};
|
|
1074
|
+
|
|
1075
|
+
const response = await fastify.injectJson({
|
|
1076
|
+
method: 'POST',
|
|
1077
|
+
url: testUrl,
|
|
1078
|
+
payload,
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
expect(response.statusCode).toEqual(400);
|
|
1082
|
+
expect(response.json).toEqual(
|
|
1083
|
+
errorResponseMatcher({
|
|
1084
|
+
error: 'Bad Request',
|
|
1085
|
+
errorCode: 'request_validation_failed',
|
|
1086
|
+
message: 'body/keys/0/purposes must NOT have fewer than 1 items',
|
|
1087
|
+
statusCode: 400,
|
|
1088
|
+
})
|
|
1089
|
+
);
|
|
1090
|
+
|
|
1091
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1092
|
+
.collection('tenants')
|
|
1093
|
+
.countDocuments();
|
|
1094
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1095
|
+
|
|
1096
|
+
const keyDocumentsCount = await mongoDb()
|
|
1097
|
+
.collection('keys')
|
|
1098
|
+
.countDocuments();
|
|
1099
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
it('should HTTP 400 and not create tenant or keys when a key purpose is not recognized', async () => {
|
|
1103
|
+
const payload = {
|
|
1104
|
+
did: orgDoc.id,
|
|
1105
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1106
|
+
keys: [
|
|
1107
|
+
{
|
|
1108
|
+
purposes: ['unrecognized-purpose'],
|
|
1109
|
+
algorithm: 'SECP256K1',
|
|
1110
|
+
encoding: 'hex',
|
|
1111
|
+
kidFragment: '#key-0',
|
|
1112
|
+
key: orgKey,
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1116
|
+
algorithm: 'SECP256K1',
|
|
1117
|
+
encoding: 'hex',
|
|
1118
|
+
kidFragment: '#key-1',
|
|
1119
|
+
key: orgKey,
|
|
1120
|
+
},
|
|
1121
|
+
],
|
|
1122
|
+
};
|
|
1123
|
+
|
|
1124
|
+
const response = await fastify.injectJson({
|
|
1125
|
+
method: 'POST',
|
|
1126
|
+
url: testUrl,
|
|
1127
|
+
payload,
|
|
1128
|
+
});
|
|
1129
|
+
|
|
1130
|
+
expect(response.statusCode).toEqual(400);
|
|
1131
|
+
expect(response.json).toEqual(
|
|
1132
|
+
errorResponseMatcher({
|
|
1133
|
+
error: 'Bad Request',
|
|
1134
|
+
errorCode: 'missing_error_code',
|
|
1135
|
+
message: 'Unrecognized purpose detected',
|
|
1136
|
+
statusCode: 400,
|
|
1137
|
+
})
|
|
1138
|
+
);
|
|
1139
|
+
|
|
1140
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1141
|
+
.collection('tenants')
|
|
1142
|
+
.countDocuments();
|
|
1143
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1144
|
+
|
|
1145
|
+
const keyDocumentsCount = await mongoDb()
|
|
1146
|
+
.collection('keys')
|
|
1147
|
+
.countDocuments();
|
|
1148
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
it('should HTTP 400 and not create tenant or keys when a key purpose is duplicated', async () => {
|
|
1152
|
+
const payload = {
|
|
1153
|
+
did: orgDoc.id,
|
|
1154
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1155
|
+
keys: [
|
|
1156
|
+
{
|
|
1157
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1158
|
+
algorithm: 'SECP256K1',
|
|
1159
|
+
encoding: 'hex',
|
|
1160
|
+
kidFragment: '#key-0',
|
|
1161
|
+
key: orgKey,
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1165
|
+
algorithm: 'SECP256K1',
|
|
1166
|
+
encoding: 'hex',
|
|
1167
|
+
kidFragment: '#key-1',
|
|
1168
|
+
key: orgKey,
|
|
1169
|
+
},
|
|
1170
|
+
],
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
const response = await fastify.injectJson({
|
|
1174
|
+
method: 'POST',
|
|
1175
|
+
url: testUrl,
|
|
1176
|
+
payload,
|
|
1177
|
+
});
|
|
1178
|
+
|
|
1179
|
+
expect(response.statusCode).toEqual(400);
|
|
1180
|
+
expect(response.json).toEqual(
|
|
1181
|
+
errorResponseMatcher({
|
|
1182
|
+
error: 'Bad Request',
|
|
1183
|
+
errorCode: 'missing_error_code',
|
|
1184
|
+
message: 'Duplicate key purposes detected',
|
|
1185
|
+
statusCode: 400,
|
|
1186
|
+
})
|
|
1187
|
+
);
|
|
1188
|
+
|
|
1189
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1190
|
+
.collection('tenants')
|
|
1191
|
+
.countDocuments();
|
|
1192
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1193
|
+
|
|
1194
|
+
const keyDocumentsCount = await mongoDb()
|
|
1195
|
+
.collection('keys')
|
|
1196
|
+
.countDocuments();
|
|
1197
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1198
|
+
});
|
|
1199
|
+
|
|
1200
|
+
it('should HTTP 400 and not create tenant or keys when a key algorithm is not recognized', async () => {
|
|
1201
|
+
const payload = {
|
|
1202
|
+
did: orgDoc.id,
|
|
1203
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1204
|
+
keys: [
|
|
1205
|
+
{
|
|
1206
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1207
|
+
algorithm: 'unrecognized-algorithm',
|
|
1208
|
+
encoding: 'hex',
|
|
1209
|
+
kidFragment: '#key-0',
|
|
1210
|
+
key: orgKey,
|
|
1211
|
+
},
|
|
1212
|
+
],
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
const response = await fastify.injectJson({
|
|
1216
|
+
method: 'POST',
|
|
1217
|
+
url: testUrl,
|
|
1218
|
+
payload,
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
expect(response.statusCode).toEqual(400);
|
|
1222
|
+
expect(response.json).toEqual(
|
|
1223
|
+
errorResponseMatcher({
|
|
1224
|
+
error: 'Bad Request',
|
|
1225
|
+
errorCode: 'missing_error_code',
|
|
1226
|
+
message: 'Unrecognized algorithm',
|
|
1227
|
+
statusCode: 400,
|
|
1228
|
+
})
|
|
1229
|
+
);
|
|
1230
|
+
|
|
1231
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1232
|
+
.collection('tenants')
|
|
1233
|
+
.countDocuments();
|
|
1234
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1235
|
+
|
|
1236
|
+
const keyDocumentsCount = await mongoDb()
|
|
1237
|
+
.collection('keys')
|
|
1238
|
+
.countDocuments();
|
|
1239
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1240
|
+
});
|
|
1241
|
+
|
|
1242
|
+
it('should HTTP 400 and not create tenant or keys when a key encoding is not recognized', async () => {
|
|
1243
|
+
const payload = {
|
|
1244
|
+
did: orgDoc.id,
|
|
1245
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1246
|
+
keys: [
|
|
1247
|
+
{
|
|
1248
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1249
|
+
algorithm: 'SECP256K1',
|
|
1250
|
+
encoding: 'unrecognized-encoding',
|
|
1251
|
+
kidFragment: '#key-0',
|
|
1252
|
+
key: orgKey,
|
|
1253
|
+
},
|
|
1254
|
+
],
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1257
|
+
const response = await fastify.injectJson({
|
|
1258
|
+
method: 'POST',
|
|
1259
|
+
url: testUrl,
|
|
1260
|
+
payload,
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
expect(response.statusCode).toEqual(400);
|
|
1264
|
+
expect(response.json).toEqual(
|
|
1265
|
+
errorResponseMatcher({
|
|
1266
|
+
error: 'Bad Request',
|
|
1267
|
+
errorCode: 'missing_error_code',
|
|
1268
|
+
message: 'Unrecognized encoding',
|
|
1269
|
+
statusCode: 400,
|
|
1270
|
+
})
|
|
1271
|
+
);
|
|
1272
|
+
|
|
1273
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1274
|
+
.collection('tenants')
|
|
1275
|
+
.countDocuments();
|
|
1276
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1277
|
+
|
|
1278
|
+
const keyDocumentsCount = await mongoDb()
|
|
1279
|
+
.collection('keys')
|
|
1280
|
+
.countDocuments();
|
|
1281
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1284
|
+
it('should HTTP 400 and not create tenant or keys when a kid fragment is duplicated', async () => {
|
|
1285
|
+
const payload = {
|
|
1286
|
+
did: orgDoc.id,
|
|
1287
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1288
|
+
keys: [
|
|
1289
|
+
{
|
|
1290
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1291
|
+
algorithm: 'SECP256K1',
|
|
1292
|
+
encoding: 'hex',
|
|
1293
|
+
kidFragment: '#key-0',
|
|
1294
|
+
key: orgKey,
|
|
1295
|
+
},
|
|
1296
|
+
{
|
|
1297
|
+
purposes: ['ISSUING_METADATA'],
|
|
1298
|
+
algorithm: 'SECP256K1',
|
|
1299
|
+
encoding: 'hex',
|
|
1300
|
+
kidFragment: '#key-0',
|
|
1301
|
+
key: orgKey,
|
|
1302
|
+
},
|
|
1303
|
+
],
|
|
1304
|
+
};
|
|
1305
|
+
|
|
1306
|
+
const response = await fastify.injectJson({
|
|
1307
|
+
method: 'POST',
|
|
1308
|
+
url: testUrl,
|
|
1309
|
+
payload,
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
expect(response.statusCode).toEqual(400);
|
|
1313
|
+
expect(response.json).toEqual(
|
|
1314
|
+
errorResponseMatcher({
|
|
1315
|
+
error: 'Bad Request',
|
|
1316
|
+
errorCode: 'missing_error_code',
|
|
1317
|
+
message: 'Duplicate kid fragments purposes detected',
|
|
1318
|
+
statusCode: 400,
|
|
1319
|
+
})
|
|
1320
|
+
);
|
|
1321
|
+
|
|
1322
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1323
|
+
.collection('tenants')
|
|
1324
|
+
.countDocuments();
|
|
1325
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1326
|
+
|
|
1327
|
+
const keyDocumentsCount = await mongoDb()
|
|
1328
|
+
.collection('keys')
|
|
1329
|
+
.countDocuments();
|
|
1330
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
it('should HTTP 400 and not create tenant or keys when a key service is not found on document', async () => {
|
|
1334
|
+
const serviceId = `${orgDoc.id}#not-a-service`;
|
|
1335
|
+
const payload = {
|
|
1336
|
+
did: orgDoc.id,
|
|
1337
|
+
serviceIds: [serviceId],
|
|
1338
|
+
keys: [
|
|
1339
|
+
{
|
|
1340
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1341
|
+
algorithm: 'SECP256K1',
|
|
1342
|
+
encoding: 'hex',
|
|
1343
|
+
kidFragment: '#key-0',
|
|
1344
|
+
key: orgKey,
|
|
1345
|
+
},
|
|
1346
|
+
],
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
const response = await fastify.injectJson({
|
|
1350
|
+
method: 'POST',
|
|
1351
|
+
url: testUrl,
|
|
1352
|
+
payload,
|
|
1353
|
+
});
|
|
1354
|
+
|
|
1355
|
+
expect(response.statusCode).toEqual(400);
|
|
1356
|
+
expect(response.json).toEqual(
|
|
1357
|
+
errorResponseMatcher({
|
|
1358
|
+
error: 'Bad Request',
|
|
1359
|
+
errorCode: 'missing_error_code',
|
|
1360
|
+
message: `ServiceId ${serviceId} is not on did document for did: ${orgDoc.id}`,
|
|
1361
|
+
statusCode: 400,
|
|
1362
|
+
})
|
|
1363
|
+
);
|
|
1364
|
+
|
|
1365
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1366
|
+
.collection('tenants')
|
|
1367
|
+
.countDocuments();
|
|
1368
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1369
|
+
|
|
1370
|
+
const keyDocumentsCount = await mongoDb()
|
|
1371
|
+
.collection('keys')
|
|
1372
|
+
.countDocuments();
|
|
1373
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1374
|
+
});
|
|
1375
|
+
|
|
1376
|
+
it('should HTTP 400 and not create tenant or keys when a private key does not match with public key on document', async () => {
|
|
1377
|
+
const payload = {
|
|
1378
|
+
did: orgDoc.id,
|
|
1379
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1380
|
+
keys: [
|
|
1381
|
+
{
|
|
1382
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1383
|
+
algorithm: 'SECP256K1',
|
|
1384
|
+
encoding: 'hex',
|
|
1385
|
+
kidFragment: '#key-0',
|
|
1386
|
+
key: 'non-matching-key',
|
|
1387
|
+
},
|
|
1388
|
+
],
|
|
1389
|
+
};
|
|
1390
|
+
|
|
1391
|
+
const response = await fastify.injectJson({
|
|
1392
|
+
method: 'POST',
|
|
1393
|
+
url: testUrl,
|
|
1394
|
+
payload,
|
|
1395
|
+
});
|
|
1396
|
+
|
|
1397
|
+
expect(response.statusCode).toEqual(400);
|
|
1398
|
+
expect(response.json).toEqual(
|
|
1399
|
+
errorResponseMatcher({
|
|
1400
|
+
error: 'Bad Request',
|
|
1401
|
+
errorCode: 'missing_error_code',
|
|
1402
|
+
message: 'Private key not matched to document',
|
|
1403
|
+
statusCode: 400,
|
|
1404
|
+
})
|
|
1405
|
+
);
|
|
1406
|
+
|
|
1407
|
+
const tenantDocumentsCount = await mongoDb()
|
|
1408
|
+
.collection('tenants')
|
|
1409
|
+
.countDocuments();
|
|
1410
|
+
expect(tenantDocumentsCount).toEqual(0);
|
|
1411
|
+
|
|
1412
|
+
const keyDocumentsCount = await mongoDb()
|
|
1413
|
+
.collection('keys')
|
|
1414
|
+
.countDocuments();
|
|
1415
|
+
expect(keyDocumentsCount).toEqual(0);
|
|
1416
|
+
});
|
|
1417
|
+
|
|
1418
|
+
it('should 400 if webhookUrl is not uri', async () => {
|
|
1419
|
+
const payload = {
|
|
1420
|
+
did: orgDoc.id,
|
|
1421
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1422
|
+
keys: [],
|
|
1423
|
+
webhookUrl: 'customUrl',
|
|
1424
|
+
};
|
|
1425
|
+
|
|
1426
|
+
const response = await fastify.injectJson({
|
|
1427
|
+
method: 'POST',
|
|
1428
|
+
url: testUrl,
|
|
1429
|
+
payload,
|
|
1430
|
+
});
|
|
1431
|
+
|
|
1432
|
+
expect(response.statusCode).toEqual(400);
|
|
1433
|
+
expect(response.json).toEqual(
|
|
1434
|
+
errorResponseMatcher({
|
|
1435
|
+
error: 'Bad Request',
|
|
1436
|
+
errorCode: 'request_validation_failed',
|
|
1437
|
+
message: 'body/webhookUrl must match format "uri"',
|
|
1438
|
+
statusCode: 400,
|
|
1439
|
+
})
|
|
1440
|
+
);
|
|
1441
|
+
});
|
|
1442
|
+
|
|
1443
|
+
it('should 400 if webhookAuth type is not a bearer', async () => {
|
|
1444
|
+
const payload = {
|
|
1445
|
+
did: orgDoc.id,
|
|
1446
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1447
|
+
keys: [],
|
|
1448
|
+
webhookAuth: {
|
|
1449
|
+
type: 'foo',
|
|
1450
|
+
bearerToken: 'secret',
|
|
1451
|
+
},
|
|
1452
|
+
};
|
|
1453
|
+
|
|
1454
|
+
const response = await fastify.injectJson({
|
|
1455
|
+
method: 'POST',
|
|
1456
|
+
url: testUrl,
|
|
1457
|
+
payload,
|
|
1458
|
+
});
|
|
1459
|
+
|
|
1460
|
+
expect(response.statusCode).toEqual(400);
|
|
1461
|
+
expect(response.json).toEqual(
|
|
1462
|
+
errorResponseMatcher({
|
|
1463
|
+
error: 'Bad Request',
|
|
1464
|
+
errorCode: 'request_validation_failed',
|
|
1465
|
+
message:
|
|
1466
|
+
'body/webhookAuth/type must be equal to one of the allowed values',
|
|
1467
|
+
statusCode: 400,
|
|
1468
|
+
})
|
|
1469
|
+
);
|
|
1470
|
+
});
|
|
1471
|
+
|
|
1472
|
+
it('should 400 if private key is not provided', async () => {
|
|
1473
|
+
const payload = {
|
|
1474
|
+
did: orgDoc.id,
|
|
1475
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1476
|
+
keys: [
|
|
1477
|
+
{
|
|
1478
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1479
|
+
algorithm: 'SECP256K1',
|
|
1480
|
+
encoding: 'hex',
|
|
1481
|
+
kidFragment: '#key-0',
|
|
1482
|
+
},
|
|
1483
|
+
],
|
|
1484
|
+
};
|
|
1485
|
+
|
|
1486
|
+
const response = await fastify.injectJson({
|
|
1487
|
+
method: 'POST',
|
|
1488
|
+
url: testUrl,
|
|
1489
|
+
payload,
|
|
1490
|
+
});
|
|
1491
|
+
|
|
1492
|
+
expect(response.statusCode).toEqual(400);
|
|
1493
|
+
expect(response.json).toEqual(
|
|
1494
|
+
errorResponseMatcher({
|
|
1495
|
+
error: 'Bad Request',
|
|
1496
|
+
errorCode: 'private_key_not_found',
|
|
1497
|
+
message: 'Private key not found',
|
|
1498
|
+
statusCode: 400,
|
|
1499
|
+
})
|
|
1500
|
+
);
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
it('should 201 and create a tenant and key', async () => {
|
|
1504
|
+
const payload = {
|
|
1505
|
+
did: orgDoc.id,
|
|
1506
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1507
|
+
keys: [
|
|
1508
|
+
{
|
|
1509
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1510
|
+
algorithm: 'SECP256K1',
|
|
1511
|
+
encoding: 'hex',
|
|
1512
|
+
kidFragment: '#key-0',
|
|
1513
|
+
key: hexFromJwk(orgKey, true),
|
|
1514
|
+
},
|
|
1515
|
+
],
|
|
1516
|
+
};
|
|
1517
|
+
|
|
1518
|
+
const response = await fastify.injectJson({
|
|
1519
|
+
method: 'POST',
|
|
1520
|
+
url: testUrl,
|
|
1521
|
+
payload,
|
|
1522
|
+
});
|
|
1523
|
+
|
|
1524
|
+
expect(response.statusCode).toEqual(201);
|
|
1525
|
+
expect(response.json).toEqual({
|
|
1526
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1527
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1528
|
+
});
|
|
1529
|
+
|
|
1530
|
+
const tenantFromDb = await mongoDb()
|
|
1531
|
+
.collection('tenants')
|
|
1532
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1533
|
+
expect(tenantFromDb).toEqual({
|
|
1534
|
+
_id: new ObjectId(response.json.id),
|
|
1535
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1536
|
+
did: orgDoc.id,
|
|
1537
|
+
dids: [orgDoc.id],
|
|
1538
|
+
primaryAddress,
|
|
1539
|
+
createdAt: expect.any(Date),
|
|
1540
|
+
updatedAt: expect.any(Date),
|
|
1541
|
+
});
|
|
1542
|
+
|
|
1543
|
+
expect(
|
|
1544
|
+
await findKmsKey({ tenantId: new ObjectId(response.json.id) })
|
|
1545
|
+
).toEqual({
|
|
1546
|
+
_id: expect.any(ObjectId),
|
|
1547
|
+
key: { use: 'sig', ...orgKey },
|
|
1548
|
+
kidFragment: '#key-0',
|
|
1549
|
+
});
|
|
1550
|
+
});
|
|
1551
|
+
|
|
1552
|
+
it('should 201 and create a tenant and key with jwk in the body', async () => {
|
|
1553
|
+
const payload = {
|
|
1554
|
+
did: orgDoc.id,
|
|
1555
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1556
|
+
keys: [
|
|
1557
|
+
{
|
|
1558
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1559
|
+
algorithm: 'SECP256K1',
|
|
1560
|
+
encoding: 'hex',
|
|
1561
|
+
kidFragment: '#key-0',
|
|
1562
|
+
jwk: orgKey,
|
|
1563
|
+
},
|
|
1564
|
+
],
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1567
|
+
const response = await fastify.injectJson({
|
|
1568
|
+
method: 'POST',
|
|
1569
|
+
url: testUrl,
|
|
1570
|
+
payload,
|
|
1571
|
+
});
|
|
1572
|
+
|
|
1573
|
+
expect(response.statusCode).toEqual(201);
|
|
1574
|
+
expect(response.json).toEqual({
|
|
1575
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1576
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1577
|
+
});
|
|
1578
|
+
|
|
1579
|
+
const tenantFromDb = await mongoDb()
|
|
1580
|
+
.collection('tenants')
|
|
1581
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1582
|
+
expect(tenantFromDb).toEqual({
|
|
1583
|
+
_id: new ObjectId(response.json.id),
|
|
1584
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1585
|
+
did: orgDoc.id,
|
|
1586
|
+
dids: [orgDoc.id],
|
|
1587
|
+
primaryAddress,
|
|
1588
|
+
createdAt: expect.any(Date),
|
|
1589
|
+
updatedAt: expect.any(Date),
|
|
1590
|
+
});
|
|
1591
|
+
|
|
1592
|
+
expect(
|
|
1593
|
+
await findKmsKey({ tenantId: new ObjectId(response.json.id) })
|
|
1594
|
+
).toEqual({
|
|
1595
|
+
_id: expect.any(ObjectId),
|
|
1596
|
+
key: orgKey,
|
|
1597
|
+
kidFragment: '#key-0',
|
|
1598
|
+
});
|
|
1599
|
+
});
|
|
1600
|
+
|
|
1601
|
+
it('should 201 and create a tenant and key with hexKey in the body', async () => {
|
|
1602
|
+
const payload = {
|
|
1603
|
+
did: orgDoc.id,
|
|
1604
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1605
|
+
keys: [
|
|
1606
|
+
{
|
|
1607
|
+
purposes: ['DLT_TRANSACTIONS'],
|
|
1608
|
+
algorithm: 'SECP256K1',
|
|
1609
|
+
encoding: 'hex',
|
|
1610
|
+
kidFragment: '#key-0',
|
|
1611
|
+
hexKey: hexFromJwk(orgKey, true),
|
|
1612
|
+
},
|
|
1613
|
+
],
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
const response = await fastify.injectJson({
|
|
1617
|
+
method: 'POST',
|
|
1618
|
+
url: testUrl,
|
|
1619
|
+
payload,
|
|
1620
|
+
});
|
|
1621
|
+
|
|
1622
|
+
expect(response.statusCode).toEqual(201);
|
|
1623
|
+
expect(response.json).toEqual({
|
|
1624
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1625
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1626
|
+
});
|
|
1627
|
+
|
|
1628
|
+
const tenantFromDb = await mongoDb()
|
|
1629
|
+
.collection('tenants')
|
|
1630
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1631
|
+
expect(tenantFromDb).toEqual({
|
|
1632
|
+
_id: new ObjectId(response.json.id),
|
|
1633
|
+
serviceIds: [`${orgDoc.id}#test-service`],
|
|
1634
|
+
did: orgDoc.id,
|
|
1635
|
+
dids: [orgDoc.id],
|
|
1636
|
+
primaryAddress,
|
|
1637
|
+
createdAt: expect.any(Date),
|
|
1638
|
+
updatedAt: expect.any(Date),
|
|
1639
|
+
});
|
|
1640
|
+
|
|
1641
|
+
expect(
|
|
1642
|
+
await findKmsKey({ tenantId: new ObjectId(response.json.id) })
|
|
1643
|
+
).toEqual({
|
|
1644
|
+
_id: expect.any(ObjectId),
|
|
1645
|
+
key: { use: 'sig', ...orgKey },
|
|
1646
|
+
kidFragment: '#key-0',
|
|
1647
|
+
});
|
|
1648
|
+
});
|
|
1649
|
+
});
|
|
1650
|
+
|
|
1651
|
+
describe('Tenant Did Refresh tests', () => {
|
|
1652
|
+
beforeEach(async () => {
|
|
1653
|
+
await mongoDb().collection('offers').deleteMany({});
|
|
1654
|
+
await mongoDb().collection('disclosures').deleteMany({});
|
|
1655
|
+
await mongoDb().collection('exchanges').deleteMany({});
|
|
1656
|
+
});
|
|
1657
|
+
it("should 400 when 'all' and 'did' props are missing from body", async () => {
|
|
1658
|
+
const payload = {
|
|
1659
|
+
foo: 'bar',
|
|
1660
|
+
};
|
|
1661
|
+
|
|
1662
|
+
const response = await fastify.injectJson({
|
|
1663
|
+
method: 'POST',
|
|
1664
|
+
url: `${testUrl}/refresh`,
|
|
1665
|
+
payload,
|
|
1666
|
+
});
|
|
1667
|
+
|
|
1668
|
+
expect(response.statusCode).toEqual(400);
|
|
1669
|
+
expect(response.json).toEqual(
|
|
1670
|
+
errorResponseMatcher({
|
|
1671
|
+
error: 'Bad Request',
|
|
1672
|
+
errorCode: 'request_validation_failed',
|
|
1673
|
+
message:
|
|
1674
|
+
"body must have required property 'all', body must have required property 'did', body must match exactly one schema in oneOf",
|
|
1675
|
+
statusCode: 400,
|
|
1676
|
+
})
|
|
1677
|
+
);
|
|
1678
|
+
});
|
|
1679
|
+
it("should 400 when both 'all' and 'did' props are present in body", async () => {
|
|
1680
|
+
const payload = {
|
|
1681
|
+
all: true,
|
|
1682
|
+
did: 'did:test:foo',
|
|
1683
|
+
};
|
|
1684
|
+
|
|
1685
|
+
const response = await fastify.injectJson({
|
|
1686
|
+
method: 'POST',
|
|
1687
|
+
url: `${testUrl}/refresh`,
|
|
1688
|
+
payload,
|
|
1689
|
+
});
|
|
1690
|
+
|
|
1691
|
+
expect(response.statusCode).toEqual(400);
|
|
1692
|
+
expect(response.json).toEqual(
|
|
1693
|
+
errorResponseMatcher({
|
|
1694
|
+
error: 'Bad Request',
|
|
1695
|
+
errorCode: 'request_validation_failed',
|
|
1696
|
+
message: 'body must match exactly one schema in oneOf',
|
|
1697
|
+
statusCode: 400,
|
|
1698
|
+
})
|
|
1699
|
+
);
|
|
1700
|
+
});
|
|
1701
|
+
it("should 400 if 'all' is false", async () => {
|
|
1702
|
+
const payload = {
|
|
1703
|
+
all: false,
|
|
1704
|
+
};
|
|
1705
|
+
|
|
1706
|
+
const response = await fastify.injectJson({
|
|
1707
|
+
method: 'POST',
|
|
1708
|
+
url: `${testUrl}/refresh`,
|
|
1709
|
+
payload,
|
|
1710
|
+
});
|
|
1711
|
+
|
|
1712
|
+
expect(response.statusCode).toEqual(400);
|
|
1713
|
+
expect(response.json).toEqual(
|
|
1714
|
+
errorResponseMatcher({
|
|
1715
|
+
error: 'Bad Request',
|
|
1716
|
+
errorCode: 'request_validation_failed',
|
|
1717
|
+
message:
|
|
1718
|
+
// eslint-disable-next-line max-len
|
|
1719
|
+
"body/all must be equal to one of the allowed values, body must have required property 'did', body must match exactly one schema in oneOf",
|
|
1720
|
+
statusCode: 400,
|
|
1721
|
+
})
|
|
1722
|
+
);
|
|
1723
|
+
});
|
|
1724
|
+
it("should 400 if 'all' is true and no tenants", async () => {
|
|
1725
|
+
const payload = {
|
|
1726
|
+
all: true,
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
const response = await fastify.injectJson({
|
|
1730
|
+
method: 'POST',
|
|
1731
|
+
url: `${testUrl}/refresh`,
|
|
1732
|
+
payload,
|
|
1733
|
+
});
|
|
1734
|
+
|
|
1735
|
+
expect(response.statusCode).toEqual(400);
|
|
1736
|
+
expect(response.json).toEqual(
|
|
1737
|
+
errorResponseMatcher({
|
|
1738
|
+
error: 'Bad Request',
|
|
1739
|
+
errorCode: 'missing_error_code',
|
|
1740
|
+
message:
|
|
1741
|
+
// eslint-disable-next-line max-len
|
|
1742
|
+
'No tenants to refresh',
|
|
1743
|
+
statusCode: 400,
|
|
1744
|
+
})
|
|
1745
|
+
);
|
|
1746
|
+
});
|
|
1747
|
+
it("should 400 if 'did' is provided and no tenants", async () => {
|
|
1748
|
+
const payload = {
|
|
1749
|
+
did: 'did:test:foo',
|
|
1750
|
+
};
|
|
1751
|
+
|
|
1752
|
+
const response = await fastify.injectJson({
|
|
1753
|
+
method: 'POST',
|
|
1754
|
+
url: `${testUrl}/refresh`,
|
|
1755
|
+
payload,
|
|
1756
|
+
});
|
|
1757
|
+
|
|
1758
|
+
expect(response.statusCode).toEqual(400);
|
|
1759
|
+
expect(response.json).toEqual(
|
|
1760
|
+
errorResponseMatcher({
|
|
1761
|
+
error: 'Bad Request',
|
|
1762
|
+
errorCode: 'missing_error_code',
|
|
1763
|
+
message:
|
|
1764
|
+
// eslint-disable-next-line max-len
|
|
1765
|
+
'No tenants to refresh',
|
|
1766
|
+
statusCode: 400,
|
|
1767
|
+
})
|
|
1768
|
+
);
|
|
1769
|
+
});
|
|
1770
|
+
it("should 200 if 'all' is true and not update anything if no preferred dids are found", async () => {
|
|
1771
|
+
const oldDid1 = 'did:test:foo1';
|
|
1772
|
+
const newDid1 = 'did:notweb:foo1';
|
|
1773
|
+
const tenant1 = await persistTenant({ did: oldDid1 });
|
|
1774
|
+
const disclosure1 = await persistDisclosure({ tenant: tenant1 });
|
|
1775
|
+
const user1 = await persistVendorUserIdMapping({ tenant: tenant1 });
|
|
1776
|
+
const exchange1 = await persistOfferExchange({
|
|
1777
|
+
tenant: tenant1,
|
|
1778
|
+
disclosure: disclosure1,
|
|
1779
|
+
});
|
|
1780
|
+
const offer1 = await persistOffer({
|
|
1781
|
+
tenant: tenant1,
|
|
1782
|
+
exchange: exchange1,
|
|
1783
|
+
user: user1,
|
|
1784
|
+
});
|
|
1785
|
+
nockRegistrarGetOrganizationDidDoc(oldDid1, {
|
|
1786
|
+
id: oldDid1,
|
|
1787
|
+
alsoKnownAs: [newDid1],
|
|
1788
|
+
});
|
|
1789
|
+
|
|
1790
|
+
const payload = {
|
|
1791
|
+
all: true,
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
const response = await fastify.injectJson({
|
|
1795
|
+
method: 'POST',
|
|
1796
|
+
url: `${testUrl}/refresh`,
|
|
1797
|
+
payload,
|
|
1798
|
+
});
|
|
1799
|
+
|
|
1800
|
+
expect(response.statusCode).toEqual(200);
|
|
1801
|
+
expect(response.json).toEqual({});
|
|
1802
|
+
const tenant1FromDb = await mongoDb()
|
|
1803
|
+
.collection('tenants')
|
|
1804
|
+
.findOne(
|
|
1805
|
+
{ _id: new ObjectId(tenant1._id) },
|
|
1806
|
+
{ projection: { did: 1, aliases: 1 } }
|
|
1807
|
+
);
|
|
1808
|
+
expect(tenant1FromDb).toEqual({
|
|
1809
|
+
_id: new ObjectId(tenant1._id),
|
|
1810
|
+
did: oldDid1,
|
|
1811
|
+
});
|
|
1812
|
+
const offer1FromDb = await mongoDb()
|
|
1813
|
+
.collection('offers')
|
|
1814
|
+
.findOne(
|
|
1815
|
+
{ _id: new ObjectId(offer1._id) },
|
|
1816
|
+
{ projection: { 'issuer.id': 1 } }
|
|
1817
|
+
);
|
|
1818
|
+
expect(offer1FromDb).toEqual({
|
|
1819
|
+
_id: new ObjectId(offer1._id),
|
|
1820
|
+
issuer: {
|
|
1821
|
+
id: oldDid1,
|
|
1822
|
+
},
|
|
1823
|
+
});
|
|
1824
|
+
});
|
|
1825
|
+
it("should 200 if 'all' is true and update existing tenants with preferred dids, serviceIds and their offers", async () => {
|
|
1826
|
+
const oldDid1 = 'did:test:foo1';
|
|
1827
|
+
const oldDid2 = 'did:test:foo2';
|
|
1828
|
+
const oldDid3 = 'did:test:foo3';
|
|
1829
|
+
const newDid1 = 'did:web:foo1';
|
|
1830
|
+
const newDid2 = 'did:web:foo2';
|
|
1831
|
+
const newDid3 = 'did:notweb:foo3';
|
|
1832
|
+
const tenant1 = await persistTenant({
|
|
1833
|
+
did: oldDid1,
|
|
1834
|
+
serviceIds: [`${oldDid1}#foo`],
|
|
1835
|
+
});
|
|
1836
|
+
const tenant2 = await persistTenant({ did: oldDid2 });
|
|
1837
|
+
const tenant3 = await persistTenant({ did: oldDid3 });
|
|
1838
|
+
const disclosure1 = await persistDisclosure({ tenant: tenant1 });
|
|
1839
|
+
const disclosure2 = await persistDisclosure({ tenant: tenant2 });
|
|
1840
|
+
const user1 = await persistVendorUserIdMapping({ tenant: tenant1 });
|
|
1841
|
+
const user2 = await persistVendorUserIdMapping({ tenant: tenant2 });
|
|
1842
|
+
const exchange1 = await persistOfferExchange({
|
|
1843
|
+
tenant: tenant1,
|
|
1844
|
+
disclosure: disclosure1,
|
|
1845
|
+
});
|
|
1846
|
+
const exchange2 = await persistOfferExchange({
|
|
1847
|
+
tenant: tenant2,
|
|
1848
|
+
disclosure: disclosure2,
|
|
1849
|
+
});
|
|
1850
|
+
const offer1 = await persistOffer({
|
|
1851
|
+
tenant: tenant1,
|
|
1852
|
+
exchange: exchange1,
|
|
1853
|
+
user: user1,
|
|
1854
|
+
});
|
|
1855
|
+
const offer2 = await persistOffer({
|
|
1856
|
+
tenant: tenant2,
|
|
1857
|
+
exchange: exchange2,
|
|
1858
|
+
user: user2,
|
|
1859
|
+
credentialSubject: {
|
|
1860
|
+
foo: oldDid2,
|
|
1861
|
+
},
|
|
1862
|
+
});
|
|
1863
|
+
nockRegistrarGetOrganizationDidDoc(oldDid1, {
|
|
1864
|
+
id: oldDid1,
|
|
1865
|
+
alsoKnownAs: [newDid1],
|
|
1866
|
+
});
|
|
1867
|
+
nockRegistrarGetOrganizationDidDoc(oldDid2, {
|
|
1868
|
+
id: oldDid2,
|
|
1869
|
+
alsoKnownAs: [newDid2],
|
|
1870
|
+
});
|
|
1871
|
+
nockRegistrarGetOrganizationDidDoc(oldDid3, {
|
|
1872
|
+
id: oldDid3,
|
|
1873
|
+
alsoKnownAs: [newDid3],
|
|
1874
|
+
});
|
|
1875
|
+
|
|
1876
|
+
const payload = {
|
|
1877
|
+
all: true,
|
|
1878
|
+
};
|
|
1879
|
+
|
|
1880
|
+
const response = await fastify.injectJson({
|
|
1881
|
+
method: 'POST',
|
|
1882
|
+
url: `${testUrl}/refresh`,
|
|
1883
|
+
payload,
|
|
1884
|
+
});
|
|
1885
|
+
|
|
1886
|
+
expect(response.statusCode).toEqual(200);
|
|
1887
|
+
expect(response.json).toEqual({});
|
|
1888
|
+
const tenant1FromDb = await mongoDb()
|
|
1889
|
+
.collection('tenants')
|
|
1890
|
+
.findOne(
|
|
1891
|
+
{ _id: new ObjectId(tenant1._id) },
|
|
1892
|
+
{ projection: { did: 1, dids: 1, serviceIds: 1 } }
|
|
1893
|
+
);
|
|
1894
|
+
expect(tenant1FromDb).toEqual({
|
|
1895
|
+
_id: new ObjectId(tenant1._id),
|
|
1896
|
+
did: newDid1,
|
|
1897
|
+
dids: [oldDid1, newDid1],
|
|
1898
|
+
serviceIds: [`${newDid1}#foo`],
|
|
1899
|
+
});
|
|
1900
|
+
const tenant2FromDb = await mongoDb()
|
|
1901
|
+
.collection('tenants')
|
|
1902
|
+
.findOne(
|
|
1903
|
+
{ _id: new ObjectId(tenant2._id) },
|
|
1904
|
+
{ projection: { did: 1, dids: 1 } }
|
|
1905
|
+
);
|
|
1906
|
+
expect(tenant2FromDb).toEqual({
|
|
1907
|
+
_id: new ObjectId(tenant2._id),
|
|
1908
|
+
did: newDid2,
|
|
1909
|
+
dids: [oldDid2, newDid2],
|
|
1910
|
+
});
|
|
1911
|
+
const tenant3FromDb = await mongoDb()
|
|
1912
|
+
.collection('tenants')
|
|
1913
|
+
.findOne(
|
|
1914
|
+
{ _id: new ObjectId(tenant3._id) },
|
|
1915
|
+
{ projection: { did: 1, aliases: 1 } }
|
|
1916
|
+
);
|
|
1917
|
+
expect(tenant3FromDb).toEqual({
|
|
1918
|
+
_id: new ObjectId(tenant3._id),
|
|
1919
|
+
did: oldDid3,
|
|
1920
|
+
});
|
|
1921
|
+
const offer1FromDb = await mongoDb()
|
|
1922
|
+
.collection('offers')
|
|
1923
|
+
.findOne(
|
|
1924
|
+
{ _id: new ObjectId(offer1._id) },
|
|
1925
|
+
{ projection: { 'issuer.id': 1 } }
|
|
1926
|
+
);
|
|
1927
|
+
expect(offer1FromDb).toEqual({
|
|
1928
|
+
_id: new ObjectId(offer1._id),
|
|
1929
|
+
issuer: {
|
|
1930
|
+
id: newDid1,
|
|
1931
|
+
},
|
|
1932
|
+
});
|
|
1933
|
+
const offer2FromDb = await mongoDb()
|
|
1934
|
+
.collection('offers')
|
|
1935
|
+
.findOne(
|
|
1936
|
+
{ _id: new ObjectId(offer2._id) },
|
|
1937
|
+
{ projection: { 'issuer.id': 1, 'credentialSubject.foo': 1 } }
|
|
1938
|
+
);
|
|
1939
|
+
expect(offer2FromDb).toEqual({
|
|
1940
|
+
_id: new ObjectId(offer2._id),
|
|
1941
|
+
issuer: {
|
|
1942
|
+
id: newDid2,
|
|
1943
|
+
},
|
|
1944
|
+
credentialSubject: { foo: newDid2 },
|
|
1945
|
+
});
|
|
1946
|
+
});
|
|
1947
|
+
it("should 200 if 'did' is passed and update a specific tenant and it's offers", async () => {
|
|
1948
|
+
const oldDid1 = 'did:test:foo1';
|
|
1949
|
+
const oldDid2 = 'did:test:foo2';
|
|
1950
|
+
const newDid1 = 'did:web:foo1';
|
|
1951
|
+
const tenant1 = await persistTenant({
|
|
1952
|
+
did: oldDid1,
|
|
1953
|
+
serviceIds: [`${oldDid1}#foo`],
|
|
1954
|
+
});
|
|
1955
|
+
const tenant2 = await persistTenant({
|
|
1956
|
+
did: oldDid2,
|
|
1957
|
+
serviceIds: [`${oldDid2}#foo`],
|
|
1958
|
+
});
|
|
1959
|
+
const disclosure1 = await persistDisclosure({ tenant: tenant1 });
|
|
1960
|
+
const disclosure2 = await persistDisclosure({ tenant: tenant2 });
|
|
1961
|
+
const user1 = await persistVendorUserIdMapping({ tenant: tenant1 });
|
|
1962
|
+
const user2 = await persistVendorUserIdMapping({ tenant: tenant2 });
|
|
1963
|
+
const exchange1 = await persistOfferExchange({
|
|
1964
|
+
tenant: tenant1,
|
|
1965
|
+
disclosure: disclosure1,
|
|
1966
|
+
});
|
|
1967
|
+
const exchange2 = await persistOfferExchange({
|
|
1968
|
+
tenant: tenant2,
|
|
1969
|
+
disclosure: disclosure2,
|
|
1970
|
+
});
|
|
1971
|
+
const offer1 = await persistOffer({
|
|
1972
|
+
tenant: tenant1,
|
|
1973
|
+
exchange: exchange1,
|
|
1974
|
+
user: user1,
|
|
1975
|
+
});
|
|
1976
|
+
const offer2 = await persistOffer({
|
|
1977
|
+
tenant: tenant2,
|
|
1978
|
+
exchange: exchange2,
|
|
1979
|
+
user: user2,
|
|
1980
|
+
});
|
|
1981
|
+
nockRegistrarGetOrganizationDidDoc(tenant1.did, {
|
|
1982
|
+
id: oldDid1,
|
|
1983
|
+
alsoKnownAs: [newDid1],
|
|
1984
|
+
});
|
|
1985
|
+
|
|
1986
|
+
const payload = {
|
|
1987
|
+
did: tenant1.did,
|
|
1988
|
+
};
|
|
1989
|
+
|
|
1990
|
+
const response = await fastify.injectJson({
|
|
1991
|
+
method: 'POST',
|
|
1992
|
+
url: `${testUrl}/refresh`,
|
|
1993
|
+
payload,
|
|
1994
|
+
});
|
|
1995
|
+
|
|
1996
|
+
expect(response.statusCode).toEqual(200);
|
|
1997
|
+
expect(response.json).toEqual({});
|
|
1998
|
+
const tenant1FromDb = await mongoDb()
|
|
1999
|
+
.collection('tenants')
|
|
2000
|
+
.findOne(
|
|
2001
|
+
{ _id: new ObjectId(tenant1._id) },
|
|
2002
|
+
{ projection: { did: 1, dids: 1, serviceIds: 1 } }
|
|
2003
|
+
);
|
|
2004
|
+
expect(tenant1FromDb).toEqual({
|
|
2005
|
+
_id: new ObjectId(tenant1._id),
|
|
2006
|
+
did: newDid1,
|
|
2007
|
+
dids: [oldDid1, newDid1],
|
|
2008
|
+
serviceIds: [`${newDid1}#foo`],
|
|
2009
|
+
});
|
|
2010
|
+
const tenant2FromDb = await mongoDb()
|
|
2011
|
+
.collection('tenants')
|
|
2012
|
+
.findOne(
|
|
2013
|
+
{ _id: new ObjectId(tenant2._id) },
|
|
2014
|
+
{ projection: { did: 1, dids: 1, serviceIds: 1 } }
|
|
2015
|
+
);
|
|
2016
|
+
expect(tenant2FromDb).toEqual({
|
|
2017
|
+
_id: new ObjectId(tenant2._id),
|
|
2018
|
+
did: oldDid2,
|
|
2019
|
+
serviceIds: [`${oldDid2}#foo`],
|
|
2020
|
+
});
|
|
2021
|
+
const offer1FromDb = await mongoDb()
|
|
2022
|
+
.collection('offers')
|
|
2023
|
+
.findOne(
|
|
2024
|
+
{ _id: new ObjectId(offer1._id) },
|
|
2025
|
+
{ projection: { 'issuer.id': 1 } }
|
|
2026
|
+
);
|
|
2027
|
+
expect(offer1FromDb).toEqual({
|
|
2028
|
+
_id: new ObjectId(offer1._id),
|
|
2029
|
+
issuer: {
|
|
2030
|
+
id: newDid1,
|
|
2031
|
+
},
|
|
2032
|
+
});
|
|
2033
|
+
const offer2FromDb = await mongoDb()
|
|
2034
|
+
.collection('offers')
|
|
2035
|
+
.findOne(
|
|
2036
|
+
{ _id: new ObjectId(offer2._id) },
|
|
2037
|
+
{ projection: { 'issuer.id': 1 } }
|
|
2038
|
+
);
|
|
2039
|
+
expect(offer2FromDb).toEqual({
|
|
2040
|
+
_id: new ObjectId(offer2._id),
|
|
2041
|
+
issuer: {
|
|
2042
|
+
id: oldDid2,
|
|
2043
|
+
},
|
|
2044
|
+
});
|
|
2045
|
+
});
|
|
2046
|
+
});
|
|
2047
|
+
});
|
|
2048
|
+
describe.skip('Private key to ethereum account test suite', () => {
|
|
2049
|
+
it('brute force eth account conversion with original jwk', () => {
|
|
2050
|
+
// This test is to showcase what is happening in
|
|
2051
|
+
// https://velocitycareerlabs.atlassian.net/browse/VL-4120
|
|
2052
|
+
// It will fail and should be skipped,
|
|
2053
|
+
// but running it should recreate the error observed on mainnet
|
|
2054
|
+
|
|
2055
|
+
// eslint-disable-next-line no-plusplus
|
|
2056
|
+
for (let i = 0; i < 300; i++) {
|
|
2057
|
+
const keyPairJwkInternal = generateKeyPair({ format: 'jwk' });
|
|
2058
|
+
const privateJwkInternalToHex = hexFromJwk(
|
|
2059
|
+
keyPairJwkInternal.privateKey,
|
|
2060
|
+
true
|
|
2061
|
+
);
|
|
2062
|
+
const publicFromPrivateHex = publicKeyFromPrivateKey(
|
|
2063
|
+
privateJwkInternalToHex
|
|
2064
|
+
);
|
|
2065
|
+
const ethAccountFromPrivate = toEthereumAddress(privateJwkInternalToHex);
|
|
2066
|
+
|
|
2067
|
+
// eslint-disable-next-line no-console
|
|
2068
|
+
console.log(`Will we finish iteration ${i}?: --------------`);
|
|
2069
|
+
const ethAccountFromPublic = toEthereumAddress(publicFromPrivateHex);
|
|
2070
|
+
expect(ethAccountFromPrivate).toEqual(ethAccountFromPublic);
|
|
2071
|
+
}
|
|
2072
|
+
});
|
|
2073
|
+
it('brute force eth account conversion with original hex', () => {
|
|
2074
|
+
// This test is different from the previous test in that it uses the
|
|
2075
|
+
// hexes coming directly out of generateKeyPair
|
|
2076
|
+
// results seem the same, possibly slightly more common
|
|
2077
|
+
|
|
2078
|
+
// eslint-disable-next-line no-plusplus
|
|
2079
|
+
for (let i = 0; i < 300; i++) {
|
|
2080
|
+
const keyPairHexInternal = generateKeyPair({ format: 'hex' });
|
|
2081
|
+
const privateJwkInternalToHex = keyPairHexInternal.privateKey;
|
|
2082
|
+
const publicFromPrivateHex = publicKeyFromPrivateKey(
|
|
2083
|
+
privateJwkInternalToHex
|
|
2084
|
+
);
|
|
2085
|
+
const ethAccountFromPrivate = toEthereumAddress(privateJwkInternalToHex);
|
|
2086
|
+
|
|
2087
|
+
// eslint-disable-next-line no-console
|
|
2088
|
+
console.log(`Will we finish iteration ${i}?: --------------`);
|
|
2089
|
+
const ethAccountFromPublic = toEthereumAddress(publicFromPrivateHex);
|
|
2090
|
+
expect(ethAccountFromPrivate).toEqual(ethAccountFromPublic);
|
|
2091
|
+
}
|
|
2092
|
+
});
|
|
2093
|
+
});
|