@icure/api 8.11.0 → 8.13.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/IccUserApi.d.ts +1 -1
- package/icc-api/api/IccUserApi.js +2 -2
- package/icc-api/api/IccUserApi.js.map +1 -1
- package/icc-api/model/HealthElement.d.ts +11 -0
- package/icc-api/model/HealthElement.js.map +1 -1
- package/icc-api/model/HealthElementAsserter.d.ts +33 -0
- package/icc-api/model/HealthElementAsserter.js +28 -0
- package/icc-api/model/HealthElementAsserter.js.map +1 -0
- package/icc-api/model/HealthElementQualifiedLink.d.ts +31 -0
- package/icc-api/model/HealthElementQualifiedLink.js +26 -0
- package/icc-api/model/HealthElementQualifiedLink.js.map +1 -0
- package/icc-api/model/models.d.ts +2 -0
- package/icc-api/model/models.js +2 -0
- package/icc-api/model/models.js.map +1 -1
- package/icc-x-api/filters/HealthElementByAssociationIdFilter.d.ts +23 -0
- package/icc-x-api/filters/HealthElementByAssociationIdFilter.js +30 -0
- package/icc-x-api/filters/HealthElementByAssociationIdFilter.js.map +1 -0
- package/icc-x-api/filters/HealthElementByQualifiedLinkFilter.d.ts +24 -0
- package/icc-x-api/filters/HealthElementByQualifiedLinkFilter.js +30 -0
- package/icc-x-api/filters/HealthElementByQualifiedLinkFilter.js.map +1 -0
- package/icc-x-api/filters/filters.d.ts +2 -0
- package/icc-x-api/filters/filters.js +2 -0
- package/icc-x-api/filters/filters.js.map +1 -1
- package/icc-x-api/index.js +1 -1
- package/icc-x-api/index.js.map +1 -1
- package/package.json +1 -1
- package/test/benchmarks/lzma-benchmark.spec.d.ts +0 -1
- package/test/benchmarks/lzma-benchmark.spec.js +0 -131
- package/test/benchmarks/lzma-benchmark.spec.js.map +0 -1
- package/test/benchmarks/lzma-compat.spec.d.ts +0 -1
- package/test/benchmarks/lzma-compat.spec.js +0 -187
- package/test/benchmarks/lzma-compat.spec.js.map +0 -1
- package/test/benchmarks/playwright.config.d.ts +0 -2
- package/test/benchmarks/playwright.config.js +0 -18
- package/test/benchmarks/playwright.config.js.map +0 -1
- package/test/icc-api/api/IccAgendaApi.d.ts +0 -1
- package/test/icc-api/api/IccAgendaApi.js +0 -64
- package/test/icc-api/api/IccAgendaApi.js.map +0 -1
- package/test/icc-api/api/IccAnonymousAccessApi.d.ts +0 -1
- package/test/icc-api/api/IccAnonymousAccessApi.js +0 -58
- package/test/icc-api/api/IccAnonymousAccessApi.js.map +0 -1
- package/test/icc-api/api/IccCalendarItemApi.d.ts +0 -1
- package/test/icc-api/api/IccCalendarItemApi.js +0 -67
- package/test/icc-api/api/IccCalendarItemApi.js.map +0 -1
- package/test/icc-api/api/IccCalendarItemTypeApi.d.ts +0 -1
- package/test/icc-api/api/IccCalendarItemTypeApi.js +0 -96
- package/test/icc-api/api/IccCalendarItemTypeApi.js.map +0 -1
- package/test/icc-api/api/IccCodeApi.d.ts +0 -1
- package/test/icc-api/api/IccCodeApi.js +0 -38
- package/test/icc-api/api/IccCodeApi.js.map +0 -1
- package/test/icc-api/api/IccDocumentApi.d.ts +0 -1
- package/test/icc-api/api/IccDocumentApi.js +0 -199
- package/test/icc-api/api/IccDocumentApi.js.map +0 -1
- package/test/icc-api/api/IccGroupApi.d.ts +0 -1
- package/test/icc-api/api/IccGroupApi.js +0 -50
- package/test/icc-api/api/IccGroupApi.js.map +0 -1
- package/test/icc-api/api/IccKeywordApi.d.ts +0 -1
- package/test/icc-api/api/IccKeywordApi.js +0 -64
- package/test/icc-api/api/IccKeywordApi.js.map +0 -1
- package/test/icc-api/api/IccMedicalLocationApi.d.ts +0 -1
- package/test/icc-api/api/IccMedicalLocationApi.js +0 -64
- package/test/icc-api/api/IccMedicalLocationApi.js.map +0 -1
- package/test/icc-api/api/IccPlaceApi.d.ts +0 -1
- package/test/icc-api/api/IccPlaceApi.js +0 -64
- package/test/icc-api/api/IccPlaceApi.js.map +0 -1
- package/test/icc-api/api/IccRecoveryDataApi.d.ts +0 -1
- package/test/icc-api/api/IccRecoveryDataApi.js +0 -95
- package/test/icc-api/api/IccRecoveryDataApi.js.map +0 -1
- package/test/icc-api/api/IccRoleApi.d.ts +0 -1
- package/test/icc-api/api/IccRoleApi.js +0 -34
- package/test/icc-api/api/IccRoleApi.js.map +0 -1
- package/test/icc-api/api/IccUserApi.d.ts +0 -1
- package/test/icc-api/api/IccUserApi.js +0 -96
- package/test/icc-api/api/IccUserApi.js.map +0 -1
- package/test/icc-api/e2e/IccCalendarItemApi.d.ts +0 -1
- package/test/icc-api/e2e/IccCalendarItemApi.js +0 -46
- package/test/icc-api/e2e/IccCalendarItemApi.js.map +0 -1
- package/test/icc-api/model/modelHelpersTest.d.ts +0 -1
- package/test/icc-api/model/modelHelpersTest.js +0 -45
- package/test/icc-api/model/modelHelpersTest.js.map +0 -1
- package/test/icc-x-api/auth/group-switch-test.d.ts +0 -1
- package/test/icc-x-api/auth/group-switch-test.js +0 -81
- package/test/icc-x-api/auth/group-switch-test.js.map +0 -1
- package/test/icc-x-api/auth/jwt-concurrency-test.d.ts +0 -2
- package/test/icc-x-api/auth/jwt-concurrency-test.js +0 -112
- package/test/icc-x-api/auth/jwt-concurrency-test.js.map +0 -1
- package/test/icc-x-api/auth/jwt-provider-test.d.ts +0 -1
- package/test/icc-x-api/auth/jwt-provider-test.js +0 -197
- package/test/icc-x-api/auth/jwt-provider-test.js.map +0 -1
- package/test/icc-x-api/auth/smart-auth-provider-test.d.ts +0 -1
- package/test/icc-x-api/auth/smart-auth-provider-test.js +0 -224
- package/test/icc-x-api/auth/smart-auth-provider-test.js.map +0 -1
- package/test/icc-x-api/autofix-anonymity-test.d.ts +0 -1
- package/test/icc-x-api/autofix-anonymity-test.js +0 -122
- package/test/icc-x-api/autofix-anonymity-test.js.map +0 -1
- package/test/icc-x-api/confidential-entities-test.d.ts +0 -1
- package/test/icc-x-api/confidential-entities-test.js +0 -168
- package/test/icc-x-api/confidential-entities-test.js.map +0 -1
- package/test/icc-x-api/crud/comprehensive-crud-test.d.ts +0 -1
- package/test/icc-x-api/crud/comprehensive-crud-test.js +0 -276
- package/test/icc-x-api/crud/comprehensive-crud-test.js.map +0 -1
- package/test/icc-x-api/crud/entities-crud-test-interface.d.ts +0 -16
- package/test/icc-x-api/crud/entities-crud-test-interface.js +0 -407
- package/test/icc-x-api/crud/entities-crud-test-interface.js.map +0 -1
- package/test/icc-x-api/crypto/anonymous-delegations-test.d.ts +0 -1
- package/test/icc-x-api/crypto/anonymous-delegations-test.js +0 -587
- package/test/icc-x-api/crypto/anonymous-delegations-test.js.map +0 -1
- package/test/icc-x-api/crypto/concurrency.d.ts +0 -1
- package/test/icc-x-api/crypto/concurrency.js +0 -35
- package/test/icc-x-api/crypto/concurrency.js.map +0 -1
- package/test/icc-x-api/crypto/crypto-utils.d.ts +0 -1
- package/test/icc-x-api/crypto/crypto-utils.js +0 -79
- package/test/icc-x-api/crypto/crypto-utils.js.map +0 -1
- package/test/icc-x-api/crypto/cryptoTest.d.ts +0 -2
- package/test/icc-x-api/crypto/cryptoTest.js +0 -402
- package/test/icc-x-api/crypto/cryptoTest.js.map +0 -1
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.d.ts +0 -1
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js +0 -166
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js.map +0 -1
- package/test/icc-x-api/crypto/exchange-data-manager-test.d.ts +0 -1
- package/test/icc-x-api/crypto/exchange-data-manager-test.js +0 -674
- package/test/icc-x-api/crypto/exchange-data-manager-test.js.map +0 -1
- package/test/icc-x-api/crypto/full-crypto-test.d.ts +0 -1
- package/test/icc-x-api/crypto/full-crypto-test.js +0 -454
- package/test/icc-x-api/crypto/full-crypto-test.js.map +0 -1
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.d.ts +0 -1
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.js +0 -379
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.js.map +0 -1
- package/test/icc-x-api/crypto/secure-delegations-manager-test.d.ts +0 -1
- package/test/icc-x-api/crypto/secure-delegations-manager-test.js +0 -278
- package/test/icc-x-api/crypto/secure-delegations-manager-test.js.map +0 -1
- package/test/icc-x-api/crypto/shamir.d.ts +0 -2
- package/test/icc-x-api/crypto/shamir.js +0 -167
- package/test/icc-x-api/crypto/shamir.js.map +0 -1
- package/test/icc-x-api/crypto/share-deduplication-test.d.ts +0 -1
- package/test/icc-x-api/crypto/share-deduplication-test.js +0 -250
- package/test/icc-x-api/crypto/share-deduplication-test.js.map +0 -1
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.d.ts +0 -1
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js +0 -71
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js.map +0 -1
- package/test/icc-x-api/crypto/soft-deleted-data-owners.d.ts +0 -2
- package/test/icc-x-api/crypto/soft-deleted-data-owners.js +0 -113
- package/test/icc-x-api/crypto/soft-deleted-data-owners.js.map +0 -1
- package/test/icc-x-api/crypto/user-encryption-keys-manager-test.d.ts +0 -1
- package/test/icc-x-api/crypto/user-encryption-keys-manager-test.js +0 -246
- package/test/icc-x-api/crypto/user-encryption-keys-manager-test.js.map +0 -1
- package/test/icc-x-api/entity-with-attachments-api-test.d.ts +0 -1
- package/test/icc-x-api/entity-with-attachments-api-test.js +0 -142
- package/test/icc-x-api/entity-with-attachments-api-test.js.map +0 -1
- package/test/icc-x-api/filters/filters.d.ts +0 -1
- package/test/icc-x-api/filters/filters.js +0 -49
- package/test/icc-x-api/filters/filters.js.map +0 -1
- package/test/icc-x-api/filters/healthelement.d.ts +0 -1
- package/test/icc-x-api/filters/healthelement.js +0 -333
- package/test/icc-x-api/filters/healthelement.js.map +0 -1
- package/test/icc-x-api/icc-accesslog-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-accesslog-x-api.js +0 -106
- package/test/icc-x-api/icc-accesslog-x-api.js.map +0 -1
- package/test/icc-x-api/icc-application-settings-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-application-settings-x-api.js +0 -91
- package/test/icc-x-api/icc-application-settings-x-api.js.map +0 -1
- package/test/icc-x-api/icc-auth-api.d.ts +0 -1
- package/test/icc-x-api/icc-auth-api.js +0 -47
- package/test/icc-x-api/icc-auth-api.js.map +0 -1
- package/test/icc-x-api/icc-calendar-item-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-calendar-item-x-api.js +0 -150
- package/test/icc-x-api/icc-calendar-item-x-api.js.map +0 -1
- package/test/icc-x-api/icc-code-x-api-test.d.ts +0 -1
- package/test/icc-x-api/icc-code-x-api-test.js +0 -74
- package/test/icc-x-api/icc-code-x-api-test.js.map +0 -1
- package/test/icc-x-api/icc-contact-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-contact-x-api.js +0 -355
- package/test/icc-x-api/icc-contact-x-api.js.map +0 -1
- package/test/icc-x-api/icc-document-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-document-x-api.js +0 -76
- package/test/icc-x-api/icc-document-x-api.js.map +0 -1
- package/test/icc-x-api/icc-form-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-form-x-api.js +0 -413
- package/test/icc-x-api/icc-form-x-api.js.map +0 -1
- package/test/icc-x-api/icc-hcparty-x-api-test.d.ts +0 -1
- package/test/icc-x-api/icc-hcparty-x-api-test.js +0 -43
- package/test/icc-x-api/icc-hcparty-x-api-test.js.map +0 -1
- package/test/icc-x-api/icc-helement-x-api-test.d.ts +0 -1
- package/test/icc-x-api/icc-helement-x-api-test.js +0 -155
- package/test/icc-x-api/icc-helement-x-api-test.js.map +0 -1
- package/test/icc-x-api/icc-invoice-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-invoice-x-api.js +0 -99
- package/test/icc-x-api/icc-invoice-x-api.js.map +0 -1
- package/test/icc-x-api/icc-maintenance-task-x-api-test.d.ts +0 -1
- package/test/icc-x-api/icc-maintenance-task-x-api-test.js +0 -222
- package/test/icc-x-api/icc-maintenance-task-x-api-test.js.map +0 -1
- package/test/icc-x-api/icc-message-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-message-x-api.js +0 -54
- package/test/icc-x-api/icc-message-x-api.js.map +0 -1
- package/test/icc-x-api/icc-patient-x-api-test.d.ts +0 -1
- package/test/icc-x-api/icc-patient-x-api-test.js +0 -209
- package/test/icc-x-api/icc-patient-x-api-test.js.map +0 -1
- package/test/icc-x-api/icc-recovery-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-recovery-x-api.js +0 -175
- package/test/icc-x-api/icc-recovery-x-api.js.map +0 -1
- package/test/icc-x-api/icc-topic-x-api.d.ts +0 -1
- package/test/icc-x-api/icc-topic-x-api.js +0 -269
- package/test/icc-x-api/icc-topic-x-api.js.map +0 -1
- package/test/icc-x-api/icc-user-x-api-test.d.ts +0 -1
- package/test/icc-x-api/icc-user-x-api-test.js +0 -99
- package/test/icc-x-api/icc-user-x-api-test.js.map +0 -1
- package/test/icc-x-api/keyless-api.d.ts +0 -1
- package/test/icc-x-api/keyless-api.js +0 -125
- package/test/icc-x-api/keyless-api.js.map +0 -1
- package/test/icc-x-api/patient-user.d.ts +0 -2
- package/test/icc-x-api/patient-user.js +0 -103
- package/test/icc-x-api/patient-user.js.map +0 -1
- package/test/icc-x-api/storage/storage.d.ts +0 -1
- package/test/icc-x-api/storage/storage.js +0 -48
- package/test/icc-x-api/storage/storage.js.map +0 -1
- package/test/icc-x-api/test-api-no-parent.d.ts +0 -1
- package/test/icc-x-api/test-api-no-parent.js +0 -79
- package/test/icc-x-api/test-api-no-parent.js.map +0 -1
- package/test/icc-x-api/test-legacy-data-support.d.ts +0 -1
- package/test/icc-x-api/test-legacy-data-support.js +0 -375
- package/test/icc-x-api/test-legacy-data-support.js.map +0 -1
- package/test/icc-x-api/utils/date-encode-test.d.ts +0 -1
- package/test/icc-x-api/utils/date-encode-test.js +0 -150
- package/test/icc-x-api/utils/date-encode-test.js.map +0 -1
- package/test/icc-x-api/utils/graph-test.d.ts +0 -1
- package/test/icc-x-api/utils/graph-test.js +0 -54
- package/test/icc-x-api/utils/graph-test.js.map +0 -1
- package/test/icc-x-api/utils/lru-temporised-async-cache-test.d.ts +0 -1
- package/test/icc-x-api/utils/lru-temporised-async-cache-test.js +0 -364
- package/test/icc-x-api/utils/lru-temporised-async-cache-test.js.map +0 -1
- package/test/icc-x-api/utils/lzma-benchmark-test.d.ts +0 -1
- package/test/icc-x-api/utils/lzma-benchmark-test.js +0 -132
- package/test/icc-x-api/utils/lzma-benchmark-test.js.map +0 -1
- package/test/icc-x-api/utils/lzma-compat-test.d.ts +0 -1
- package/test/icc-x-api/utils/lzma-compat-test.js +0 -218
- package/test/icc-x-api/utils/lzma-compat-test.js.map +0 -1
- package/test/icc-x-api/utils/mutex-test.d.ts +0 -1
- package/test/icc-x-api/utils/mutex-test.js +0 -114
- package/test/icc-x-api/utils/mutex-test.js.map +0 -1
- package/test/icc-x-api/utils/to-moment-test.d.ts +0 -1
- package/test/icc-x-api/utils/to-moment-test.js +0 -110
- package/test/icc-x-api/utils/to-moment-test.js.map +0 -1
- package/test/support/CSM-185.d.ts +0 -1
- package/test/support/CSM-185.js +0 -124
- package/test/support/CSM-185.js.map +0 -1
- package/test/support/CSM-243.d.ts +0 -1
- package/test/support/CSM-243.js +0 -120
- package/test/support/CSM-243.js.map +0 -1
- package/test/support/CSM-543.d.ts +0 -1
- package/test/support/CSM-543.js +0 -164
- package/test/support/CSM-543.js.map +0 -1
- package/test/support/CSM-729.d.ts +0 -1
- package/test/support/CSM-729.js +0 -225
- package/test/support/CSM-729.js.map +0 -1
- package/test/support/CSM-814.d.ts +0 -1
- package/test/support/CSM-814.js +0 -475
- package/test/support/CSM-814.js.map +0 -1
- package/test/support/CSM-87.d.ts +0 -0
- package/test/support/CSM-87.js +0 -21
- package/test/support/CSM-87.js.map +0 -1
- package/test/support/CSM-93.d.ts +0 -1
- package/test/support/CSM-93.js +0 -112
- package/test/support/CSM-93.js.map +0 -1
- package/test/utils/FakeDataOwnerApi.d.ts +0 -32
- package/test/utils/FakeDataOwnerApi.js +0 -136
- package/test/utils/FakeDataOwnerApi.js.map +0 -1
- package/test/utils/FakeEncryptionKeysManager.d.ts +0 -36
- package/test/utils/FakeEncryptionKeysManager.js +0 -97
- package/test/utils/FakeEncryptionKeysManager.js.map +0 -1
- package/test/utils/FakeExchangeDataApi.d.ts +0 -32
- package/test/utils/FakeExchangeDataApi.js +0 -92
- package/test/utils/FakeExchangeDataApi.js.map +0 -1
- package/test/utils/FakeExchangeDataManager.d.ts +0 -48
- package/test/utils/FakeExchangeDataManager.js +0 -82
- package/test/utils/FakeExchangeDataManager.js.map +0 -1
- package/test/utils/FakeExchangeDataMapManager.d.ts +0 -12
- package/test/utils/FakeExchangeDataMapManager.js +0 -38
- package/test/utils/FakeExchangeDataMapManager.js.map +0 -1
- package/test/utils/FakeGenericApi.d.ts +0 -16
- package/test/utils/FakeGenericApi.js +0 -65
- package/test/utils/FakeGenericApi.js.map +0 -1
- package/test/utils/KeylessCryptoStrategies.d.ts +0 -23
- package/test/utils/KeylessCryptoStrategies.js +0 -26
- package/test/utils/KeylessCryptoStrategies.js.map +0 -1
- package/test/utils/TestApi.d.ts +0 -3
- package/test/utils/TestApi.js +0 -30
- package/test/utils/TestApi.js.map +0 -1
- package/test/utils/TestCollectionUtils.d.ts +0 -1
- package/test/utils/TestCollectionUtils.js +0 -310
- package/test/utils/TestCollectionUtils.js.map +0 -1
- package/test/utils/TestCryptoStrategies.d.ts +0 -42
- package/test/utils/TestCryptoStrategies.js +0 -80
- package/test/utils/TestCryptoStrategies.js.map +0 -1
- package/test/utils/TestStorage.d.ts +0 -23
- package/test/utils/TestStorage.js +0 -61
- package/test/utils/TestStorage.js.map +0 -1
- package/test/utils/roles.d.ts +0 -14
- package/test/utils/roles.js +0 -345
- package/test/utils/roles.js.map +0 -1
- package/test/utils/test_utils.d.ts +0 -87
- package/test/utils/test_utils.js +0 -452
- package/test/utils/test_utils.js.map +0 -1
package/test/support/CSM-814.js
DELETED
|
@@ -1,475 +0,0 @@
|
|
|
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 icc_api_1 = require("../../icc-api");
|
|
19
|
-
const User_1 = require("../../icc-api/model/User");
|
|
20
|
-
const TestStorage_1 = require("../utils/TestStorage");
|
|
21
|
-
const TestCryptoStrategies_1 = require("../utils/TestCryptoStrategies");
|
|
22
|
-
const chaiAsPromised = require("chai-as-promised");
|
|
23
|
-
var initMasterApi = test_utils_1.TestUtils.initMasterApi;
|
|
24
|
-
(0, chai_1.use)(chaiAsPromised);
|
|
25
|
-
(0, test_utils_1.setLocalStorage)(fetch);
|
|
26
|
-
let env;
|
|
27
|
-
let hierarchyApis;
|
|
28
|
-
const pPrivateKey = '308204bf020100300d06092a864886f70d0101010500048204a9308204a50201000282010100ba2cd9058441dccb3238ab4725e6536e7d8daba3a3590e226c350c84cd421b3f8cf63e4deb90eff1d7264f3d1facad0dc46e26237bd9afe476c992b1913ace05b3b5531f1d5d2618d01d7201c88b18eccfb16876a3cba3d1a928530de9e19f37a25ef41c069a7527493c603771ea638e5667c98cca585b99c91161e8eeccd17b58c649c156dcbbe02f0140565a1ea08ff72ef4466a3967e50b93a83d6a82084a40d050776b0a3bcafe3d0cdd4c56bf673d905b9fc800b146b990a2a33d0f1575c1c724c629d2c4978125e769631f6c5b86d7db1e4dbcf26edd2e383dd28bc3df7853581b5555fdc09b1a85e7a6b7b1981d63abf2e29c315d03f4e4e0dd735d25020301000102820100204165e645484df32c83d1f4f535870df515c6ff866d06fc62c7fc1fc41a287365be4204290486f5dd0347a63ce7236267be77c01d14959b5d1346659a56585c778aba58813362c6d8c3c93d52dbfa9908d0e15af0bcf6e87bc8bf3f015ef44164d1d3b449569866929331ce595fb518f3926ec2844a33b09cbbf4bd31266e4286b60f156d6ba2bf9dd429725d705c92b2ef9167cddea39a479629e400f8c6469b17facff14c4823b3d14a4bbbb739f4360e0635b443cd30ba6f35c260aa3ce6bbc4e6aa0e430061e464e8a5b5feac05ade105acebbbf39d7f31c6de9005fa701289688ee1c8892babab209d443f40c5da201aacaaa16d6b8163cc7c43cea54f02818100fb269017878b8f7ba9ddfa021a4a7996cf35259db2230e72404fdf8e3572cb56ba17af365b1c7c5550ab6a1be72a37a8f6acb2456b4252461f979c2a9b54e90e9e1de40d9a4f187b270bfa0818b9bc0afcc9a2145ba8767d55f5361b18c9c2e78597ed11e351447df68c7ce0118ef447873dd82783cb538cb011ead98c7ec4c702818100bdc51c817f4ca90e4786336f518b7c5d88042bb898bcfa28b6e54847ca9161497c7e9eef03ae5c618e7a5ab5720c77408f3c0950bf36b649fc7d4c8dcb01b032694d97d14e80550d2088c359f2da6ea41eb85dad76a4918e1aa548e0b3a2b8cefb80c3211c724c8404d7b5aaeeb63ff4b980468f32fbedad2ebc2a9489e00ab302818100c60d3df9e020d5305edf36852bf868f3dd48faf5e58131a6354307771c7cff0ed047571b55341c7426de5619d4ec7ce2184c4d74e2c5751de951e48bd0dc5fc0f03d80169e061bb71a2e9ea87ddf1203d41ea95ac6810d977f0e94f13f55f406215a924fd5e3c35055f9a98c052ca74434c93748c9ecb06134839ca09be36807028181008cc2fcd6017af79b23eaa3945ac440479070a78d919dfb60dfe94aa815d5a8783de41e37e45f1d1f2ff409fcb4d01254ccea176ed1a6dfa819a5477795b176e4adbf647158ed5029208cd17a92ecfb4cb98cbfcfbf456ac22179a0892c35f32774de99dea19f16aa867d0abff3b933cf6f197b3d14f051e837d6532f42e5f08902818100f80e6a6fdaf6e1a8292868bc386cfc8804451502b747b92ca506ad459537e8e7e0b58fd648836da034ef0ef59c81c3819913060408f9d7e6ec533ff39331914a9db2476dfe498e22c1774892c1d979f5ad1396d172edd416fb0467e5ae340c93c11ab47732c184c3a6e90df1e6a39742b401b02fa2fde1f7d50ec8b8a1dc9157'; // pragma: allowlist secret
|
|
29
|
-
const pPublicKey = '30820122300d06092a864886f70d01010105000382010f003082010a0282010100ba2cd9058441dccb3238ab4725e6536e7d8daba3a3590e226c350c84cd421b3f8cf63e4deb90eff1d7264f3d1facad0dc46e26237bd9afe476c992b1913ace05b3b5531f1d5d2618d01d7201c88b18eccfb16876a3cba3d1a928530de9e19f37a25ef41c069a7527493c603771ea638e5667c98cca585b99c91161e8eeccd17b58c649c156dcbbe02f0140565a1ea08ff72ef4466a3967e50b93a83d6a82084a40d050776b0a3bcafe3d0cdd4c56bf673d905b9fc800b146b990a2a33d0f1575c1c724c629d2c4978125e769631f6c5b86d7db1e4dbcf26edd2e383dd28bc3df7853581b5555fdc09b1a85e7a6b7b1981d63abf2e29c315d03f4e4e0dd735d250203010001'; // pragma: allowlist secret
|
|
30
|
-
const aFixture = {
|
|
31
|
-
privateKey: '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100c35a740119a64b265b8524e44c2a548efc21b088f8df2575a6a89bf0f0a7c9fb7888ba3719d5433032d4a3c1290fc525e6874523c841aa43367a3bbb015f1b2e1b3b2cdd323369a9df80768a5583fb6b2b01ebe601d680e0ad2cb5cf8d853a49df2f95cb6cd0caf9eb9cb59d6161dd7fbd4a980166ec1972808b57ad75721ae9988b85fe23b7278f3efeb530805da70b7afd1f7a017bc0da2f75ff2df15240b57b29d4c178599d3b7324ff6e3016792695a5725f3cc9475d69fc8181f66587d3382906a912c7a1f28485fe98b2faf06cb6c2877d1195f1147543a52ab919b912f3b2d7ee867715ba7faafd25522f091d4bfa00682f43aa5def879985d651862302030100010282010005b2cb447a25f68fd2f9cf302ed7634375aff3e46fc208346676a2d6aab33f13c5b36cebf38c75815febce950af549b4d49e5bb8a5fc485faa8b0c7197eef2c7856c6df8e56d484d44bd0c782926a222c13fe832fbb28a9fa990bb9c8d9af62ed00f8b95c201ee5e9c21579c148a6df9bb3a844e655d1586f206c4ecab7e10b24123ec6a9cc3089472dc3be93eb8af256ceefd5f609e020eb85bbf53aaf91dc0306df33321b2e4688320f3834d3b9e074545206ec18c3b011273edcddbc6135f2af9d71b6b41a2c331c96a08c90a24109b94a33e6a9c8905977a32ac25e78b16f9f6b27f5b66f6103de723ecc72a0db40b400408684da8143475317688298b3902818100fef04b985e01df81e290ab75db0836b662eb23b846908caff9c8e76da29280412cc713223234c6eab3a3d0f908a005343c11846addb672b999250763a4d2a76f67e83a2d9120d433a734a098320ec3afdfc082e3c27e3d06e12ab0dcef4d9a466727f3e7e2446d0fcf4908dd6784eb121f4e2fe72da118ee2945d2d547d9a65902818100c42aa765b54fa65e73f277b6c8e90a8b5f1186fd5cd57ffedfa0e535efa58e2b6832e466d119f669e0e1644f5f12ebd0298eaa995a96dc72574a19277e9e030dcf052136d3e811ea8db145b5d9dd11a097794dbf74015952eb1a04d96882e26dc23eafbd455bdad7e01fee889c713213c724f0bbc68ecaa997c34b126a8af8db0281801768f5681e69c99e61b1ab2cfd59f9bc31c529d8881249f8f6d4edfb714c469eb57fea4fdf905d1bbc3734bf497d783cddaf361ba21458e09621825632126df19af706309cfd08bf5d8145a5f422caf161788a0c6415b780e438495960581dec8d186c1b44f9c7920614cccd97edeab01553d6ae41d0633bab6a8ffba9c760b102818019c0efd12e889272fc0ded219626e23781f7af1d3c3edb5afec904ce9bf3c442769f97d4d7c6eccee1b33594260b39e24e52689b518554d3be1a004b6b181b96888347e506d504e5224d0fb5dc3065cc0b96e55a2944b4116ac433b6c73dc7b4593819a263a4b78a77e6394ebe1b2e53e2653b25abdfbb43a0a5070a17eabed902818100e27ed14daac47b6edbf202468e4aa43b9a8caca188235a7bf492ee3bdf72300f1d53cf3f5d09f1496000fa5b26e486f5c9d3e93e830dbbd409ddb67a07240d6bd25d0cadbc9ba9ade07144ee6b9ed05cb5d1e1c069098f661db6cd1e355a65bb3b2a28bbf16711f38afa3c9c8da28d4261bf9536a50b9368c7e7aec217e4aa91', // pragma: allowlist secret
|
|
32
|
-
publicKey: '30820122300d06092a864886f70d01010105000382010f003082010a0282010100c35a740119a64b265b8524e44c2a548efc21b088f8df2575a6a89bf0f0a7c9fb7888ba3719d5433032d4a3c1290fc525e6874523c841aa43367a3bbb015f1b2e1b3b2cdd323369a9df80768a5583fb6b2b01ebe601d680e0ad2cb5cf8d853a49df2f95cb6cd0caf9eb9cb59d6161dd7fbd4a980166ec1972808b57ad75721ae9988b85fe23b7278f3efeb530805da70b7afd1f7a017bc0da2f75ff2df15240b57b29d4c178599d3b7324ff6e3016792695a5725f3cc9475d69fc8181f66587d3382906a912c7a1f28485fe98b2faf06cb6c2877d1195f1147543a52ab919b912f3b2d7ee867715ba7faafd25522f091d4bfa00682f43aa5def879985d65186230203010001', // pragma: allowlist secret
|
|
33
|
-
selfFingerprint: '43aa5def879985d65186230203010001', // pragma: allowlist secret
|
|
34
|
-
selfExchangeKey: '8a7cd219e185ba9ec3f47afeb5a8bd0e446f162bb69c74459b63ffb17af7ce55e33bdce2ac609734592b80241866599922cfc69f9d934a4cecb079c5f23d17e0604115b118946c72739b901c98af54ccbad4e53af24de9f989c39f9d60f39d88a974d6c8aa82f42385693db64ee76ea32cad323c2bd106fda80f9b681f113671876fa2f53f84113cb54a5e67db2a7faa882250b28568755feca69302f2d71f42d76fd63313e4db52f7b32a90c0b5633fc23ac4ed0c0e1861610be6e57980e3ede9de1998f467752938001ad2d89c3705b364545edda4f807fff7ed2abeffa8dbfca82952602209db0d026a6f64d7652847b6ddc0e32dd95547412cb0eaf86ad2', // pragma: allowlist secret
|
|
35
|
-
toParentFingerprint: '9c315d03f4e4e0dd735d250203010001', // pragma: allowlist secret
|
|
36
|
-
toParentExchangeKey: 'b1cfd3684b474ced80cf5cbb651f1228d0700c49ceda07e9b0a675d94ca737d3b93531881fdd68b65c97f0fd26b30a05346a0c194a23a90a809af31eb93c52f3d830f163e226b876c1eee4104d85be524ca35a8732243df381be8553713f3c987f1ee0cf04e8b9bb56d501012435722a634755e7aafae892f341feb61c9b6aafe36b1b425c3b0af770cba8de52ab861336f17c0ccea67b4b9b24b5fd46768876ea58764af11ff9a644777038087812519a2ef64425bf863ffb9091c5530aa5905e60224fa03eac99ff994b0727fda1dbb68200496d46df6b312255ae86614f99b47f5b5330567ee73f232aa1008ad48f434f179a4cd6ddd9c20d39058de4b453', // pragma: allowlist secret
|
|
37
|
-
toParentExchangeKeyOwnCopy: '1531714e09925bf4864063efb6f7f8a6d9ae522568f1fe4eda5722fdb88cc8caaba6f1e791d97d269c8ccbd40a0ca6d7163a99aa160831c7beb571f1c21819c23b6211bb2ee2f745701bebb2492db5e77b210669e32bf9cc98f7e681b092da6b207aa40564c93be462c148a8a9e7876e4a0989937e135dfbfe0bb7539cd01ceef4da45e3e087b3b6bce89561c8e35c7962ff411a0fef01eda721bd01ec4b7efe12742fc22fe2c96d5c7176620ed0897dc0d1e7151d6c2ac9688c9b0fde3e03ff445814dcb60f52c8f0f59b2b414d2859324d5201637e78236352bf12bda0b134026b05b4b6948dfd20f859979b97141d13675766c08bef058ebb7c3a277b9e7b', // pragma: allowlist secret
|
|
38
|
-
selfDelegationKey: 'f1b055534b35feb503ca2ce44e160b7b899bb2550789e409d212639cf536409eab05555fe38ee1c42d0eec740336c0a44cb6ca23b58f273e96a6d526711737bc8476fc4b630cd237373547cfc648c222d4fe22589c0baa9c8e3c5c0498e8efb9', // pragma: allowlist secret
|
|
39
|
-
toParentDelegationKey: 'd298bad5544a61db3c796a7da8924fcd7545886c6431b8d5a1032a017dd211c7fef10ea6559671c8af8b3492656b4b999328e2420df2b6cb2833aca3ad02dfb11b633442f6a0a44abfbda8ec54785213b5bf38e1bcc30cc1a39051749238c954', // pragma: allowlist secret
|
|
40
|
-
selfEncryptionKey: '46f02bcd460442dbfdc911b64f633cac3d81e6a2baaf3bca8f31c6ce86827d89be14a47fe3a466c51515ee439cc020384836789d72e3fa6dc1a09f23798ea6719af2a1da67bc3bd496bca7c9d1ae03482aa5a6e9d0a7dfd6954aac15f82b2b91', // pragma: allowlist secret
|
|
41
|
-
toParentEncryptionKey: '21b7a2b03e63f5858a7cd7ffba8e3577daca71961a6095eb1d273156001f3023a629c41acff4b8d570c450429648b385d1b542343e0dd7e8241fea45b84af4938739daacfe882e2801f321b9ec95434983834642b75c5be4e75c731d661f1983', // pragma: allowlist secret
|
|
42
|
-
encryptedSelf: 'HAQoMr0VAX9CrU1fBKzWSfUsXham+TFtlUSbb7e3iA0=', // pragma: allowlist secret
|
|
43
|
-
};
|
|
44
|
-
const bFixture = {
|
|
45
|
-
privateKey: '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100bca9f007e74c4f256437e5d81b0dd7d2a5c1c934dbe15968b0201415f7611f816d742da515f707433b70b8c2cf0fd0e1fad7ff55805e059126778d79759b1467ed41594881ca9ec69a5972280eb296191b4e6e641b4810df34fbca1cae31b1622db4e932b2b94ac4cbc2ecdfab979ae60ea9824a7e809cd539c3f28a6a2589a91277281082ab892e0f726b1cebed61c68bdfd4c93f8c48a285e875dbfb90a46a1a168b2b25e2115edfcf27040703212b8a76b4d206aab0bed4235b023a2ef415be40cf32864d2fb0e8313a16e98b4a1e0777035203f926b51456bb0441e20119631f7e4cd3ef5e1307fb48312a5c646e2a8105ecbe6a290a809fb18a0d170e59020301000102820100271bed339e397de0a8ed437ab06506bbd67b9ceb95b719b32f6b7eee6cc917e05b21adc29e9286516415825f73cffa03965dc742e0a8dceb91774fff0127a42bc50d7a6622edaf4b493cc882d0452a034b5b4f5bf621d2c98a70b59d8b68a6b64cf6472f28c86b5cef465997263977b5400dd881fbc64a7c930c710f4b60bbafd30a6ead5a6184a01b9fd4fcd5d5a4be5e89442b7f80897e35443f159da6de1f911c14324afea504f505ae95f84c2b0a4c5e142b32a1c7ac0415d165c77fda2cf5e696d5b7c937abc5afa002cf58c85ed6af540ce388488371e3903ad48444d1dca3a5d93912b44a94a9d21f0523986829cd752a5538b30c91ccf5696906339702818100e2352b516e5f0e44ecbf6361be811897e287318095827420c96e63d3e2adb2712386066dacc7962280bbc8890d02f97afb9816bab1cb1b5339d6def2e2b9cbb7ae2223528b0a04298f02546b629f232ba2bbd5f290c6552196c0f4dc4814e407d499444e874c9da04213a7249ecc5c327e4309d23cfd0d8947d7daddc9cc431302818100d582efe894ce249859262c0a27867c87e8b6fbe417b2bc27fd1542873d76582000b31c10f4c41074df8a175c97eabe08bd112a3503951939d28cd393c93465f619ed4e5b90aa4d4e5bc919a6c0bba298ad8f00dc317594ab545fb808ed2084bbfaad5631fd279c7adb9ae6e55874e0aceb4591e7a3ac82d8f84e80206a882a6302818100ba3dd86a751ae21eb1656a27a1b79c4e00fe1a2da9eafc3dba5a9eea66e967cf6ad60018f0766b1001399a83ec2894cb42b61790a2ad7cd3eafd141699c12b0f11d99d876a5e56caf8a98c63d590fc5e02dfefe8847626c53edfa33a724670f05983cf0f70aa0de55241e80d68890d27ad78f86f1633aa9f6a7d37ffff13a3ed0281807f064d50e3e6d8a2c2b71110617f836b202a6d25c06b97c17ab24148506aadf72c3363093b75c20ca64973a8a4c1059a1151baf89b4f03190188c2ff737ef702395e9375aa5587748cead19601a8200e1183b89147e39a356c171e58412b4d8cc0908b6d661d40dd5ef58355031155f1ca6f3364ca5d81e32fa7145734ca19dd028180491522dd3c2eb7b1e612c5bb0c321e910e4037bbe88e4221d8d5d3fc95915acab6404c08a5360723b057342152213c12707fde00beb43c7113b8f7150f88c80eca521867f49c9ebd37f3d3c32ac76bcb521f15d01921dac0bdadee2b248db73471b53bbce26cbbc50a4c0772d982dfa1984addbb560a58eb7f02a55484d09a13', // pragma: allowlist secret
|
|
46
|
-
publicKey: '30820122300d06092a864886f70d01010105000382010f003082010a0282010100bca9f007e74c4f256437e5d81b0dd7d2a5c1c934dbe15968b0201415f7611f816d742da515f707433b70b8c2cf0fd0e1fad7ff55805e059126778d79759b1467ed41594881ca9ec69a5972280eb296191b4e6e641b4810df34fbca1cae31b1622db4e932b2b94ac4cbc2ecdfab979ae60ea9824a7e809cd539c3f28a6a2589a91277281082ab892e0f726b1cebed61c68bdfd4c93f8c48a285e875dbfb90a46a1a168b2b25e2115edfcf27040703212b8a76b4d206aab0bed4235b023a2ef415be40cf32864d2fb0e8313a16e98b4a1e0777035203f926b51456bb0441e20119631f7e4cd3ef5e1307fb48312a5c646e2a8105ecbe6a290a809fb18a0d170e590203010001', // pragma: allowlist secret
|
|
47
|
-
selfFingerprint: '6a290a809fb18a0d170e590203010001', // pragma: allowlist secret
|
|
48
|
-
selfExchangeKey: '2e0e20a809aa336805ad7f933d4dbc4a18194d130b89d01369c48330e90ea845f2c960077a33721004cc759921759e2d3b302ec6989889a6e76863fa8a24dea33f8d0543fc975a16642d7a5508a1a2216e10d776bec61bb1a64ab1716af8d8e1348525c404bc57a0f33978faca9bb59df571279aec39f028ba49966a8faec7c376143c8e753c19d89da739d3e9d52ec1e25418c5d1d8c2b677c02fe2587b8e6cfcf14a84909b6e9759cc4f60beebd9d087b438d2fe2ee98b64a86cb24ec7c7ff32686773c53a5ee9374770764a70e662926af23e9595f5bdd0e9b6e9b420aa46764f2fe1583b06c46fd3991a60baa5faa191d141631b76540d05ac99f918c8f2', // pragma: allowlist secret
|
|
49
|
-
toParentFingerprint: '9c315d03f4e4e0dd735d250203010001', // pragma: allowlist secret
|
|
50
|
-
toParentExchangeKey: 'a47381e623617b9f36272d0e9a9f7f3eb28232f10894d0d097d590399abf95a37a54a72fb063112bb0947828ce88a81e772aac1eac2fc31c3ea8e295c93319a08453ace46c863f389f3d7ce57d55c2642db4ffc8edf28d8bd957a80b940991ef237286df32e4cffc6efcf70f0c3b3a8f733742173dc0219f4a193dcd64c29e393d3c0ab4b21d69732c409bbe905ef460befda36b309d4097a63847db9fbfbebecf23eb768f3aed08d156f518ef9efc18ba5670312184d6f08ff4d20f5205aad6bc24bcd1b05cc92d14f7a0fc1c410b77a67b4619ac921f2fc96d2dbb779f5b029bd2f2a6894ae69f7b2047158936e009c5755ac5805b0fc8cf08ea84dd2d4d75', // pragma: allowlist secret
|
|
51
|
-
toParentExchangeKeyOwnCopy: '91719b9311f00e8ea8880b5a4a2da4ca8e35e26d5f46d6640df5ad1bb4f61051547f90cf16c06b1480e5c73862920f33da8081c468d343c054b177e9b9b9680642fdb6dcdb49ad0a1fd0dde979bc2e5154781228d46cbcd2ad33756e372459eb2267fd6bdaba4cacb2f345acef94251521cc5320cd22606398163cd6f40e3d7b1be6832017513960bc4c24490b9f11458958ccc9ae376eee8501374a540c91ec60a98e6d3c9132288e032b7143f75c33b790a499e40052511e7cc282e8a20e59454df29cc3332296ce583d35fbf145ba9ab2268c30fb105df5ee291aa90b33a90a15f9b891294b1c952748d65031d00b2a7db17712f171bb6190a9483c47360e', // pragma: allowlist secret
|
|
52
|
-
selfDelegationKey: '93a5601d3fd899ac9a7493f7222be465f77ee7925cc6fbf0ece66f799aaab0b19b80f9998ed1c738bf5672468a3de2cb6d6f2493a601c28dafcdbba8a50d0a1c67e70bd3a7786e423cba7601fa851b9b29ba15f8c5c97e92dd6bec338599c0a9', // pragma: allowlist secret
|
|
53
|
-
toParentDelegationKey: '815d54c92b2a4b18194698c31343aa40ebe5f525b1fa1d178150fe50f5f39125ac400580d2a37df486c505960348d6ab9f8fa3e7ce94bccd23dc8622e5c285be2b0eed7b0142e00bfe81d8840eb64aad3eaa0b47373eecd78024f4c47b86bde3', // pragma: allowlist secret
|
|
54
|
-
selfEncryptionKey: '11aa5c306539cae18625164724d4a7141be0bb5ebc888b9c6255f2aa6c93f7e96b1b5c38a0355a82d0d9667a3d4606eb73d733b02581a6f1cbc4dda9c71ee831ce5648be7f06443a830872974b73cfac6e6d5b0aaa04ecd186a2551f73203b10', // pragma: allowlist secret
|
|
55
|
-
toParentEncryptionKey: '24fd6f9e63f75cbe7ee8d3d5b8c18befda21dc35b4cfed0860434ff296e10023534da97b00d5a09372c7264ac44c45a20f5c2a1858515f75a70a922009228c1245d6401ef1f9f7a30cf63f6db765ddfb7e12f27243691ff6c5116931c9479e6c', // pragma: allowlist secret
|
|
56
|
-
encryptedSelf: 'zqX7C7Jxgm0Kx0XMByQqnn/F3QSD3wJabtxBX2bMM1U=', // pragma: allowlist secret
|
|
57
|
-
};
|
|
58
|
-
function legacyAesExchangeKeys(fixture, ownId, parentId) {
|
|
59
|
-
return {
|
|
60
|
-
[fixture.publicKey]: {
|
|
61
|
-
[ownId]: { [fixture.selfFingerprint]: fixture.selfExchangeKey },
|
|
62
|
-
[parentId]: {
|
|
63
|
-
[fixture.toParentFingerprint]: fixture.toParentExchangeKey,
|
|
64
|
-
[fixture.selfFingerprint]: fixture.toParentExchangeKeyOwnCopy,
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
function legacyPatientBase(fixture, ownId, parentId, firstName) {
|
|
70
|
-
return {
|
|
71
|
-
id: (0, crypto_1.randomUUID)(),
|
|
72
|
-
firstName,
|
|
73
|
-
lastName: 'Doe',
|
|
74
|
-
delegations: {
|
|
75
|
-
[ownId]: [{ owner: ownId, delegatedTo: ownId, key: fixture.selfDelegationKey }],
|
|
76
|
-
[parentId]: [{ owner: ownId, delegatedTo: parentId, key: fixture.toParentDelegationKey }],
|
|
77
|
-
},
|
|
78
|
-
encryptionKeys: {
|
|
79
|
-
[ownId]: [{ owner: ownId, delegatedTo: ownId, key: fixture.selfEncryptionKey }],
|
|
80
|
-
[parentId]: [{ owner: ownId, delegatedTo: parentId, key: fixture.toParentEncryptionKey }],
|
|
81
|
-
},
|
|
82
|
-
encryptedSelf: fixture.encryptedSelf,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Creates a data owner with a caller-provided (fixed or freshly generated) RSA keypair, an
|
|
87
|
-
* optional parent and aesExchangeKeys (for legacy fixture owners), and an initialised api for it.
|
|
88
|
-
* extraKeys lets the returned api locally hold another data owner's key too (e.g. the shared
|
|
89
|
-
* parent's), simulating a device/session with access to multiple keys.
|
|
90
|
-
*/
|
|
91
|
-
function createFixedKeyDataOwner(testSetupApi, id, opts) {
|
|
92
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
var _a;
|
|
94
|
-
yield testSetupApi.healthcarePartyApi.createHealthcareParty({
|
|
95
|
-
id,
|
|
96
|
-
firstName: opts.firstName,
|
|
97
|
-
lastName: 'Doe',
|
|
98
|
-
parentId: opts.parentId,
|
|
99
|
-
publicKey: opts.publicKey,
|
|
100
|
-
aesExchangeKeys: opts.aesExchangeKeys,
|
|
101
|
-
});
|
|
102
|
-
const login = `csm814-${opts.firstName.toLowerCase()}-${(0, crypto_1.randomUUID)()}`;
|
|
103
|
-
const password = (0, crypto_1.randomUUID)();
|
|
104
|
-
yield testSetupApi.userApi.createUser({
|
|
105
|
-
id: (0, crypto_1.randomUUID)(),
|
|
106
|
-
name: login,
|
|
107
|
-
status: User_1.User.StatusEnum.ACTIVE,
|
|
108
|
-
login,
|
|
109
|
-
passwordHash: password,
|
|
110
|
-
healthcarePartyId: id,
|
|
111
|
-
autoDelegations: opts.autoDelegations ? { all: opts.autoDelegations } : undefined,
|
|
112
|
-
email: `${login}@icure.com`,
|
|
113
|
-
});
|
|
114
|
-
const storage = yield (0, TestStorage_1.testStorageWithKeys)([
|
|
115
|
-
{ dataOwnerId: id, pairs: [{ keyPair: { privateKey: opts.privateKey, publicKey: opts.publicKey }, shaVersion: icc_x_api_1.ShaVersion.Sha1 }] },
|
|
116
|
-
...((_a = opts.extraKeys) !== null && _a !== void 0 ? _a : []).map((k) => ({
|
|
117
|
-
dataOwnerId: k.dataOwnerId,
|
|
118
|
-
pairs: [{ keyPair: { privateKey: k.privateKey, publicKey: k.publicKey }, shaVersion: icc_x_api_1.ShaVersion.Sha1 }],
|
|
119
|
-
})),
|
|
120
|
-
]);
|
|
121
|
-
const api = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: login, password }, new TestCryptoStrategies_1.TestCryptoStrategies(), crypto_1.webcrypto, fetch, {
|
|
122
|
-
storage: storage.storage,
|
|
123
|
-
keyStorage: storage.keyStorage,
|
|
124
|
-
entryKeysFactory: storage.keyFactory,
|
|
125
|
-
});
|
|
126
|
-
const user = yield api.userApi.getCurrentUser();
|
|
127
|
-
return { api, user };
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
/** Creates a patient the normal (v8) way and immediately shares its secret id with parentId. */
|
|
131
|
-
function createV8PatientSharedWithParent(ownerApi, ownerUser, parentId, firstName) {
|
|
132
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
-
const created = yield ownerApi.patientApi.createPatientWithUser(ownerUser, yield ownerApi.patientApi.newInstance(ownerUser, { firstName, lastName: 'Doe' }));
|
|
134
|
-
const secretIds = yield ownerApi.patientApi.decryptSecretIdsOf(created);
|
|
135
|
-
return yield ownerApi.patientApi.shareWithMany(created, { [parentId]: { shareSecretIds: secretIds } });
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/** Inserts a legacy (v7-native, already shared with parentId) patient directly from its fixture. */
|
|
139
|
-
function createV7PatientSharedWithParent(ownerApi, fixture, ownerId, parentId, firstName) {
|
|
140
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
-
return new icc_api_1.IccPatientApi(env.iCureUrl, {}, ownerApi.authApi.authenticationProvider, fetch).createPatient(legacyPatientBase(fixture, ownerId, parentId, firstName));
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Creates a fresh hcp (random keypair) and makes it a child of parentId, to establish the existing
|
|
146
|
-
* relationship that operations such as mergePatients require between data owners in order to
|
|
147
|
-
* authorize the operation (an entirely unrelated hcp gets a 403).
|
|
148
|
-
*
|
|
149
|
-
* By default this does NOT give the child a locally-held copy of the parent's key
|
|
150
|
-
* (disableParentKeysInitialisation skips the startup check that would otherwise require one): in
|
|
151
|
-
* tests where we only care about the authorization relationship, we don't want the child to also
|
|
152
|
-
* be able to reach anything shared with the parent through a locally-cached parent key, which
|
|
153
|
-
* would muddy visibility assertions.
|
|
154
|
-
* Pass holdParentKey: true for tests that specifically want to exercise genuine hierarchical
|
|
155
|
-
* inheritance (a child that has actually verified/cached its parent's key, like a properly
|
|
156
|
-
* provisioned device in the same care organisation - as opposed to the confidentiality checks
|
|
157
|
-
* elsewhere in this suite, which intentionally avoid this).
|
|
158
|
-
*/
|
|
159
|
-
function createChildOfParent(testSetupApi, parentId, parentKeys) {
|
|
160
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
-
const info = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
162
|
-
yield testSetupApi.healthcarePartyApi.modifyHealthcareParty(Object.assign(Object.assign({}, (yield testSetupApi.healthcarePartyApi.getHealthcareParty(info.credentials.dataOwnerId))), { parentId }));
|
|
163
|
-
const storage = yield (0, TestStorage_1.testStorageWithKeys)([
|
|
164
|
-
{
|
|
165
|
-
dataOwnerId: info.credentials.dataOwnerId,
|
|
166
|
-
pairs: [{ keyPair: { privateKey: info.credentials.privateKey, publicKey: info.credentials.publicKey }, shaVersion: icc_x_api_1.ShaVersion.Sha1 }],
|
|
167
|
-
},
|
|
168
|
-
...(parentKeys ? [{ dataOwnerId: parentId, pairs: [{ keyPair: parentKeys, shaVersion: icc_x_api_1.ShaVersion.Sha1 }] }] : []),
|
|
169
|
-
]);
|
|
170
|
-
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 });
|
|
171
|
-
const user = yield api.userApi.getCurrentUser();
|
|
172
|
-
return { api, user, id: info.credentials.dataOwnerId };
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
describe('CSM-814', function () {
|
|
176
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
-
before(function () {
|
|
178
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
-
this.timeout(600000);
|
|
180
|
-
const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
|
|
181
|
-
env = yield initializer.execute((0, types_1.getEnvVariables)());
|
|
182
|
-
hierarchyApis = yield (0, test_utils_1.createHcpHierarchyApis)(env);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
it('A user should be able to share a just created patient secret id', function () {
|
|
186
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
-
const { childApi, childUser, child2Api, child2User, grandCredentials } = hierarchyApis;
|
|
188
|
-
const pat = yield childApi.patientApi.createPatientWithUser(childUser, yield childApi.patientApi.newInstance(childUser, {
|
|
189
|
-
firstName: 'John',
|
|
190
|
-
lastName: 'Doe',
|
|
191
|
-
}));
|
|
192
|
-
const initialSecretIds = yield childApi.patientApi.decryptSecretIdsOf(yield childApi.patientApi.getPatientWithUser(childUser, pat.id));
|
|
193
|
-
(0, chai_1.expect)(initialSecretIds).to.have.length(1);
|
|
194
|
-
(0, chai_1.expect)(yield child2Api.patientApi.decryptSecretIdsOf(yield child2Api.patientApi.getPatientWithUser(child2User, pat.id))).to.have.members(initialSecretIds);
|
|
195
|
-
const newSecretId = (0, crypto_1.randomUUID)();
|
|
196
|
-
const allSecretIds = [...initialSecretIds, newSecretId];
|
|
197
|
-
yield childApi.patientApi.shareWithMany(pat, {
|
|
198
|
-
[grandCredentials.dataOwnerId]: {
|
|
199
|
-
shareSecretIds: allSecretIds,
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
(0, chai_1.expect)(yield childApi.patientApi.decryptSecretIdsOf(yield childApi.patientApi.getPatientWithUser(childUser, pat.id))).to.have.members(allSecretIds);
|
|
203
|
-
(0, chai_1.expect)(yield child2Api.patientApi.decryptSecretIdsOf(yield child2Api.patientApi.getPatientWithUser(child2User, pat.id))).to.have.members(allSecretIds);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
it('A user should be able to share the secret id of a just created patient and add a new secret id to a legacy patient created by an old sdk version, in the same operation', function () {
|
|
207
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
208
|
-
const testSetupApi = yield initMasterApi(env);
|
|
209
|
-
// P, the shared parent of A and B, and the delegate the legacy patient is already shared with.
|
|
210
|
-
const pId = (0, crypto_1.randomUUID)();
|
|
211
|
-
const { api: pApi, user: pUser } = yield createFixedKeyDataOwner(testSetupApi, pId, {
|
|
212
|
-
firstName: 'Jane',
|
|
213
|
-
privateKey: pPrivateKey,
|
|
214
|
-
publicKey: pPublicKey,
|
|
215
|
-
});
|
|
216
|
-
const aId = (0, crypto_1.randomUUID)();
|
|
217
|
-
const { api: aApi, user: aUser } = yield createFixedKeyDataOwner(testSetupApi, aId, {
|
|
218
|
-
firstName: 'John',
|
|
219
|
-
privateKey: aFixture.privateKey,
|
|
220
|
-
publicKey: aFixture.publicKey,
|
|
221
|
-
parentId: pId,
|
|
222
|
-
aesExchangeKeys: legacyAesExchangeKeys(aFixture, aId, pId),
|
|
223
|
-
autoDelegations: [pId],
|
|
224
|
-
extraKeys: [{ dataOwnerId: pId, privateKey: pPrivateKey, publicKey: pPublicKey }],
|
|
225
|
-
});
|
|
226
|
-
const patient = yield createV7PatientSharedWithParent(aApi, aFixture, aId, pId, 'John');
|
|
227
|
-
// B, a sibling of A under the same parent P. B does not have any direct access to the patient,
|
|
228
|
-
// but has access to P's key (e.g. a shared workstation), so it should be able to decrypt
|
|
229
|
-
// anything shared with P, both before and after the new secret id is added.
|
|
230
|
-
const bInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
231
|
-
yield testSetupApi.healthcarePartyApi.modifyHealthcareParty(Object.assign(Object.assign({}, (yield testSetupApi.healthcarePartyApi.getHealthcareParty(bInfo.credentials.dataOwnerId))), { parentId: pId }));
|
|
232
|
-
const bStorage = yield (0, TestStorage_1.testStorageWithKeys)([
|
|
233
|
-
{ dataOwnerId: pId, pairs: [{ keyPair: { privateKey: pPrivateKey, publicKey: pPublicKey }, shaVersion: icc_x_api_1.ShaVersion.Sha1 }] },
|
|
234
|
-
{
|
|
235
|
-
dataOwnerId: bInfo.credentials.dataOwnerId,
|
|
236
|
-
pairs: [{ keyPair: { privateKey: bInfo.credentials.privateKey, publicKey: bInfo.credentials.publicKey }, shaVersion: icc_x_api_1.ShaVersion.Sha1 }],
|
|
237
|
-
},
|
|
238
|
-
]);
|
|
239
|
-
const bApi = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: bInfo.credentials.user, password: bInfo.credentials.password }, new TestCryptoStrategies_1.TestCryptoStrategies(), crypto_1.webcrypto, fetch, {
|
|
240
|
-
storage: bStorage.storage,
|
|
241
|
-
keyStorage: bStorage.keyStorage,
|
|
242
|
-
entryKeysFactory: bStorage.keyFactory,
|
|
243
|
-
});
|
|
244
|
-
const bUser = yield bApi.userApi.getCurrentUser();
|
|
245
|
-
// P's own login can't yet resolve the pure-legacy (v7-native) delegation directly - that legacy
|
|
246
|
-
// format is only self-service-resolvable by its owner (A) or by a session that already holds
|
|
247
|
-
// the delegate's private key locally (B, standing in for a shared workstation), same as
|
|
248
|
-
// test/icc-x-api/crypto/legacy-metadata-migration-test.ts never checks a bare "p" login against
|
|
249
|
-
// pure legacy data either. Once A performs a real (v8) share below, P's own login resolves fine.
|
|
250
|
-
const initialSecretIds = yield aApi.patientApi.decryptSecretIdsOf(yield aApi.patientApi.getPatientWithUser(aUser, patient.id));
|
|
251
|
-
(0, chai_1.expect)(initialSecretIds).to.have.length(1);
|
|
252
|
-
(0, chai_1.expect)(yield bApi.patientApi.decryptSecretIdsOf(yield bApi.patientApi.getPatientWithUser(bUser, patient.id))).to.have.members(initialSecretIds);
|
|
253
|
-
const newSecretId = (0, crypto_1.randomUUID)();
|
|
254
|
-
const allSecretIds = [...initialSecretIds, newSecretId];
|
|
255
|
-
yield aApi.patientApi.shareWithMany(patient, {
|
|
256
|
-
[pId]: { shareSecretIds: allSecretIds },
|
|
257
|
-
});
|
|
258
|
-
(0, chai_1.expect)(yield aApi.patientApi.decryptSecretIdsOf(yield aApi.patientApi.getPatientWithUser(aUser, patient.id))).to.have.members(allSecretIds);
|
|
259
|
-
(0, chai_1.expect)(yield pApi.patientApi.decryptSecretIdsOf(yield pApi.patientApi.getPatientWithUser(pUser, patient.id))).to.have.members(allSecretIds);
|
|
260
|
-
(0, chai_1.expect)(yield bApi.patientApi.decryptSecretIdsOf(yield bApi.patientApi.getPatientWithUser(bUser, patient.id))).to.have.members(allSecretIds);
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
describe('mergePatients', function () {
|
|
264
|
-
const versions = ['v8', 'v7'];
|
|
265
|
-
const mergedBys = ['A', 'B'];
|
|
266
|
-
const variants = versions.flatMap((fromVersion) => versions.flatMap((intoVersion) => mergedBys.map((mergedBy) => ({ fromVersion, intoVersion, mergedBy }))));
|
|
267
|
-
/**
|
|
268
|
-
* Sets up a shared parent P and two sibling hcps A and B (each with their own fixed keypair,
|
|
269
|
-
* both holding P's key locally too, standing in for a shared workstation - so that regardless
|
|
270
|
-
* of which of A/B performs the merge, and regardless of how much direct access the merge
|
|
271
|
-
* propagates to each side, both can fall back on P's key to reach anything shared with P).
|
|
272
|
-
*/
|
|
273
|
-
function setupParticipants() {
|
|
274
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
275
|
-
const testSetupApi = yield initMasterApi(env);
|
|
276
|
-
const pId = (0, crypto_1.randomUUID)();
|
|
277
|
-
yield createFixedKeyDataOwner(testSetupApi, pId, { firstName: 'Jane', privateKey: pPrivateKey, publicKey: pPublicKey });
|
|
278
|
-
const aId = (0, crypto_1.randomUUID)();
|
|
279
|
-
const { api: aApi, user: aUser } = yield createFixedKeyDataOwner(testSetupApi, aId, {
|
|
280
|
-
firstName: 'John',
|
|
281
|
-
privateKey: aFixture.privateKey,
|
|
282
|
-
publicKey: aFixture.publicKey,
|
|
283
|
-
parentId: pId,
|
|
284
|
-
aesExchangeKeys: legacyAesExchangeKeys(aFixture, aId, pId),
|
|
285
|
-
autoDelegations: [pId],
|
|
286
|
-
extraKeys: [{ dataOwnerId: pId, privateKey: pPrivateKey, publicKey: pPublicKey }],
|
|
287
|
-
});
|
|
288
|
-
const bId = (0, crypto_1.randomUUID)();
|
|
289
|
-
const { api: bApi, user: bUser } = yield createFixedKeyDataOwner(testSetupApi, bId, {
|
|
290
|
-
firstName: 'Jack',
|
|
291
|
-
privateKey: bFixture.privateKey,
|
|
292
|
-
publicKey: bFixture.publicKey,
|
|
293
|
-
parentId: pId,
|
|
294
|
-
aesExchangeKeys: legacyAesExchangeKeys(bFixture, bId, pId),
|
|
295
|
-
autoDelegations: [pId],
|
|
296
|
-
extraKeys: [{ dataOwnerId: pId, privateKey: pPrivateKey, publicKey: pPublicKey }],
|
|
297
|
-
});
|
|
298
|
-
return { testSetupApi, pId, aId, bId, aApi, aUser, bApi, bUser };
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
for (const variant of variants) {
|
|
302
|
-
it(`merges a ${variant.fromVersion} patient owned by A into a ${variant.intoVersion} patient owned by B, both shared with the same parent P, merge performed by ${variant.mergedBy}`, function () {
|
|
303
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
304
|
-
const { pId, aId, bId, aApi, aUser, bApi, bUser } = yield setupParticipants();
|
|
305
|
-
const pA = variant.fromVersion === 'v8'
|
|
306
|
-
? yield createV8PatientSharedWithParent(aApi, aUser, pId, 'John')
|
|
307
|
-
: yield createV7PatientSharedWithParent(aApi, aFixture, aId, pId, 'John');
|
|
308
|
-
const pB = variant.intoVersion === 'v8'
|
|
309
|
-
? yield createV8PatientSharedWithParent(bApi, bUser, pId, 'Jack')
|
|
310
|
-
: yield createV7PatientSharedWithParent(bApi, bFixture, bId, pId, 'Jack');
|
|
311
|
-
const aSecretId = (yield aApi.patientApi.decryptSecretIdsOf(pA))[0];
|
|
312
|
-
const bSecretId = (yield bApi.patientApi.decryptSecretIdsOf(pB))[0];
|
|
313
|
-
(0, chai_1.expect)(aSecretId).to.not.be.undefined;
|
|
314
|
-
(0, chai_1.expect)(bSecretId).to.not.be.undefined;
|
|
315
|
-
const allSecretIds = [aSecretId, bSecretId];
|
|
316
|
-
// Re-fetch right before merging: A's autoDelegations (and B's, symmetrically) may still be
|
|
317
|
-
// asynchronously finishing an auto-share in the background after creation, which would
|
|
318
|
-
// otherwise leave us holding a stale rev and make the merge fail with a 409 conflict.
|
|
319
|
-
const freshPA = yield aApi.patientApi.getPatientWithUser(aUser, pA.id);
|
|
320
|
-
const freshPB = yield bApi.patientApi.getPatientWithUser(bUser, pB.id);
|
|
321
|
-
const merger = variant.mergedBy === 'A' ? aApi : bApi;
|
|
322
|
-
const otherId = variant.mergedBy === 'A' ? bId : aId;
|
|
323
|
-
const mergedInto = yield merger.patientApi.mergePatients(freshPA, freshPB);
|
|
324
|
-
// Documented merge metadata: `from` is soft-deleted and points to `into`; `into` records the merge.
|
|
325
|
-
const fromAfterMerge = yield aApi.patientApi.getPatientWithUser(aUser, pA.id);
|
|
326
|
-
(0, chai_1.expect)(fromAfterMerge.deletionDate).to.not.be.undefined;
|
|
327
|
-
(0, chai_1.expect)(fromAfterMerge.mergeToPatientId).to.equal(pB.id);
|
|
328
|
-
(0, chai_1.expect)(mergedInto.mergedIds).to.include(pA.id);
|
|
329
|
-
// Per mergePatients' own documentation, the merge alone does not share the merged content
|
|
330
|
-
// with users that only had access to one of the two original entities: the merger (who per
|
|
331
|
-
// the docs gets full access to everything as a result of the merge) has to explicitly share
|
|
332
|
-
// with the other sibling afterwards for both to end up with full access to both secret ids.
|
|
333
|
-
yield merger.patientApi.shareWithMany(mergedInto, { [otherId]: { shareSecretIds: allSecretIds } });
|
|
334
|
-
(0, chai_1.expect)(yield aApi.patientApi.decryptSecretIdsOf(yield aApi.patientApi.getPatientWithUser(aUser, mergedInto.id))).to.have.members(allSecretIds);
|
|
335
|
-
(0, chai_1.expect)(yield bApi.patientApi.decryptSecretIdsOf(yield bApi.patientApi.getPatientWithUser(bUser, mergedInto.id))).to.have.members(allSecretIds);
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
/*
|
|
341
|
-
* mergePatients only merges the two entities' existing security metadata (secret id/encryption
|
|
342
|
-
* key delegations) server-side, without decrypting anything: whatever a data owner could access
|
|
343
|
-
* on one of the two original patients, it can still access on the merged patient, and nothing
|
|
344
|
-
* more. In particular:
|
|
345
|
-
* - a secret id that was never shared with anyone but its owner (e.g. a confidential secret id)
|
|
346
|
-
* stays known only to that owner after the merge
|
|
347
|
-
* - a secret id that was shared with a third party (here, a common parent P of A and B) is still
|
|
348
|
-
* known to that third party after the merge
|
|
349
|
-
* - none of this depends on which of A, B, or a completely unrelated third hcp performs the merge,
|
|
350
|
-
* since the merger's own identity only matters for re-encrypting the `into` patient's content
|
|
351
|
-
* for itself, not for the secret id metadata merge itself.
|
|
352
|
-
*/
|
|
353
|
-
describe('mergePatients preserves secret id visibility independently of the merger', function () {
|
|
354
|
-
const mergers = ['A', 'B', 'C'];
|
|
355
|
-
for (const merger of mergers) {
|
|
356
|
-
it(`keeps every secret id visible to exactly the data owners it was shared with before the merge, regardless of who performs it (merged by ${merger})`, function () {
|
|
357
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
358
|
-
const testSetupApi = yield initMasterApi(env);
|
|
359
|
-
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
360
|
-
const pId = pInfo.credentials.dataOwnerId;
|
|
361
|
-
// A, B and the merger C are all children of the same parent P: mergePatients (like most
|
|
362
|
-
// write operations) is only authorized between data owners that have some existing
|
|
363
|
-
// relationship, so an entirely unrelated hcp couldn't perform the merge at all - C stands
|
|
364
|
-
// in for "anyone else in the same care organisation", not a random stranger.
|
|
365
|
-
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
366
|
-
const bInfo = yield createChildOfParent(testSetupApi, pId);
|
|
367
|
-
const cInfo = yield createChildOfParent(testSetupApi, pId);
|
|
368
|
-
// PatientA: s1 stays confidential (known only to A), s2 gets shared with the parent P.
|
|
369
|
-
const createdPA = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe' }));
|
|
370
|
-
const s1 = (yield aInfo.api.patientApi.decryptSecretIdsOf(createdPA))[0];
|
|
371
|
-
const s2 = (0, crypto_1.randomUUID)();
|
|
372
|
-
const pA = yield aInfo.api.patientApi.shareWithMany(createdPA, { [pId]: { shareSecretIds: [s2] } });
|
|
373
|
-
// PatientB: s3 stays confidential (known only to B), s4 gets shared with the same parent P.
|
|
374
|
-
const createdPB = yield bInfo.api.patientApi.createPatientWithUser(bInfo.user, yield bInfo.api.patientApi.newInstance(bInfo.user, { firstName: 'Jack', lastName: 'Doe' }));
|
|
375
|
-
const s3 = (yield bInfo.api.patientApi.decryptSecretIdsOf(createdPB))[0];
|
|
376
|
-
const s4 = (0, crypto_1.randomUUID)();
|
|
377
|
-
const pB = yield bInfo.api.patientApi.shareWithMany(createdPB, { [pId]: { shareSecretIds: [s4] } });
|
|
378
|
-
const mergerApi = merger === 'A' ? aInfo.api : merger === 'B' ? bInfo.api : cInfo.api;
|
|
379
|
-
const freshPA = yield aInfo.api.patientApi.getPatientWithUser(aInfo.user, pA.id);
|
|
380
|
-
const freshPB = yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, pB.id);
|
|
381
|
-
const merged = yield mergerApi.patientApi.mergePatients(freshPA, freshPB);
|
|
382
|
-
(0, chai_1.expect)(yield aInfo.api.patientApi.decryptSecretIdsOf(yield aInfo.api.patientApi.getPatientWithUser(aInfo.user, merged.id))).to.have.members([
|
|
383
|
-
s1,
|
|
384
|
-
s2,
|
|
385
|
-
]);
|
|
386
|
-
(0, chai_1.expect)(yield bInfo.api.patientApi.decryptSecretIdsOf(yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, merged.id))).to.have.members([
|
|
387
|
-
s3,
|
|
388
|
-
s4,
|
|
389
|
-
]);
|
|
390
|
-
(0, chai_1.expect)(yield pInfo.api.patientApi.decryptSecretIdsOf(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, merged.id))).to.have.members([
|
|
391
|
-
s2,
|
|
392
|
-
s4,
|
|
393
|
-
]);
|
|
394
|
-
});
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
/*
|
|
399
|
-
* mergePatients forcefully disables merging the `from` patient's encryption key into the `into`
|
|
400
|
-
* patient (the `into` patient keeps only its own, pre-existing encryption key): the method
|
|
401
|
-
* expects callers to be working with decrypted patients, so there is no need to end up with two
|
|
402
|
-
* distinct encryption keys on the merged patient the way kraken would by default.
|
|
403
|
-
* One consequence is a corner case: if the `into` patient's encryption key was never shared with
|
|
404
|
-
* a party that *did* have the `from` patient's encryption key, that party loses the ability to
|
|
405
|
-
* decrypt the merged patient's content (though not its secret ids, which are unaffected and still
|
|
406
|
-
* merge normally) - a followup shareWith/shareWithMany restores it. Sharing only the encryption
|
|
407
|
-
* key (shareSecretIds: []) again with someone who already has it is a harmless no-op, even when
|
|
408
|
-
* the caller isn't the entity's original creator.
|
|
409
|
-
*/
|
|
410
|
-
describe('mergePatients does not merge encryption keys, and a follow-up shareWith restores lost access', function () {
|
|
411
|
-
it('drops the encryption key of the from patient, and a shareWith with empty shareSecretIds afterwards fixes decryption for whoever needs it', function () {
|
|
412
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
413
|
-
const testSetupApi = yield initMasterApi(env);
|
|
414
|
-
const pInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
415
|
-
const pId = pInfo.credentials.dataOwnerId;
|
|
416
|
-
// A and B are children of the same parent P, so that A is authorized to merge B's patient
|
|
417
|
-
// into its own (see the note above about mergePatients requiring an existing relationship).
|
|
418
|
-
// B additionally holds P's key locally (holdParentKey), like a properly provisioned device
|
|
419
|
-
// in the same care organisation, so that anything shared with P is genuinely, automatically
|
|
420
|
-
// reachable by B too - this is what the redundant-reshare check below relies on.
|
|
421
|
-
const aInfo = yield createChildOfParent(testSetupApi, pId);
|
|
422
|
-
const bInfo = yield createChildOfParent(testSetupApi, pId, { privateKey: pInfo.credentials.privateKey, publicKey: pInfo.credentials.publicKey });
|
|
423
|
-
// PatientA created by hcpA, but for some reason not shared with the parent at all.
|
|
424
|
-
const pA = yield aInfo.api.patientApi.createPatientWithUser(aInfo.user, yield aInfo.api.patientApi.newInstance(aInfo.user, { firstName: 'John', lastName: 'Doe', note: 'note from A' }));
|
|
425
|
-
// PatientB created by hcpB and properly shared with the parent (secret id + encryption key).
|
|
426
|
-
const createdPB = yield bInfo.api.patientApi.createPatientWithUser(bInfo.user, yield bInfo.api.patientApi.newInstance(bInfo.user, { firstName: 'Jack', lastName: 'Doe', note: 'note from B' }));
|
|
427
|
-
const bSecretId = (yield bInfo.api.patientApi.decryptSecretIdsOf(createdPB))[0];
|
|
428
|
-
const pB = yield bInfo.api.patientApi.shareWithMany(createdPB, { [pId]: { shareSecretIds: [bSecretId] } });
|
|
429
|
-
(0, chai_1.expect)(yield pInfo.api.patientApi.decryptSecretIdsOf(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, pB.id))).to.have.members([
|
|
430
|
-
bSecretId,
|
|
431
|
-
]);
|
|
432
|
-
// hcpA merges PatientB into PatientA: PatientB's secret id still gets merged in (unaffected),
|
|
433
|
-
// but PatientA's own encryption key is the only one that survives on the merged patient - so
|
|
434
|
-
// even though the parent could decrypt PatientB's content a moment ago, it now can't decrypt
|
|
435
|
-
// the merged patient's content at all (note comes back undefined), despite still being able to
|
|
436
|
-
// find the merged-in secret id.
|
|
437
|
-
const freshPA = yield aInfo.api.patientApi.getPatientWithUser(aInfo.user, pA.id);
|
|
438
|
-
const freshPB = yield bInfo.api.patientApi.getPatientWithUser(bInfo.user, pB.id);
|
|
439
|
-
const merged = yield aInfo.api.patientApi.mergePatients(freshPB, freshPA);
|
|
440
|
-
(0, chai_1.expect)(yield pInfo.api.patientApi.decryptSecretIdsOf(yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, merged.id))).to.have.members([
|
|
441
|
-
bSecretId,
|
|
442
|
-
]);
|
|
443
|
-
(0, chai_1.expect)((yield pInfo.api.patientApi.getPatientWithUser(pInfo.user, merged.id)).note).to.be.undefined;
|
|
444
|
-
// hcpA shares just the encryption key with the parent to fix this: shareSecretIds is left
|
|
445
|
-
// empty (no new secret id to share) and shareEncryptionKey defaults to IF_AVAILABLE, which
|
|
446
|
-
// applies here since A currently holds the only surviving encryption key. This is a real
|
|
447
|
-
// change (the parent never had access to this specific entity before), so the rev changes.
|
|
448
|
-
const resharedByA = yield aInfo.api.patientApi.shareWith(pId, merged, []);
|
|
449
|
-
(0, chai_1.expect)(resharedByA.rev).to.not.equal(merged.rev);
|
|
450
|
-
// Redundant shareWith of an already-shared encryption key, this time performed by B rather
|
|
451
|
-
// than A (the entity's current, and only, encryption key holder): B is a child of the same
|
|
452
|
-
// parent P and genuinely holds P's key locally (like a properly provisioned device in the
|
|
453
|
-
// same care organisation), so B can decrypt the A->P delegation and see that P already has
|
|
454
|
-
// this encryption key directly. This is a harmless no-op - there is nothing new to grant, so
|
|
455
|
-
// the rev stays unchanged, even though B itself never granted this access.
|
|
456
|
-
const reshareAgain = yield bInfo.api.patientApi.shareWith(pId, resharedByA, []);
|
|
457
|
-
(0, chai_1.expect)(reshareAgain.rev).to.equal(resharedByA.rev);
|
|
458
|
-
// shareWithMany to a mix of delegates that already have the key (the parent, a no-op) and
|
|
459
|
-
// delegates that don't yet (a fresh, unrelated hcp, a real change) also works cleanly -
|
|
460
|
-
// explicitly (and, for the parent, wastefully) re-granting access that in a real hierarchy
|
|
461
|
-
// might already be inherited, but not harmfully so. Since D's part is a real change, the rev
|
|
462
|
-
// still changes overall, and D can now decrypt the content.
|
|
463
|
-
const dInfo = yield (0, test_utils_1.createNewHcpApi)(env);
|
|
464
|
-
const sharedWithBoth = yield aInfo.api.patientApi.shareWithMany(reshareAgain, {
|
|
465
|
-
[pId]: { shareSecretIds: [] },
|
|
466
|
-
[dInfo.credentials.dataOwnerId]: { shareSecretIds: [] },
|
|
467
|
-
});
|
|
468
|
-
(0, chai_1.expect)(sharedWithBoth.rev).to.not.equal(reshareAgain.rev);
|
|
469
|
-
(0, chai_1.expect)((yield dInfo.api.patientApi.getPatientWithUser(dInfo.user, sharedWithBoth.id)).note).to.equal('note from A');
|
|
470
|
-
});
|
|
471
|
-
});
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
|
-
});
|
|
475
|
-
//# sourceMappingURL=CSM-814.js.map
|