@icure/api 8.0.64 → 8.0.66
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/internal/IccExchangeDataApi.d.ts +2 -0
- package/icc-api/api/internal/IccExchangeDataApi.js +10 -0
- package/icc-api/api/internal/IccExchangeDataApi.js.map +1 -1
- package/icc-api/iccApi.d.ts +0 -1
- package/icc-api/iccApi.js +0 -1
- package/icc-api/iccApi.js.map +1 -1
- package/icc-api/index.d.ts +0 -1
- package/icc-api/index.js +0 -1
- package/icc-api/index.js.map +1 -1
- package/icc-x-api/crypto/AccessControlSecretUtils.d.ts +4 -13
- package/icc-x-api/crypto/AccessControlSecretUtils.js +19 -29
- package/icc-x-api/crypto/AccessControlSecretUtils.js.map +1 -1
- package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +8 -3
- package/icc-x-api/crypto/BaseExchangeDataManager.js +45 -10
- package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -1
- package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +2 -3
- package/icc-x-api/crypto/BaseExchangeKeysManager.js +17 -20
- package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/CryptoPrimitives.d.ts +2 -0
- package/icc-x-api/crypto/CryptoPrimitives.js +3 -0
- package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -1
- package/icc-x-api/crypto/DelegationsDeAnonymization.d.ts +3 -3
- package/icc-x-api/crypto/DelegationsDeAnonymization.js +7 -7
- package/icc-x-api/crypto/DelegationsDeAnonymization.js.map +1 -1
- package/icc-x-api/crypto/ExchangeDataManager.d.ts +19 -29
- package/icc-x-api/crypto/ExchangeDataManager.js +200 -225
- package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -1
- package/icc-x-api/crypto/ExchangeDataMapManager.js +6 -4
- package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -1
- package/icc-x-api/crypto/ExchangeKeysManager.d.ts +4 -16
- package/icc-x-api/crypto/ExchangeKeysManager.js +44 -41
- package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/ExtendedApisUtils.d.ts +47 -25
- package/icc-x-api/crypto/ExtendedApisUtils.js.map +1 -1
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +19 -18
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +213 -134
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -1
- package/icc-x-api/crypto/HMACUtils.d.ts +2 -2
- package/icc-x-api/crypto/HMACUtils.js +3 -4
- package/icc-x-api/crypto/HMACUtils.js.map +1 -1
- package/icc-x-api/crypto/NativeCryptoPrimitivesBridge.d.ts +1 -0
- package/icc-x-api/crypto/NativeCryptoPrimitivesBridge.js +5 -0
- package/icc-x-api/crypto/NativeCryptoPrimitivesBridge.js.map +1 -1
- package/icc-x-api/crypto/SecureDelegationsManager.d.ts +0 -1
- package/icc-x-api/crypto/SecureDelegationsManager.js +17 -49
- package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -1
- package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +59 -90
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js +470 -56
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -1
- package/icc-x-api/crypto/ShamirKeysManager.js +1 -1
- package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -1
- package/icc-x-api/crypto/TransferKeysManager.d.ts +1 -3
- package/icc-x-api/crypto/TransferKeysManager.js +2 -4
- package/icc-x-api/crypto/TransferKeysManager.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +2 -2
- package/icc-x-api/icc-accesslog-x-api.js +7 -3
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.js +4 -2
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.d.ts +0 -1
- package/icc-x-api/icc-contact-x-api.js +33 -48
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-crypto-x-api.js +1 -1
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.d.ts +2 -2
- package/icc-x-api/icc-document-x-api.js +45 -42
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.js +3 -1
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.js +4 -4
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.js +4 -2
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-message-x-api.js +4 -2
- package/icc-x-api/icc-message-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.js +5 -7
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-topic-x-api.js +2 -2
- package/icc-x-api/icc-topic-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +6 -2
- package/icc-x-api/index.js +16 -20
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/utils/crypto-utils.d.ts +6 -4
- package/icc-x-api/utils/crypto-utils.js +27 -6
- package/icc-x-api/utils/crypto-utils.js.map +1 -1
- package/icc-x-api/utils/simple-lru-cache.d.ts +19 -0
- package/icc-x-api/utils/simple-lru-cache.js +90 -0
- package/icc-x-api/utils/simple-lru-cache.js.map +1 -0
- package/package.json +4 -2
- package/test/icc-x-api/crud/entities-crud-test-interface.js +0 -8
- package/test/icc-x-api/crud/entities-crud-test-interface.js.map +1 -1
- package/test/icc-x-api/crypto/exchange-data-manager-test.js +75 -93
- package/test/icc-x-api/crypto/exchange-data-manager-test.js.map +1 -1
- package/test/icc-x-api/crypto/legacy-metadata-migration-test.js.map +1 -1
- package/test/icc-x-api/crypto/secure-delegations-manager-test.js +28 -16
- package/test/icc-x-api/crypto/secure-delegations-manager-test.js.map +1 -1
- package/test/utils/FakeEncryptionKeysManager.d.ts +1 -0
- package/test/utils/FakeEncryptionKeysManager.js +11 -0
- package/test/utils/FakeEncryptionKeysManager.js.map +1 -1
- package/test/utils/FakeExchangeDataApi.d.ts +4 -2
- package/test/utils/FakeExchangeDataApi.js +24 -6
- package/test/utils/FakeExchangeDataApi.js.map +1 -1
- package/test/utils/FakeExchangeDataManager.d.ts +10 -10
- package/test/utils/FakeExchangeDataManager.js +12 -22
- package/test/utils/FakeExchangeDataManager.js.map +1 -1
- package/test/utils/TestApi.js +1 -0
- package/test/utils/TestApi.js.map +1 -1
- package/icc-api/api/IccArticleApi.d.ts +0 -72
- package/icc-api/api/IccArticleApi.js +0 -149
- package/icc-api/api/IccArticleApi.js.map +0 -1
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.d.ts +0 -33
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js +0 -141
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js.map +0 -1
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.d.ts +0 -46
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js +0 -312
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js.map +0 -1
- package/icc-x-api/crypto/UserSignatureKeysManager.d.ts +0 -26
- package/icc-x-api/crypto/UserSignatureKeysManager.js +0 -78
- package/icc-x-api/crypto/UserSignatureKeysManager.js.map +0 -1
- package/test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.d.ts +0 -1
- package/test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.js +0 -393
- package/test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.js.map +0 -1
- package/test/icc-x-api/crypto/security-metadata-decryptor-chain-test.d.ts +0 -1
- package/test/icc-x-api/crypto/security-metadata-decryptor-chain-test.js +0 -213
- package/test/icc-x-api/crypto/security-metadata-decryptor-chain-test.js.map +0 -1
- package/test/icc-x-api/crypto/signature-keys-manager-test.d.ts +0 -1
- package/test/icc-x-api/crypto/signature-keys-manager-test.js +0 -44
- package/test/icc-x-api/crypto/signature-keys-manager-test.js.map +0 -1
- package/test/utils/FakeSignatureKeysManager.d.ts +0 -16
- package/test/utils/FakeSignatureKeysManager.js +0 -54
- package/test/utils/FakeSignatureKeysManager.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityMetadataDecryptor.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/SecurityMetadataDecryptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA,2EAAuE;AACvE,IAAO,eAAe,GAAG,mCAAgB,CAAC,eAAe,CAAA;AA6EzD;;;GAGG;AACH,MAAa,8BAA8B;IACzC,YAA6B,UAAuC;QAAvC,eAAU,GAAV,UAAU,CAA6B;IAAG,CAAC;IAExE,uBAAuB,CACrB,WAAoC,EACpC,yBAAmC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAA;IACnG,CAAC;IAED,wBAAwB,CACtB,WAAoC,EACpC,yBAAmC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAA;IACpG,CAAC;IAED,kBAAkB,CAChB,WAAoC,EACpC,yBAAmC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAA;IAC9F,CAAC;IAEK,oBAAoB,CACxB,WAAoC,EACpC,yBAAmC;;YAEnC,IAAI,YAAY,GAAiD,SAAS,CAAA;YAC1E,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE;gBAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAA;gBACtF,IAAI,SAAS,KAAK,eAAe,CAAC,KAAK,EAAE;oBACvC,OAAO,SAAS,CAAA;iBACjB;gBACD,IAAI,SAAS,KAAK,eAAe,CAAC,IAAI,EAAE;oBACtC,YAAY,GAAG,eAAe,CAAC,IAAI,CAAA;iBACpC;aACF;YACD,OAAO,YAAY,CAAA;QACrB,CAAC;KAAA;IAED,oBAAoB,CAAC,MAA6C;QAChE,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAA;IACpE,CAAC;IAEO,WAAW,CAAI,YAA8E;QACnG,SAAgB,SAAS,CAAC,UAAuC;;gBAC/D,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE;oBAC1B,MAAM,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;oBACrC,IAAI,IAAI,GAAG,cAAM,aAAa,CAAC,IAAI,EAAE,CAAA,CAAA;oBACrC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE;wBACjB,oBAAM,IAAI,CAAC,KAAK,CAAA,CAAA;wBAChB,IAAI,GAAG,cAAM,aAAa,CAAC,IAAI,EAAE,CAAA,CAAA;qBAClC;iBACF;YACH,CAAC;SAAA;QACD,OAAO,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC;CACF;AA1DD,wEA0DC","sourcesContent":["import { EncryptedEntity, EncryptedEntityStub } from '../../icc-api/model/models'\nimport { EncryptedEntityWithType } from '../utils/EntityWithDelegationTypeName'\nimport { SecureDelegation } from '../../icc-api/model/SecureDelegation'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\n\n/**\n * @internal this class is for internal use only and may be changed without notice.\n * Logic for the decryption of the metadata used for access control, encryption, and other security features in an entity.\n */\nexport interface SecurityMetadataDecryptor {\n /**\n * Decrypt the encryption keys for an entity. Keys must be returned in raw hex format, removing dashes if they were generated from a UUID.\n * @param typedEntity an encrypted entity or its stub.\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when decrypting. It should\n * contain only data owners from the current data owner hierarchy.\n * @throws if dataOwnersHierarchySubset is empty\n * @return a generator for the decrypted exchange key which yields objects containing:\n * - `decrypted`: a decrypted encryption key for {@link typedEntity}. Note that the same key may be yielded multiple times by the generator.\n * - `dataOwnersWithAccess`: data owners which have access to the exchange data necessary for the decryption of the encrypted data from which this\n * key was extracted. The generator may yield more elements with the same `decrypted` but different `dataOwnersWithAccess`\n */\n decryptEncryptionKeysOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never>\n\n /**\n * Decrypt the secret ids for an entity.\n * @param typedEntity an encrypted entity or its stub.\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when decrypting. It should\n * contain only data owners from the current data owner hierarchy.\n * @throws if dataOwnersHierarchySubset is empty\n * @return a generator for the decrypted secret ids which yields objects containing:\n * - `decrypted`: a decrypted secret id of {@link entity}. Note that the same id may be yielded multiple times by the generator.\n * - `dataOwnersWithAccess`: data owners which have access to the exchange data necessary for the decryption of the encrypted data from which this\n * id was extracted. The generator may yield more elements with the same `decrypted` but different `dataOwnersWithAccess`\n */\n decryptSecretIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never>\n\n /**\n * Decrypt the owning entity ids of an entity.\n * @param typedEntity an encrypted entity or its stub.\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when decrypting. It should\n * contain only data owners from the current data owner hierarchy.\n * @throws if dataOwnersHierarchySubset is empty\n * @return a generator for the decrypted owning entity ids which yields objects containing:\n * - `decrypted`: a decrypted owning entity id of {@link entity}. Note that the same id may be yielded multiple times by the generator.\n * - `dataOwnersWithAccess`: data owners which have access to the exchange data necessary for the decryption of the encrypted data from which this\n * id was extracted. The generator may yield more elements with the same `decrypted` but different `dataOwnersWithAccess`\n */\n decryptOwningEntityIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never>\n\n /**\n * Get the maximum access level that any data owner in {@link dataOwnersHierarchySubset} has to {@link typedEntity}, according to the metadata\n * supported by this decryptor.\n * - If at least a data owner in {@link dataOwnersHierarchySubset} has write access the method returns {@link AccessLevel.WRITE}.\n * - If at least a data owner in {@link dataOwnersHierarchySubset} has read access and no data owner has write access the method returns\n * {@link AccessLevel.READ}.\n * - If a data owner has no access to the entity the method returns undefined (this can happen if the data owner has access to an entity through\n * some metadata which is not supported by this decryptor).\n * @param typedEntity an entity\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when calculating the\n * access level. This array should contain only data owners from the current data owner hierarchy.\n * @return the access level to the entity or undefined if none of the data owners has full access to the entity.\n */\n getEntityAccessLevel(typedEntity: EncryptedEntityWithType, dataOwnersHierarchySubset: string[]): Promise<AccessLevelEnum | undefined>\n\n /**\n * Verifies if there is at least one (encrypted) encryption key in the metadata supported by this decryptor, even if it can't be decrypted by the\n * current data owner.\n */\n hasAnyEncryptionKeys(entity: EncryptedEntity | EncryptedEntityStub): boolean\n}\n\n/**\n * @internal this class is meant for internal use only and may be changed without notice.\n * Security metadata decryptor which combines other existing decryptors.\n */\nexport class SecurityMetadataDecryptorChain implements SecurityMetadataDecryptor {\n constructor(private readonly decryptors: SecurityMetadataDecryptor[]) {}\n\n decryptEncryptionKeysOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never> {\n return this.concatenate((d) => d.decryptEncryptionKeysOf(typedEntity, dataOwnersHierarchySubset))\n }\n\n decryptOwningEntityIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never> {\n return this.concatenate((d) => d.decryptOwningEntityIdsOf(typedEntity, dataOwnersHierarchySubset))\n }\n\n decryptSecretIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never> {\n return this.concatenate((d) => d.decryptSecretIdsOf(typedEntity, dataOwnersHierarchySubset))\n }\n\n async getEntityAccessLevel(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): Promise<SecureDelegation.AccessLevelEnum | undefined> {\n let currMaxLevel: SecureDelegation.AccessLevelEnum | undefined = undefined\n for (const d of this.decryptors) {\n const currLevel = await d.getEntityAccessLevel(typedEntity, dataOwnersHierarchySubset)\n if (currLevel === AccessLevelEnum.WRITE) {\n return currLevel\n }\n if (currLevel === AccessLevelEnum.READ) {\n currMaxLevel = AccessLevelEnum.READ\n }\n }\n return currMaxLevel\n }\n\n hasAnyEncryptionKeys(entity: EncryptedEntity | EncryptedEntityStub): boolean {\n return this.decryptors.some((d) => d.hasAnyEncryptionKeys(entity))\n }\n\n private concatenate<T>(getGenerator: (d: SecurityMetadataDecryptor) => AsyncGenerator<T, void, never>): AsyncGenerator<T, void, never> {\n async function* generator(decryptors: SecurityMetadataDecryptor[]): AsyncGenerator<T, void, never> {\n for (const d of decryptors) {\n const currGenerator = getGenerator(d)\n let next = await currGenerator.next()\n while (!next.done) {\n yield next.value\n next = await currGenerator.next()\n }\n }\n }\n return generator(this.decryptors)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SecurityMetadataDecryptor.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/SecurityMetadataDecryptor.ts"],"names":[],"mappings":"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","sourcesContent":["import { b64_2ab, EncryptedEntityWithType, EntityWithDelegationTypeName, hex2ua, ua2string } from '../utils'\nimport { ExchangeKeysManager } from './ExchangeKeysManager'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { Delegation } from '../../icc-api/model/Delegation'\nimport { ExchangeDataManager } from './ExchangeDataManager'\nimport { ExchangeDataMapManager } from './ExchangeDataMapManager'\nimport { SecureDelegationsEncryption } from './SecureDelegationsEncryption'\nimport { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { EncryptedEntity, EncryptedEntityStub, SecureDelegation } from '../../icc-api/model/models'\nimport { ExchangeData } from '../../icc-api/model/internal/ExchangeData'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\n\nexport type DelegationMembersDetails = {\n delegator: string | undefined\n delegate: string | undefined\n fullyExplicit: boolean\n accessControlSecret: string | undefined\n accessLevel: AccessLevelEnum\n}\n\nexport enum SecurityMetadataType {\n SecretId = 1, // Start from 1, avoids issues with SecretId being falsy\n EncryptionKey,\n OwningEntityId,\n}\n\nexport class SecurityMetadataDecryptor {\n constructor(\n private readonly exchangeKeysManager: ExchangeKeysManager,\n private readonly primitives: CryptoPrimitives,\n private readonly exchangeData: ExchangeDataManager,\n private readonly exchangeDataMap: ExchangeDataMapManager,\n private readonly secureDelegationsEncryption: SecureDelegationsEncryption,\n private readonly dataOwnerApi: IccDataOwnerXApi\n ) {}\n\n async decryptLegacyDelegations(\n entities: (EncryptedEntityStub | EncryptedEntity)[],\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ [entityId: string]: string[] }> {\n // For legacy delegations there is no advantage in doing stuff in bulk.\n const res: { [entityId: string]: string[] } = {}\n for (const e of entities) {\n const allDecrypted = await this.extractFromLegacyDelegations(e, dataOwnersHierarchySubset, metadataType)\n const deduplicatedDecrypted = new Set(allDecrypted.map((x) => x.decrypted))\n res[e.id!] = [...deduplicatedDecrypted]\n }\n return res\n }\n\n private async extractFromLegacyDelegations(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ decrypted: string; dataOwnersWithAccess: string[] }[]> {\n if (!dataOwnersHierarchySubset.length) throw new Error(\"`dataOwnersHierarchySubset` can't be empty\")\n let delegations: { [delegateId: string]: Delegation[] }\n let validateDecrypted: (result: string) => Promise<boolean> = (x) => Promise.resolve(!!x)\n let mapDecrypted: (result: string) => string = (x) => x\n switch (metadataType) {\n case SecurityMetadataType.SecretId:\n delegations = entity.delegations ?? {}\n break\n case SecurityMetadataType.EncryptionKey:\n delegations = entity.encryptionKeys ?? {}\n validateDecrypted = async (key) => {\n if (!/^[0-9A-Fa-f\\-]+$/g.test(key)) return false\n try {\n await this.primitives.AES.importKey('raw', hex2ua(key.replace(/-/g, '')))\n return true\n } catch (e) {\n console.warn(`Could not import key ${key} as an encryption key.`, e)\n return false\n }\n }\n mapDecrypted = (key) => key.replace(/-/g, '')\n break\n case SecurityMetadataType.OwningEntityId:\n delegations = entity.cryptedForeignKeys ?? {}\n break\n default:\n throw new Error(`Internal error: invalid SecurityMetadataType ${metadataType}`)\n }\n const delegationsWithOwner = Object.entries(delegations).flatMap(([delegateId, delegations]) =>\n dataOwnersHierarchySubset.some((dataOwnerId) => dataOwnerId === delegateId)\n ? this.populateLegacyDelegationDelegate(delegateId, delegations)\n : this.populateLegacyDelegationDelegate(\n delegateId,\n delegations.filter((d) => dataOwnersHierarchySubset.some((dataOwnerId) => d.owner === dataOwnerId))\n )\n )\n const res: { decrypted: string; dataOwnersWithAccess: string[] }[] = []\n for (const delegation of delegationsWithOwner) {\n const decrypted = await this.tryDecryptLegacyDelegation(delegation, (k) => validateDecrypted(k))\n if (decrypted)\n res.push({\n decrypted: mapDecrypted(decrypted),\n dataOwnersWithAccess: delegation.owner ? [delegation.owner, delegation.delegatedTo!] : [delegation.delegatedTo!],\n })\n }\n return res\n }\n\n private populateLegacyDelegationDelegate(delegateId: string, delegations: Delegation[]): Delegation[] {\n return delegations.map((d) => (d.delegatedTo === delegateId ? d : { ...d, delegatedTo: delegateId }))\n }\n\n private async tryDecryptLegacyDelegation(\n delegation: Delegation,\n validateDecrypted: (result: string) => Promise<boolean>\n ): Promise<string | undefined> {\n const exchangeKeys = await this.exchangeKeysManager.getDecryptionExchangeKeysFor(delegation.owner!, delegation.delegatedTo!)\n for (const key of exchangeKeys) {\n try {\n // Format of encrypted key for any delegation should be entityId:key, but with the merging of entities the entityId might not match the\n // current id. As a checksum we are only verifying that the decrypted bytes can be represented as a string with exactly one ':'.\n // Additionally, we also have a validator that is specific for each type of delegation content (encryption key, secret id, ...)\n const decrypted = ua2string(await this.primitives.AES.decrypt(key, hex2ua(delegation.key!)))\n const decryptedSplit = decrypted.split(':')\n if (decryptedSplit.length === 2) {\n if (await validateDecrypted(decryptedSplit[1])) return decryptedSplit[1]\n } else {\n console.warn(\"Error in the decrypted delegation: content should contain exactly 1 ':', the delegation is ignored.\")\n }\n } catch (e) {\n // Do nothing: the delegation uses another exchange key owner->delegator\n }\n }\n }\n\n async decryptSecureDelegationsUsingCache(\n entities: (EncryptedEntityStub | EncryptedEntity)[],\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ [entityId: string]: string[] }> {\n const toSearchById: Set<string> = new Set([])\n const toSearchByDelegationKey: Set<string> = new Set([])\n for (const e of entities) {\n for (const [delegationKey, delegation] of Object.entries(e.securityMetadata?.secureDelegations ?? {})) {\n if (\n !delegation.delegator ||\n !delegation.delegate ||\n dataOwnersHierarchySubset.some((it) => it == delegation.delegator || it == delegation.delegate)\n ) {\n if (delegation.exchangeDataId) {\n toSearchById.add(delegation.exchangeDataId)\n } else {\n toSearchByDelegationKey.add(delegationKey)\n }\n }\n }\n }\n const cachedByExchangeDataId = await this.exchangeData.getDecryptionDataKeyByIds([...toSearchById], false)\n const cachedByDelegationKey = await this.exchangeData.getCachedDecryptionDataKeyByAccessControlHash([...toSearchByDelegationKey])\n const res: { [entityId: string]: string[] } = {}\n for (const entity of entities) {\n const currEntityRes: Set<string> = new Set([])\n for (const [delegationKey, delegation] of Object.entries(entity.securityMetadata?.secureDelegations ?? {})) {\n const cached = delegation.exchangeDataId ? cachedByExchangeDataId[delegation.exchangeDataId] : cachedByDelegationKey[delegationKey]\n if (\n cached?.exchangeKey &&\n dataOwnersHierarchySubset.some((it) => it == cached?.exchangeData?.delegator || it == cached?.exchangeData?.delegate)\n ) {\n ;(await this.decryptSecureDelegationMetadata(delegation, metadataType, cached.exchangeKey)).forEach((decrypted) =>\n currEntityRes.add(decrypted)\n )\n }\n }\n res[entity.id!] = [...currEntityRes]\n }\n return res\n }\n\n hasSecurityMetadataOfType(delegation: SecureDelegation, metadataType: SecurityMetadataType): boolean {\n switch (metadataType) {\n case SecurityMetadataType.SecretId:\n return (delegation.secretIds ?? []).length > 0\n case SecurityMetadataType.EncryptionKey:\n return (delegation.encryptionKeys ?? []).length > 0\n case SecurityMetadataType.OwningEntityId:\n return (delegation.owningEntityIds ?? []).length > 0\n default:\n throw new Error('Internal error: invalid metadata type')\n }\n }\n\n async decryptSecureDelegationsUsingKnownExchangeData(\n entities: (EncryptedEntityStub | EncryptedEntity)[],\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ [entityId: string]: string[] }> {\n const toSearchById: Set<string> = new Set([])\n for (const e of entities) {\n for (const delegation of Object.values(e.securityMetadata?.secureDelegations ?? {})) {\n if (dataOwnersHierarchySubset.some((it) => it == delegation.delegator || it == delegation.delegate)) {\n if (delegation.exchangeDataId && this.hasSecurityMetadataOfType(delegation, metadataType)) {\n toSearchById.add(delegation.exchangeDataId)\n }\n }\n }\n }\n const retrievedByExchangeDataId = toSearchById.size > 0 ? await this.exchangeData.getDecryptionDataKeyByIds([...toSearchById], true) : {}\n const res: { [entityId: string]: string[] } = {}\n for (const entity of entities) {\n const currEntityRes: Set<string> = new Set([])\n for (const delegation of Object.values(entity.securityMetadata?.secureDelegations ?? {})) {\n const currDelegationExchangeData = delegation.exchangeDataId ? retrievedByExchangeDataId[delegation.exchangeDataId] : undefined\n if (currDelegationExchangeData?.exchangeKey) {\n ;(await this.decryptSecureDelegationMetadata(delegation, metadataType, currDelegationExchangeData.exchangeKey)).forEach((decrypted) =>\n currEntityRes.add(decrypted)\n )\n }\n }\n res[entity.id!] = [...currEntityRes]\n }\n return res\n }\n\n async decryptSecureDelegationsUsingExchangeDataMap(\n entities: (EncryptedEntityStub | EncryptedEntity)[],\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ [entityId: string]: string[] }> {\n const toSearchByExchangeDataMap: Set<string> = new Set([])\n for (const e of entities) {\n for (const [delegationKey, delegation] of Object.entries(e.securityMetadata?.secureDelegations ?? {})) {\n if (dataOwnersHierarchySubset.some((it) => it == delegation.delegator || it == delegation.delegate)) {\n if (!delegation.exchangeDataId && this.hasSecurityMetadataOfType(delegation, metadataType)) {\n toSearchByExchangeDataMap.add(delegationKey)\n }\n }\n }\n }\n const exchangeDataMaps =\n toSearchByExchangeDataMap.size > 0 ? await this.exchangeDataMap.getExchangeDataMapBatch([...toSearchByExchangeDataMap]) : []\n const exchangeDataIdByDelegationKey: { [delegationKey: string]: string } = {}\n for (const exchangeDataMap of exchangeDataMaps) {\n const decrypted = await this.secureDelegationsEncryption.decryptExchangeDataId(exchangeDataMap.encryptedExchangeDataIds)\n if (decrypted) {\n exchangeDataIdByDelegationKey[exchangeDataMap.id] = decrypted\n }\n }\n if (Object.keys(exchangeDataIdByDelegationKey).length == 0) return {}\n const retrievedByExchangeDataId =\n Object.values(exchangeDataIdByDelegationKey).length > 0\n ? await this.exchangeData.getDecryptionDataKeyByIds([...new Set(Object.values(exchangeDataIdByDelegationKey))], true)\n : {}\n const res: { [entityId: string]: string[] } = {}\n for (const entity of entities) {\n const currEntityRes: Set<string> = new Set([])\n for (const [delegationKey, delegation] of Object.entries(entity.securityMetadata?.secureDelegations ?? {})) {\n const exchangeDataId = exchangeDataIdByDelegationKey[delegationKey]\n const cached = exchangeDataId ? retrievedByExchangeDataId[exchangeDataId] : undefined\n if (cached?.exchangeKey) {\n ;(await this.decryptSecureDelegationMetadata(delegation, metadataType, cached.exchangeKey)).forEach((decrypted) =>\n currEntityRes.add(decrypted)\n )\n }\n }\n res[entity.id!] = [...currEntityRes]\n }\n return res\n }\n\n async decryptAll(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ ownerId: string; extracted: string[] }[]> {\n const allExtractedWithDataOwners = [\n ...(await this.decryptAllLegacyDelegations(entity, dataOwnersHierarchySubset, metadataType)),\n ...(await this.decryptAllSecureDelegations(entity, dataOwnersHierarchySubset, metadataType)),\n ]\n return dataOwnersHierarchySubset.map((dataOwner) => {\n const decryptedEntriesForDataOwner = allExtractedWithDataOwners\n .filter((x) => x.dataOwnersWithAccess.some((d) => dataOwner == d))\n .map((x) => x.decrypted)\n return {\n ownerId: dataOwner,\n extracted: [...new Set(decryptedEntriesForDataOwner)],\n }\n })\n }\n\n async decryptAllLegacyDelegations(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ decrypted: string; dataOwnersWithAccess: string[] }[]> {\n return this.extractFromLegacyDelegations(entity, dataOwnersHierarchySubset, metadataType)\n }\n\n async decryptAllSecureDelegations(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[],\n metadataType: SecurityMetadataType\n ): Promise<{ decrypted: string; dataOwnersWithAccess: string[] }[]> {\n const secureDelegationEntries: [string, SecureDelegation][] = Object.entries(entity.securityMetadata?.secureDelegations ?? {})\n const toSearchByDelegationKey: string[] = secureDelegationEntries.flatMap(([delegationKey, delegation]): string[] => {\n if (!delegation.exchangeDataId) {\n return [delegationKey]\n } else {\n return []\n }\n })\n const exchangeDataByDelegationKey = await this.exchangeData.getCachedDecryptionDataKeyByAccessControlHash(toSearchByDelegationKey)\n const toSearchWithExchangeDataMap = secureDelegationEntries.flatMap(([delegationKey, delegation]): string[] => {\n if (\n !delegation.exchangeDataId &&\n dataOwnersHierarchySubset.some((it) => delegation.delegate == it || delegation.delegator == it) &&\n !exchangeDataByDelegationKey[delegationKey] &&\n this.hasSecurityMetadataOfType(delegation, metadataType)\n ) {\n return [delegationKey]\n } else {\n return []\n }\n })\n const exchangeDataMaps =\n toSearchWithExchangeDataMap.length > 0 ? await this.exchangeDataMap.getExchangeDataMapBatch(toSearchWithExchangeDataMap) : []\n const exchangeDataIdByDelegationKey: { [delegationKey: string]: string } = {}\n for (const exchangeDataMap of exchangeDataMaps) {\n const decrypted = await this.secureDelegationsEncryption.decryptExchangeDataId(exchangeDataMap.encryptedExchangeDataIds)\n if (decrypted) {\n exchangeDataIdByDelegationKey[exchangeDataMap.id] = decrypted\n }\n }\n const toSearchDirectlyById = secureDelegationEntries.flatMap(([delegationKey, delegation]): string[] => {\n if (\n delegation.exchangeDataId &&\n dataOwnersHierarchySubset.some((it) => delegation.delegate == it || delegation.delegator == it) &&\n !exchangeDataByDelegationKey[delegationKey] &&\n this.hasSecurityMetadataOfType(delegation, metadataType)\n ) {\n return [delegation.exchangeDataId]\n } else {\n return []\n }\n })\n const allExchangeDataIdToRetrieve = [...new Set([...toSearchDirectlyById, ...Object.values(exchangeDataIdByDelegationKey)])]\n const exchangeDataById =\n allExchangeDataIdToRetrieve.length > 0 ? await this.exchangeData.getDecryptionDataKeyByIds(allExchangeDataIdToRetrieve, true) : {}\n const allExtractedWithDataOwners: { decrypted: string; dataOwnersWithAccess: string[] }[] = []\n for (const [delegationKey, delegation] of secureDelegationEntries) {\n let exchangeData:\n | {\n exchangeKey: CryptoKey | undefined\n accessControlSecret: string | undefined\n exchangeData: ExchangeData\n }\n | undefined = undefined\n if (exchangeDataByDelegationKey[delegationKey]) {\n exchangeData = exchangeDataByDelegationKey[delegationKey]\n } else if (delegation.exchangeDataId) {\n exchangeData = exchangeDataById[delegation.exchangeDataId]\n } else if (exchangeDataIdByDelegationKey[delegationKey]) {\n exchangeData = exchangeDataById[exchangeDataIdByDelegationKey[delegationKey]]\n }\n if (exchangeData && exchangeData.exchangeKey) {\n const decrypted = await this.decryptSecureDelegationMetadata(delegation, metadataType, exchangeData.exchangeKey)\n for (const d of decrypted) {\n allExtractedWithDataOwners.push({\n decrypted: d,\n dataOwnersWithAccess: [exchangeData.exchangeData.delegator, exchangeData.exchangeData.delegate],\n })\n }\n }\n }\n return allExtractedWithDataOwners\n }\n\n async getDelegationMemberDetails(typedEntity: EncryptedEntityWithType): Promise<{\n [delegationKey: string]: DelegationMembersDetails\n }> {\n const res: { [delegationKey: string]: DelegationMembersDetails } = {}\n // 1. Add all explicit data owners, keep only delegations with at least an anonymous data owner to check later\n let remainingDelegations = Object.entries(typedEntity.entity.securityMetadata?.secureDelegations ?? {})\n let updatedRemainingDelegations: [string, SecureDelegation][] = []\n for (const delegationEntry of remainingDelegations) {\n const delegation = delegationEntry[1]\n if (delegation.delegator && delegation.delegate) {\n res[delegationEntry[0]] = {\n delegate: delegation.delegate,\n delegator: delegation.delegator,\n fullyExplicit: true,\n accessLevel: delegation.permissions,\n accessControlSecret: undefined,\n }\n } else {\n updatedRemainingDelegations.push(delegationEntry)\n }\n }\n remainingDelegations = updatedRemainingDelegations\n if (!remainingDelegations.length) return res\n updatedRemainingDelegations = []\n // 2. Attempt to identify the anonymous data owner of remaining delegations by checking if we have the exchange data cached by hash\n // Note: we can find exchange data by hash only if we could successfully decrypt it\n const cachedExchangeData = await this.exchangeData.getCachedDecryptionDataKeyByAccessControlHash(remainingDelegations.map((d) => d[0]))\n for (const delegationEntry of remainingDelegations) {\n const exchangeDataOfDelegation = cachedExchangeData[delegationEntry[0]]\n if (exchangeDataOfDelegation) {\n res[delegationEntry[0]] = {\n delegate: exchangeDataOfDelegation.exchangeData.delegate,\n delegator: exchangeDataOfDelegation.exchangeData.delegator,\n fullyExplicit: false,\n accessLevel: delegationEntry[1].permissions,\n accessControlSecret: exchangeDataOfDelegation.accessControlSecret,\n }\n } else {\n updatedRemainingDelegations.push(delegationEntry)\n }\n }\n remainingDelegations = updatedRemainingDelegations\n if (!remainingDelegations.length) return res\n updatedRemainingDelegations = []\n // 3. Attempt to identify the anonymous data owner of remaining delegations between us (or one of our parents) and an anonymous data owner\n const hierarchy = await this.dataOwnerApi.getCurrentDataOwnerHierarchyIds()\n const remainingExchangeDataMaps = await this.exchangeDataMap.getExchangeDataMapBatch(\n remainingDelegations\n .filter(([_, delegation]) => hierarchy.some((x) => x == delegation.delegator || x == delegation.delegate))\n .map(([hash, _]) => hash)\n )\n const exchangeDataIdByDelegationKey: { [delegationKey: string]: string } = {}\n for (const exchangeDataMap of remainingExchangeDataMaps) {\n if (!!exchangeDataMap.encryptedExchangeDataIds) {\n const decrypted = await this.secureDelegationsEncryption.decryptExchangeDataId(exchangeDataMap.encryptedExchangeDataIds)\n if (decrypted) {\n exchangeDataIdByDelegationKey[exchangeDataMap.id] = decrypted\n }\n }\n }\n const exchangeDataByIds = await this.exchangeData.getDecryptionDataKeyByIds(Object.values(exchangeDataIdByDelegationKey), true)\n for (const [hash, delegation] of remainingDelegations) {\n if (hierarchy.some((x) => x === delegation.delegate || x === delegation.delegator)) {\n const dataId = exchangeDataIdByDelegationKey[hash]\n const exchangeDataInfo = dataId ? exchangeDataByIds[dataId] : undefined\n if (exchangeDataInfo) {\n res[hash] = {\n delegator: exchangeDataInfo.exchangeData.delegator,\n delegate: exchangeDataInfo.exchangeData.delegate,\n fullyExplicit: false,\n accessLevel: delegation.permissions,\n accessControlSecret: exchangeDataInfo.accessControlSecret,\n }\n } else {\n updatedRemainingDelegations.push([hash, delegation])\n }\n } else {\n updatedRemainingDelegations.push([hash, delegation])\n }\n }\n return {\n ...res,\n ...Object.fromEntries(\n updatedRemainingDelegations.map(([hash, secureDelegation]) => [\n hash,\n {\n delegator: secureDelegation.delegator,\n delegate: secureDelegation.delegate,\n fullyExplicit: false,\n accessLevel: secureDelegation.permissions,\n accessControlSecret: undefined,\n },\n ])\n ),\n }\n }\n\n async decryptSecureDelegationMetadata(delegation: SecureDelegation, metadataType: SecurityMetadataType, key: CryptoKey): Promise<string[]> {\n switch (metadataType) {\n case SecurityMetadataType.SecretId:\n return this.secureDelegationsEncryption.decryptSecretIds(delegation, key)\n case SecurityMetadataType.EncryptionKey:\n return this.secureDelegationsEncryption.decryptEncryptionKeys(delegation, key)\n case SecurityMetadataType.OwningEntityId:\n return this.secureDelegationsEncryption.decryptOwningEntityIds(delegation, key)\n default:\n throw new Error(`Internal error: invalid SecurityMetadataType ${metadataType}`)\n }\n }\n\n async getEntityLegacyDelegationAccessLevel(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[]\n ): Promise<AccessLevelEnum | undefined> {\n if (!dataOwnersHierarchySubset.length) throw new Error(\"`dataOwnersHierarchySubset` can't be empty\")\n // Legacy delegations provide write access\n if (Object.keys(entity.delegations ?? {}).some((delegate) => dataOwnersHierarchySubset.includes(delegate))) {\n return AccessLevelEnum.WRITE\n }\n return undefined\n }\n\n async getEntitySecureDelegationAccessLevel(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[]\n ): Promise<AccessLevelEnum | undefined> {\n if (!dataOwnersHierarchySubset.length) throw new Error(\"`dataOwnersHierarchySubset` can't be empty\")\n // If the data owner is explicit all delegations he can access has his id. If the delegator is anonymous all delegations he can access are\n // accessible by hash. No mixed scenario possible.\n let accessibleDelegations: SecureDelegation[] = Object.values(entity.securityMetadata?.secureDelegations ?? {}).filter((secureDelegation) =>\n dataOwnersHierarchySubset.some((dataOwner) => dataOwner === secureDelegation.delegator || dataOwner === secureDelegation.delegate)\n )\n if (!accessibleDelegations.length) {\n const availableCanonicalHashes = Object.keys(\n await this.exchangeData.getCachedDecryptionDataKeyByAccessControlHash(Object.keys(entity.securityMetadata?.secureDelegations ?? {}))\n )\n accessibleDelegations = availableCanonicalHashes.map((hash) => (entity.securityMetadata?.secureDelegations ?? {})[hash])\n }\n const permissions = accessibleDelegations.map((secureDelegation) => secureDelegation.permissions)\n let maxLevel: AccessLevelEnum | undefined = undefined\n for (const permission of permissions) {\n if (permission === AccessLevelEnum.WRITE) {\n return AccessLevelEnum.WRITE\n }\n if (permission === AccessLevelEnum.READ) {\n maxLevel = AccessLevelEnum.READ\n }\n }\n return maxLevel\n }\n\n async getEntityAccessLevel(\n entity: EncryptedEntityStub | EncryptedEntity,\n dataOwnersHierarchySubset: string[]\n ): Promise<AccessLevelEnum | undefined> {\n const legacyAccess = await this.getEntityLegacyDelegationAccessLevel(entity, dataOwnersHierarchySubset)\n if (legacyAccess != undefined) return legacyAccess\n return this.getEntitySecureDelegationAccessLevel(entity, dataOwnersHierarchySubset)\n }\n\n hasAnyEncryptionKeys(entity: EncryptedEntityStub | EncryptedEntity): boolean {\n return Object.keys(entity.encryptionKeys ?? {}).length > 0 || Object.keys(entity.securityMetadata?.secureDelegations ?? {}).length > 0\n }\n}\n"]}
|
|
@@ -71,7 +71,7 @@ class ShamirKeysManager {
|
|
|
71
71
|
const delegatesKeys = {};
|
|
72
72
|
let updatedSelf = self;
|
|
73
73
|
for (const delegateId of new Set(Object.values(keySplitsToUpdate).flatMap((x) => x.notariesIds))) {
|
|
74
|
-
const res = yield this.exchangeDataManager.getOrCreateEncryptionDataTo(delegateId,
|
|
74
|
+
const res = yield this.exchangeDataManager.getOrCreateEncryptionDataTo(delegateId, false);
|
|
75
75
|
delegatesKeys[delegateId] = res.exchangeKey;
|
|
76
76
|
}
|
|
77
77
|
for (const [key, params] of Object.entries(keySplitsToUpdate)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShamirKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/ShamirKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { UserEncryptionKeysManager } from './UserEncryptionKeysManager'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\nimport { hex2ua, ua2hex } from '../utils'\nimport { ExchangeDataManager } from './ExchangeDataManager'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { fingerprintV1 } from './utils'\n\n/**\n * Allows to create or update shamir split keys.\n */\nexport class ShamirKeysManager {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly encryptionKeysManager: UserEncryptionKeysManager,\n private readonly exchangeDataManager: ExchangeDataManager\n ) {}\n\n /**\n * Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been\n * split using the Shamir sharing algorithm gives the list of the notaries (other data owners) which hold a copy of the key part.\n * @param dataOwner a data owner\n * @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object\n */\n getExistingSplitsInfo(dataOwner: DataOwnerOrStub): { [keyPairFingerprint: string]: string[] } {\n const legacyPartitionDelegates = Object.keys(dataOwner.privateKeyShamirPartitions ?? {})\n if (legacyPartitionDelegates.length > 0) {\n const fp = dataOwner.publicKey && fingerprintV1(dataOwner.publicKey)\n if (!fp) {\n console.error('Invalid data owner: the owner has legacy key partitions but no legacy key.')\n } else return { [fp]: legacyPartitionDelegates }\n }\n return {}\n }\n\n /**\n * Creates, updates or deletes shamir splits for keys of the current data owner. Any request to update the splits for a specific key will completely\n * replace any existing data on that split (all previous notaries will be ignored).\n * Note: currently you can only split the legacy key pair.\n * @param keySplitsToUpdate the fingerprints of key pairs which will have updated/new splits and the details on how to create the updated splits.\n * @param keySplitsToDelete the fingerprints or hex-encoded spki public keys which will not be shared anymore.\n * @throws if the parameters refer to non-existing or unavailable keys, have split creation details, or if they request to delete a non-existing\n * split.\n */\n async updateSelfSplits(\n keySplitsToUpdate: { [publicKeyHexOrFp: string]: { notariesIds: string[]; minShares: number } },\n keySplitsToDelete: string[]\n ): Promise<CryptoActorStubWithType> {\n const self = CryptoActorStubWithType.fromDataOwner(await this.dataOwnerApi.getCurrentDataOwner())\n const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => fingerprintV1(x)))\n const toDeleteSet = new Set(Object.keys(keySplitsToDelete).map((x) => fingerprintV1(x)))\n const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x))\n const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.stub)))\n const allKeys = this.encryptionKeysManager.getDecryptionKeys()\n if (toDeleteSet.size !== keySplitsToDelete.length || toUpdateSet.size !== Object.keys(keySplitsToUpdate).length || intersection.length > 0)\n throw new Error(`Duplicate keys in input:\\nkeySplitsToUpdate: ${keySplitsToUpdate}\\nkeySplitsToDelete: ${keySplitsToDelete}`)\n Object.entries(keySplitsToUpdate).forEach(([key, params]) => this.validateShamirParams(key, params))\n if (!Array.from(existingSplits).every((x) => existingSplits.has(x))) {\n throw new Error(`Requested to delete non-existing split.\\nexistingSplits: ${Array.from(existingSplits)}\\ntoDelete:${Array.from(toDeleteSet)}`)\n }\n if (Array.from(toUpdateSet).some((x) => !allKeys[x])) {\n throw new Error(`Private key is not available for some of the requested key split updates. ${keySplitsToUpdate}`)\n }\n const delegatesKeys: { [delegateId: string]: CryptoKey } = {}\n let updatedSelf = self\n for (const delegateId of new Set(Object.values(keySplitsToUpdate).flatMap((x) => x.notariesIds))) {\n const res = await this.exchangeDataManager.getOrCreateEncryptionDataTo(delegateId, undefined, undefined, false)\n delegatesKeys[delegateId] = res.exchangeKey\n }\n for (const [key, params] of Object.entries(keySplitsToUpdate)) {\n updatedSelf = await this.updateKeySplit(updatedSelf, fingerprintV1(key), params.notariesIds, params.minShares, delegatesKeys, allKeys)\n }\n for (const keyFp of toDeleteSet) {\n updatedSelf = this.deleteKeySplit(updatedSelf, keyFp)\n }\n return await this.dataOwnerApi.modifyCryptoActorStub(updatedSelf)\n }\n\n /*TODO\n * Get suggested recovery keys: analyse transfer keys and shamir to get keys which should be shared with shamir for optimal recovery.\n */\n\n private validateShamirParams(key: string, params: { notariesIds: string[]; minShares: number }) {\n if (params.notariesIds.length > 0) {\n if (params.minShares > params.notariesIds.length) {\n throw new Error(`Invalid parameters for key ${key}: min shares can't be greater than the number of delegates. ${params}`)\n }\n } else throw new Error(`Invalid parameters for key ${key}: must have at least one delegate. ${params}`)\n }\n\n private deleteKeySplit(dataOwner: CryptoActorStubWithType, keyFp: string): CryptoActorStubWithType {\n if (!dataOwner.stub.publicKey || keyFp !== fingerprintV1(dataOwner.stub.publicKey)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n stub: {\n ...dataOwner.stub,\n privateKeyShamirPartitions: {},\n },\n }\n }\n\n private async updateKeySplit(\n dataOwner: CryptoActorStubWithType,\n keyFp: string,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey },\n allKeys: { [p: string]: KeyPair<CryptoKey> }\n ): Promise<CryptoActorStubWithType> {\n if (!dataOwner.stub.publicKey || keyFp !== fingerprintV1(dataOwner.stub.publicKey)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n stub: {\n ...dataOwner.stub,\n privateKeyShamirPartitions: await this.createPartitionsFor(allKeys[keyFp], delegateIds, minShares, delegatesKeys),\n },\n }\n }\n\n private async createPartitionsFor(\n keyPair: KeyPair<CryptoKey>,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n const exportedKey = await this.primitives.RSA.exportKey(keyPair.privateKey, 'pkcs8')\n if (delegateIds.length == 1) {\n return await this.encryptShares([exportedKey], delegateIds, delegatesKeys)\n } else {\n const exportedKeysHex = ua2hex(exportedKey)\n const stringShares = this.primitives.shamir.share(exportedKeysHex, delegateIds.length, minShares)\n const paddedStringShares = stringShares.map((x) => `f${x}`) // Shares are uneven length, apart from that they are perfect hexes\n for (const share of paddedStringShares) {\n if (!/^(?:[0-9a-f][0-9a-f])+$/g.test(share)) throw new Error('Unexpected result of shamir split: padded shares should be a valid hex value')\n if (share !== ua2hex(hex2ua(share))) throw new Error('Unexpected result with encoding-decoding share')\n }\n return await this.encryptShares(\n paddedStringShares.map((x) => hex2ua(x)),\n delegateIds,\n delegatesKeys\n )\n }\n }\n\n private async encryptShares(\n shares: ArrayBuffer[],\n delegateIds: string[],\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n return delegateIds.reduce(\n async (acc, delegateId, index) => ({\n ...(await acc),\n [delegateId]: ua2hex(await this.primitives.AES.encrypt(delegatesKeys[delegateId], shares[index])),\n }),\n Promise.resolve({} as { [delegateId: string]: string })\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ShamirKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/ShamirKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { UserEncryptionKeysManager } from './UserEncryptionKeysManager'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\nimport { hex2ua, ua2hex } from '../utils'\nimport { ExchangeDataManager } from './ExchangeDataManager'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { fingerprintV1 } from './utils'\n\n/**\n * Allows to create or update shamir split keys.\n */\nexport class ShamirKeysManager {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly encryptionKeysManager: UserEncryptionKeysManager,\n private readonly exchangeDataManager: ExchangeDataManager\n ) {}\n\n /**\n * Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been\n * split using the Shamir sharing algorithm gives the list of the notaries (other data owners) which hold a copy of the key part.\n * @param dataOwner a data owner\n * @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object\n */\n getExistingSplitsInfo(dataOwner: DataOwnerOrStub): { [keyPairFingerprint: string]: string[] } {\n const legacyPartitionDelegates = Object.keys(dataOwner.privateKeyShamirPartitions ?? {})\n if (legacyPartitionDelegates.length > 0) {\n const fp = dataOwner.publicKey && fingerprintV1(dataOwner.publicKey)\n if (!fp) {\n console.error('Invalid data owner: the owner has legacy key partitions but no legacy key.')\n } else return { [fp]: legacyPartitionDelegates }\n }\n return {}\n }\n\n /**\n * Creates, updates or deletes shamir splits for keys of the current data owner. Any request to update the splits for a specific key will completely\n * replace any existing data on that split (all previous notaries will be ignored).\n * Note: currently you can only split the legacy key pair.\n * @param keySplitsToUpdate the fingerprints of key pairs which will have updated/new splits and the details on how to create the updated splits.\n * @param keySplitsToDelete the fingerprints or hex-encoded spki public keys which will not be shared anymore.\n * @throws if the parameters refer to non-existing or unavailable keys, have split creation details, or if they request to delete a non-existing\n * split.\n */\n async updateSelfSplits(\n keySplitsToUpdate: { [publicKeyHexOrFp: string]: { notariesIds: string[]; minShares: number } },\n keySplitsToDelete: string[]\n ): Promise<CryptoActorStubWithType> {\n const self = CryptoActorStubWithType.fromDataOwner(await this.dataOwnerApi.getCurrentDataOwner())\n const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => fingerprintV1(x)))\n const toDeleteSet = new Set(Object.keys(keySplitsToDelete).map((x) => fingerprintV1(x)))\n const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x))\n const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.stub)))\n const allKeys = this.encryptionKeysManager.getDecryptionKeys()\n if (toDeleteSet.size !== keySplitsToDelete.length || toUpdateSet.size !== Object.keys(keySplitsToUpdate).length || intersection.length > 0)\n throw new Error(`Duplicate keys in input:\\nkeySplitsToUpdate: ${keySplitsToUpdate}\\nkeySplitsToDelete: ${keySplitsToDelete}`)\n Object.entries(keySplitsToUpdate).forEach(([key, params]) => this.validateShamirParams(key, params))\n if (!Array.from(existingSplits).every((x) => existingSplits.has(x))) {\n throw new Error(`Requested to delete non-existing split.\\nexistingSplits: ${Array.from(existingSplits)}\\ntoDelete:${Array.from(toDeleteSet)}`)\n }\n if (Array.from(toUpdateSet).some((x) => !allKeys[x])) {\n throw new Error(`Private key is not available for some of the requested key split updates. ${keySplitsToUpdate}`)\n }\n const delegatesKeys: { [delegateId: string]: CryptoKey } = {}\n let updatedSelf = self\n for (const delegateId of new Set(Object.values(keySplitsToUpdate).flatMap((x) => x.notariesIds))) {\n const res = await this.exchangeDataManager.getOrCreateEncryptionDataTo(delegateId, false)\n delegatesKeys[delegateId] = res.exchangeKey\n }\n for (const [key, params] of Object.entries(keySplitsToUpdate)) {\n updatedSelf = await this.updateKeySplit(updatedSelf, fingerprintV1(key), params.notariesIds, params.minShares, delegatesKeys, allKeys)\n }\n for (const keyFp of toDeleteSet) {\n updatedSelf = this.deleteKeySplit(updatedSelf, keyFp)\n }\n return await this.dataOwnerApi.modifyCryptoActorStub(updatedSelf)\n }\n\n /*TODO\n * Get suggested recovery keys: analyse transfer keys and shamir to get keys which should be shared with shamir for optimal recovery.\n */\n\n private validateShamirParams(key: string, params: { notariesIds: string[]; minShares: number }) {\n if (params.notariesIds.length > 0) {\n if (params.minShares > params.notariesIds.length) {\n throw new Error(`Invalid parameters for key ${key}: min shares can't be greater than the number of delegates. ${params}`)\n }\n } else throw new Error(`Invalid parameters for key ${key}: must have at least one delegate. ${params}`)\n }\n\n private deleteKeySplit(dataOwner: CryptoActorStubWithType, keyFp: string): CryptoActorStubWithType {\n if (!dataOwner.stub.publicKey || keyFp !== fingerprintV1(dataOwner.stub.publicKey)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n stub: {\n ...dataOwner.stub,\n privateKeyShamirPartitions: {},\n },\n }\n }\n\n private async updateKeySplit(\n dataOwner: CryptoActorStubWithType,\n keyFp: string,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey },\n allKeys: { [p: string]: KeyPair<CryptoKey> }\n ): Promise<CryptoActorStubWithType> {\n if (!dataOwner.stub.publicKey || keyFp !== fingerprintV1(dataOwner.stub.publicKey)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n stub: {\n ...dataOwner.stub,\n privateKeyShamirPartitions: await this.createPartitionsFor(allKeys[keyFp], delegateIds, minShares, delegatesKeys),\n },\n }\n }\n\n private async createPartitionsFor(\n keyPair: KeyPair<CryptoKey>,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n const exportedKey = await this.primitives.RSA.exportKey(keyPair.privateKey, 'pkcs8')\n if (delegateIds.length == 1) {\n return await this.encryptShares([exportedKey], delegateIds, delegatesKeys)\n } else {\n const exportedKeysHex = ua2hex(exportedKey)\n const stringShares = this.primitives.shamir.share(exportedKeysHex, delegateIds.length, minShares)\n const paddedStringShares = stringShares.map((x) => `f${x}`) // Shares are uneven length, apart from that they are perfect hexes\n for (const share of paddedStringShares) {\n if (!/^(?:[0-9a-f][0-9a-f])+$/g.test(share)) throw new Error('Unexpected result of shamir split: padded shares should be a valid hex value')\n if (share !== ua2hex(hex2ua(share))) throw new Error('Unexpected result with encoding-decoding share')\n }\n return await this.encryptShares(\n paddedStringShares.map((x) => hex2ua(x)),\n delegateIds,\n delegatesKeys\n )\n }\n }\n\n private async encryptShares(\n shares: ArrayBuffer[],\n delegateIds: string[],\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n return delegateIds.reduce(\n async (acc, delegateId, index) => ({\n ...(await acc),\n [delegateId]: ua2hex(await this.primitives.AES.encrypt(delegatesKeys[delegateId], shares[index])),\n }),\n Promise.resolve({} as { [delegateId: string]: string })\n )\n }\n}\n"]}
|
|
@@ -3,7 +3,6 @@ import { UserEncryptionKeysManager } from './UserEncryptionKeysManager';
|
|
|
3
3
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
4
4
|
import { IcureStorageFacade } from '../storage/IcureStorageFacade';
|
|
5
5
|
import { BaseExchangeDataManager } from './BaseExchangeDataManager';
|
|
6
|
-
import { UserSignatureKeysManager } from './UserSignatureKeysManager';
|
|
7
6
|
import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
8
7
|
/**
|
|
9
8
|
* @internal this class is intended only for internal use and may be changed without notice.
|
|
@@ -14,9 +13,8 @@ export declare class TransferKeysManager {
|
|
|
14
13
|
private readonly baseExchangeDataManager;
|
|
15
14
|
private readonly dataOwnerApi;
|
|
16
15
|
private readonly encryptionKeysManager;
|
|
17
|
-
private readonly userSignatureKeysManager;
|
|
18
16
|
private readonly icureStorage;
|
|
19
|
-
constructor(primitives: CryptoPrimitives, baseExchangeDataManager: BaseExchangeDataManager, dataOwnerApi: IccDataOwnerXApi, encryptionKeysManager: UserEncryptionKeysManager,
|
|
17
|
+
constructor(primitives: CryptoPrimitives, baseExchangeDataManager: BaseExchangeDataManager, dataOwnerApi: IccDataOwnerXApi, encryptionKeysManager: UserEncryptionKeysManager, icureStorage: IcureStorageFacade);
|
|
20
18
|
/**
|
|
21
19
|
* Analyses the transfer keys graph and creates new transfer keys which allow to improve data accessibility from other devices.
|
|
22
20
|
* For security reasons transfer keys will only be created between keys verified by the user, but this will be done ignoring any existing edges from
|
|
@@ -19,12 +19,11 @@ const utils_2 = require("./utils");
|
|
|
19
19
|
* Allows to create new transfer keys.
|
|
20
20
|
*/
|
|
21
21
|
class TransferKeysManager {
|
|
22
|
-
constructor(primitives, baseExchangeDataManager, dataOwnerApi, encryptionKeysManager,
|
|
22
|
+
constructor(primitives, baseExchangeDataManager, dataOwnerApi, encryptionKeysManager, icureStorage) {
|
|
23
23
|
this.primitives = primitives;
|
|
24
24
|
this.baseExchangeDataManager = baseExchangeDataManager;
|
|
25
25
|
this.dataOwnerApi = dataOwnerApi;
|
|
26
26
|
this.encryptionKeysManager = encryptionKeysManager;
|
|
27
|
-
this.userSignatureKeysManager = userSignatureKeysManager;
|
|
28
27
|
this.icureStorage = icureStorage;
|
|
29
28
|
}
|
|
30
29
|
/**
|
|
@@ -43,14 +42,13 @@ class TransferKeysManager {
|
|
|
43
42
|
const selfId = self.stub.id;
|
|
44
43
|
const fpToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub, RSA_1.ShaVersion.Sha1);
|
|
45
44
|
const fpToPublicKeyWithSha256 = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub, RSA_1.ShaVersion.Sha256);
|
|
46
|
-
const signatureKeyPair = yield this.userSignatureKeysManager.getOrCreateSignatureKeyPair();
|
|
47
45
|
const verifiedFps = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint));
|
|
48
46
|
const allVerifiedSourcesAndTarget = Array.from(new Set(newEdgesByTarget.flatMap((x) =>
|
|
49
47
|
// Sources are guaranteed to be verified, but target may not be
|
|
50
48
|
verifiedFps.has(x.targetFp) ? [x.targetFp, ...x.sources] : x.sources)));
|
|
51
49
|
const newExchangeKeyPublicKeys = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKey[fp]).filter((key) => !!key);
|
|
52
50
|
const newExchangeKeyPublicKeysWithSha256 = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKeyWithSha256[fp]).filter((key) => !!key);
|
|
53
|
-
const createdExchangeData = yield this.baseExchangeDataManager.createExchangeData(selfId,
|
|
51
|
+
const createdExchangeData = yield this.baseExchangeDataManager.createExchangeData(selfId, Object.fromEntries(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => [x.fingerprint, x.pair.privateKey])), Object.assign(Object.assign({}, (yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, newExchangeKeyPublicKeys, RSA_1.ShaVersion.Sha1))), (yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, newExchangeKeyPublicKeysWithSha256, RSA_1.ShaVersion.Sha256))));
|
|
54
52
|
let updatedTransferKeys = (_a = self.stub.transferKeys) !== null && _a !== void 0 ? _a : {};
|
|
55
53
|
for (const newEdges of newEdgesByTarget) {
|
|
56
54
|
const encryptedTransferKey = yield this.encryptTransferKey(newEdges.target, createdExchangeData.exchangeKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransferKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/TransferKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair, ShaVersion } from './RSA'\nimport { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { ua2hex } from '../utils'\nimport { UserEncryptionKeysManager } from './UserEncryptionKeysManager'\nimport { reachSetsAcyclic, StronglyConnectedGraph } from '../utils/graph-utils'\nimport { fingerprintToPublicKeysMapOf, fingerprintV1, loadPublicKeys, transferKeysFpGraphOf, fingerprintIsV1, fingerprintV1toV2 } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\nimport { BaseExchangeDataManager } from './BaseExchangeDataManager'\nimport { UserSignatureKeysManager } from './UserSignatureKeysManager'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n * Allows to create new transfer keys.\n */\nexport class TransferKeysManager {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly baseExchangeDataManager: BaseExchangeDataManager,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly encryptionKeysManager: UserEncryptionKeysManager,\n private readonly userSignatureKeysManager: UserSignatureKeysManager,\n private readonly icureStorage: IcureStorageFacade\n ) {}\n\n /**\n * Analyses the transfer keys graph and creates new transfer keys which allow to improve data accessibility from other devices.\n * For security reasons transfer keys will only be created between keys verified by the user, but this will be done ignoring any existing edges from\n * unverified keys to verified keys.\n * @param self the current data owner.\n * @return the updated data owner.\n */\n async updateTransferKeys(self: CryptoActorStubWithType): Promise<void> {\n const newEdgesByTarget = await this.getNewVerifiedTransferKeysEdges(self)\n if (!newEdgesByTarget.length) return\n const selfId = self.stub.id!\n const fpToPublicKey = fingerprintToPublicKeysMapOf(self.stub, ShaVersion.Sha1)\n const fpToPublicKeyWithSha256 = fingerprintToPublicKeysMapOf(self.stub, ShaVersion.Sha256)\n const signatureKeyPair = await this.userSignatureKeysManager.getOrCreateSignatureKeyPair()\n const verifiedFps = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n const allVerifiedSourcesAndTarget = Array.from(\n new Set(\n newEdgesByTarget.flatMap((x) =>\n // Sources are guaranteed to be verified, but target may not be\n verifiedFps.has(x.targetFp) ? [x.targetFp, ...x.sources] : x.sources\n )\n )\n )\n const newExchangeKeyPublicKeys = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKey[fp]).filter((key) => !!key)\n const newExchangeKeyPublicKeysWithSha256 = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKeyWithSha256[fp]).filter((key) => !!key)\n const createdExchangeData = await this.baseExchangeDataManager.createExchangeData(\n selfId,\n { [signatureKeyPair.fingerprint]: signatureKeyPair.keyPair.privateKey },\n {\n ...(await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeys, ShaVersion.Sha1)),\n ...(await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeysWithSha256, ShaVersion.Sha256)),\n }\n )\n let updatedTransferKeys = self.stub.transferKeys ?? {}\n for (const newEdges of newEdgesByTarget) {\n const encryptedTransferKey = await this.encryptTransferKey(newEdges.target, createdExchangeData.exchangeKey)\n updatedTransferKeys = newEdges.sources.reduce((acc, candidateFp) => {\n const existingKeys = { ...(acc[candidateFp] ?? {}) }\n existingKeys[newEdges.targetFp] = encryptedTransferKey\n acc[candidateFp] = existingKeys\n return acc\n }, updatedTransferKeys)\n }\n await this.dataOwnerApi.modifyCryptoActorStub({\n stub: {\n ...self.stub,\n transferKeys: updatedTransferKeys,\n },\n type: self.type,\n })\n }\n\n // encrypts a transfer key in pkcs8 format using an exchange key, returns the hex representation\n private async encryptTransferKey(transferKey: KeyPair<CryptoKey>, exchangeKey: CryptoKey): Promise<string> {\n const exportedKey = await this.primitives.RSA.exportKey(transferKey.privateKey, 'pkcs8')\n return ua2hex(await this.primitives.AES.encrypt(exchangeKey, exportedKey))\n }\n\n // all public keys would go to the stored keys -> no need for specifying the key.\n // Result only includes the acyclic label, not the full group\n private transferKeysCandidatesFp(keyToFp: string, graph: StronglyConnectedGraph): string[] {\n return Object.entries(reachSetsAcyclic(graph.acyclicGraph))\n .filter(([from, reachable]) => {\n const currGroup = graph.acyclicLabelToGroup[from] ?? [from]\n const reachableOriginal = new Set(Array.from(reachable).flatMap((x) => graph.acyclicLabelToGroup[x] ?? [x]))\n return !currGroup.includes(keyToFp) && !reachableOriginal.has(keyToFp)\n })\n .map((x) => x[0])\n }\n\n private async transferTargetKeys(\n keyManager: UserEncryptionKeysManager,\n graph: StronglyConnectedGraph\n ): Promise<{ fingerprint: string; pair: KeyPair<CryptoKey> }[]> {\n const availableGroups = new Set(Object.keys(keyManager.getDecryptionKeys()).map((x) => graph.originalLabelToAcyclicLabel[x] ?? x))\n const groupsReachableFromAvailable = new Set(\n Object.entries(graph.acyclicGraph).flatMap(([source, reachables]) => (availableGroups.has(source) ? Array.from(reachables) : []))\n )\n const targetCandidates = Array.from(availableGroups).filter((x) => !groupsReachableFromAvailable.has(x))\n const verifiedFps = new Set(keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n return targetCandidates.map((candidateFp) => {\n const candidateGroup = graph.acyclicLabelToGroup[candidateFp] ?? [candidateFp] // May not be part of transfer keys graph yet\n const bestCandidateOfGroup = candidateGroup.find((x) => verifiedFps.has(x)) ?? candidateFp\n return { fingerprint: bestCandidateOfGroup, pair: keyManager.getKeyPairForFingerprint(bestCandidateOfGroup)!.pair }\n })\n }\n\n // Decides the best edges considering the verified public keys.\n private async getNewVerifiedTransferKeysEdges(self: CryptoActorStubWithType): Promise<\n {\n sources: string[]\n target: KeyPair<CryptoKey>\n targetFp: string\n }[]\n > {\n const verifiedKeysFpSet = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(self.stub.id!)).forEach(([key, verified]) => {\n if (verified) verifiedKeysFpSet.add(fingerprintV1(key))\n })\n if (verifiedKeysFpSet.size == 0) return []\n const graph = transferKeysFpGraphOf(self.stub)\n // 1. Choose keys available in this device which should be reachable from all other verified keys\n const targetKeys = await this.transferTargetKeys(this.encryptionKeysManager, graph)\n const res = []\n for (const { fingerprint: targetKeyFp, pair: targetKey } of targetKeys) {\n // 2. Find groups which can't reach the existing target keys\n const candidatesFp = this.transferKeysCandidatesFp(targetKeyFp, graph)\n // 3. Keep only groups which contain at least a verified candidate\n const verifiedGroupCandidates = candidatesFp.filter((candidate) =>\n graph.acyclicLabelToGroup[candidate].some((candidateGroupMember) => verifiedKeysFpSet.has(candidateGroupMember))\n )\n const verifiedCandidatesSet = new Set(verifiedGroupCandidates)\n if (verifiedCandidatesSet.size == 0) continue\n // 4. Drop all candidates which can already reach another candidate group: it is sufficient to create a transfer key from that group.\n const reachSets = reachSetsAcyclic(graph.acyclicGraph)\n const optimizedCandidates = verifiedGroupCandidates.filter((candidate) =>\n Array.from(reachSets[candidate]).every((reachableNode) => !verifiedCandidatesSet.has(reachableNode))\n )\n if (optimizedCandidates.length == 0) throw new Error('Check failed: at least one candidate should survive optimization')\n // 5. Transfer keys could also be faked: to make sure we are not giving access to unauthorised people we remap the candidates to a verified public\n // keys\n const verifiedOptimizedCandidates = optimizedCandidates.map((candidate) => {\n const res = graph.acyclicLabelToGroup[candidate].find((groupMemberFp) => verifiedKeysFpSet.has(groupMemberFp))\n if (!res) throw new Error('Check failed: optimized candidates groups should have at least a verified member')\n return res\n })\n res.push({\n sources: verifiedOptimizedCandidates,\n target: targetKey,\n targetFp: targetKeyFp,\n })\n }\n return res\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TransferKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/TransferKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair, ShaVersion } from './RSA'\nimport { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { ua2hex } from '../utils'\nimport { UserEncryptionKeysManager } from './UserEncryptionKeysManager'\nimport { reachSetsAcyclic, StronglyConnectedGraph } from '../utils/graph-utils'\nimport { fingerprintToPublicKeysMapOf, fingerprintV1, loadPublicKeys, transferKeysFpGraphOf, fingerprintIsV1, fingerprintV1toV2 } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\nimport { BaseExchangeDataManager } from './BaseExchangeDataManager'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n * Allows to create new transfer keys.\n */\nexport class TransferKeysManager {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly baseExchangeDataManager: BaseExchangeDataManager,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly encryptionKeysManager: UserEncryptionKeysManager,\n private readonly icureStorage: IcureStorageFacade\n ) {}\n\n /**\n * Analyses the transfer keys graph and creates new transfer keys which allow to improve data accessibility from other devices.\n * For security reasons transfer keys will only be created between keys verified by the user, but this will be done ignoring any existing edges from\n * unverified keys to verified keys.\n * @param self the current data owner.\n * @return the updated data owner.\n */\n async updateTransferKeys(self: CryptoActorStubWithType): Promise<void> {\n const newEdgesByTarget = await this.getNewVerifiedTransferKeysEdges(self)\n if (!newEdgesByTarget.length) return\n const selfId = self.stub.id!\n const fpToPublicKey = fingerprintToPublicKeysMapOf(self.stub, ShaVersion.Sha1)\n const fpToPublicKeyWithSha256 = fingerprintToPublicKeysMapOf(self.stub, ShaVersion.Sha256)\n const verifiedFps = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n const allVerifiedSourcesAndTarget = Array.from(\n new Set(\n newEdgesByTarget.flatMap((x) =>\n // Sources are guaranteed to be verified, but target may not be\n verifiedFps.has(x.targetFp) ? [x.targetFp, ...x.sources] : x.sources\n )\n )\n )\n const newExchangeKeyPublicKeys = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKey[fp]).filter((key) => !!key)\n const newExchangeKeyPublicKeysWithSha256 = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKeyWithSha256[fp]).filter((key) => !!key)\n const createdExchangeData = await this.baseExchangeDataManager.createExchangeData(\n selfId,\n Object.fromEntries(this.encryptionKeysManager.getSelfVerifiedKeys().map((x): [string, CryptoKey] => [x.fingerprint, x.pair.privateKey])),\n {\n ...(await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeys, ShaVersion.Sha1)),\n ...(await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeysWithSha256, ShaVersion.Sha256)),\n }\n )\n let updatedTransferKeys = self.stub.transferKeys ?? {}\n for (const newEdges of newEdgesByTarget) {\n const encryptedTransferKey = await this.encryptTransferKey(newEdges.target, createdExchangeData.exchangeKey)\n updatedTransferKeys = newEdges.sources.reduce((acc, candidateFp) => {\n const existingKeys = { ...(acc[candidateFp] ?? {}) }\n existingKeys[newEdges.targetFp] = encryptedTransferKey\n acc[candidateFp] = existingKeys\n return acc\n }, updatedTransferKeys)\n }\n await this.dataOwnerApi.modifyCryptoActorStub({\n stub: {\n ...self.stub,\n transferKeys: updatedTransferKeys,\n },\n type: self.type,\n })\n }\n\n // encrypts a transfer key in pkcs8 format using an exchange key, returns the hex representation\n private async encryptTransferKey(transferKey: KeyPair<CryptoKey>, exchangeKey: CryptoKey): Promise<string> {\n const exportedKey = await this.primitives.RSA.exportKey(transferKey.privateKey, 'pkcs8')\n return ua2hex(await this.primitives.AES.encrypt(exchangeKey, exportedKey))\n }\n\n // all public keys would go to the stored keys -> no need for specifying the key.\n // Result only includes the acyclic label, not the full group\n private transferKeysCandidatesFp(keyToFp: string, graph: StronglyConnectedGraph): string[] {\n return Object.entries(reachSetsAcyclic(graph.acyclicGraph))\n .filter(([from, reachable]) => {\n const currGroup = graph.acyclicLabelToGroup[from] ?? [from]\n const reachableOriginal = new Set(Array.from(reachable).flatMap((x) => graph.acyclicLabelToGroup[x] ?? [x]))\n return !currGroup.includes(keyToFp) && !reachableOriginal.has(keyToFp)\n })\n .map((x) => x[0])\n }\n\n private async transferTargetKeys(\n keyManager: UserEncryptionKeysManager,\n graph: StronglyConnectedGraph\n ): Promise<{ fingerprint: string; pair: KeyPair<CryptoKey> }[]> {\n const availableGroups = new Set(Object.keys(keyManager.getDecryptionKeys()).map((x) => graph.originalLabelToAcyclicLabel[x] ?? x))\n const groupsReachableFromAvailable = new Set(\n Object.entries(graph.acyclicGraph).flatMap(([source, reachables]) => (availableGroups.has(source) ? Array.from(reachables) : []))\n )\n const targetCandidates = Array.from(availableGroups).filter((x) => !groupsReachableFromAvailable.has(x))\n const verifiedFps = new Set(keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n return targetCandidates.map((candidateFp) => {\n const candidateGroup = graph.acyclicLabelToGroup[candidateFp] ?? [candidateFp] // May not be part of transfer keys graph yet\n const bestCandidateOfGroup = candidateGroup.find((x) => verifiedFps.has(x)) ?? candidateFp\n return { fingerprint: bestCandidateOfGroup, pair: keyManager.getKeyPairForFingerprint(bestCandidateOfGroup)!.pair }\n })\n }\n\n // Decides the best edges considering the verified public keys.\n private async getNewVerifiedTransferKeysEdges(self: CryptoActorStubWithType): Promise<\n {\n sources: string[]\n target: KeyPair<CryptoKey>\n targetFp: string\n }[]\n > {\n const verifiedKeysFpSet = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(self.stub.id!)).forEach(([key, verified]) => {\n if (verified) verifiedKeysFpSet.add(fingerprintV1(key))\n })\n if (verifiedKeysFpSet.size == 0) return []\n const graph = transferKeysFpGraphOf(self.stub)\n // 1. Choose keys available in this device which should be reachable from all other verified keys\n const targetKeys = await this.transferTargetKeys(this.encryptionKeysManager, graph)\n const res = []\n for (const { fingerprint: targetKeyFp, pair: targetKey } of targetKeys) {\n // 2. Find groups which can't reach the existing target keys\n const candidatesFp = this.transferKeysCandidatesFp(targetKeyFp, graph)\n // 3. Keep only groups which contain at least a verified candidate\n const verifiedGroupCandidates = candidatesFp.filter((candidate) =>\n graph.acyclicLabelToGroup[candidate].some((candidateGroupMember) => verifiedKeysFpSet.has(candidateGroupMember))\n )\n const verifiedCandidatesSet = new Set(verifiedGroupCandidates)\n if (verifiedCandidatesSet.size == 0) continue\n // 4. Drop all candidates which can already reach another candidate group: it is sufficient to create a transfer key from that group.\n const reachSets = reachSetsAcyclic(graph.acyclicGraph)\n const optimizedCandidates = verifiedGroupCandidates.filter((candidate) =>\n Array.from(reachSets[candidate]).every((reachableNode) => !verifiedCandidatesSet.has(reachableNode))\n )\n if (optimizedCandidates.length == 0) throw new Error('Check failed: at least one candidate should survive optimization')\n // 5. Transfer keys could also be faked: to make sure we are not giving access to unauthorised people we remap the candidates to a verified public\n // keys\n const verifiedOptimizedCandidates = optimizedCandidates.map((candidate) => {\n const res = graph.acyclicLabelToGroup[candidate].find((groupMemberFp) => verifiedKeysFpSet.has(groupMemberFp))\n if (!res) throw new Error('Check failed: optimized candidates groups should have at least a verified member')\n return res\n })\n res.push({\n sources: verifiedOptimizedCandidates,\n target: targetKey,\n targetFp: targetKeyFp,\n })\n }\n return res\n }\n}\n"]}
|
|
@@ -5,13 +5,13 @@ import { AccessLog, ListOfIds, PaginatedListAccessLog } from '../icc-api/model/m
|
|
|
5
5
|
import { IccDataOwnerXApi } from './icc-data-owner-x-api';
|
|
6
6
|
import { AuthenticationProvider } from './auth/AuthenticationProvider';
|
|
7
7
|
import { SecureDelegation } from '../icc-api/model/SecureDelegation';
|
|
8
|
-
import AccessLevelEnum = SecureDelegation.AccessLevelEnum;
|
|
9
8
|
import { ShareMetadataBehaviour } from './crypto/ShareMetadataBehaviour';
|
|
10
9
|
import { EntityShareRequest } from '../icc-api/model/requests/EntityShareRequest';
|
|
11
|
-
import RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum;
|
|
12
10
|
import { ShareResult } from './utils/ShareResult';
|
|
13
11
|
import { XHR } from '../icc-api/api/XHR';
|
|
14
12
|
import { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi';
|
|
13
|
+
import AccessLevelEnum = SecureDelegation.AccessLevelEnum;
|
|
14
|
+
import RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum;
|
|
15
15
|
export interface AccessLogWithPatientId extends AccessLog {
|
|
16
16
|
patientId: string;
|
|
17
17
|
}
|
|
@@ -15,8 +15,8 @@ const models_1 = require("../icc-api/model/models");
|
|
|
15
15
|
const _ = require("lodash");
|
|
16
16
|
const AuthenticationProvider_1 = require("./auth/AuthenticationProvider");
|
|
17
17
|
const SecureDelegation_1 = require("../icc-api/model/SecureDelegation");
|
|
18
|
-
var AccessLevelEnum = SecureDelegation_1.SecureDelegation.AccessLevelEnum;
|
|
19
18
|
const utils_1 = require("./utils");
|
|
19
|
+
var AccessLevelEnum = SecureDelegation_1.SecureDelegation.AccessLevelEnum;
|
|
20
20
|
class IccAccesslogXApi extends icc_api_1.IccAccesslogApi {
|
|
21
21
|
get headers() {
|
|
22
22
|
return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, utils_1.EntityWithDelegationTypeName.AccessLog));
|
|
@@ -123,14 +123,18 @@ class IccAccesslogXApi extends icc_api_1.IccAccesslogApi {
|
|
|
123
123
|
return super.findAccessLogsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys).then((accesslogs) => this.decrypt(hcPartyId, accesslogs));
|
|
124
124
|
}
|
|
125
125
|
decrypt(hcpId, accessLogs) {
|
|
126
|
-
return
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
return (yield this.crypto.xapi.tryDecryptEntities(accessLogs, utils_1.EntityWithDelegationTypeName.AccessLog, (json) => new models_1.AccessLog(json))).map(({ entity }) => entity);
|
|
128
|
+
});
|
|
127
129
|
}
|
|
128
130
|
encrypt(user, accessLogs) {
|
|
129
131
|
const owner = this.dataOwnerApi.getDataOwnerIdOf(user);
|
|
130
132
|
return this.encryptAs(owner, accessLogs);
|
|
131
133
|
}
|
|
132
134
|
encryptAs(dataOwner, accessLogs) {
|
|
133
|
-
return
|
|
135
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
return this.crypto.xapi.tryEncryptEntities(accessLogs, utils_1.EntityWithDelegationTypeName.AccessLog, this.encryptedFields, false, false, (json) => new models_1.AccessLog(json));
|
|
137
|
+
});
|
|
134
138
|
}
|
|
135
139
|
createAccessLog(body) {
|
|
136
140
|
throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icc-accesslog-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-accesslog-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccAccesslogApi } from '../icc-api'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\nimport * as models from '../icc-api/model/models'\nimport { AccessLog, ListOfIds, PaginatedListAccessLog } from '../icc-api/model/models'\nimport * as _ from 'lodash'\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 { EntityShareRequest } from '../icc-api/model/requests/EntityShareRequest'\nimport RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum\nimport { ShareResult } from './utils/ShareResult'\nimport { XHR } from '../icc-api/api/XHR'\nimport { EncryptedFieldsManifest, EntityWithDelegationTypeName, parseEncryptedFields } from './utils'\nimport { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi'\n\nexport interface AccessLogWithPatientId extends AccessLog {\n patientId: string\n}\n\nexport class IccAccesslogXApi extends IccAccesslogApi implements EncryptedEntityXApi<models.AccessLog> {\n private readonly encryptedFields: EncryptedFieldsManifest\n crypto: IccCryptoXApi\n dataOwnerApi: IccDataOwnerXApi\n\n get headers(): Promise<Array<XHR.Header>> {\n return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, EntityWithDelegationTypeName.AccessLog))\n }\n\n constructor(\n host: string,\n headers: { [key: string]: string },\n crypto: IccCryptoXApi,\n dataOwnerApi: IccDataOwnerXApi,\n private readonly autofillAuthor: boolean,\n cryptedKeys = ['detail', 'objectId'],\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.encryptedFields = parseEncryptedFields(cryptedKeys, 'AccessLog.')\n }\n\n /**\n * Creates a new instance of access log with initialised encryption metadata (not in the database).\n * @param user the current user.\n * @param patient the patient this access log refers to.\n * @param h initialised data for the access log. 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 access log. The default value will be a\n * secret id of patient known by the topmost parent in the current data owner hierarchy.\n * @return a new instance of access log.\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 } = {}\n ) {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n\n const accessLog = {\n ...(h ?? {}),\n _type: 'org.taktik.icure.entities.AccessLog',\n id: h?.id ?? this.crypto.primitives.randomUuid(),\n created: h?.created ?? new Date().getTime(),\n modified: h?.modified ?? new Date().getTime(),\n date: h?.date ?? new Date().getTime(),\n responsible: h?.responsible ?? (this.autofillAuthor ? dataOwnerId : undefined),\n author: h?.author ?? (this.autofillAuthor ? user.id : undefined),\n codes: h?.codes ?? [],\n tags: h?.tags ?? [],\n user: h?.user ?? user.id,\n patientId: h?.patientId ?? patient.id,\n accessType: h?.accessType ?? 'USER_ACCESS',\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 (await this.crypto.confidential.getAnySecretIdSharedWithParents({ entity: patient, type: EntityWithDelegationTypeName.Patient }))\n if (!sfk) throw new Error(`Couldn't find any sfk of parent patient ${patient.id}`)\n const extraDelegations = {\n ...Object.fromEntries(\n [...(user.autoDelegations?.all ?? []), ...(user.autoDelegations?.administrativeData ?? [])].map((x) => [x, AccessLevelEnum.WRITE])\n ),\n ...(options.additionalDelegates ?? {}),\n }\n return new AccessLog(\n await this.crypto.xapi\n .entityWithInitialisedEncryptedMetadata(accessLog, EntityWithDelegationTypeName.AccessLog, patient.id, sfk, true, extraDelegations)\n .then((x) => x.updatedEntity)\n )\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 access logs with (allSecretForeignKeysDelimitedByComma, hcpartyId)\n *\n * After these painful steps, you have the access logs of the patient.\n *\n * @deprecated use {@link findIdsBy} instead\n * @param hcpartyId\n * @param patient (Promise)\n * @param usingPost\n */\n async findBy(hcpartyId: string, patient: models.Patient, usingPost: boolean = false): Promise<models.AccessLog[]> {\n const extractedKeys = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, hcpartyId)\n const topmostParentId = (await this.dataOwnerApi.getCurrentDataOwnerHierarchyIds())[0]\n return extractedKeys && extractedKeys.length > 0\n ? usingPost\n ? this.findByHCPartyPatientSecretFKeysArray(hcpartyId!, _.uniq(extractedKeys))\n : this.findByHCPartyPatientSecretFKeys(hcpartyId!, _.uniq(extractedKeys).join(','))\n : Promise.resolve([])\n }\n\n /**\n * Same as `findBy` but it will only return the ids of the access logs. It can also filter the access logs where AccessLog.date is between\n * startDate and endDate in ascending or descending order by that field. (default: ascending).\n */\n async findIdsBy(hcpartyId: string, patient: models.Patient, startDate?: number, endDate?: number, descending?: boolean): Promise<string[]> {\n const extractedKeys = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, hcpartyId)\n return extractedKeys && extractedKeys.length > 0\n ? this.findAccessLogIdsByDataOwnerPatientDate(hcpartyId, _.uniq(extractedKeys), startDate, endDate, descending)\n : Promise.resolve([])\n }\n\n /**\n * @deprecated use {@link findAccessLogIdsByDataOwnerPatientDate} instead\n */\n async findByHCPartyPatientSecretFKeys(hcPartyId: string, secretFKeys: string): Promise<AccessLog[]> {\n const accessLogs = await super.findAccessLogsByHCPartyPatientForeignKeys(hcPartyId, secretFKeys)\n return await this.decrypt(hcPartyId, accessLogs)\n }\n\n /**\n * @deprecated use {@link findAccessLogIdsByDataOwnerPatientDate} instead\n */\n findByHCPartyPatientSecretFKeysArray(hcPartyId: string, secretFKeys: string[]): Promise<Array<AccessLog> | any> {\n return super.findAccessLogsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys).then((accesslogs) => this.decrypt(hcPartyId, accesslogs))\n }\n\n decrypt(hcpId: string, accessLogs: Array<models.AccessLog>): Promise<Array<models.AccessLog>> {\n return Promise.all(\n accessLogs.map((x) =>\n this.crypto.xapi.decryptEntity(x, EntityWithDelegationTypeName.AccessLog, (json) => new AccessLog(json)).then(({ entity }) => entity)\n )\n )\n }\n\n encrypt(user: models.User, accessLogs: Array<models.AccessLog>): Promise<Array<models.AccessLog>> {\n const owner = this.dataOwnerApi.getDataOwnerIdOf(user)\n return this.encryptAs(owner, accessLogs)\n }\n\n private encryptAs(dataOwner: string, accessLogs: Array<models.AccessLog>): Promise<Array<models.AccessLog>> {\n return Promise.all(\n accessLogs.map((x) =>\n this.crypto.xapi.tryEncryptEntity(\n x,\n EntityWithDelegationTypeName.AccessLog,\n this.encryptedFields,\n false,\n false,\n (json) => new AccessLog(json)\n )\n )\n )\n }\n\n createAccessLog(body?: models.AccessLog): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n createAccessLogWithUser(user: models.User, body?: models.AccessLog): Promise<models.AccessLog | any> {\n return body\n ? this.encrypt(user, [_.cloneDeep(body)])\n .then((als) => super.createAccessLog(als[0]))\n .then((accessLog) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, [accessLog]))\n .then((als) => als[0])\n : Promise.resolve()\n }\n\n getAccessLog(accessLogId: string): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n getAccessLogWithUser(user: models.User, accessLogId: string): Promise<models.AccessLog | any> {\n return super\n .getAccessLog(accessLogId)\n .then((accessLog) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, [accessLog]))\n .then((als) => als[0])\n }\n\n async getAccessLogs(ids: ListOfIds): Promise<AccessLog[]> {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n getAccessLogsWithUser(user: models.User, ids: ListOfIds): Promise<AccessLog[]> {\n return super.getAccessLogs(ids).then((accessLogs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, accessLogs))\n }\n\n listAccessLogs(fromEpoch?: number, toEpoch?: number, startKey?: number, startDocumentId?: string, limit?: number): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n listAccessLogsWithUser(\n user: models.User,\n fromEpoch?: number,\n toEpoch?: number,\n startKey?: number,\n startDocumentId?: string,\n limit?: number,\n descending?: boolean\n ): Promise<PaginatedListAccessLog> {\n return super\n .listAccessLogs(fromEpoch, toEpoch, startKey, startDocumentId, limit, descending)\n .then((accessLog) =>\n this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, accessLog.rows!).then((dr) => Object.assign(accessLog, { rows: dr }))\n )\n }\n\n modifyAccessLog(body?: models.AccessLog): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n async modifyAccessLogWithUser(user: models.User, body?: models.AccessLog): Promise<models.AccessLog | null> {\n return body ? this.modifyAs(this.dataOwnerApi.getDataOwnerIdOf(user)!, _.cloneDeep(body)) : null\n }\n\n private async modifyAs(owner: string, body: models.AccessLog): Promise<models.AccessLog> {\n return this.encryptAs(owner, [_.cloneDeep(body)])\n .then((als) => super.modifyAccessLog(als[0]))\n .then((accessLog) => this.decrypt(owner, [accessLog]))\n .then((als) => als[0])\n }\n\n findByUserAfterDate(\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n descending?: boolean\n ): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n findByUserAfterDateWithUser(\n user: models.User,\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n descending?: boolean\n ): Promise<models.AccessLog | any> {\n return super\n .findByUserAfterDate(userId, accessType, startDate, startKey, startDocumentId, limit, descending)\n .then((accessLog) =>\n this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, accessLog.rows!).then((dr) => Object.assign(accessLog, { rows: dr }))\n )\n }\n\n async findLatestAccessLogsOfPatientsWithUser(user: models.User, userId: string, limit = 100, startDate?: number): Promise<models.AccessLog[]> {\n let foundAccessLogs: AccessLogWithPatientId[] = [],\n nextKeyPair: models.PaginatedDocumentKeyIdPairObject | undefined = undefined\n const numberRequestedAccessLogs = 100\n const MAX_WHILE_ITERATIONS = 5\n\n for (let currentIteration = 0; foundAccessLogs.length < limit && currentIteration < MAX_WHILE_ITERATIONS; currentIteration++) {\n const currentLimit = limit - foundAccessLogs.length\n const { rows: logs, nextKeyPair: newNextKeyPair }: models.PaginatedListAccessLog = (await super.findByUserAfterDate(\n userId,\n 'USER_ACCESS',\n startDate,\n nextKeyPair && JSON.stringify(nextKeyPair.startKey!),\n nextKeyPair && nextKeyPair.startKeyDocId!,\n numberRequestedAccessLogs,\n true\n )) as models.PaginatedListAccessLog\n const logsWithPatientId: AccessLogWithPatientId[] = await this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, logs as AccessLog[]).then(\n (decryptedLogs) =>\n Promise.all(\n _.map(decryptedLogs, (decryptedLog) => {\n return this.crypto.xapi\n .owningEntityIdsOf({ entity: decryptedLog, type: EntityWithDelegationTypeName.AccessLog }, user.healthcarePartyId as string)\n .then(\n (keys) =>\n ({\n ...decryptedLog,\n patientId: _.head(keys),\n } as AccessLogWithPatientId)\n )\n })\n )\n )\n\n const uniqueLogs: AccessLogWithPatientId[] = _.chain(logsWithPatientId)\n .reject((log) => _.some(foundAccessLogs, ({ patientId }) => patientId === log.patientId))\n .uniqBy((log: AccessLogWithPatientId) => log.patientId)\n .value()\n .slice(0, currentLimit)\n\n foundAccessLogs = [...foundAccessLogs, ...uniqueLogs]\n\n if ((logs || []).length < numberRequestedAccessLogs) {\n break\n } else if (newNextKeyPair) {\n nextKeyPair = newNextKeyPair\n } else {\n break\n }\n }\n\n return foundAccessLogs\n }\n\n /**\n * @param accessLog an access log\n * @return the id of the patient that the access log refers to, retrieved from the encrypted metadata (not from the decrypted entity body). Normally\n * there should only be one element in the returned array, but in case of entity merges there could be multiple values.\n */\n async decryptPatientIdOf(accessLog: AccessLog): Promise<string[]> {\n return this.crypto.xapi.owningEntityIdsOf({ entity: accessLog, type: EntityWithDelegationTypeName.AccessLog }, undefined)\n }\n\n /**\n * @return if the logged data owner has write access to the content of the given access log\n */\n async hasWriteAccess(accessLog: AccessLog): Promise<boolean> {\n return this.crypto.xapi.hasWriteAccess({ entity: accessLog, type: EntityWithDelegationTypeName.AccessLog })\n }\n\n /**\n * Share an existing access log with other data owners, allowing them to access the non-encrypted data of the access log and optionally also the\n * 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 access log.\n * @param accessLog the access log to share.\n * @param options optional parameters to customize the sharing behaviour:\n * - shareSecretIds: specifies which secret ids of the entity should be shared. If not provided all secret ids available to the current user will be shared\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}).\n * - sharePatientId: specifies if the id of the patient that this access log refers to should be shared with the delegate. Normally this would\n * be the same as objectId, but it is encrypted separately from it allowing you to give access to the patient id without giving access to the other\n * encrypted data of the access log (defaults to {@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 accessLog: AccessLog,\n options: {\n shareSecretIds?: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n } = {}\n ): Promise<AccessLog> {\n return this.shareWithMany(accessLog, { [delegateId]: options })\n }\n\n /**\n * Share an existing access log with other data owners, allowing them to access the non-encrypted data of the access log and optionally also the\n * encrypted content, with read-only or read-write permissions.\n * @param accessLog the access log 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 * - shareSecretIds: specifies which secret ids of the entity should be shared. If not provided all secret ids available to the current user will be shared\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}).\n * - sharePatientId: specifies if the id of the patient that this access log refers to should be shared with the delegate. Normally this would\n * be the same as objectId, but it is encrypted separately from it allowing you to give access to the patient id without giving access to the other\n * encrypted data of the access log (defaults to {@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 accessLog: AccessLog,\n delegates: {\n [delegateId: string]: {\n shareSecretId?: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<AccessLog> {\n return (await this.tryShareWithMany(accessLog, delegates)).updatedEntityOrThrow\n }\n\n /**\n * Share an existing access log with other data owners, allowing them to access the non-encrypted data of the access log and optionally also the\n * encrypted content, with read-only or read-write permissions.\n * @param accessLog the access log 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 * - shareSecretIds: specifies which secret ids of the entity should be shared. If not provided all secret ids available to the current user will be shared\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}).\n * - sharePatientId: specifies if the id of the patient that this access log refers to should be shared with the delegate. Normally this would\n * be the same as objectId, but it is encrypted separately from it allowing you to give access to the patient id without giving access to the other\n * encrypted data of the access log (defaults to {@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 accessLog: AccessLog,\n delegates: {\n [delegateId: string]: {\n shareSecretIds?: 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<AccessLog>> {\n const self = await this.dataOwnerApi.getCurrentDataOwnerId()\n // All entities should have an encryption key.\n const entityWithEncryptionKey = await this.crypto.xapi.ensureEncryptionKeysInitialised(accessLog, EntityWithDelegationTypeName.AccessLog)\n const updatedEntity = entityWithEncryptionKey ? await this.modifyAs(self, entityWithEncryptionKey) : accessLog\n return this.crypto.xapi\n .simpleShareOrUpdateEncryptedEntityMetadata(\n {\n entity: updatedEntity,\n type: EntityWithDelegationTypeName.AccessLog,\n },\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: options.shareSecretIds,\n },\n ])\n ),\n (x) => this.bulkShareAccessLogs(x)\n )\n .then((r) => r.mapSuccessAsync((e) => this.decrypt(self, [e]).then((es) => es[0])))\n }\n\n getDataOwnersWithAccessTo(\n entity: AccessLog\n ): Promise<{ permissionsByDataOwnerId: { [p: string]: AccessLevelEnum }; hasUnknownAnonymousDataOwners: boolean }> {\n return this.crypto.delegationsDeAnonymization.getDataOwnersWithAccessTo({ entity, type: EntityWithDelegationTypeName.AccessLog })\n }\n\n getEncryptionKeysOf(entity: AccessLog): Promise<string[]> {\n return this.crypto.xapi.encryptionKeysOf({ entity, type: EntityWithDelegationTypeName.AccessLog }, undefined)\n }\n\n createDelegationDeAnonymizationMetadata(entity: AccessLog, delegates: string[]): Promise<void> {\n return this.crypto.delegationsDeAnonymization.createOrUpdateDeAnonymizationInfo(\n { entity, type: EntityWithDelegationTypeName.AccessLog },\n delegates\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"icc-accesslog-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-accesslog-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccAccesslogApi } from '../icc-api'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\nimport * as models from '../icc-api/model/models'\nimport { AccessLog, ListOfIds, PaginatedListAccessLog } from '../icc-api/model/models'\nimport * as _ from 'lodash'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { AuthenticationProvider, NoAuthenticationProvider } from './auth/AuthenticationProvider'\nimport { SecureDelegation } from '../icc-api/model/SecureDelegation'\nimport { ShareMetadataBehaviour } from './crypto/ShareMetadataBehaviour'\nimport { EntityShareRequest } from '../icc-api/model/requests/EntityShareRequest'\nimport { ShareResult } from './utils/ShareResult'\nimport { XHR } from '../icc-api/api/XHR'\nimport { EncryptedFieldsManifest, EntityWithDelegationTypeName, parseEncryptedFields } from './utils'\nimport { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\nimport RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum\n\nexport interface AccessLogWithPatientId extends AccessLog {\n patientId: string\n}\n\nexport class IccAccesslogXApi extends IccAccesslogApi implements EncryptedEntityXApi<models.AccessLog> {\n private readonly encryptedFields: EncryptedFieldsManifest\n crypto: IccCryptoXApi\n dataOwnerApi: IccDataOwnerXApi\n\n get headers(): Promise<Array<XHR.Header>> {\n return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, EntityWithDelegationTypeName.AccessLog))\n }\n\n constructor(\n host: string,\n headers: { [key: string]: string },\n crypto: IccCryptoXApi,\n dataOwnerApi: IccDataOwnerXApi,\n private readonly autofillAuthor: boolean,\n cryptedKeys = ['detail', 'objectId'],\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.encryptedFields = parseEncryptedFields(cryptedKeys, 'AccessLog.')\n }\n\n /**\n * Creates a new instance of access log with initialised encryption metadata (not in the database).\n * @param user the current user.\n * @param patient the patient this access log refers to.\n * @param h initialised data for the access log. 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 access log. The default value will be a\n * secret id of patient known by the topmost parent in the current data owner hierarchy.\n * @return a new instance of access log.\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 } = {}\n ) {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n\n const accessLog = {\n ...(h ?? {}),\n _type: 'org.taktik.icure.entities.AccessLog',\n id: h?.id ?? this.crypto.primitives.randomUuid(),\n created: h?.created ?? new Date().getTime(),\n modified: h?.modified ?? new Date().getTime(),\n date: h?.date ?? new Date().getTime(),\n responsible: h?.responsible ?? (this.autofillAuthor ? dataOwnerId : undefined),\n author: h?.author ?? (this.autofillAuthor ? user.id : undefined),\n codes: h?.codes ?? [],\n tags: h?.tags ?? [],\n user: h?.user ?? user.id,\n patientId: h?.patientId ?? patient.id,\n accessType: h?.accessType ?? 'USER_ACCESS',\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 (await this.crypto.confidential.getAnySecretIdSharedWithParents({ entity: patient, type: EntityWithDelegationTypeName.Patient }))\n if (!sfk) throw new Error(`Couldn't find any sfk of parent patient ${patient.id}`)\n const extraDelegations = {\n ...Object.fromEntries(\n [...(user.autoDelegations?.all ?? []), ...(user.autoDelegations?.administrativeData ?? [])].map((x) => [x, AccessLevelEnum.WRITE])\n ),\n ...(options.additionalDelegates ?? {}),\n }\n return new AccessLog(\n await this.crypto.xapi\n .entityWithInitialisedEncryptedMetadata(accessLog, EntityWithDelegationTypeName.AccessLog, patient.id, sfk, true, extraDelegations)\n .then((x) => x.updatedEntity)\n )\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 access logs with (allSecretForeignKeysDelimitedByComma, hcpartyId)\n *\n * After these painful steps, you have the access logs of the patient.\n *\n * @deprecated use {@link findIdsBy} instead\n * @param hcpartyId\n * @param patient (Promise)\n * @param usingPost\n */\n async findBy(hcpartyId: string, patient: models.Patient, usingPost: boolean = false): Promise<models.AccessLog[]> {\n const extractedKeys = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, hcpartyId)\n const topmostParentId = (await this.dataOwnerApi.getCurrentDataOwnerHierarchyIds())[0]\n return extractedKeys && extractedKeys.length > 0\n ? usingPost\n ? this.findByHCPartyPatientSecretFKeysArray(hcpartyId!, _.uniq(extractedKeys))\n : this.findByHCPartyPatientSecretFKeys(hcpartyId!, _.uniq(extractedKeys).join(','))\n : Promise.resolve([])\n }\n\n /**\n * Same as `findBy` but it will only return the ids of the access logs. It can also filter the access logs where AccessLog.date is between\n * startDate and endDate in ascending or descending order by that field. (default: ascending).\n */\n async findIdsBy(hcpartyId: string, patient: models.Patient, startDate?: number, endDate?: number, descending?: boolean): Promise<string[]> {\n const extractedKeys = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, hcpartyId)\n return extractedKeys && extractedKeys.length > 0\n ? this.findAccessLogIdsByDataOwnerPatientDate(hcpartyId, _.uniq(extractedKeys), startDate, endDate, descending)\n : Promise.resolve([])\n }\n\n /**\n * @deprecated use {@link findAccessLogIdsByDataOwnerPatientDate} instead\n */\n async findByHCPartyPatientSecretFKeys(hcPartyId: string, secretFKeys: string): Promise<AccessLog[]> {\n const accessLogs = await super.findAccessLogsByHCPartyPatientForeignKeys(hcPartyId, secretFKeys)\n return await this.decrypt(hcPartyId, accessLogs)\n }\n\n /**\n * @deprecated use {@link findAccessLogIdsByDataOwnerPatientDate} instead\n */\n findByHCPartyPatientSecretFKeysArray(hcPartyId: string, secretFKeys: string[]): Promise<Array<AccessLog> | any> {\n return super.findAccessLogsByHCPartyPatientForeignKeysUsingPost(hcPartyId, secretFKeys).then((accesslogs) => this.decrypt(hcPartyId, accesslogs))\n }\n\n async decrypt(hcpId: string, accessLogs: Array<models.AccessLog>): Promise<Array<models.AccessLog>> {\n return (await this.crypto.xapi.tryDecryptEntities(accessLogs, EntityWithDelegationTypeName.AccessLog, (json) => new AccessLog(json))).map(\n ({ entity }) => entity\n )\n }\n\n encrypt(user: models.User, accessLogs: Array<models.AccessLog>): Promise<Array<models.AccessLog>> {\n const owner = this.dataOwnerApi.getDataOwnerIdOf(user)\n return this.encryptAs(owner, accessLogs)\n }\n\n private async encryptAs(dataOwner: string, accessLogs: Array<models.AccessLog>): Promise<Array<models.AccessLog>> {\n return this.crypto.xapi.tryEncryptEntities(\n accessLogs,\n EntityWithDelegationTypeName.AccessLog,\n this.encryptedFields,\n false,\n false,\n (json) => new AccessLog(json)\n )\n }\n\n createAccessLog(body?: models.AccessLog): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n createAccessLogWithUser(user: models.User, body?: models.AccessLog): Promise<models.AccessLog | any> {\n return body\n ? this.encrypt(user, [_.cloneDeep(body)])\n .then((als) => super.createAccessLog(als[0]))\n .then((accessLog) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, [accessLog]))\n .then((als) => als[0])\n : Promise.resolve()\n }\n\n getAccessLog(accessLogId: string): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n getAccessLogWithUser(user: models.User, accessLogId: string): Promise<models.AccessLog | any> {\n return super\n .getAccessLog(accessLogId)\n .then((accessLog) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, [accessLog]))\n .then((als) => als[0])\n }\n\n async getAccessLogs(ids: ListOfIds): Promise<AccessLog[]> {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n getAccessLogsWithUser(user: models.User, ids: ListOfIds): Promise<AccessLog[]> {\n return super.getAccessLogs(ids).then((accessLogs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, accessLogs))\n }\n\n listAccessLogs(fromEpoch?: number, toEpoch?: number, startKey?: number, startDocumentId?: string, limit?: number): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n listAccessLogsWithUser(\n user: models.User,\n fromEpoch?: number,\n toEpoch?: number,\n startKey?: number,\n startDocumentId?: string,\n limit?: number,\n descending?: boolean\n ): Promise<PaginatedListAccessLog> {\n return super\n .listAccessLogs(fromEpoch, toEpoch, startKey, startDocumentId, limit, descending)\n .then((accessLog) =>\n this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, accessLog.rows!).then((dr) => Object.assign(accessLog, { rows: dr }))\n )\n }\n\n modifyAccessLog(body?: models.AccessLog): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n async modifyAccessLogWithUser(user: models.User, body?: models.AccessLog): Promise<models.AccessLog | null> {\n return body ? this.modifyAs(this.dataOwnerApi.getDataOwnerIdOf(user)!, _.cloneDeep(body)) : null\n }\n\n private async modifyAs(owner: string, body: models.AccessLog): Promise<models.AccessLog> {\n return this.encryptAs(owner, [_.cloneDeep(body)])\n .then((als) => super.modifyAccessLog(als[0]))\n .then((accessLog) => this.decrypt(owner, [accessLog]))\n .then((als) => als[0])\n }\n\n findByUserAfterDate(\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n descending?: boolean\n ): never {\n throw new Error('Cannot call a method that returns access logs without providing a user for de/encryption')\n }\n\n findByUserAfterDateWithUser(\n user: models.User,\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n descending?: boolean\n ): Promise<models.AccessLog | any> {\n return super\n .findByUserAfterDate(userId, accessType, startDate, startKey, startDocumentId, limit, descending)\n .then((accessLog) =>\n this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, accessLog.rows!).then((dr) => Object.assign(accessLog, { rows: dr }))\n )\n }\n\n async findLatestAccessLogsOfPatientsWithUser(user: models.User, userId: string, limit = 100, startDate?: number): Promise<models.AccessLog[]> {\n let foundAccessLogs: AccessLogWithPatientId[] = [],\n nextKeyPair: models.PaginatedDocumentKeyIdPairObject | undefined = undefined\n const numberRequestedAccessLogs = 100\n const MAX_WHILE_ITERATIONS = 5\n\n for (let currentIteration = 0; foundAccessLogs.length < limit && currentIteration < MAX_WHILE_ITERATIONS; currentIteration++) {\n const currentLimit = limit - foundAccessLogs.length\n const { rows: logs, nextKeyPair: newNextKeyPair }: models.PaginatedListAccessLog = (await super.findByUserAfterDate(\n userId,\n 'USER_ACCESS',\n startDate,\n nextKeyPair && JSON.stringify(nextKeyPair.startKey!),\n nextKeyPair && nextKeyPair.startKeyDocId!,\n numberRequestedAccessLogs,\n true\n )) as models.PaginatedListAccessLog\n const logsWithPatientId: AccessLogWithPatientId[] = await this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user)!, logs as AccessLog[]).then(\n (decryptedLogs) =>\n Promise.all(\n _.map(decryptedLogs, (decryptedLog) => {\n return this.crypto.xapi\n .owningEntityIdsOf({ entity: decryptedLog, type: EntityWithDelegationTypeName.AccessLog }, user.healthcarePartyId as string)\n .then(\n (keys) =>\n ({\n ...decryptedLog,\n patientId: _.head(keys),\n } as AccessLogWithPatientId)\n )\n })\n )\n )\n\n const uniqueLogs: AccessLogWithPatientId[] = _.chain(logsWithPatientId)\n .reject((log) => _.some(foundAccessLogs, ({ patientId }) => patientId === log.patientId))\n .uniqBy((log: AccessLogWithPatientId) => log.patientId)\n .value()\n .slice(0, currentLimit)\n\n foundAccessLogs = [...foundAccessLogs, ...uniqueLogs]\n\n if ((logs || []).length < numberRequestedAccessLogs) {\n break\n } else if (newNextKeyPair) {\n nextKeyPair = newNextKeyPair\n } else {\n break\n }\n }\n\n return foundAccessLogs\n }\n\n /**\n * @param accessLog an access log\n * @return the id of the patient that the access log refers to, retrieved from the encrypted metadata (not from the decrypted entity body). Normally\n * there should only be one element in the returned array, but in case of entity merges there could be multiple values.\n */\n async decryptPatientIdOf(accessLog: AccessLog): Promise<string[]> {\n return this.crypto.xapi.owningEntityIdsOf({ entity: accessLog, type: EntityWithDelegationTypeName.AccessLog }, undefined)\n }\n\n /**\n * @return if the logged data owner has write access to the content of the given access log\n */\n async hasWriteAccess(accessLog: AccessLog): Promise<boolean> {\n return this.crypto.xapi.hasWriteAccess({ entity: accessLog, type: EntityWithDelegationTypeName.AccessLog })\n }\n\n /**\n * Share an existing access log with other data owners, allowing them to access the non-encrypted data of the access log and optionally also the\n * 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 access log.\n * @param accessLog the access log to share.\n * @param options optional parameters to customize the sharing behaviour:\n * - shareSecretIds: specifies which secret ids of the entity should be shared. If not provided all secret ids available to the current user will be shared\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}).\n * - sharePatientId: specifies if the id of the patient that this access log refers to should be shared with the delegate. Normally this would\n * be the same as objectId, but it is encrypted separately from it allowing you to give access to the patient id without giving access to the other\n * encrypted data of the access log (defaults to {@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 accessLog: AccessLog,\n options: {\n shareSecretIds?: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n } = {}\n ): Promise<AccessLog> {\n return this.shareWithMany(accessLog, { [delegateId]: options })\n }\n\n /**\n * Share an existing access log with other data owners, allowing them to access the non-encrypted data of the access log and optionally also the\n * encrypted content, with read-only or read-write permissions.\n * @param accessLog the access log 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 * - shareSecretIds: specifies which secret ids of the entity should be shared. If not provided all secret ids available to the current user will be shared\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}).\n * - sharePatientId: specifies if the id of the patient that this access log refers to should be shared with the delegate. Normally this would\n * be the same as objectId, but it is encrypted separately from it allowing you to give access to the patient id without giving access to the other\n * encrypted data of the access log (defaults to {@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 accessLog: AccessLog,\n delegates: {\n [delegateId: string]: {\n shareSecretId?: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n sharePatientId?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<AccessLog> {\n return (await this.tryShareWithMany(accessLog, delegates)).updatedEntityOrThrow\n }\n\n /**\n * Share an existing access log with other data owners, allowing them to access the non-encrypted data of the access log and optionally also the\n * encrypted content, with read-only or read-write permissions.\n * @param accessLog the access log 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 * - shareSecretIds: specifies which secret ids of the entity should be shared. If not provided all secret ids available to the current user will be shared\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}).\n * - sharePatientId: specifies if the id of the patient that this access log refers to should be shared with the delegate. Normally this would\n * be the same as objectId, but it is encrypted separately from it allowing you to give access to the patient id without giving access to the other\n * encrypted data of the access log (defaults to {@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 accessLog: AccessLog,\n delegates: {\n [delegateId: string]: {\n shareSecretIds?: 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<AccessLog>> {\n const self = await this.dataOwnerApi.getCurrentDataOwnerId()\n // All entities should have an encryption key.\n const entityWithEncryptionKey = await this.crypto.xapi.ensureEncryptionKeysInitialised(accessLog, EntityWithDelegationTypeName.AccessLog)\n const updatedEntity = entityWithEncryptionKey ? await this.modifyAs(self, entityWithEncryptionKey) : accessLog\n return this.crypto.xapi\n .simpleShareOrUpdateEncryptedEntityMetadata(\n {\n entity: updatedEntity,\n type: EntityWithDelegationTypeName.AccessLog,\n },\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: options.shareSecretIds,\n },\n ])\n ),\n (x) => this.bulkShareAccessLogs(x)\n )\n .then((r) => r.mapSuccessAsync((e) => this.decrypt(self, [e]).then((es) => es[0])))\n }\n\n getDataOwnersWithAccessTo(\n entity: AccessLog\n ): Promise<{ permissionsByDataOwnerId: { [p: string]: AccessLevelEnum }; hasUnknownAnonymousDataOwners: boolean }> {\n return this.crypto.delegationsDeAnonymization.getDataOwnersWithAccessTo({ entity, type: EntityWithDelegationTypeName.AccessLog })\n }\n\n getEncryptionKeysOf(entity: AccessLog): Promise<string[]> {\n return this.crypto.xapi.encryptionKeysOf({ entity, type: EntityWithDelegationTypeName.AccessLog }, undefined)\n }\n\n createDelegationDeAnonymizationMetadata(entity: AccessLog, delegates: string[]): Promise<void> {\n return this.crypto.delegationsDeAnonymization.createOrUpdateDeAnonymizationInfo(\n { entity, type: EntityWithDelegationTypeName.AccessLog },\n delegates\n )\n }\n}\n"]}
|
|
@@ -274,10 +274,12 @@ class IccCalendarItemXApi extends icc_api_1.IccCalendarItemApi {
|
|
|
274
274
|
return this.encryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), calendarItems);
|
|
275
275
|
}
|
|
276
276
|
encryptAs(dataOwner, calendarItems) {
|
|
277
|
-
return
|
|
277
|
+
return this.crypto.xapi.tryEncryptEntities(calendarItems, utils_1.EntityWithDelegationTypeName.CalendarItem, this.encryptedFields, false, false, (json) => new models_1.CalendarItem(json));
|
|
278
278
|
}
|
|
279
279
|
decrypt(hcpId, calendarItems) {
|
|
280
|
-
return
|
|
280
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
281
|
+
return (yield this.crypto.xapi.tryDecryptEntities(calendarItems, utils_1.EntityWithDelegationTypeName.CalendarItem, (json) => new models_1.CalendarItem(json))).map(({ entity }) => entity);
|
|
282
|
+
});
|
|
281
283
|
}
|
|
282
284
|
/**
|
|
283
285
|
* @param calendarItem a calendar item
|