@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,4157 @@
|
|
|
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 buildFastify = require('./helpers/credentialagent-operator-build-fastify');
|
|
19
|
+
|
|
20
|
+
const { mongoDb } = require('@spencejs/spence-mongo-repos');
|
|
21
|
+
const nock = require('nock');
|
|
22
|
+
const { ObjectId } = require('mongodb');
|
|
23
|
+
const _ = require('lodash/fp');
|
|
24
|
+
const {
|
|
25
|
+
ISO_DATETIME_FORMAT,
|
|
26
|
+
OBJECT_ID_FORMAT,
|
|
27
|
+
} = require('@verii/test-regexes');
|
|
28
|
+
const {
|
|
29
|
+
errorResponseMatcher,
|
|
30
|
+
mongoify,
|
|
31
|
+
testAuthToken,
|
|
32
|
+
} = require('@verii/tests-helpers');
|
|
33
|
+
const { samplePresentationDefinition } = require('@verii/sample-data');
|
|
34
|
+
const {
|
|
35
|
+
initDisclosureFactory,
|
|
36
|
+
initFeedFactory,
|
|
37
|
+
initTenantFactory,
|
|
38
|
+
tenantRepoPlugin,
|
|
39
|
+
VendorEndpoint,
|
|
40
|
+
ConfigurationType,
|
|
41
|
+
} = require('../../src/entities');
|
|
42
|
+
|
|
43
|
+
const disclosureUrlPrefix = '/operator-api/v0.8/tenants/';
|
|
44
|
+
|
|
45
|
+
const disclosureUrl = (tenant) =>
|
|
46
|
+
`${disclosureUrlPrefix}${tenant._id}/disclosures`;
|
|
47
|
+
|
|
48
|
+
const nockVerifiedProfile = (did, response = {}) =>
|
|
49
|
+
nock('http://oracle.localhost.test')
|
|
50
|
+
.get(`/api/v0.6/organizations/${encodeURIComponent(did)}/verified-profile`)
|
|
51
|
+
.reply(200, response);
|
|
52
|
+
|
|
53
|
+
describe('disclosures management', () => {
|
|
54
|
+
const commercialEntityName = 'Example Inc.';
|
|
55
|
+
const commercialEntityLogo = 'https://www.example.com/logo.png';
|
|
56
|
+
|
|
57
|
+
let fastify;
|
|
58
|
+
let persistFeed;
|
|
59
|
+
let persistDisclosure;
|
|
60
|
+
let newDisclosure;
|
|
61
|
+
let persistTenant;
|
|
62
|
+
let tenant;
|
|
63
|
+
let altTenant;
|
|
64
|
+
let disclosures;
|
|
65
|
+
let tenantRepo;
|
|
66
|
+
let nockVP;
|
|
67
|
+
let nockAltVP;
|
|
68
|
+
|
|
69
|
+
beforeAll(async () => {
|
|
70
|
+
fastify = buildFastify();
|
|
71
|
+
await fastify.ready();
|
|
72
|
+
({ persistFeed } = initFeedFactory(fastify));
|
|
73
|
+
({ persistDisclosure, newDisclosure } = initDisclosureFactory(fastify));
|
|
74
|
+
({ persistTenant } = initTenantFactory(fastify));
|
|
75
|
+
|
|
76
|
+
tenantRepo = tenantRepoPlugin(fastify)();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
beforeEach(async () => {
|
|
80
|
+
fastify.resetOverrides();
|
|
81
|
+
nock.cleanAll();
|
|
82
|
+
await mongoDb().collection('disclosures').deleteMany({});
|
|
83
|
+
await mongoDb().collection('tenants').deleteMany({});
|
|
84
|
+
await mongoDb().collection('feeds').deleteMany({});
|
|
85
|
+
|
|
86
|
+
tenant = await persistTenant();
|
|
87
|
+
altTenant = await persistTenant();
|
|
88
|
+
disclosures = {
|
|
89
|
+
a: await persistDisclosure({ description: 'getManyTest1', tenant }),
|
|
90
|
+
b: await persistDisclosure({ description: 'getManyTest2', tenant }),
|
|
91
|
+
c: await persistDisclosure({
|
|
92
|
+
description: 'getManyTest3',
|
|
93
|
+
tenant: altTenant,
|
|
94
|
+
}),
|
|
95
|
+
d: await persistDisclosure({
|
|
96
|
+
description: 'withoffermode',
|
|
97
|
+
tenant,
|
|
98
|
+
offerMode: 'preloaded',
|
|
99
|
+
}),
|
|
100
|
+
e: await persistDisclosure({
|
|
101
|
+
description: 'withbadoffermode',
|
|
102
|
+
tenant,
|
|
103
|
+
offerMode: 'hello',
|
|
104
|
+
}),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
nockVP = nockVerifiedProfile(tenant.did, {
|
|
108
|
+
credentialSubject: {
|
|
109
|
+
commercialEntities: [
|
|
110
|
+
{
|
|
111
|
+
name: commercialEntityName,
|
|
112
|
+
logo: commercialEntityLogo,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
nockAltVP = nockVerifiedProfile(altTenant.did, {
|
|
118
|
+
credentialSubject: {
|
|
119
|
+
commercialEntities: [],
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
afterAll(async () => {
|
|
125
|
+
await fastify.close();
|
|
126
|
+
nock.cleanAll();
|
|
127
|
+
nock.restore();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('Create Disclosure', () => {
|
|
131
|
+
describe('Create Disclosure - Common Missing Required Properties', () => {
|
|
132
|
+
it('should 404 if organizationDID is blank', async () => {
|
|
133
|
+
const payload = await newDisclosure({ tenant });
|
|
134
|
+
|
|
135
|
+
const response = await fastify.injectJson({
|
|
136
|
+
method: 'POST',
|
|
137
|
+
url: `${disclosureUrl({ _id: '' })}`,
|
|
138
|
+
payload,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
expect(response.statusCode).toEqual(404);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should 401 and not create the disclosure with wrong token', async () => {
|
|
145
|
+
const payload = _.omit(['tenantId'], await newDisclosure({ tenant }));
|
|
146
|
+
|
|
147
|
+
const response = await fastify.injectJson({
|
|
148
|
+
method: 'POST',
|
|
149
|
+
url: `${disclosureUrl(tenant)}`,
|
|
150
|
+
payload,
|
|
151
|
+
headers: {
|
|
152
|
+
'x-override-auth-unauthorized': true,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(response.statusCode).toEqual(401);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should 400 and fail to create an integrated identity disclosure with unexpected rule', async () => {
|
|
160
|
+
const payload = _.omit(
|
|
161
|
+
['tenantId'],
|
|
162
|
+
await newDisclosure({
|
|
163
|
+
tenant,
|
|
164
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
165
|
+
types: [{ type: 'EmailV1.0' }],
|
|
166
|
+
identityMatchers: {
|
|
167
|
+
rules: [
|
|
168
|
+
{
|
|
169
|
+
valueIndex: 0, // used for identifying the value
|
|
170
|
+
path: ['$.emails'], // jsonPath within the credential
|
|
171
|
+
rule: 'nonRule', // Rule to execute can be pick, all (if the target is an array), equal (if the target is a singleValue)
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
vendorUserIdIndex: 0,
|
|
175
|
+
values: [
|
|
176
|
+
['adam.smith@example.com'],
|
|
177
|
+
['carmen.jones@example.com'],
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
);
|
|
182
|
+
const response = await fastify.injectJson({
|
|
183
|
+
method: 'POST',
|
|
184
|
+
url: `${disclosureUrl(tenant)}`,
|
|
185
|
+
payload,
|
|
186
|
+
headers: {
|
|
187
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
expect(response.statusCode).toEqual(400);
|
|
192
|
+
expect(response.json).toEqual(
|
|
193
|
+
errorResponseMatcher({
|
|
194
|
+
error: 'Bad Request',
|
|
195
|
+
statusCode: 400,
|
|
196
|
+
errorCode: 'request_validation_failed',
|
|
197
|
+
message:
|
|
198
|
+
'body/identityMatchers/rules/0/rule must be equal to one of the allowed values',
|
|
199
|
+
})
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('should 400 when disclosure configuration type required', async () => {
|
|
204
|
+
const payload = _.omit(
|
|
205
|
+
['tenantId', 'configurationType'],
|
|
206
|
+
await newDisclosure({
|
|
207
|
+
tenant,
|
|
208
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
209
|
+
offerMode: 'preloaded',
|
|
210
|
+
})
|
|
211
|
+
);
|
|
212
|
+
const response = await fastify.injectJson({
|
|
213
|
+
method: 'POST',
|
|
214
|
+
url: `${disclosureUrl(tenant)}`,
|
|
215
|
+
payload: {
|
|
216
|
+
...payload,
|
|
217
|
+
setIssuingDefault: false,
|
|
218
|
+
},
|
|
219
|
+
headers: {
|
|
220
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
expect(response.statusCode).toEqual(400);
|
|
225
|
+
expect(response.json).toEqual(
|
|
226
|
+
errorResponseMatcher({
|
|
227
|
+
error: 'Bad Request',
|
|
228
|
+
errorCode: 'disclosure_configuration_type_required',
|
|
229
|
+
message: 'Disclosure configuration type required',
|
|
230
|
+
statusCode: 400,
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should 400 when vendor webhook is not exists', async () => {
|
|
236
|
+
fastify.overrides.reqConfig = (config) => ({
|
|
237
|
+
...config,
|
|
238
|
+
vendorUrl: '',
|
|
239
|
+
});
|
|
240
|
+
const customTenant = await persistTenant({
|
|
241
|
+
webhookUrl: '',
|
|
242
|
+
});
|
|
243
|
+
nockVerifiedProfile(customTenant.did);
|
|
244
|
+
const payload = _.omit(
|
|
245
|
+
['tenantId'],
|
|
246
|
+
await newDisclosure({ customTenant })
|
|
247
|
+
);
|
|
248
|
+
const response = await fastify.injectJson({
|
|
249
|
+
method: 'POST',
|
|
250
|
+
url: `${disclosureUrl(tenant)}`,
|
|
251
|
+
payload,
|
|
252
|
+
headers: {
|
|
253
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
expect(response.statusCode).toEqual(400);
|
|
258
|
+
expect(response.json).toEqual(
|
|
259
|
+
errorResponseMatcher({
|
|
260
|
+
error: 'Bad Request',
|
|
261
|
+
errorCode: 'vendor_url_required',
|
|
262
|
+
message: 'Vendor URL is required',
|
|
263
|
+
statusCode: 400,
|
|
264
|
+
})
|
|
265
|
+
);
|
|
266
|
+
fastify.resetOverrides();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should 400 if no commercial entity', async () => {
|
|
270
|
+
const payload = _.omit(
|
|
271
|
+
['tenantId'],
|
|
272
|
+
await newDisclosure({
|
|
273
|
+
tenant,
|
|
274
|
+
offerMode: 'preloaded',
|
|
275
|
+
commercialEntityName: 'abc',
|
|
276
|
+
commercialEntityLogo: 'dsa',
|
|
277
|
+
})
|
|
278
|
+
);
|
|
279
|
+
const response = await fastify.injectJson({
|
|
280
|
+
method: 'POST',
|
|
281
|
+
url: `${disclosureUrl(tenant)}`,
|
|
282
|
+
payload,
|
|
283
|
+
headers: {
|
|
284
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
expect(response.statusCode).toEqual(400);
|
|
288
|
+
expect(response.json).toEqual(
|
|
289
|
+
errorResponseMatcher({
|
|
290
|
+
error: 'Bad Request',
|
|
291
|
+
errorCode: 'invalid_commercial_entity',
|
|
292
|
+
message: 'Invalid commercial entity',
|
|
293
|
+
statusCode: 400,
|
|
294
|
+
})
|
|
295
|
+
);
|
|
296
|
+
expect(nockVP.isDone()).toBe(true);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('should 500 if registrar does not response', async () => {
|
|
300
|
+
nock.cleanAll();
|
|
301
|
+
const payload = _.omit(
|
|
302
|
+
['tenantId'],
|
|
303
|
+
await newDisclosure({
|
|
304
|
+
tenant,
|
|
305
|
+
offerMode: 'preloaded',
|
|
306
|
+
})
|
|
307
|
+
);
|
|
308
|
+
const response = await fastify.injectJson({
|
|
309
|
+
method: 'POST',
|
|
310
|
+
url: `${disclosureUrl(tenant)}`,
|
|
311
|
+
payload,
|
|
312
|
+
headers: {
|
|
313
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
expect(response.statusCode).toEqual(500);
|
|
317
|
+
expect(response.json).toEqual(
|
|
318
|
+
errorResponseMatcher({
|
|
319
|
+
error: 'Internal Server Error',
|
|
320
|
+
errorCode: 'missing_error_code',
|
|
321
|
+
statusCode: 500,
|
|
322
|
+
})
|
|
323
|
+
);
|
|
324
|
+
}, 20000);
|
|
325
|
+
|
|
326
|
+
it('should 400 if commercial entity is only a partial match', async () => {
|
|
327
|
+
const payload = _.omit(
|
|
328
|
+
['tenantId'],
|
|
329
|
+
await newDisclosure({
|
|
330
|
+
tenant,
|
|
331
|
+
offerMode: 'preloaded',
|
|
332
|
+
commercialEntityName: 'not-match',
|
|
333
|
+
commercialEntityLogo: 'https://www.example.com/logo.png',
|
|
334
|
+
})
|
|
335
|
+
);
|
|
336
|
+
const response = await fastify.injectJson({
|
|
337
|
+
method: 'POST',
|
|
338
|
+
url: `${disclosureUrl(tenant)}`,
|
|
339
|
+
payload,
|
|
340
|
+
headers: {
|
|
341
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
expect(response.statusCode).toEqual(400);
|
|
345
|
+
expect(response.json).toEqual(
|
|
346
|
+
errorResponseMatcher({
|
|
347
|
+
error: 'Bad Request',
|
|
348
|
+
errorCode: 'invalid_commercial_entity',
|
|
349
|
+
message: 'Invalid commercial entity',
|
|
350
|
+
statusCode: 400,
|
|
351
|
+
})
|
|
352
|
+
);
|
|
353
|
+
expect(nockVP.isDone()).toBe(true);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('should 400 if commercial entity is empty array', async () => {
|
|
357
|
+
const payload = _.omit(
|
|
358
|
+
['tenantId'],
|
|
359
|
+
await newDisclosure({
|
|
360
|
+
tenant: altTenant,
|
|
361
|
+
offerMode: 'preloaded',
|
|
362
|
+
commercialEntityName: 'abc',
|
|
363
|
+
commercialEntityLogo: 'dsa',
|
|
364
|
+
})
|
|
365
|
+
);
|
|
366
|
+
const response = await fastify.injectJson({
|
|
367
|
+
method: 'POST',
|
|
368
|
+
url: `${disclosureUrl(altTenant)}`,
|
|
369
|
+
payload,
|
|
370
|
+
headers: {
|
|
371
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
expect(response.statusCode).toEqual(400);
|
|
375
|
+
expect(response.json).toEqual(
|
|
376
|
+
errorResponseMatcher({
|
|
377
|
+
error: 'Bad Request',
|
|
378
|
+
errorCode: 'invalid_commercial_entity',
|
|
379
|
+
message: 'Invalid commercial entity',
|
|
380
|
+
statusCode: 400,
|
|
381
|
+
})
|
|
382
|
+
);
|
|
383
|
+
expect(nockAltVP.isDone()).toBe(true);
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
describe('Create Disclosure - Inspection Configuration', () => {
|
|
388
|
+
it('should 400 when types are not provided', async () => {
|
|
389
|
+
const payload = _.omit(
|
|
390
|
+
['tenantId', 'types'],
|
|
391
|
+
await newDisclosure({ tenant })
|
|
392
|
+
);
|
|
393
|
+
const response = await fastify.injectJson({
|
|
394
|
+
method: 'POST',
|
|
395
|
+
url: `${disclosureUrl(tenant)}`,
|
|
396
|
+
payload,
|
|
397
|
+
headers: {
|
|
398
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
399
|
+
},
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
expect(response.statusCode).toEqual(400);
|
|
403
|
+
expect(response.json).toEqual(
|
|
404
|
+
errorResponseMatcher({
|
|
405
|
+
errorCode: 'types_required',
|
|
406
|
+
statusCode: 400,
|
|
407
|
+
error: 'Bad Request',
|
|
408
|
+
message: 'Types should has minimum one item',
|
|
409
|
+
})
|
|
410
|
+
);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it('should 400 when empty types is provided', async () => {
|
|
414
|
+
const payload = _.flow(
|
|
415
|
+
_.omit(['tenantId']),
|
|
416
|
+
_.set('types', [])
|
|
417
|
+
)(await newDisclosure({ tenant }));
|
|
418
|
+
const response = await fastify.injectJson({
|
|
419
|
+
method: 'POST',
|
|
420
|
+
url: `${disclosureUrl(tenant)}`,
|
|
421
|
+
payload,
|
|
422
|
+
headers: {
|
|
423
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
424
|
+
},
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
expect(response.statusCode).toEqual(400);
|
|
428
|
+
expect(response.json).toEqual(
|
|
429
|
+
errorResponseMatcher({
|
|
430
|
+
errorCode: 'request_validation_failed',
|
|
431
|
+
statusCode: 400,
|
|
432
|
+
error: 'Bad Request',
|
|
433
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
434
|
+
})
|
|
435
|
+
);
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it('should 400 when empty object provided in types array', async () => {
|
|
439
|
+
const payload = _.flow(
|
|
440
|
+
_.omit(['tenantId']),
|
|
441
|
+
_.set('types', [{}])
|
|
442
|
+
)(await newDisclosure({ tenant }));
|
|
443
|
+
const response = await fastify.injectJson({
|
|
444
|
+
method: 'POST',
|
|
445
|
+
url: `${disclosureUrl(tenant)}`,
|
|
446
|
+
payload,
|
|
447
|
+
headers: {
|
|
448
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
449
|
+
},
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
expect(response.statusCode).toEqual(400);
|
|
453
|
+
expect(response.json).toEqual(
|
|
454
|
+
errorResponseMatcher({
|
|
455
|
+
errorCode: 'request_validation_failed',
|
|
456
|
+
statusCode: 400,
|
|
457
|
+
error: 'Bad Request',
|
|
458
|
+
message: "body should have required property 'types'",
|
|
459
|
+
})
|
|
460
|
+
);
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
it('should 400 when missing duration', async () => {
|
|
464
|
+
const payload = _.omit(
|
|
465
|
+
['tenantId', 'duration'],
|
|
466
|
+
await newDisclosure({
|
|
467
|
+
tenant,
|
|
468
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
469
|
+
identificationMethods: ['verifiable_presentation'],
|
|
470
|
+
vendorEndpoint: 'receive-applicant',
|
|
471
|
+
})
|
|
472
|
+
);
|
|
473
|
+
const response = await fastify.injectJson({
|
|
474
|
+
method: 'POST',
|
|
475
|
+
url: `${disclosureUrl(tenant)}`,
|
|
476
|
+
payload,
|
|
477
|
+
headers: {
|
|
478
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
expect(response.statusCode).toEqual(400);
|
|
483
|
+
expect(response.json).toEqual(
|
|
484
|
+
errorResponseMatcher({
|
|
485
|
+
error: 'Bad Request',
|
|
486
|
+
errorCode: 'duration_required',
|
|
487
|
+
message: 'Duration is required',
|
|
488
|
+
statusCode: 400,
|
|
489
|
+
})
|
|
490
|
+
);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it('should 400 when missing Purpose', async () => {
|
|
494
|
+
const payload = _.omit(
|
|
495
|
+
['tenantId', 'purpose'],
|
|
496
|
+
await newDisclosure({
|
|
497
|
+
tenant,
|
|
498
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
499
|
+
identificationMethods: ['verifiable_presentation'],
|
|
500
|
+
vendorEndpoint: 'receive-applicant',
|
|
501
|
+
})
|
|
502
|
+
);
|
|
503
|
+
const response = await fastify.injectJson({
|
|
504
|
+
method: 'POST',
|
|
505
|
+
url: `${disclosureUrl(tenant)}`,
|
|
506
|
+
payload,
|
|
507
|
+
headers: {
|
|
508
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
expect(response.statusCode).toEqual(400);
|
|
513
|
+
expect(response.json).toEqual(
|
|
514
|
+
errorResponseMatcher({
|
|
515
|
+
error: 'Bad Request',
|
|
516
|
+
errorCode: 'purpose_required',
|
|
517
|
+
message: 'Purpose is required',
|
|
518
|
+
statusCode: 400,
|
|
519
|
+
})
|
|
520
|
+
);
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it('should 400 when feed is true and configurationType is not inspection', async () => {
|
|
524
|
+
const payload = {
|
|
525
|
+
..._.omit(
|
|
526
|
+
['tenantId'],
|
|
527
|
+
await newDisclosure({
|
|
528
|
+
tenant,
|
|
529
|
+
configurationType: 'issuing',
|
|
530
|
+
vendorEndpoint: 'issuing-identification',
|
|
531
|
+
setIssuingDefault: true,
|
|
532
|
+
feed: true,
|
|
533
|
+
})
|
|
534
|
+
),
|
|
535
|
+
};
|
|
536
|
+
const response = await fastify.injectJson({
|
|
537
|
+
method: 'POST',
|
|
538
|
+
url: `${disclosureUrl(tenant)}`,
|
|
539
|
+
payload,
|
|
540
|
+
headers: {
|
|
541
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
expect(response.statusCode).toEqual(400);
|
|
546
|
+
expect(response.json).toEqual(
|
|
547
|
+
errorResponseMatcher({
|
|
548
|
+
error: 'Bad Request',
|
|
549
|
+
errorCode: 'issuing_feed_not_supported',
|
|
550
|
+
message: 'Issuing feeds are not supported',
|
|
551
|
+
statusCode: 400,
|
|
552
|
+
})
|
|
553
|
+
);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it('should create a particular disclosure with offerMode', async () => {
|
|
557
|
+
const payload = _.omit(
|
|
558
|
+
['tenantId'],
|
|
559
|
+
await newDisclosure({ tenant, offerMode: 'preloaded' })
|
|
560
|
+
);
|
|
561
|
+
const response = await fastify.injectJson({
|
|
562
|
+
method: 'POST',
|
|
563
|
+
url: `${disclosureUrl(tenant)}`,
|
|
564
|
+
payload,
|
|
565
|
+
headers: {
|
|
566
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
expect(response.statusCode).toEqual(201);
|
|
570
|
+
expect(response.json).toEqual({
|
|
571
|
+
createdAt: expect.any(String),
|
|
572
|
+
description: 'Clerk',
|
|
573
|
+
duration: '6y',
|
|
574
|
+
id: expect.any(String),
|
|
575
|
+
identificationMethods: ['verifiable_presentation'],
|
|
576
|
+
offerMode: 'preloaded',
|
|
577
|
+
purpose: 'Job Application',
|
|
578
|
+
sendPushOnVerification: false,
|
|
579
|
+
termsUrl: 'https://www.lipsum.com/feed/html',
|
|
580
|
+
feed: false,
|
|
581
|
+
types: [
|
|
582
|
+
{ type: 'PastEmploymentPosition' },
|
|
583
|
+
{ type: 'CurrentEmploymentPosition' },
|
|
584
|
+
],
|
|
585
|
+
updatedAt: expect.any(String),
|
|
586
|
+
vendorDisclosureId: 'HR-PKG-USPS-CLRK',
|
|
587
|
+
vendorEndpoint: 'receive-applicant',
|
|
588
|
+
configurationType: 'inspection',
|
|
589
|
+
deactivationDate: expect.any(String),
|
|
590
|
+
authTokensExpireIn: 10080,
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it('should create a disclosure with commercial entity', async () => {
|
|
595
|
+
const payload = _.omit(
|
|
596
|
+
['tenantId'],
|
|
597
|
+
await newDisclosure({
|
|
598
|
+
tenant,
|
|
599
|
+
offerMode: 'preloaded',
|
|
600
|
+
commercialEntityName,
|
|
601
|
+
commercialEntityLogo,
|
|
602
|
+
})
|
|
603
|
+
);
|
|
604
|
+
const response = await fastify.injectJson({
|
|
605
|
+
method: 'POST',
|
|
606
|
+
url: `${disclosureUrl(tenant)}`,
|
|
607
|
+
payload,
|
|
608
|
+
headers: {
|
|
609
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
expect(response.statusCode).toEqual(201);
|
|
613
|
+
expect(response.json).toEqual({
|
|
614
|
+
createdAt: expect.any(String),
|
|
615
|
+
description: 'Clerk',
|
|
616
|
+
duration: '6y',
|
|
617
|
+
id: expect.any(String),
|
|
618
|
+
identificationMethods: ['verifiable_presentation'],
|
|
619
|
+
offerMode: 'preloaded',
|
|
620
|
+
purpose: 'Job Application',
|
|
621
|
+
sendPushOnVerification: false,
|
|
622
|
+
termsUrl: 'https://www.lipsum.com/feed/html',
|
|
623
|
+
feed: false,
|
|
624
|
+
types: [
|
|
625
|
+
{ type: 'PastEmploymentPosition' },
|
|
626
|
+
{ type: 'CurrentEmploymentPosition' },
|
|
627
|
+
],
|
|
628
|
+
commercialEntityName,
|
|
629
|
+
commercialEntityLogo,
|
|
630
|
+
updatedAt: expect.any(String),
|
|
631
|
+
vendorDisclosureId: 'HR-PKG-USPS-CLRK',
|
|
632
|
+
vendorEndpoint: 'receive-applicant',
|
|
633
|
+
configurationType: 'inspection',
|
|
634
|
+
deactivationDate: expect.any(String),
|
|
635
|
+
authTokensExpireIn: 10080,
|
|
636
|
+
});
|
|
637
|
+
expect(nockVP.isDone()).toBe(true);
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('should create disclosure if tenant has webhookUrl', async () => {
|
|
641
|
+
fastify.overrides.reqConfig = (config) => ({
|
|
642
|
+
...config,
|
|
643
|
+
vendorUrl: '',
|
|
644
|
+
});
|
|
645
|
+
const customTenant = await persistTenant({
|
|
646
|
+
webhookUrl: 'http://test.io',
|
|
647
|
+
});
|
|
648
|
+
nockVerifiedProfile(customTenant.did);
|
|
649
|
+
const payload = _.omit(
|
|
650
|
+
['tenantId'],
|
|
651
|
+
await newDisclosure({ tenant: customTenant, offerMode: 'preloaded' })
|
|
652
|
+
);
|
|
653
|
+
const response = await fastify.injectJson({
|
|
654
|
+
method: 'POST',
|
|
655
|
+
url: `${disclosureUrl(customTenant)}`,
|
|
656
|
+
payload,
|
|
657
|
+
headers: {
|
|
658
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
659
|
+
},
|
|
660
|
+
});
|
|
661
|
+
expect(response.statusCode).toEqual(201);
|
|
662
|
+
expect(response.json).toEqual({
|
|
663
|
+
createdAt: expect.any(String),
|
|
664
|
+
description: 'Clerk',
|
|
665
|
+
duration: '6y',
|
|
666
|
+
id: expect.any(String),
|
|
667
|
+
identificationMethods: ['verifiable_presentation'],
|
|
668
|
+
offerMode: 'preloaded',
|
|
669
|
+
purpose: 'Job Application',
|
|
670
|
+
sendPushOnVerification: false,
|
|
671
|
+
termsUrl: 'https://www.lipsum.com/feed/html',
|
|
672
|
+
feed: false,
|
|
673
|
+
types: [
|
|
674
|
+
{ type: 'PastEmploymentPosition' },
|
|
675
|
+
{ type: 'CurrentEmploymentPosition' },
|
|
676
|
+
],
|
|
677
|
+
updatedAt: expect.any(String),
|
|
678
|
+
vendorDisclosureId: 'HR-PKG-USPS-CLRK',
|
|
679
|
+
vendorEndpoint: 'receive-applicant',
|
|
680
|
+
configurationType: 'inspection',
|
|
681
|
+
deactivationDate: expect.any(String),
|
|
682
|
+
authTokensExpireIn: 10080,
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
it('should 201 when feed is true and configurationType is inspection', async () => {
|
|
687
|
+
const payload = {
|
|
688
|
+
..._.omit(
|
|
689
|
+
['tenantId'],
|
|
690
|
+
await newDisclosure({
|
|
691
|
+
tenant,
|
|
692
|
+
feed: true,
|
|
693
|
+
})
|
|
694
|
+
),
|
|
695
|
+
};
|
|
696
|
+
const response = await fastify.injectJson({
|
|
697
|
+
method: 'POST',
|
|
698
|
+
url: `${disclosureUrl(tenant)}`,
|
|
699
|
+
payload,
|
|
700
|
+
headers: {
|
|
701
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
702
|
+
},
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
expect(response.statusCode).toEqual(201);
|
|
706
|
+
expect(response.json).toEqual({
|
|
707
|
+
..._.omit(
|
|
708
|
+
['presentationDefinition.submission_requirements[0].foo'],
|
|
709
|
+
payload
|
|
710
|
+
),
|
|
711
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
712
|
+
identificationMethods: ['verifiable_presentation'],
|
|
713
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
714
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
715
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
716
|
+
});
|
|
717
|
+
const dbResult = await mongoDb()
|
|
718
|
+
.collection('disclosures')
|
|
719
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
720
|
+
expect(dbResult).toEqual({
|
|
721
|
+
...mongoify(_.omit(['id'], response.json)),
|
|
722
|
+
_id: new ObjectId(response.json.id),
|
|
723
|
+
tenantId: new ObjectId(tenant._id),
|
|
724
|
+
});
|
|
725
|
+
expect(dbResult.feed).toEqual(true);
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
describe('Create Disclosure - Issuing Missing Required Properties', () => {
|
|
730
|
+
it('should 400 creating disclosure with invalid offerMode', async () => {
|
|
731
|
+
const payload = {
|
|
732
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosures.a),
|
|
733
|
+
offerMode: 'blabla',
|
|
734
|
+
};
|
|
735
|
+
const response = await fastify.injectJson({
|
|
736
|
+
method: 'POST',
|
|
737
|
+
url: `${disclosureUrl(tenant)}`,
|
|
738
|
+
payload,
|
|
739
|
+
headers: {
|
|
740
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
741
|
+
},
|
|
742
|
+
});
|
|
743
|
+
expect(response.statusCode).toEqual(400);
|
|
744
|
+
expect(response.json).toEqual(
|
|
745
|
+
errorResponseMatcher({
|
|
746
|
+
errorCode: 'request_validation_failed',
|
|
747
|
+
statusCode: 400,
|
|
748
|
+
error: 'Bad Request',
|
|
749
|
+
message:
|
|
750
|
+
'body/offerMode must be equal to one of the allowed values',
|
|
751
|
+
})
|
|
752
|
+
);
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
it('should 400 when default disclosure type mismatch', async () => {
|
|
756
|
+
const payload = _.omit(
|
|
757
|
+
['tenantId'],
|
|
758
|
+
await newDisclosure({
|
|
759
|
+
tenant,
|
|
760
|
+
})
|
|
761
|
+
);
|
|
762
|
+
const response = await fastify.injectJson({
|
|
763
|
+
method: 'POST',
|
|
764
|
+
url: `${disclosureUrl(tenant)}`,
|
|
765
|
+
payload: {
|
|
766
|
+
...payload,
|
|
767
|
+
setIssuingDefault: true,
|
|
768
|
+
},
|
|
769
|
+
headers: {
|
|
770
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
771
|
+
},
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
expect(response.statusCode).toEqual(400);
|
|
775
|
+
expect(response.json).toEqual(
|
|
776
|
+
errorResponseMatcher({
|
|
777
|
+
error: 'Bad Request',
|
|
778
|
+
errorCode: 'issuing_default_not_compatible',
|
|
779
|
+
message: 'The default disclosure cannot be of type "inspection"',
|
|
780
|
+
statusCode: 400,
|
|
781
|
+
})
|
|
782
|
+
);
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
it('should 400 when configuration type is wrong', async () => {
|
|
786
|
+
const payload = _.omit(
|
|
787
|
+
['tenantId'],
|
|
788
|
+
await newDisclosure({
|
|
789
|
+
tenant,
|
|
790
|
+
vendorEndpoint: VendorEndpoint.RECEIVE_APPLICANT,
|
|
791
|
+
configurationType: ConfigurationType.ISSUING,
|
|
792
|
+
})
|
|
793
|
+
);
|
|
794
|
+
const response = await fastify.injectJson({
|
|
795
|
+
method: 'POST',
|
|
796
|
+
url: `${disclosureUrl(tenant)}`,
|
|
797
|
+
payload,
|
|
798
|
+
headers: {
|
|
799
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
expect(response.statusCode).toEqual(400);
|
|
804
|
+
expect(response.json).toEqual(
|
|
805
|
+
errorResponseMatcher({
|
|
806
|
+
error: 'Bad Request',
|
|
807
|
+
errorCode: 'disclosure_invalid',
|
|
808
|
+
message: 'Disclosure configuration type invalid',
|
|
809
|
+
statusCode: 400,
|
|
810
|
+
})
|
|
811
|
+
);
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
it('should 400 when default disclosure not set', async () => {
|
|
815
|
+
const payload = _.omit(
|
|
816
|
+
['tenantId'],
|
|
817
|
+
await newDisclosure({
|
|
818
|
+
tenant,
|
|
819
|
+
configurationType: ConfigurationType.ISSUING,
|
|
820
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
821
|
+
offerMode: 'preloaded',
|
|
822
|
+
})
|
|
823
|
+
);
|
|
824
|
+
const response = await fastify.injectJson({
|
|
825
|
+
method: 'POST',
|
|
826
|
+
url: `${disclosureUrl(tenant)}`,
|
|
827
|
+
payload: {
|
|
828
|
+
...payload,
|
|
829
|
+
setIssuingDefault: false,
|
|
830
|
+
},
|
|
831
|
+
headers: {
|
|
832
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
833
|
+
},
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
expect(response.statusCode).toEqual(400);
|
|
837
|
+
expect(response.json).toEqual(
|
|
838
|
+
errorResponseMatcher({
|
|
839
|
+
error: 'Bad Request',
|
|
840
|
+
errorCode: 'first_issuing_configuration_must_be_default',
|
|
841
|
+
message:
|
|
842
|
+
'The first "issuing" configuration created must be set as the default.',
|
|
843
|
+
statusCode: 400,
|
|
844
|
+
})
|
|
845
|
+
);
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
it('should 400 when missing offer mode', async () => {
|
|
849
|
+
const payload = _.omit(
|
|
850
|
+
['tenantId', 'offerMode'],
|
|
851
|
+
await newDisclosure({
|
|
852
|
+
tenant,
|
|
853
|
+
configurationType: ConfigurationType.ISSUING,
|
|
854
|
+
identificationMethods: ['preauth'],
|
|
855
|
+
vendorEndpoint: 'issuing-identification',
|
|
856
|
+
})
|
|
857
|
+
);
|
|
858
|
+
const response = await fastify.injectJson({
|
|
859
|
+
method: 'POST',
|
|
860
|
+
url: `${disclosureUrl(tenant)}`,
|
|
861
|
+
payload,
|
|
862
|
+
headers: {
|
|
863
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
864
|
+
},
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
expect(response.statusCode).toEqual(400);
|
|
868
|
+
expect(response.json).toEqual(
|
|
869
|
+
errorResponseMatcher({
|
|
870
|
+
error: 'Bad Request',
|
|
871
|
+
errorCode: 'offer_mode_required',
|
|
872
|
+
message: 'Offer mode is required',
|
|
873
|
+
statusCode: 400,
|
|
874
|
+
})
|
|
875
|
+
);
|
|
876
|
+
});
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
describe('Create Disclosure - Issuing + VP Identification Method', () => {
|
|
880
|
+
it('should 400 if identificationMethods is set to [verifiable_presentation] and types is not passed', async () => {
|
|
881
|
+
const payload = _.flow(_.omit(['tenantId', 'types']))(
|
|
882
|
+
await newDisclosure({
|
|
883
|
+
tenant,
|
|
884
|
+
identificationMethods: ['verifiable_presentation'],
|
|
885
|
+
})
|
|
886
|
+
);
|
|
887
|
+
const response = await fastify.injectJson({
|
|
888
|
+
method: 'POST',
|
|
889
|
+
url: `${disclosureUrl(tenant)}`,
|
|
890
|
+
payload,
|
|
891
|
+
headers: {
|
|
892
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
893
|
+
},
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
expect(response.statusCode).toEqual(400);
|
|
897
|
+
expect(response.json).toEqual(
|
|
898
|
+
errorResponseMatcher({
|
|
899
|
+
errorCode: 'types_required',
|
|
900
|
+
statusCode: 400,
|
|
901
|
+
error: 'Bad Request',
|
|
902
|
+
message: 'Types should has minimum one item',
|
|
903
|
+
})
|
|
904
|
+
);
|
|
905
|
+
});
|
|
906
|
+
it('should 400 if identificationMethods is set to [verifiable_presentation] and empty types is passed', async () => {
|
|
907
|
+
const payload = _.flow(_.omit(['tenantId']))(
|
|
908
|
+
await newDisclosure({
|
|
909
|
+
tenant,
|
|
910
|
+
identificationMethods: ['verifiable_presentation'],
|
|
911
|
+
types: [],
|
|
912
|
+
})
|
|
913
|
+
);
|
|
914
|
+
const response = await fastify.injectJson({
|
|
915
|
+
method: 'POST',
|
|
916
|
+
url: `${disclosureUrl(tenant)}`,
|
|
917
|
+
payload,
|
|
918
|
+
headers: {
|
|
919
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
920
|
+
},
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
expect(response.statusCode).toEqual(400);
|
|
924
|
+
expect(response.json).toEqual(
|
|
925
|
+
errorResponseMatcher({
|
|
926
|
+
errorCode: 'request_validation_failed',
|
|
927
|
+
statusCode: 400,
|
|
928
|
+
error: 'Bad Request',
|
|
929
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
930
|
+
})
|
|
931
|
+
);
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
it('should create the disclosure', async () => {
|
|
935
|
+
const payload = _.omit(
|
|
936
|
+
['tenantId'],
|
|
937
|
+
await newDisclosure({
|
|
938
|
+
tenant,
|
|
939
|
+
identificationMethods: ['verifiable_presentation'],
|
|
940
|
+
})
|
|
941
|
+
);
|
|
942
|
+
const response = await fastify.injectJson({
|
|
943
|
+
method: 'POST',
|
|
944
|
+
url: `${disclosureUrl(tenant)}`,
|
|
945
|
+
payload,
|
|
946
|
+
headers: {
|
|
947
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
948
|
+
},
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
expect(response.statusCode).toEqual(201);
|
|
952
|
+
expect(response.json).toEqual({
|
|
953
|
+
...payload,
|
|
954
|
+
feed: false,
|
|
955
|
+
deactivationDate: expect.any(String),
|
|
956
|
+
identificationMethods: ['verifiable_presentation'],
|
|
957
|
+
sendPushOnVerification: false,
|
|
958
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
959
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
960
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
const dbResult = await mongoDb()
|
|
964
|
+
.collection('disclosures')
|
|
965
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
966
|
+
expect(dbResult).toEqual({
|
|
967
|
+
...payload,
|
|
968
|
+
identificationMethods: ['verifiable_presentation'],
|
|
969
|
+
sendPushOnVerification: false,
|
|
970
|
+
feed: false,
|
|
971
|
+
_id: new ObjectId(response.json.id),
|
|
972
|
+
tenantId: new ObjectId(tenant._id),
|
|
973
|
+
createdAt: expect.any(Date),
|
|
974
|
+
updatedAt: expect.any(Date),
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
it('should allow duplicate issuing-identification', async () => {
|
|
979
|
+
await persistDisclosure({
|
|
980
|
+
tenant,
|
|
981
|
+
vendorEndpoint: 'issuing-identification',
|
|
982
|
+
identificationMethods: ['verifiable_presentation'],
|
|
983
|
+
types: [
|
|
984
|
+
{ type: 'EmailV1.0' },
|
|
985
|
+
{ type: 'PhoneV1.0' },
|
|
986
|
+
{ type: 'IdDocumentV1.0' },
|
|
987
|
+
],
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
const payload = _.omit(
|
|
991
|
+
['tenantId'],
|
|
992
|
+
await newDisclosure({
|
|
993
|
+
tenant,
|
|
994
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
995
|
+
types: [
|
|
996
|
+
{ type: 'EmailV1.0' },
|
|
997
|
+
{ type: 'PhoneV1.0' },
|
|
998
|
+
{ type: 'IdDocumentV1.0' },
|
|
999
|
+
],
|
|
1000
|
+
})
|
|
1001
|
+
);
|
|
1002
|
+
|
|
1003
|
+
const response = await fastify.injectJson({
|
|
1004
|
+
method: 'POST',
|
|
1005
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1006
|
+
payload,
|
|
1007
|
+
headers: {
|
|
1008
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1009
|
+
},
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
expect(response.statusCode).toEqual(201);
|
|
1013
|
+
expect(response.json).toEqual({
|
|
1014
|
+
...payload,
|
|
1015
|
+
deactivationDate: expect.any(String),
|
|
1016
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1017
|
+
sendPushOnVerification: false,
|
|
1018
|
+
feed: false,
|
|
1019
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1020
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1021
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1022
|
+
});
|
|
1023
|
+
});
|
|
1024
|
+
|
|
1025
|
+
it('should create an identity disclosure', async () => {
|
|
1026
|
+
const payload = _.omit(
|
|
1027
|
+
['tenantId', 'deactivationDate'],
|
|
1028
|
+
await newDisclosure({
|
|
1029
|
+
tenant,
|
|
1030
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1031
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1032
|
+
offerMode: 'preloaded',
|
|
1033
|
+
types: [
|
|
1034
|
+
{ type: 'EmailV1.0' },
|
|
1035
|
+
{ type: 'PhoneV1.0' },
|
|
1036
|
+
{ type: 'IdDocumentV1.0' },
|
|
1037
|
+
],
|
|
1038
|
+
})
|
|
1039
|
+
);
|
|
1040
|
+
const response = await fastify.injectJson({
|
|
1041
|
+
method: 'POST',
|
|
1042
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1043
|
+
payload: {
|
|
1044
|
+
...payload,
|
|
1045
|
+
setIssuingDefault: true,
|
|
1046
|
+
},
|
|
1047
|
+
headers: {
|
|
1048
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1049
|
+
},
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
expect(response.statusCode).toEqual(201);
|
|
1053
|
+
expect(response.json).toEqual({
|
|
1054
|
+
...payload,
|
|
1055
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1056
|
+
sendPushOnVerification: false,
|
|
1057
|
+
feed: false,
|
|
1058
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1059
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1060
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
const dbResult = await mongoDb()
|
|
1064
|
+
.collection('disclosures')
|
|
1065
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1066
|
+
expect(dbResult).toEqual({
|
|
1067
|
+
...payload,
|
|
1068
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1069
|
+
sendPushOnVerification: false,
|
|
1070
|
+
feed: false,
|
|
1071
|
+
_id: new ObjectId(response.json.id),
|
|
1072
|
+
tenantId: new ObjectId(tenant._id),
|
|
1073
|
+
createdAt: expect.any(Date),
|
|
1074
|
+
updatedAt: expect.any(Date),
|
|
1075
|
+
});
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
it('should create an disclosure if configuration type is not specified', async () => {
|
|
1079
|
+
fastify.overrides.reqConfig = (config) => ({
|
|
1080
|
+
...config,
|
|
1081
|
+
disclosureCredentialTypeRequired: false,
|
|
1082
|
+
});
|
|
1083
|
+
const payload = _.omit(
|
|
1084
|
+
['tenantId', 'configurationType'],
|
|
1085
|
+
await newDisclosure({
|
|
1086
|
+
tenant,
|
|
1087
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1088
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1089
|
+
offerMode: 'preloaded',
|
|
1090
|
+
types: [
|
|
1091
|
+
{ type: 'EmailV1.0' },
|
|
1092
|
+
{ type: 'PhoneV1.0' },
|
|
1093
|
+
{ type: 'IdDocumentV1.0' },
|
|
1094
|
+
],
|
|
1095
|
+
})
|
|
1096
|
+
);
|
|
1097
|
+
const response = await fastify.injectJson({
|
|
1098
|
+
method: 'POST',
|
|
1099
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1100
|
+
payload: {
|
|
1101
|
+
...payload,
|
|
1102
|
+
setIssuingDefault: true,
|
|
1103
|
+
},
|
|
1104
|
+
headers: {
|
|
1105
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1106
|
+
},
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
expect(response.statusCode).toEqual(201);
|
|
1110
|
+
expect(response.json).toEqual({
|
|
1111
|
+
...payload,
|
|
1112
|
+
deactivationDate: expect.any(String),
|
|
1113
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1114
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1115
|
+
feed: false,
|
|
1116
|
+
sendPushOnVerification: false,
|
|
1117
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1118
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1119
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1120
|
+
});
|
|
1121
|
+
|
|
1122
|
+
const dbResult = await mongoDb()
|
|
1123
|
+
.collection('disclosures')
|
|
1124
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1125
|
+
expect(dbResult).toEqual({
|
|
1126
|
+
...payload,
|
|
1127
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1128
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1129
|
+
sendPushOnVerification: false,
|
|
1130
|
+
feed: false,
|
|
1131
|
+
_id: new ObjectId(response.json.id),
|
|
1132
|
+
tenantId: new ObjectId(tenant._id),
|
|
1133
|
+
createdAt: expect.any(Date),
|
|
1134
|
+
updatedAt: expect.any(Date),
|
|
1135
|
+
});
|
|
1136
|
+
});
|
|
1137
|
+
|
|
1138
|
+
it('should create an disclosure and should update a tenant (defaultIssuingDisclosureId)', async () => {
|
|
1139
|
+
fastify.overrides.reqConfig = (config) => ({
|
|
1140
|
+
...config,
|
|
1141
|
+
disclosureCredentialTypeRequired: false,
|
|
1142
|
+
});
|
|
1143
|
+
const payload = _.omit(
|
|
1144
|
+
['tenantId', 'configurationType'],
|
|
1145
|
+
await newDisclosure({
|
|
1146
|
+
tenant,
|
|
1147
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1148
|
+
offerMode: 'preloaded',
|
|
1149
|
+
types: [
|
|
1150
|
+
{ type: 'EmailV1.0' },
|
|
1151
|
+
{ type: 'PhoneV1.0' },
|
|
1152
|
+
{ type: 'IdDocumentV1.0' },
|
|
1153
|
+
],
|
|
1154
|
+
})
|
|
1155
|
+
);
|
|
1156
|
+
const response = await fastify.injectJson({
|
|
1157
|
+
method: 'POST',
|
|
1158
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1159
|
+
payload: {
|
|
1160
|
+
...payload,
|
|
1161
|
+
setIssuingDefault: true,
|
|
1162
|
+
},
|
|
1163
|
+
headers: {
|
|
1164
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1165
|
+
},
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
expect(response.statusCode).toEqual(201);
|
|
1169
|
+
expect(response.json).toEqual({
|
|
1170
|
+
...payload,
|
|
1171
|
+
deactivationDate: expect.any(String),
|
|
1172
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1173
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1174
|
+
sendPushOnVerification: false,
|
|
1175
|
+
feed: false,
|
|
1176
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1177
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1178
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
const dbResult = await mongoDb()
|
|
1182
|
+
.collection('tenants')
|
|
1183
|
+
.findOne({ _id: new ObjectId(tenant._id) });
|
|
1184
|
+
expect(dbResult.defaultIssuingDisclosureId.toString()).toStrictEqual(
|
|
1185
|
+
response.json.id.toString()
|
|
1186
|
+
);
|
|
1187
|
+
});
|
|
1188
|
+
|
|
1189
|
+
it('should create an disclosure and should not update a tenant (defaultIssuingDisclosureId) if `setIssuingDefault` is false', async () => {
|
|
1190
|
+
fastify.overrides.reqConfig = (config) => ({
|
|
1191
|
+
...config,
|
|
1192
|
+
disclosureCredentialTypeRequired: false,
|
|
1193
|
+
});
|
|
1194
|
+
tenant = await persistTenant({
|
|
1195
|
+
defaultIssuingDisclosureId: 'abc',
|
|
1196
|
+
});
|
|
1197
|
+
nockVerifiedProfile(tenant.did);
|
|
1198
|
+
const payload = _.omit(
|
|
1199
|
+
['tenantId', 'configurationType'],
|
|
1200
|
+
await newDisclosure({
|
|
1201
|
+
tenant,
|
|
1202
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1203
|
+
offerMode: 'preloaded',
|
|
1204
|
+
types: [
|
|
1205
|
+
{ type: 'EmailV1.0' },
|
|
1206
|
+
{ type: 'PhoneV1.0' },
|
|
1207
|
+
{ type: 'IdDocumentV1.0' },
|
|
1208
|
+
],
|
|
1209
|
+
})
|
|
1210
|
+
);
|
|
1211
|
+
const response = await fastify.injectJson({
|
|
1212
|
+
method: 'POST',
|
|
1213
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1214
|
+
payload: {
|
|
1215
|
+
...payload,
|
|
1216
|
+
setIssuingDefault: false,
|
|
1217
|
+
},
|
|
1218
|
+
headers: {
|
|
1219
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1220
|
+
},
|
|
1221
|
+
});
|
|
1222
|
+
|
|
1223
|
+
expect(response.statusCode).toEqual(201);
|
|
1224
|
+
expect(response.json).toEqual({
|
|
1225
|
+
...payload,
|
|
1226
|
+
deactivationDate: expect.any(String),
|
|
1227
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1228
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1229
|
+
sendPushOnVerification: false,
|
|
1230
|
+
feed: false,
|
|
1231
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1232
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1233
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
const dbResult = await mongoDb()
|
|
1237
|
+
.collection('tenants')
|
|
1238
|
+
.findOne({ _id: new ObjectId(tenant._id) });
|
|
1239
|
+
expect(dbResult.defaultIssuingDisclosureId).toStrictEqual('abc');
|
|
1240
|
+
});
|
|
1241
|
+
|
|
1242
|
+
it('should 200 and create the disclosure with identificationMethods set to [verifiable_presentation]', async () => {
|
|
1243
|
+
const payload = _.flow(_.omit(['tenantId']))(
|
|
1244
|
+
await newDisclosure({
|
|
1245
|
+
tenant,
|
|
1246
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1247
|
+
})
|
|
1248
|
+
);
|
|
1249
|
+
const response = await fastify.injectJson({
|
|
1250
|
+
method: 'POST',
|
|
1251
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1252
|
+
payload,
|
|
1253
|
+
headers: {
|
|
1254
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1255
|
+
},
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
expect(response.statusCode).toEqual(201);
|
|
1259
|
+
expect(response.json).toEqual({
|
|
1260
|
+
...payload,
|
|
1261
|
+
deactivationDate: expect.any(String),
|
|
1262
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1263
|
+
sendPushOnVerification: false,
|
|
1264
|
+
feed: false,
|
|
1265
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1266
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1267
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
const dbResult = await mongoDb()
|
|
1271
|
+
.collection('disclosures')
|
|
1272
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1273
|
+
expect(dbResult).toEqual({
|
|
1274
|
+
...payload,
|
|
1275
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1276
|
+
sendPushOnVerification: false,
|
|
1277
|
+
feed: false,
|
|
1278
|
+
_id: new ObjectId(response.json.id),
|
|
1279
|
+
tenantId: new ObjectId(tenant._id),
|
|
1280
|
+
createdAt: expect.any(Date),
|
|
1281
|
+
updatedAt: expect.any(Date),
|
|
1282
|
+
});
|
|
1283
|
+
});
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
describe('Create Disclosure - Issuing + VP Identification Method + Integrated Issuing Identification', () => {
|
|
1287
|
+
it('should 400 and fail to create an integrated identity disclosure without "identityMatchers"', async () => {
|
|
1288
|
+
const payload = _.omit(
|
|
1289
|
+
['tenantId'],
|
|
1290
|
+
await newDisclosure({
|
|
1291
|
+
tenant,
|
|
1292
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
1293
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1294
|
+
setIssuingDefault: true,
|
|
1295
|
+
})
|
|
1296
|
+
);
|
|
1297
|
+
const response = await fastify.injectJson({
|
|
1298
|
+
method: 'POST',
|
|
1299
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1300
|
+
payload,
|
|
1301
|
+
headers: {
|
|
1302
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1303
|
+
},
|
|
1304
|
+
});
|
|
1305
|
+
|
|
1306
|
+
expect(response.statusCode).toEqual(400);
|
|
1307
|
+
expect(response.json).toEqual(
|
|
1308
|
+
errorResponseMatcher({
|
|
1309
|
+
error: 'Bad Request',
|
|
1310
|
+
errorCode: 'request_validation_failed',
|
|
1311
|
+
message:
|
|
1312
|
+
'When using { "vendorEndpoint": "integrated-issuing-identification" } "identityMatchers" property is required',
|
|
1313
|
+
statusCode: 400,
|
|
1314
|
+
})
|
|
1315
|
+
);
|
|
1316
|
+
});
|
|
1317
|
+
|
|
1318
|
+
it('should create an integrated identity disclosure with sendPushOnVerification true', async () => {
|
|
1319
|
+
const payload = _.omit(
|
|
1320
|
+
['tenantId'],
|
|
1321
|
+
await newDisclosure({
|
|
1322
|
+
tenant,
|
|
1323
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
1324
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1325
|
+
offerMode: 'preloaded',
|
|
1326
|
+
types: [{ type: 'EmailV1.0' }],
|
|
1327
|
+
identityMatchers: {
|
|
1328
|
+
rules: [
|
|
1329
|
+
{
|
|
1330
|
+
valueIndex: 0, // used for identifying the value
|
|
1331
|
+
path: ['$.emails'], // jsonPath within the credential
|
|
1332
|
+
rule: 'pick', // Rule to execute can be pick, all (if the target is an array), equal (if the target is a singleValue)
|
|
1333
|
+
},
|
|
1334
|
+
],
|
|
1335
|
+
vendorUserIdIndex: 0,
|
|
1336
|
+
},
|
|
1337
|
+
})
|
|
1338
|
+
);
|
|
1339
|
+
const response = await fastify.injectJson({
|
|
1340
|
+
method: 'POST',
|
|
1341
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1342
|
+
payload: {
|
|
1343
|
+
...payload,
|
|
1344
|
+
setIssuingDefault: true,
|
|
1345
|
+
sendPushOnVerification: true,
|
|
1346
|
+
},
|
|
1347
|
+
headers: {
|
|
1348
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1349
|
+
},
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
expect(response.statusCode).toEqual(201);
|
|
1353
|
+
expect(response.json).toEqual({
|
|
1354
|
+
...payload,
|
|
1355
|
+
deactivationDate: expect.any(String),
|
|
1356
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1357
|
+
sendPushOnVerification: true,
|
|
1358
|
+
feed: false,
|
|
1359
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1360
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1361
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
const dbResult = await mongoDb()
|
|
1365
|
+
.collection('disclosures')
|
|
1366
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1367
|
+
expect(dbResult).toEqual({
|
|
1368
|
+
...payload,
|
|
1369
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1370
|
+
sendPushOnVerification: true,
|
|
1371
|
+
feed: false,
|
|
1372
|
+
_id: new ObjectId(response.json.id),
|
|
1373
|
+
tenantId: new ObjectId(tenant._id),
|
|
1374
|
+
createdAt: expect.any(Date),
|
|
1375
|
+
updatedAt: expect.any(Date),
|
|
1376
|
+
});
|
|
1377
|
+
});
|
|
1378
|
+
|
|
1379
|
+
it('should create an integrated identity disclosure', async () => {
|
|
1380
|
+
const payload = _.omit(
|
|
1381
|
+
['tenantId'],
|
|
1382
|
+
await newDisclosure({
|
|
1383
|
+
tenant,
|
|
1384
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
1385
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1386
|
+
types: [{ type: 'EmailV1.0' }],
|
|
1387
|
+
offerMode: 'preloaded',
|
|
1388
|
+
identityMatchers: {
|
|
1389
|
+
rules: [
|
|
1390
|
+
{
|
|
1391
|
+
valueIndex: 0, // used for identifying the value
|
|
1392
|
+
path: ['$.emails'], // jsonPath within the credential
|
|
1393
|
+
rule: 'pick', // Rule to execute can be pick, all (if the target is an array), equal (if the target is a singleValue)
|
|
1394
|
+
},
|
|
1395
|
+
],
|
|
1396
|
+
vendorUserIdIndex: 0,
|
|
1397
|
+
},
|
|
1398
|
+
})
|
|
1399
|
+
);
|
|
1400
|
+
const response = await fastify.injectJson({
|
|
1401
|
+
method: 'POST',
|
|
1402
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1403
|
+
payload: {
|
|
1404
|
+
...payload,
|
|
1405
|
+
setIssuingDefault: true,
|
|
1406
|
+
},
|
|
1407
|
+
headers: {
|
|
1408
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1409
|
+
},
|
|
1410
|
+
});
|
|
1411
|
+
|
|
1412
|
+
expect(response.statusCode).toEqual(201);
|
|
1413
|
+
expect(response.json).toEqual({
|
|
1414
|
+
...payload,
|
|
1415
|
+
deactivationDate: expect.any(String),
|
|
1416
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1417
|
+
sendPushOnVerification: false,
|
|
1418
|
+
feed: false,
|
|
1419
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1420
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1421
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1422
|
+
});
|
|
1423
|
+
|
|
1424
|
+
const dbResult = await mongoDb()
|
|
1425
|
+
.collection('disclosures')
|
|
1426
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1427
|
+
expect(dbResult).toEqual({
|
|
1428
|
+
...payload,
|
|
1429
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1430
|
+
sendPushOnVerification: false,
|
|
1431
|
+
feed: false,
|
|
1432
|
+
_id: new ObjectId(response.json.id),
|
|
1433
|
+
tenantId: new ObjectId(tenant._id),
|
|
1434
|
+
createdAt: expect.any(Date),
|
|
1435
|
+
updatedAt: expect.any(Date),
|
|
1436
|
+
});
|
|
1437
|
+
});
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
describe('Create Disclosure - Issuing + Preauth Identification Method', () => {
|
|
1441
|
+
it('should 400 when identification methods has preauth and disclosure is default', async () => {
|
|
1442
|
+
const payload = _.omit(
|
|
1443
|
+
['tenantId'],
|
|
1444
|
+
await newDisclosure({
|
|
1445
|
+
tenant,
|
|
1446
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1447
|
+
identificationMethods: ['preauth'],
|
|
1448
|
+
vendorEndpoint: 'issuing-identification',
|
|
1449
|
+
setIssuingDefault: true,
|
|
1450
|
+
offerMode: 'preloaded',
|
|
1451
|
+
})
|
|
1452
|
+
);
|
|
1453
|
+
const response = await fastify.injectJson({
|
|
1454
|
+
method: 'POST',
|
|
1455
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1456
|
+
payload,
|
|
1457
|
+
headers: {
|
|
1458
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1459
|
+
},
|
|
1460
|
+
});
|
|
1461
|
+
|
|
1462
|
+
expect(response.statusCode).toEqual(400);
|
|
1463
|
+
expect(response.json).toEqual(
|
|
1464
|
+
errorResponseMatcher({
|
|
1465
|
+
error: 'Bad Request',
|
|
1466
|
+
errorCode: 'request_validation_failed',
|
|
1467
|
+
message:
|
|
1468
|
+
"body may not have property 'setIssuingDefault' when 'identificationMode' is set to 'preauth'",
|
|
1469
|
+
statusCode: 400,
|
|
1470
|
+
})
|
|
1471
|
+
);
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1474
|
+
it('should 400 if identificationMethods is set to [preauth] and types is passed', async () => {
|
|
1475
|
+
const payload = _.flow(_.omit(['tenantId']))(
|
|
1476
|
+
await newDisclosure({
|
|
1477
|
+
tenant,
|
|
1478
|
+
identificationMethods: ['preauth'],
|
|
1479
|
+
types: [{ type: 'PastEmploymentPosition' }],
|
|
1480
|
+
})
|
|
1481
|
+
);
|
|
1482
|
+
const response = await fastify.injectJson({
|
|
1483
|
+
method: 'POST',
|
|
1484
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1485
|
+
payload,
|
|
1486
|
+
headers: {
|
|
1487
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1488
|
+
},
|
|
1489
|
+
});
|
|
1490
|
+
|
|
1491
|
+
expect(response.statusCode).toEqual(400);
|
|
1492
|
+
expect(response.json).toEqual(
|
|
1493
|
+
errorResponseMatcher({
|
|
1494
|
+
errorCode: 'request_validation_failed',
|
|
1495
|
+
statusCode: 400,
|
|
1496
|
+
error: 'Bad Request',
|
|
1497
|
+
message:
|
|
1498
|
+
"body may not have property 'types' when 'identificationMode' is set to 'preauth'",
|
|
1499
|
+
})
|
|
1500
|
+
);
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
it('should 200 and create the disclosure with identificationMethods set to [preauth]', async () => {
|
|
1504
|
+
tenant = await persistTenant({
|
|
1505
|
+
defaultIssuingDisclosureId: new ObjectId(),
|
|
1506
|
+
});
|
|
1507
|
+
nockVerifiedProfile(tenant.did);
|
|
1508
|
+
const payload = _.flow(_.omit(['tenantId']))(
|
|
1509
|
+
await newDisclosure({
|
|
1510
|
+
tenant,
|
|
1511
|
+
identificationMethods: ['preauth'],
|
|
1512
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1513
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1514
|
+
offerMode: 'preloaded',
|
|
1515
|
+
})
|
|
1516
|
+
);
|
|
1517
|
+
const response = await fastify.injectJson({
|
|
1518
|
+
method: 'POST',
|
|
1519
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1520
|
+
payload,
|
|
1521
|
+
headers: {
|
|
1522
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1523
|
+
},
|
|
1524
|
+
});
|
|
1525
|
+
|
|
1526
|
+
expect(response.statusCode).toEqual(201);
|
|
1527
|
+
expect(response.json).toEqual({
|
|
1528
|
+
..._.omit(['setIssuingDefault'])(payload),
|
|
1529
|
+
deactivationDate: expect.any(String),
|
|
1530
|
+
identificationMethods: ['preauth'],
|
|
1531
|
+
sendPushOnVerification: false,
|
|
1532
|
+
feed: false,
|
|
1533
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1534
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1535
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1536
|
+
});
|
|
1537
|
+
|
|
1538
|
+
const dbResult = await mongoDb()
|
|
1539
|
+
.collection('disclosures')
|
|
1540
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1541
|
+
expect(dbResult).toEqual({
|
|
1542
|
+
..._.omit(['setIssuingDefault'])(payload),
|
|
1543
|
+
identificationMethods: ['preauth'],
|
|
1544
|
+
sendPushOnVerification: false,
|
|
1545
|
+
feed: false,
|
|
1546
|
+
_id: new ObjectId(response.json.id),
|
|
1547
|
+
tenantId: new ObjectId(tenant._id),
|
|
1548
|
+
createdAt: expect.any(Date),
|
|
1549
|
+
updatedAt: expect.any(Date),
|
|
1550
|
+
});
|
|
1551
|
+
});
|
|
1552
|
+
|
|
1553
|
+
it('should 200 if none of purpose, duration or types not sent', async () => {
|
|
1554
|
+
tenant = await persistTenant({
|
|
1555
|
+
defaultIssuingDisclosureId: new ObjectId(),
|
|
1556
|
+
});
|
|
1557
|
+
nockVerifiedProfile(tenant.did);
|
|
1558
|
+
const payload = _.flow(
|
|
1559
|
+
_.omit(['tenantId', 'purpose', 'duration', 'types'])
|
|
1560
|
+
)(
|
|
1561
|
+
await newDisclosure({
|
|
1562
|
+
tenant,
|
|
1563
|
+
identificationMethods: ['preauth'],
|
|
1564
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1565
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1566
|
+
offerMode: 'preloaded',
|
|
1567
|
+
})
|
|
1568
|
+
);
|
|
1569
|
+
const response = await fastify.injectJson({
|
|
1570
|
+
method: 'POST',
|
|
1571
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1572
|
+
payload,
|
|
1573
|
+
headers: {
|
|
1574
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1575
|
+
},
|
|
1576
|
+
});
|
|
1577
|
+
|
|
1578
|
+
expect(response.statusCode).toEqual(201);
|
|
1579
|
+
expect(response.json).toEqual({
|
|
1580
|
+
..._.omit(['setIssuingDefault'])(payload),
|
|
1581
|
+
deactivationDate: expect.any(String),
|
|
1582
|
+
identificationMethods: ['preauth'],
|
|
1583
|
+
sendPushOnVerification: false,
|
|
1584
|
+
feed: false,
|
|
1585
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1586
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1587
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1588
|
+
});
|
|
1589
|
+
|
|
1590
|
+
const dbResult = await mongoDb()
|
|
1591
|
+
.collection('disclosures')
|
|
1592
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1593
|
+
expect(dbResult).toEqual({
|
|
1594
|
+
..._.omit(['setIssuingDefault'])(payload),
|
|
1595
|
+
identificationMethods: ['preauth'],
|
|
1596
|
+
sendPushOnVerification: false,
|
|
1597
|
+
feed: false,
|
|
1598
|
+
_id: new ObjectId(response.json.id),
|
|
1599
|
+
tenantId: new ObjectId(tenant._id),
|
|
1600
|
+
createdAt: expect.any(Date),
|
|
1601
|
+
updatedAt: expect.any(Date),
|
|
1602
|
+
});
|
|
1603
|
+
});
|
|
1604
|
+
|
|
1605
|
+
it('should 200 if tenant does not have default disclosure and create first issuing disclosure', async () => {
|
|
1606
|
+
tenant = await persistTenant({
|
|
1607
|
+
defaultIssuingDisclosureId: null,
|
|
1608
|
+
});
|
|
1609
|
+
nockVerifiedProfile(tenant.did);
|
|
1610
|
+
const payload = _.flow(_.omit(['tenantId']))(
|
|
1611
|
+
await newDisclosure({
|
|
1612
|
+
tenant,
|
|
1613
|
+
identificationMethods: ['preauth'],
|
|
1614
|
+
configurationType: ConfigurationType.ISSUING,
|
|
1615
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
1616
|
+
offerMode: 'webhook',
|
|
1617
|
+
termsUrl:
|
|
1618
|
+
'https://www.velocityexperiencecenter.com/terms-and-conditions-vnf',
|
|
1619
|
+
})
|
|
1620
|
+
);
|
|
1621
|
+
const response = await fastify.injectJson({
|
|
1622
|
+
method: 'POST',
|
|
1623
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1624
|
+
payload,
|
|
1625
|
+
headers: {
|
|
1626
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1627
|
+
},
|
|
1628
|
+
});
|
|
1629
|
+
|
|
1630
|
+
expect(response.statusCode).toEqual(201);
|
|
1631
|
+
expect(response.json).toEqual({
|
|
1632
|
+
..._.omit(['setIssuingDefault'])(payload),
|
|
1633
|
+
deactivationDate: expect.any(String),
|
|
1634
|
+
identificationMethods: ['preauth'],
|
|
1635
|
+
sendPushOnVerification: false,
|
|
1636
|
+
feed: false,
|
|
1637
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1638
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1639
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1640
|
+
});
|
|
1641
|
+
|
|
1642
|
+
const dbResult = await mongoDb()
|
|
1643
|
+
.collection('disclosures')
|
|
1644
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
1645
|
+
expect(dbResult).toEqual({
|
|
1646
|
+
..._.omit(['setIssuingDefault'])(payload),
|
|
1647
|
+
identificationMethods: ['preauth'],
|
|
1648
|
+
sendPushOnVerification: false,
|
|
1649
|
+
feed: false,
|
|
1650
|
+
_id: new ObjectId(response.json.id),
|
|
1651
|
+
tenantId: new ObjectId(tenant._id),
|
|
1652
|
+
createdAt: expect.any(Date),
|
|
1653
|
+
updatedAt: expect.any(Date),
|
|
1654
|
+
});
|
|
1655
|
+
});
|
|
1656
|
+
});
|
|
1657
|
+
|
|
1658
|
+
describe('Create Disclosure - Presentation Definition', () => {
|
|
1659
|
+
it('should 400 when presentationDefinition and types are present', async () => {
|
|
1660
|
+
const payload = {
|
|
1661
|
+
..._.omit(['tenantId'], await newDisclosure({ tenant })),
|
|
1662
|
+
presentationDefinition: samplePresentationDefinition,
|
|
1663
|
+
};
|
|
1664
|
+
const response = await fastify.injectJson({
|
|
1665
|
+
method: 'POST',
|
|
1666
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1667
|
+
payload,
|
|
1668
|
+
headers: {
|
|
1669
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1670
|
+
},
|
|
1671
|
+
});
|
|
1672
|
+
|
|
1673
|
+
expect(response.statusCode).toEqual(400);
|
|
1674
|
+
expect(response.json).toEqual(
|
|
1675
|
+
errorResponseMatcher({
|
|
1676
|
+
error: 'Bad Request',
|
|
1677
|
+
errorCode: 'request_validation_failed',
|
|
1678
|
+
message:
|
|
1679
|
+
"body may only have one property of 'types' or 'presentationDefinition'",
|
|
1680
|
+
statusCode: 400,
|
|
1681
|
+
})
|
|
1682
|
+
);
|
|
1683
|
+
});
|
|
1684
|
+
|
|
1685
|
+
it('should 400 when presentationDefinition.input_descriptors is empty', async () => {
|
|
1686
|
+
const presentationDefinition = {
|
|
1687
|
+
...samplePresentationDefinition,
|
|
1688
|
+
input_descriptors: [],
|
|
1689
|
+
};
|
|
1690
|
+
const payload = {
|
|
1691
|
+
..._.omit(
|
|
1692
|
+
['tenantId'],
|
|
1693
|
+
await newDisclosure({
|
|
1694
|
+
tenant,
|
|
1695
|
+
presentationDefinition,
|
|
1696
|
+
})
|
|
1697
|
+
),
|
|
1698
|
+
};
|
|
1699
|
+
const response = await fastify.injectJson({
|
|
1700
|
+
method: 'POST',
|
|
1701
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1702
|
+
payload,
|
|
1703
|
+
headers: {
|
|
1704
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1705
|
+
},
|
|
1706
|
+
});
|
|
1707
|
+
|
|
1708
|
+
expect(response.statusCode).toEqual(400);
|
|
1709
|
+
expect(response.json).toEqual(
|
|
1710
|
+
errorResponseMatcher({
|
|
1711
|
+
error: 'Bad Request',
|
|
1712
|
+
errorCode: 'request_validation_failed',
|
|
1713
|
+
message:
|
|
1714
|
+
// eslint-disable-next-line max-len
|
|
1715
|
+
'body/presentationDefinition/input_descriptors must NOT have fewer than 1 items',
|
|
1716
|
+
statusCode: 400,
|
|
1717
|
+
})
|
|
1718
|
+
);
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
it('should 400 when presentationDefinition.input_descriptors.*.group is missing/empty and submission_requirements is non-empty', async () => {
|
|
1722
|
+
const inputDescriptors = _.map(
|
|
1723
|
+
_.omit(['group']),
|
|
1724
|
+
samplePresentationDefinition.input_descriptors
|
|
1725
|
+
);
|
|
1726
|
+
const presentationDefinition = {
|
|
1727
|
+
input_descriptors: inputDescriptors,
|
|
1728
|
+
submission_requirements:
|
|
1729
|
+
samplePresentationDefinition.submission_requirements,
|
|
1730
|
+
};
|
|
1731
|
+
const payload = {
|
|
1732
|
+
..._.omit(
|
|
1733
|
+
['tenantId'],
|
|
1734
|
+
await newDisclosure({
|
|
1735
|
+
tenant,
|
|
1736
|
+
presentationDefinition,
|
|
1737
|
+
})
|
|
1738
|
+
),
|
|
1739
|
+
};
|
|
1740
|
+
const response = await fastify.injectJson({
|
|
1741
|
+
method: 'POST',
|
|
1742
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1743
|
+
payload,
|
|
1744
|
+
headers: {
|
|
1745
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1746
|
+
},
|
|
1747
|
+
});
|
|
1748
|
+
|
|
1749
|
+
expect(response.statusCode).toEqual(400);
|
|
1750
|
+
expect(response.json).toEqual(
|
|
1751
|
+
errorResponseMatcher({
|
|
1752
|
+
error: 'Bad Request',
|
|
1753
|
+
errorCode: 'request_validation_failed',
|
|
1754
|
+
message:
|
|
1755
|
+
// eslint-disable-next-line max-len
|
|
1756
|
+
'presentationDefinition input_descriptors[*].group is required when submission_requirements are sent',
|
|
1757
|
+
statusCode: 400,
|
|
1758
|
+
})
|
|
1759
|
+
);
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1762
|
+
it('should 400 when submission_requirements.*.rule is missing', async () => {
|
|
1763
|
+
const submissionRequirements = _.map(
|
|
1764
|
+
_.omit(['rule']),
|
|
1765
|
+
samplePresentationDefinition.submission_requirements
|
|
1766
|
+
);
|
|
1767
|
+
const presentationDefinition = {
|
|
1768
|
+
input_descriptors: samplePresentationDefinition.input_descriptors,
|
|
1769
|
+
submission_requirements: submissionRequirements,
|
|
1770
|
+
};
|
|
1771
|
+
const payload = {
|
|
1772
|
+
..._.omit(
|
|
1773
|
+
['tenantId'],
|
|
1774
|
+
await newDisclosure({
|
|
1775
|
+
tenant,
|
|
1776
|
+
presentationDefinition,
|
|
1777
|
+
})
|
|
1778
|
+
),
|
|
1779
|
+
};
|
|
1780
|
+
const response = await fastify.injectJson({
|
|
1781
|
+
method: 'POST',
|
|
1782
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1783
|
+
payload,
|
|
1784
|
+
headers: {
|
|
1785
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1786
|
+
},
|
|
1787
|
+
});
|
|
1788
|
+
|
|
1789
|
+
expect(response.statusCode).toEqual(400);
|
|
1790
|
+
expect(response.json).toEqual(
|
|
1791
|
+
errorResponseMatcher({
|
|
1792
|
+
error: 'Bad Request',
|
|
1793
|
+
errorCode: 'request_validation_failed',
|
|
1794
|
+
message:
|
|
1795
|
+
"body/presentationDefinition/submission_requirements/0 must have required property 'rule'",
|
|
1796
|
+
statusCode: 400,
|
|
1797
|
+
})
|
|
1798
|
+
);
|
|
1799
|
+
});
|
|
1800
|
+
|
|
1801
|
+
it('should 400 when submission_requirements.*.from is missing', async () => {
|
|
1802
|
+
const submissionRequirements = _.map(
|
|
1803
|
+
_.omit(['from']),
|
|
1804
|
+
samplePresentationDefinition.submission_requirements
|
|
1805
|
+
);
|
|
1806
|
+
const presentationDefinition = {
|
|
1807
|
+
input_descriptors: samplePresentationDefinition.input_descriptors,
|
|
1808
|
+
submission_requirements: submissionRequirements,
|
|
1809
|
+
};
|
|
1810
|
+
const payload = {
|
|
1811
|
+
..._.omit(
|
|
1812
|
+
['tenantId'],
|
|
1813
|
+
await newDisclosure({
|
|
1814
|
+
tenant,
|
|
1815
|
+
presentationDefinition,
|
|
1816
|
+
})
|
|
1817
|
+
),
|
|
1818
|
+
};
|
|
1819
|
+
const response = await fastify.injectJson({
|
|
1820
|
+
method: 'POST',
|
|
1821
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1822
|
+
payload,
|
|
1823
|
+
headers: {
|
|
1824
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1825
|
+
},
|
|
1826
|
+
});
|
|
1827
|
+
|
|
1828
|
+
expect(response.statusCode).toEqual(400);
|
|
1829
|
+
expect(response.json).toEqual(
|
|
1830
|
+
errorResponseMatcher({
|
|
1831
|
+
error: 'Bad Request',
|
|
1832
|
+
errorCode: 'request_validation_failed',
|
|
1833
|
+
message:
|
|
1834
|
+
// eslint-disable-next-line max-len
|
|
1835
|
+
"body/presentationDefinition/submission_requirements/0 must have required property 'from'",
|
|
1836
|
+
statusCode: 400,
|
|
1837
|
+
})
|
|
1838
|
+
);
|
|
1839
|
+
});
|
|
1840
|
+
|
|
1841
|
+
it('should 200 and strip presentationDefinition.foo property', async () => {
|
|
1842
|
+
const presentationDefinition = {
|
|
1843
|
+
...samplePresentationDefinition,
|
|
1844
|
+
foo: 'foo',
|
|
1845
|
+
};
|
|
1846
|
+
const payload = {
|
|
1847
|
+
..._.omit(
|
|
1848
|
+
['tenantId'],
|
|
1849
|
+
await newDisclosure({
|
|
1850
|
+
tenant,
|
|
1851
|
+
presentationDefinition,
|
|
1852
|
+
})
|
|
1853
|
+
),
|
|
1854
|
+
};
|
|
1855
|
+
const response = await fastify.injectJson({
|
|
1856
|
+
method: 'POST',
|
|
1857
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1858
|
+
payload,
|
|
1859
|
+
headers: {
|
|
1860
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1861
|
+
},
|
|
1862
|
+
});
|
|
1863
|
+
|
|
1864
|
+
expect(response.statusCode).toEqual(201);
|
|
1865
|
+
expect(response.json).toEqual({
|
|
1866
|
+
..._.omit(['presentationDefinition.foo'], payload),
|
|
1867
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1868
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1869
|
+
feed: false,
|
|
1870
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1871
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1872
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1873
|
+
});
|
|
1874
|
+
});
|
|
1875
|
+
|
|
1876
|
+
it('should 200 and strip presentationDefinition.id when present', async () => {
|
|
1877
|
+
const presentationDefinition = {
|
|
1878
|
+
...samplePresentationDefinition,
|
|
1879
|
+
id: 'fooId',
|
|
1880
|
+
};
|
|
1881
|
+
const payload = {
|
|
1882
|
+
..._.omit(
|
|
1883
|
+
['tenantId'],
|
|
1884
|
+
await newDisclosure({
|
|
1885
|
+
tenant,
|
|
1886
|
+
presentationDefinition,
|
|
1887
|
+
})
|
|
1888
|
+
),
|
|
1889
|
+
};
|
|
1890
|
+
const response = await fastify.injectJson({
|
|
1891
|
+
method: 'POST',
|
|
1892
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1893
|
+
payload,
|
|
1894
|
+
headers: {
|
|
1895
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1896
|
+
},
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1899
|
+
expect(response.statusCode).toEqual(201);
|
|
1900
|
+
expect(response.json).toEqual({
|
|
1901
|
+
..._.omit(['presentationDefinition.id'], payload),
|
|
1902
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1903
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1904
|
+
feed: false,
|
|
1905
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1906
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1907
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1908
|
+
});
|
|
1909
|
+
});
|
|
1910
|
+
|
|
1911
|
+
it('should 200 and strip presentationDefinition.format when present', async () => {
|
|
1912
|
+
const presentationDefinition = {
|
|
1913
|
+
...samplePresentationDefinition,
|
|
1914
|
+
format: 'format',
|
|
1915
|
+
};
|
|
1916
|
+
const payload = {
|
|
1917
|
+
..._.omit(
|
|
1918
|
+
['tenantId'],
|
|
1919
|
+
await newDisclosure({
|
|
1920
|
+
tenant,
|
|
1921
|
+
presentationDefinition,
|
|
1922
|
+
})
|
|
1923
|
+
),
|
|
1924
|
+
};
|
|
1925
|
+
const response = await fastify.injectJson({
|
|
1926
|
+
method: 'POST',
|
|
1927
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1928
|
+
payload,
|
|
1929
|
+
headers: {
|
|
1930
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1931
|
+
},
|
|
1932
|
+
});
|
|
1933
|
+
|
|
1934
|
+
expect(response.statusCode).toEqual(201);
|
|
1935
|
+
expect(response.json).toEqual({
|
|
1936
|
+
..._.omit(['presentationDefinition.format'], payload),
|
|
1937
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1938
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1939
|
+
feed: false,
|
|
1940
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1941
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1942
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1943
|
+
});
|
|
1944
|
+
});
|
|
1945
|
+
|
|
1946
|
+
it('should 200 and strip input_descriptors.*.foo property', async () => {
|
|
1947
|
+
const presentationDefinition = {
|
|
1948
|
+
...samplePresentationDefinition,
|
|
1949
|
+
input_descriptors: _.map(
|
|
1950
|
+
_.set('foo', 'foo'),
|
|
1951
|
+
samplePresentationDefinition.input_descriptors
|
|
1952
|
+
),
|
|
1953
|
+
};
|
|
1954
|
+
const payload = {
|
|
1955
|
+
..._.omit(
|
|
1956
|
+
['tenantId'],
|
|
1957
|
+
await newDisclosure({
|
|
1958
|
+
tenant,
|
|
1959
|
+
presentationDefinition,
|
|
1960
|
+
})
|
|
1961
|
+
),
|
|
1962
|
+
};
|
|
1963
|
+
const response = await fastify.injectJson({
|
|
1964
|
+
method: 'POST',
|
|
1965
|
+
url: `${disclosureUrl(tenant)}`,
|
|
1966
|
+
payload,
|
|
1967
|
+
headers: {
|
|
1968
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
1969
|
+
},
|
|
1970
|
+
});
|
|
1971
|
+
|
|
1972
|
+
expect(response.statusCode).toEqual(201);
|
|
1973
|
+
expect(response.json).toEqual({
|
|
1974
|
+
..._.omit(
|
|
1975
|
+
[
|
|
1976
|
+
'presentationDefinition.input_descriptors[0].foo',
|
|
1977
|
+
'presentationDefinition.input_descriptors[1].foo',
|
|
1978
|
+
'presentationDefinition.input_descriptors[2].foo',
|
|
1979
|
+
],
|
|
1980
|
+
payload
|
|
1981
|
+
),
|
|
1982
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
1983
|
+
identificationMethods: ['verifiable_presentation'],
|
|
1984
|
+
feed: false,
|
|
1985
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1986
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1987
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
1988
|
+
});
|
|
1989
|
+
});
|
|
1990
|
+
|
|
1991
|
+
it('should 200 and strip presentationDefinition.input_descriptors.*.format when present', async () => {
|
|
1992
|
+
const presentationDefinition = {
|
|
1993
|
+
...samplePresentationDefinition,
|
|
1994
|
+
input_descriptors: _.map(
|
|
1995
|
+
_.set('format', 'fooFormat'),
|
|
1996
|
+
samplePresentationDefinition.input_descriptors
|
|
1997
|
+
),
|
|
1998
|
+
};
|
|
1999
|
+
const payload = {
|
|
2000
|
+
..._.omit(
|
|
2001
|
+
['tenantId'],
|
|
2002
|
+
await newDisclosure({
|
|
2003
|
+
tenant,
|
|
2004
|
+
presentationDefinition,
|
|
2005
|
+
})
|
|
2006
|
+
),
|
|
2007
|
+
};
|
|
2008
|
+
const response = await fastify.injectJson({
|
|
2009
|
+
method: 'POST',
|
|
2010
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2011
|
+
payload,
|
|
2012
|
+
headers: {
|
|
2013
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2014
|
+
},
|
|
2015
|
+
});
|
|
2016
|
+
|
|
2017
|
+
expect(response.statusCode).toEqual(201);
|
|
2018
|
+
expect(response.json).toEqual({
|
|
2019
|
+
..._.omit(
|
|
2020
|
+
[
|
|
2021
|
+
'presentationDefinition.input_descriptors[0].format',
|
|
2022
|
+
'presentationDefinition.input_descriptors[1].format',
|
|
2023
|
+
'presentationDefinition.input_descriptors[2].format',
|
|
2024
|
+
],
|
|
2025
|
+
payload
|
|
2026
|
+
),
|
|
2027
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2028
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2029
|
+
feed: false,
|
|
2030
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2031
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2032
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2033
|
+
});
|
|
2034
|
+
});
|
|
2035
|
+
|
|
2036
|
+
it('should 200 and allow empty submission_requirements', async () => {
|
|
2037
|
+
const presentationDefinition = {
|
|
2038
|
+
...samplePresentationDefinition,
|
|
2039
|
+
submission_requirements: [],
|
|
2040
|
+
};
|
|
2041
|
+
const payload = {
|
|
2042
|
+
..._.omit(
|
|
2043
|
+
['tenantId'],
|
|
2044
|
+
await newDisclosure({
|
|
2045
|
+
tenant,
|
|
2046
|
+
presentationDefinition,
|
|
2047
|
+
})
|
|
2048
|
+
),
|
|
2049
|
+
};
|
|
2050
|
+
const response = await fastify.injectJson({
|
|
2051
|
+
method: 'POST',
|
|
2052
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2053
|
+
payload,
|
|
2054
|
+
headers: {
|
|
2055
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2056
|
+
},
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
expect(response.statusCode).toEqual(201);
|
|
2060
|
+
expect(response.json).toEqual({
|
|
2061
|
+
..._.omit(
|
|
2062
|
+
['presentationDefinition.submission_requirements[0].foo'],
|
|
2063
|
+
payload
|
|
2064
|
+
),
|
|
2065
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2066
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2067
|
+
feed: false,
|
|
2068
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2069
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2070
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2071
|
+
});
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
it('should 200 and if submission_requirements is not supplied', async () => {
|
|
2075
|
+
const presentationDefinition = {
|
|
2076
|
+
..._.omit(['submission_requirements'], samplePresentationDefinition),
|
|
2077
|
+
};
|
|
2078
|
+
const payload = {
|
|
2079
|
+
..._.omit(
|
|
2080
|
+
['tenantId'],
|
|
2081
|
+
await newDisclosure({
|
|
2082
|
+
tenant,
|
|
2083
|
+
presentationDefinition,
|
|
2084
|
+
})
|
|
2085
|
+
),
|
|
2086
|
+
};
|
|
2087
|
+
const response = await fastify.injectJson({
|
|
2088
|
+
method: 'POST',
|
|
2089
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2090
|
+
payload,
|
|
2091
|
+
headers: {
|
|
2092
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2093
|
+
},
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
expect(response.statusCode).toEqual(201);
|
|
2097
|
+
expect(response.json).toEqual({
|
|
2098
|
+
..._.omit(
|
|
2099
|
+
['presentationDefinition.submission_requirements[0].foo'],
|
|
2100
|
+
payload
|
|
2101
|
+
),
|
|
2102
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2103
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2104
|
+
feed: false,
|
|
2105
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2106
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2107
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2108
|
+
});
|
|
2109
|
+
});
|
|
2110
|
+
|
|
2111
|
+
it('should 200 and strip submission_requirements.*.foo property', async () => {
|
|
2112
|
+
const presentationDefinition = {
|
|
2113
|
+
...samplePresentationDefinition,
|
|
2114
|
+
submission_requirements: _.map(
|
|
2115
|
+
_.set('foo', 'foo'),
|
|
2116
|
+
samplePresentationDefinition.submission_requirements
|
|
2117
|
+
),
|
|
2118
|
+
};
|
|
2119
|
+
const payload = {
|
|
2120
|
+
..._.omit(
|
|
2121
|
+
['tenantId'],
|
|
2122
|
+
await newDisclosure({
|
|
2123
|
+
tenant,
|
|
2124
|
+
presentationDefinition,
|
|
2125
|
+
})
|
|
2126
|
+
),
|
|
2127
|
+
};
|
|
2128
|
+
const response = await fastify.injectJson({
|
|
2129
|
+
method: 'POST',
|
|
2130
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2131
|
+
payload,
|
|
2132
|
+
headers: {
|
|
2133
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2134
|
+
},
|
|
2135
|
+
});
|
|
2136
|
+
|
|
2137
|
+
expect(response.statusCode).toEqual(201);
|
|
2138
|
+
expect(response.json).toEqual({
|
|
2139
|
+
..._.omit(
|
|
2140
|
+
['presentationDefinition.submission_requirements[0].foo'],
|
|
2141
|
+
payload
|
|
2142
|
+
),
|
|
2143
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2144
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2145
|
+
feed: false,
|
|
2146
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2147
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2148
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2149
|
+
});
|
|
2150
|
+
});
|
|
2151
|
+
|
|
2152
|
+
it('should 200 and strip submission_requirements.*.from_nested property', async () => {
|
|
2153
|
+
const presentationDefinition = {
|
|
2154
|
+
...samplePresentationDefinition,
|
|
2155
|
+
submission_requirements: _.map(
|
|
2156
|
+
_.set('from_nested', 'foo'),
|
|
2157
|
+
samplePresentationDefinition.submission_requirements
|
|
2158
|
+
),
|
|
2159
|
+
};
|
|
2160
|
+
const payload = {
|
|
2161
|
+
..._.omit(
|
|
2162
|
+
['tenantId'],
|
|
2163
|
+
await newDisclosure({
|
|
2164
|
+
tenant,
|
|
2165
|
+
presentationDefinition,
|
|
2166
|
+
})
|
|
2167
|
+
),
|
|
2168
|
+
};
|
|
2169
|
+
const response = await fastify.injectJson({
|
|
2170
|
+
method: 'POST',
|
|
2171
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2172
|
+
payload,
|
|
2173
|
+
headers: {
|
|
2174
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2175
|
+
},
|
|
2176
|
+
});
|
|
2177
|
+
|
|
2178
|
+
expect(response.statusCode).toEqual(201);
|
|
2179
|
+
expect(response.json).toEqual({
|
|
2180
|
+
..._.omit(
|
|
2181
|
+
['presentationDefinition.submission_requirements[0].from_nested'],
|
|
2182
|
+
payload
|
|
2183
|
+
),
|
|
2184
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2185
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2186
|
+
feed: false,
|
|
2187
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2188
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2189
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2190
|
+
});
|
|
2191
|
+
});
|
|
2192
|
+
});
|
|
2193
|
+
|
|
2194
|
+
it('should create the disclosure', async () => {
|
|
2195
|
+
const payload = _.omit(['tenantId'], await newDisclosure({ tenant }));
|
|
2196
|
+
const response = await fastify.injectJson({
|
|
2197
|
+
method: 'POST',
|
|
2198
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2199
|
+
payload: {
|
|
2200
|
+
...payload,
|
|
2201
|
+
authTokensExpireIn: 1440,
|
|
2202
|
+
},
|
|
2203
|
+
headers: {
|
|
2204
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2205
|
+
},
|
|
2206
|
+
});
|
|
2207
|
+
|
|
2208
|
+
expect(response.statusCode).toEqual(201);
|
|
2209
|
+
expect(response.json.authTokensExpireIn).toEqual(1440);
|
|
2210
|
+
|
|
2211
|
+
const dbResult = await mongoDb()
|
|
2212
|
+
.collection('disclosures')
|
|
2213
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
2214
|
+
expect(dbResult.authTokensExpireIn).toEqual(1440);
|
|
2215
|
+
});
|
|
2216
|
+
});
|
|
2217
|
+
|
|
2218
|
+
describe('Disclosure Update Test Suite', () => {
|
|
2219
|
+
describe('Update Disclosure - Common Missing Required Properties', () => {
|
|
2220
|
+
it('should 404 if tenant doesnt match', async () => {
|
|
2221
|
+
const updatePayload = {
|
|
2222
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosures.a),
|
|
2223
|
+
description: 'update test',
|
|
2224
|
+
};
|
|
2225
|
+
const response = await fastify.injectJson({
|
|
2226
|
+
method: 'PUT',
|
|
2227
|
+
url: `${disclosureUrl(altTenant)}/${disclosures.a._id}`,
|
|
2228
|
+
payload: updatePayload,
|
|
2229
|
+
});
|
|
2230
|
+
expect(response.statusCode).toEqual(404);
|
|
2231
|
+
});
|
|
2232
|
+
|
|
2233
|
+
it('should 404 and not update if not found error', async () => {
|
|
2234
|
+
const response = await fastify.injectJson({
|
|
2235
|
+
method: 'PUT',
|
|
2236
|
+
url: `${disclosureUrl(tenant)}/${new ObjectId()}`,
|
|
2237
|
+
payload: await newDisclosure(),
|
|
2238
|
+
});
|
|
2239
|
+
expect(response.statusCode).toEqual(404);
|
|
2240
|
+
});
|
|
2241
|
+
|
|
2242
|
+
it('should 400 with invalid configuration type', async () => {
|
|
2243
|
+
const updatePayload = {
|
|
2244
|
+
..._.omit(
|
|
2245
|
+
[
|
|
2246
|
+
'createdAt',
|
|
2247
|
+
'updatedAt',
|
|
2248
|
+
'_id',
|
|
2249
|
+
'configurationType',
|
|
2250
|
+
'vendorEndpoint',
|
|
2251
|
+
],
|
|
2252
|
+
disclosures.a
|
|
2253
|
+
),
|
|
2254
|
+
vendorEndpoint: VendorEndpoint.RECEIVE_APPLICANT,
|
|
2255
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2256
|
+
};
|
|
2257
|
+
|
|
2258
|
+
const response = await fastify.injectJson({
|
|
2259
|
+
method: 'PUT',
|
|
2260
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2261
|
+
payload: updatePayload,
|
|
2262
|
+
});
|
|
2263
|
+
expect(response.statusCode).toEqual(400);
|
|
2264
|
+
expect(response.json).toEqual(
|
|
2265
|
+
errorResponseMatcher({
|
|
2266
|
+
error: 'Bad Request',
|
|
2267
|
+
errorCode: 'disclosure_invalid',
|
|
2268
|
+
message: 'Disclosure configuration type invalid',
|
|
2269
|
+
statusCode: 400,
|
|
2270
|
+
})
|
|
2271
|
+
);
|
|
2272
|
+
});
|
|
2273
|
+
});
|
|
2274
|
+
|
|
2275
|
+
describe('Update Disclosure - Issuing Missing Required Properties', () => {
|
|
2276
|
+
it('should 400 with invalid offermode', async () => {
|
|
2277
|
+
const updatePayload = {
|
|
2278
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosures.a),
|
|
2279
|
+
offerMode: 'blabla',
|
|
2280
|
+
};
|
|
2281
|
+
|
|
2282
|
+
const response = await fastify.injectJson({
|
|
2283
|
+
method: 'PUT',
|
|
2284
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2285
|
+
payload: updatePayload,
|
|
2286
|
+
});
|
|
2287
|
+
expect(response.statusCode).toEqual(400);
|
|
2288
|
+
expect(response.json).toEqual(
|
|
2289
|
+
errorResponseMatcher({
|
|
2290
|
+
error: 'Bad Request',
|
|
2291
|
+
errorCode: 'request_validation_failed',
|
|
2292
|
+
message:
|
|
2293
|
+
'body/offerMode must be equal to one of the allowed values',
|
|
2294
|
+
statusCode: 400,
|
|
2295
|
+
})
|
|
2296
|
+
);
|
|
2297
|
+
});
|
|
2298
|
+
|
|
2299
|
+
it('should 400 when default disclosure type mismatch', async () => {
|
|
2300
|
+
const payload = _.omit(
|
|
2301
|
+
['tenantId'],
|
|
2302
|
+
await persistDisclosure({
|
|
2303
|
+
tenant,
|
|
2304
|
+
})
|
|
2305
|
+
);
|
|
2306
|
+
const response = await fastify.injectJson({
|
|
2307
|
+
method: 'POST',
|
|
2308
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2309
|
+
payload: {
|
|
2310
|
+
...payload,
|
|
2311
|
+
setIssuingDefault: true,
|
|
2312
|
+
},
|
|
2313
|
+
headers: {
|
|
2314
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2315
|
+
},
|
|
2316
|
+
});
|
|
2317
|
+
|
|
2318
|
+
expect(response.statusCode).toEqual(400);
|
|
2319
|
+
expect(response.json).toEqual(
|
|
2320
|
+
errorResponseMatcher({
|
|
2321
|
+
error: 'Bad Request',
|
|
2322
|
+
errorCode: 'issuing_default_not_compatible',
|
|
2323
|
+
message: 'The default disclosure cannot be of type "inspection"',
|
|
2324
|
+
statusCode: 400,
|
|
2325
|
+
})
|
|
2326
|
+
);
|
|
2327
|
+
});
|
|
2328
|
+
|
|
2329
|
+
it('should 400 when default disclosure not set', async () => {
|
|
2330
|
+
const payload = _.omit(
|
|
2331
|
+
['tenantId'],
|
|
2332
|
+
await newDisclosure({
|
|
2333
|
+
tenant,
|
|
2334
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
2335
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2336
|
+
offerMode: 'preloaded',
|
|
2337
|
+
})
|
|
2338
|
+
);
|
|
2339
|
+
const response = await fastify.injectJson({
|
|
2340
|
+
method: 'POST',
|
|
2341
|
+
url: `${disclosureUrl(tenant)}`,
|
|
2342
|
+
payload: {
|
|
2343
|
+
...payload,
|
|
2344
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2345
|
+
setIssuingDefault: false,
|
|
2346
|
+
},
|
|
2347
|
+
headers: {
|
|
2348
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2349
|
+
},
|
|
2350
|
+
});
|
|
2351
|
+
|
|
2352
|
+
expect(response.statusCode).toEqual(400);
|
|
2353
|
+
expect(response.json).toEqual(
|
|
2354
|
+
errorResponseMatcher({
|
|
2355
|
+
error: 'Bad Request',
|
|
2356
|
+
errorCode: 'first_issuing_configuration_must_be_default',
|
|
2357
|
+
message:
|
|
2358
|
+
'The first "issuing" configuration created must be set as the default.',
|
|
2359
|
+
statusCode: 400,
|
|
2360
|
+
})
|
|
2361
|
+
);
|
|
2362
|
+
});
|
|
2363
|
+
|
|
2364
|
+
it('should 400 when commercial entity does not match', async () => {
|
|
2365
|
+
const disclosure = await persistDisclosure({
|
|
2366
|
+
tenant,
|
|
2367
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2368
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2369
|
+
offerMode: 'preloaded',
|
|
2370
|
+
commercialEntityLogo,
|
|
2371
|
+
commercialEntityName,
|
|
2372
|
+
});
|
|
2373
|
+
const updatePayload = {
|
|
2374
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosure),
|
|
2375
|
+
commercialEntityLogo: 'https://www.xyz.com',
|
|
2376
|
+
};
|
|
2377
|
+
|
|
2378
|
+
const response = await fastify.injectJson({
|
|
2379
|
+
method: 'PUT',
|
|
2380
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2381
|
+
payload: {
|
|
2382
|
+
...updatePayload,
|
|
2383
|
+
setIssuingDefault: true,
|
|
2384
|
+
},
|
|
2385
|
+
});
|
|
2386
|
+
expect(response.statusCode).toEqual(400);
|
|
2387
|
+
expect(response.json).toEqual(
|
|
2388
|
+
errorResponseMatcher({
|
|
2389
|
+
error: 'Bad Request',
|
|
2390
|
+
errorCode: 'invalid_commercial_entity',
|
|
2391
|
+
message: 'Invalid commercial entity',
|
|
2392
|
+
statusCode: 400,
|
|
2393
|
+
})
|
|
2394
|
+
);
|
|
2395
|
+
expect(nockVP.isDone()).toBeTruthy();
|
|
2396
|
+
});
|
|
2397
|
+
|
|
2398
|
+
it('should update a disclosure with and set default disclosure to tenant', async () => {
|
|
2399
|
+
const disclosure = await persistDisclosure({
|
|
2400
|
+
tenant,
|
|
2401
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2402
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2403
|
+
offerMode: 'preloaded',
|
|
2404
|
+
});
|
|
2405
|
+
const updatePayload = {
|
|
2406
|
+
..._.omit(['createdAt', 'updatedAt', '_id', 'feed'], disclosure),
|
|
2407
|
+
description: 'update test',
|
|
2408
|
+
};
|
|
2409
|
+
|
|
2410
|
+
const response = await fastify.injectJson({
|
|
2411
|
+
method: 'PUT',
|
|
2412
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2413
|
+
payload: {
|
|
2414
|
+
...updatePayload,
|
|
2415
|
+
setIssuingDefault: true,
|
|
2416
|
+
},
|
|
2417
|
+
});
|
|
2418
|
+
expect(response.statusCode).toEqual(200);
|
|
2419
|
+
expect(response.json).toEqual({
|
|
2420
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2421
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2422
|
+
feed: false,
|
|
2423
|
+
createdAt: expect.any(String),
|
|
2424
|
+
updatedAt: expect.any(String),
|
|
2425
|
+
...updatePayload,
|
|
2426
|
+
});
|
|
2427
|
+
|
|
2428
|
+
const tenantDb = await tenantRepo.findOne({
|
|
2429
|
+
filter: {
|
|
2430
|
+
_id: new ObjectId(tenant._id),
|
|
2431
|
+
},
|
|
2432
|
+
});
|
|
2433
|
+
|
|
2434
|
+
expect(tenantDb.defaultIssuingDisclosureId.toString()).toEqual(
|
|
2435
|
+
disclosure._id
|
|
2436
|
+
);
|
|
2437
|
+
});
|
|
2438
|
+
|
|
2439
|
+
it('should update a disclosure commercial entity info', async () => {
|
|
2440
|
+
nock.cleanAll();
|
|
2441
|
+
const disclosure = await persistDisclosure({
|
|
2442
|
+
tenant,
|
|
2443
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2444
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2445
|
+
offerMode: 'preloaded',
|
|
2446
|
+
commercialEntityLogo: 'https://www.abc.com',
|
|
2447
|
+
commercialEntityName: 'ABC',
|
|
2448
|
+
});
|
|
2449
|
+
const updatePayload = {
|
|
2450
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosure),
|
|
2451
|
+
commercialEntityLogo: 'https://www.xyz.com',
|
|
2452
|
+
commercialEntityName: 'XYZ',
|
|
2453
|
+
};
|
|
2454
|
+
|
|
2455
|
+
nockVP = nockVerifiedProfile(tenant.did, {
|
|
2456
|
+
credentialSubject: {
|
|
2457
|
+
commercialEntities: [
|
|
2458
|
+
{
|
|
2459
|
+
logo: 'https://www.abc.com',
|
|
2460
|
+
name: 'ABC',
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
logo: 'https://www.xyz.com',
|
|
2464
|
+
name: 'XYZ',
|
|
2465
|
+
},
|
|
2466
|
+
],
|
|
2467
|
+
},
|
|
2468
|
+
});
|
|
2469
|
+
|
|
2470
|
+
const response = await fastify.injectJson({
|
|
2471
|
+
method: 'PUT',
|
|
2472
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2473
|
+
payload: {
|
|
2474
|
+
...updatePayload,
|
|
2475
|
+
setIssuingDefault: true,
|
|
2476
|
+
},
|
|
2477
|
+
});
|
|
2478
|
+
expect(response.statusCode).toEqual(200);
|
|
2479
|
+
expect(response.json).toEqual({
|
|
2480
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2481
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2482
|
+
feed: false,
|
|
2483
|
+
createdAt: expect.any(String),
|
|
2484
|
+
updatedAt: expect.any(String),
|
|
2485
|
+
...updatePayload,
|
|
2486
|
+
commercialEntityLogo: 'https://www.xyz.com',
|
|
2487
|
+
commercialEntityName: 'XYZ',
|
|
2488
|
+
});
|
|
2489
|
+
expect(nockVP.isDone()).toBeTruthy();
|
|
2490
|
+
});
|
|
2491
|
+
|
|
2492
|
+
it('should update a disclosure commercial entity info using cache', async () => {
|
|
2493
|
+
nock.cleanAll();
|
|
2494
|
+
const disclosure = await persistDisclosure({
|
|
2495
|
+
tenant,
|
|
2496
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2497
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2498
|
+
offerMode: 'preloaded',
|
|
2499
|
+
commercialEntityLogo: 'https://www.abc.com',
|
|
2500
|
+
commercialEntityName: 'ABC',
|
|
2501
|
+
});
|
|
2502
|
+
const updatePayload = {
|
|
2503
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosure),
|
|
2504
|
+
commercialEntityLogo: 'https://www.xyz.com',
|
|
2505
|
+
commercialEntityName: 'XYZ',
|
|
2506
|
+
};
|
|
2507
|
+
|
|
2508
|
+
// nock verified profile to return commercial entities only once
|
|
2509
|
+
nockVP = nock('http://oracle.localhost.test')
|
|
2510
|
+
.get(
|
|
2511
|
+
`/api/v0.6/organizations/${encodeURIComponent(
|
|
2512
|
+
tenant.did
|
|
2513
|
+
)}/verified-profile`
|
|
2514
|
+
)
|
|
2515
|
+
.reply(
|
|
2516
|
+
200,
|
|
2517
|
+
{
|
|
2518
|
+
credentialSubject: {
|
|
2519
|
+
commercialEntities: [
|
|
2520
|
+
{
|
|
2521
|
+
logo: 'https://www.abc.com',
|
|
2522
|
+
name: 'ABC',
|
|
2523
|
+
},
|
|
2524
|
+
{
|
|
2525
|
+
logo: 'https://www.fyn.com',
|
|
2526
|
+
name: 'FYN',
|
|
2527
|
+
},
|
|
2528
|
+
{
|
|
2529
|
+
logo: 'https://www.xyz.com',
|
|
2530
|
+
name: 'XYZ',
|
|
2531
|
+
},
|
|
2532
|
+
],
|
|
2533
|
+
},
|
|
2534
|
+
},
|
|
2535
|
+
{ 'cache-control': 'max-age=60' }
|
|
2536
|
+
);
|
|
2537
|
+
|
|
2538
|
+
const response = await fastify.injectJson({
|
|
2539
|
+
method: 'PUT',
|
|
2540
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2541
|
+
payload: {
|
|
2542
|
+
...updatePayload,
|
|
2543
|
+
setIssuingDefault: true,
|
|
2544
|
+
},
|
|
2545
|
+
});
|
|
2546
|
+
expect(response.statusCode).toEqual(200);
|
|
2547
|
+
expect(response.json).toEqual({
|
|
2548
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2549
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2550
|
+
feed: false,
|
|
2551
|
+
createdAt: expect.any(String),
|
|
2552
|
+
updatedAt: expect.any(String),
|
|
2553
|
+
...updatePayload,
|
|
2554
|
+
commercialEntityLogo: 'https://www.xyz.com',
|
|
2555
|
+
commercialEntityName: 'XYZ',
|
|
2556
|
+
});
|
|
2557
|
+
|
|
2558
|
+
const response2 = await fastify.injectJson({
|
|
2559
|
+
method: 'PUT',
|
|
2560
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2561
|
+
payload: {
|
|
2562
|
+
...updatePayload,
|
|
2563
|
+
commercialEntityLogo: 'https://www.fyn.com',
|
|
2564
|
+
commercialEntityName: 'FYN',
|
|
2565
|
+
setIssuingDefault: true,
|
|
2566
|
+
},
|
|
2567
|
+
});
|
|
2568
|
+
expect(response2.statusCode).toEqual(200);
|
|
2569
|
+
expect(response2.json).toEqual({
|
|
2570
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2571
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2572
|
+
createdAt: expect.any(String),
|
|
2573
|
+
updatedAt: expect.any(String),
|
|
2574
|
+
feed: false,
|
|
2575
|
+
...updatePayload,
|
|
2576
|
+
commercialEntityLogo: 'https://www.fyn.com',
|
|
2577
|
+
commercialEntityName: 'FYN',
|
|
2578
|
+
});
|
|
2579
|
+
|
|
2580
|
+
expect(nockVP.pendingMocks()).toEqual([]);
|
|
2581
|
+
});
|
|
2582
|
+
|
|
2583
|
+
it('should update a disclosure', async () => {
|
|
2584
|
+
fastify.overrides.reqConfig = (config) => ({
|
|
2585
|
+
...config,
|
|
2586
|
+
disclosureCredentialTypeRequired: false,
|
|
2587
|
+
});
|
|
2588
|
+
const updatePayload = {
|
|
2589
|
+
..._.omit(
|
|
2590
|
+
['createdAt', 'updatedAt', '_id', 'configurationType'],
|
|
2591
|
+
disclosures.a
|
|
2592
|
+
),
|
|
2593
|
+
description: 'update test',
|
|
2594
|
+
};
|
|
2595
|
+
const updatedDate = disclosures.a.updatedAt;
|
|
2596
|
+
expect(updatedDate).toBeDefined();
|
|
2597
|
+
|
|
2598
|
+
const response = await fastify.injectJson({
|
|
2599
|
+
method: 'PUT',
|
|
2600
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2601
|
+
payload: updatePayload,
|
|
2602
|
+
});
|
|
2603
|
+
expect(response.statusCode).toEqual(200);
|
|
2604
|
+
expect(response.json).toEqual({
|
|
2605
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2606
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2607
|
+
feed: false,
|
|
2608
|
+
createdAt: disclosures.a.createdAt,
|
|
2609
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2610
|
+
configurationType: 'inspection',
|
|
2611
|
+
...updatePayload,
|
|
2612
|
+
});
|
|
2613
|
+
expect(updatedDate).not.toEqual(response.json.updatedAt);
|
|
2614
|
+
});
|
|
2615
|
+
|
|
2616
|
+
it('should not update a defaultIssuingDisclosureId for tenant if already updated', async () => {
|
|
2617
|
+
tenant = await persistTenant({
|
|
2618
|
+
defaultIssuingDisclosureId: new ObjectId(),
|
|
2619
|
+
});
|
|
2620
|
+
nockVerifiedProfile(tenant.did);
|
|
2621
|
+
const disclosure = await persistDisclosure({
|
|
2622
|
+
tenant,
|
|
2623
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2624
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2625
|
+
offerMode: 'preloaded',
|
|
2626
|
+
});
|
|
2627
|
+
const updatePayload = {
|
|
2628
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosure),
|
|
2629
|
+
description: 'update test',
|
|
2630
|
+
};
|
|
2631
|
+
|
|
2632
|
+
const response = await fastify.injectJson({
|
|
2633
|
+
method: 'PUT',
|
|
2634
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2635
|
+
payload: updatePayload,
|
|
2636
|
+
});
|
|
2637
|
+
expect(response.statusCode).toEqual(200);
|
|
2638
|
+
expect(response.json).toEqual({
|
|
2639
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2640
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2641
|
+
feed: false,
|
|
2642
|
+
createdAt: expect.any(String),
|
|
2643
|
+
updatedAt: expect.any(String),
|
|
2644
|
+
...updatePayload,
|
|
2645
|
+
});
|
|
2646
|
+
|
|
2647
|
+
const tenantDb = await tenantRepo.findOne({
|
|
2648
|
+
filter: {
|
|
2649
|
+
_id: new ObjectId(tenant._id),
|
|
2650
|
+
},
|
|
2651
|
+
});
|
|
2652
|
+
|
|
2653
|
+
expect(tenantDb.defaultIssuingDisclosureId.toString()).toEqual(
|
|
2654
|
+
tenant.defaultIssuingDisclosureId.toString()
|
|
2655
|
+
);
|
|
2656
|
+
});
|
|
2657
|
+
|
|
2658
|
+
it('should update a disclosure with offermode', async () => {
|
|
2659
|
+
const updatePayload = {
|
|
2660
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosures.a),
|
|
2661
|
+
offerMode: 'preloaded',
|
|
2662
|
+
};
|
|
2663
|
+
|
|
2664
|
+
const response = await fastify.injectJson({
|
|
2665
|
+
method: 'PUT',
|
|
2666
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2667
|
+
payload: updatePayload,
|
|
2668
|
+
});
|
|
2669
|
+
expect(response.statusCode).toEqual(200);
|
|
2670
|
+
expect(response.json).toEqual({
|
|
2671
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2672
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2673
|
+
feed: false,
|
|
2674
|
+
createdAt: disclosures.a.createdAt,
|
|
2675
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2676
|
+
...updatePayload,
|
|
2677
|
+
});
|
|
2678
|
+
});
|
|
2679
|
+
|
|
2680
|
+
it('should update a disclosure with `setIssuingDefault` and update tenant `defaultIssuingDisclosureId`', async () => {
|
|
2681
|
+
const disclosure1 = await persistDisclosure({
|
|
2682
|
+
tenant,
|
|
2683
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2684
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2685
|
+
});
|
|
2686
|
+
await mongoDb()
|
|
2687
|
+
.collection('tenants')
|
|
2688
|
+
.updateOne(
|
|
2689
|
+
{ _id: new ObjectId(tenant._id) },
|
|
2690
|
+
{
|
|
2691
|
+
$set: {
|
|
2692
|
+
defaultIssuingDisclosureId: new ObjectId(disclosure1._id),
|
|
2693
|
+
},
|
|
2694
|
+
}
|
|
2695
|
+
);
|
|
2696
|
+
const disclosure2 = await persistDisclosure({
|
|
2697
|
+
tenant,
|
|
2698
|
+
configurationType: ConfigurationType.ISSUING,
|
|
2699
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
2700
|
+
offerMode: 'preloaded',
|
|
2701
|
+
});
|
|
2702
|
+
const updatePayload = {
|
|
2703
|
+
..._.omit(['createdAt', 'updatedAt', '_id'], disclosure2),
|
|
2704
|
+
description: 'update test 2',
|
|
2705
|
+
};
|
|
2706
|
+
const tenantDb1 = await tenantRepo.findOne({
|
|
2707
|
+
filter: {
|
|
2708
|
+
_id: new ObjectId(tenant._id),
|
|
2709
|
+
},
|
|
2710
|
+
});
|
|
2711
|
+
expect(tenantDb1.defaultIssuingDisclosureId.toString()).toEqual(
|
|
2712
|
+
disclosure1._id
|
|
2713
|
+
);
|
|
2714
|
+
const response = await fastify.injectJson({
|
|
2715
|
+
method: 'PUT',
|
|
2716
|
+
url: `${disclosureUrl(tenant)}/${disclosure2._id}`,
|
|
2717
|
+
payload: {
|
|
2718
|
+
...updatePayload,
|
|
2719
|
+
setIssuingDefault: true,
|
|
2720
|
+
},
|
|
2721
|
+
});
|
|
2722
|
+
expect(response.statusCode).toEqual(200);
|
|
2723
|
+
expect(response.json).toEqual({
|
|
2724
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2725
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2726
|
+
feed: false,
|
|
2727
|
+
createdAt: expect.any(String),
|
|
2728
|
+
updatedAt: expect.any(String),
|
|
2729
|
+
...updatePayload,
|
|
2730
|
+
});
|
|
2731
|
+
|
|
2732
|
+
const tenantDb2 = await tenantRepo.findOne({
|
|
2733
|
+
filter: {
|
|
2734
|
+
_id: new ObjectId(tenant._id),
|
|
2735
|
+
},
|
|
2736
|
+
});
|
|
2737
|
+
|
|
2738
|
+
expect(tenantDb2.defaultIssuingDisclosureId.toString()).toEqual(
|
|
2739
|
+
disclosure2._id
|
|
2740
|
+
);
|
|
2741
|
+
});
|
|
2742
|
+
});
|
|
2743
|
+
|
|
2744
|
+
describe('Update Disclosure - Inspection Configuration', () => {
|
|
2745
|
+
it('should 400 if identificationMethods is set to [verifiable_presentation] and types is not passed', async () => {
|
|
2746
|
+
const disclosure = await persistDisclosure({
|
|
2747
|
+
tenant,
|
|
2748
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2749
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
2750
|
+
});
|
|
2751
|
+
const updatePayload = _.flow(
|
|
2752
|
+
_.omit(['createdAt', 'updatedAt', '_id', 'types'])
|
|
2753
|
+
)(disclosure);
|
|
2754
|
+
|
|
2755
|
+
const response = await fastify.injectJson({
|
|
2756
|
+
method: 'PUT',
|
|
2757
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2758
|
+
payload: {
|
|
2759
|
+
...updatePayload,
|
|
2760
|
+
types: [],
|
|
2761
|
+
},
|
|
2762
|
+
});
|
|
2763
|
+
expect(response.statusCode).toEqual(400);
|
|
2764
|
+
expect(response.json).toEqual(
|
|
2765
|
+
errorResponseMatcher({
|
|
2766
|
+
errorCode: 'request_validation_failed',
|
|
2767
|
+
statusCode: 400,
|
|
2768
|
+
error: 'Bad Request',
|
|
2769
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
2770
|
+
})
|
|
2771
|
+
);
|
|
2772
|
+
});
|
|
2773
|
+
|
|
2774
|
+
it('should 400 if identificationMethods is set to [verifiable_presentation] and empty types is passed', async () => {
|
|
2775
|
+
const updatePayload = _.flow(
|
|
2776
|
+
_.omit(['createdAt', 'updatedAt', '_id']),
|
|
2777
|
+
_.set('types', [])
|
|
2778
|
+
)(disclosures.a);
|
|
2779
|
+
|
|
2780
|
+
const response = await fastify.injectJson({
|
|
2781
|
+
method: 'PUT',
|
|
2782
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2783
|
+
payload: updatePayload,
|
|
2784
|
+
});
|
|
2785
|
+
expect(response.statusCode).toEqual(400);
|
|
2786
|
+
expect(response.json).toEqual(
|
|
2787
|
+
errorResponseMatcher({
|
|
2788
|
+
errorCode: 'request_validation_failed',
|
|
2789
|
+
statusCode: 400,
|
|
2790
|
+
error: 'Bad Request',
|
|
2791
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
2792
|
+
})
|
|
2793
|
+
);
|
|
2794
|
+
});
|
|
2795
|
+
|
|
2796
|
+
it('should 400 when missing duration', async () => {
|
|
2797
|
+
const payload = _.omit(
|
|
2798
|
+
['tenantId', 'duration'],
|
|
2799
|
+
await persistDisclosure({
|
|
2800
|
+
tenant,
|
|
2801
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
2802
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2803
|
+
vendorEndpoint: 'receive-applicant',
|
|
2804
|
+
})
|
|
2805
|
+
);
|
|
2806
|
+
const response = await fastify.injectJson({
|
|
2807
|
+
method: 'PUT',
|
|
2808
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
2809
|
+
payload: {
|
|
2810
|
+
...payload,
|
|
2811
|
+
duration: '',
|
|
2812
|
+
},
|
|
2813
|
+
headers: {
|
|
2814
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2815
|
+
},
|
|
2816
|
+
});
|
|
2817
|
+
|
|
2818
|
+
expect(response.statusCode).toEqual(400);
|
|
2819
|
+
expect(response.json).toEqual(
|
|
2820
|
+
errorResponseMatcher({
|
|
2821
|
+
error: 'Bad Request',
|
|
2822
|
+
errorCode: 'duration_required',
|
|
2823
|
+
message: 'Duration is required',
|
|
2824
|
+
statusCode: 400,
|
|
2825
|
+
})
|
|
2826
|
+
);
|
|
2827
|
+
});
|
|
2828
|
+
|
|
2829
|
+
it('should 400 when missing purpose', async () => {
|
|
2830
|
+
const payload = _.omit(
|
|
2831
|
+
['tenantId', 'purpose'],
|
|
2832
|
+
await persistDisclosure({
|
|
2833
|
+
tenant,
|
|
2834
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
2835
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2836
|
+
vendorEndpoint: 'receive-applicant',
|
|
2837
|
+
})
|
|
2838
|
+
);
|
|
2839
|
+
const response = await fastify.injectJson({
|
|
2840
|
+
method: 'PUT',
|
|
2841
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
2842
|
+
payload: {
|
|
2843
|
+
...payload,
|
|
2844
|
+
purpose: '',
|
|
2845
|
+
},
|
|
2846
|
+
headers: {
|
|
2847
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2848
|
+
},
|
|
2849
|
+
});
|
|
2850
|
+
|
|
2851
|
+
expect(response.statusCode).toEqual(400);
|
|
2852
|
+
expect(response.json).toEqual(
|
|
2853
|
+
errorResponseMatcher({
|
|
2854
|
+
error: 'Bad Request',
|
|
2855
|
+
errorCode: 'purpose_required',
|
|
2856
|
+
message: 'Purpose is required',
|
|
2857
|
+
statusCode: 400,
|
|
2858
|
+
})
|
|
2859
|
+
);
|
|
2860
|
+
});
|
|
2861
|
+
|
|
2862
|
+
it('should 400 when types is array of empty object', async () => {
|
|
2863
|
+
const payload = _.omit(
|
|
2864
|
+
['tenantId', 'types'],
|
|
2865
|
+
await persistDisclosure({
|
|
2866
|
+
tenant,
|
|
2867
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
2868
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2869
|
+
vendorEndpoint: 'receive-applicant',
|
|
2870
|
+
})
|
|
2871
|
+
);
|
|
2872
|
+
const response = await fastify.injectJson({
|
|
2873
|
+
method: 'PUT',
|
|
2874
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
2875
|
+
payload: {
|
|
2876
|
+
...payload,
|
|
2877
|
+
types: [{}],
|
|
2878
|
+
},
|
|
2879
|
+
headers: {
|
|
2880
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
2881
|
+
},
|
|
2882
|
+
});
|
|
2883
|
+
|
|
2884
|
+
expect(response.statusCode).toEqual(400);
|
|
2885
|
+
expect(response.json).toEqual(
|
|
2886
|
+
errorResponseMatcher({
|
|
2887
|
+
error: 'Bad Request',
|
|
2888
|
+
errorCode: 'request_validation_failed',
|
|
2889
|
+
message: "body should have required property 'types'",
|
|
2890
|
+
statusCode: 400,
|
|
2891
|
+
})
|
|
2892
|
+
);
|
|
2893
|
+
});
|
|
2894
|
+
|
|
2895
|
+
it('should 200 and update the disclosure with identificationMethods set to [verifiable_presentation]', async () => {
|
|
2896
|
+
const updatePayload = _.flow(
|
|
2897
|
+
_.omit(['createdAt', 'updatedAt', '_id']),
|
|
2898
|
+
_.set('identificationMethods', ['verifiable_presentation'])
|
|
2899
|
+
)(disclosures.a);
|
|
2900
|
+
|
|
2901
|
+
const response = await fastify.injectJson({
|
|
2902
|
+
method: 'PUT',
|
|
2903
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2904
|
+
payload: updatePayload,
|
|
2905
|
+
});
|
|
2906
|
+
|
|
2907
|
+
expect(response.statusCode).toEqual(200);
|
|
2908
|
+
expect(response.json).toEqual({
|
|
2909
|
+
...updatePayload,
|
|
2910
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2911
|
+
sendPushOnVerification: false,
|
|
2912
|
+
feed: false,
|
|
2913
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2914
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2915
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2916
|
+
});
|
|
2917
|
+
|
|
2918
|
+
const dbResult = await mongoDb()
|
|
2919
|
+
.collection('disclosures')
|
|
2920
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
2921
|
+
expect(mongoify(dbResult)).toEqual({
|
|
2922
|
+
...updatePayload,
|
|
2923
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2924
|
+
sendPushOnVerification: false,
|
|
2925
|
+
_id: new ObjectId(response.json.id),
|
|
2926
|
+
tenantId: new ObjectId(tenant._id),
|
|
2927
|
+
deactivationDate: expect.any(Date),
|
|
2928
|
+
createdAt: expect.any(Date),
|
|
2929
|
+
updatedAt: expect.any(Date),
|
|
2930
|
+
});
|
|
2931
|
+
});
|
|
2932
|
+
|
|
2933
|
+
it('should 200 and strip the feed property', async () => {
|
|
2934
|
+
const disclosure = await persistDisclosure({
|
|
2935
|
+
description: 'feedTrueTest',
|
|
2936
|
+
feed: true,
|
|
2937
|
+
tenant,
|
|
2938
|
+
});
|
|
2939
|
+
const updatePayload = _.flow(
|
|
2940
|
+
_.omit(['createdAt', 'updatedAt', '_id']),
|
|
2941
|
+
_.set('feed', false)
|
|
2942
|
+
)(disclosure);
|
|
2943
|
+
|
|
2944
|
+
const response = await fastify.injectJson({
|
|
2945
|
+
method: 'PUT',
|
|
2946
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
2947
|
+
payload: updatePayload,
|
|
2948
|
+
});
|
|
2949
|
+
|
|
2950
|
+
expect(response.statusCode).toEqual(200);
|
|
2951
|
+
expect(response.json).toEqual({
|
|
2952
|
+
...updatePayload,
|
|
2953
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2954
|
+
sendPushOnVerification: false,
|
|
2955
|
+
feed: true,
|
|
2956
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
2957
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2958
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
2959
|
+
});
|
|
2960
|
+
|
|
2961
|
+
const dbResult = await mongoDb()
|
|
2962
|
+
.collection('disclosures')
|
|
2963
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
2964
|
+
expect(mongoify(dbResult)).toEqual({
|
|
2965
|
+
...updatePayload,
|
|
2966
|
+
feed: true,
|
|
2967
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2968
|
+
sendPushOnVerification: false,
|
|
2969
|
+
_id: new ObjectId(response.json.id),
|
|
2970
|
+
tenantId: new ObjectId(tenant._id),
|
|
2971
|
+
deactivationDate: expect.any(Date),
|
|
2972
|
+
createdAt: expect.any(Date),
|
|
2973
|
+
updatedAt: expect.any(Date),
|
|
2974
|
+
});
|
|
2975
|
+
});
|
|
2976
|
+
});
|
|
2977
|
+
|
|
2978
|
+
describe('Update Disclosure - Issuing + VP Identification Method', () => {
|
|
2979
|
+
it('should 400 if identificationMethods is set to [verifiable_presentation] and types is not passed', async () => {
|
|
2980
|
+
const disclosure = await persistDisclosure({
|
|
2981
|
+
tenant,
|
|
2982
|
+
identificationMethods: ['verifiable_presentation'],
|
|
2983
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
2984
|
+
});
|
|
2985
|
+
const updatePayload = _.flow(
|
|
2986
|
+
_.omit(['createdAt', 'updatedAt', '_id', 'types'])
|
|
2987
|
+
)(disclosure);
|
|
2988
|
+
|
|
2989
|
+
const response = await fastify.injectJson({
|
|
2990
|
+
method: 'PUT',
|
|
2991
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
2992
|
+
payload: {
|
|
2993
|
+
...updatePayload,
|
|
2994
|
+
types: [],
|
|
2995
|
+
},
|
|
2996
|
+
});
|
|
2997
|
+
expect(response.statusCode).toEqual(400);
|
|
2998
|
+
expect(response.json).toEqual(
|
|
2999
|
+
errorResponseMatcher({
|
|
3000
|
+
errorCode: 'request_validation_failed',
|
|
3001
|
+
statusCode: 400,
|
|
3002
|
+
error: 'Bad Request',
|
|
3003
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
3004
|
+
})
|
|
3005
|
+
);
|
|
3006
|
+
});
|
|
3007
|
+
|
|
3008
|
+
it('should 400 if identificationMethods is set to [verifiable_presentation] and empty types is passed', async () => {
|
|
3009
|
+
const updatePayload = _.flow(
|
|
3010
|
+
_.omit(['createdAt', 'updatedAt', '_id']),
|
|
3011
|
+
_.set('types', [])
|
|
3012
|
+
)(disclosures.a);
|
|
3013
|
+
|
|
3014
|
+
const response = await fastify.injectJson({
|
|
3015
|
+
method: 'PUT',
|
|
3016
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
3017
|
+
payload: updatePayload,
|
|
3018
|
+
});
|
|
3019
|
+
expect(response.statusCode).toEqual(400);
|
|
3020
|
+
expect(response.json).toEqual(
|
|
3021
|
+
errorResponseMatcher({
|
|
3022
|
+
errorCode: 'request_validation_failed',
|
|
3023
|
+
statusCode: 400,
|
|
3024
|
+
error: 'Bad Request',
|
|
3025
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
3026
|
+
})
|
|
3027
|
+
);
|
|
3028
|
+
});
|
|
3029
|
+
|
|
3030
|
+
it('should 400 when missing duration', async () => {
|
|
3031
|
+
const payload = _.omit(
|
|
3032
|
+
['tenantId', 'duration'],
|
|
3033
|
+
await persistDisclosure({
|
|
3034
|
+
tenant,
|
|
3035
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
3036
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3037
|
+
vendorEndpoint: 'receive-applicant',
|
|
3038
|
+
})
|
|
3039
|
+
);
|
|
3040
|
+
const response = await fastify.injectJson({
|
|
3041
|
+
method: 'PUT',
|
|
3042
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
3043
|
+
payload: {
|
|
3044
|
+
...payload,
|
|
3045
|
+
duration: '',
|
|
3046
|
+
},
|
|
3047
|
+
headers: {
|
|
3048
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3049
|
+
},
|
|
3050
|
+
});
|
|
3051
|
+
|
|
3052
|
+
expect(response.statusCode).toEqual(400);
|
|
3053
|
+
expect(response.json).toEqual(
|
|
3054
|
+
errorResponseMatcher({
|
|
3055
|
+
error: 'Bad Request',
|
|
3056
|
+
errorCode: 'duration_required',
|
|
3057
|
+
message: 'Duration is required',
|
|
3058
|
+
statusCode: 400,
|
|
3059
|
+
})
|
|
3060
|
+
);
|
|
3061
|
+
});
|
|
3062
|
+
|
|
3063
|
+
it('should 400 when missing purpose', async () => {
|
|
3064
|
+
const payload = _.omit(
|
|
3065
|
+
['tenantId', 'purpose'],
|
|
3066
|
+
await persistDisclosure({
|
|
3067
|
+
tenant,
|
|
3068
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
3069
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3070
|
+
vendorEndpoint: 'receive-applicant',
|
|
3071
|
+
})
|
|
3072
|
+
);
|
|
3073
|
+
const response = await fastify.injectJson({
|
|
3074
|
+
method: 'PUT',
|
|
3075
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
3076
|
+
payload: {
|
|
3077
|
+
...payload,
|
|
3078
|
+
purpose: '',
|
|
3079
|
+
},
|
|
3080
|
+
headers: {
|
|
3081
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3082
|
+
},
|
|
3083
|
+
});
|
|
3084
|
+
|
|
3085
|
+
expect(response.statusCode).toEqual(400);
|
|
3086
|
+
expect(response.json).toEqual(
|
|
3087
|
+
errorResponseMatcher({
|
|
3088
|
+
error: 'Bad Request',
|
|
3089
|
+
errorCode: 'purpose_required',
|
|
3090
|
+
message: 'Purpose is required',
|
|
3091
|
+
statusCode: 400,
|
|
3092
|
+
})
|
|
3093
|
+
);
|
|
3094
|
+
});
|
|
3095
|
+
|
|
3096
|
+
it('should 400 when types is array of empty object', async () => {
|
|
3097
|
+
const payload = _.omit(
|
|
3098
|
+
['tenantId', 'types'],
|
|
3099
|
+
await persistDisclosure({
|
|
3100
|
+
tenant,
|
|
3101
|
+
configurationType: ConfigurationType.INSPECTION,
|
|
3102
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3103
|
+
vendorEndpoint: 'receive-applicant',
|
|
3104
|
+
})
|
|
3105
|
+
);
|
|
3106
|
+
const response = await fastify.injectJson({
|
|
3107
|
+
method: 'PUT',
|
|
3108
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
3109
|
+
payload: {
|
|
3110
|
+
...payload,
|
|
3111
|
+
types: [{}],
|
|
3112
|
+
},
|
|
3113
|
+
headers: {
|
|
3114
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3115
|
+
},
|
|
3116
|
+
});
|
|
3117
|
+
|
|
3118
|
+
expect(response.statusCode).toEqual(400);
|
|
3119
|
+
expect(response.json).toEqual(
|
|
3120
|
+
errorResponseMatcher({
|
|
3121
|
+
error: 'Bad Request',
|
|
3122
|
+
errorCode: 'request_validation_failed',
|
|
3123
|
+
message: "body should have required property 'types'",
|
|
3124
|
+
statusCode: 400,
|
|
3125
|
+
})
|
|
3126
|
+
);
|
|
3127
|
+
});
|
|
3128
|
+
|
|
3129
|
+
it('should 200 and update the disclosure with identificationMethods set to [verifiable_presentation]', async () => {
|
|
3130
|
+
const updatePayload = _.flow(
|
|
3131
|
+
_.omit(['createdAt', 'updatedAt', '_id']),
|
|
3132
|
+
_.set('identificationMethods', ['verifiable_presentation'])
|
|
3133
|
+
)(disclosures.a);
|
|
3134
|
+
|
|
3135
|
+
const response = await fastify.injectJson({
|
|
3136
|
+
method: 'PUT',
|
|
3137
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
3138
|
+
payload: updatePayload,
|
|
3139
|
+
});
|
|
3140
|
+
|
|
3141
|
+
expect(response.statusCode).toEqual(200);
|
|
3142
|
+
expect(response.json).toEqual({
|
|
3143
|
+
...updatePayload,
|
|
3144
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3145
|
+
sendPushOnVerification: false,
|
|
3146
|
+
feed: false,
|
|
3147
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
3148
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3149
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3150
|
+
});
|
|
3151
|
+
|
|
3152
|
+
const dbResult = await mongoDb()
|
|
3153
|
+
.collection('disclosures')
|
|
3154
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
3155
|
+
expect(mongoify(dbResult)).toEqual({
|
|
3156
|
+
...updatePayload,
|
|
3157
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3158
|
+
sendPushOnVerification: false,
|
|
3159
|
+
_id: new ObjectId(response.json.id),
|
|
3160
|
+
tenantId: new ObjectId(tenant._id),
|
|
3161
|
+
deactivationDate: expect.any(Date),
|
|
3162
|
+
createdAt: expect.any(Date),
|
|
3163
|
+
updatedAt: expect.any(Date),
|
|
3164
|
+
});
|
|
3165
|
+
});
|
|
3166
|
+
});
|
|
3167
|
+
|
|
3168
|
+
describe('Update Disclosure - Issuing + VP Identification Method + Integrated Issuing Identification', () => {
|
|
3169
|
+
it('should 400 and fail to create an integrated identity disclosure without "identityMatchers"', async () => {
|
|
3170
|
+
const payload = _.omit(
|
|
3171
|
+
['tenantId'],
|
|
3172
|
+
await persistDisclosure({
|
|
3173
|
+
tenant,
|
|
3174
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
3175
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3176
|
+
setIssuingDefault: true,
|
|
3177
|
+
})
|
|
3178
|
+
);
|
|
3179
|
+
const response = await fastify.injectJson({
|
|
3180
|
+
method: 'PUT',
|
|
3181
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
3182
|
+
payload,
|
|
3183
|
+
headers: {
|
|
3184
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3185
|
+
},
|
|
3186
|
+
});
|
|
3187
|
+
|
|
3188
|
+
expect(response.statusCode).toEqual(400);
|
|
3189
|
+
expect(response.json).toEqual(
|
|
3190
|
+
errorResponseMatcher({
|
|
3191
|
+
error: 'Bad Request',
|
|
3192
|
+
errorCode: 'request_validation_failed',
|
|
3193
|
+
message:
|
|
3194
|
+
'When using { "vendorEndpoint": "integrated-issuing-identification" } "identityMatchers" property is required',
|
|
3195
|
+
statusCode: 400,
|
|
3196
|
+
})
|
|
3197
|
+
);
|
|
3198
|
+
});
|
|
3199
|
+
|
|
3200
|
+
it('should create an integrated identity disclosure', async () => {
|
|
3201
|
+
const payload = _.omit(
|
|
3202
|
+
['tenantId'],
|
|
3203
|
+
await persistDisclosure({
|
|
3204
|
+
tenant,
|
|
3205
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
3206
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3207
|
+
types: [{ type: 'EmailV1.0' }],
|
|
3208
|
+
offerMode: 'preloaded',
|
|
3209
|
+
identityMatchers: {
|
|
3210
|
+
rules: [
|
|
3211
|
+
{
|
|
3212
|
+
valueIndex: 0, // used for identifying the value
|
|
3213
|
+
path: ['$.emails'], // jsonPath within the credential
|
|
3214
|
+
rule: 'pick', // Rule to execute can be pick, all (if the target is an array), equal (if the target is a singleValue)
|
|
3215
|
+
},
|
|
3216
|
+
],
|
|
3217
|
+
vendorUserIdIndex: 0,
|
|
3218
|
+
},
|
|
3219
|
+
})
|
|
3220
|
+
);
|
|
3221
|
+
const response = await fastify.injectJson({
|
|
3222
|
+
method: 'PUT',
|
|
3223
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
3224
|
+
payload: {
|
|
3225
|
+
..._.omit(['_id', 'createdAt', 'updatedAt'], payload),
|
|
3226
|
+
types: [{ type: 'EmailV1.0' }, { type: 'PhoneV1.0' }],
|
|
3227
|
+
},
|
|
3228
|
+
headers: {
|
|
3229
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3230
|
+
},
|
|
3231
|
+
});
|
|
3232
|
+
|
|
3233
|
+
expect(response.statusCode).toEqual(200);
|
|
3234
|
+
expect(response.json).toEqual({
|
|
3235
|
+
..._.omit(['_id'], payload),
|
|
3236
|
+
deactivationDate: expect.any(String),
|
|
3237
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3238
|
+
sendPushOnVerification: false,
|
|
3239
|
+
feed: false,
|
|
3240
|
+
types: [{ type: 'EmailV1.0' }, { type: 'PhoneV1.0' }],
|
|
3241
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
3242
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3243
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3244
|
+
});
|
|
3245
|
+
|
|
3246
|
+
const dbResult = await mongoDb()
|
|
3247
|
+
.collection('disclosures')
|
|
3248
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
3249
|
+
expect(mongoify(dbResult)).toEqual({
|
|
3250
|
+
..._.omit(['_id'], payload),
|
|
3251
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3252
|
+
sendPushOnVerification: false,
|
|
3253
|
+
_id: new ObjectId(response.json.id),
|
|
3254
|
+
tenantId: new ObjectId(tenant._id),
|
|
3255
|
+
types: [{ type: 'EmailV1.0' }, { type: 'PhoneV1.0' }],
|
|
3256
|
+
deactivationDate: expect.any(Date),
|
|
3257
|
+
createdAt: expect.any(Date),
|
|
3258
|
+
updatedAt: expect.any(Date),
|
|
3259
|
+
});
|
|
3260
|
+
});
|
|
3261
|
+
});
|
|
3262
|
+
|
|
3263
|
+
describe('Update Disclosure - Issuing + Preauth Identification Method', () => {
|
|
3264
|
+
it('should 400 if identificationMethods is set to [preauth] and types is passed', async () => {
|
|
3265
|
+
const updatePayload = _.flow(
|
|
3266
|
+
_.omit(['createdAt', 'updatedAt', '_id']),
|
|
3267
|
+
_.set('types', []),
|
|
3268
|
+
_.set('identificationMethods', ['preauth'])
|
|
3269
|
+
)(disclosures.a);
|
|
3270
|
+
|
|
3271
|
+
const response = await fastify.injectJson({
|
|
3272
|
+
method: 'PUT',
|
|
3273
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
3274
|
+
payload: updatePayload,
|
|
3275
|
+
});
|
|
3276
|
+
expect(response.statusCode).toEqual(400);
|
|
3277
|
+
expect(response.json).toEqual(
|
|
3278
|
+
errorResponseMatcher({
|
|
3279
|
+
errorCode: 'request_validation_failed',
|
|
3280
|
+
statusCode: 400,
|
|
3281
|
+
error: 'Bad Request',
|
|
3282
|
+
message: 'body/types must NOT have fewer than 1 items',
|
|
3283
|
+
})
|
|
3284
|
+
);
|
|
3285
|
+
});
|
|
3286
|
+
|
|
3287
|
+
it('should 400 if identificationMethods is set to [preauth] and types is passed', async () => {
|
|
3288
|
+
const payload = _.flow(_.omit(['tenantId']))(
|
|
3289
|
+
await persistDisclosure({
|
|
3290
|
+
tenant,
|
|
3291
|
+
identificationMethods: ['preauth'],
|
|
3292
|
+
})
|
|
3293
|
+
);
|
|
3294
|
+
const response = await fastify.injectJson({
|
|
3295
|
+
method: 'PUT',
|
|
3296
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
3297
|
+
payload: {
|
|
3298
|
+
...payload,
|
|
3299
|
+
types: [{ type: 'PastEmploymentPosition' }],
|
|
3300
|
+
},
|
|
3301
|
+
headers: {
|
|
3302
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3303
|
+
},
|
|
3304
|
+
});
|
|
3305
|
+
|
|
3306
|
+
expect(response.statusCode).toEqual(400);
|
|
3307
|
+
expect(response.json).toEqual(
|
|
3308
|
+
errorResponseMatcher({
|
|
3309
|
+
errorCode: 'request_validation_failed',
|
|
3310
|
+
statusCode: 400,
|
|
3311
|
+
error: 'Bad Request',
|
|
3312
|
+
message:
|
|
3313
|
+
"body may not have property 'types' when 'identificationMode' is set to 'preauth'",
|
|
3314
|
+
})
|
|
3315
|
+
);
|
|
3316
|
+
});
|
|
3317
|
+
|
|
3318
|
+
it('should 400 when identification methods has preauth and disclosure is default', async () => {
|
|
3319
|
+
const payload = _.omit(
|
|
3320
|
+
['tenantId', 'types'],
|
|
3321
|
+
await persistDisclosure({
|
|
3322
|
+
tenant,
|
|
3323
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3324
|
+
identificationMethods: ['preauth'],
|
|
3325
|
+
vendorEndpoint: 'issuing-identification',
|
|
3326
|
+
offerMode: 'preloaded',
|
|
3327
|
+
})
|
|
3328
|
+
);
|
|
3329
|
+
const response = await fastify.injectJson({
|
|
3330
|
+
method: 'PUT',
|
|
3331
|
+
url: `${disclosureUrl(tenant)}/${payload._id}`,
|
|
3332
|
+
payload: {
|
|
3333
|
+
...payload,
|
|
3334
|
+
setIssuingDefault: true,
|
|
3335
|
+
},
|
|
3336
|
+
headers: {
|
|
3337
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3338
|
+
},
|
|
3339
|
+
});
|
|
3340
|
+
|
|
3341
|
+
expect(response.statusCode).toEqual(400);
|
|
3342
|
+
expect(response.json).toEqual(
|
|
3343
|
+
errorResponseMatcher({
|
|
3344
|
+
error: 'Bad Request',
|
|
3345
|
+
errorCode: 'request_validation_failed',
|
|
3346
|
+
message:
|
|
3347
|
+
"body may not have property 'setIssuingDefault' when 'identificationMode' is set to 'preauth'",
|
|
3348
|
+
statusCode: 400,
|
|
3349
|
+
})
|
|
3350
|
+
);
|
|
3351
|
+
});
|
|
3352
|
+
|
|
3353
|
+
it('should 200 and update the disclosure with identificationMethods set to [preauth]', async () => {
|
|
3354
|
+
const preauthDisclosure = await persistDisclosure({
|
|
3355
|
+
tenant,
|
|
3356
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
3357
|
+
offerMode: 'preloaded',
|
|
3358
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3359
|
+
identificationMethods: ['preauth'],
|
|
3360
|
+
});
|
|
3361
|
+
const updatePayload = _.flow(
|
|
3362
|
+
_.omit(['createdAt', 'updatedAt', '_id', 'types'])
|
|
3363
|
+
)(preauthDisclosure);
|
|
3364
|
+
|
|
3365
|
+
const response = await fastify.injectJson({
|
|
3366
|
+
method: 'PUT',
|
|
3367
|
+
url: `${disclosureUrl(tenant)}/${preauthDisclosure._id}`,
|
|
3368
|
+
payload: updatePayload,
|
|
3369
|
+
});
|
|
3370
|
+
|
|
3371
|
+
expect(response.statusCode).toEqual(200);
|
|
3372
|
+
expect(response.json).toEqual({
|
|
3373
|
+
...updatePayload,
|
|
3374
|
+
identificationMethods: ['preauth'],
|
|
3375
|
+
sendPushOnVerification: false,
|
|
3376
|
+
feed: false,
|
|
3377
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
3378
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3379
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3380
|
+
});
|
|
3381
|
+
|
|
3382
|
+
const dbResult = await mongoDb()
|
|
3383
|
+
.collection('disclosures')
|
|
3384
|
+
.findOne({ _id: new ObjectId(response.json.id) });
|
|
3385
|
+
expect(mongoify(dbResult)).toEqual({
|
|
3386
|
+
...updatePayload,
|
|
3387
|
+
identificationMethods: ['preauth'],
|
|
3388
|
+
sendPushOnVerification: false,
|
|
3389
|
+
_id: new ObjectId(response.json.id),
|
|
3390
|
+
tenantId: new ObjectId(tenant._id),
|
|
3391
|
+
deactivationDate: expect.any(Date),
|
|
3392
|
+
createdAt: expect.any(Date),
|
|
3393
|
+
updatedAt: expect.any(Date),
|
|
3394
|
+
});
|
|
3395
|
+
});
|
|
3396
|
+
});
|
|
3397
|
+
|
|
3398
|
+
describe('Update Disclosure - Presentation Definition', () => {
|
|
3399
|
+
it('should 400 when presentationDefinition and types are present', async () => {
|
|
3400
|
+
const disclosure = await persistDisclosure({
|
|
3401
|
+
tenant,
|
|
3402
|
+
});
|
|
3403
|
+
const payload = {
|
|
3404
|
+
..._.omit(['_id', 'tenantId'], disclosure),
|
|
3405
|
+
presentationDefinition: samplePresentationDefinition,
|
|
3406
|
+
};
|
|
3407
|
+
const response = await fastify.injectJson({
|
|
3408
|
+
method: 'PUT',
|
|
3409
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
3410
|
+
payload,
|
|
3411
|
+
headers: {
|
|
3412
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3413
|
+
},
|
|
3414
|
+
});
|
|
3415
|
+
|
|
3416
|
+
expect(response.statusCode).toEqual(400);
|
|
3417
|
+
expect(response.json).toEqual(
|
|
3418
|
+
errorResponseMatcher({
|
|
3419
|
+
error: 'Bad Request',
|
|
3420
|
+
errorCode: 'request_validation_failed',
|
|
3421
|
+
message:
|
|
3422
|
+
"body may only have one property of 'types' or 'presentationDefinition'",
|
|
3423
|
+
statusCode: 400,
|
|
3424
|
+
})
|
|
3425
|
+
);
|
|
3426
|
+
});
|
|
3427
|
+
|
|
3428
|
+
it('should 200 and switch from types to presentationDefinition', async () => {
|
|
3429
|
+
const disclosure = await persistDisclosure({
|
|
3430
|
+
tenant,
|
|
3431
|
+
});
|
|
3432
|
+
const payload = {
|
|
3433
|
+
..._.omit(['_id', 'tenantId', 'types'], disclosure),
|
|
3434
|
+
presentationDefinition: samplePresentationDefinition,
|
|
3435
|
+
};
|
|
3436
|
+
const response = await fastify.injectJson({
|
|
3437
|
+
method: 'PUT',
|
|
3438
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
3439
|
+
payload,
|
|
3440
|
+
headers: {
|
|
3441
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3442
|
+
},
|
|
3443
|
+
});
|
|
3444
|
+
|
|
3445
|
+
expect(response.statusCode).toEqual(200);
|
|
3446
|
+
expect(response.json).toEqual({
|
|
3447
|
+
...payload,
|
|
3448
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
3449
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3450
|
+
feed: false,
|
|
3451
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3452
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3453
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3454
|
+
});
|
|
3455
|
+
|
|
3456
|
+
const updatedDisclosure = await mongoDb()
|
|
3457
|
+
.collection('disclosures')
|
|
3458
|
+
.findOne({ _id: new ObjectId(disclosure._id) });
|
|
3459
|
+
expect(mongoify(updatedDisclosure)).toEqual({
|
|
3460
|
+
...payload,
|
|
3461
|
+
_id: expect.any(ObjectId),
|
|
3462
|
+
tenantId: expect.any(ObjectId),
|
|
3463
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3464
|
+
deactivationDate: expect.any(Date),
|
|
3465
|
+
createdAt: expect.any(Date),
|
|
3466
|
+
updatedAt: expect.any(Date),
|
|
3467
|
+
});
|
|
3468
|
+
expect(updatedDisclosure.types).toBeUndefined();
|
|
3469
|
+
});
|
|
3470
|
+
|
|
3471
|
+
it('should 200 and switch from presentationDefinition to types', async () => {
|
|
3472
|
+
const disclosure = await persistDisclosure({
|
|
3473
|
+
tenant,
|
|
3474
|
+
presentationDefinition: samplePresentationDefinition,
|
|
3475
|
+
});
|
|
3476
|
+
const payload = {
|
|
3477
|
+
..._.omit(['_id', 'tenantId', 'presentationDefinition'], disclosure),
|
|
3478
|
+
types: [
|
|
3479
|
+
{ type: 'PastEmploymentPosition' },
|
|
3480
|
+
{ type: 'CurrentEmploymentPosition' },
|
|
3481
|
+
],
|
|
3482
|
+
};
|
|
3483
|
+
const response = await fastify.injectJson({
|
|
3484
|
+
method: 'PUT',
|
|
3485
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
3486
|
+
payload,
|
|
3487
|
+
headers: {
|
|
3488
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3489
|
+
},
|
|
3490
|
+
});
|
|
3491
|
+
|
|
3492
|
+
expect(response.statusCode).toEqual(200);
|
|
3493
|
+
expect(response.json).toEqual({
|
|
3494
|
+
...payload,
|
|
3495
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
3496
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3497
|
+
feed: false,
|
|
3498
|
+
deactivationDate: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3499
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3500
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
3501
|
+
});
|
|
3502
|
+
|
|
3503
|
+
const updatedDisclosure = await mongoDb()
|
|
3504
|
+
.collection('disclosures')
|
|
3505
|
+
.findOne({ _id: new ObjectId(disclosure._id) });
|
|
3506
|
+
expect(mongoify(updatedDisclosure)).toEqual({
|
|
3507
|
+
...payload,
|
|
3508
|
+
_id: expect.any(ObjectId),
|
|
3509
|
+
tenantId: expect.any(ObjectId),
|
|
3510
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3511
|
+
deactivationDate: expect.any(Date),
|
|
3512
|
+
createdAt: expect.any(Date),
|
|
3513
|
+
updatedAt: expect.any(Date),
|
|
3514
|
+
});
|
|
3515
|
+
expect(updatedDisclosure.presentationDefinition).toBeUndefined();
|
|
3516
|
+
});
|
|
3517
|
+
});
|
|
3518
|
+
});
|
|
3519
|
+
|
|
3520
|
+
describe('Disclosure Retrieval Test Suite', () => {
|
|
3521
|
+
it('should 404 for a missing but properly formatted disclosure id', async () => {
|
|
3522
|
+
const response = await fastify.injectJson({
|
|
3523
|
+
method: 'GET',
|
|
3524
|
+
url: `${disclosureUrl(tenant)}/${disclosures.c._id}`,
|
|
3525
|
+
});
|
|
3526
|
+
expect(response.statusCode).toEqual(404);
|
|
3527
|
+
});
|
|
3528
|
+
|
|
3529
|
+
it('should 404 for a malformatted disclosure', async () => {
|
|
3530
|
+
const response = await fastify.injectJson({
|
|
3531
|
+
method: 'GET',
|
|
3532
|
+
url: `${disclosureUrl(tenant)}/abc`,
|
|
3533
|
+
});
|
|
3534
|
+
expect(response.statusCode).toEqual(404);
|
|
3535
|
+
});
|
|
3536
|
+
|
|
3537
|
+
it('should get a particular disclosure with offerMode', async () => {
|
|
3538
|
+
const response = await fastify.injectJson({
|
|
3539
|
+
method: 'GET',
|
|
3540
|
+
url: `${disclosureUrl(tenant)}/${disclosures.d._id}`,
|
|
3541
|
+
});
|
|
3542
|
+
expect(response.statusCode).toEqual(200);
|
|
3543
|
+
expect(response.json).toEqual({
|
|
3544
|
+
createdAt: expect.any(String),
|
|
3545
|
+
description: 'withoffermode',
|
|
3546
|
+
duration: '6y',
|
|
3547
|
+
id: expect.any(String),
|
|
3548
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3549
|
+
offerMode: 'preloaded',
|
|
3550
|
+
purpose: 'Job Application',
|
|
3551
|
+
sendPushOnVerification: false,
|
|
3552
|
+
feed: false,
|
|
3553
|
+
termsUrl: 'https://www.lipsum.com/feed/html',
|
|
3554
|
+
types: [
|
|
3555
|
+
{ type: 'PastEmploymentPosition' },
|
|
3556
|
+
{ type: 'CurrentEmploymentPosition' },
|
|
3557
|
+
],
|
|
3558
|
+
updatedAt: expect.any(String),
|
|
3559
|
+
vendorDisclosureId: 'HR-PKG-USPS-CLRK',
|
|
3560
|
+
vendorEndpoint: 'receive-applicant',
|
|
3561
|
+
configurationType: 'inspection',
|
|
3562
|
+
deactivationDate: expect.any(String),
|
|
3563
|
+
authTokensExpireIn: 10080,
|
|
3564
|
+
});
|
|
3565
|
+
});
|
|
3566
|
+
|
|
3567
|
+
it('should get a particular disclosure', async () => {
|
|
3568
|
+
const disclosure = await persistDisclosure({
|
|
3569
|
+
tenant,
|
|
3570
|
+
presentationDefinition: samplePresentationDefinition,
|
|
3571
|
+
feed: true,
|
|
3572
|
+
});
|
|
3573
|
+
const response = await fastify.injectJson({
|
|
3574
|
+
method: 'GET',
|
|
3575
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
3576
|
+
});
|
|
3577
|
+
expect(response.statusCode).toEqual(200);
|
|
3578
|
+
expect(response.json).toEqual({
|
|
3579
|
+
id: disclosure._id,
|
|
3580
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3581
|
+
..._.omit(['_id'], disclosure),
|
|
3582
|
+
feed: true,
|
|
3583
|
+
});
|
|
3584
|
+
});
|
|
3585
|
+
|
|
3586
|
+
it('should not set disclosure as default for tenant if has only preauth identification method', async () => {
|
|
3587
|
+
await mongoDb().collection('disclosures').deleteMany({});
|
|
3588
|
+
|
|
3589
|
+
const disclosure = await persistDisclosure({
|
|
3590
|
+
identificationMethods: ['preauth'],
|
|
3591
|
+
configurationType: 'issuing',
|
|
3592
|
+
offerMode: 'webhook',
|
|
3593
|
+
vendorEndpoint: 'issuing-identification',
|
|
3594
|
+
tenant,
|
|
3595
|
+
});
|
|
3596
|
+
|
|
3597
|
+
expect(tenant.defaultIssuingDisclosureId).toBeUndefined();
|
|
3598
|
+
const response = await fastify.injectJson({
|
|
3599
|
+
method: 'GET',
|
|
3600
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
3601
|
+
});
|
|
3602
|
+
expect(response.statusCode).toEqual(200);
|
|
3603
|
+
|
|
3604
|
+
const tenantDb = await tenantRepo.findOne({
|
|
3605
|
+
filter: {
|
|
3606
|
+
_id: new ObjectId(tenant._id),
|
|
3607
|
+
},
|
|
3608
|
+
});
|
|
3609
|
+
|
|
3610
|
+
expect(tenantDb.defaultIssuingDisclosureId).toBeUndefined();
|
|
3611
|
+
});
|
|
3612
|
+
|
|
3613
|
+
it('should set disclosure as default for tenant if has apart from preauth identification method', async () => {
|
|
3614
|
+
await mongoDb().collection('disclosures').deleteMany({});
|
|
3615
|
+
|
|
3616
|
+
const disclosure = await persistDisclosure({
|
|
3617
|
+
identificationMethods: ['preauth', 'verifiable_presentation'],
|
|
3618
|
+
configurationType: 'issuing',
|
|
3619
|
+
offerMode: 'webhook',
|
|
3620
|
+
vendorEndpoint: 'issuing-identification',
|
|
3621
|
+
tenant,
|
|
3622
|
+
});
|
|
3623
|
+
|
|
3624
|
+
expect(tenant.defaultIssuingDisclosureId).toBeUndefined();
|
|
3625
|
+
const response = await fastify.injectJson({
|
|
3626
|
+
method: 'GET',
|
|
3627
|
+
url: `${disclosureUrl(tenant)}/${disclosure._id}`,
|
|
3628
|
+
});
|
|
3629
|
+
expect(response.statusCode).toEqual(200);
|
|
3630
|
+
|
|
3631
|
+
const tenantDb = await tenantRepo.findOne({
|
|
3632
|
+
filter: {
|
|
3633
|
+
_id: new ObjectId(tenant._id),
|
|
3634
|
+
},
|
|
3635
|
+
});
|
|
3636
|
+
|
|
3637
|
+
expect(tenantDb.defaultIssuingDisclosureId.toString()).toBe(
|
|
3638
|
+
disclosure._id.toString()
|
|
3639
|
+
);
|
|
3640
|
+
});
|
|
3641
|
+
|
|
3642
|
+
it('should update disclosure configuration type', async () => {
|
|
3643
|
+
const disclosure = await mongoDb()
|
|
3644
|
+
.collection('disclosures')
|
|
3645
|
+
.insertOne({
|
|
3646
|
+
description: 'Clerk',
|
|
3647
|
+
types: [
|
|
3648
|
+
{ type: 'PastEmploymentPosition' },
|
|
3649
|
+
{ type: 'CurrentEmploymentPosition' },
|
|
3650
|
+
],
|
|
3651
|
+
vendorEndpoint: VendorEndpoint.RECEIVE_APPLICANT,
|
|
3652
|
+
tenantId: new ObjectId(tenant._id),
|
|
3653
|
+
vendorDisclosureId: 'HR-PKG-USPS-CLRK',
|
|
3654
|
+
purpose: 'Job Application',
|
|
3655
|
+
duration: '6y',
|
|
3656
|
+
termsUrl: 'https://www.lipsum.com/feed/html',
|
|
3657
|
+
sendPushOnVerification: false,
|
|
3658
|
+
createdAt: new Date(),
|
|
3659
|
+
updatedAt: new Date(),
|
|
3660
|
+
});
|
|
3661
|
+
|
|
3662
|
+
const response = await fastify.injectJson({
|
|
3663
|
+
method: 'GET',
|
|
3664
|
+
url: `${disclosureUrl(tenant)}/${disclosure.insertedId.toString()}`,
|
|
3665
|
+
});
|
|
3666
|
+
expect(response.statusCode).toEqual(200);
|
|
3667
|
+
expect(response.json.id).toBe(disclosure.insertedId.toString());
|
|
3668
|
+
expect(response.json.configurationType).toEqual('inspection');
|
|
3669
|
+
});
|
|
3670
|
+
|
|
3671
|
+
it('should get a disclosures by one vendor endpoint', async () => {
|
|
3672
|
+
const disclosure = await persistDisclosure({
|
|
3673
|
+
description: 've-test',
|
|
3674
|
+
vendorEndpoint: 'receive-applicant-789',
|
|
3675
|
+
tenant,
|
|
3676
|
+
});
|
|
3677
|
+
const response = await fastify.injectJson({
|
|
3678
|
+
method: 'GET',
|
|
3679
|
+
url: `${disclosureUrl(tenant)}?vendorEndpoint=receive-applicant-789`,
|
|
3680
|
+
});
|
|
3681
|
+
expect(response.statusCode).toEqual(200);
|
|
3682
|
+
expect(response.json).toEqual([
|
|
3683
|
+
{
|
|
3684
|
+
id: disclosure._id,
|
|
3685
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3686
|
+
feed: false,
|
|
3687
|
+
..._.omit(['_id'], disclosure),
|
|
3688
|
+
},
|
|
3689
|
+
]);
|
|
3690
|
+
});
|
|
3691
|
+
|
|
3692
|
+
it('should get a disclosures by vendor endpoint list', async () => {
|
|
3693
|
+
const disclosure = await persistDisclosure({
|
|
3694
|
+
description: 've-test',
|
|
3695
|
+
vendorEndpoint: 'receive-applicant-789',
|
|
3696
|
+
tenant,
|
|
3697
|
+
});
|
|
3698
|
+
const disclosure2 = await persistDisclosure({
|
|
3699
|
+
description: 've-test',
|
|
3700
|
+
vendorEndpoint: 'mock',
|
|
3701
|
+
tenant,
|
|
3702
|
+
});
|
|
3703
|
+
const response = await fastify.injectJson({
|
|
3704
|
+
method: 'GET',
|
|
3705
|
+
url: `${disclosureUrl(
|
|
3706
|
+
tenant
|
|
3707
|
+
)}?vendorEndpoint=receive-applicant-789&vendorEndpoint=mock`,
|
|
3708
|
+
});
|
|
3709
|
+
expect(response.statusCode).toEqual(200);
|
|
3710
|
+
expect(response.json.length).toEqual(2);
|
|
3711
|
+
expect(response.json).toEqual(
|
|
3712
|
+
expect.arrayContaining([
|
|
3713
|
+
{
|
|
3714
|
+
id: disclosure2._id,
|
|
3715
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3716
|
+
feed: false,
|
|
3717
|
+
..._.omit(['_id'], disclosure2),
|
|
3718
|
+
},
|
|
3719
|
+
{
|
|
3720
|
+
id: disclosure._id,
|
|
3721
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3722
|
+
feed: false,
|
|
3723
|
+
..._.omit(['_id'], disclosure),
|
|
3724
|
+
},
|
|
3725
|
+
])
|
|
3726
|
+
);
|
|
3727
|
+
});
|
|
3728
|
+
|
|
3729
|
+
it('should get a particular disclosure without sendPushOnVerification', async () => {
|
|
3730
|
+
const oldFormatDisclosure = await persistDisclosure({
|
|
3731
|
+
tenant,
|
|
3732
|
+
});
|
|
3733
|
+
|
|
3734
|
+
await mongoDb()
|
|
3735
|
+
.collection('disclosures')
|
|
3736
|
+
.updateOne(
|
|
3737
|
+
{ _id: new ObjectId(oldFormatDisclosure._id) },
|
|
3738
|
+
{ $unset: { sendPushOnVerification: '' } }
|
|
3739
|
+
);
|
|
3740
|
+
|
|
3741
|
+
const response = await fastify.injectJson({
|
|
3742
|
+
method: 'GET',
|
|
3743
|
+
url: `${disclosureUrl(tenant)}/${oldFormatDisclosure._id}`,
|
|
3744
|
+
});
|
|
3745
|
+
expect(response.statusCode).toEqual(200);
|
|
3746
|
+
|
|
3747
|
+
expect(response.json).toEqual({
|
|
3748
|
+
id: oldFormatDisclosure._id,
|
|
3749
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3750
|
+
feed: false,
|
|
3751
|
+
..._.omit(['_id'], oldFormatDisclosure),
|
|
3752
|
+
});
|
|
3753
|
+
});
|
|
3754
|
+
|
|
3755
|
+
it('should get many disclosures', async () => {
|
|
3756
|
+
const response = await fastify.injectJson({
|
|
3757
|
+
method: 'GET',
|
|
3758
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3759
|
+
});
|
|
3760
|
+
expect(response.statusCode).toEqual(200);
|
|
3761
|
+
expect(response.json).toStrictEqual(
|
|
3762
|
+
expect.arrayContaining([
|
|
3763
|
+
{
|
|
3764
|
+
id: disclosures.d._id,
|
|
3765
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3766
|
+
feed: false,
|
|
3767
|
+
..._.omit(['_id'], disclosures.d),
|
|
3768
|
+
},
|
|
3769
|
+
{
|
|
3770
|
+
id: disclosures.e._id,
|
|
3771
|
+
identificationMethods: ['verifiable_presentation'],
|
|
3772
|
+
feed: false,
|
|
3773
|
+
..._.omit(['_id'], disclosures.e),
|
|
3774
|
+
},
|
|
3775
|
+
])
|
|
3776
|
+
);
|
|
3777
|
+
});
|
|
3778
|
+
});
|
|
3779
|
+
|
|
3780
|
+
describe('Disclosure QR code Test Suite', () => {
|
|
3781
|
+
it('should return a url for the qr-code', async () => {
|
|
3782
|
+
const payload = _.omit(['tenantId'], await newDisclosure({ tenant }));
|
|
3783
|
+
|
|
3784
|
+
const createResponse = await fastify.injectJson({
|
|
3785
|
+
method: 'POST',
|
|
3786
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3787
|
+
payload,
|
|
3788
|
+
});
|
|
3789
|
+
const urlEncodedDid = encodeURIComponent(tenant.did); // encodeURIComponent(tenant.did);
|
|
3790
|
+
|
|
3791
|
+
const response = await fastify.inject({
|
|
3792
|
+
method: 'GET',
|
|
3793
|
+
url: `${disclosureUrl(tenant)}/${createResponse.json.id}/qrcode.uri`,
|
|
3794
|
+
headers: {
|
|
3795
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3796
|
+
},
|
|
3797
|
+
});
|
|
3798
|
+
|
|
3799
|
+
expect(response.statusCode).toEqual(200);
|
|
3800
|
+
expect(response.body).toEqual(
|
|
3801
|
+
// eslint-disable-next-line max-len
|
|
3802
|
+
`velocity-test://inspect?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Finspect%2Fget-presentation-request%3Fid%3D${createResponse.json.id}&inspectorDid=${urlEncodedDid}`
|
|
3803
|
+
);
|
|
3804
|
+
});
|
|
3805
|
+
|
|
3806
|
+
it('should return a url for the qr-code with vendorOriginContext', async () => {
|
|
3807
|
+
const payload = _.omit(['tenantId'], await newDisclosure({ tenant }));
|
|
3808
|
+
const vendorOriginContext = 'abc123';
|
|
3809
|
+
|
|
3810
|
+
const createResponse = await fastify.injectJson({
|
|
3811
|
+
method: 'POST',
|
|
3812
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3813
|
+
payload,
|
|
3814
|
+
});
|
|
3815
|
+
|
|
3816
|
+
const response = await fastify.inject({
|
|
3817
|
+
method: 'GET',
|
|
3818
|
+
url: `${disclosureUrl(tenant)}/${
|
|
3819
|
+
createResponse.json.id
|
|
3820
|
+
}/qrcode.uri?vendorOriginContext=${vendorOriginContext}`,
|
|
3821
|
+
headers: {
|
|
3822
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3823
|
+
},
|
|
3824
|
+
});
|
|
3825
|
+
|
|
3826
|
+
expect(response.statusCode).toEqual(200);
|
|
3827
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
3828
|
+
expect(response.body).toEqual(
|
|
3829
|
+
// eslint-disable-next-line max-len
|
|
3830
|
+
`velocity-test://inspect?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Finspect%2Fget-presentation-request%3Fid%3D${createResponse.json.id}&inspectorDid=${urlEncodedDid}&vendorOriginContext=${vendorOriginContext}`
|
|
3831
|
+
);
|
|
3832
|
+
});
|
|
3833
|
+
|
|
3834
|
+
it('should return a url for the qr-code for vendorEndpoint is `issuing-identification`', async () => {
|
|
3835
|
+
const payload = _.omit(
|
|
3836
|
+
['tenantId'],
|
|
3837
|
+
await newDisclosure({
|
|
3838
|
+
tenant,
|
|
3839
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
3840
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3841
|
+
offerMode: 'preloaded',
|
|
3842
|
+
})
|
|
3843
|
+
);
|
|
3844
|
+
|
|
3845
|
+
const createResponse = await fastify.injectJson({
|
|
3846
|
+
method: 'POST',
|
|
3847
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3848
|
+
payload: {
|
|
3849
|
+
...payload,
|
|
3850
|
+
setIssuingDefault: true,
|
|
3851
|
+
},
|
|
3852
|
+
});
|
|
3853
|
+
|
|
3854
|
+
const response = await fastify.inject({
|
|
3855
|
+
method: 'GET',
|
|
3856
|
+
url: `${disclosureUrl(tenant)}/${createResponse.json.id}/qrcode.uri`,
|
|
3857
|
+
headers: {
|
|
3858
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3859
|
+
},
|
|
3860
|
+
});
|
|
3861
|
+
|
|
3862
|
+
expect(response.statusCode).toEqual(200);
|
|
3863
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
3864
|
+
expect(response.body).toEqual(
|
|
3865
|
+
// eslint-disable-next-line max-len
|
|
3866
|
+
`velocity-test://issue?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Fissue%2Fget-credential-manifest%3Fid%3D${
|
|
3867
|
+
createResponse.json.id
|
|
3868
|
+
}&issuerDid=${encodeURIComponent(tenant.did)}`
|
|
3869
|
+
);
|
|
3870
|
+
});
|
|
3871
|
+
|
|
3872
|
+
it('should return a url for the qr-code for vendorEndpoint is `issuing-identification` with vendorOriginContext', async () => {
|
|
3873
|
+
const payload = _.omit(
|
|
3874
|
+
['tenantId'],
|
|
3875
|
+
await newDisclosure({
|
|
3876
|
+
tenant,
|
|
3877
|
+
vendorEndpoint: VendorEndpoint.ISSUING_IDENTIFICATION,
|
|
3878
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3879
|
+
offerMode: 'preloaded',
|
|
3880
|
+
})
|
|
3881
|
+
);
|
|
3882
|
+
|
|
3883
|
+
const createResponse = await fastify.injectJson({
|
|
3884
|
+
method: 'POST',
|
|
3885
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3886
|
+
payload: {
|
|
3887
|
+
...payload,
|
|
3888
|
+
setIssuingDefault: true,
|
|
3889
|
+
},
|
|
3890
|
+
});
|
|
3891
|
+
|
|
3892
|
+
const response = await fastify.inject({
|
|
3893
|
+
method: 'GET',
|
|
3894
|
+
url: `${disclosureUrl(tenant)}/${
|
|
3895
|
+
createResponse.json.id
|
|
3896
|
+
}/qrcode.uri?vendorOriginContext=123`,
|
|
3897
|
+
headers: {
|
|
3898
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3899
|
+
},
|
|
3900
|
+
});
|
|
3901
|
+
|
|
3902
|
+
expect(response.statusCode).toEqual(200);
|
|
3903
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
3904
|
+
expect(response.body).toEqual(
|
|
3905
|
+
// eslint-disable-next-line max-len
|
|
3906
|
+
`velocity-test://issue?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Fissue%2Fget-credential-manifest%3Fid%3D${
|
|
3907
|
+
createResponse.json.id
|
|
3908
|
+
}&issuerDid=${encodeURIComponent(tenant.did)}&vendorOriginContext=123`
|
|
3909
|
+
);
|
|
3910
|
+
});
|
|
3911
|
+
|
|
3912
|
+
it('should return a url for the qr-code for vendorEndpoint is `integrated-issuing-identification`', async () => {
|
|
3913
|
+
const payload = _.omit(
|
|
3914
|
+
['tenantId'],
|
|
3915
|
+
await newDisclosure({
|
|
3916
|
+
tenant,
|
|
3917
|
+
vendorEndpoint: VendorEndpoint.INTEGRATED_ISSUING_IDENTIFICATION,
|
|
3918
|
+
configurationType: ConfigurationType.ISSUING,
|
|
3919
|
+
types: [{ type: 'EmailV1.0' }],
|
|
3920
|
+
offerMode: 'preloaded',
|
|
3921
|
+
identityMatchers: {
|
|
3922
|
+
rules: [
|
|
3923
|
+
{
|
|
3924
|
+
valueIndex: 0, // used for identifying the value
|
|
3925
|
+
path: ['$.emails'], // jsonPath within the credential
|
|
3926
|
+
rule: 'pick', // Rule to execute can be pick, all (if the target is an array), equal (if the target is a singleValue)
|
|
3927
|
+
},
|
|
3928
|
+
],
|
|
3929
|
+
vendorUserIdIndex: 0,
|
|
3930
|
+
},
|
|
3931
|
+
})
|
|
3932
|
+
);
|
|
3933
|
+
|
|
3934
|
+
const createResponse = await fastify.injectJson({
|
|
3935
|
+
method: 'POST',
|
|
3936
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3937
|
+
payload: {
|
|
3938
|
+
...payload,
|
|
3939
|
+
setIssuingDefault: true,
|
|
3940
|
+
},
|
|
3941
|
+
});
|
|
3942
|
+
|
|
3943
|
+
const response = await fastify.inject({
|
|
3944
|
+
method: 'GET',
|
|
3945
|
+
url: `${disclosureUrl(tenant)}/${createResponse.json.id}/qrcode.uri`,
|
|
3946
|
+
headers: {
|
|
3947
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3948
|
+
},
|
|
3949
|
+
});
|
|
3950
|
+
|
|
3951
|
+
expect(response.statusCode).toEqual(200);
|
|
3952
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
3953
|
+
expect(response.body).toEqual(
|
|
3954
|
+
// eslint-disable-next-line max-len
|
|
3955
|
+
`velocity-test://issue?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Fissue%2Fget-credential-manifest%3Fid%3D${
|
|
3956
|
+
createResponse.json.id
|
|
3957
|
+
}&issuerDid=${encodeURIComponent(tenant.did)}`
|
|
3958
|
+
);
|
|
3959
|
+
});
|
|
3960
|
+
|
|
3961
|
+
it('should return an image for the qr-code', async () => {
|
|
3962
|
+
const payload = _.omit(['tenantId'], await newDisclosure({ tenant }));
|
|
3963
|
+
|
|
3964
|
+
const createResponse = await fastify.injectJson({
|
|
3965
|
+
method: 'POST',
|
|
3966
|
+
url: `${disclosureUrl(tenant)}`,
|
|
3967
|
+
payload,
|
|
3968
|
+
});
|
|
3969
|
+
|
|
3970
|
+
const response = await fastify.inject({
|
|
3971
|
+
method: 'GET',
|
|
3972
|
+
url: `${disclosureUrl(tenant)}/${createResponse.json.id}/qrcode.png`,
|
|
3973
|
+
headers: {
|
|
3974
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
3975
|
+
},
|
|
3976
|
+
});
|
|
3977
|
+
|
|
3978
|
+
expect(response.headers['content-type']).toEqual('image/png');
|
|
3979
|
+
expect(response.statusCode).toEqual(200);
|
|
3980
|
+
expect(response.body.length).toBeGreaterThan(100);
|
|
3981
|
+
});
|
|
3982
|
+
});
|
|
3983
|
+
|
|
3984
|
+
describe('Disclosure HTTP Deep Link Tests', () => {
|
|
3985
|
+
it('Should get a Disclosure HTTP Deep Link', async () => {
|
|
3986
|
+
const payload = await persistDisclosure({ tenant });
|
|
3987
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
3988
|
+
|
|
3989
|
+
const response = await fastify.injectJson({
|
|
3990
|
+
method: 'GET',
|
|
3991
|
+
url: `${disclosureUrl(tenant)}/${payload._id}/deep-link`,
|
|
3992
|
+
});
|
|
3993
|
+
|
|
3994
|
+
expect(response.statusCode).toEqual(200);
|
|
3995
|
+
expect(response.json).toEqual({
|
|
3996
|
+
deepLink:
|
|
3997
|
+
// eslint-disable-next-line max-len
|
|
3998
|
+
`http://localhost.test/app-redirect?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Finspect%2Fget-presentation-request%3Fid%3D${payload._id}&inspectorDid=${urlEncodedDid}&exchange_type=inspect`,
|
|
3999
|
+
});
|
|
4000
|
+
});
|
|
4001
|
+
|
|
4002
|
+
it('Should generate a Disclosure HTTP Deep Link with vendor origin context', async () => {
|
|
4003
|
+
const payload = await persistDisclosure({ tenant });
|
|
4004
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
4005
|
+
|
|
4006
|
+
const response = await fastify.injectJson({
|
|
4007
|
+
method: 'GET',
|
|
4008
|
+
url: `${disclosureUrl(tenant)}/${
|
|
4009
|
+
payload._id
|
|
4010
|
+
}/deep-link?vendorOriginContext=123`,
|
|
4011
|
+
});
|
|
4012
|
+
|
|
4013
|
+
expect(response.statusCode).toEqual(200);
|
|
4014
|
+
expect(response.json).toEqual({
|
|
4015
|
+
deepLink:
|
|
4016
|
+
// eslint-disable-next-line max-len
|
|
4017
|
+
`http://localhost.test/app-redirect?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Finspect%2Fget-presentation-request%3Fid%3D${payload._id}&inspectorDid=${urlEncodedDid}&vendorOriginContext=123&exchange_type=inspect`,
|
|
4018
|
+
});
|
|
4019
|
+
});
|
|
4020
|
+
|
|
4021
|
+
it('Should generate a Disclosure HTTP Deep Link for issuing', async () => {
|
|
4022
|
+
const payload = await persistDisclosure({
|
|
4023
|
+
tenant,
|
|
4024
|
+
vendorEndpoint: 'integrated-issuing-identification',
|
|
4025
|
+
});
|
|
4026
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
4027
|
+
|
|
4028
|
+
const response = await fastify.injectJson({
|
|
4029
|
+
method: 'GET',
|
|
4030
|
+
url: `${disclosureUrl(tenant)}/${payload._id}/deep-link`,
|
|
4031
|
+
});
|
|
4032
|
+
|
|
4033
|
+
expect(response.statusCode).toEqual(200);
|
|
4034
|
+
expect(response.json).toEqual({
|
|
4035
|
+
deepLink:
|
|
4036
|
+
// eslint-disable-next-line max-len
|
|
4037
|
+
`http://localhost.test/app-redirect?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Fissue%2Fget-credential-manifest%3Fid%3D${payload._id}&issuerDid=${urlEncodedDid}&exchange_type=issue`,
|
|
4038
|
+
});
|
|
4039
|
+
});
|
|
4040
|
+
|
|
4041
|
+
it('Should generate a Disclosure HTTP Deep Link for issuing with vendorOriginContext', async () => {
|
|
4042
|
+
const payload = await persistDisclosure({
|
|
4043
|
+
tenant,
|
|
4044
|
+
vendorEndpoint: 'integrated-issuing-identification',
|
|
4045
|
+
});
|
|
4046
|
+
const urlEncodedDid = encodeURIComponent(tenant.did);
|
|
4047
|
+
|
|
4048
|
+
const response = await fastify.injectJson({
|
|
4049
|
+
method: 'GET',
|
|
4050
|
+
url: `${disclosureUrl(tenant)}/${
|
|
4051
|
+
payload._id
|
|
4052
|
+
}/deep-link?vendorOriginContext=123`,
|
|
4053
|
+
});
|
|
4054
|
+
|
|
4055
|
+
expect(response.statusCode).toEqual(200);
|
|
4056
|
+
expect(response.json).toEqual({
|
|
4057
|
+
deepLink:
|
|
4058
|
+
// eslint-disable-next-line max-len
|
|
4059
|
+
`http://localhost.test/app-redirect?request_uri=http%3A%2F%2Flocalhost.test%2Fapi%2Fholder%2Fv0.6%2Forg%2F${urlEncodedDid}%2Fissue%2Fget-credential-manifest%3Fid%3D${payload._id}&issuerDid=${urlEncodedDid}&vendorOriginContext=123&exchange_type=issue`,
|
|
4060
|
+
});
|
|
4061
|
+
});
|
|
4062
|
+
});
|
|
4063
|
+
|
|
4064
|
+
describe('Disclosure Deletion Test Suite', () => {
|
|
4065
|
+
it('should 404 and not delete if not found error', async () => {
|
|
4066
|
+
const response = await fastify.injectJson({
|
|
4067
|
+
method: 'DELETE',
|
|
4068
|
+
url: `${disclosureUrl(tenant)}/${new ObjectId()}`,
|
|
4069
|
+
});
|
|
4070
|
+
|
|
4071
|
+
expect(response.statusCode).toEqual(404);
|
|
4072
|
+
});
|
|
4073
|
+
|
|
4074
|
+
it('should 404 and not delete if wrong tenant found error', async () => {
|
|
4075
|
+
const response = await fastify.injectJson({
|
|
4076
|
+
method: 'DELETE',
|
|
4077
|
+
url: `${disclosureUrl(altTenant)}/${disclosures.a._id}`,
|
|
4078
|
+
});
|
|
4079
|
+
|
|
4080
|
+
expect(response.statusCode).toEqual(404);
|
|
4081
|
+
|
|
4082
|
+
const dbResult = await mongoDb()
|
|
4083
|
+
.collection('disclosures')
|
|
4084
|
+
.findOne({ _id: new ObjectId(disclosures.a._id) });
|
|
4085
|
+
expect(dbResult).toBeTruthy();
|
|
4086
|
+
});
|
|
4087
|
+
|
|
4088
|
+
it('should 400 if disclosure linked to tenant', async () => {
|
|
4089
|
+
await tenantRepo.update(tenant._id, {
|
|
4090
|
+
defaultIssuingDisclosureId: new ObjectId(disclosures.a._id),
|
|
4091
|
+
});
|
|
4092
|
+
|
|
4093
|
+
const response = await fastify.injectJson({
|
|
4094
|
+
method: 'DELETE',
|
|
4095
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
4096
|
+
});
|
|
4097
|
+
|
|
4098
|
+
expect(response.statusCode).toEqual(400);
|
|
4099
|
+
expect(response.json).toEqual(
|
|
4100
|
+
errorResponseMatcher({
|
|
4101
|
+
error: 'Bad Request',
|
|
4102
|
+
message: 'Disclosure cannot be deleted',
|
|
4103
|
+
statusCode: 400,
|
|
4104
|
+
errorCode: 'default_disclosure_cannot_be_deleted',
|
|
4105
|
+
})
|
|
4106
|
+
);
|
|
4107
|
+
|
|
4108
|
+
expect(
|
|
4109
|
+
await mongoDb()
|
|
4110
|
+
.collection('disclosures')
|
|
4111
|
+
.countDocuments({
|
|
4112
|
+
_id: new ObjectId(disclosures.a._id),
|
|
4113
|
+
})
|
|
4114
|
+
).toEqual(1);
|
|
4115
|
+
});
|
|
4116
|
+
|
|
4117
|
+
it('should 400 if disclosure has feeds', async () => {
|
|
4118
|
+
await persistFeed({ tenant, disclosure: disclosures.a });
|
|
4119
|
+
const response = await fastify.injectJson({
|
|
4120
|
+
method: 'DELETE',
|
|
4121
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
4122
|
+
});
|
|
4123
|
+
|
|
4124
|
+
expect(response.statusCode).toEqual(400);
|
|
4125
|
+
expect(response.json).toEqual(
|
|
4126
|
+
errorResponseMatcher({
|
|
4127
|
+
error: 'Bad Request',
|
|
4128
|
+
message: 'Disclosure cannot be deleted',
|
|
4129
|
+
statusCode: 400,
|
|
4130
|
+
errorCode: 'disclosure_with_feeds_cannot_be_deleted',
|
|
4131
|
+
})
|
|
4132
|
+
);
|
|
4133
|
+
|
|
4134
|
+
expect(
|
|
4135
|
+
await mongoDb()
|
|
4136
|
+
.collection('disclosures')
|
|
4137
|
+
.countDocuments({
|
|
4138
|
+
_id: new ObjectId(disclosures.a._id),
|
|
4139
|
+
})
|
|
4140
|
+
).toEqual(1);
|
|
4141
|
+
});
|
|
4142
|
+
|
|
4143
|
+
it('should delete a disclosure', async () => {
|
|
4144
|
+
const response = await fastify.injectJson({
|
|
4145
|
+
method: 'DELETE',
|
|
4146
|
+
url: `${disclosureUrl(tenant)}/${disclosures.a._id}`,
|
|
4147
|
+
});
|
|
4148
|
+
|
|
4149
|
+
expect(response.statusCode).toEqual(204);
|
|
4150
|
+
await expect(
|
|
4151
|
+
mongoDb()
|
|
4152
|
+
.collection('disclosures')
|
|
4153
|
+
.findOne({ _id: new ObjectId(disclosures.a._id) })
|
|
4154
|
+
).resolves.toEqual(null);
|
|
4155
|
+
});
|
|
4156
|
+
});
|
|
4157
|
+
});
|