@icure/api 7.1.14 → 8.0.0-RC.1
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/IccAccesslogApi.d.ts +12 -1
- package/icc-api/api/IccAccesslogApi.js +142 -98
- package/icc-api/api/IccAccesslogApi.js.map +1 -1
- package/icc-api/api/IccBemikronoApi.d.ts +81 -0
- package/icc-api/api/IccBemikronoApi.js +163 -0
- package/icc-api/api/IccBemikronoApi.js.map +1 -0
- package/icc-api/api/IccCalendarItemApi.d.ts +21 -1
- package/icc-api/api/IccCalendarItemApi.js +183 -117
- package/icc-api/api/IccCalendarItemApi.js.map +1 -1
- package/icc-api/api/IccClassificationApi.d.ts +21 -1
- package/icc-api/api/IccClassificationApi.js +119 -63
- package/icc-api/api/IccClassificationApi.js.map +1 -1
- package/icc-api/api/IccContactApi.d.ts +21 -1
- package/icc-api/api/IccContactApi.js +385 -294
- package/icc-api/api/IccContactApi.js.map +1 -1
- package/icc-api/api/IccDocumentApi.d.ts +32 -25
- package/icc-api/api/IccDocumentApi.js +264 -212
- package/icc-api/api/IccDocumentApi.js.map +1 -1
- package/icc-api/api/IccExchangeDataApi.d.ts +19 -0
- package/icc-api/api/IccExchangeDataApi.js +85 -0
- package/icc-api/api/IccExchangeDataApi.js.map +1 -0
- package/icc-api/api/IccExchangeDataMapApi.d.ts +18 -0
- package/icc-api/api/IccExchangeDataMapApi.js +65 -0
- package/icc-api/api/IccExchangeDataMapApi.js.map +1 -0
- package/icc-api/api/IccFormApi.d.ts +21 -1
- package/icc-api/api/IccFormApi.js +321 -229
- package/icc-api/api/IccFormApi.js.map +1 -1
- package/icc-api/api/IccHelementApi.d.ts +21 -1
- package/icc-api/api/IccHelementApi.js +207 -137
- package/icc-api/api/IccHelementApi.js.map +1 -1
- package/icc-api/api/IccInvoiceApi.d.ts +21 -1
- package/icc-api/api/IccInvoiceApi.js +404 -298
- package/icc-api/api/IccInvoiceApi.js.map +1 -1
- package/icc-api/api/IccMaintenanceTaskApi.d.ts +12 -1
- package/icc-api/api/IccMaintenanceTaskApi.js +79 -43
- package/icc-api/api/IccMaintenanceTaskApi.js.map +1 -1
- package/icc-api/api/IccMessageApi.d.ts +12 -1
- package/icc-api/api/IccMessageApi.js +257 -191
- package/icc-api/api/IccMessageApi.js.map +1 -1
- package/icc-api/api/IccPatientApi.d.ts +12 -1
- package/icc-api/api/IccPatientApi.js +447 -351
- package/icc-api/api/IccPatientApi.js.map +1 -1
- package/icc-api/api/IccReceiptApi.d.ts +22 -8
- package/icc-api/api/IccReceiptApi.js +121 -64
- package/icc-api/api/IccReceiptApi.js.map +1 -1
- package/icc-api/api/IccRestApiPath.js +1 -1
- package/icc-api/api/IccRestApiPath.js.map +1 -1
- package/icc-api/api/IccTimeTableApi.d.ts +12 -1
- package/icc-api/api/IccTimeTableApi.js +86 -48
- package/icc-api/api/IccTimeTableApi.js.map +1 -1
- package/icc-api/index.d.ts +1 -0
- package/icc-api/index.js +1 -0
- package/icc-api/index.js.map +1 -1
- package/icc-api/model/AccessLog.d.ts +4 -0
- package/icc-api/model/AccessLog.js +1 -0
- package/icc-api/model/AccessLog.js.map +1 -1
- package/icc-api/model/Article.d.ts +4 -0
- package/icc-api/model/Article.js +1 -0
- package/icc-api/model/Article.js.map +1 -1
- package/icc-api/model/CalendarItem.d.ts +4 -0
- package/icc-api/model/CalendarItem.js +1 -0
- package/icc-api/model/CalendarItem.js.map +1 -1
- package/icc-api/model/Classification.d.ts +4 -0
- package/icc-api/model/Classification.js +1 -0
- package/icc-api/model/Classification.js.map +1 -1
- package/icc-api/model/ClassificationTemplate.d.ts +2 -0
- package/icc-api/model/ClassificationTemplate.js.map +1 -1
- package/icc-api/model/Contact.d.ts +4 -0
- package/icc-api/model/Contact.js +1 -0
- package/icc-api/model/Contact.js.map +1 -1
- package/icc-api/model/Device.d.ts +4 -4
- package/icc-api/model/Device.js.map +1 -1
- package/icc-api/model/Document.d.ts +4 -0
- package/icc-api/model/Document.js +1 -0
- package/icc-api/model/Document.js.map +1 -1
- package/icc-api/model/ExchangeData.d.ts +61 -0
- package/icc-api/model/ExchangeData.js +12 -0
- package/icc-api/model/ExchangeData.js.map +1 -0
- package/icc-api/model/ExchangeDataMap.d.ts +21 -0
- package/icc-api/model/ExchangeDataMap.js +10 -0
- package/icc-api/model/ExchangeDataMap.js.map +1 -0
- package/icc-api/model/ExchangeDataMapCreationBatch.d.ts +13 -0
- package/icc-api/model/ExchangeDataMapCreationBatch.js +10 -0
- package/icc-api/model/ExchangeDataMapCreationBatch.js.map +1 -0
- package/icc-api/model/Form.d.ts +4 -0
- package/icc-api/model/Form.js +1 -0
- package/icc-api/model/Form.js.map +1 -1
- package/icc-api/model/HealthElement.d.ts +4 -0
- package/icc-api/model/HealthElement.js +1 -0
- package/icc-api/model/HealthElement.js.map +1 -1
- package/icc-api/model/HealthcareParty.d.ts +2 -2
- package/icc-api/model/HealthcareParty.js.map +1 -1
- package/icc-api/model/IcureStub.d.ts +2 -0
- package/icc-api/model/IcureStub.js.map +1 -1
- package/icc-api/model/Invoice.d.ts +4 -0
- package/icc-api/model/Invoice.js +1 -0
- package/icc-api/model/Invoice.js.map +1 -1
- package/icc-api/model/MaintenanceTask.d.ts +4 -0
- package/icc-api/model/MaintenanceTask.js +1 -0
- package/icc-api/model/MaintenanceTask.js.map +1 -1
- package/icc-api/model/Message.d.ts +4 -0
- package/icc-api/model/Message.js +1 -0
- package/icc-api/model/Message.js.map +1 -1
- package/icc-api/model/PaginatedListExchangeData.d.ts +9 -0
- package/icc-api/model/PaginatedListExchangeData.js +10 -0
- package/icc-api/model/PaginatedListExchangeData.js.map +1 -0
- package/icc-api/model/Patient.d.ts +6 -2
- package/icc-api/model/Patient.js +1 -0
- package/icc-api/model/Patient.js.map +1 -1
- package/icc-api/model/PatientByHcPartyGenderEducationProfession.d.ts +31 -0
- package/icc-api/model/PatientByHcPartyGenderEducationProfession.js +32 -0
- package/icc-api/model/PatientByHcPartyGenderEducationProfession.js.map +1 -0
- package/icc-api/model/Receipt.d.ts +4 -0
- package/icc-api/model/Receipt.js +1 -0
- package/icc-api/model/Receipt.js.map +1 -1
- package/icc-api/model/SecureDelegation.d.ts +52 -0
- package/icc-api/model/SecureDelegation.js +16 -0
- package/icc-api/model/SecureDelegation.js.map +1 -0
- package/icc-api/model/SecurityMetadata.d.ts +33 -0
- package/icc-api/model/SecurityMetadata.js +13 -0
- package/icc-api/model/SecurityMetadata.js.map +1 -0
- package/icc-api/model/Service.d.ts +2 -0
- package/icc-api/model/Service.js.map +1 -1
- package/icc-api/model/TimeTable.d.ts +4 -0
- package/icc-api/model/TimeTable.js +1 -0
- package/icc-api/model/TimeTable.js.map +1 -1
- package/icc-api/model/models.d.ts +20 -39
- package/icc-api/model/models.js +15 -37
- package/icc-api/model/models.js.map +1 -1
- package/icc-api/model/requests/EntityBulkShareResult.d.ts +28 -0
- package/icc-api/model/requests/EntityBulkShareResult.js +16 -0
- package/icc-api/model/requests/EntityBulkShareResult.js.map +1 -0
- package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.d.ts +10 -0
- package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.js +17 -0
- package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.js.map +1 -0
- package/icc-api/model/requests/EntityShareRequest.d.ts +110 -0
- package/icc-api/model/requests/EntityShareRequest.js +63 -0
- package/icc-api/model/requests/EntityShareRequest.js.map +1 -0
- package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.d.ts +54 -0
- package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.js +24 -0
- package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.js.map +1 -0
- package/icc-api/model/requests/MinimalEntityBulkShareResult.d.ts +23 -0
- package/icc-api/model/requests/MinimalEntityBulkShareResult.js +13 -0
- package/icc-api/model/requests/MinimalEntityBulkShareResult.js.map +1 -0
- package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.d.ts +21 -0
- package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.js +14 -0
- package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.js.map +1 -0
- package/icc-x-api/basexapi/EncryptedEntityXApi.d.ts +3 -2
- package/icc-x-api/basexapi/EncryptedEntityXApi.js.map +1 -1
- package/icc-x-api/crypto/AES.js +1 -1
- package/icc-x-api/crypto/AES.js.map +1 -1
- package/icc-x-api/crypto/AccessControlKeysHeadersProvider.d.ts +16 -0
- package/icc-x-api/crypto/AccessControlKeysHeadersProvider.js +41 -0
- package/icc-x-api/crypto/AccessControlKeysHeadersProvider.js.map +1 -0
- package/icc-x-api/crypto/AccessControlSecretUtils.d.ts +42 -0
- package/icc-x-api/crypto/AccessControlSecretUtils.js +86 -0
- package/icc-x-api/crypto/AccessControlSecretUtils.js.map +1 -0
- package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +146 -0
- package/icc-x-api/crypto/BaseExchangeDataManager.js +342 -0
- package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -0
- package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +0 -18
- package/icc-x-api/crypto/BaseExchangeKeysManager.js +11 -85
- package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/ConfidentialEntities.d.ts +26 -16
- package/icc-x-api/crypto/ConfidentialEntities.js +30 -17
- package/icc-x-api/crypto/ConfidentialEntities.js.map +1 -1
- package/icc-x-api/crypto/CryptoStrategies.d.ts +8 -1
- package/icc-x-api/crypto/CryptoStrategies.js.map +1 -1
- package/icc-x-api/crypto/ExchangeDataManager.d.ts +95 -0
- package/icc-x-api/crypto/ExchangeDataManager.js +493 -0
- package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -0
- package/icc-x-api/crypto/ExchangeDataMapManager.d.ts +32 -0
- package/icc-x-api/crypto/ExchangeDataMapManager.js +70 -0
- package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -0
- package/icc-x-api/crypto/ExchangeKeysManager.d.ts +4 -16
- package/icc-x-api/crypto/ExchangeKeysManager.js +4 -62
- package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/ExtendedApisUtils.d.ts +336 -0
- package/icc-x-api/crypto/ExtendedApisUtils.js +3 -0
- package/icc-x-api/crypto/ExtendedApisUtils.js.map +1 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +181 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +562 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -0
- package/icc-x-api/crypto/KeyRecovery.d.ts +5 -2
- package/icc-x-api/crypto/KeyRecovery.js +59 -29
- package/icc-x-api/crypto/KeyRecovery.js.map +1 -1
- package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +7 -2
- package/icc-x-api/crypto/LegacyCryptoStrategies.js +8 -1
- package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -1
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.d.ts +39 -0
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js +150 -0
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js.map +1 -0
- package/icc-x-api/crypto/RSA.d.ts +34 -8
- package/icc-x-api/crypto/RSA.js +80 -13
- package/icc-x-api/crypto/RSA.js.map +1 -1
- package/icc-x-api/crypto/SecureDelegationsEncryption.d.ts +54 -0
- package/icc-x-api/crypto/SecureDelegationsEncryption.js +178 -0
- package/icc-x-api/crypto/SecureDelegationsEncryption.js.map +1 -0
- package/icc-x-api/crypto/SecureDelegationsManager.d.ts +66 -0
- package/icc-x-api/crypto/SecureDelegationsManager.js +261 -0
- package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -0
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.d.ts +37 -0
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js +294 -0
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js.map +1 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +114 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js +98 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -0
- package/icc-x-api/crypto/ShamirKeysManager.d.ts +5 -5
- package/icc-x-api/crypto/ShamirKeysManager.js +6 -9
- package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -1
- package/icc-x-api/crypto/TransferKeysManager.d.ts +8 -6
- package/icc-x-api/crypto/TransferKeysManager.js +75 -52
- package/icc-x-api/crypto/TransferKeysManager.js.map +1 -1
- package/icc-x-api/crypto/{KeyManager.d.ts → UserEncryptionKeysManager.d.ts} +4 -6
- package/icc-x-api/crypto/{KeyManager.js → UserEncryptionKeysManager.js} +43 -23
- package/icc-x-api/crypto/UserEncryptionKeysManager.js.map +1 -0
- package/icc-x-api/crypto/UserSignatureKeysManager.d.ts +26 -0
- package/icc-x-api/crypto/UserSignatureKeysManager.js +74 -0
- package/icc-x-api/crypto/UserSignatureKeysManager.js.map +1 -0
- package/icc-x-api/crypto/utils.d.ts +61 -11
- package/icc-x-api/crypto/utils.js +113 -44
- package/icc-x-api/crypto/utils.js.map +1 -1
- package/icc-x-api/filters/filters.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +46 -11
- package/icc-x-api/icc-accesslog-x-api.js +75 -42
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.d.ts +50 -14
- package/icc-x-api/icc-calendar-item-x-api.js +99 -49
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-classification-x-api.d.ts +44 -9
- package/icc-x-api/icc-classification-x-api.js +56 -31
- package/icc-x-api/icc-classification-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.d.ts +56 -32
- package/icc-x-api/icc-contact-x-api.js +95 -64
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-crypto-x-api.d.ts +28 -334
- package/icc-x-api/icc-crypto-x-api.js +41 -765
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/icc-data-owner-x-api.d.ts +20 -8
- package/icc-x-api/icc-data-owner-x-api.js +31 -10
- package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.d.ts +48 -11
- package/icc-x-api/icc-document-x-api.js +111 -64
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.d.ts +45 -10
- package/icc-x-api/icc-form-x-api.js +65 -35
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-hcparty-x-api.d.ts +2 -2
- package/icc-x-api/icc-hcparty-x-api.js +3 -3
- package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.d.ts +55 -18
- package/icc-x-api/icc-helement-x-api.js +76 -41
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-icure-maintenance-x-api.d.ts +7 -2
- package/icc-x-api/icc-icure-maintenance-x-api.js +38 -27
- package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -1
- package/icc-x-api/icc-invoice-x-api.d.ts +50 -15
- package/icc-x-api/icc-invoice-x-api.js +63 -33
- package/icc-x-api/icc-invoice-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.d.ts +53 -21
- package/icc-x-api/icc-maintenance-task-x-api.js +72 -35
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-message-x-api.d.ts +53 -15
- package/icc-x-api/icc-message-x-api.js +65 -36
- package/icc-x-api/icc-message-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.d.ts +84 -29
- package/icc-x-api/icc-patient-x-api.js +313 -378
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-receipt-x-api.d.ts +44 -12
- package/icc-x-api/icc-receipt-x-api.js +67 -35
- package/icc-x-api/icc-receipt-x-api.js.map +1 -1
- package/icc-x-api/icc-time-table-x-api.d.ts +43 -12
- package/icc-x-api/icc-time-table-x-api.js +56 -26
- package/icc-x-api/icc-time-table-x-api.js.map +1 -1
- package/icc-x-api/icc-user-x-api.d.ts +2 -2
- package/icc-x-api/icc-user-x-api.js +3 -3
- package/icc-x-api/icc-user-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +4 -2
- package/icc-x-api/index.js +154 -135
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.d.ts +2 -0
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js +9 -2
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js.map +1 -1
- package/icc-x-api/storage/IcureStorageFacade.d.ts +23 -2
- package/icc-x-api/storage/IcureStorageFacade.js +36 -2
- package/icc-x-api/storage/IcureStorageFacade.js.map +1 -1
- package/icc-x-api/storage/KeyStorageFacade.d.ts +12 -0
- package/icc-x-api/storage/KeyStorageFacade.js.map +1 -1
- package/icc-x-api/storage/KeyStorageImpl.d.ts +2 -0
- package/icc-x-api/storage/KeyStorageImpl.js +10 -0
- package/icc-x-api/storage/KeyStorageImpl.js.map +1 -1
- package/icc-x-api/storage/StorageEntryKeysFactory.d.ts +14 -1
- package/icc-x-api/storage/StorageEntryKeysFactory.js.map +1 -1
- package/icc-x-api/utils/EntityWithDelegationTypeName.d.ts +32 -0
- package/icc-x-api/utils/EntityWithDelegationTypeName.js +75 -0
- package/icc-x-api/utils/EntityWithDelegationTypeName.js.map +1 -0
- package/icc-x-api/utils/ShareResult.d.ts +74 -0
- package/icc-x-api/utils/ShareResult.js +61 -0
- package/icc-x-api/utils/ShareResult.js.map +1 -0
- package/icc-x-api/utils/binary-utils.d.ts +1 -0
- package/icc-x-api/utils/binary-utils.js +8 -1
- package/icc-x-api/utils/binary-utils.js.map +1 -1
- package/icc-x-api/utils/collection-utils.d.ts +5 -0
- package/icc-x-api/utils/collection-utils.js +26 -1
- package/icc-x-api/utils/collection-utils.js.map +1 -1
- package/icc-x-api/utils/crypto-utils.d.ts +4 -3
- package/icc-x-api/utils/crypto-utils.js +5 -4
- package/icc-x-api/utils/crypto-utils.js.map +1 -1
- package/icc-x-api/utils/lru-temporised-async-cache.d.ts +26 -3
- package/icc-x-api/utils/lru-temporised-async-cache.js +75 -15
- package/icc-x-api/utils/lru-temporised-async-cache.js.map +1 -1
- package/icc-x-api/utils/websocket.d.ts +10 -10
- package/icc-x-api/utils/websocket.js +18 -9
- package/icc-x-api/utils/websocket.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.js +3 -1
- package/index.js.map +1 -1
- package/package.json +2 -3
- package/icc-x-api/crypto/EntitiesEncryption.d.ts +0 -275
- package/icc-x-api/crypto/EntitiesEncryption.js +0 -734
- package/icc-x-api/crypto/EntitiesEncryption.js.map +0 -1
- package/icc-x-api/crypto/KeyManager.js.map +0 -1
|
@@ -15,10 +15,14 @@ const models = require("../icc-api/model/models");
|
|
|
15
15
|
const _ = require("lodash");
|
|
16
16
|
const moment = require("moment");
|
|
17
17
|
const AuthenticationProvider_1 = require("./auth/AuthenticationProvider");
|
|
18
|
+
const SecureDelegation_1 = require("../icc-api/model/SecureDelegation");
|
|
19
|
+
var AccessLevelEnum = SecureDelegation_1.SecureDelegation.AccessLevelEnum;
|
|
18
20
|
const utils_1 = require("./utils");
|
|
19
21
|
const Connection_1 = require("../icc-api/model/Connection");
|
|
20
|
-
const websocket_1 = require("./utils/websocket");
|
|
21
22
|
class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
23
|
+
get headers() {
|
|
24
|
+
return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, 'HealthElement'));
|
|
25
|
+
}
|
|
22
26
|
constructor(host, headers, crypto, dataOwnerApi, userApi, authApi, encryptedKeys = ['descr', 'note'], authenticationProvider = new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl = typeof window !== 'undefined'
|
|
23
27
|
? window.fetch
|
|
24
28
|
: typeof self !== 'undefined'
|
|
@@ -29,6 +33,10 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
29
33
|
this.dataOwnerApi = dataOwnerApi;
|
|
30
34
|
this.userApi = userApi;
|
|
31
35
|
this.authApi = authApi;
|
|
36
|
+
this.crypto = crypto;
|
|
37
|
+
this.dataOwnerApi = dataOwnerApi;
|
|
38
|
+
this.userApi = userApi;
|
|
39
|
+
this.authApi = authApi;
|
|
32
40
|
this.encryptedFields = (0, utils_1.parseEncryptedFields)(encryptedKeys, 'HealthElement.');
|
|
33
41
|
}
|
|
34
42
|
/**
|
|
@@ -40,32 +48,31 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
40
48
|
* @param options optional parameters:
|
|
41
49
|
* - additionalDelegates: delegates which will have access to the entity in addition to the current data owner and delegates from the
|
|
42
50
|
* auto-delegations. Must be an object which associates each data owner id with the access level to give to that data owner. May overlap with
|
|
43
|
-
* auto-delegations, in such case the access level specified here will be used.
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
51
|
+
* auto-delegations, in such case the access level specified here will be used.
|
|
52
|
+
* - preferredSfk: secret id of the patient to use as the secret foreign key to use for the health element. The default value will be a
|
|
53
|
+
* secret id of patient known by the topmost parent in the current data owner hierarchy if the confidential is set to false, else a secret id that
|
|
54
|
+
* the data owner did not share with any of his parents.
|
|
47
55
|
* - confidential: if true, the entity will be created as confidential. Confidential entities are not shared with auto-delegations, and the default
|
|
48
56
|
* foreign key used is any key that is not shared with any of the data owner parents. By default entities are created as non-confidential.
|
|
49
57
|
* @return a new instance of health element.
|
|
50
58
|
*/
|
|
51
59
|
newInstance(user, patient, h, options = {}) {
|
|
52
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
60
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
53
61
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54
62
|
const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user);
|
|
55
63
|
const helement = Object.assign(Object.assign({}, (h !== null && h !== void 0 ? h : {})), { _type: 'org.taktik.icure.entities.HealthElement', id: (_a = h === null || h === void 0 ? void 0 : h.id) !== null && _a !== void 0 ? _a : this.crypto.primitives.randomUuid(), created: (_b = h === null || h === void 0 ? void 0 : h.created) !== null && _b !== void 0 ? _b : new Date().getTime(), modified: (_c = h === null || h === void 0 ? void 0 : h.modified) !== null && _c !== void 0 ? _c : new Date().getTime(), responsible: (_d = h === null || h === void 0 ? void 0 : h.responsible) !== null && _d !== void 0 ? _d : dataOwnerId, author: (_e = h === null || h === void 0 ? void 0 : h.author) !== null && _e !== void 0 ? _e : user.id, codes: (_f = h === null || h === void 0 ? void 0 : h.codes) !== null && _f !== void 0 ? _f : [], tags: (_g = h === null || h === void 0 ? void 0 : h.tags) !== null && _g !== void 0 ? _g : [], healthElementId: (_h = h === null || h === void 0 ? void 0 : h.healthElementId) !== null && _h !== void 0 ? _h : this.crypto.primitives.randomUuid(), openingDate: (_j = h === null || h === void 0 ? void 0 : h.openingDate) !== null && _j !== void 0 ? _j : parseInt(moment().format('YYYYMMDDHHmmss')) });
|
|
56
64
|
const ownerId = this.dataOwnerApi.getDataOwnerIdOf(user);
|
|
57
65
|
if (ownerId !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
|
|
58
66
|
throw new Error('Can only initialise entities as current data owner.');
|
|
59
|
-
const sfk = (_k = options.preferredSfk) !== null && _k !== void 0 ? _k : (
|
|
60
|
-
? yield this.crypto.confidential.getConfidentialSecretId(patient)
|
|
61
|
-
: yield this.crypto.confidential.getAnySecretIdSharedWithParents(patient));
|
|
67
|
+
const sfk = (_k = options.preferredSfk) !== null && _k !== void 0 ? _k : ((options === null || options === void 0 ? void 0 : options.confidential)
|
|
68
|
+
? yield this.crypto.confidential.getConfidentialSecretId({ entity: patient, type: 'Patient' })
|
|
69
|
+
: yield this.crypto.confidential.getAnySecretIdSharedWithParents({ entity: patient, type: 'Patient' }));
|
|
62
70
|
if (!sfk)
|
|
63
|
-
throw new Error(`Couldn't find any sfk of parent patient ${patient.id} for confidential=${
|
|
64
|
-
const extraDelegations =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const initialisationInfo = yield this.crypto.entities.entityWithInitialisedEncryptedMetadata(helement, patient.id, sfk, true, extraDelegations);
|
|
71
|
+
throw new Error(`Couldn't find any sfk of parent patient ${patient.id} for confidential=${(_l = options === null || options === void 0 ? void 0 : options.confidential) !== null && _l !== void 0 ? _l : false}`);
|
|
72
|
+
const extraDelegations = Object.assign(Object.assign({}, (options.confidential
|
|
73
|
+
? {}
|
|
74
|
+
: Object.fromEntries([...((_o = (_m = user.autoDelegations) === null || _m === void 0 ? void 0 : _m.all) !== null && _o !== void 0 ? _o : []), ...((_q = (_p = user.autoDelegations) === null || _p === void 0 ? void 0 : _p.medicalInformation) !== null && _q !== void 0 ? _q : [])].map((d) => [d, AccessLevelEnum.WRITE])))), ((_r = options === null || options === void 0 ? void 0 : options.additionalDelegates) !== null && _r !== void 0 ? _r : {}));
|
|
75
|
+
const initialisationInfo = yield this.crypto.xapi.entityWithInitialisedEncryptedMetadata(helement, 'HealthElement', patient.id, sfk, true, false, extraDelegations);
|
|
69
76
|
return new models.HealthElement(initialisationInfo.updatedEntity);
|
|
70
77
|
});
|
|
71
78
|
}
|
|
@@ -126,7 +133,7 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
126
133
|
findHealthElementsByHCPartyAndPatientWithUser(user, hcPartyId, patient, usingPost = false) {
|
|
127
134
|
var _a;
|
|
128
135
|
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
-
let keysAndHcPartyId = yield this.crypto.
|
|
136
|
+
let keysAndHcPartyId = yield this.crypto.xapi.secretIdsForHcpHierarchyOf({ entity: patient, type: 'Patient' });
|
|
130
137
|
const keys = (_a = keysAndHcPartyId.find((secretForeignKeys) => secretForeignKeys.ownerId == hcPartyId)) === null || _a === void 0 ? void 0 : _a.extracted;
|
|
131
138
|
if (keys == undefined) {
|
|
132
139
|
throw Error('No delegation for user');
|
|
@@ -140,9 +147,9 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
140
147
|
throw new Error('Cannot call a method that returns health element without providing a user for de/encryption');
|
|
141
148
|
}
|
|
142
149
|
modifyHealthElementWithUser(user, body) {
|
|
143
|
-
return body ? this.
|
|
150
|
+
return body ? this.modifyHealthElementAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : Promise.resolve(null);
|
|
144
151
|
}
|
|
145
|
-
|
|
152
|
+
modifyHealthElementAs(dataOwner, body) {
|
|
146
153
|
return this.encryptAs(dataOwner, [_.cloneDeep(body)])
|
|
147
154
|
.then((hes) => super.modifyHealthElement(hes[0]))
|
|
148
155
|
.then((he) => this.decrypt(dataOwner, [he]))
|
|
@@ -177,8 +184,8 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
177
184
|
* @param usingPost
|
|
178
185
|
*/
|
|
179
186
|
findBy(hcpartyId, patient, keepObsoleteVersions = false, usingPost = false) {
|
|
180
|
-
return this.crypto.
|
|
181
|
-
.secretIdsForHcpHierarchyOf(patient)
|
|
187
|
+
return this.crypto.xapi
|
|
188
|
+
.secretIdsForHcpHierarchyOf({ entity: patient, type: 'Patient' })
|
|
182
189
|
.then((secretForeignKeys) => secretForeignKeys && secretForeignKeys.length > 0
|
|
183
190
|
? Promise.all(secretForeignKeys
|
|
184
191
|
.reduce((acc, level) => {
|
|
@@ -224,13 +231,13 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
224
231
|
return this.encryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), healthElements);
|
|
225
232
|
}
|
|
226
233
|
encryptAs(owner, healthElements) {
|
|
227
|
-
return Promise.all(healthElements.map((he) => this.crypto.
|
|
234
|
+
return Promise.all(healthElements.map((he) => this.crypto.xapi.tryEncryptEntity(he, 'HealthElement', this.encryptedFields, false, false, (x) => new models.HealthElement(x))));
|
|
228
235
|
}
|
|
229
236
|
decryptWithUser(user, hes) {
|
|
230
237
|
return this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes);
|
|
231
238
|
}
|
|
232
239
|
decrypt(dataOwnerId, hes) {
|
|
233
|
-
return Promise.all(hes.map((he) => this.crypto.
|
|
240
|
+
return Promise.all(hes.map((he) => this.crypto.xapi.decryptEntity(he, 'HealthElement', (x) => new models.HealthElement(x)).then(({ entity }) => entity)));
|
|
234
241
|
}
|
|
235
242
|
filterHealthElementsBy(startDocumentId, limit, body) {
|
|
236
243
|
throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption');
|
|
@@ -274,7 +281,15 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
274
281
|
*/
|
|
275
282
|
decryptPatientIdOf(healthElement) {
|
|
276
283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
-
return this.crypto.
|
|
284
|
+
return this.crypto.xapi.owningEntityIdsOf({ entity: healthElement, type: 'HealthElement' }, undefined);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* @return if the logged data owner has write access to the content of the given health element
|
|
289
|
+
*/
|
|
290
|
+
hasWriteAccess(healthElement) {
|
|
291
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
292
|
+
return this.crypto.xapi.hasWriteAccess({ entity: healthElement, type: 'HealthElement' });
|
|
278
293
|
});
|
|
279
294
|
}
|
|
280
295
|
/**
|
|
@@ -288,7 +303,8 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
288
303
|
* health element does not have encrypted content.
|
|
289
304
|
* - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to
|
|
290
305
|
* {@link ShareMetadataBehaviour.IF_AVAILABLE}).
|
|
291
|
-
*
|
|
306
|
+
* - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.
|
|
307
|
+
* @return the updated entity
|
|
292
308
|
*/
|
|
293
309
|
shareWith(delegateId, healthElement, options = {}) {
|
|
294
310
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -298,46 +314,65 @@ class IccHelementXApi extends icc_api_1.IccHelementApi {
|
|
|
298
314
|
/**
|
|
299
315
|
* Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also
|
|
300
316
|
* the encrypted content, with read-only or read-write permissions.
|
|
317
|
+
* @param delegateId the id of the data owner which will be granted access to the health element.
|
|
301
318
|
* @param healthElement the health element to share.
|
|
302
|
-
* @param delegates
|
|
319
|
+
* @param delegates associates the id of data owners which will be granted access to the entity, to the following sharing options:
|
|
303
320
|
* - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted
|
|
304
321
|
* content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a
|
|
305
322
|
* health element does not have encrypted content.
|
|
306
323
|
* - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to
|
|
307
324
|
* {@link ShareMetadataBehaviour.IF_AVAILABLE}).
|
|
308
|
-
*
|
|
325
|
+
* - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.
|
|
326
|
+
* @return the updated entity
|
|
309
327
|
*/
|
|
310
328
|
shareWithMany(healthElement, delegates) {
|
|
329
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
330
|
+
return (yield this.tryShareWithMany(healthElement, delegates)).updatedEntityOrThrow;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also
|
|
335
|
+
* the encrypted content, with read-only or read-write permissions.
|
|
336
|
+
* @param healthElement the health element to share.
|
|
337
|
+
* @param delegates associates the id of data owners which will be granted access to the entity, to the following sharing options:
|
|
338
|
+
* - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted
|
|
339
|
+
* content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a
|
|
340
|
+
* health element does not have encrypted content.
|
|
341
|
+
* - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to
|
|
342
|
+
* {@link ShareMetadataBehaviour.IF_AVAILABLE}).
|
|
343
|
+
* - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.
|
|
344
|
+
* @return a promise which will contain the result of the operation: the updated entity if the operation was successful or details of the error if
|
|
345
|
+
* the operation failed.
|
|
346
|
+
*/
|
|
347
|
+
tryShareWithMany(healthElement, delegates) {
|
|
311
348
|
return __awaiter(this, void 0, void 0, function* () {
|
|
312
349
|
const self = yield this.dataOwnerApi.getCurrentDataOwnerId();
|
|
313
|
-
|
|
350
|
+
// All entities should have an encryption key.
|
|
351
|
+
const entityWithEncryptionKey = yield this.crypto.xapi.ensureEncryptionKeysInitialised(healthElement, 'HealthElement');
|
|
352
|
+
const updatedEntity = entityWithEncryptionKey ? yield this.modifyHealthElementAs(self, entityWithEncryptionKey) : healthElement;
|
|
353
|
+
return this.crypto.xapi
|
|
354
|
+
.simpleShareOrUpdateEncryptedEntityMetadata({ entity: updatedEntity, type: 'HealthElement' }, true, Object.fromEntries(Object.entries(delegates).map(([delegateId, options]) => [
|
|
314
355
|
delegateId,
|
|
315
356
|
{
|
|
316
|
-
|
|
357
|
+
requestedPermissions: options.requestedPermissions,
|
|
358
|
+
shareEncryptionKeys: options.shareEncryptionKey,
|
|
317
359
|
shareOwningEntityIds: options.sharePatientId,
|
|
360
|
+
shareSecretIds: undefined,
|
|
318
361
|
},
|
|
319
|
-
])))
|
|
320
|
-
|
|
321
|
-
return yield this.modifyAs(self, extended);
|
|
322
|
-
}
|
|
323
|
-
else
|
|
324
|
-
return healthElement;
|
|
362
|
+
])), (x) => this.bulkShareHealthElements(x))
|
|
363
|
+
.then((r) => r.mapSuccessAsync((e) => this.decrypt(self, [e]).then((es) => es[0])));
|
|
325
364
|
});
|
|
326
365
|
}
|
|
327
366
|
getDataOwnersWithAccessTo(entity) {
|
|
328
|
-
return
|
|
329
|
-
return yield this.crypto.entities.getDataOwnersWithAccessTo(entity);
|
|
330
|
-
});
|
|
367
|
+
return this.crypto.xapi.getDataOwnersWithAccessTo({ entity, type: 'HealthElement' });
|
|
331
368
|
}
|
|
332
369
|
getEncryptionKeysOf(entity) {
|
|
333
|
-
return
|
|
334
|
-
return yield this.crypto.entities.encryptionKeysOf(entity);
|
|
335
|
-
});
|
|
370
|
+
return this.crypto.xapi.encryptionKeysOf({ entity, type: 'HealthElement' }, undefined);
|
|
336
371
|
}
|
|
337
372
|
subscribeToHealthElementEvents(eventTypes, filter, eventFired, options = {}) {
|
|
338
373
|
return __awaiter(this, void 0, void 0, function* () {
|
|
339
374
|
const currentUser = yield this.userApi.getCurrentUser();
|
|
340
|
-
return (0,
|
|
375
|
+
return (0, utils_1.subscribeToEntityEvents)(this.host, this.authApi, 'HealthElement', eventTypes, filter, eventFired, options, (encrypted) => __awaiter(this, void 0, void 0, function* () { return (yield this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(currentUser), [encrypted]))[0]; })).then((rs) => new Connection_1.ConnectionImpl(rs));
|
|
341
376
|
});
|
|
342
377
|
}
|
|
343
378
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icc-helement-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-helement-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import {IccAuthApi, IccHelementApi} from '../icc-api'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\n\nimport * as models from '../icc-api/model/models'\n\nimport * as _ from 'lodash'\nimport * as moment from 'moment'\nimport { FilterChainHealthElement, HealthElement, PaginatedListHealthElement } from '../icc-api/model/models'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { AuthenticationProvider, NoAuthenticationProvider } from './auth/AuthenticationProvider'\nimport { ShareMetadataBehaviour } from './crypto/ShareMetadataBehaviour'\nimport { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi'\nimport {EncryptedFieldsManifest, parseEncryptedFields, SubscriptionOptions} from './utils'\nimport {AbstractFilter} from \"./filters/filters\"\nimport {Connection, ConnectionImpl} from \"../icc-api/model/Connection\"\nimport {subscribeToEntityEvents} from \"./utils/websocket\"\nimport {IccUserXApi} from \"./icc-user-x-api\"\n\nexport class IccHelementXApi extends IccHelementApi implements EncryptedEntityXApi<models.HealthElement> {\n crypto: IccCryptoXApi\n dataOwnerApi: IccDataOwnerXApi\n private readonly userApi: IccUserXApi\n private readonly authApi: IccAuthApi\n private readonly encryptedFields: EncryptedFieldsManifest\n\n constructor(\n host: string,\n headers: { [key: string]: string },\n crypto: IccCryptoXApi,\n dataOwnerApi: IccDataOwnerXApi,\n userApi: IccUserXApi,\n authApi: IccAuthApi,\n encryptedKeys: Array<string> = ['descr', 'note'],\n authenticationProvider: AuthenticationProvider = new NoAuthenticationProvider(),\n fetchImpl: (input: RequestInfo, init?: RequestInit) => Promise<Response> = typeof window !== 'undefined'\n ? window.fetch\n : typeof self !== 'undefined'\n ? self.fetch\n : fetch\n ) {\n super(host, headers, authenticationProvider, fetchImpl)\n this.crypto = crypto\n this.dataOwnerApi = dataOwnerApi\n this.userApi = userApi\n this.authApi = authApi\n this.encryptedFields = parseEncryptedFields(encryptedKeys, 'HealthElement.')\n }\n\n /**\n * Creates a new instance of health element with initialised encryption metadata (not in the database).\n * @param user the current user.\n * @param patient the patient this health element refers to.\n * @param h initialised data for the health element. Metadata such as id, creation data, etc. will be automatically initialised, but you can specify\n * other kinds of data or overwrite generated metadata with this. You can't specify encryption metadata.\n * @param options optional parameters:\n * - additionalDelegates: delegates which will have access to the entity in addition to the current data owner and delegates from the\n * auto-delegations. Must be an object which associates each data owner id with the access level to give to that data owner. May overlap with\n * auto-delegations, in such case the access level specified here will be used. Currently only WRITE access is supported, but in future also read\n * access will be possible.\n * - preferredSfk: secret id of the patient to use as the secret foreign key to use for the classification. The default value will be a\n * secret id of patient known by the topmost parent in the current data owner hierarchy.\n * - confidential: if true, the entity will be created as confidential. Confidential entities are not shared with auto-delegations, and the default\n * foreign key used is any key that is not shared with any of the data owner parents. By default entities are created as non-confidential.\n * @return a new instance of health element.\n */\n async newInstance(\n user: models.User,\n patient: models.Patient,\n h: any,\n options: {\n additionalDelegates?: { [dataOwnerId: string]: 'WRITE' }\n preferredSfk?: string\n confidential?: boolean\n } = {}\n ) {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n const helement = {\n ...(h ?? {}),\n _type: 'org.taktik.icure.entities.HealthElement',\n id: h?.id ?? this.crypto.primitives.randomUuid(),\n created: h?.created ?? new Date().getTime(),\n modified: h?.modified ?? new Date().getTime(),\n responsible: h?.responsible ?? dataOwnerId,\n author: h?.author ?? user.id,\n codes: h?.codes ?? [],\n tags: h?.tags ?? [],\n healthElementId: h?.healthElementId ?? this.crypto.primitives.randomUuid(),\n openingDate: h?.openingDate ?? parseInt(moment().format('YYYYMMDDHHmmss')),\n }\n\n const ownerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n if (ownerId !== (await this.dataOwnerApi.getCurrentDataOwnerId())) throw new Error('Can only initialise entities as current data owner.')\n const sfk =\n options.preferredSfk ??\n (!!options.confidential\n ? await this.crypto.confidential.getConfidentialSecretId(patient)\n : await this.crypto.confidential.getAnySecretIdSharedWithParents(patient))\n if (!sfk) throw new Error(`Couldn't find any sfk of parent patient ${patient.id} for confidential=${!!options.confidential}`)\n const extraDelegations = [\n ...Object.keys(options.additionalDelegates ?? {}),\n ...(options.confidential ? [] : [...(user.autoDelegations?.all ?? []), ...(user.autoDelegations?.medicalInformation ?? [])]),\n ]\n const initialisationInfo = await this.crypto.entities.entityWithInitialisedEncryptedMetadata(helement, patient.id, sfk, true, extraDelegations)\n return new models.HealthElement(initialisationInfo.updatedEntity)\n }\n\n createHealthElement(body?: models.HealthElement): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n createHealthElementWithUser(user: models.User, body?: models.HealthElement): Promise<models.HealthElement | any> {\n return body\n ? this.encrypt(user, [_.cloneDeep(body)])\n .then((hes) => super.createHealthElement(hes[0]))\n .then((he) => this.decryptWithUser(user, [he]))\n .then((hes) => hes[0])\n : Promise.resolve(null)\n }\n\n createHealthElements(body?: Array<HealthElement>): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n createHealthElementsWithUser(user: models.User, bodies?: models.HealthElement[]): Promise<models.HealthElement[] | any> {\n return bodies\n ? this.encrypt(\n user,\n bodies.map((c) => _.cloneDeep(c))\n )\n .then((hes) => super.createHealthElements(hes))\n .then((hes) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes))\n : Promise.resolve(null)\n }\n\n getHealthElement(healthElementId: string): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n getHealthElementWithUser(user: models.User, healthElementId: string): Promise<models.HealthElement> {\n return super\n .getHealthElement(healthElementId)\n .then((he) => this.decryptWithUser(user, [he]))\n .then((hes) => hes[0])\n }\n\n getHealthElements(body?: models.ListOfIds): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n getHealthElementsWithUser(user: models.User, body?: models.ListOfIds): Promise<models.HealthElement[]> {\n return super.getHealthElements(body).then((hes) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes))\n }\n\n newHealthElementDelegations(healthElementId: string, body?: Array<models.Delegation>): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n newHealthElementDelegationsWithUser(user: models.User, healthElementId: string, body?: Array<models.Delegation>): Promise<models.HealthElement> {\n return super\n .newHealthElementDelegations(healthElementId, body)\n .then((he) => this.decryptWithUser(user, [he]))\n .then((he) => he[0])\n }\n\n findHealthElementsByHCPartyPatientForeignKeys(hcPartyId: string, secretFKeys: string): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n findHealthElementsByHCPartyPatientForeignKeysWithUser(user: models.User, hcPartyId: string, secretFKeys: string): Promise<HealthElement[]> {\n return super.findHealthElementsByHCPartyPatientForeignKeys(hcPartyId, secretFKeys).then((hes) => this.decryptWithUser(user, hes))\n }\n\n findHealthElementsByHCPartyPatientForeignKeysArrayWithUser(user: models.User, hcPartyId: string, secretFKeys: string[]): Promise<HealthElement[]> {\n return super.findHealthElementsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys).then((hes) => this.decryptWithUser(user, hes))\n }\n\n async findHealthElementsByHCPartyAndPatientWithUser(\n user: models.User,\n hcPartyId: string,\n patient: models.Patient,\n usingPost: boolean = false\n ): Promise<models.HealthElement[]> {\n let keysAndHcPartyId = await this.crypto.entities.secretIdsForHcpHierarchyOf(patient)\n const keys = keysAndHcPartyId.find((secretForeignKeys) => secretForeignKeys.ownerId == hcPartyId)?.extracted\n if (keys == undefined) {\n throw Error('No delegation for user')\n }\n return usingPost\n ? this.findHealthElementsByHCPartyPatientForeignKeysArrayWithUser(user, hcPartyId, keys)\n : this.findHealthElementsByHCPartyPatientForeignKeysWithUser(user, hcPartyId, keys.join(','))\n }\n\n modifyHealthElement(body?: HealthElement): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n modifyHealthElementWithUser(user: models.User, body?: HealthElement): Promise<HealthElement | any> {\n return body ? this.modifyAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : Promise.resolve(null)\n }\n private modifyAs(dataOwner: string, body: HealthElement): Promise<HealthElement | any> {\n return this.encryptAs(dataOwner, [_.cloneDeep(body)])\n .then((hes) => super.modifyHealthElement(hes[0]))\n .then((he) => this.decrypt(dataOwner, [he]))\n .then((hes) => hes[0])\n }\n\n modifyHealthElements(body?: Array<HealthElement>): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n modifyHealthElementsWithUser(user: models.User, bodies?: HealthElement[]): Promise<HealthElement[] | any> {\n return bodies\n ? this.encrypt(\n user,\n bodies.map((c) => _.cloneDeep(c))\n )\n .then((hes) => super.modifyHealthElements(hes))\n .then((hes) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes))\n : Promise.resolve(null)\n }\n\n // noinspection JSUnusedGlobalSymbols\n /**\n * 1. Check whether there is a delegation with 'hcpartyId' or not.\n * 2. 'fetchHcParty[hcpartyId][1]': is encrypted AES exchange key by RSA public key of him.\n * 3. Obtain the AES exchange key, by decrypting the previous step value with hcparty private key\n * 3.1. KeyPair should be fetch from cache (in jwk)\n * 3.2. if it doesn't exist in the cache, it has to be loaded from Browser Local store, and then import it to WebCrypto\n * 4. Obtain the array of delegations which are delegated to his ID (hcpartyId) in this patient\n * 5. Decrypt and collect all keys (secretForeignKeys) within delegations of previous step (with obtained AES key of step 4)\n * 6. Do the REST call to get all helements with (allSecretForeignKeysDelimitedByComa, hcpartyId)\n *\n * After these painful steps, you have the helements of the patient.\n *\n * @param hcpartyId\n * @param patient (Promise)\n * @param keepObsoleteVersions\n * @param usingPost\n */\n\n findBy(hcpartyId: string, patient: models.Patient, keepObsoleteVersions = false, usingPost = false) {\n return this.crypto.entities\n .secretIdsForHcpHierarchyOf(patient)\n .then((secretForeignKeys) =>\n secretForeignKeys && secretForeignKeys.length > 0\n ? Promise.all(\n secretForeignKeys\n .reduce((acc, level) => {\n return acc.concat([\n {\n hcpartyId: level.ownerId,\n extractedKeys: level.extracted.filter((key) => !acc.some((previousLevel) => previousLevel.extractedKeys.includes(key))),\n },\n ])\n }, [] as Array<{ hcpartyId: string; extractedKeys: Array<string> }>)\n .filter((l) => l.extractedKeys.length > 0)\n .map(({ hcpartyId, extractedKeys }) =>\n usingPost\n ? this.findByHCPartyPatientSecretFKeysArray(hcpartyId, _.uniq(extractedKeys))\n : this.findByHCPartyPatientSecretFKeys(hcpartyId, _.uniq(extractedKeys).join(','))\n )\n ).then((results) => _.uniqBy(_.flatMap(results), (x) => x.id))\n : Promise.resolve([])\n )\n .then((decryptedHelements: Array<models.HealthElement>) => {\n const byIds: { [key: string]: models.HealthElement } = {}\n\n if (keepObsoleteVersions) {\n return decryptedHelements\n } else {\n decryptedHelements.forEach((he) => {\n if (he.healthElementId) {\n const phe = byIds[he.healthElementId]\n if (!phe || !phe.modified || (he.modified && phe.modified < he.modified)) {\n byIds[he.healthElementId] = he\n }\n }\n })\n return _.values(byIds).filter((s: any) => !s.endOfLife)\n }\n })\n }\n\n findByHCPartyPatientSecretFKeys(hcPartyId: string, secretFKeys: string): Promise<Array<models.Contact> | any> {\n return super.findHealthElementsByHCPartyPatientForeignKeys(hcPartyId, secretFKeys).then((helements) => this.decrypt(hcPartyId, helements))\n }\n\n findByHCPartyPatientSecretFKeysArray(hcPartyId: string, secretFKeys: string[]): Promise<Array<models.Contact> | any> {\n return super\n .findHealthElementsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys)\n .then((helements) => this.decrypt(hcPartyId, helements))\n }\n\n encrypt(user: models.User, healthElements: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return this.encryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), healthElements)\n }\n\n private encryptAs(owner: string, healthElements: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return Promise.all(\n healthElements.map((he) =>\n this.crypto.entities.tryEncryptEntity(he, owner, this.encryptedFields, false, true, (x) => new models.HealthElement(x))\n )\n )\n }\n\n decryptWithUser(user: models.User, hes: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes)\n }\n\n decrypt(dataOwnerId: string, hes: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return Promise.all(\n hes.map((he) => this.crypto.entities.decryptEntity(he, dataOwnerId, (x) => new models.HealthElement(x)).then(({ entity }) => entity))\n )\n }\n\n filterHealthElementsBy(startDocumentId?: string, limit?: number, body?: FilterChainHealthElement): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n filterByWithUser(\n user: models.User,\n startDocumentId?: string,\n limit?: number,\n body?: FilterChainHealthElement\n ): Promise<PaginatedListHealthElement> {\n return super\n .filterHealthElementsBy(startDocumentId, limit, body)\n .then((pl) => this.decryptWithUser(user, pl.rows!).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n // noinspection JSUnusedGlobalSymbols\n serviceToHealthElement(user: models.User, patient: models.Patient, heSvc: models.Service, descr: string) {\n return this.newInstance(user, patient, {\n idService: heSvc.id,\n author: heSvc.author,\n responsible: heSvc.responsible,\n openingDate: heSvc.valueDate || heSvc.openingDate,\n descr: descr,\n idOpeningContact: heSvc.contactId,\n modified: heSvc.modified,\n created: heSvc.created,\n codes: heSvc.codes,\n tags: heSvc.tags,\n }).then((he) => {\n return this.createHealthElement(he)\n })\n }\n\n // noinspection JSUnusedGlobalSymbols, JSMethodCanBeStatic\n stringToCode(code: string) {\n const c = code.split('|')\n return new models.Code({\n type: c[0],\n code: c[1],\n version: c[2],\n id: code,\n })\n }\n\n /**\n * @param healthElement a health element\n * @return the id of the patient that the health element refers to, retrieved from the encrypted metadata. Normally there should only be one element\n * in the returned array, but in case of entity merges there could be multiple values.\n */\n async decryptPatientIdOf(healthElement: models.HealthElement): Promise<string[]> {\n return this.crypto.entities.owningEntityIdsOf(healthElement, undefined)\n }\n\n /**\n * Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param delegateId the id of the data owner which will be granted access to the health element.\n * @param healthElement the health element to share.\n * @param options optional parameters to customize the sharing behaviour:\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * health element does not have encrypted content.\n * - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * @return a promise which will contain the updated health element.\n */\n async shareWith(\n delegateId: string,\n healthElement: models.HealthElement,\n options: {\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n } = {}\n ): Promise<models.HealthElement> {\n return this.shareWithMany(healthElement, { [delegateId]: options })\n }\n /**\n * Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param healthElement the health element to share.\n * @param delegates sharing options for each delegate.\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * health element does not have encrypted content.\n * - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * @return a promise which will contain the updated health element.\n */\n async shareWithMany(\n healthElement: models.HealthElement,\n delegates: {\n [delegateId: string]: {\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<models.HealthElement> {\n const self = await this.dataOwnerApi.getCurrentDataOwnerId()\n const extended = await this.crypto.entities.entityWithAutoExtendedEncryptedMetadata(\n healthElement,\n true,\n Object.fromEntries(\n Object.entries(delegates).map(([delegateId, options]) => [\n delegateId,\n {\n shareEncryptionKey: options.shareEncryptionKey,\n shareOwningEntityIds: options.sharePatientId,\n },\n ])\n )\n )\n if (!!extended) {\n return await this.modifyAs(self, extended)\n } else return healthElement\n }\n\n async getDataOwnersWithAccessTo(\n entity: HealthElement\n ): Promise<{ permissionsByDataOwnerId: { [p: string]: 'WRITE' }; hasUnknownAnonymousDataOwners: boolean }> {\n return await this.crypto.entities.getDataOwnersWithAccessTo(entity)\n }\n\n async getEncryptionKeysOf(entity: HealthElement): Promise<string[]> {\n return await this.crypto.entities.encryptionKeysOf(entity)\n }\n\n async subscribeToHealthElementEvents(\n eventTypes: ('CREATE' | 'UPDATE' | 'DELETE')[],\n filter: AbstractFilter<HealthElement> | undefined,\n eventFired: (dataSample: HealthElement) => Promise<void>,\n options: SubscriptionOptions = {}\n ): Promise<Connection> {\n const currentUser = await this.userApi.getCurrentUser()\n\n return subscribeToEntityEvents(\n this.host,\n this.authApi,\n 'HealthElement',\n eventTypes,\n filter,\n eventFired,\n options,\n async (encrypted) => (await this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(currentUser), [encrypted]))[0]\n ).then((rs) => new ConnectionImpl(rs))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"icc-helement-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-helement-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccAuthApi, IccHelementApi } from '../icc-api'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\n\nimport * as models from '../icc-api/model/models'\n\nimport * as _ from 'lodash'\nimport * as moment from 'moment'\nimport { a2b, b2a, hex2ua, string2ua, ua2utf8, utf8_2ua } from './utils/binary-utils'\nimport { FilterChainHealthElement, HealthElement, PaginatedListHealthElement } from '../icc-api/model/models'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { AuthenticationProvider, NoAuthenticationProvider } from './auth/AuthenticationProvider'\nimport { SecureDelegation } from '../icc-api/model/SecureDelegation'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\nimport { ShareMetadataBehaviour } from './crypto/ShareMetadataBehaviour'\nimport { ShareResult } from './utils/ShareResult'\nimport { EntityShareRequest } from '../icc-api/model/requests/EntityShareRequest'\nimport RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum\nimport { XHR } from '../icc-api/api/XHR'\nimport { IccUserXApi } from './icc-user-x-api'\nimport { EncryptedFieldsManifest, parseEncryptedFields, subscribeToEntityEvents, SubscriptionOptions } from './utils'\nimport { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi'\nimport { AbstractFilter } from './filters/filters'\nimport { Connection, ConnectionImpl } from '../icc-api/model/Connection'\n\nexport class IccHelementXApi extends IccHelementApi implements EncryptedEntityXApi<models.HealthElement> {\n private readonly encryptedFields: EncryptedFieldsManifest\n\n get headers(): Promise<Array<XHR.Header>> {\n return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, 'HealthElement'))\n }\n\n constructor(\n host: string,\n headers: { [key: string]: string },\n private readonly crypto: IccCryptoXApi,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly userApi: IccUserXApi,\n private readonly authApi: IccAuthApi,\n encryptedKeys: Array<string> = ['descr', 'note'],\n authenticationProvider: AuthenticationProvider = new NoAuthenticationProvider(),\n fetchImpl: (input: RequestInfo, init?: RequestInit) => Promise<Response> = typeof window !== 'undefined'\n ? window.fetch\n : typeof self !== 'undefined'\n ? self.fetch\n : fetch\n ) {\n super(host, headers, authenticationProvider, fetchImpl)\n this.crypto = crypto\n this.dataOwnerApi = dataOwnerApi\n this.userApi = userApi\n this.authApi = authApi\n this.encryptedFields = parseEncryptedFields(encryptedKeys, 'HealthElement.')\n }\n\n /**\n * Creates a new instance of health element with initialised encryption metadata (not in the database).\n * @param user the current user.\n * @param patient the patient this health element refers to.\n * @param h initialised data for the health element. Metadata such as id, creation data, etc. will be automatically initialised, but you can specify\n * other kinds of data or overwrite generated metadata with this. You can't specify encryption metadata.\n * @param options optional parameters:\n * - additionalDelegates: delegates which will have access to the entity in addition to the current data owner and delegates from the\n * auto-delegations. Must be an object which associates each data owner id with the access level to give to that data owner. May overlap with\n * auto-delegations, in such case the access level specified here will be used.\n * - preferredSfk: secret id of the patient to use as the secret foreign key to use for the health element. The default value will be a\n * secret id of patient known by the topmost parent in the current data owner hierarchy if the confidential is set to false, else a secret id that\n * the data owner did not share with any of his parents.\n * - confidential: if true, the entity will be created as confidential. Confidential entities are not shared with auto-delegations, and the default\n * foreign key used is any key that is not shared with any of the data owner parents. By default entities are created as non-confidential.\n * @return a new instance of health element.\n */\n async newInstance(\n user: models.User,\n patient: models.Patient,\n h: any,\n options: {\n additionalDelegates?: { [dataOwnerId: string]: AccessLevelEnum }\n preferredSfk?: string\n confidential?: boolean\n } = {}\n ) {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n const helement = {\n ...(h ?? {}),\n _type: 'org.taktik.icure.entities.HealthElement',\n id: h?.id ?? this.crypto.primitives.randomUuid(),\n created: h?.created ?? new Date().getTime(),\n modified: h?.modified ?? new Date().getTime(),\n responsible: h?.responsible ?? dataOwnerId,\n author: h?.author ?? user.id,\n codes: h?.codes ?? [],\n tags: h?.tags ?? [],\n healthElementId: h?.healthElementId ?? this.crypto.primitives.randomUuid(),\n openingDate: h?.openingDate ?? parseInt(moment().format('YYYYMMDDHHmmss')),\n }\n\n const ownerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n if (ownerId !== (await this.dataOwnerApi.getCurrentDataOwnerId())) throw new Error('Can only initialise entities as current data owner.')\n const sfk =\n options.preferredSfk ??\n (options?.confidential\n ? await this.crypto.confidential.getConfidentialSecretId({ entity: patient, type: 'Patient' })\n : await this.crypto.confidential.getAnySecretIdSharedWithParents({ entity: patient, type: 'Patient' }))\n if (!sfk) throw new Error(`Couldn't find any sfk of parent patient ${patient.id} for confidential=${options?.confidential ?? false}`)\n const extraDelegations = {\n ...(options.confidential\n ? {}\n : Object.fromEntries(\n [...(user.autoDelegations?.all ?? []), ...(user.autoDelegations?.medicalInformation ?? [])].map((d) => [d, AccessLevelEnum.WRITE])\n )),\n ...(options?.additionalDelegates ?? {}),\n }\n const initialisationInfo = await this.crypto.xapi.entityWithInitialisedEncryptedMetadata(\n helement,\n 'HealthElement',\n patient.id,\n sfk,\n true,\n false,\n extraDelegations\n )\n return new models.HealthElement(initialisationInfo.updatedEntity)\n }\n\n createHealthElement(body?: models.HealthElement): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n createHealthElementWithUser(user: models.User, body?: models.HealthElement): Promise<models.HealthElement | any> {\n return body\n ? this.encrypt(user, [_.cloneDeep(body)])\n .then((hes) => super.createHealthElement(hes[0]))\n .then((he) => this.decryptWithUser(user, [he]))\n .then((hes) => hes[0])\n : Promise.resolve(null)\n }\n\n createHealthElements(body?: Array<HealthElement>): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n createHealthElementsWithUser(user: models.User, bodies?: models.HealthElement[]): Promise<models.HealthElement[] | any> {\n return bodies\n ? this.encrypt(\n user,\n bodies.map((c) => _.cloneDeep(c))\n )\n .then((hes) => super.createHealthElements(hes))\n .then((hes) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes))\n : Promise.resolve(null)\n }\n\n getHealthElement(healthElementId: string): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n getHealthElementWithUser(user: models.User, healthElementId: string): Promise<models.HealthElement> {\n return super\n .getHealthElement(healthElementId)\n .then((he) => this.decryptWithUser(user, [he]))\n .then((hes) => hes[0])\n }\n\n getHealthElements(body?: models.ListOfIds): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n getHealthElementsWithUser(user: models.User, body?: models.ListOfIds): Promise<models.HealthElement[]> {\n return super.getHealthElements(body).then((hes) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes))\n }\n\n newHealthElementDelegations(healthElementId: string, body?: Array<models.Delegation>): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n newHealthElementDelegationsWithUser(user: models.User, healthElementId: string, body?: Array<models.Delegation>): Promise<models.HealthElement> {\n return super\n .newHealthElementDelegations(healthElementId, body)\n .then((he) => this.decryptWithUser(user, [he]))\n .then((he) => he[0])\n }\n\n findHealthElementsByHCPartyPatientForeignKeys(hcPartyId: string, secretFKeys: string): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n findHealthElementsByHCPartyPatientForeignKeysWithUser(user: models.User, hcPartyId: string, secretFKeys: string): Promise<HealthElement[]> {\n return super.findHealthElementsByHCPartyPatientForeignKeys(hcPartyId, secretFKeys).then((hes) => this.decryptWithUser(user, hes))\n }\n\n findHealthElementsByHCPartyPatientForeignKeysArrayWithUser(user: models.User, hcPartyId: string, secretFKeys: string[]): Promise<HealthElement[]> {\n return super.findHealthElementsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys).then((hes) => this.decryptWithUser(user, hes))\n }\n\n async findHealthElementsByHCPartyAndPatientWithUser(\n user: models.User,\n hcPartyId: string,\n patient: models.Patient,\n usingPost: boolean = false\n ): Promise<models.HealthElement[]> {\n let keysAndHcPartyId = await this.crypto.xapi.secretIdsForHcpHierarchyOf({ entity: patient, type: 'Patient' })\n const keys = keysAndHcPartyId.find((secretForeignKeys) => secretForeignKeys.ownerId == hcPartyId)?.extracted\n if (keys == undefined) {\n throw Error('No delegation for user')\n }\n return usingPost\n ? this.findHealthElementsByHCPartyPatientForeignKeysArrayWithUser(user, hcPartyId, keys)\n : this.findHealthElementsByHCPartyPatientForeignKeysWithUser(user, hcPartyId, keys.join(','))\n }\n\n modifyHealthElement(body?: HealthElement): never {\n throw new Error('Cannot call a method that returns health element without providing a user for de/encryption')\n }\n\n modifyHealthElementWithUser(user: models.User, body?: HealthElement): Promise<HealthElement | any> {\n return body ? this.modifyHealthElementAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : Promise.resolve(null)\n }\n private modifyHealthElementAs(dataOwner: string, body: HealthElement): Promise<HealthElement> {\n return this.encryptAs(dataOwner, [_.cloneDeep(body)])\n .then((hes) => super.modifyHealthElement(hes[0]))\n .then((he) => this.decrypt(dataOwner, [he]))\n .then((hes) => hes[0])\n }\n\n modifyHealthElements(body?: Array<HealthElement>): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n modifyHealthElementsWithUser(user: models.User, bodies?: HealthElement[]): Promise<HealthElement[] | any> {\n return bodies\n ? this.encrypt(\n user,\n bodies.map((c) => _.cloneDeep(c))\n )\n .then((hes) => super.modifyHealthElements(hes))\n .then((hes) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes))\n : Promise.resolve(null)\n }\n\n // noinspection JSUnusedGlobalSymbols\n /**\n * 1. Check whether there is a delegation with 'hcpartyId' or not.\n * 2. 'fetchHcParty[hcpartyId][1]': is encrypted AES exchange key by RSA public key of him.\n * 3. Obtain the AES exchange key, by decrypting the previous step value with hcparty private key\n * 3.1. KeyPair should be fetch from cache (in jwk)\n * 3.2. if it doesn't exist in the cache, it has to be loaded from Browser Local store, and then import it to WebCrypto\n * 4. Obtain the array of delegations which are delegated to his ID (hcpartyId) in this patient\n * 5. Decrypt and collect all keys (secretForeignKeys) within delegations of previous step (with obtained AES key of step 4)\n * 6. Do the REST call to get all helements with (allSecretForeignKeysDelimitedByComa, hcpartyId)\n *\n * After these painful steps, you have the helements of the patient.\n *\n * @param hcpartyId\n * @param patient (Promise)\n * @param keepObsoleteVersions\n * @param usingPost\n */\n\n findBy(hcpartyId: string, patient: models.Patient, keepObsoleteVersions = false, usingPost = false) {\n return this.crypto.xapi\n .secretIdsForHcpHierarchyOf({ entity: patient, type: 'Patient' })\n .then((secretForeignKeys) =>\n secretForeignKeys && secretForeignKeys.length > 0\n ? Promise.all(\n secretForeignKeys\n .reduce((acc, level) => {\n return acc.concat([\n {\n hcpartyId: level.ownerId,\n extractedKeys: level.extracted.filter((key) => !acc.some((previousLevel) => previousLevel.extractedKeys.includes(key))),\n },\n ])\n }, [] as Array<{ hcpartyId: string; extractedKeys: Array<string> }>)\n .filter((l) => l.extractedKeys.length > 0)\n .map(({ hcpartyId, extractedKeys }) =>\n usingPost\n ? this.findByHCPartyPatientSecretFKeysArray(hcpartyId, _.uniq(extractedKeys))\n : this.findByHCPartyPatientSecretFKeys(hcpartyId, _.uniq(extractedKeys).join(','))\n )\n ).then((results) => _.uniqBy(_.flatMap(results), (x) => x.id))\n : Promise.resolve([])\n )\n .then((decryptedHelements: Array<models.HealthElement>) => {\n const byIds: { [key: string]: models.HealthElement } = {}\n\n if (keepObsoleteVersions) {\n return decryptedHelements\n } else {\n decryptedHelements.forEach((he) => {\n if (he.healthElementId) {\n const phe = byIds[he.healthElementId]\n if (!phe || !phe.modified || (he.modified && phe.modified < he.modified)) {\n byIds[he.healthElementId] = he\n }\n }\n })\n return _.values(byIds).filter((s: any) => !s.endOfLife)\n }\n })\n }\n\n findByHCPartyPatientSecretFKeys(hcPartyId: string, secretFKeys: string): Promise<Array<models.Contact> | any> {\n return super.findHealthElementsByHCPartyPatientForeignKeys(hcPartyId, secretFKeys).then((helements) => this.decrypt(hcPartyId, helements))\n }\n\n findByHCPartyPatientSecretFKeysArray(hcPartyId: string, secretFKeys: string[]): Promise<Array<models.Contact> | any> {\n return super\n .findHealthElementsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys)\n .then((helements) => this.decrypt(hcPartyId, helements))\n }\n\n encrypt(user: models.User, healthElements: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return this.encryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), healthElements)\n }\n\n private encryptAs(owner: string, healthElements: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return Promise.all(\n healthElements.map((he) =>\n this.crypto.xapi.tryEncryptEntity(he, 'HealthElement', this.encryptedFields, false, false, (x) => new models.HealthElement(x))\n )\n )\n }\n\n decryptWithUser(user: models.User, hes: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), hes)\n }\n\n decrypt(dataOwnerId: string, hes: Array<models.HealthElement>): Promise<Array<models.HealthElement>> {\n return Promise.all(\n hes.map((he) => this.crypto.xapi.decryptEntity(he, 'HealthElement', (x) => new models.HealthElement(x)).then(({ entity }) => entity))\n )\n }\n\n filterHealthElementsBy(startDocumentId?: string, limit?: number, body?: FilterChainHealthElement): never {\n throw new Error('Cannot call a method that returns health elements without providing a user for de/encryption')\n }\n\n filterByWithUser(\n user: models.User,\n startDocumentId?: string,\n limit?: number,\n body?: FilterChainHealthElement\n ): Promise<PaginatedListHealthElement> {\n return super\n .filterHealthElementsBy(startDocumentId, limit, body)\n .then((pl) => this.decryptWithUser(user, pl.rows!).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n // noinspection JSUnusedGlobalSymbols\n serviceToHealthElement(user: models.User, patient: models.Patient, heSvc: models.Service, descr: string) {\n return this.newInstance(user, patient, {\n idService: heSvc.id,\n author: heSvc.author,\n responsible: heSvc.responsible,\n openingDate: heSvc.valueDate || heSvc.openingDate,\n descr: descr,\n idOpeningContact: heSvc.contactId,\n modified: heSvc.modified,\n created: heSvc.created,\n codes: heSvc.codes,\n tags: heSvc.tags,\n }).then((he) => {\n return this.createHealthElement(he)\n })\n }\n\n // noinspection JSUnusedGlobalSymbols, JSMethodCanBeStatic\n stringToCode(code: string) {\n const c = code.split('|')\n return new models.Code({\n type: c[0],\n code: c[1],\n version: c[2],\n id: code,\n })\n }\n\n /**\n * @param healthElement a health element\n * @return the id of the patient that the health element refers to, retrieved from the encrypted metadata. Normally there should only be one element\n * in the returned array, but in case of entity merges there could be multiple values.\n */\n async decryptPatientIdOf(healthElement: models.HealthElement): Promise<string[]> {\n return this.crypto.xapi.owningEntityIdsOf({ entity: healthElement, type: 'HealthElement' }, undefined)\n }\n\n /**\n * @return if the logged data owner has write access to the content of the given health element\n */\n async hasWriteAccess(healthElement: models.HealthElement): Promise<boolean> {\n return this.crypto.xapi.hasWriteAccess({ entity: healthElement, type: 'HealthElement' })\n }\n\n /**\n * Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param delegateId the id of the data owner which will be granted access to the health element.\n * @param healthElement the health element to share.\n * @param options optional parameters to customize the sharing behaviour:\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * health element does not have encrypted content.\n * - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return the updated entity\n */\n async shareWith(\n delegateId: string,\n healthElement: models.HealthElement,\n options: {\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n } = {}\n ): Promise<models.HealthElement> {\n return this.shareWithMany(healthElement, { [delegateId]: options })\n }\n /**\n * Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param delegateId the id of the data owner which will be granted access to the health element.\n * @param healthElement the health element to share.\n * @param delegates associates the id of data owners which will be granted access to the entity, to the following sharing options:\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * health element does not have encrypted content.\n * - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return the updated entity\n */\n async shareWithMany(\n healthElement: models.HealthElement,\n delegates: {\n [delegateId: string]: {\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<models.HealthElement> {\n return (await this.tryShareWithMany(healthElement, delegates)).updatedEntityOrThrow\n }\n /**\n * Share an existing health element with other data owners, allowing them to access the non-encrypted data of the health element and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param healthElement the health element to share.\n * @param delegates associates the id of data owners which will be granted access to the entity, to the following sharing options:\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * health element does not have encrypted content.\n * - sharePatientId: specifies if the id of the patient that this health element refers to should be shared with the delegate (defaults to\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return a promise which will contain the result of the operation: the updated entity if the operation was successful or details of the error if\n * the operation failed.\n */\n async tryShareWithMany(\n healthElement: models.HealthElement,\n delegates: {\n [delegateId: string]: {\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<ShareResult<models.HealthElement>> {\n const self = await this.dataOwnerApi.getCurrentDataOwnerId()\n // All entities should have an encryption key.\n const entityWithEncryptionKey = await this.crypto.xapi.ensureEncryptionKeysInitialised(healthElement, 'HealthElement')\n const updatedEntity = entityWithEncryptionKey ? await this.modifyHealthElementAs(self, entityWithEncryptionKey) : healthElement\n return this.crypto.xapi\n .simpleShareOrUpdateEncryptedEntityMetadata(\n { entity: updatedEntity, type: 'HealthElement' },\n true,\n Object.fromEntries(\n Object.entries(delegates).map(([delegateId, options]) => [\n delegateId,\n {\n requestedPermissions: options.requestedPermissions,\n shareEncryptionKeys: options.shareEncryptionKey,\n shareOwningEntityIds: options.sharePatientId,\n shareSecretIds: undefined,\n },\n ])\n ),\n (x) => this.bulkShareHealthElements(x)\n )\n .then((r) => r.mapSuccessAsync((e) => this.decrypt(self, [e]).then((es) => es[0])))\n }\n\n getDataOwnersWithAccessTo(\n entity: models.HealthElement\n ): Promise<{ permissionsByDataOwnerId: { [p: string]: AccessLevelEnum }; hasUnknownAnonymousDataOwners: boolean }> {\n return this.crypto.xapi.getDataOwnersWithAccessTo({ entity, type: 'HealthElement' })\n }\n\n getEncryptionKeysOf(entity: models.HealthElement): Promise<string[]> {\n return this.crypto.xapi.encryptionKeysOf({ entity, type: 'HealthElement' }, undefined)\n }\n\n async subscribeToHealthElementEvents(\n eventTypes: ('CREATE' | 'UPDATE' | 'DELETE')[],\n filter: AbstractFilter<HealthElement> | undefined,\n eventFired: (dataSample: HealthElement) => Promise<void>,\n options: SubscriptionOptions = {}\n ): Promise<Connection> {\n const currentUser = await this.userApi.getCurrentUser()\n\n return subscribeToEntityEvents(\n this.host,\n this.authApi,\n 'HealthElement',\n eventTypes,\n filter,\n eventFired,\n options,\n async (encrypted) => (await this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(currentUser), [encrypted]))[0]\n ).then((rs) => new ConnectionImpl(rs))\n }\n}\n"]}
|
|
@@ -4,6 +4,8 @@ import { IccCryptoXApi } from './icc-crypto-x-api';
|
|
|
4
4
|
import { KeyPairUpdateRequest } from './maintenance/KeyPairUpdateRequest';
|
|
5
5
|
import { IccDataOwnerXApi } from './icc-data-owner-x-api';
|
|
6
6
|
import { User } from '../icc-api/model/User';
|
|
7
|
+
import { IccExchangeDataApi } from '../icc-api/api/IccExchangeDataApi';
|
|
8
|
+
import { DataOwnerTypeEnum } from '../icc-api/model/DataOwnerTypeEnum';
|
|
7
9
|
/**
|
|
8
10
|
* Api for interpreting maintenance tasks and applying required client-side actions.
|
|
9
11
|
*/
|
|
@@ -11,7 +13,8 @@ export declare class IccIcureMaintenanceXApi {
|
|
|
11
13
|
private readonly crypto;
|
|
12
14
|
private readonly tasksApi;
|
|
13
15
|
private readonly dataOwnerApi;
|
|
14
|
-
|
|
16
|
+
private readonly exchangeDataApi;
|
|
17
|
+
constructor(crypto: IccCryptoXApi, tasksApi: IccMaintenanceTaskXApi, dataOwnerApi: IccDataOwnerXApi, exchangeDataApi: IccExchangeDataApi);
|
|
15
18
|
/**
|
|
16
19
|
* Applies a key pair update request between another data owner and the current data owner to allow the other data owner to access existing exchange
|
|
17
20
|
* keys shared with the current data owner. IMPORTANT: it is your responsibility to verify the authenticity of the public key / update request
|
|
@@ -24,8 +27,10 @@ export declare class IccIcureMaintenanceXApi {
|
|
|
24
27
|
* Creates the necessary maintenance tasks to request access to existing exchange keys with the new key pair for the current user.
|
|
25
28
|
* @param user the user which owns the new key pair.
|
|
26
29
|
* @param keypair a new key pair for the current user.
|
|
30
|
+
* @param requestToOwnerTypes specifies the types of data owner that have shared data with the current data owner or which were given access to data
|
|
31
|
+
* from the current data owner will receive a 'give access back' request. If not specified, the value be inferred from the current data owner type.
|
|
27
32
|
*/
|
|
28
|
-
createMaintenanceTasksForNewKeypair(user: User, keypair: KeyPair<CryptoKey
|
|
33
|
+
createMaintenanceTasksForNewKeypair(user: User, keypair: KeyPair<CryptoKey>, requestToOwnerTypes?: DataOwnerTypeEnum[]): Promise<void>;
|
|
29
34
|
private getExchangeKeysInfosOf;
|
|
30
35
|
private createMaintenanceTask;
|
|
31
36
|
}
|
|
@@ -16,15 +16,18 @@ const PropertyStub_1 = require("../icc-api/model/PropertyStub");
|
|
|
16
16
|
const PropertyTypeStub_1 = require("../icc-api/model/PropertyTypeStub");
|
|
17
17
|
const TypedValueObject_1 = require("../icc-api/model/TypedValueObject");
|
|
18
18
|
const KeyPairUpdateRequest_1 = require("./maintenance/KeyPairUpdateRequest");
|
|
19
|
+
const SecureDelegation_1 = require("../icc-api/model/SecureDelegation");
|
|
19
20
|
const DataOwnerTypeEnum_1 = require("../icc-api/model/DataOwnerTypeEnum");
|
|
21
|
+
var AccessLevelEnum = SecureDelegation_1.SecureDelegation.AccessLevelEnum;
|
|
20
22
|
/**
|
|
21
23
|
* Api for interpreting maintenance tasks and applying required client-side actions.
|
|
22
24
|
*/
|
|
23
25
|
class IccIcureMaintenanceXApi {
|
|
24
|
-
constructor(crypto, tasksApi, dataOwnerApi) {
|
|
26
|
+
constructor(crypto, tasksApi, dataOwnerApi, exchangeDataApi) {
|
|
25
27
|
this.crypto = crypto;
|
|
26
28
|
this.tasksApi = tasksApi;
|
|
27
29
|
this.dataOwnerApi = dataOwnerApi;
|
|
30
|
+
this.exchangeDataApi = exchangeDataApi;
|
|
28
31
|
}
|
|
29
32
|
// TODO api to get all tasks for current owner from owner with id
|
|
30
33
|
/**
|
|
@@ -36,6 +39,7 @@ class IccIcureMaintenanceXApi {
|
|
|
36
39
|
applyKeyPairUpdate(update) {
|
|
37
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
41
|
yield this.crypto.exchangeKeys.base.giveAccessBackTo(update.concernedDataOwnerId, update.newPublicKey, this.crypto.userKeysManager.getDecryptionKeys());
|
|
42
|
+
yield this.crypto.exchangeData.giveAccessBackTo(update.concernedDataOwnerId, update.newPublicKey);
|
|
39
43
|
});
|
|
40
44
|
}
|
|
41
45
|
/**
|
|
@@ -43,39 +47,46 @@ class IccIcureMaintenanceXApi {
|
|
|
43
47
|
* Creates the necessary maintenance tasks to request access to existing exchange keys with the new key pair for the current user.
|
|
44
48
|
* @param user the user which owns the new key pair.
|
|
45
49
|
* @param keypair a new key pair for the current user.
|
|
50
|
+
* @param requestToOwnerTypes specifies the types of data owner that have shared data with the current data owner or which were given access to data
|
|
51
|
+
* from the current data owner will receive a 'give access back' request. If not specified, the value be inferred from the current data owner type.
|
|
46
52
|
*/
|
|
47
|
-
createMaintenanceTasksForNewKeypair(user, keypair) {
|
|
53
|
+
createMaintenanceTasksForNewKeypair(user, keypair, requestToOwnerTypes) {
|
|
48
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
55
|
const currentUserType = yield this.dataOwnerApi.getCurrentDataOwnerType();
|
|
50
|
-
if (
|
|
51
|
-
|
|
56
|
+
if (!requestToOwnerTypes) {
|
|
57
|
+
if (currentUserType === 'device') {
|
|
58
|
+
console.warn('Current data owner is a device and there is no need to create maintenance tasks for updated keypair.');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
requestToOwnerTypes =
|
|
63
|
+
currentUserType === DataOwnerTypeEnum_1.DataOwnerTypeEnum.Patient ? [DataOwnerTypeEnum_1.DataOwnerTypeEnum.Patient, DataOwnerTypeEnum_1.DataOwnerTypeEnum.Hcp] : [DataOwnerTypeEnum_1.DataOwnerTypeEnum.Hcp];
|
|
64
|
+
}
|
|
52
65
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
const hexNewPubKey = (0, utils_1.ua2hex)(yield this.crypto.primitives.RSA.exportKey(keypair.publicKey, 'spki'));
|
|
67
|
+
const hexNewPubKeyFp = hexNewPubKey.slice(-32);
|
|
68
|
+
const selfId = yield this.dataOwnerApi.getCurrentDataOwnerId();
|
|
69
|
+
const requestDataOwnersForExchangeKeys = (yield this.getExchangeKeysInfosOf(selfId, requestToOwnerTypes))
|
|
70
|
+
.filter((info) => !info.fingerprints.has(hexNewPubKeyFp))
|
|
71
|
+
.flatMap((info) => [info.delegate, info.delegator])
|
|
72
|
+
.filter((dataOwner) => dataOwner !== selfId);
|
|
73
|
+
const requestDataOwnersForExchangeData = yield this.exchangeDataApi.getExchangeDataParticipantCounterparts(selfId, [...new Set(requestToOwnerTypes)].join(','));
|
|
74
|
+
const requestDataOwners = [...new Set([...requestDataOwnersForExchangeKeys, ...requestDataOwnersForExchangeData])];
|
|
75
|
+
if (requestDataOwners.length > 0) {
|
|
76
|
+
const tasksToCreate = requestDataOwners.map((dataOwner) => ({
|
|
77
|
+
delegate: dataOwner,
|
|
78
|
+
task: this.createMaintenanceTask(selfId, hexNewPubKey),
|
|
79
|
+
}));
|
|
80
|
+
for (const taskToCreate of tasksToCreate) {
|
|
81
|
+
const instance = yield this.tasksApi.newInstance(user, taskToCreate.task, {
|
|
82
|
+
additionalDelegates: { [taskToCreate.delegate]: AccessLevelEnum.WRITE },
|
|
83
|
+
});
|
|
84
|
+
if (instance) {
|
|
85
|
+
// TODO create in bulk
|
|
86
|
+
yield this.tasksApi.createMaintenanceTaskWithUser(user, instance);
|
|
74
87
|
}
|
|
75
88
|
}
|
|
76
89
|
}
|
|
77
|
-
else
|
|
78
|
-
throw new Error(`Unknown data owner type for current user ${currentUserType}`);
|
|
79
90
|
});
|
|
80
91
|
}
|
|
81
92
|
getExchangeKeysInfosOf(dataOwnerId, otherOwnerTypes) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icc-icure-maintenance-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-icure-maintenance-x-api.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,sEAAkE;AAClE,mCAAgC;AAChC,gEAA4D;AAC5D,wEAAoE;AACpE,wEAAoE;AAEpE,6EAAyE;AAGzE,0EAAsE;AAItE;;GAEG;AACH,MAAa,uBAAuB;IAKlC,YAAY,MAAqB,EAAE,QAAgC,EAAE,YAA8B;QACjG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAED,iEAAiE;IAEjE;;;;;OAKG;IACG,kBAAkB,CAAC,MAA4B;;YACnD,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAClD,MAAM,CAAC,oBAAoB,EAC3B,MAAM,CAAC,YAAY,EACnB,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAChD,CAAA;QACH,CAAC;KAAA;IAED;;;;;OAKG;IACG,mCAAmC,CAAC,IAAU,EAAE,OAA2B;;YAC/E,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,uBAAuB,EAAE,CAAA;YACzE,IAAI,eAAe,KAAK,qCAAiB,CAAC,MAAM,EAAE;gBAChD,OAAO,CAAC,IAAI,CAAC,sGAAsG,CAAC,CAAA;aACrH;iBAAM,IAAI,eAAe,KAAK,qCAAiB,CAAC,OAAO,IAAI,eAAe,KAAK,qCAAiB,CAAC,GAAG,EAAE;gBACrG,MAAM,oBAAoB,GACxB,eAAe,KAAK,qCAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,qCAAiB,CAAC,OAAO,EAAE,qCAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,qCAAiB,CAAC,GAAG,CAAC,CAAA;gBAC9H,MAAM,YAAY,GAAG,IAAA,cAAM,EAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;gBAClG,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;gBAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,CAAA;gBAC9D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;gBAChF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAC/B,QAAQ;qBACL,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;qBACxD,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;qBAClD,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,CAC/C,CAAA;gBACD,IAAI,iBAAiB,CAAC,IAAI,GAAG,CAAC,EAAE;oBAC9B,MAAM,aAAa,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;wBAC/D,QAAQ,EAAE,SAAS;wBACnB,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,YAAY,CAAC;qBACvD,CAAC,CAAC,CAAA;oBACH,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE;wBACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,EAAE,mBAAmB,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;wBACxI,IAAI,QAAQ,EAAE;4BACZ,sBAAsB;4BACtB,MAAM,IAAI,CAAC,QAAQ,CAAC,6BAA6B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;yBAClE;qBACF;iBACF;aACF;;gBAAM,MAAM,IAAI,KAAK,CAAC,4CAA4C,eAAe,EAAE,CAAC,CAAA;QACvF,CAAC;KAAA;IAEa,sBAAsB,CAAC,WAAmB,EAAE,eAAoC;;YAC5F,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;YAChH,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,CACtG,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;gBACvD,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,WAAW;gBACrB,YAAY,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aAC3E,CAAC,CAAC,CACJ,CAAA;YACD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,EAAE,CACzF,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrE,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,UAAU;gBACpB,YAAY,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aAC3E,CAAC,CAAC,CACJ,CAAA;YACD,OAAO,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAA;QACjC,CAAC;KAAA;IAEO,qBAAqB,CAAC,OAAe,EAAE,eAAuB;QACpE,OAAO,IAAI,iCAAe,CAAC;YACzB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE;YACvC,QAAQ,EAAE,2CAAoB,CAAC,SAAS;YACxC,MAAM,EAAE,iCAAe,CAAC,UAAU,CAAC,OAAO;YAC1C,UAAU,EAAE;gBACV,IAAI,2BAAY,CAAC;oBACf,EAAE,EAAE,2CAAoB,CAAC,gBAAgB;oBACzC,IAAI,EAAE,IAAI,mCAAgB,CAAC,EAAE,IAAI,EAAE,mCAAgB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACtE,UAAU,EAAE,IAAI,mCAAgB,CAAC;wBAC/B,IAAI,EAAE,mCAAgB,CAAC,QAAQ,CAAC,MAAM;wBACtC,WAAW,EAAE,OAAO;qBACrB,CAAC;iBACH,CAAC;gBACF,IAAI,2BAAY,CAAC;oBACf,EAAE,EAAE,2CAAoB,CAAC,iBAAiB;oBAC1C,IAAI,EAAE,IAAI,mCAAgB,CAAC,EAAE,IAAI,EAAE,mCAAgB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACtE,UAAU,EAAE,IAAI,mCAAgB,CAAC;wBAC/B,IAAI,EAAE,mCAAgB,CAAC,QAAQ,CAAC,MAAM;wBACtC,WAAW,EAAE,eAAe;qBAC7B,CAAC;iBACH,CAAC;aACH;SACF,CAAC,CAAA;IACJ,CAAC;CACF;AA9GD,0DA8GC","sourcesContent":["import { KeyPair } from './crypto/RSA'\nimport { IccMaintenanceTaskXApi } from './icc-maintenance-task-x-api'\nimport { MaintenanceTask } from '../icc-api/model/MaintenanceTask'\nimport { ua2hex } from './utils'\nimport { PropertyStub } from '../icc-api/model/PropertyStub'\nimport { PropertyTypeStub } from '../icc-api/model/PropertyTypeStub'\nimport { TypedValueObject } from '../icc-api/model/TypedValueObject'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\nimport { KeyPairUpdateRequest } from './maintenance/KeyPairUpdateRequest'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { User } from '../icc-api/model/User'\nimport { DataOwnerTypeEnum } from '../icc-api/model/DataOwnerTypeEnum'\n\ntype ExchangeKeyInfo = { delegator: string; delegate: string; fingerprints: Set<string> }\n\n/**\n * Api for interpreting maintenance tasks and applying required client-side actions.\n */\nexport class IccIcureMaintenanceXApi {\n private readonly crypto: IccCryptoXApi\n private readonly tasksApi: IccMaintenanceTaskXApi\n private readonly dataOwnerApi: IccDataOwnerXApi\n\n constructor(crypto: IccCryptoXApi, tasksApi: IccMaintenanceTaskXApi, dataOwnerApi: IccDataOwnerXApi) {\n this.crypto = crypto\n this.tasksApi = tasksApi\n this.dataOwnerApi = dataOwnerApi\n }\n\n // TODO api to get all tasks for current owner from owner with id\n\n /**\n * Applies a key pair update request between another data owner and the current data owner to allow the other data owner to access existing exchange\n * keys shared with the current data owner. IMPORTANT: it is your responsibility to verify the authenticity of the public key / update request\n * before calling this method: this method assumes the new public key for the concerned data owner is authentic.\n * @param update a keypair update request to the current data owner.\n */\n async applyKeyPairUpdate(update: KeyPairUpdateRequest) {\n await this.crypto.exchangeKeys.base.giveAccessBackTo(\n update.concernedDataOwnerId,\n update.newPublicKey,\n this.crypto.userKeysManager.getDecryptionKeys()\n )\n }\n\n /**\n * @internal This method is intended only for internal use and may be changed without notice.\n * Creates the necessary maintenance tasks to request access to existing exchange keys with the new key pair for the current user.\n * @param user the user which owns the new key pair.\n * @param keypair a new key pair for the current user.\n */\n async createMaintenanceTasksForNewKeypair(user: User, keypair: KeyPair<CryptoKey>): Promise<void> {\n const currentUserType = await this.dataOwnerApi.getCurrentDataOwnerType()\n if (currentUserType === DataOwnerTypeEnum.Device) {\n console.warn('Current data owner is a device and there is no need to create maintenance tasks for updated keypair.')\n } else if (currentUserType === DataOwnerTypeEnum.Patient || currentUserType === DataOwnerTypeEnum.Hcp) {\n const requestsToOwnerTypes =\n currentUserType === DataOwnerTypeEnum.Patient ? [DataOwnerTypeEnum.Patient, DataOwnerTypeEnum.Hcp] : [DataOwnerTypeEnum.Hcp]\n const hexNewPubKey = ua2hex(await this.crypto.primitives.RSA.exportKey(keypair.publicKey, 'spki'))\n const hexNewPubKeyFp = hexNewPubKey.slice(-32)\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const keysInfo = await this.getExchangeKeysInfosOf(selfId, requestsToOwnerTypes)\n const requestDataOwners = new Set(\n keysInfo\n .filter((info) => !info.fingerprints.has(hexNewPubKeyFp))\n .flatMap((info) => [info.delegate, info.delegator])\n .filter((dataOwner) => dataOwner !== selfId)\n )\n if (requestDataOwners.size > 0) {\n const tasksToCreate = [...requestDataOwners].map((dataOwner) => ({\n delegate: dataOwner,\n task: this.createMaintenanceTask(selfId, hexNewPubKey),\n }))\n for (const taskToCreate of tasksToCreate) {\n const instance = await this.tasksApi.newInstance(user, taskToCreate.task, { additionalDelegates: { [taskToCreate.delegate]: 'WRITE' } })\n if (instance) {\n // TODO create in bulk\n await this.tasksApi.createMaintenanceTaskWithUser(user, instance)\n }\n }\n }\n } else throw new Error(`Unknown data owner type for current user ${currentUserType}`)\n }\n\n private async getExchangeKeysInfosOf(dataOwnerId: string, otherOwnerTypes: DataOwnerTypeEnum[]): Promise<ExchangeKeyInfo[]> {\n const allExchangeKeys = await this.crypto.exchangeKeys.base.getAllExchangeKeysWith(dataOwnerId, otherOwnerTypes)\n const infoTo = Object.entries(allExchangeKeys.keysToOwner).flatMap(([delegatorId, delegatorFpToKeys]) =>\n Object.values(delegatorFpToKeys).map((encryptedKeys) => ({\n delegator: delegatorId,\n delegate: dataOwnerId,\n fingerprints: new Set(Object.keys(encryptedKeys).map((x) => x.slice(-32))),\n }))\n )\n const infoFrom = Object.values(allExchangeKeys.keysFromOwner).flatMap((delegateIdToKeys) =>\n Object.entries(delegateIdToKeys).map(([delegateId, encryptedKeys]) => ({\n delegator: dataOwnerId,\n delegate: delegateId,\n fingerprints: new Set(Object.keys(encryptedKeys).map((x) => x.slice(-32))),\n }))\n )\n return [...infoFrom, ...infoTo]\n }\n\n private createMaintenanceTask(ownerId: string, concernedPubKey: string) {\n return new MaintenanceTask({\n id: this.crypto.primitives.randomUuid(),\n taskType: KeyPairUpdateRequest.TASK_TYPE,\n status: MaintenanceTask.StatusEnum.Pending,\n properties: [\n new PropertyStub({\n id: KeyPairUpdateRequest.OWNER_ID_PROP_ID,\n type: new PropertyTypeStub({ type: PropertyTypeStub.TypeEnum.STRING }),\n typedValue: new TypedValueObject({\n type: TypedValueObject.TypeEnum.STRING,\n stringValue: ownerId,\n }),\n }),\n new PropertyStub({\n id: KeyPairUpdateRequest.OWNER_PUB_PROP_ID,\n type: new PropertyTypeStub({ type: PropertyTypeStub.TypeEnum.STRING }),\n typedValue: new TypedValueObject({\n type: TypedValueObject.TypeEnum.STRING,\n stringValue: concernedPubKey,\n }),\n }),\n ],\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"icc-icure-maintenance-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-icure-maintenance-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './crypto/RSA'\nimport { IccMaintenanceTaskXApi } from './icc-maintenance-task-x-api'\nimport { MaintenanceTask } from '../icc-api/model/MaintenanceTask'\nimport { ua2hex } from './utils'\nimport { PropertyStub } from '../icc-api/model/PropertyStub'\nimport { PropertyTypeStub } from '../icc-api/model/PropertyTypeStub'\nimport { TypedValueObject } from '../icc-api/model/TypedValueObject'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\nimport { KeyPairUpdateRequest } from './maintenance/KeyPairUpdateRequest'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { User } from '../icc-api/model/User'\nimport { SecureDelegation } from '../icc-api/model/SecureDelegation'\nimport { IccExchangeDataApi } from '../icc-api/api/IccExchangeDataApi'\nimport { DataOwnerTypeEnum } from '../icc-api/model/DataOwnerTypeEnum'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\n\ntype ExchangeKeyInfo = { delegator: string; delegate: string; fingerprints: Set<string> }\n\n/**\n * Api for interpreting maintenance tasks and applying required client-side actions.\n */\nexport class IccIcureMaintenanceXApi {\n constructor(\n private readonly crypto: IccCryptoXApi,\n private readonly tasksApi: IccMaintenanceTaskXApi,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly exchangeDataApi: IccExchangeDataApi\n ) {}\n\n // TODO api to get all tasks for current owner from owner with id\n\n /**\n * Applies a key pair update request between another data owner and the current data owner to allow the other data owner to access existing exchange\n * keys shared with the current data owner. IMPORTANT: it is your responsibility to verify the authenticity of the public key / update request\n * before calling this method: this method assumes the new public key for the concerned data owner is authentic.\n * @param update a keypair update request to the current data owner.\n */\n async applyKeyPairUpdate(update: KeyPairUpdateRequest) {\n await this.crypto.exchangeKeys.base.giveAccessBackTo(\n update.concernedDataOwnerId,\n update.newPublicKey,\n this.crypto.userKeysManager.getDecryptionKeys()\n )\n await this.crypto.exchangeData.giveAccessBackTo(update.concernedDataOwnerId, update.newPublicKey)\n }\n\n /**\n * @internal This method is intended only for internal use and may be changed without notice.\n * Creates the necessary maintenance tasks to request access to existing exchange keys with the new key pair for the current user.\n * @param user the user which owns the new key pair.\n * @param keypair a new key pair for the current user.\n * @param requestToOwnerTypes specifies the types of data owner that have shared data with the current data owner or which were given access to data\n * from the current data owner will receive a 'give access back' request. If not specified, the value be inferred from the current data owner type.\n */\n async createMaintenanceTasksForNewKeypair(user: User, keypair: KeyPair<CryptoKey>, requestToOwnerTypes?: DataOwnerTypeEnum[]): Promise<void> {\n const currentUserType = await this.dataOwnerApi.getCurrentDataOwnerType()\n if (!requestToOwnerTypes) {\n if (currentUserType === 'device') {\n console.warn('Current data owner is a device and there is no need to create maintenance tasks for updated keypair.')\n return\n } else {\n requestToOwnerTypes =\n currentUserType === DataOwnerTypeEnum.Patient ? [DataOwnerTypeEnum.Patient, DataOwnerTypeEnum.Hcp] : [DataOwnerTypeEnum.Hcp]\n }\n }\n const hexNewPubKey = ua2hex(await this.crypto.primitives.RSA.exportKey(keypair.publicKey, 'spki'))\n const hexNewPubKeyFp = hexNewPubKey.slice(-32)\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const requestDataOwnersForExchangeKeys = (await this.getExchangeKeysInfosOf(selfId, requestToOwnerTypes))\n .filter((info) => !info.fingerprints.has(hexNewPubKeyFp))\n .flatMap((info) => [info.delegate, info.delegator])\n .filter((dataOwner) => dataOwner !== selfId)\n const requestDataOwnersForExchangeData = await this.exchangeDataApi.getExchangeDataParticipantCounterparts(\n selfId,\n [...new Set(requestToOwnerTypes)].join(',')\n )\n const requestDataOwners = [...new Set([...requestDataOwnersForExchangeKeys, ...requestDataOwnersForExchangeData])]\n if (requestDataOwners.length > 0) {\n const tasksToCreate = requestDataOwners.map((dataOwner) => ({\n delegate: dataOwner,\n task: this.createMaintenanceTask(selfId, hexNewPubKey),\n }))\n for (const taskToCreate of tasksToCreate) {\n const instance = await this.tasksApi.newInstance(user, taskToCreate.task, {\n additionalDelegates: { [taskToCreate.delegate]: AccessLevelEnum.WRITE },\n })\n if (instance) {\n // TODO create in bulk\n await this.tasksApi.createMaintenanceTaskWithUser(user, instance)\n }\n }\n }\n }\n\n private async getExchangeKeysInfosOf(dataOwnerId: string, otherOwnerTypes: DataOwnerTypeEnum[]): Promise<ExchangeKeyInfo[]> {\n const allExchangeKeys = await this.crypto.exchangeKeys.base.getAllExchangeKeysWith(dataOwnerId, otherOwnerTypes)\n const infoTo = Object.entries(allExchangeKeys.keysToOwner).flatMap(([delegatorId, delegatorFpToKeys]) =>\n Object.values(delegatorFpToKeys).map((encryptedKeys) => ({\n delegator: delegatorId,\n delegate: dataOwnerId,\n fingerprints: new Set(Object.keys(encryptedKeys).map((x) => x.slice(-32))),\n }))\n )\n const infoFrom = Object.values(allExchangeKeys.keysFromOwner).flatMap((delegateIdToKeys) =>\n Object.entries(delegateIdToKeys).map(([delegateId, encryptedKeys]) => ({\n delegator: dataOwnerId,\n delegate: delegateId,\n fingerprints: new Set(Object.keys(encryptedKeys).map((x) => x.slice(-32))),\n }))\n )\n return [...infoFrom, ...infoTo]\n }\n\n private createMaintenanceTask(ownerId: string, concernedPubKey: string) {\n return new MaintenanceTask({\n id: this.crypto.primitives.randomUuid(),\n taskType: KeyPairUpdateRequest.TASK_TYPE,\n status: MaintenanceTask.StatusEnum.Pending,\n properties: [\n new PropertyStub({\n id: KeyPairUpdateRequest.OWNER_ID_PROP_ID,\n type: new PropertyTypeStub({ type: PropertyTypeStub.TypeEnum.STRING }),\n typedValue: new TypedValueObject({\n type: TypedValueObject.TypeEnum.STRING,\n stringValue: ownerId,\n }),\n }),\n new PropertyStub({\n id: KeyPairUpdateRequest.OWNER_PUB_PROP_ID,\n type: new PropertyTypeStub({ type: PropertyTypeStub.TypeEnum.STRING }),\n typedValue: new TypedValueObject({\n type: TypedValueObject.TypeEnum.STRING,\n stringValue: concernedPubKey,\n }),\n }),\n ],\n })\n }\n}\n"]}
|