@icure/api 8.10.2 → 8.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/icc-api/api/IccPatientApi.d.ts +1 -1
- package/icc-api/api/IccPatientApi.js +4 -2
- package/icc-api/api/IccPatientApi.js.map +1 -1
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +11 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +75 -13
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -1
- package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +14 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js +28 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.d.ts +4 -1
- package/icc-x-api/icc-patient-x-api.js +5 -2
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/package.json +1 -1
- package/test/benchmarks/lzma-benchmark.spec.d.ts +1 -0
- package/test/benchmarks/lzma-benchmark.spec.js +131 -0
- package/test/benchmarks/lzma-benchmark.spec.js.map +1 -0
- package/test/benchmarks/lzma-compat.spec.d.ts +1 -0
- package/test/benchmarks/lzma-compat.spec.js +187 -0
- package/test/benchmarks/lzma-compat.spec.js.map +1 -0
- package/test/benchmarks/playwright.config.d.ts +2 -0
- package/test/benchmarks/playwright.config.js +18 -0
- package/test/benchmarks/playwright.config.js.map +1 -0
- package/test/icc-api/api/IccAgendaApi.d.ts +1 -0
- package/test/icc-api/api/IccAgendaApi.js +64 -0
- package/test/icc-api/api/IccAgendaApi.js.map +1 -0
- package/test/icc-api/api/IccAnonymousAccessApi.d.ts +1 -0
- package/test/icc-api/api/IccAnonymousAccessApi.js +58 -0
- package/test/icc-api/api/IccAnonymousAccessApi.js.map +1 -0
- package/test/icc-api/api/IccCalendarItemApi.d.ts +1 -0
- package/test/icc-api/api/IccCalendarItemApi.js +67 -0
- package/test/icc-api/api/IccCalendarItemApi.js.map +1 -0
- package/test/icc-api/api/IccCalendarItemTypeApi.d.ts +1 -0
- package/test/icc-api/api/IccCalendarItemTypeApi.js +96 -0
- package/test/icc-api/api/IccCalendarItemTypeApi.js.map +1 -0
- package/test/icc-api/api/IccCodeApi.d.ts +1 -0
- package/test/icc-api/api/IccCodeApi.js +38 -0
- package/test/icc-api/api/IccCodeApi.js.map +1 -0
- package/test/icc-api/api/IccDocumentApi.d.ts +1 -0
- package/test/icc-api/api/IccDocumentApi.js +199 -0
- package/test/icc-api/api/IccDocumentApi.js.map +1 -0
- package/test/icc-api/api/IccGroupApi.d.ts +1 -0
- package/test/icc-api/api/IccGroupApi.js +50 -0
- package/test/icc-api/api/IccGroupApi.js.map +1 -0
- package/test/icc-api/api/IccKeywordApi.d.ts +1 -0
- package/test/icc-api/api/IccKeywordApi.js +64 -0
- package/test/icc-api/api/IccKeywordApi.js.map +1 -0
- package/test/icc-api/api/IccMedicalLocationApi.d.ts +1 -0
- package/test/icc-api/api/IccMedicalLocationApi.js +64 -0
- package/test/icc-api/api/IccMedicalLocationApi.js.map +1 -0
- package/test/icc-api/api/IccPlaceApi.d.ts +1 -0
- package/test/icc-api/api/IccPlaceApi.js +64 -0
- package/test/icc-api/api/IccPlaceApi.js.map +1 -0
- package/test/icc-api/api/IccRecoveryDataApi.d.ts +1 -0
- package/test/icc-api/api/IccRecoveryDataApi.js +95 -0
- package/test/icc-api/api/IccRecoveryDataApi.js.map +1 -0
- package/test/icc-api/api/IccRoleApi.d.ts +1 -0
- package/test/icc-api/api/IccRoleApi.js +34 -0
- package/test/icc-api/api/IccRoleApi.js.map +1 -0
- package/test/icc-api/api/IccUserApi.d.ts +1 -0
- package/test/icc-api/api/IccUserApi.js +96 -0
- package/test/icc-api/api/IccUserApi.js.map +1 -0
- package/test/icc-api/e2e/IccCalendarItemApi.d.ts +1 -0
- package/test/icc-api/e2e/IccCalendarItemApi.js +46 -0
- package/test/icc-api/e2e/IccCalendarItemApi.js.map +1 -0
- package/test/icc-api/model/modelHelpersTest.d.ts +1 -0
- package/test/icc-api/model/modelHelpersTest.js +45 -0
- package/test/icc-api/model/modelHelpersTest.js.map +1 -0
- package/test/icc-x-api/auth/group-switch-test.d.ts +1 -0
- package/test/icc-x-api/auth/group-switch-test.js +81 -0
- package/test/icc-x-api/auth/group-switch-test.js.map +1 -0
- package/test/icc-x-api/auth/jwt-concurrency-test.d.ts +2 -0
- package/test/icc-x-api/auth/jwt-concurrency-test.js +112 -0
- package/test/icc-x-api/auth/jwt-concurrency-test.js.map +1 -0
- package/test/icc-x-api/auth/jwt-provider-test.d.ts +1 -0
- package/test/icc-x-api/auth/jwt-provider-test.js +197 -0
- package/test/icc-x-api/auth/jwt-provider-test.js.map +1 -0
- package/test/icc-x-api/auth/smart-auth-provider-test.d.ts +1 -0
- package/test/icc-x-api/auth/smart-auth-provider-test.js +224 -0
- package/test/icc-x-api/auth/smart-auth-provider-test.js.map +1 -0
- package/test/icc-x-api/autofix-anonymity-test.d.ts +1 -0
- package/test/icc-x-api/autofix-anonymity-test.js +122 -0
- package/test/icc-x-api/autofix-anonymity-test.js.map +1 -0
- package/test/icc-x-api/confidential-entities-test.d.ts +1 -0
- package/test/icc-x-api/confidential-entities-test.js +168 -0
- package/test/icc-x-api/confidential-entities-test.js.map +1 -0
- package/test/icc-x-api/crud/comprehensive-crud-test.d.ts +1 -0
- package/test/icc-x-api/crud/comprehensive-crud-test.js +276 -0
- package/test/icc-x-api/crud/comprehensive-crud-test.js.map +1 -0
- package/test/icc-x-api/crud/entities-crud-test-interface.d.ts +16 -0
- package/test/icc-x-api/crud/entities-crud-test-interface.js +407 -0
- package/test/icc-x-api/crud/entities-crud-test-interface.js.map +1 -0
- package/test/icc-x-api/crypto/anonymous-delegations-test.d.ts +1 -0
- package/test/icc-x-api/crypto/anonymous-delegations-test.js +587 -0
- package/test/icc-x-api/crypto/anonymous-delegations-test.js.map +1 -0
- package/test/icc-x-api/crypto/concurrency.d.ts +1 -0
- package/test/icc-x-api/crypto/concurrency.js +35 -0
- package/test/icc-x-api/crypto/concurrency.js.map +1 -0
- package/test/icc-x-api/crypto/crypto-utils.d.ts +1 -0
- package/test/icc-x-api/crypto/crypto-utils.js +79 -0
- package/test/icc-x-api/crypto/crypto-utils.js.map +1 -0
- package/test/icc-x-api/crypto/cryptoTest.d.ts +2 -0
- package/test/icc-x-api/crypto/cryptoTest.js +402 -0
- package/test/icc-x-api/crypto/cryptoTest.js.map +1 -0
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.d.ts +1 -0
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js +166 -0
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js.map +1 -0
- package/test/icc-x-api/crypto/exchange-data-manager-test.d.ts +1 -0
- package/test/icc-x-api/crypto/exchange-data-manager-test.js +674 -0
- package/test/icc-x-api/crypto/exchange-data-manager-test.js.map +1 -0
- package/test/icc-x-api/crypto/full-crypto-test.d.ts +1 -0
- package/test/icc-x-api/crypto/full-crypto-test.js +454 -0
- package/test/icc-x-api/crypto/full-crypto-test.js.map +1 -0
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.d.ts +1 -0
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.js +379 -0
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.js.map +1 -0
- package/test/icc-x-api/crypto/secure-delegations-manager-test.d.ts +1 -0
- package/test/icc-x-api/crypto/secure-delegations-manager-test.js +278 -0
- package/test/icc-x-api/crypto/secure-delegations-manager-test.js.map +1 -0
- package/test/icc-x-api/crypto/shamir.d.ts +2 -0
- package/test/icc-x-api/crypto/shamir.js +167 -0
- package/test/icc-x-api/crypto/shamir.js.map +1 -0
- package/test/icc-x-api/crypto/share-deduplication-test.d.ts +1 -0
- package/test/icc-x-api/crypto/share-deduplication-test.js +250 -0
- package/test/icc-x-api/crypto/share-deduplication-test.js.map +1 -0
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.d.ts +1 -0
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js +71 -0
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js.map +1 -0
- package/test/icc-x-api/crypto/soft-deleted-data-owners.d.ts +2 -0
- package/test/icc-x-api/crypto/soft-deleted-data-owners.js +113 -0
- package/test/icc-x-api/crypto/soft-deleted-data-owners.js.map +1 -0
- package/test/icc-x-api/crypto/user-encryption-keys-manager-test.d.ts +1 -0
- package/test/icc-x-api/crypto/user-encryption-keys-manager-test.js +246 -0
- package/test/icc-x-api/crypto/user-encryption-keys-manager-test.js.map +1 -0
- package/test/icc-x-api/entity-with-attachments-api-test.d.ts +1 -0
- package/test/icc-x-api/entity-with-attachments-api-test.js +142 -0
- package/test/icc-x-api/entity-with-attachments-api-test.js.map +1 -0
- package/test/icc-x-api/filters/filters.d.ts +1 -0
- package/test/icc-x-api/filters/filters.js +49 -0
- package/test/icc-x-api/filters/filters.js.map +1 -0
- package/test/icc-x-api/filters/healthelement.d.ts +1 -0
- package/test/icc-x-api/filters/healthelement.js +333 -0
- package/test/icc-x-api/filters/healthelement.js.map +1 -0
- package/test/icc-x-api/icc-accesslog-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-accesslog-x-api.js +106 -0
- package/test/icc-x-api/icc-accesslog-x-api.js.map +1 -0
- package/test/icc-x-api/icc-application-settings-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-application-settings-x-api.js +91 -0
- package/test/icc-x-api/icc-application-settings-x-api.js.map +1 -0
- package/test/icc-x-api/icc-auth-api.d.ts +1 -0
- package/test/icc-x-api/icc-auth-api.js +47 -0
- package/test/icc-x-api/icc-auth-api.js.map +1 -0
- package/test/icc-x-api/icc-calendar-item-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-calendar-item-x-api.js +150 -0
- package/test/icc-x-api/icc-calendar-item-x-api.js.map +1 -0
- package/test/icc-x-api/icc-code-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-code-x-api-test.js +74 -0
- package/test/icc-x-api/icc-code-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-contact-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-contact-x-api.js +355 -0
- package/test/icc-x-api/icc-contact-x-api.js.map +1 -0
- package/test/icc-x-api/icc-document-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-document-x-api.js +76 -0
- package/test/icc-x-api/icc-document-x-api.js.map +1 -0
- package/test/icc-x-api/icc-form-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-form-x-api.js +413 -0
- package/test/icc-x-api/icc-form-x-api.js.map +1 -0
- package/test/icc-x-api/icc-hcparty-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-hcparty-x-api-test.js +43 -0
- package/test/icc-x-api/icc-hcparty-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-helement-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-helement-x-api-test.js +155 -0
- package/test/icc-x-api/icc-helement-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-invoice-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-invoice-x-api.js +99 -0
- package/test/icc-x-api/icc-invoice-x-api.js.map +1 -0
- package/test/icc-x-api/icc-maintenance-task-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-maintenance-task-x-api-test.js +222 -0
- package/test/icc-x-api/icc-maintenance-task-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-message-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-message-x-api.js +54 -0
- package/test/icc-x-api/icc-message-x-api.js.map +1 -0
- package/test/icc-x-api/icc-patient-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-patient-x-api-test.js +209 -0
- package/test/icc-x-api/icc-patient-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-recovery-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-recovery-x-api.js +175 -0
- package/test/icc-x-api/icc-recovery-x-api.js.map +1 -0
- package/test/icc-x-api/icc-topic-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-topic-x-api.js +269 -0
- package/test/icc-x-api/icc-topic-x-api.js.map +1 -0
- package/test/icc-x-api/icc-user-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-user-x-api-test.js +99 -0
- package/test/icc-x-api/icc-user-x-api-test.js.map +1 -0
- package/test/icc-x-api/keyless-api.d.ts +1 -0
- package/test/icc-x-api/keyless-api.js +125 -0
- package/test/icc-x-api/keyless-api.js.map +1 -0
- package/test/icc-x-api/patient-user.d.ts +2 -0
- package/test/icc-x-api/patient-user.js +103 -0
- package/test/icc-x-api/patient-user.js.map +1 -0
- package/test/icc-x-api/storage/storage.d.ts +1 -0
- package/test/icc-x-api/storage/storage.js +48 -0
- package/test/icc-x-api/storage/storage.js.map +1 -0
- package/test/icc-x-api/test-api-no-parent.d.ts +1 -0
- package/test/icc-x-api/test-api-no-parent.js +79 -0
- package/test/icc-x-api/test-api-no-parent.js.map +1 -0
- package/test/icc-x-api/test-legacy-data-support.d.ts +1 -0
- package/test/icc-x-api/test-legacy-data-support.js +375 -0
- package/test/icc-x-api/test-legacy-data-support.js.map +1 -0
- package/test/icc-x-api/utils/date-encode-test.d.ts +1 -0
- package/test/icc-x-api/utils/date-encode-test.js +150 -0
- package/test/icc-x-api/utils/date-encode-test.js.map +1 -0
- package/test/icc-x-api/utils/graph-test.d.ts +1 -0
- package/test/icc-x-api/utils/graph-test.js +54 -0
- package/test/icc-x-api/utils/graph-test.js.map +1 -0
- package/test/icc-x-api/utils/lru-temporised-async-cache-test.d.ts +1 -0
- package/test/icc-x-api/utils/lru-temporised-async-cache-test.js +364 -0
- package/test/icc-x-api/utils/lru-temporised-async-cache-test.js.map +1 -0
- package/test/icc-x-api/utils/lzma-benchmark-test.d.ts +1 -0
- package/test/icc-x-api/utils/lzma-benchmark-test.js +132 -0
- package/test/icc-x-api/utils/lzma-benchmark-test.js.map +1 -0
- package/test/icc-x-api/utils/lzma-compat-test.d.ts +1 -0
- package/test/icc-x-api/utils/lzma-compat-test.js +218 -0
- package/test/icc-x-api/utils/lzma-compat-test.js.map +1 -0
- package/test/icc-x-api/utils/mutex-test.d.ts +1 -0
- package/test/icc-x-api/utils/mutex-test.js +114 -0
- package/test/icc-x-api/utils/mutex-test.js.map +1 -0
- package/test/icc-x-api/utils/to-moment-test.d.ts +1 -0
- package/test/icc-x-api/utils/to-moment-test.js +110 -0
- package/test/icc-x-api/utils/to-moment-test.js.map +1 -0
- package/test/support/CSM-185.d.ts +1 -0
- package/test/support/CSM-185.js +124 -0
- package/test/support/CSM-185.js.map +1 -0
- package/test/support/CSM-243.d.ts +1 -0
- package/test/support/CSM-243.js +120 -0
- package/test/support/CSM-243.js.map +1 -0
- package/test/support/CSM-543.d.ts +1 -0
- package/test/support/CSM-543.js +164 -0
- package/test/support/CSM-543.js.map +1 -0
- package/test/support/CSM-729.d.ts +1 -0
- package/test/support/CSM-729.js +225 -0
- package/test/support/CSM-729.js.map +1 -0
- package/test/support/CSM-814.d.ts +1 -0
- package/test/support/CSM-814.js +475 -0
- package/test/support/CSM-814.js.map +1 -0
- package/test/support/CSM-87.d.ts +0 -0
- package/test/support/CSM-87.js +21 -0
- package/test/support/CSM-87.js.map +1 -0
- package/test/support/CSM-93.d.ts +1 -0
- package/test/support/CSM-93.js +112 -0
- package/test/support/CSM-93.js.map +1 -0
- package/test/utils/FakeDataOwnerApi.d.ts +32 -0
- package/test/utils/FakeDataOwnerApi.js +136 -0
- package/test/utils/FakeDataOwnerApi.js.map +1 -0
- package/test/utils/FakeEncryptionKeysManager.d.ts +36 -0
- package/test/utils/FakeEncryptionKeysManager.js +97 -0
- package/test/utils/FakeEncryptionKeysManager.js.map +1 -0
- package/test/utils/FakeExchangeDataApi.d.ts +32 -0
- package/test/utils/FakeExchangeDataApi.js +92 -0
- package/test/utils/FakeExchangeDataApi.js.map +1 -0
- package/test/utils/FakeExchangeDataManager.d.ts +48 -0
- package/test/utils/FakeExchangeDataManager.js +82 -0
- package/test/utils/FakeExchangeDataManager.js.map +1 -0
- package/test/utils/FakeExchangeDataMapManager.d.ts +12 -0
- package/test/utils/FakeExchangeDataMapManager.js +38 -0
- package/test/utils/FakeExchangeDataMapManager.js.map +1 -0
- package/test/utils/FakeGenericApi.d.ts +16 -0
- package/test/utils/FakeGenericApi.js +65 -0
- package/test/utils/FakeGenericApi.js.map +1 -0
- package/test/utils/KeylessCryptoStrategies.d.ts +23 -0
- package/test/utils/KeylessCryptoStrategies.js +26 -0
- package/test/utils/KeylessCryptoStrategies.js.map +1 -0
- package/test/utils/TestApi.d.ts +3 -0
- package/test/utils/TestApi.js +30 -0
- package/test/utils/TestApi.js.map +1 -0
- package/test/utils/TestCollectionUtils.d.ts +1 -0
- package/test/utils/TestCollectionUtils.js +310 -0
- package/test/utils/TestCollectionUtils.js.map +1 -0
- package/test/utils/TestCryptoStrategies.d.ts +42 -0
- package/test/utils/TestCryptoStrategies.js +80 -0
- package/test/utils/TestCryptoStrategies.js.map +1 -0
- package/test/utils/TestStorage.d.ts +23 -0
- package/test/utils/TestStorage.js +61 -0
- package/test/utils/TestStorage.js.map +1 -0
- package/test/utils/roles.d.ts +14 -0
- package/test/utils/roles.js +345 -0
- package/test/utils/roles.js.map +1 -0
- package/test/utils/test_utils.d.ts +87 -0
- package/test/utils/test_utils.js +452 -0
- package/test/utils/test_utils.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'isomorphic-fetch';
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const test_utils_1 = require("../../utils/test_utils");
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
const chai_1 = require("chai");
|
|
15
|
+
require("isomorphic-fetch");
|
|
16
|
+
const types_1 = require("@icure/test-setup/types");
|
|
17
|
+
const icc_x_api_1 = require("../../../icc-x-api");
|
|
18
|
+
const TestStorage_1 = require("../../utils/TestStorage");
|
|
19
|
+
const TestCryptoStrategies_1 = require("../../utils/TestCryptoStrategies");
|
|
20
|
+
const EntityShareRequest_1 = require("../../../icc-api/model/requests/EntityShareRequest");
|
|
21
|
+
var initMasterApi = test_utils_1.TestUtils.initMasterApi;
|
|
22
|
+
var RequestedPermissionEnum = EntityShareRequest_1.EntityShareRequest.RequestedPermissionEnum;
|
|
23
|
+
(0, test_utils_1.setLocalStorage)(fetch);
|
|
24
|
+
let env;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a fresh hcp (random keypair) and makes it a child of parentId, to establish the existing
|
|
27
|
+
* relationship that operations such as mergePatients require between data owners in order to
|
|
28
|
+
* authorize the operation (an entirely unrelated hcp gets a 403).
|
|
29
|
+
*
|
|
30
|
+
* By default this does NOT give the child a locally-held copy of the parent's key
|
|
31
|
+
* (disableParentKeysInitialisation skips the startup check that would otherwise require one): in
|
|
32
|
+
* tests where we only care about the authorization relationship, we don't want the child to also
|
|
33
|
+
* be able to reach anything shared with the parent through a locally-cached parent key, which
|
|
34
|
+
* would muddy visibility assertions.
|
|
35
|
+
* Pass parentKeys for tests that specifically want to exercise genuine hierarchical inheritance (a
|
|
36
|
+
* child that has actually verified/cached its parent's key, like a properly provisioned device in
|
|
37
|
+
* the same care organisation).
|
|
38
|
+
*/
|
|
39
|
+
function createChildOfParent(testSetupApi, parentId, parentKeys) {
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
const info = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
42
|
+
yield testSetupApi.healthcarePartyApi.modifyHealthcareParty(Object.assign(Object.assign({}, (yield testSetupApi.healthcarePartyApi.getHealthcareParty(info.credentials.dataOwnerId))), { parentId }));
|
|
43
|
+
const storage = yield (0, TestStorage_1.testStorageWithKeys)([
|
|
44
|
+
{
|
|
45
|
+
dataOwnerId: info.credentials.dataOwnerId,
|
|
46
|
+
pairs: [{ keyPair: { privateKey: info.credentials.privateKey, publicKey: info.credentials.publicKey }, shaVersion: icc_x_api_1.ShaVersion.Sha1 }],
|
|
47
|
+
},
|
|
48
|
+
...(parentKeys ? [{ dataOwnerId: parentId, pairs: [{ keyPair: parentKeys, shaVersion: icc_x_api_1.ShaVersion.Sha1 }] }] : []),
|
|
49
|
+
]);
|
|
50
|
+
const api = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: info.credentials.user, password: info.credentials.password }, new TestCryptoStrategies_1.TestCryptoStrategies(), crypto_1.webcrypto, fetch, { storage: storage.storage, keyStorage: storage.keyStorage, entryKeysFactory: storage.keyFactory, disableParentKeysInitialisation: !parentKeys });
|
|
51
|
+
const user = yield api.userApi.getCurrentUser();
|
|
52
|
+
return { api, user, id: info.credentials.dataOwnerId };
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/*
|
|
56
|
+
* shareWith/shareWithMany should skip writing a delegation only when the target already has DIRECT access -
|
|
57
|
+
* named as either party of a specific, already-decryptable-by-the-caller delegation edge - never inferred via
|
|
58
|
+
* hierarchy, and never conflating content coverage with permission sufficiency (the two are independent: the
|
|
59
|
+
* backend only checks "is there at least one delegation naming this data owner with write access", it never
|
|
60
|
+
* correlates that with which specific secret id/encryption key a delegation happens to carry).
|
|
61
|
+
*/
|
|
62
|
+
describe('shareWith/shareWithMany only skip writes when the delegate has genuinely direct, decryptable access', function () {
|
|
63
|
+
before(function () {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
this.timeout(600000);
|
|
66
|
+
const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
|
|
67
|
+
env = yield initializer.execute((0, types_1.getEnvVariables)());
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
it('still writes when an unrelated third party X (who was separately given access by A) tries to reshare with P, since X cannot decrypt the A->P delegation', function () {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const aInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
73
|
+
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
74
|
+
const xInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
75
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
76
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
77
|
+
const sharedWithP = yield aInfo.api.patientApi.shareWithMany(created, {
|
|
78
|
+
[pInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },
|
|
79
|
+
});
|
|
80
|
+
const sharedWithX = yield aInfo.api.patientApi.shareWithMany(sharedWithP, {
|
|
81
|
+
[xInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },
|
|
82
|
+
});
|
|
83
|
+
const freshForX = yield xInfo.api.patientApi.getPatientWithUser(xInfo.user, sharedWithX.id);
|
|
84
|
+
const reshared = yield xInfo.api.patientApi.shareWith(pInfo.credentials.dataOwnerId, freshForX, [secretId]);
|
|
85
|
+
(0, chai_1.expect)(reshared.rev).to.not.equal(freshForX.rev);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
it('still shares directly with B even though P (a shared parent that already has the content, and B is a child of) already has it', function () {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const testSetupApi = yield initMasterApi(env);
|
|
91
|
+
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
92
|
+
const pId = pInfo.credentials.dataOwnerId;
|
|
93
|
+
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
94
|
+
const bInfo = yield createChildOfParent(testSetupApi, pId);
|
|
95
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
96
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
97
|
+
const sharedWithP = yield aInfo.api.patientApi.shareWithMany(created, { [pId]: { shareSecretIds: [secretId] } });
|
|
98
|
+
const freshForA = yield aInfo.api.patientApi.getPatientWithUser(aInfo.user, sharedWithP.id);
|
|
99
|
+
const sharedWithB = yield aInfo.api.patientApi.shareWith(bInfo.id, freshForA, [secretId]);
|
|
100
|
+
(0, chai_1.expect)(sharedWithB.rev).to.not.equal(freshForA.rev);
|
|
101
|
+
(0, chai_1.expect)(yield bInfo.api.patientApi.decryptSecretIdsOf(yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id))).to.have.members([secretId]);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it('still writes when A shares directly with Y, even though only an unrelated X->Y delegation (which A cannot decrypt) already covers it', function () {
|
|
105
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
const aInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
107
|
+
const xInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
108
|
+
const yInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
109
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
110
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
111
|
+
const sharedWithX = yield aInfo.api.patientApi.shareWithMany(created, {
|
|
112
|
+
[xInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },
|
|
113
|
+
});
|
|
114
|
+
const freshForX = yield xInfo.api.patientApi.getPatientWithUser(xInfo.user, sharedWithX.id);
|
|
115
|
+
const sharedWithY = yield xInfo.api.patientApi.shareWithMany(freshForX, {
|
|
116
|
+
[yInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },
|
|
117
|
+
});
|
|
118
|
+
const freshForA = yield aInfo.api.patientApi.getPatientWithUser(aInfo.user, sharedWithY.id);
|
|
119
|
+
const aSharesWithY = yield aInfo.api.patientApi.shareWith(yInfo.credentials.dataOwnerId, freshForA, [secretId]);
|
|
120
|
+
(0, chai_1.expect)(aSharesWithY.rev).to.not.equal(freshForA.rev);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
it('is a no-op when B shares content back with A, since A->B delegations are symmetric and A can decrypt its own', function () {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
const aInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
126
|
+
const bInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
127
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
128
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
129
|
+
const sharedWithB = yield aInfo.api.patientApi.shareWithMany(created, {
|
|
130
|
+
[bInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },
|
|
131
|
+
});
|
|
132
|
+
const freshForB = yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id);
|
|
133
|
+
const bSharesBackWithA = yield bInfo.api.patientApi.shareWith(aInfo.credentials.dataOwnerId, freshForB, [secretId]);
|
|
134
|
+
(0, chai_1.expect)(bSharesBackWithA.rev).to.equal(freshForB.rev);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
it('still writes a permission-only grant when the delegate already has the content, but only at an insufficient permission level', function () {
|
|
138
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
const testSetupApi = yield initMasterApi(env);
|
|
140
|
+
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
141
|
+
const pId = pInfo.credentials.dataOwnerId;
|
|
142
|
+
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
143
|
+
// B genuinely holds P's key (like a properly provisioned device), so it can verify P's existing coverage
|
|
144
|
+
// directly rather than relying on any hierarchy inference. B also needs its own, real write-level delegation
|
|
145
|
+
// on the entity (from A) - merely being able to decrypt via a borrowed key is not enough for the backend to
|
|
146
|
+
// authorize B to grant permissions to someone else; B must have genuine recorded access of its own too.
|
|
147
|
+
const bInfo = yield createChildOfParent(testSetupApi, pId, {
|
|
148
|
+
privateKey: pInfo.credentials.privateKey,
|
|
149
|
+
publicKey: pInfo.credentials.publicKey,
|
|
150
|
+
});
|
|
151
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
152
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
153
|
+
const sharedReadOnly = yield aInfo.api.patientApi.shareWith(pId, created, [secretId], {
|
|
154
|
+
requestedPermissions: RequestedPermissionEnum.FULL_READ,
|
|
155
|
+
});
|
|
156
|
+
(0, chai_1.expect)(yield pInfo.api.patientApi.hasWriteAccess(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, sharedReadOnly.id))).to.be.false;
|
|
157
|
+
const sharedWithB = yield aInfo.api.patientApi.shareWithMany(sharedReadOnly, { [bInfo.id]: { shareSecretIds: [secretId] } });
|
|
158
|
+
const freshForB = yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id);
|
|
159
|
+
const upgraded = yield bInfo.api.patientApi.shareWith(pId, freshForB, [secretId], {
|
|
160
|
+
requestedPermissions: RequestedPermissionEnum.FULL_WRITE,
|
|
161
|
+
});
|
|
162
|
+
(0, chai_1.expect)(upgraded.rev).to.not.equal(freshForB.rev);
|
|
163
|
+
(0, chai_1.expect)(yield pInfo.api.patientApi.hasWriteAccess(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, upgraded.id))).to.be.true;
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
it('is a no-op when the delegate already has the content at a sufficient permission level, verified via a different, unrelated caller', function () {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
const testSetupApi = yield initMasterApi(env);
|
|
169
|
+
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
170
|
+
const pId = pInfo.credentials.dataOwnerId;
|
|
171
|
+
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
172
|
+
const parentKeys = { privateKey: pInfo.credentials.privateKey, publicKey: pInfo.credentials.publicKey };
|
|
173
|
+
const bInfo = yield createChildOfParent(testSetupApi, pId, parentKeys);
|
|
174
|
+
const cInfo = yield createChildOfParent(testSetupApi, pId, parentKeys);
|
|
175
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
176
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
177
|
+
const sharedReadOnly = yield aInfo.api.patientApi.shareWith(pId, created, [secretId], {
|
|
178
|
+
requestedPermissions: RequestedPermissionEnum.FULL_READ,
|
|
179
|
+
});
|
|
180
|
+
// B and C each need their own real write-level delegation on the entity (from A) to be authorized to grant
|
|
181
|
+
// permissions to someone else - merely holding P's key for decryption purposes is not enough on its own.
|
|
182
|
+
const sharedWithBAndC = yield aInfo.api.patientApi.shareWithMany(sharedReadOnly, {
|
|
183
|
+
[bInfo.id]: { shareSecretIds: [secretId] },
|
|
184
|
+
[cInfo.id]: { shareSecretIds: [secretId] },
|
|
185
|
+
});
|
|
186
|
+
const freshForB = yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithBAndC.id);
|
|
187
|
+
const upgraded = yield bInfo.api.patientApi.shareWith(pId, freshForB, [secretId], {
|
|
188
|
+
requestedPermissions: RequestedPermissionEnum.FULL_WRITE,
|
|
189
|
+
});
|
|
190
|
+
// C never shared anything with P itself, but (via P's key) can verify P already has the content at a
|
|
191
|
+
// sufficient (WRITE) permission now - requesting only FULL_READ should be a true no-op.
|
|
192
|
+
const freshForC = yield cInfo.api.patientApi.getPatientWithUser(cInfo.user, upgraded.id);
|
|
193
|
+
const reshared = yield cInfo.api.patientApi.shareWith(pId, freshForC, [secretId], {
|
|
194
|
+
requestedPermissions: RequestedPermissionEnum.FULL_READ,
|
|
195
|
+
});
|
|
196
|
+
(0, chai_1.expect)(reshared.rev).to.equal(freshForC.rev);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
it('is a no-op when re-sharing at the default MAX_WRITE permission would only resolve to READ anyway, since the caller granting it has no write access itself', function () {
|
|
200
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
201
|
+
const testSetupApi = yield initMasterApi(env);
|
|
202
|
+
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
203
|
+
const pId = pInfo.credentials.dataOwnerId;
|
|
204
|
+
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
205
|
+
// X genuinely holds P's key, so it can verify P's existing coverage directly, and only ever gets FULL_READ
|
|
206
|
+
// access itself from A - MAX_WRITE resolves to "WRITE if the caller granting it has WRITE, else READ", so a
|
|
207
|
+
// MAX_WRITE request from X could never exceed READ, matching what P already has: nothing would change.
|
|
208
|
+
const xInfo = yield createChildOfParent(testSetupApi, pId, { privateKey: pInfo.credentials.privateKey, publicKey: pInfo.credentials.publicKey });
|
|
209
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
210
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
211
|
+
const sharedWithP = yield aInfo.api.patientApi.shareWith(pId, created, [secretId], { requestedPermissions: RequestedPermissionEnum.FULL_READ });
|
|
212
|
+
const sharedWithX = yield aInfo.api.patientApi.shareWith(xInfo.id, sharedWithP, [secretId], {
|
|
213
|
+
requestedPermissions: RequestedPermissionEnum.FULL_READ,
|
|
214
|
+
});
|
|
215
|
+
const freshForX = yield xInfo.api.patientApi.getPatientWithUser(xInfo.user, sharedWithX.id);
|
|
216
|
+
const reshared = yield xInfo.api.patientApi.shareWith(pId, freshForX, [secretId]); // default requestedPermissions: MAX_WRITE
|
|
217
|
+
(0, chai_1.expect)(reshared.rev).to.equal(freshForX.rev);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
it('still upgrades the delegate to WRITE via the default MAX_WRITE permission when the caller granting it genuinely has write access, even though the delegate already has READ', function () {
|
|
221
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
222
|
+
const testSetupApi = yield initMasterApi(env);
|
|
223
|
+
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
224
|
+
const pId = pInfo.credentials.dataOwnerId;
|
|
225
|
+
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
226
|
+
// B genuinely holds P's key (so it can verify P's existing READ coverage directly) and gets its own real
|
|
227
|
+
// WRITE-level delegation from A (the default MAX_WRITE, since A itself has full write access). B has never
|
|
228
|
+
// shared anything with P before, so its re-share below creates a brand new delegation rather than updating an
|
|
229
|
+
// existing one - unlike a same-caller re-share, a new delegation's permissions aren't limited to a content diff.
|
|
230
|
+
const bInfo = yield createChildOfParent(testSetupApi, pId, {
|
|
231
|
+
privateKey: pInfo.credentials.privateKey,
|
|
232
|
+
publicKey: pInfo.credentials.publicKey,
|
|
233
|
+
});
|
|
234
|
+
const created = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
235
|
+
const secretId = (yield aInfo.api.patientApi.decryptSecretIdsOf(created))[0];
|
|
236
|
+
const sharedReadOnly = yield aInfo.api.patientApi.shareWith(pId, created, [secretId], {
|
|
237
|
+
requestedPermissions: RequestedPermissionEnum.FULL_READ,
|
|
238
|
+
});
|
|
239
|
+
(0, chai_1.expect)(yield pInfo.api.patientApi.hasWriteAccess(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, sharedReadOnly.id))).to.be.false;
|
|
240
|
+
const sharedWithB = yield aInfo.api.patientApi.shareWithMany(sharedReadOnly, { [bInfo.id]: { shareSecretIds: [secretId] } });
|
|
241
|
+
// B (fresh caller for P, genuinely has WRITE) re-shares at the default MAX_WRITE - resolves to WRITE, a real
|
|
242
|
+
// upgrade over P's existing READ, even though the content itself is already fully covered.
|
|
243
|
+
const freshForB = yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id);
|
|
244
|
+
const upgraded = yield bInfo.api.patientApi.shareWith(pId, freshForB, [secretId]);
|
|
245
|
+
(0, chai_1.expect)(upgraded.rev).to.not.equal(freshForB.rev);
|
|
246
|
+
(0, chai_1.expect)(yield pInfo.api.patientApi.hasWriteAccess(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, upgraded.id))).to.be.true;
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
//# sourceMappingURL=share-deduplication-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-deduplication-test.js","sourceRoot":"","sources":["../../../../test/icc-x-api/crypto/share-deduplication-test.ts"],"names":[],"mappings":"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","sourcesContent":["import { createNewHcpApi, getEnvironmentInitializer, setLocalStorage, TestUtils } from '../../utils/test_utils'\nimport { randomUUID, webcrypto } from 'crypto'\nimport { expect } from 'chai'\nimport 'isomorphic-fetch'\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { IcureApi, ShaVersion } from '../../../icc-x-api'\nimport { User } from '../../../icc-api/model/User'\nimport { testStorageWithKeys } from '../../utils/TestStorage'\nimport { TestCryptoStrategies } from '../../utils/TestCryptoStrategies'\nimport { EntityShareRequest } from '../../../icc-api/model/requests/EntityShareRequest'\nimport initMasterApi = TestUtils.initMasterApi\nimport RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum\n\nsetLocalStorage(fetch)\n\nlet env: TestVars\n\n/**\n * Creates a fresh hcp (random keypair) and makes it a child of parentId, to establish the existing\n * relationship that operations such as mergePatients require between data owners in order to\n * authorize the operation (an entirely unrelated hcp gets a 403).\n *\n * By default this does NOT give the child a locally-held copy of the parent's key\n * (disableParentKeysInitialisation skips the startup check that would otherwise require one): in\n * tests where we only care about the authorization relationship, we don't want the child to also\n * be able to reach anything shared with the parent through a locally-cached parent key, which\n * would muddy visibility assertions.\n * Pass parentKeys for tests that specifically want to exercise genuine hierarchical inheritance (a\n * child that has actually verified/cached its parent's key, like a properly provisioned device in\n * the same care organisation).\n */\nasync function createChildOfParent(\n testSetupApi: IcureApi,\n parentId: string,\n parentKeys?: { privateKey: string; publicKey: string }\n): Promise<{ api: IcureApi; user: User; id: string }> {\n const info = await createNewHcpApi(env)\n await testSetupApi.healthcarePartyApi.modifyHealthcareParty({\n ...(await testSetupApi.healthcarePartyApi.getHealthcareParty(info.credentials.dataOwnerId)),\n parentId,\n })\n const storage = await testStorageWithKeys([\n {\n dataOwnerId: info.credentials.dataOwnerId,\n pairs: [{ keyPair: { privateKey: info.credentials.privateKey, publicKey: info.credentials.publicKey }, shaVersion: ShaVersion.Sha1 }],\n },\n ...(parentKeys ? [{ dataOwnerId: parentId, pairs: [{ keyPair: parentKeys, shaVersion: ShaVersion.Sha1 }] }] : []),\n ])\n const api = await IcureApi.initialise(\n env.iCureUrl,\n { username: info.credentials.user, password: info.credentials.password },\n new TestCryptoStrategies(),\n webcrypto as any,\n fetch,\n { storage: storage.storage, keyStorage: storage.keyStorage, entryKeysFactory: storage.keyFactory, disableParentKeysInitialisation: !parentKeys }\n )\n const user = await api.userApi.getCurrentUser()\n return { api, user, id: info.credentials.dataOwnerId }\n}\n\n/*\n * shareWith/shareWithMany should skip writing a delegation only when the target already has DIRECT access -\n * named as either party of a specific, already-decryptable-by-the-caller delegation edge - never inferred via\n * hierarchy, and never conflating content coverage with permission sufficiency (the two are independent: the\n * backend only checks \"is there at least one delegation naming this data owner with write access\", it never\n * correlates that with which specific secret id/encryption key a delegation happens to carry).\n */\ndescribe('shareWith/shareWithMany only skip writes when the delegate has genuinely direct, decryptable access', function () {\n before(async function () {\n this.timeout(600000)\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n })\n\n it('still writes when an unrelated third party X (who was separately given access by A) tries to reshare with P, since X cannot decrypt the A->P delegation', async function () {\n const aInfo = await createNewHcpApi(env)\n const pInfo = await createNewHcpApi(env)\n const xInfo = await createNewHcpApi(env)\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedWithP = await aInfo.api.patientApi.shareWithMany(created, {\n [pInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },\n })\n const sharedWithX = await aInfo.api.patientApi.shareWithMany(sharedWithP, {\n [xInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },\n })\n\n const freshForX = await xInfo.api.patientApi.getPatientWithUser(xInfo.user, sharedWithX.id!)\n const reshared = await xInfo.api.patientApi.shareWith(pInfo.credentials.dataOwnerId, freshForX, [secretId])\n expect(reshared.rev).to.not.equal(freshForX.rev)\n })\n\n it('still shares directly with B even though P (a shared parent that already has the content, and B is a child of) already has it', async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n const aInfo = await createChildOfParent(testSetupApi, pId)\n const bInfo = await createChildOfParent(testSetupApi, pId)\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedWithP = await aInfo.api.patientApi.shareWithMany(created, { [pId]: { shareSecretIds: [secretId] } })\n\n const freshForA = await aInfo.api.patientApi.getPatientWithUser(aInfo.user, sharedWithP.id!)\n const sharedWithB = await aInfo.api.patientApi.shareWith(bInfo.id, freshForA, [secretId])\n expect(sharedWithB.rev).to.not.equal(freshForA.rev)\n expect(await bInfo.api.patientApi.decryptSecretIdsOf(await bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id!))).to.have.members(\n [secretId]\n )\n })\n\n it('still writes when A shares directly with Y, even though only an unrelated X->Y delegation (which A cannot decrypt) already covers it', async function () {\n const aInfo = await createNewHcpApi(env)\n const xInfo = await createNewHcpApi(env)\n const yInfo = await createNewHcpApi(env)\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedWithX = await aInfo.api.patientApi.shareWithMany(created, {\n [xInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },\n })\n\n const freshForX = await xInfo.api.patientApi.getPatientWithUser(xInfo.user, sharedWithX.id!)\n const sharedWithY = await xInfo.api.patientApi.shareWithMany(freshForX, {\n [yInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },\n })\n\n const freshForA = await aInfo.api.patientApi.getPatientWithUser(aInfo.user, sharedWithY.id!)\n const aSharesWithY = await aInfo.api.patientApi.shareWith(yInfo.credentials.dataOwnerId, freshForA, [secretId])\n expect(aSharesWithY.rev).to.not.equal(freshForA.rev)\n })\n\n it('is a no-op when B shares content back with A, since A->B delegations are symmetric and A can decrypt its own', async function () {\n const aInfo = await createNewHcpApi(env)\n const bInfo = await createNewHcpApi(env)\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedWithB = await aInfo.api.patientApi.shareWithMany(created, {\n [bInfo.credentials.dataOwnerId]: { shareSecretIds: [secretId] },\n })\n\n const freshForB = await bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id!)\n const bSharesBackWithA = await bInfo.api.patientApi.shareWith(aInfo.credentials.dataOwnerId, freshForB, [secretId])\n expect(bSharesBackWithA.rev).to.equal(freshForB.rev)\n })\n\n it('still writes a permission-only grant when the delegate already has the content, but only at an insufficient permission level', async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n const aInfo = await createChildOfParent(testSetupApi, pId)\n // B genuinely holds P's key (like a properly provisioned device), so it can verify P's existing coverage\n // directly rather than relying on any hierarchy inference. B also needs its own, real write-level delegation\n // on the entity (from A) - merely being able to decrypt via a borrowed key is not enough for the backend to\n // authorize B to grant permissions to someone else; B must have genuine recorded access of its own too.\n const bInfo = await createChildOfParent(testSetupApi, pId, {\n privateKey: pInfo.credentials.privateKey,\n publicKey: pInfo.credentials.publicKey,\n })\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedReadOnly = await aInfo.api.patientApi.shareWith(pId, created, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_READ,\n })\n expect(await pInfo.api.patientApi.hasWriteAccess(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, sharedReadOnly.id!))).to.be.false\n const sharedWithB = await aInfo.api.patientApi.shareWithMany(sharedReadOnly, { [bInfo.id]: { shareSecretIds: [secretId] } })\n\n const freshForB = await bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id!)\n const upgraded = await bInfo.api.patientApi.shareWith(pId, freshForB, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_WRITE,\n })\n expect(upgraded.rev).to.not.equal(freshForB.rev)\n expect(await pInfo.api.patientApi.hasWriteAccess(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, upgraded.id!))).to.be.true\n })\n\n it('is a no-op when the delegate already has the content at a sufficient permission level, verified via a different, unrelated caller', async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n const aInfo = await createChildOfParent(testSetupApi, pId)\n const parentKeys = { privateKey: pInfo.credentials.privateKey, publicKey: pInfo.credentials.publicKey }\n const bInfo = await createChildOfParent(testSetupApi, pId, parentKeys)\n const cInfo = await createChildOfParent(testSetupApi, pId, parentKeys)\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedReadOnly = await aInfo.api.patientApi.shareWith(pId, created, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_READ,\n })\n // B and C each need their own real write-level delegation on the entity (from A) to be authorized to grant\n // permissions to someone else - merely holding P's key for decryption purposes is not enough on its own.\n const sharedWithBAndC = await aInfo.api.patientApi.shareWithMany(sharedReadOnly, {\n [bInfo.id]: { shareSecretIds: [secretId] },\n [cInfo.id]: { shareSecretIds: [secretId] },\n })\n const freshForB = await bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithBAndC.id!)\n const upgraded = await bInfo.api.patientApi.shareWith(pId, freshForB, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_WRITE,\n })\n\n // C never shared anything with P itself, but (via P's key) can verify P already has the content at a\n // sufficient (WRITE) permission now - requesting only FULL_READ should be a true no-op.\n const freshForC = await cInfo.api.patientApi.getPatientWithUser(cInfo.user, upgraded.id!)\n const reshared = await cInfo.api.patientApi.shareWith(pId, freshForC, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_READ,\n })\n expect(reshared.rev).to.equal(freshForC.rev)\n })\n\n it('is a no-op when re-sharing at the default MAX_WRITE permission would only resolve to READ anyway, since the caller granting it has no write access itself', async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n const aInfo = await createChildOfParent(testSetupApi, pId)\n // X genuinely holds P's key, so it can verify P's existing coverage directly, and only ever gets FULL_READ\n // access itself from A - MAX_WRITE resolves to \"WRITE if the caller granting it has WRITE, else READ\", so a\n // MAX_WRITE request from X could never exceed READ, matching what P already has: nothing would change.\n const xInfo = await createChildOfParent(testSetupApi, pId, { privateKey: pInfo.credentials.privateKey, publicKey: pInfo.credentials.publicKey })\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedWithP = await aInfo.api.patientApi.shareWith(pId, created, [secretId], { requestedPermissions: RequestedPermissionEnum.FULL_READ })\n const sharedWithX = await aInfo.api.patientApi.shareWith(xInfo.id, sharedWithP, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_READ,\n })\n\n const freshForX = await xInfo.api.patientApi.getPatientWithUser(xInfo.user, sharedWithX.id!)\n const reshared = await xInfo.api.patientApi.shareWith(pId, freshForX, [secretId]) // default requestedPermissions: MAX_WRITE\n expect(reshared.rev).to.equal(freshForX.rev)\n })\n\n it('still upgrades the delegate to WRITE via the default MAX_WRITE permission when the caller granting it genuinely has write access, even though the delegate already has READ', async function () {\n const testSetupApi = await initMasterApi(env)\n const pInfo = await createNewHcpApi(env)\n const pId = pInfo.credentials.dataOwnerId\n const aInfo = await createChildOfParent(testSetupApi, pId)\n // B genuinely holds P's key (so it can verify P's existing READ coverage directly) and gets its own real\n // WRITE-level delegation from A (the default MAX_WRITE, since A itself has full write access). B has never\n // shared anything with P before, so its re-share below creates a brand new delegation rather than updating an\n // existing one - unlike a same-caller re-share, a new delegation's permissions aren't limited to a content diff.\n const bInfo = await createChildOfParent(testSetupApi, pId, {\n privateKey: pInfo.credentials.privateKey,\n publicKey: pInfo.credentials.publicKey,\n })\n\n const created = await aInfo.api.patientApi.createPatientWithUser(\n aInfo.user,\n await aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' })\n )\n const secretId = (await aInfo.api.patientApi.decryptSecretIdsOf(created))[0]\n const sharedReadOnly = await aInfo.api.patientApi.shareWith(pId, created, [secretId], {\n requestedPermissions: RequestedPermissionEnum.FULL_READ,\n })\n expect(await pInfo.api.patientApi.hasWriteAccess(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, sharedReadOnly.id!))).to.be.false\n const sharedWithB = await aInfo.api.patientApi.shareWithMany(sharedReadOnly, { [bInfo.id]: { shareSecretIds: [secretId] } })\n\n // B (fresh caller for P, genuinely has WRITE) re-shares at the default MAX_WRITE - resolves to WRITE, a real\n // upgrade over P's existing READ, even though the content itself is already fully covered.\n const freshForB = await bInfo.api.patientApi.getPatientWithUser(bInfo.user, sharedWithB.id!)\n const upgraded = await bInfo.api.patientApi.shareWith(pId, freshForB, [secretId])\n expect(upgraded.rev).to.not.equal(freshForB.rev)\n expect(await pInfo.api.patientApi.hasWriteAccess(await pInfo.api.patientApi.getPatientWithUser(pInfo.user, upgraded.id!))).to.be.true\n })\n})\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'isomorphic-fetch';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const uuid_1 = require("uuid");
|
|
13
|
+
const User_1 = require("../../../icc-api/model/User");
|
|
14
|
+
const mocha_1 = require("mocha");
|
|
15
|
+
const crypto_1 = require("crypto");
|
|
16
|
+
require("isomorphic-fetch");
|
|
17
|
+
const icc_api_1 = require("../../../icc-api");
|
|
18
|
+
const chai_1 = require("chai");
|
|
19
|
+
const test_utils_1 = require("../../utils/test_utils");
|
|
20
|
+
const TestStorage_1 = require("../../utils/TestStorage");
|
|
21
|
+
const TestCryptoStrategies_1 = require("../../utils/TestCryptoStrategies");
|
|
22
|
+
const types_1 = require("@icure/test-setup/types");
|
|
23
|
+
const icc_x_api_1 = require("../../../icc-x-api");
|
|
24
|
+
const icc_x_api_2 = require("../../../icc-x-api");
|
|
25
|
+
(0, test_utils_1.setLocalStorage)(fetch);
|
|
26
|
+
let env;
|
|
27
|
+
(0, mocha_1.describe)('Full battery of tests on crypto and keys', function () {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
this.timeout(600000);
|
|
30
|
+
(0, mocha_1.before)(function () {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
|
|
33
|
+
env = yield initializer.execute((0, types_1.getEnvVariables)());
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
(0, mocha_1.it)(`Share patient from hcp to patient`, () => __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
var _a;
|
|
38
|
+
const { childApi: api, childUser: u } = yield (0, test_utils_1.createHcpHierarchyApis)(env);
|
|
39
|
+
const patient = yield api.patientApi.createPatientWithUser(u, yield api.patientApi.newInstance(u, { id: (0, uuid_1.v4)(), firstName: 'test', lastName: 'test', note: 'secure' }));
|
|
40
|
+
const heNote = 'Some encrypted note';
|
|
41
|
+
const he = yield api.healthcareElementApi.createHealthElementWithUser(u, yield api.healthcareElementApi.newInstance(u, patient, { note: heNote }));
|
|
42
|
+
const check = yield api.patientApi.getPatientWithUser(u, patient.id);
|
|
43
|
+
(0, chai_1.expect)(check.note).to.equal('secure');
|
|
44
|
+
const newPatientUser = yield api.userApi.createUser(new User_1.User({
|
|
45
|
+
id: `user-${patient.id}-patient`,
|
|
46
|
+
login: `patient-${patient.id}`,
|
|
47
|
+
status: 'ACTIVE',
|
|
48
|
+
passwordHash: 'LetMeInForReal',
|
|
49
|
+
patientId: patient.id,
|
|
50
|
+
}));
|
|
51
|
+
const apiAsPatient = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: newPatientUser.login, password: 'LetMeInForReal' }, new TestCryptoStrategies_1.TestCryptoStrategies(yield api.cryptoApi.primitives.RSA.generateKeyPair(icc_x_api_1.ShaVersion.Sha256)), crypto_1.webcrypto, fetch, {
|
|
52
|
+
storage: new TestStorage_1.TestStorage(),
|
|
53
|
+
keyStorage: new TestStorage_1.TestKeyStorage(),
|
|
54
|
+
});
|
|
55
|
+
const patientBaseApi = new icc_api_1.IccPatientApi(env.iCureUrl, {}, new icc_x_api_2.BasicAuthenticationProvider(newPatientUser.login, 'LetMeInForReal'));
|
|
56
|
+
const pat = yield patientBaseApi.getPatient(patient.id);
|
|
57
|
+
(0, chai_1.expect)((_a = pat.note) !== null && _a !== void 0 ? _a : undefined).to.be.undefined;
|
|
58
|
+
yield api.patientApi.shareAllDataOfPatient(u, patient.id, u.healthcarePartyId, [patient.id], { [patient.id]: ['all'] });
|
|
59
|
+
yield apiAsPatient.cryptoApi.forceReload();
|
|
60
|
+
const patUser = yield apiAsPatient.userApi.getCurrentUser();
|
|
61
|
+
const entity = yield apiAsPatient.patientApi.getPatientWithUser(patUser, patient.id);
|
|
62
|
+
const retrievedHe = yield apiAsPatient.healthcareElementApi.getHealthElementWithUser(patUser, he.id);
|
|
63
|
+
(0, chai_1.expect)(entity.id).to.be.not.null;
|
|
64
|
+
(0, chai_1.expect)(entity.rev).to.be.not.null;
|
|
65
|
+
(0, chai_1.expect)(entity.note).to.equal('secure');
|
|
66
|
+
(0, chai_1.expect)(retrievedHe.id).to.equal(he.id);
|
|
67
|
+
(0, chai_1.expect)(retrievedHe.note).to.equal(heNote);
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=share-to-newly-created-patient-from-hcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-to-newly-created-patient-from-hcp.js","sourceRoot":"","sources":["../../../../test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuid } from 'uuid'\nimport { User } from '../../../icc-api/model/User'\nimport { before, describe, it } from 'mocha'\n\nimport { webcrypto } from 'crypto'\nimport 'isomorphic-fetch'\n\nimport { IccPatientApi } from '../../../icc-api'\nimport { expect } from 'chai'\n\nimport { createHcpHierarchyApis, getEnvironmentInitializer, setLocalStorage } from '../../utils/test_utils'\nimport { TestKeyStorage, TestStorage } from '../../utils/TestStorage'\nimport { TestCryptoStrategies } from '../../utils/TestCryptoStrategies'\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { IcureApi, ShaVersion } from '../../../icc-x-api'\nimport { BasicAuthenticationProvider } from '../../../icc-x-api'\n\nsetLocalStorage(fetch)\n\nlet env: TestVars\n\ndescribe('Full battery of tests on crypto and keys', async function () {\n this.timeout(600000)\n\n before(async function () {\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n })\n\n it(`Share patient from hcp to patient`, async () => {\n const { childApi: api, childUser: u } = await createHcpHierarchyApis(env!)\n\n const patient = await api.patientApi.createPatientWithUser(\n u,\n await api.patientApi.newInstance(u, { id: uuid(), firstName: 'test', lastName: 'test', note: 'secure' })\n )\n const heNote = 'Some encrypted note'\n const he = await api.healthcareElementApi.createHealthElementWithUser(u, await api.healthcareElementApi.newInstance(u, patient, { note: heNote }))\n const check = await api.patientApi.getPatientWithUser(u, patient.id)\n\n expect(check.note).to.equal('secure')\n\n const newPatientUser = await api.userApi.createUser(\n new User({\n id: `user-${patient.id}-patient`,\n login: `patient-${patient.id}`,\n status: 'ACTIVE',\n passwordHash: 'LetMeInForReal',\n patientId: patient.id,\n })\n )\n\n const apiAsPatient = await IcureApi.initialise(\n env!.iCureUrl,\n { username: newPatientUser.login!, password: 'LetMeInForReal' },\n new TestCryptoStrategies(await api.cryptoApi.primitives.RSA.generateKeyPair(ShaVersion.Sha256)),\n webcrypto as unknown as Crypto,\n fetch,\n {\n storage: new TestStorage(),\n keyStorage: new TestKeyStorage(),\n }\n )\n\n const patientBaseApi = new IccPatientApi(env!.iCureUrl, {}, new BasicAuthenticationProvider(newPatientUser.login!, 'LetMeInForReal'))\n\n const pat = await patientBaseApi.getPatient(patient.id)\n\n expect(pat.note ?? undefined).to.be.undefined\n\n await api.patientApi.shareAllDataOfPatient(u, patient.id, u.healthcarePartyId!, [patient.id], { [patient.id]: ['all'] })\n await apiAsPatient.cryptoApi.forceReload()\n const patUser = await apiAsPatient.userApi.getCurrentUser()\n const entity = await apiAsPatient.patientApi.getPatientWithUser(patUser, patient.id)\n const retrievedHe = await apiAsPatient.healthcareElementApi.getHealthElementWithUser(patUser, he.id!)\n\n expect(entity.id).to.be.not.null\n expect(entity.rev).to.be.not.null\n expect(entity.note).to.equal('secure')\n expect(retrievedHe.id).to.equal(he.id)\n expect(retrievedHe.note).to.equal(heNote)\n })\n})\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("isomorphic-fetch");
|
|
13
|
+
require("mocha");
|
|
14
|
+
const test_utils_1 = require("../../utils/test_utils");
|
|
15
|
+
const mocha_1 = require("mocha");
|
|
16
|
+
const types_1 = require("@icure/test-setup/types");
|
|
17
|
+
const icc_x_api_1 = require("../../../icc-x-api");
|
|
18
|
+
const crypto_1 = require("crypto");
|
|
19
|
+
const HealthcareParty_1 = require("../../../icc-api/model/HealthcareParty");
|
|
20
|
+
const TestApi_1 = require("../../utils/TestApi");
|
|
21
|
+
const chai_1 = require("chai");
|
|
22
|
+
(0, test_utils_1.setLocalStorage)(fetch);
|
|
23
|
+
describe('SDL in an environment with soft-deleted data owners', function () {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
this.timeout(600000);
|
|
26
|
+
let env;
|
|
27
|
+
let masterApi;
|
|
28
|
+
let primitives;
|
|
29
|
+
// Test values, not real data
|
|
30
|
+
const pubKeyHex = '30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001'; // pragma: allowlist secret
|
|
31
|
+
const privKeyHex = '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001028201000189beeb385a9652e212e03f4e5ca84579f7b5e4aeb2a893e3fbae54db4babf8f2285692fbb206a171e3a32d889a83b4dcc2d725084d8b1c1bc58548f88e2c1b890187c23293c73163cafa82e43490d080558c78ebc8fab2ddda5b829efa1b0813ecb9a24bf22eb54e47a532aacdd70d587b59bac79c146d7759e8c52aeb774603f4b282e699aca98793aa0086233a8aafc8fad58b62df011f33c1dcc6efdfc9aa51f4f11ea450ba5e02f9b69de33c756f3504ff086d2e58c25db871e3c021ee3720837466bb41d886bd4300eeac41742206110158578315d29a527b520e11ec6f7e98558931bdde63a4402635473244fa9764bb3527ff33473ff08f63b3a94102818100c8032014c593f8aecc15287d3dfd6143c75e8fb27faf7944fa030016b26fa5133d8e0d13a5244bcd6155ba29258a498e44fef239dc75dee9db4756c9a2b2be93cf2c67049ff2b2f5cbf949960e44e3fc56c90a66485ec22079a0eb864100404e0d7ea96f21ced9793633d87c49056be4c507768d51c310f69605befec087bbcd02818100d380b7a8cbc5a87c5d91e1497949acfe3c61671b31bc4c54f2f8e8cd8e709a617b49d1e7d6c0333fbb42af119db8660d1a58165e716b976bebdb12104c0dba951719f8c6711e84b704bcdd80248a767609680e4ff125126a23bbee5362f88d881c5c24c5ff0400edde1dd7044fd0d5d06a9cda33a1004daad7df8aa2eb63a5b90281801d0ab721ccfe8b617628ac546327e373a0034f0230201e8fb16db61995973874eebf2d8ee8afb881fddc20c7d0b79fae94be2015deb90ec10e21f1ac1d7faec46f9496f0c8f8c89b801e965cbf7da94cfe9cfa7197988abf8469a5493d2ef8275d36430bebf0c90b1c9fb2937956dc2fbf9c31ce9b4ca3adea62b334f267c3110281806453facb275e6bbe12e4d0697a0f68f070d40384f2e2cf92bc6f367fcbc1be79df71f51074de577133f33df8ad487ba05b8ecd8d9f5fda44676d53f4471f7c129d12c4dfdd690cab84a3d2aea6a6c7ead62b761e95d57016c93caca101a1c6017af27abf316944c79145b66965333b39d258f568e846ac910e360c1d9c6b788102818100879751ba5fe91d86410037ca9df05b2bb689734af710ab50a75b1aa1083dd596f295d710ba630c9fbfe6dcdedd8f0fca22595f8723376e72721c01275572692ebd2d5b39d5715ea052ed0968a9dabb76f7eef7c4c894a5031ae237772c21b62a43322e324c793fccf8b3abe340ca029e54255ed735549918352f3abaaf0850b7'; // pragma: allowlist secret
|
|
32
|
+
const deletedOtherId = 'dc88f05e-6f9f-4203-bc8d-59b1737322f4'; // pragma: allowlist secret
|
|
33
|
+
const exchangeKeySelf = '6aac0c669a4423d5fed7c8d5a434ddf70e8f9ab34db8104cf88d810a535f2701'; // pragma: allowlist secret
|
|
34
|
+
const exchangeKeyOther = '24a58ab4837d2a7dbed477abf03c87816dfbae113604a1e3d93093194291907e'; // pragma: allowlist secret
|
|
35
|
+
function makeTestHcp(props) {
|
|
36
|
+
const hcpId = primitives.randomUuid();
|
|
37
|
+
return new HealthcareParty_1.HealthcareParty({
|
|
38
|
+
id: hcpId,
|
|
39
|
+
name: `Test-${primitives.randomUuid()}`,
|
|
40
|
+
hcPartyKeys: props.includeHcPartyKeys
|
|
41
|
+
? {
|
|
42
|
+
[hcpId]: [
|
|
43
|
+
'785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret
|
|
44
|
+
'785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret
|
|
45
|
+
],
|
|
46
|
+
'dc88f05e-6f9f-4203-bc8d-59b1737322f4': [
|
|
47
|
+
// pragma: allowlist secret
|
|
48
|
+
'9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7', // pragma: allowlist secret
|
|
49
|
+
'27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret
|
|
50
|
+
],
|
|
51
|
+
}
|
|
52
|
+
: {},
|
|
53
|
+
aesExchangeKeys: props.includeAesExchangeKeys
|
|
54
|
+
? {
|
|
55
|
+
// pragma: allowlist nextline secret
|
|
56
|
+
'30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001': {
|
|
57
|
+
[hcpId]: {
|
|
58
|
+
// pragma: allowlist secret
|
|
59
|
+
ccc08799369fcd6d68d8250203010001: '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret
|
|
60
|
+
},
|
|
61
|
+
'dc88f05e-6f9f-4203-bc8d-59b1737322f4': {
|
|
62
|
+
// pragma: allowlist secret
|
|
63
|
+
// pragma: allowlist secret
|
|
64
|
+
ccc08799369fcd6d68d8250203010001: '9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7', // pragma: allowlist secret
|
|
65
|
+
// pragma: allowlist nextline secret
|
|
66
|
+
'0c8b6fa8a116ecfee683b10203010001': '27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
: {},
|
|
71
|
+
publicKey: pubKeyHex,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
(0, mocha_1.before)(function () {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
|
|
77
|
+
env = yield initializer.execute((0, types_1.getEnvVariables)());
|
|
78
|
+
masterApi = yield test_utils_1.TestUtils.initMasterApi(env);
|
|
79
|
+
primitives = masterApi.cryptoApi.primitives;
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
function doLegacyKeysTestWithDeletedDataOwner(hcp) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
const userPw = primitives.randomUuid();
|
|
85
|
+
const user = yield masterApi.userApi.createUser({
|
|
86
|
+
id: primitives.randomUuid(),
|
|
87
|
+
email: `${primitives.randomUuid()}@test.icure.com`,
|
|
88
|
+
passwordHash: userPw,
|
|
89
|
+
healthcarePartyId: hcp.id,
|
|
90
|
+
});
|
|
91
|
+
const hcpKeypair = yield primitives.RSA.importKeyPair('pkcs8', (0, icc_x_api_1.ua2ab)((0, icc_x_api_1.hex2ua)(privKeyHex)), 'spki', (0, icc_x_api_1.ua2ab)((0, icc_x_api_1.hex2ua)(pubKeyHex)), icc_x_api_1.ShaVersion.Sha1);
|
|
92
|
+
const testApi = yield (0, TestApi_1.TestApi)(env.iCureUrl, user.email, userPw, crypto_1.webcrypto, hcpKeypair);
|
|
93
|
+
const selfKeys = yield testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id, hcp.id);
|
|
94
|
+
(0, chai_1.expect)(selfKeys.length).to.eq(1);
|
|
95
|
+
const selfKeyHex = (0, icc_x_api_1.ua2hex)(yield primitives.AES.exportKey(selfKeys[0], 'raw'));
|
|
96
|
+
(0, chai_1.expect)(selfKeyHex).to.eq(exchangeKeySelf);
|
|
97
|
+
const delegateKeys = yield testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id, deletedOtherId);
|
|
98
|
+
(0, chai_1.expect)(delegateKeys.length).to.eq(1);
|
|
99
|
+
const delegateKeysHex = (0, icc_x_api_1.ua2hex)(yield primitives.AES.exportKey(delegateKeys[0], 'raw'));
|
|
100
|
+
(0, chai_1.expect)(delegateKeysHex).to.eq(exchangeKeyOther);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
it('hcp with hcPartyKeys to soft-deleted user', () => __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
const hcp = yield masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeHcPartyKeys: true }));
|
|
105
|
+
yield doLegacyKeysTestWithDeletedDataOwner(hcp);
|
|
106
|
+
}));
|
|
107
|
+
it('hcp with aesExchangeKeys to soft-deleted user', () => __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
const hcp = yield masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeAesExchangeKeys: true }));
|
|
109
|
+
yield doLegacyKeysTestWithDeletedDataOwner(hcp);
|
|
110
|
+
}));
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=soft-deleted-data-owners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft-deleted-data-owners.js","sourceRoot":"","sources":["../../../../test/icc-x-api/crypto/soft-deleted-data-owners.ts"],"names":[],"mappings":"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","sourcesContent":["import 'isomorphic-fetch'\nimport 'mocha'\nimport { createNewHcpApi, getEnvironmentInitializer, setLocalStorage, TestUtils } from '../../utils/test_utils'\nimport { before } from 'mocha'\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { CryptoPrimitives, hex2ua, IcureApi, ShaVersion, ua2ab, ua2hex } from '../../../icc-x-api'\nimport { randomUUID, webcrypto } from 'crypto'\nimport { HealthcareParty } from '../../../icc-api/model/HealthcareParty'\nimport { TestApi } from '../../utils/TestApi'\nimport { he } from 'date-fns/locale'\nimport { expect } from 'chai'\n\nsetLocalStorage(fetch)\n\ndescribe('SDL in an environment with soft-deleted data owners', async function () {\n this.timeout(600000)\n let env: TestVars\n let masterApi: IcureApi\n let primitives: CryptoPrimitives\n\n // Test values, not real data\n const pubKeyHex =\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001' // pragma: allowlist secret\n const privKeyHex =\n '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001028201000189beeb385a9652e212e03f4e5ca84579f7b5e4aeb2a893e3fbae54db4babf8f2285692fbb206a171e3a32d889a83b4dcc2d725084d8b1c1bc58548f88e2c1b890187c23293c73163cafa82e43490d080558c78ebc8fab2ddda5b829efa1b0813ecb9a24bf22eb54e47a532aacdd70d587b59bac79c146d7759e8c52aeb774603f4b282e699aca98793aa0086233a8aafc8fad58b62df011f33c1dcc6efdfc9aa51f4f11ea450ba5e02f9b69de33c756f3504ff086d2e58c25db871e3c021ee3720837466bb41d886bd4300eeac41742206110158578315d29a527b520e11ec6f7e98558931bdde63a4402635473244fa9764bb3527ff33473ff08f63b3a94102818100c8032014c593f8aecc15287d3dfd6143c75e8fb27faf7944fa030016b26fa5133d8e0d13a5244bcd6155ba29258a498e44fef239dc75dee9db4756c9a2b2be93cf2c67049ff2b2f5cbf949960e44e3fc56c90a66485ec22079a0eb864100404e0d7ea96f21ced9793633d87c49056be4c507768d51c310f69605befec087bbcd02818100d380b7a8cbc5a87c5d91e1497949acfe3c61671b31bc4c54f2f8e8cd8e709a617b49d1e7d6c0333fbb42af119db8660d1a58165e716b976bebdb12104c0dba951719f8c6711e84b704bcdd80248a767609680e4ff125126a23bbee5362f88d881c5c24c5ff0400edde1dd7044fd0d5d06a9cda33a1004daad7df8aa2eb63a5b90281801d0ab721ccfe8b617628ac546327e373a0034f0230201e8fb16db61995973874eebf2d8ee8afb881fddc20c7d0b79fae94be2015deb90ec10e21f1ac1d7faec46f9496f0c8f8c89b801e965cbf7da94cfe9cfa7197988abf8469a5493d2ef8275d36430bebf0c90b1c9fb2937956dc2fbf9c31ce9b4ca3adea62b334f267c3110281806453facb275e6bbe12e4d0697a0f68f070d40384f2e2cf92bc6f367fcbc1be79df71f51074de577133f33df8ad487ba05b8ecd8d9f5fda44676d53f4471f7c129d12c4dfdd690cab84a3d2aea6a6c7ead62b761e95d57016c93caca101a1c6017af27abf316944c79145b66965333b39d258f568e846ac910e360c1d9c6b788102818100879751ba5fe91d86410037ca9df05b2bb689734af710ab50a75b1aa1083dd596f295d710ba630c9fbfe6dcdedd8f0fca22595f8723376e72721c01275572692ebd2d5b39d5715ea052ed0968a9dabb76f7eef7c4c894a5031ae237772c21b62a43322e324c793fccf8b3abe340ca029e54255ed735549918352f3abaaf0850b7' // pragma: allowlist secret\n const deletedOtherId = 'dc88f05e-6f9f-4203-bc8d-59b1737322f4' // pragma: allowlist secret\n const exchangeKeySelf = '6aac0c669a4423d5fed7c8d5a434ddf70e8f9ab34db8104cf88d810a535f2701' // pragma: allowlist secret\n const exchangeKeyOther = '24a58ab4837d2a7dbed477abf03c87816dfbae113604a1e3d93093194291907e' // pragma: allowlist secret\n function makeTestHcp(props: { includeHcPartyKeys?: boolean; includeAesExchangeKeys?: boolean }): HealthcareParty {\n const hcpId = primitives.randomUuid()\n return new HealthcareParty({\n id: hcpId,\n name: `Test-${primitives.randomUuid()}`,\n hcPartyKeys: props.includeHcPartyKeys\n ? {\n [hcpId]: [\n '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret\n '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret\n ],\n 'dc88f05e-6f9f-4203-bc8d-59b1737322f4': [\n // pragma: allowlist secret\n '9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7', // pragma: allowlist secret\n '27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret\n ],\n }\n : {},\n aesExchangeKeys: props.includeAesExchangeKeys\n ? {\n // pragma: allowlist nextline secret\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001':\n {\n [hcpId]: {\n // pragma: allowlist secret\n ccc08799369fcd6d68d8250203010001:\n '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret\n },\n 'dc88f05e-6f9f-4203-bc8d-59b1737322f4': {\n // pragma: allowlist secret\n // pragma: allowlist secret\n ccc08799369fcd6d68d8250203010001:\n '9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7', // pragma: allowlist secret\n // pragma: allowlist nextline secret\n '0c8b6fa8a116ecfee683b10203010001':\n '27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret\n },\n },\n }\n : {},\n publicKey: pubKeyHex,\n })\n }\n\n before(async function () {\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n masterApi = await TestUtils.initMasterApi(env)\n primitives = masterApi.cryptoApi.primitives\n })\n\n async function doLegacyKeysTestWithDeletedDataOwner(hcp: HealthcareParty) {\n const userPw = primitives.randomUuid()\n const user = await masterApi.userApi.createUser({\n id: primitives.randomUuid(),\n email: `${primitives.randomUuid()}@test.icure.com`,\n passwordHash: userPw,\n healthcarePartyId: hcp.id!,\n })\n const hcpKeypair = await primitives.RSA.importKeyPair('pkcs8', ua2ab(hex2ua(privKeyHex)), 'spki', ua2ab(hex2ua(pubKeyHex)), ShaVersion.Sha1)\n const testApi = await TestApi(env.iCureUrl, user.email!, userPw, webcrypto as any, hcpKeypair)\n const selfKeys = await testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id!, hcp.id!)\n expect(selfKeys.length).to.eq(1)\n const selfKeyHex = ua2hex(await primitives.AES.exportKey(selfKeys[0], 'raw'))\n expect(selfKeyHex).to.eq(exchangeKeySelf)\n const delegateKeys = await testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id!, deletedOtherId)\n expect(delegateKeys.length).to.eq(1)\n const delegateKeysHex = ua2hex(await primitives.AES.exportKey(delegateKeys[0], 'raw'))\n expect(delegateKeysHex).to.eq(exchangeKeyOther)\n }\n\n it('hcp with hcPartyKeys to soft-deleted user', async () => {\n const hcp = await masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeHcPartyKeys: true }))\n await doLegacyKeysTestWithDeletedDataOwner(hcp)\n })\n\n it('hcp with aesExchangeKeys to soft-deleted user', async () => {\n const hcp = await masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeAesExchangeKeys: true }))\n await doLegacyKeysTestWithDeletedDataOwner(hcp)\n })\n})\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'isomorphic-fetch';
|