@icure/api 8.0.69 → 8.0.71
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-x-api/crypto/BaseExchangeKeysManager.js +19 -13
- package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.js +15 -0
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/package.json +1 -1
- package/test/icc-x-api/crypto/soft-deleted-data-owners.d.ts +2 -0
- package/test/icc-x-api/crypto/soft-deleted-data-owners.js +113 -0
- package/test/icc-x-api/crypto/soft-deleted-data-owners.js.map +1 -0
- package/test/icc-x-api/icc-patient-x-api-test.js +7 -0
- package/test/icc-x-api/icc-patient-x-api-test.js.map +1 -1
|
@@ -93,7 +93,7 @@ class BaseExchangeKeysManager {
|
|
|
93
93
|
: Promise.resolve({}),
|
|
94
94
|
]).then(([a, b, c]) => (Object.assign(Object.assign(Object.assign({}, a), b), c)));
|
|
95
95
|
const dataOwner = yield this.dataOwnerApi.getCryptoActorStub(dataOwnerId);
|
|
96
|
-
const allOwnerKeys = yield this.combineLegacyHcpKeysWithAesExchangeKeys(dataOwner.stub, undefined);
|
|
96
|
+
const allOwnerKeys = yield this.combineLegacyHcpKeysWithAesExchangeKeys(dataOwner.stub, undefined, false);
|
|
97
97
|
const filteredDelegates = new Set(yield Array.from(new Set(Object.values(allOwnerKeys).flatMap((x) => Object.keys(x)))).reduce((acc, ownerId) => __awaiter(this, void 0, void 0, function* () {
|
|
98
98
|
const awaitedAcc = yield acc;
|
|
99
99
|
if (ownerId === dataOwnerId || otherOwnerTypes == null) {
|
|
@@ -151,7 +151,7 @@ class BaseExchangeKeysManager {
|
|
|
151
151
|
const delegator = yield this.dataOwnerApi.getCryptoActorStub(delegatorId);
|
|
152
152
|
const delegate = yield this.dataOwnerApi.getCryptoActorStub(delegateId);
|
|
153
153
|
let didUpdateSomeKey = false;
|
|
154
|
-
const combinedKeys = yield this.combineLegacyHcpKeysWithAesExchangeKeys(delegator.stub, delegate.stub);
|
|
154
|
+
const combinedKeys = yield this.combineLegacyHcpKeysWithAesExchangeKeys(delegator.stub, delegate.stub, true);
|
|
155
155
|
const updatedExchangeKeys = {};
|
|
156
156
|
const newEncryptionKeys = { [newPublicKeyFp]: newPublicKey };
|
|
157
157
|
for (const [currDelegatorKey, currDelegatesToKeys] of Object.entries(combinedKeys)) {
|
|
@@ -255,25 +255,31 @@ class BaseExchangeKeysManager {
|
|
|
255
255
|
});
|
|
256
256
|
}
|
|
257
257
|
// Copy all legacy hcp exchange keys into the new aes exchange keys
|
|
258
|
-
combineLegacyHcpKeysWithAesExchangeKeys(owner, delegate) {
|
|
258
|
+
combineLegacyHcpKeysWithAesExchangeKeys(owner, delegate, fillDelegateLegacyKey) {
|
|
259
259
|
var _a, _b, _c, _d, _e;
|
|
260
260
|
return __awaiter(this, void 0, void 0, function* () {
|
|
261
261
|
const ownerLegacyPublicKey = owner.publicKey;
|
|
262
|
-
if (ownerLegacyPublicKey && !((_a = owner.aesExchangeKeys) !== null && _a !== void 0 ? _a : {})[ownerLegacyPublicKey]) {
|
|
262
|
+
if (ownerLegacyPublicKey != undefined && !((_a = owner.aesExchangeKeys) !== null && _a !== void 0 ? _a : {})[ownerLegacyPublicKey]) {
|
|
263
263
|
/*
|
|
264
264
|
* This condition would technically prevent new updates to the hcPartyKeys to be migrated to the aes exchange keys, but since I can only update
|
|
265
265
|
* data for self data owner and parent entities this is not an issue, because I will always be using the new api from now on and I won't have
|
|
266
266
|
* a situation where the legacy keys are updated but the aes exchange keys are not.
|
|
267
267
|
*/
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
owner
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
268
|
+
const counterPartsById = {};
|
|
269
|
+
if (fillDelegateLegacyKey) {
|
|
270
|
+
counterPartsById[owner.id] = owner;
|
|
271
|
+
if (delegate) {
|
|
272
|
+
counterPartsById[delegate.id] = delegate;
|
|
273
|
+
}
|
|
274
|
+
for (const other of Object.keys((_b = owner.hcPartyKeys) !== null && _b !== void 0 ? _b : {}).filter((x) => x !== owner.id && x !== (delegate === null || delegate === void 0 ? void 0 : delegate.id))) {
|
|
275
|
+
try {
|
|
276
|
+
counterPartsById[other] = (yield this.dataOwnerApi.getCryptoActorStub(other)).stub;
|
|
277
|
+
}
|
|
278
|
+
catch (_f) {
|
|
279
|
+
// ignore
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
277
283
|
return Object.assign({ [ownerLegacyPublicKey]: Object.entries((_c = owner.hcPartyKeys) !== null && _c !== void 0 ? _c : {}).reduce((acc, [hcpId, keys]) => {
|
|
278
284
|
var _a, _b;
|
|
279
285
|
const counterpartKey = (_a = counterPartsById[hcpId]) === null || _a === void 0 ? void 0 : _a.publicKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseExchangeKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/BaseExchangeKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './RSA'\nimport { hex2ua, notConcurrent, ua2hex } from '../utils'\nimport { DataOwner, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IccDeviceApi, IccHcpartyApi, IccPatientApi } from '../../icc-api'\nimport { fingerprintV1, getShaVersionForKey } from './utils'\nimport { CryptoActorStub, CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { DataOwnerTypeEnum } from '../../icc-api/model/DataOwnerTypeEnum'\n\n/**\n * @internal This class is meant only for internal use and may be changed without notice.\n * Functions to create and get exchange keys.\n * The methods of this api require to pass the appropriate keys for encryption/decryption manually.\n */\nexport class BaseExchangeKeysManager {\n private readonly generateKeyConcurrencyMap: { [key: string]: PromiseLike<any> } = {}\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly hcpartyBaseApi: IccHcpartyApi\n private readonly patientBaseApi: IccPatientApi\n private readonly deviceBaseApi: IccDeviceApi\n\n constructor(\n primitives: CryptoPrimitives,\n dataOwnerApi: IccDataOwnerXApi,\n hcpartyBaseApi: IccHcpartyApi,\n patientBaseApi: IccPatientApi,\n deviceBaseApi: IccDeviceApi\n ) {\n this.primitives = primitives\n this.dataOwnerApi = dataOwnerApi\n this.hcpartyBaseApi = hcpartyBaseApi\n this.patientBaseApi = patientBaseApi\n this.deviceBaseApi = deviceBaseApi\n }\n\n /**\n * Updates the aes exchange keys between the current data owner and another data owner to allow the other data owner to access the exchange key\n * using his new public key. Note that this will make existing exchange keys from the other data owner to the current data owner invalid for\n * encryption.\n * @param otherDataOwner the other data owner.\n * @param newDataOwnerPublicKey a new public key of the other data owner.\n * @param keyPairsByFingerprint all available key pairs to use for the decryption of existing aes exchange keys.\n */\n async giveAccessBackTo(\n otherDataOwner: string,\n newDataOwnerPublicKey: string,\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const other = await this.dataOwnerApi.getCryptoActorStub(otherDataOwner)\n const newKeyHashVersion = getShaVersionForKey(other.stub, newDataOwnerPublicKey)\n if (!newKeyHashVersion) throw new Error(`Public key not found for data owner ${otherDataOwner}`)\n const newPublicKey = await this.primitives.RSA.importKey('spki', hex2ua(newDataOwnerPublicKey), ['encrypt'], newKeyHashVersion)\n await this.extendForGiveAccessBackTo(selfId, otherDataOwner, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n await this.extendForGiveAccessBackTo(otherDataOwner, selfId, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n }\n\n /**\n * Get the encrypted exchange keys for a delegator-delegate pair.\n * @param delegatorId id of the delegator data owner.\n * @param delegateId id of the delegate data owner.\n * @return an array of exchange keys from the delegator to delegate where each key is encrypted with one or more public keys.\n */\n async getEncryptedExchangeKeysFor(delegatorId: string, delegateId: string): Promise<{ [publicKeyFingerprint: string]: string }[]> {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const res: { [publicKeyFingerprint: string]: string }[] = Object.values(delegator.stub.aesExchangeKeys ?? {}).flatMap((delegateToKey) => {\n const encryptedKeyForDelegate = delegateToKey[delegateId]\n if (encryptedKeyForDelegate) {\n return [encryptedKeyForDelegate]\n } else {\n return []\n }\n })\n const legacyDelegation = delegator.stub.hcPartyKeys?.[delegateId]?.[1]\n if (legacyDelegation) res.push({ '': legacyDelegation })\n return res\n }\n\n /**\n * Get all exchange keys where the provided data owner is involved either as the delegator or as the delegate.\n * @param dataOwnerId id of a data owner.\n * @param otherOwnerTypes only exchange keys between the current data owner and data owners of this type will be included in the result. If null considers all delegates\n * @return all exchange keys involving the provided data owner. Note that there may be an overlap between some keys to and from the data owner.\n */\n async getAllExchangeKeysWith(\n dataOwnerId: string,\n otherOwnerTypes: DataOwnerTypeEnum[] | null\n ): Promise<{\n keysToOwner: { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }\n keysFromOwner: { [delegatorFp: string]: { [delegateId: string]: { [entryFp: string]: string } } }\n }> {\n if (otherOwnerTypes != null && otherOwnerTypes.length === 0) throw new Error('otherOwnerTypes must not be empty!')\n const keysToOwner = await Promise.all([\n otherOwnerTypes == null || otherOwnerTypes.find((x) => x === 'hcp')\n ? this.hcpartyBaseApi.getAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n otherOwnerTypes == null || otherOwnerTypes.find((x) => x === 'patient')\n ? this.patientBaseApi.getPatientAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n otherOwnerTypes == null || otherOwnerTypes.find((x) => x === 'device')\n ? this.deviceBaseApi.getDeviceAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n ]).then(([a, b, c]) => ({ ...a, ...b, ...c } as { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }))\n const dataOwner = await this.dataOwnerApi.getCryptoActorStub(dataOwnerId)\n const allOwnerKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(dataOwner.stub, undefined)\n const filteredDelegates = new Set(\n await Array.from(new Set(Object.values(allOwnerKeys).flatMap((x) => Object.keys(x)))).reduce(async (acc, ownerId) => {\n const awaitedAcc = await acc\n if (ownerId === dataOwnerId || otherOwnerTypes == null) {\n return [...awaitedAcc, ownerId]\n } else {\n try {\n const dataOwnerType: DataOwnerTypeEnum = (await this.dataOwnerApi.getCryptoActorStub(ownerId)).type\n if (otherOwnerTypes.some((x) => x === dataOwnerType)) {\n return [...awaitedAcc, ownerId]\n } else return awaitedAcc\n } catch (_) {\n return awaitedAcc\n }\n }\n }, Promise.resolve([] as string[]))\n )\n const keysFromOwner = Object.fromEntries(\n Object.entries(allOwnerKeys)\n .map(([delegatorPubKey, delegateToKeys]) => [\n delegatorPubKey,\n Object.fromEntries(\n Object.entries(delegateToKeys).filter(([delegateId]) => filteredDelegates.has(delegateId)) as [string, { [k: string]: string }][]\n ),\n ])\n .filter(([, x]) => Object.keys(x).length > 0) as [string, { [k: string]: { [k: string]: string } }][]\n )\n return { keysToOwner, keysFromOwner }\n }\n\n /**\n * Attempts to decrypt many exchange keys using any of the provided key pairs.\n * @param encryptedExchangeKeys an array of exchange keys where each key is encrypted with one or more public keys.\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return an array all successfully decrypted exchange keys and an array containing all exchange keys which could not be decrypted.\n */\n async tryDecryptExchangeKeys(\n encryptedExchangeKeys: { [publicKeyFingerprint: string]: string }[],\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n }> {\n const raws = new Set<string>()\n const res: {\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n } = { successfulDecryptions: [], failedDecryptions: [] }\n for (const encryptedExchangeKey of encryptedExchangeKeys) {\n const decrypted = await this.tryDecryptExchangeKey(encryptedExchangeKey, keyPairsByFingerprint)\n if (decrypted !== undefined && !raws.has(decrypted.raw)) {\n raws.add(decrypted.raw)\n res.successfulDecryptions.push(decrypted.key)\n } else {\n res.failedDecryptions.push(encryptedExchangeKey)\n }\n }\n return res\n }\n\n private async extendForGiveAccessBackTo(\n delegatorId: string,\n delegateId: string,\n newPublicKeyFp: string,\n newPublicKey: CryptoKey,\n decryptionKeyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n await notConcurrent(this.generateKeyConcurrencyMap, delegatorId, async () => {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const delegate = await this.dataOwnerApi.getCryptoActorStub(delegateId)\n let didUpdateSomeKey = false\n const combinedKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(delegator.stub, delegate.stub)\n const updatedExchangeKeys: { [delegatorKey: string]: { [delegateId: string]: { [keyFp: string]: string } } } = {}\n const newEncryptionKeys = { [newPublicKeyFp]: newPublicKey }\n for (const [currDelegatorKey, currDelegatesToKeys] of Object.entries(combinedKeys)) {\n const updatedDelegatesToKeys: { [delegateId: string]: { [keyFp: string]: string } } = {}\n for (const [currDelegateId, currEncryptedKey] of Object.entries(currDelegatesToKeys)) {\n if (delegateId !== currDelegateId || newPublicKeyFp in currEncryptedKey) {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n } else {\n const decrypted = await this.tryDecryptExchangeKey(currEncryptedKey, decryptionKeyPairsByFingerprint)\n if (decrypted) {\n didUpdateSomeKey = true\n updatedDelegatesToKeys[currDelegateId] = {\n ...currEncryptedKey,\n ...(await this.encryptExchangeKey(decrypted, newEncryptionKeys)).encryptedExchangeKey,\n }\n } else {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n }\n }\n }\n updatedExchangeKeys[currDelegatorKey] = updatedDelegatesToKeys\n }\n if (didUpdateSomeKey) {\n await this.dataOwnerApi.modifyCryptoActorStub({\n type: delegator.type,\n stub: {\n ...delegator.stub,\n aesExchangeKeys: updatedExchangeKeys,\n },\n })\n }\n })\n }\n\n /**\n * Attempts to decrypt an exchange key using any of the provided key pairs.\n * @param encryptedExchangeKey an encrypted exchange key, in the form publicKeyXyzFingerprint -> hex(exchangeKeyEncryptedByPrivateKeyXyz).\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided keys.\n */\n private async tryDecryptExchangeKey(\n encryptedExchangeKey: { [publicKeyFingerprint: string]: string },\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n for (const [entryKey, encrypted] of Object.entries(encryptedExchangeKey)) {\n // Due to bugs in past version the entry may actually contain the full public key instead of just the fingerprint.\n const fp = fingerprintV1(entryKey)\n const keyPair = keyPairsByFingerprint[fp]\n if (keyPair !== undefined) {\n const res = await this.tryDecryptExchangeKeyWith(encrypted, keyPair, fp)\n if (res !== undefined) return res\n }\n }\n const defaultEncryptedKey = encryptedExchangeKey['']\n if (defaultEncryptedKey !== undefined) {\n for (const keyPair of Object.values(keyPairsByFingerprint)) {\n // disable error logging, we are not sure keyPair is the correct key\n const res = await this.tryDecryptExchangeKeyWith(defaultEncryptedKey, keyPair, undefined)\n if (res !== undefined) return res\n }\n }\n return undefined\n }\n\n /**\n * Creates an encrypted exchange key for the provided public keys.\n * @param exchangeKey the exchange key in raw and imported format. If undefined a new key will be automatically created.\n * @param publicKeys additional public keys that will have access to the exchange key in spki format, hex-encoded.\n * @return the exchangeKey and an object with the exchange key encrypted with each of the provided public keys, hex-encoded, by fingerprint.\n */\n private async encryptExchangeKey(\n exchangeKey: { raw: string; key: CryptoKey } | undefined,\n publicKeys: { [keyFingerprint: string]: CryptoKey }\n ): Promise<{\n exchangeKey: CryptoKey\n encryptedExchangeKey: { [pubKeyFp: string]: string }\n }> {\n const exchangeKeyCrypto = exchangeKey?.key ?? (await this.primitives.AES.generateCryptoKey(false))\n const exchangeKeyBytes = exchangeKey !== undefined ? hex2ua(exchangeKey.raw) : await this.primitives.AES.exportKey(exchangeKeyCrypto, 'raw')\n const encryptedExchangeKey = await Object.entries(publicKeys).reduce(\n async (acc, [currKeyFp, currKey]) => ({\n ...(await acc),\n [currKeyFp]: ua2hex(await this.primitives.RSA.encrypt(currKey, new Uint8Array(exchangeKeyBytes))),\n }),\n Promise.resolve({} as { [pubKeyFp: string]: string })\n )\n return { exchangeKey: exchangeKeyCrypto, encryptedExchangeKey }\n }\n\n /**\n * Attempts to decrypt an exchange key using the provided key pairs.\n * If you are confident that the provided {@link keyPair} was used to encrypt {@link encryptedByOneKey} you should also provide {@link keyPairFp},\n * so that if the decryption fail an error will be logged to console before returning undefined.\n * @param encryptedByOneKey an exchange key which may be encrypted with {@link keyPair}.\n * @param keyPair an rsa key pair.\n * @param keyPairFp the fingerprint of the provided key pair or undefined to disable logging of error if the decryption failed.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided key.\n */\n private async tryDecryptExchangeKeyWith(\n encryptedByOneKey: string,\n keyPair: KeyPair<CryptoKey>,\n keyPairFp: string | undefined // if undefined will not log errors, when we are not sure the key to be used is the provided key.\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n try {\n const decrypted = await this.primitives.RSA.decrypt(keyPair.privateKey, hex2ua(encryptedByOneKey))\n return { raw: ua2hex(decrypted), key: await this.primitives.AES.importKey('raw', decrypted) }\n } catch (e) {\n if (keyPairFp) {\n console.error(`Failed to decrypt or import exchange key ${encryptedByOneKey} using key with fingerprint ${keyPairFp}.`, e)\n }\n }\n }\n // Copy all legacy hcp exchange keys into the new aes exchange keys\n private async combineLegacyHcpKeysWithAesExchangeKeys(\n owner: CryptoActorStub,\n delegate: CryptoActorStub | undefined\n ): Promise<{ [ownerPublicKey: string]: { [delegateId: string]: { [fingerprint: string]: string } } }> {\n const ownerLegacyPublicKey = owner.publicKey\n if (ownerLegacyPublicKey && !(owner.aesExchangeKeys ?? {})[ownerLegacyPublicKey]) {\n /*\n * This condition would technically prevent new updates to the hcPartyKeys to be migrated to the aes exchange keys, but since I can only update\n * data for self data owner and parent entities this is not an issue, because I will always be using the new api from now on and I won't have\n * a situation where the legacy keys are updated but the aes exchange keys are not.\n */\n const unknownDataOwnerCounterPartIds = Object.keys(owner.hcPartyKeys ?? {}).filter((x) => x !== owner.id && x !== delegate?.id)\n const counterPartsById = [\n owner,\n ...(delegate ? [delegate] : []),\n ...(await Promise.all(unknownDataOwnerCounterPartIds.map(async (cpid) => (await this.dataOwnerApi.getCryptoActorStub(cpid)).stub))),\n ].reduce((acc, dataOwner) => {\n acc[dataOwner.id!] = dataOwner\n return acc\n }, {} as { [id: string]: CryptoActorStub })\n return {\n [ownerLegacyPublicKey]: Object.entries(owner.hcPartyKeys ?? {}).reduce((acc, [hcpId, keys]) => {\n const counterpartKey = counterPartsById[hcpId]?.publicKey\n acc[hcpId] = {\n [fingerprintV1(ownerLegacyPublicKey)]: keys[0],\n [(counterpartKey && fingerprintV1(counterpartKey)) ?? '']: keys[1],\n }\n return acc\n }, {} as { [delegateId: string]: { [fingerprint: string]: string } }),\n ...(owner.aesExchangeKeys ?? {}),\n }\n } else return owner.aesExchangeKeys ?? {}\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BaseExchangeKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/BaseExchangeKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './RSA'\nimport { hex2ua, notConcurrent, ua2hex } from '../utils'\nimport { DataOwner, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IccDeviceApi, IccHcpartyApi, IccPatientApi } from '../../icc-api'\nimport { fingerprintV1, getShaVersionForKey } from './utils'\nimport { CryptoActorStub, CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { DataOwnerTypeEnum } from '../../icc-api/model/DataOwnerTypeEnum'\n\n/**\n * @internal This class is meant only for internal use and may be changed without notice.\n * Functions to create and get exchange keys.\n * The methods of this api require to pass the appropriate keys for encryption/decryption manually.\n */\nexport class BaseExchangeKeysManager {\n private readonly generateKeyConcurrencyMap: { [key: string]: PromiseLike<any> } = {}\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly hcpartyBaseApi: IccHcpartyApi\n private readonly patientBaseApi: IccPatientApi\n private readonly deviceBaseApi: IccDeviceApi\n\n constructor(\n primitives: CryptoPrimitives,\n dataOwnerApi: IccDataOwnerXApi,\n hcpartyBaseApi: IccHcpartyApi,\n patientBaseApi: IccPatientApi,\n deviceBaseApi: IccDeviceApi\n ) {\n this.primitives = primitives\n this.dataOwnerApi = dataOwnerApi\n this.hcpartyBaseApi = hcpartyBaseApi\n this.patientBaseApi = patientBaseApi\n this.deviceBaseApi = deviceBaseApi\n }\n\n /**\n * Updates the aes exchange keys between the current data owner and another data owner to allow the other data owner to access the exchange key\n * using his new public key. Note that this will make existing exchange keys from the other data owner to the current data owner invalid for\n * encryption.\n * @param otherDataOwner the other data owner.\n * @param newDataOwnerPublicKey a new public key of the other data owner.\n * @param keyPairsByFingerprint all available key pairs to use for the decryption of existing aes exchange keys.\n */\n async giveAccessBackTo(\n otherDataOwner: string,\n newDataOwnerPublicKey: string,\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const other = await this.dataOwnerApi.getCryptoActorStub(otherDataOwner)\n const newKeyHashVersion = getShaVersionForKey(other.stub, newDataOwnerPublicKey)\n if (!newKeyHashVersion) throw new Error(`Public key not found for data owner ${otherDataOwner}`)\n const newPublicKey = await this.primitives.RSA.importKey('spki', hex2ua(newDataOwnerPublicKey), ['encrypt'], newKeyHashVersion)\n await this.extendForGiveAccessBackTo(selfId, otherDataOwner, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n await this.extendForGiveAccessBackTo(otherDataOwner, selfId, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n }\n\n /**\n * Get the encrypted exchange keys for a delegator-delegate pair.\n * @param delegatorId id of the delegator data owner.\n * @param delegateId id of the delegate data owner.\n * @return an array of exchange keys from the delegator to delegate where each key is encrypted with one or more public keys.\n */\n async getEncryptedExchangeKeysFor(delegatorId: string, delegateId: string): Promise<{ [publicKeyFingerprint: string]: string }[]> {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const res: { [publicKeyFingerprint: string]: string }[] = Object.values(delegator.stub.aesExchangeKeys ?? {}).flatMap((delegateToKey) => {\n const encryptedKeyForDelegate = delegateToKey[delegateId]\n if (encryptedKeyForDelegate) {\n return [encryptedKeyForDelegate]\n } else {\n return []\n }\n })\n const legacyDelegation = delegator.stub.hcPartyKeys?.[delegateId]?.[1]\n if (legacyDelegation) res.push({ '': legacyDelegation })\n return res\n }\n\n /**\n * Get all exchange keys where the provided data owner is involved either as the delegator or as the delegate.\n * @param dataOwnerId id of a data owner.\n * @param otherOwnerTypes only exchange keys between the current data owner and data owners of this type will be included in the result. If null considers all delegates\n * @return all exchange keys involving the provided data owner. Note that there may be an overlap between some keys to and from the data owner.\n */\n async getAllExchangeKeysWith(\n dataOwnerId: string,\n otherOwnerTypes: DataOwnerTypeEnum[] | null\n ): Promise<{\n keysToOwner: { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }\n keysFromOwner: { [delegatorFp: string]: { [delegateId: string]: { [entryFp: string]: string } } }\n }> {\n if (otherOwnerTypes != null && otherOwnerTypes.length === 0) throw new Error('otherOwnerTypes must not be empty!')\n const keysToOwner = await Promise.all([\n otherOwnerTypes == null || otherOwnerTypes.find((x) => x === 'hcp')\n ? this.hcpartyBaseApi.getAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n otherOwnerTypes == null || otherOwnerTypes.find((x) => x === 'patient')\n ? this.patientBaseApi.getPatientAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n otherOwnerTypes == null || otherOwnerTypes.find((x) => x === 'device')\n ? this.deviceBaseApi.getDeviceAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n ]).then(([a, b, c]) => ({ ...a, ...b, ...c } as { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }))\n const dataOwner = await this.dataOwnerApi.getCryptoActorStub(dataOwnerId)\n const allOwnerKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(dataOwner.stub, undefined, false)\n const filteredDelegates = new Set(\n await Array.from(new Set(Object.values(allOwnerKeys).flatMap((x) => Object.keys(x)))).reduce(async (acc, ownerId) => {\n const awaitedAcc = await acc\n if (ownerId === dataOwnerId || otherOwnerTypes == null) {\n return [...awaitedAcc, ownerId]\n } else {\n try {\n const dataOwnerType: DataOwnerTypeEnum = (await this.dataOwnerApi.getCryptoActorStub(ownerId)).type\n if (otherOwnerTypes.some((x) => x === dataOwnerType)) {\n return [...awaitedAcc, ownerId]\n } else return awaitedAcc\n } catch (_) {\n return awaitedAcc\n }\n }\n }, Promise.resolve([] as string[]))\n )\n const keysFromOwner = Object.fromEntries(\n Object.entries(allOwnerKeys)\n .map(([delegatorPubKey, delegateToKeys]) => [\n delegatorPubKey,\n Object.fromEntries(\n Object.entries(delegateToKeys).filter(([delegateId]) => filteredDelegates.has(delegateId)) as [string, { [k: string]: string }][]\n ),\n ])\n .filter(([, x]) => Object.keys(x).length > 0) as [string, { [k: string]: { [k: string]: string } }][]\n )\n return { keysToOwner, keysFromOwner }\n }\n\n /**\n * Attempts to decrypt many exchange keys using any of the provided key pairs.\n * @param encryptedExchangeKeys an array of exchange keys where each key is encrypted with one or more public keys.\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return an array all successfully decrypted exchange keys and an array containing all exchange keys which could not be decrypted.\n */\n async tryDecryptExchangeKeys(\n encryptedExchangeKeys: { [publicKeyFingerprint: string]: string }[],\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n }> {\n const raws = new Set<string>()\n const res: {\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n } = { successfulDecryptions: [], failedDecryptions: [] }\n for (const encryptedExchangeKey of encryptedExchangeKeys) {\n const decrypted = await this.tryDecryptExchangeKey(encryptedExchangeKey, keyPairsByFingerprint)\n if (decrypted !== undefined && !raws.has(decrypted.raw)) {\n raws.add(decrypted.raw)\n res.successfulDecryptions.push(decrypted.key)\n } else {\n res.failedDecryptions.push(encryptedExchangeKey)\n }\n }\n return res\n }\n\n private async extendForGiveAccessBackTo(\n delegatorId: string,\n delegateId: string,\n newPublicKeyFp: string,\n newPublicKey: CryptoKey,\n decryptionKeyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n await notConcurrent(this.generateKeyConcurrencyMap, delegatorId, async () => {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const delegate = await this.dataOwnerApi.getCryptoActorStub(delegateId)\n let didUpdateSomeKey = false\n const combinedKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(delegator.stub, delegate.stub, true)\n const updatedExchangeKeys: { [delegatorKey: string]: { [delegateId: string]: { [keyFp: string]: string } } } = {}\n const newEncryptionKeys = { [newPublicKeyFp]: newPublicKey }\n for (const [currDelegatorKey, currDelegatesToKeys] of Object.entries(combinedKeys)) {\n const updatedDelegatesToKeys: { [delegateId: string]: { [keyFp: string]: string } } = {}\n for (const [currDelegateId, currEncryptedKey] of Object.entries(currDelegatesToKeys)) {\n if (delegateId !== currDelegateId || newPublicKeyFp in currEncryptedKey) {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n } else {\n const decrypted = await this.tryDecryptExchangeKey(currEncryptedKey, decryptionKeyPairsByFingerprint)\n if (decrypted) {\n didUpdateSomeKey = true\n updatedDelegatesToKeys[currDelegateId] = {\n ...currEncryptedKey,\n ...(await this.encryptExchangeKey(decrypted, newEncryptionKeys)).encryptedExchangeKey,\n }\n } else {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n }\n }\n }\n updatedExchangeKeys[currDelegatorKey] = updatedDelegatesToKeys\n }\n if (didUpdateSomeKey) {\n await this.dataOwnerApi.modifyCryptoActorStub({\n type: delegator.type,\n stub: {\n ...delegator.stub,\n aesExchangeKeys: updatedExchangeKeys,\n },\n })\n }\n })\n }\n\n /**\n * Attempts to decrypt an exchange key using any of the provided key pairs.\n * @param encryptedExchangeKey an encrypted exchange key, in the form publicKeyXyzFingerprint -> hex(exchangeKeyEncryptedByPrivateKeyXyz).\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided keys.\n */\n private async tryDecryptExchangeKey(\n encryptedExchangeKey: { [publicKeyFingerprint: string]: string },\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n for (const [entryKey, encrypted] of Object.entries(encryptedExchangeKey)) {\n // Due to bugs in past version the entry may actually contain the full public key instead of just the fingerprint.\n const fp = fingerprintV1(entryKey)\n const keyPair = keyPairsByFingerprint[fp]\n if (keyPair !== undefined) {\n const res = await this.tryDecryptExchangeKeyWith(encrypted, keyPair, fp)\n if (res !== undefined) return res\n }\n }\n const defaultEncryptedKey = encryptedExchangeKey['']\n if (defaultEncryptedKey !== undefined) {\n for (const keyPair of Object.values(keyPairsByFingerprint)) {\n // disable error logging, we are not sure keyPair is the correct key\n const res = await this.tryDecryptExchangeKeyWith(defaultEncryptedKey, keyPair, undefined)\n if (res !== undefined) return res\n }\n }\n return undefined\n }\n\n /**\n * Creates an encrypted exchange key for the provided public keys.\n * @param exchangeKey the exchange key in raw and imported format. If undefined a new key will be automatically created.\n * @param publicKeys additional public keys that will have access to the exchange key in spki format, hex-encoded.\n * @return the exchangeKey and an object with the exchange key encrypted with each of the provided public keys, hex-encoded, by fingerprint.\n */\n private async encryptExchangeKey(\n exchangeKey: { raw: string; key: CryptoKey } | undefined,\n publicKeys: { [keyFingerprint: string]: CryptoKey }\n ): Promise<{\n exchangeKey: CryptoKey\n encryptedExchangeKey: { [pubKeyFp: string]: string }\n }> {\n const exchangeKeyCrypto = exchangeKey?.key ?? (await this.primitives.AES.generateCryptoKey(false))\n const exchangeKeyBytes = exchangeKey !== undefined ? hex2ua(exchangeKey.raw) : await this.primitives.AES.exportKey(exchangeKeyCrypto, 'raw')\n const encryptedExchangeKey = await Object.entries(publicKeys).reduce(\n async (acc, [currKeyFp, currKey]) => ({\n ...(await acc),\n [currKeyFp]: ua2hex(await this.primitives.RSA.encrypt(currKey, new Uint8Array(exchangeKeyBytes))),\n }),\n Promise.resolve({} as { [pubKeyFp: string]: string })\n )\n return { exchangeKey: exchangeKeyCrypto, encryptedExchangeKey }\n }\n\n /**\n * Attempts to decrypt an exchange key using the provided key pairs.\n * If you are confident that the provided {@link keyPair} was used to encrypt {@link encryptedByOneKey} you should also provide {@link keyPairFp},\n * so that if the decryption fail an error will be logged to console before returning undefined.\n * @param encryptedByOneKey an exchange key which may be encrypted with {@link keyPair}.\n * @param keyPair an rsa key pair.\n * @param keyPairFp the fingerprint of the provided key pair or undefined to disable logging of error if the decryption failed.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided key.\n */\n private async tryDecryptExchangeKeyWith(\n encryptedByOneKey: string,\n keyPair: KeyPair<CryptoKey>,\n keyPairFp: string | undefined // if undefined will not log errors, when we are not sure the key to be used is the provided key.\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n try {\n const decrypted = await this.primitives.RSA.decrypt(keyPair.privateKey, hex2ua(encryptedByOneKey))\n return { raw: ua2hex(decrypted), key: await this.primitives.AES.importKey('raw', decrypted) }\n } catch (e) {\n if (keyPairFp) {\n console.error(`Failed to decrypt or import exchange key ${encryptedByOneKey} using key with fingerprint ${keyPairFp}.`, e)\n }\n }\n }\n // Copy all legacy hcp exchange keys into the new aes exchange keys\n private async combineLegacyHcpKeysWithAesExchangeKeys(\n owner: CryptoActorStub,\n delegate: CryptoActorStub | undefined,\n fillDelegateLegacyKey: boolean\n ): Promise<{ [ownerPublicKey: string]: { [delegateId: string]: { [fingerprint: string]: string } } }> {\n const ownerLegacyPublicKey = owner.publicKey\n if (ownerLegacyPublicKey != undefined && !(owner.aesExchangeKeys ?? {})[ownerLegacyPublicKey]) {\n /*\n * This condition would technically prevent new updates to the hcPartyKeys to be migrated to the aes exchange keys, but since I can only update\n * data for self data owner and parent entities this is not an issue, because I will always be using the new api from now on and I won't have\n * a situation where the legacy keys are updated but the aes exchange keys are not.\n */\n const counterPartsById: { [id: string]: CryptoActorStub } = {}\n if (fillDelegateLegacyKey) {\n counterPartsById[owner.id!] = owner\n if (delegate) {\n counterPartsById[delegate.id!] = delegate\n }\n for (const other of Object.keys(owner.hcPartyKeys ?? {}).filter((x) => x !== owner.id && x !== delegate?.id)) {\n try {\n counterPartsById[other] = (await this.dataOwnerApi.getCryptoActorStub(other)).stub\n } catch {\n // ignore\n }\n }\n }\n return {\n [ownerLegacyPublicKey]: Object.entries(owner.hcPartyKeys ?? {}).reduce((acc, [hcpId, keys]) => {\n const counterpartKey = counterPartsById[hcpId]?.publicKey\n acc[hcpId] = {\n [fingerprintV1(ownerLegacyPublicKey)]: keys[0],\n [(counterpartKey && fingerprintV1(counterpartKey)) ?? '']: keys[1],\n }\n return acc\n }, {} as { [delegateId: string]: { [fingerprint: string]: string } }),\n ...(owner.aesExchangeKeys ?? {}),\n }\n } else return owner.aesExchangeKeys ?? {}\n }\n}\n"]}
|
|
@@ -140,6 +140,21 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
|
|
|
140
140
|
return body
|
|
141
141
|
? this.encrypt(user, [_.cloneDeep(this.completeNames(body))])
|
|
142
142
|
.then((pats) => super.createPatient(pats[0]))
|
|
143
|
+
.then((patient) => __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
/**
|
|
145
|
+
* This code is a workaround for the fact that the backend is adding empty delegations to the patient when it is created.
|
|
146
|
+
*/
|
|
147
|
+
const patientDelegations = patient.delegations;
|
|
148
|
+
if (patientDelegations != undefined && Object.keys(patientDelegations).length > 0) {
|
|
149
|
+
const areDelegationsEmpty = Object
|
|
150
|
+
.values(patientDelegations)
|
|
151
|
+
.every((delegation) => delegation.length === 0);
|
|
152
|
+
if (areDelegationsEmpty) {
|
|
153
|
+
return yield this.modifyPatientRaw(new models_1.Patient(Object.assign(Object.assign({}, patient), { delegations: {} })));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return patient;
|
|
157
|
+
}))
|
|
143
158
|
.then((p) => this.decrypt(user, [p]))
|
|
144
159
|
.then((pats) => pats[0])
|
|
145
160
|
: Promise.resolve(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icc-patient-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-patient-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccAuthApi, IccPatientApi } from '../icc-api'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\nimport { IccContactXApi } from './icc-contact-x-api'\nimport { IccFormXApi } from './icc-form-x-api'\nimport { IccHcpartyXApi } from './icc-hcparty-x-api'\nimport { IccInvoiceXApi } from './icc-invoice-x-api'\nimport { IccDocumentXApi } from './icc-document-x-api'\nimport { IccHelementXApi } from './icc-helement-x-api'\nimport { IccClassificationXApi } from './icc-classification-x-api'\n\nimport * as _ from 'lodash'\nimport * as models from '../icc-api/model/models'\nimport { Document, IcureStub, ListOfIds, MaintenanceTask, Patient } from '../icc-api/model/models'\nimport { IccCalendarItemXApi } from './icc-calendar-item-x-api'\nimport { b64_2ab } from '../icc-api/model/ModelHelper'\nimport { findName, garnishPersonWithName, hasName } from './utils/person-util'\nimport { EncryptedFieldsManifest, parseEncryptedFields, retry, subscribeToEntityEvents, SubscriptionOptions } from './utils'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { AuthenticationProvider, NoAuthenticationProvider } from './auth/AuthenticationProvider'\nimport { EntityWithDelegationTypeName } from './utils/EntityWithDelegationTypeName'\nimport { SecureDelegation } from '../icc-api/model/SecureDelegation'\nimport { EntityShareOrMetadataUpdateRequest } from '../icc-api/model/requests/EntityShareOrMetadataUpdateRequest'\nimport { MinimalEntityBulkShareResult } from '../icc-api/model/requests/MinimalEntityBulkShareResult'\nimport { EntityShareRequest } from '../icc-api/model/requests/EntityShareRequest'\nimport { ShareMetadataBehaviour } from './crypto/ShareMetadataBehaviour'\nimport { ShareResult } from './utils/ShareResult'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\nimport RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum\nimport { XHR } from '../icc-api/api/XHR'\nimport { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi'\nimport { IccUserXApi } from './icc-user-x-api'\nimport { AbstractFilter } from './filters/filters'\nimport { Connection, ConnectionImpl } from '../icc-api/model/Connection'\nimport { BulkShareOrUpdateMetadataParams } from '../icc-api/model/requests/BulkShareOrUpdateMetadataParams'\n\n// noinspection JSUnusedGlobalSymbols\nexport class IccPatientXApi extends IccPatientApi implements EncryptedEntityXApi<models.Patient> {\n private readonly encryptedFields: EncryptedFieldsManifest\n\n get headers(): Promise<Array<XHR.Header>> {\n return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, EntityWithDelegationTypeName.Patient))\n }\n\n constructor(\n host: string,\n headers: { [key: string]: string },\n private readonly crypto: IccCryptoXApi,\n private readonly contactApi: IccContactXApi,\n private readonly formApi: IccFormXApi,\n private readonly helementApi: IccHelementXApi,\n private readonly invoiceApi: IccInvoiceXApi,\n private readonly documentApi: IccDocumentXApi,\n private readonly hcpartyApi: IccHcpartyXApi,\n private readonly classificationApi: IccClassificationXApi,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly calendarItemApi: IccCalendarItemXApi,\n private readonly userApi: IccUserXApi,\n private readonly authApi: IccAuthApi,\n private readonly autofillAuthor: boolean,\n encryptedKeys: Array<string> = ['note'],\n authenticationProvider: AuthenticationProvider = new NoAuthenticationProvider(),\n fetchImpl: (input: RequestInfo, init?: RequestInit) => Promise<Response> = typeof window !== 'undefined'\n ? window.fetch\n : typeof self !== 'undefined'\n ? self.fetch\n : fetch\n ) {\n super(host, headers, authenticationProvider, fetchImpl)\n\n this.encryptedFields = parseEncryptedFields(encryptedKeys, 'Patient.')\n }\n\n /**\n * Creates a new instance of patient with initialised encryption metadata (not in the database).\n * @param user the current user.\n * @param p initialised data for the patient. 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 * @return a new instance of patient.\n */\n async newInstance(\n user: models.User,\n p: any = {},\n options: {\n additionalDelegates?: { [dataOwnerId: string]: AccessLevelEnum }\n } = {}\n ) {\n const patient = {\n ...(p ?? {}),\n _type: 'org.taktik.icure.entities.Patient',\n id: p?.id ?? this.crypto.primitives.randomUuid(),\n created: p?.created ?? new Date().getTime(),\n modified: p?.modified ?? new Date().getTime(),\n responsible: p?.responsible ?? (this.autofillAuthor ? this.dataOwnerApi.getDataOwnerIdOf(user) : undefined),\n author: p?.author ?? (this.autofillAuthor ? user.id : undefined),\n codes: p?.codes ?? [],\n tags: p?.tags ?? [],\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 extraDelegations = {\n ...Object.fromEntries(\n [...(user.autoDelegations?.all ?? []), ...(user.autoDelegations?.medicalInformation ?? [])].map((d) => [d, AccessLevelEnum.WRITE])\n ),\n ...(options?.additionalDelegates ?? {}),\n }\n const initialisationInfo = await this.crypto.xapi.entityWithInitialisedEncryptedMetadata(\n patient,\n EntityWithDelegationTypeName.Patient,\n undefined,\n undefined,\n true,\n extraDelegations\n )\n return new models.Patient(initialisationInfo.updatedEntity)\n }\n\n completeNames(patient: models.Patient): models.Patient {\n let finalPatient: any = patient\n\n if (!!finalPatient.lastName && !hasName(finalPatient, models.PersonName.UseEnum.Official)) {\n finalPatient = garnishPersonWithName(finalPatient, models.PersonName.UseEnum.Official, finalPatient.lastName, finalPatient.firstName)\n }\n\n if (!!finalPatient.maidenName && !hasName(finalPatient, models.PersonName.UseEnum.Maiden)) {\n finalPatient = garnishPersonWithName(finalPatient, models.PersonName.UseEnum.Maiden, finalPatient.maidenName, finalPatient.firstName)\n }\n\n if (!!finalPatient.alias && !hasName(finalPatient, models.PersonName.UseEnum.Nickname)) {\n finalPatient = garnishPersonWithName(finalPatient, models.PersonName.UseEnum.Nickname, finalPatient.alias, finalPatient.firstName)\n }\n\n if (!finalPatient.lastName && !!hasName(finalPatient, models.PersonName.UseEnum.Official)) {\n const officialName = findName(finalPatient, models.PersonName.UseEnum.Official)\n finalPatient = {\n ...finalPatient,\n lastName: officialName!.lastName,\n firstName: officialName!.firstNames?.[0],\n }\n }\n\n if (!finalPatient.maidenName && !!hasName(finalPatient, models.PersonName.UseEnum.Maiden)) {\n finalPatient = {\n ...finalPatient,\n maidenName: findName(finalPatient, models.PersonName.UseEnum.Maiden)!.lastName,\n }\n }\n\n if (!finalPatient.alias && !!hasName(finalPatient, models.PersonName.UseEnum.Nickname)) {\n finalPatient = {\n ...finalPatient,\n alias: findName(finalPatient, models.PersonName.UseEnum.Nickname)!.lastName,\n }\n }\n\n return new Patient(finalPatient)\n }\n\n /**\n * @deprecated replace with {@link initConfidentialSecretId}\n */\n async initConfidentialDelegation(patient: models.Patient, user: models.User): Promise<models.Patient> {\n return this.initConfidentialSecretId(patient, user)\n }\n\n /**\n * Ensures that the current data owner has some confidential secret ids for the provided patient. If not creates them and updates the patient in the\n * database.\n * @param patient the patient for which you want to initialise the confidential secret id.\n * @param user the current user.\n * @return the updated patient or the original patient if no change was necessary.\n */\n async initConfidentialSecretId(patient: models.Patient, user: models.User): Promise<models.Patient> {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n if (dataOwnerId !== (await this.dataOwnerApi.getCurrentDataOwnerId()))\n throw new Error('You can initialise confidential delegations only for the current data owner')\n let updatedPatient = patient\n if (!patient.rev) {\n updatedPatient = await this.createPatientWithUser(user, patient)\n if (!updatedPatient) throw new Error('Could not create patient')\n }\n const initialised = await this.crypto.confidential.initialiseConfidentialSecretId(updatedPatient, EntityWithDelegationTypeName.Patient, (x) =>\n this.bulkSharePatients(x)\n )\n if (initialised) {\n return initialised\n } else {\n return updatedPatient\n }\n }\n\n createPatient(body?: models.Patient): never {\n throw new Error('Cannot call a method that returns patients without providing a user for de/encryption')\n }\n\n createPatientWithUser(user: models.User, body?: models.Patient): Promise<models.Patient | any> {\n return body\n ? this.encrypt(user, [_.cloneDeep(this.completeNames(body))])\n .then((pats) => super.createPatient(pats[0]))\n .then((p) => this.decrypt(user, [p]))\n .then((pats) => pats[0])\n : Promise.resolve(null)\n }\n\n filterBy(\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n skip?: number,\n sort?: string,\n desc?: boolean,\n body?: models.FilterChainPatient\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n filterByWithUser(\n user: models.User,\n filterChain: models.FilterChainPatient,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n skip?: number,\n sort?: string,\n desc?: boolean\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .filterPatientsBy(startKey, startDocumentId, limit, skip, sort, desc, filterChain)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n findByAccessLogUserAfterDate(\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n findByAccessLogUserAfterDateWithUser(\n user: models.User,\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .findByAccessLogUserAfterDate(userId, accessType, startDate, startKey, startDocumentId, limit)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n findByAccessLogUserAfterDate_1(externalId: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n findByExternalIdWithUser(user: models.User, externalId: string): Promise<models.Patient | any> {\n return super\n .findByExternalId(externalId)\n .then((pats) => this.decrypt(user, [pats]))\n .then((x) => x[0])\n }\n\n findByNameBirthSsinAuto(\n healthcarePartyId?: string,\n filterValue?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n findByNameBirthSsinAutoWithUser(\n user: models.User,\n healthcarePartyId?: string,\n filterValue?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .findByNameBirthSsinAuto(healthcarePartyId, filterValue, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n fuzzySearch(firstName?: string, lastName?: string, dateOfBirth?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n fuzzySearchWithUser(user: models.User, firstName?: string, lastName?: string, dateOfBirth?: number): Promise<Array<models.Patient> | any> {\n return super.fuzzySearch(firstName, lastName, dateOfBirth).then((pats) => this.decrypt(user, pats))\n }\n\n getPatient(patientId: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n getPatientRaw(patientId: string): Promise<models.Patient | any> {\n return super.getPatient(patientId)\n }\n\n getPatientWithUser(user: models.User, patientId: string): Promise<models.Patient | any> {\n return super\n .getPatient(patientId)\n .then((p) => this.tryDecryptOrReturnOriginal([p]))\n .then((pats) => pats[0].entity)\n }\n\n getPotentiallyEncryptedPatientWithUser(user: models.User, patientId: string): Promise<{ patient: models.Patient; decrypted: boolean }> {\n return super\n .getPatient(patientId)\n .then((p) => this.tryDecryptOrReturnOriginal([p]))\n .then((pats) => ({ patient: pats[0].entity, decrypted: pats[0].decrypted }))\n }\n\n getPatients(body?: models.ListOfIds): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n getPatientsWithUser(user: models.User, body?: models.ListOfIds): Promise<Array<models.Patient> | any> {\n return super.getPatients(body).then((pats) => this.decrypt(user, pats))\n }\n\n listDeletedPatients(startDate?: number, endDate?: number, desc?: boolean, startKey?: string, startDocumentId?: string, limit?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listDeletedPatientsWithUser(\n user: models.User,\n startDate?: number,\n endDate?: number,\n desc?: boolean,\n startKey?: string,\n startDocumentId?: string,\n limit?: number\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listDeletedPatients(startDate, endDate, desc, startDocumentId, startKey, limit)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listDeletedPatients_2(firstName?: string, lastName?: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listDeletedPatientsByNameWithUser(user: models.User, firstName?: string, lastName?: string): Promise<Array<models.Patient> | any> {\n return super.listDeletedPatientsByName(firstName, lastName).then((rows) => this.decrypt(user, rows, false))\n }\n\n listOfMergesAfter(date: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listOfMergesAfterWithUser(user: models.User, date: number): Promise<Array<models.Patient> | any> {\n return super.listOfMergesAfter(date).then((pats) => this.decrypt(user, pats, false))\n }\n\n listOfPatientsModifiedAfter(date: number, startKey?: number, startDocumentId?: string, limit?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listOfPatientsModifiedAfterWithUser(\n user: models.User,\n date: number,\n startKey?: number,\n startDocumentId?: string,\n limit?: number\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listOfPatientsModifiedAfter(date, startKey, startDocumentId, limit)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listPatients(hcPartyId?: string, sortField?: string, startKey?: string, startDocumentId?: string, limit?: number, sortDirection?: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listPatientsWithUser(\n user: models.User,\n hcPartyId?: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listPatients(hcPartyId, sortField, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listPatientsByHcParty(\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listPatientsByHcPartyWithUser(\n user: models.User,\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listPatientsByHcParty(hcPartyId, sortField, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listPatientsOfHcParty(\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listPatientsOfHcPartyWithUser(\n user: models.User,\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listPatientsOfHcParty(hcPartyId, sortField, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n mergeInto(toId: string, fromIds: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n mergeIntoWithUser(user: models.User, toId: string, fromIds: string): Promise<models.Patient | any> {\n return super\n .mergeInto(toId, fromIds)\n .then((p) => this.decrypt(user, [p]))\n .then((pats) => pats[0])\n }\n\n modifyPatient(body?: models.Patient): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n /**\n * @internal this method is for internal use only and may be changed without notice.\n */\n modifyPatientRaw(body?: models.Patient): Promise<models.Patient | any> {\n return super.modifyPatient(body)\n }\n\n modifyPatientWithUser(user: models.User, body?: models.Patient): Promise<models.Patient | null> {\n return body ? this.modifyPatientAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : Promise.resolve(null)\n }\n\n private modifyPatientAs(dataOwner: string, body: models.Patient): Promise<models.Patient> {\n return this.encryptAs(dataOwner, [_.cloneDeep(this.completeNames(body))])\n .then((pats) => super.modifyPatient(pats[0]))\n .then((p) => this.decryptAs(dataOwner, [p]))\n .then((pats) => pats[0])\n }\n\n modifyPatientReferral(patientId: string, referralId: string, start?: number, end?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n modifyPatientReferralWithUser(\n user: models.User,\n patientId: string,\n referralId: string,\n start?: number,\n end?: number\n ): Promise<models.Patient | any> {\n return super\n .modifyPatientReferral(patientId, referralId, start, end)\n .then((p) => this.decrypt(user, [p]))\n .then((pats) => pats[0])\n }\n\n encrypt(user: models.User, pats: Array<models.Patient>): Promise<Array<models.Patient>> {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n return this.encryptAs(dataOwnerId, pats)\n }\n\n private encryptAs(dataOwner: string, pats: Array<models.Patient>): Promise<Array<models.Patient>> {\n return this.crypto.xapi.tryEncryptEntities(\n pats,\n EntityWithDelegationTypeName.Patient,\n this.encryptedFields,\n true,\n false,\n (x) => new models.Patient(x)\n )\n }\n\n // If patient can't be decrypted returns patient with encrypted data.\n decrypt(user: models.User, patients: Array<models.Patient>, fillDelegations = true): Promise<Array<models.Patient>> {\n return this.decryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), patients, fillDelegations)\n }\n\n private decryptAs(dataOwner: string, patients: Array<models.Patient>, fillDelegations = true): Promise<Array<models.Patient>> {\n return this.tryDecryptOrReturnOriginal(patients).then((ps) => ps.map((p) => p.entity))\n }\n\n async tryDecryptOrReturnOriginal(patients: Array<models.Patient>): Promise<{ entity: models.Patient; decrypted: boolean }[]> {\n return (await this.crypto.xapi.tryDecryptEntities(patients, EntityWithDelegationTypeName.Patient, (x) => new models.Patient(x))).map((p) => {\n if (p.entity.picture && !(p.entity.picture instanceof ArrayBuffer)) {\n return {\n entity: new models.Patient({\n ...p.entity,\n picture: b64_2ab(p.entity.picture),\n }),\n decrypted: p.decrypted,\n }\n } else return p\n })\n }\n\n /**\n * @deprecated replace with {@link shareAllDataOfPatient}\n */\n async share(\n user: models.User,\n patId: string,\n ownerId: string,\n delegateIds: Array<string>,\n delegationTags: { [key: string]: Array<string> },\n usingPost: boolean = false\n ): Promise<{\n patient: models.Patient | null\n statuses: { [key: string]: { success: boolean | null; error: Error | null } }\n } | null> {\n return this.shareAllDataOfPatient(user, patId, ownerId, delegateIds, delegationTags, usingPost)\n }\n\n async shareAllDataOfPatient(\n user: models.User,\n patId: string,\n ownerId: string,\n delegateIds: Array<string>,\n delegationTags: { [key: string]: Array<string> },\n usingPost: boolean = false\n ): Promise<{\n patient: models.Patient | null\n statuses: { [key: string]: { success: boolean | null; error: Error | null } }\n } | null> {\n const allTags: string[] = _.uniq(_.flatMap(Object.values(delegationTags)))\n const status = {\n contacts: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n forms: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n healthElements: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n invoices: {\n success: allTags.includes('financialInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n documents: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n classifications: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n calendarItems: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n patient: { success: false, error: null, modified: 0 } as {\n success: boolean\n error: Error | null\n },\n }\n const hcp = await this.hcpartyApi.getHealthcareParty(ownerId)\n const parentId = hcp.parentId\n let patient = await retry(() => this.getPatientWithUser(user, patId))\n const patientWithInitialisedEncryption = await this.crypto.xapi.ensureEncryptionKeysInitialised(patient, EntityWithDelegationTypeName.Patient)\n if (patientWithInitialisedEncryption) {\n patient = await this.modifyPatientWithUser(user, patientWithInitialisedEncryption)\n }\n\n if (!patient) {\n status.patient = {\n success: false,\n error: new Error('Patient does not exist or cannot initialise encryption keys'),\n }\n return { patient: patient, statuses: status }\n }\n\n const delSfks = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, ownerId)\n const ecKeys = await this.crypto.xapi.encryptionKeysOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, ownerId)\n\n if (delSfks.length) {\n const retrievedHealthElements = await retry(() =>\n (usingPost\n ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((hes) =>\n parentId\n ? (usingPost\n ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))\n : hes\n )\n )\n const retrievedForms = await retry(() =>\n (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((frms) =>\n parentId\n ? (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))\n : frms\n )\n )\n const retrievedContacts = await retry(() =>\n (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(ownerId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ctcs) =>\n parentId\n ? (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(parentId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))\n : ctcs\n )\n )\n const retrievedInvoices = await retry(() =>\n (usingPost\n ? this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ivs) =>\n parentId\n ? this.invoiceApi\n .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))\n : ivs\n )\n )\n const retrievedClassifications = await retry(() =>\n this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n .then((cls) =>\n parentId\n ? this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))\n : cls\n )\n )\n const retrievedCalendarItems = await retry(() =>\n (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((cls) =>\n parentId\n ? (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))\n : cls\n )\n )\n const isMedicalInfoTags = (tags: string[]) => tags.includes('medicalInformation') || tags.includes('all')\n const isFinancialInfoTags = (tags: string[]) => tags.includes('financialInformation') || tags.includes('all')\n const doShareEntitiesAndUpdateStatus = async (\n entities: models.IcureStub[],\n entitiesType: EntityWithDelegationTypeName,\n status: {\n success: boolean | null\n error: null | Error\n modified: number\n },\n tagsCondition: (tags: string[]) => boolean,\n doShareMinimal: (request: BulkShareOrUpdateMetadataParams) => Promise<MinimalEntityBulkShareResult[]>\n ): Promise<void> => {\n const delegatesToApply = delegateIds.filter((delegateId) => tagsCondition(delegationTags[delegateId]))\n if (entities.length && delegatesToApply.length) {\n const requests: {\n entity: IcureStub\n dataForDelegates: {\n [delegateId: string]: {\n shareSecretIds: string[]\n shareEncryptionKeys: string[]\n shareOwningEntityIds: string[]\n requestedPermissions: RequestedPermissionEnum\n }\n }\n }[] = []\n for (const entity of entities) {\n const currentEntityRequests: {\n [delegateId: string]: {\n shareSecretIds: string[]\n shareEncryptionKeys: string[]\n shareOwningEntityIds: string[]\n requestedPermissions: RequestedPermissionEnum\n }\n } = {}\n const secretIds = await this.crypto.xapi.secretIdsOf({ entity, type: entitiesType }, undefined)\n const encryptionKeys = await this.crypto.xapi.encryptionKeysOf({ entity, type: entitiesType }, undefined)\n const request = {\n shareSecretIds: secretIds,\n shareEncryptionKeys: encryptionKeys,\n shareOwningEntityIds: [patient.id!],\n requestedPermissions: RequestedPermissionEnum.MAX_WRITE,\n }\n for (const delegateId of delegatesToApply) {\n currentEntityRequests[delegateId] = request\n }\n requests.push({ dataForDelegates: currentEntityRequests, entity })\n }\n await this.crypto.xapi\n .bulkShareOrUpdateEncryptedEntityMetadataNoEntities(entitiesType, requests, (x) => doShareMinimal(x))\n .then((shareResult) => {\n status.modified = new Set(shareResult.successfulUpdates.map((x) => x.entityId)).size\n status.success = shareResult.updateErrors.length === 0\n if (!status.success) {\n const errorMsg = `Error while sharing (some) entities of type ${entitiesType} for patient ${patient.id} : ${JSON.stringify(\n shareResult.updateErrors\n )}`\n console.error(errorMsg)\n status.error = new Error(errorMsg)\n }\n })\n .catch((e) => {\n status.success = false\n status.error = e\n })\n } else {\n status.success = true\n }\n }\n await doShareEntitiesAndUpdateStatus(\n retrievedHealthElements,\n EntityWithDelegationTypeName.HealthElement,\n status.healthElements,\n isMedicalInfoTags,\n (x) => this.helementApi.bulkShareHealthElementsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(retrievedContacts, EntityWithDelegationTypeName.Contact, status.contacts, isMedicalInfoTags, (x) =>\n this.contactApi.bulkShareContactsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(retrievedInvoices, EntityWithDelegationTypeName.Invoice, status.invoices, isFinancialInfoTags, (x) =>\n this.invoiceApi.bulkShareInvoicesMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(\n retrievedClassifications,\n EntityWithDelegationTypeName.Classification,\n status.classifications,\n isMedicalInfoTags,\n (x) => this.classificationApi.bulkShareClassificationsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(\n retrievedCalendarItems,\n EntityWithDelegationTypeName.CalendarItem,\n status.calendarItems,\n isMedicalInfoTags,\n (x) => this.calendarItemApi.bulkShareCalendarItemsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(retrievedForms, EntityWithDelegationTypeName.Form, status.forms, isMedicalInfoTags, (x) =>\n this.formApi.bulkShareFormsMinimal(x)\n )\n }\n const sharePatientDataRequest = {\n shareSecretIds: delSfks,\n shareEncryptionKeys: ecKeys,\n shareOwningEntityIds: [],\n requestedPermissions: RequestedPermissionEnum.MAX_WRITE,\n }\n const sharePatientRequest = {\n entity: patient,\n dataForDelegates: Object.fromEntries(delegateIds.map((delegateId) => [delegateId, sharePatientDataRequest])),\n }\n return await this.crypto.xapi\n .bulkShareOrUpdateEncryptedEntityMetadata(EntityWithDelegationTypeName.Patient, [sharePatientRequest], (x) => this.bulkSharePatients(x))\n .then((shareResult) => {\n if (shareResult.updatedEntities.length && !shareResult.updateErrors.length) {\n status.patient.success = true\n return { patient: shareResult.updatedEntities[0], statuses: status }\n } else {\n const errorMsg = `Error while sharing patient with id ${patient.id} : ${JSON.stringify(shareResult.updateErrors)}`\n console.error(errorMsg)\n status.patient.error = new Error(errorMsg)\n status.patient.success = false\n return { patient: shareResult.updatedEntities[0] ?? patient, statuses: status }\n }\n })\n .catch((e) => {\n status.patient.error = e\n status.patient.success = false\n return { patient, statuses: status }\n })\n }\n\n export(user: models.User, patId: string, ownerId: string, usingPost: boolean = false): Promise<{ id: string }> {\n return this.hcpartyApi.getHealthcareParty(ownerId).then((hcp) => {\n const parentId = hcp.parentId\n\n return retry(() => this.getPatientWithUser(user, patId))\n .then(async (patient: models.Patient) => {\n const initialised = await this.crypto.xapi.ensureEncryptionKeysInitialised(patient, EntityWithDelegationTypeName.Patient)\n if (!initialised) {\n return patient\n } else {\n return await this.modifyPatientWithUser(user, initialised)\n }\n })\n .then(async (patient: models.Patient | null) => {\n if (!patient) {\n return Promise.resolve({ id: patId })\n }\n const delSfks = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, ownerId)\n return delSfks.length\n ? Promise.all([\n retry(() =>\n (usingPost\n ? this.helementApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n : this.helementApi.findByHCPartyPatientSecretFKeysArray(ownerId, delSfks)\n ).then((hes) =>\n parentId\n ? (usingPost\n ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))\n : hes\n )\n ) as Promise<Array<models.IcureStub>>,\n retry(() =>\n (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((frms) =>\n parentId\n ? (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))\n : frms\n )\n ) as Promise<Array<models.Form>>,\n retry(() =>\n (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(ownerId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ctcs) =>\n parentId\n ? (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(parentId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))\n : ctcs\n )\n ) as Promise<Array<models.Contact>>,\n retry(() =>\n (usingPost\n ? this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ivs) =>\n parentId\n ? this.invoiceApi\n .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))\n : ivs\n )\n ) as Promise<Array<models.IcureStub>>,\n retry(() =>\n this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n .then((cls) =>\n parentId\n ? this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))\n : cls\n )\n ) as Promise<Array<models.Classification>>,\n retry(async () => {\n const delegationSFKs = _.uniq(delSfks).join(',')\n try {\n let calendarItems = await (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(',')))\n\n if (parentId) {\n const moreCalendarItems = await (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(',')))\n calendarItems = _.uniqBy(calendarItems.concat(moreCalendarItems), 'id')\n }\n\n return calendarItems\n } catch (ex) {\n console.log(`exception occured exporting calendarItem for ownerId: ${ownerId} - ${ex}`)\n //throw ex\n }\n }) as Promise<Array<models.CalendarItem>>,\n ]).then(([hes, frms, ctcs, ivs, cls, cis]) => {\n const docIds: { [key: string]: number } = {}\n ctcs.forEach(\n (c: models.Contact) =>\n c.services &&\n c.services.forEach((s) => s.content && Object.values(s.content).forEach((c) => c && c.documentId && (docIds[c.documentId] = 1)))\n )\n\n return retry(() => this.documentApi.getDocuments(new ListOfIds({ ids: Object.keys(docIds) }))).then((docs: Array<Document>) => {\n return {\n id: patId,\n patient: patient,\n contacts: ctcs,\n forms: frms,\n healthElements: hes,\n invoices: ivs,\n classifications: cls,\n calItems: cis,\n documents: docs,\n }\n })\n })\n : Promise.resolve({\n id: patId,\n patient: patient,\n contacts: [],\n forms: [],\n healthElements: [],\n invoices: [],\n classifications: [],\n calItems: [],\n documents: [],\n })\n })\n })\n }\n\n checkInami(inami: string): boolean {\n const num_inami = inami.replace(new RegExp('[^(0-9)]', 'g'), '')\n\n const checkDigit = num_inami.substring(6, 2)\n const numSansCheck = num_inami.substring(0, 6)\n let retour = false\n\n //modulo du niss\n const modINAMI = parseInt(numSansCheck) % 97\n\n //obtention du num de check 97 - le resultat du mod\n const checkDigit_2 = 97 - modINAMI\n\n if (parseInt(checkDigit) == checkDigit_2) {\n retour = true\n }\n return retour\n }\n\n isValidSsin(ssin: string) {\n ssin = ssin.replace(new RegExp('[^(0-9)]', 'g'), '')\n let isValidNiss = false\n\n const normalNumber =\n /^[0-9][0-9](([0][0-9])|([1][0-2]))(([0-2][0-9])|([3][0-1]))(([0-9]{2}[1-9])|([0-9][1-9][0-9])|([1-9][0-9]{2}))(([0-8][0-9])|([9][0-7]))$/.test(\n ssin\n )\n const bisNumber = /^[0-9][0-9](([2][0-9])|([3][0-2]))(([0-2][0-9])|([3][0-1]))[0-9]{3}(([0-8][0-9])|([9][0-7]))$/.test(ssin)\n const terNumber = /^[0-9][0-9](([4][0-9])|([5][0-2]))(([0-2][0-9])|([3][0-1]))[0-9]{3}(([0-8][0-9])|([9][0-7]))$/.test(ssin)\n\n if (normalNumber || bisNumber || terNumber) {\n isValidNiss =\n 97 - (Number(ssin.substring(0, 9)) % 97) === Number(ssin.substring(9, 2))\n ? true\n : 97 - (Number('2' + ssin.substring(0, 9)) % 97) === Number(ssin.substring(9, 2))\n }\n\n return isValidNiss\n }\n\n async getPatientIdOfChildDocumentForHcpAndHcpParents(\n childDocument: models.Invoice | models.CalendarItem | models.Contact | models.AccessLog,\n hcpId: string,\n childDocumentType: EntityWithDelegationTypeName\n ): Promise<string> {\n const parentIdsArray = await this.crypto.xapi.owningEntityIdsOf({ entity: childDocument, type: childDocumentType }, hcpId)\n\n const multipleParentIds = _.uniq(parentIdsArray).length > 1\n\n if (multipleParentIds) {\n throw 'Child document with id ' + childDocument.id + ' contains multiple parent ids in its CFKs for hcpId: ' + hcpId\n }\n\n const parentId = _.first(parentIdsArray)\n\n if (!parentId) {\n throw 'Parent id is empty in CFK of child document with id ' + childDocument.id + ' for hcpId: ' + hcpId\n }\n\n let patient: models.Patient = await super.getPatient(parentId!)\n\n let mergeLevel = 0\n const maxMergeLevel = 10\n while (patient.mergeToPatientId) {\n mergeLevel++\n if (mergeLevel === maxMergeLevel) {\n throw 'Too many merged levels for parent (Patient) of child document ' + childDocument.id + ' ; hcpId: ' + hcpId\n }\n\n patient = await super.getPatient(patient.mergeToPatientId!)\n }\n\n return patient.id!\n }\n\n /**\n * @return if the logged data owner has write access to the content of the given patient\n */\n async hasWriteAccess(patient: models.Patient): Promise<boolean> {\n return this.crypto.xapi.hasWriteAccess({ entity: patient, type: EntityWithDelegationTypeName.Patient })\n }\n\n /**\n * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param delegateId the id of the data owner which will be granted access to the patient.\n * @param patient the patient to share.\n * @param shareSecretIds the secret ids of the Patient that the delegate will be given access to. Allows the delegate to search for data where the\n * shared Patient is the owning entity id.\n * @param options optional parameters to customize the sharing behaviour:\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * patient does not have encrypted content.\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return the updated entity\n */\n async shareWith(\n delegateId: string,\n patient: models.Patient,\n shareSecretIds: string[],\n options: {\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n } = {}\n ): Promise<models.Patient> {\n return this.shareWithMany(patient, { [delegateId]: { ...options, shareSecretIds: shareSecretIds } })\n }\n\n /**\n * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param patient the patient 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 the secret ids of the Patient that the delegate will be given access to. Allows the delegate to search for data where the\n * shared Patient is the owning entity id.\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * patient does not have encrypted content.\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return the updated entity\n */\n async shareWithMany(\n patient: models.Patient,\n delegates: {\n [delegateIds: string]: {\n shareSecretIds: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<models.Patient> {\n return (await this.tryShareWithMany(patient, delegates)).updatedEntityOrThrow\n }\n\n /**\n * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param patient the patient 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 the secret ids of the Patient that the delegate will be given access to. Allows the delegate to search for data where the\n * shared Patient is the owning entity id.\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * patient does not have encrypted content.\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return a promise which will contain the result of the operation: the updated entity if the operation was successful or details of the error if\n * the operation failed.\n */\n async tryShareWithMany(\n patient: models.Patient,\n delegates: {\n [delegateIds: string]: {\n shareSecretIds: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<ShareResult<models.Patient>> {\n const self = await this.dataOwnerApi.getCurrentDataOwnerId()\n // All entities should have an encryption key.\n const entityWithEncryptionKey = await this.crypto.xapi.ensureEncryptionKeysInitialised(patient, EntityWithDelegationTypeName.Patient)\n const updatedEntity = entityWithEncryptionKey ? await this.modifyPatientAs(self, entityWithEncryptionKey) : patient\n return this.crypto.xapi\n .simpleShareOrUpdateEncryptedEntityMetadata(\n {\n entity: updatedEntity,\n type: EntityWithDelegationTypeName.Patient,\n },\n Object.fromEntries(\n Object.entries(delegates).map(([delegateId, options]) => [\n delegateId,\n {\n requestedPermissions: options.requestedPermissions,\n shareEncryptionKeys: options.shareEncryptionKey,\n shareOwningEntityIds: ShareMetadataBehaviour.NEVER,\n shareSecretIds: options.shareSecretIds,\n },\n ])\n ),\n (x) => this.bulkSharePatients(x)\n )\n .then((r) => r.mapSuccessAsync((e) => this.decryptAs(self, [e]).then((es) => es[0])))\n }\n\n /**\n * @param patient a patient\n * @return all the decryptable secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the\n * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.\n */\n decryptSecretIdsOf(patient: models.Patient): Promise<string[]> {\n return this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, undefined)\n }\n\n /**\n * @param patient a patient\n * @return the confidential secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the\n * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.\n */\n decryptConfidentialSecretIdsOf(patient: models.Patient): Promise<string[]> {\n return this.crypto.confidential.getConfidentialSecretIds({ entity: patient, type: EntityWithDelegationTypeName.Patient }, undefined)\n }\n\n /**\n * @param patient a patient\n * @return the non-confidential secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the\n * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.\n */\n decryptNonConfidentialSecretIdsOf(patient: models.Patient): Promise<string[]> {\n return this.crypto.confidential.getSecretIdsSharedWithParents({ entity: patient, type: EntityWithDelegationTypeName.Patient })\n }\n\n getDataOwnersWithAccessTo(\n entity: models.Patient\n ): Promise<{ permissionsByDataOwnerId: { [p: string]: AccessLevelEnum }; hasUnknownAnonymousDataOwners: boolean }> {\n return this.crypto.delegationsDeAnonymization.getDataOwnersWithAccessTo({ entity, type: EntityWithDelegationTypeName.Patient })\n }\n\n getEncryptionKeysOf(entity: models.Patient): Promise<string[]> {\n return this.crypto.xapi.encryptionKeysOf({ entity, type: EntityWithDelegationTypeName.Patient }, undefined)\n }\n\n /**\n * Merge two patients into one. This method performs the following operations:\n * - The `from` patient will be soft-deleted, and it will point to the `into` patient. Only the `deletionDate` and `mergeToPatientId` fields of the\n * patient will be changed (automatically by this method). Note that the value of {@link from} is only used to verify that the client is aware of\n * the last version of the `from` patient: any changes to its content and/or metadata compared to what is actually stored in the database will be\n * ignored.\n * - The metadata of the `into` patient will be automatically updated to contain also the metadata of the `from` patient and to keep track of the\n * merge:\n * - the `mergedIds` will be updated to contain the `from` patient id\n * - all secret ids of the `from` patient will be added to the `into` patient\n * - all data owners (including anonymous data owners) with access to the `from` patient will have the same access to the merged `into` patient\n * (unless they already had greater access to the `into` patient, in which case they keep the greater access)\n * - The content of the `into` patient will be updated to match the content (name, address, note, ...) of the provided {@link mergedInto} parameter.\n * Note that since the metadata is automatically updated by this method you must not change the metadata of the `mergedInto` patient\n * (`delegations`, mergedInto`, ...): if there is any change between the metadata of the provided `mergedInto` patient and the stored patient this\n * method will fail with an error.\n *\n * In case the revisions of {@link from} and/or {@link mergedInto} does not match the latest revisions for these patients in the database this\n * method will fail without soft-deleting the `from` patient and without updating the `into` patient with the merged content and metadata. You will\n * have to retrieve the updated versions of both patients before retrying the merge.\n *\n * Finally, note that this method only merges existing data, and does not perform any automatic sharing of the data. The secret ids and encryption\n * keys will not be shared with users that had access only to one of the entity, you will have to use the {@link shareWith} method after the merge\n * if you want to do so.\n * For example consider hcps A, B with access to P' and hcps A, C with access to P'', and we merge P'' into P'. After the merge:\n * - A has access to all secret ids of the merged patient and to the encryption key of the merged patient\n * - B has access to the encryption key of the merged patient (since it is the same as in P'), but only to the secret id which was originally from\n * the unmerged P'\n * - C has no access to the encryption key of the merged patient, and has access only to the secret id which was originally from the unmerged P''\n *\n * @param from the original, unmodified `from` patient. Its content will be unchanged and its metadata will be automatically updated by this method\n * to reflect the merge.\n * @param mergedInto the `into` patient with updated content result of the merge with the `from` patient, as specified by your application logic.\n * The metadata of the `mergedInto` patient must not differ from the metadata of the stored version of the patient, since it will be automatically\n * updated by the method.\n * @return the updated `into` patient.\n */\n async mergePatients(from: Patient, mergedInto: Patient): Promise<Patient> {\n const encryptedMerged = (await this.encryptAs(await this.dataOwnerApi.getCurrentDataOwnerId(), [mergedInto]))[0]\n const merged = await super.baseMergePatients(from.id!, from.rev!, encryptedMerged)\n return (await this.tryDecryptOrReturnOriginal([merged]))[0].entity\n }\n\n async subscribeToPatientEvents(\n eventTypes: ('CREATE' | 'UPDATE' | 'DELETE')[],\n filter: AbstractFilter<Patient> | undefined,\n eventFired: (patient: Patient) => Promise<void>,\n options: SubscriptionOptions = {}\n ): Promise<Connection> {\n const currentUser = await this.userApi.getCurrentUser()\n return subscribeToEntityEvents(\n this.host,\n this.authApi,\n EntityWithDelegationTypeName.Patient,\n eventTypes,\n filter,\n eventFired,\n options,\n async (encrypted) => (await this.decrypt(currentUser, [encrypted]))[0]\n ).then((rs) => new ConnectionImpl(rs))\n }\n\n createDelegationDeAnonymizationMetadata(entity: Patient, delegates: string[]): Promise<void> {\n return this.crypto.delegationsDeAnonymization.createOrUpdateDeAnonymizationInfo({ entity, type: EntityWithDelegationTypeName.Patient }, delegates)\n }\n\n /**\n * Initializes the exchange data towards a newly invited patient. This allows the doctor to share data with the\n * patient even if the patient has not yet initialized a keypair for himself.\n *\n * This method should be used only if the patient has not yet initialized a keypair for himself. If the patient has\n * already initialized a keypair this method does nothing and returns false. In this case the exchange data will be\n * automatically created the first time you share data with the patient, and your implementation of the crypto\n * strategies will be used to validate the public keys of the patient.\n *\n * Once exchange data is initialized you can use the {@link IccRecoveryXApi.createExchangeDataRecoveryInfo} to\n * generate a key that the patient will be able to use on his first login to immediately gain access to the exchange\n * data (through the {@link IccRecoveryXApi.recoverExchangeData} method).\n *\n * @param patientId the id of the newly invited patient.\n * @return true if exchange data was initialized, false if the patient already has a key pair and the exchange data\n * will be initialized in the standard way (automatically on the first time data is shared with the user).\n */\n async forceInitialiseExchangeDataToNewlyInvitedPatient(patientId: string): Promise<boolean> {\n const patient = await super.getPatient(patientId)\n if (this.dataOwnerApi.getHexPublicKeysOf(patient).size) return false\n await this.crypto.exchangeData.getOrCreateEncryptionDataTo(patientId, true)\n return true\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"icc-patient-x-api.js","sourceRoot":"","sources":["../../icc-x-api/icc-patient-x-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccAuthApi, IccPatientApi } from '../icc-api'\nimport { IccCryptoXApi } from './icc-crypto-x-api'\nimport { IccContactXApi } from './icc-contact-x-api'\nimport { IccFormXApi } from './icc-form-x-api'\nimport { IccHcpartyXApi } from './icc-hcparty-x-api'\nimport { IccInvoiceXApi } from './icc-invoice-x-api'\nimport { IccDocumentXApi } from './icc-document-x-api'\nimport { IccHelementXApi } from './icc-helement-x-api'\nimport { IccClassificationXApi } from './icc-classification-x-api'\n\nimport * as _ from 'lodash'\nimport * as models from '../icc-api/model/models'\nimport { Document, IcureStub, ListOfIds, MaintenanceTask, Patient } from '../icc-api/model/models'\nimport { IccCalendarItemXApi } from './icc-calendar-item-x-api'\nimport { b64_2ab } from '../icc-api/model/ModelHelper'\nimport { findName, garnishPersonWithName, hasName } from './utils/person-util'\nimport { EncryptedFieldsManifest, parseEncryptedFields, retry, subscribeToEntityEvents, SubscriptionOptions } from './utils'\nimport { IccDataOwnerXApi } from './icc-data-owner-x-api'\nimport { AuthenticationProvider, NoAuthenticationProvider } from './auth/AuthenticationProvider'\nimport { EntityWithDelegationTypeName } from './utils/EntityWithDelegationTypeName'\nimport { SecureDelegation } from '../icc-api/model/SecureDelegation'\nimport { MinimalEntityBulkShareResult } from '../icc-api/model/requests/MinimalEntityBulkShareResult'\nimport { EntityShareRequest } from '../icc-api/model/requests/EntityShareRequest'\nimport { ShareMetadataBehaviour } from './crypto/ShareMetadataBehaviour'\nimport { ShareResult } from './utils/ShareResult'\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\nimport RequestedPermissionEnum = EntityShareRequest.RequestedPermissionEnum\nimport { XHR } from '../icc-api/api/XHR'\nimport { EncryptedEntityXApi } from './basexapi/EncryptedEntityXApi'\nimport { IccUserXApi } from './icc-user-x-api'\nimport { AbstractFilter } from './filters/filters'\nimport { Connection, ConnectionImpl } from '../icc-api/model/Connection'\nimport { BulkShareOrUpdateMetadataParams } from '../icc-api/model/requests/BulkShareOrUpdateMetadataParams'\n\n// noinspection JSUnusedGlobalSymbols\nexport class IccPatientXApi extends IccPatientApi implements EncryptedEntityXApi<models.Patient> {\n private readonly encryptedFields: EncryptedFieldsManifest\n\n get headers(): Promise<Array<XHR.Header>> {\n return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, EntityWithDelegationTypeName.Patient))\n }\n\n constructor(\n host: string,\n headers: { [key: string]: string },\n private readonly crypto: IccCryptoXApi,\n private readonly contactApi: IccContactXApi,\n private readonly formApi: IccFormXApi,\n private readonly helementApi: IccHelementXApi,\n private readonly invoiceApi: IccInvoiceXApi,\n private readonly documentApi: IccDocumentXApi,\n private readonly hcpartyApi: IccHcpartyXApi,\n private readonly classificationApi: IccClassificationXApi,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly calendarItemApi: IccCalendarItemXApi,\n private readonly userApi: IccUserXApi,\n private readonly authApi: IccAuthApi,\n private readonly autofillAuthor: boolean,\n encryptedKeys: Array<string> = ['note'],\n authenticationProvider: AuthenticationProvider = new NoAuthenticationProvider(),\n fetchImpl: (input: RequestInfo, init?: RequestInit) => Promise<Response> = typeof window !== 'undefined'\n ? window.fetch\n : typeof self !== 'undefined'\n ? self.fetch\n : fetch\n ) {\n super(host, headers, authenticationProvider, fetchImpl)\n\n this.encryptedFields = parseEncryptedFields(encryptedKeys, 'Patient.')\n }\n\n /**\n * Creates a new instance of patient with initialised encryption metadata (not in the database).\n * @param user the current user.\n * @param p initialised data for the patient. 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 * @return a new instance of patient.\n */\n async newInstance(\n user: models.User,\n p: any = {},\n options: {\n additionalDelegates?: { [dataOwnerId: string]: AccessLevelEnum }\n } = {}\n ) {\n const patient = {\n ...(p ?? {}),\n _type: 'org.taktik.icure.entities.Patient',\n id: p?.id ?? this.crypto.primitives.randomUuid(),\n created: p?.created ?? new Date().getTime(),\n modified: p?.modified ?? new Date().getTime(),\n responsible: p?.responsible ?? (this.autofillAuthor ? this.dataOwnerApi.getDataOwnerIdOf(user) : undefined),\n author: p?.author ?? (this.autofillAuthor ? user.id : undefined),\n codes: p?.codes ?? [],\n tags: p?.tags ?? [],\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 extraDelegations = {\n ...Object.fromEntries(\n [...(user.autoDelegations?.all ?? []), ...(user.autoDelegations?.medicalInformation ?? [])].map((d) => [d, AccessLevelEnum.WRITE])\n ),\n ...(options?.additionalDelegates ?? {}),\n }\n const initialisationInfo = await this.crypto.xapi.entityWithInitialisedEncryptedMetadata(\n patient,\n EntityWithDelegationTypeName.Patient,\n undefined,\n undefined,\n true,\n extraDelegations\n )\n return new models.Patient(initialisationInfo.updatedEntity)\n }\n\n completeNames(patient: models.Patient): models.Patient {\n let finalPatient: any = patient\n\n if (!!finalPatient.lastName && !hasName(finalPatient, models.PersonName.UseEnum.Official)) {\n finalPatient = garnishPersonWithName(finalPatient, models.PersonName.UseEnum.Official, finalPatient.lastName, finalPatient.firstName)\n }\n\n if (!!finalPatient.maidenName && !hasName(finalPatient, models.PersonName.UseEnum.Maiden)) {\n finalPatient = garnishPersonWithName(finalPatient, models.PersonName.UseEnum.Maiden, finalPatient.maidenName, finalPatient.firstName)\n }\n\n if (!!finalPatient.alias && !hasName(finalPatient, models.PersonName.UseEnum.Nickname)) {\n finalPatient = garnishPersonWithName(finalPatient, models.PersonName.UseEnum.Nickname, finalPatient.alias, finalPatient.firstName)\n }\n\n if (!finalPatient.lastName && !!hasName(finalPatient, models.PersonName.UseEnum.Official)) {\n const officialName = findName(finalPatient, models.PersonName.UseEnum.Official)\n finalPatient = {\n ...finalPatient,\n lastName: officialName!.lastName,\n firstName: officialName!.firstNames?.[0],\n }\n }\n\n if (!finalPatient.maidenName && !!hasName(finalPatient, models.PersonName.UseEnum.Maiden)) {\n finalPatient = {\n ...finalPatient,\n maidenName: findName(finalPatient, models.PersonName.UseEnum.Maiden)!.lastName,\n }\n }\n\n if (!finalPatient.alias && !!hasName(finalPatient, models.PersonName.UseEnum.Nickname)) {\n finalPatient = {\n ...finalPatient,\n alias: findName(finalPatient, models.PersonName.UseEnum.Nickname)!.lastName,\n }\n }\n\n return new Patient(finalPatient)\n }\n\n /**\n * @deprecated replace with {@link initConfidentialSecretId}\n */\n async initConfidentialDelegation(patient: models.Patient, user: models.User): Promise<models.Patient> {\n return this.initConfidentialSecretId(patient, user)\n }\n\n /**\n * Ensures that the current data owner has some confidential secret ids for the provided patient. If not creates them and updates the patient in the\n * database.\n * @param patient the patient for which you want to initialise the confidential secret id.\n * @param user the current user.\n * @return the updated patient or the original patient if no change was necessary.\n */\n async initConfidentialSecretId(patient: models.Patient, user: models.User): Promise<models.Patient> {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n if (dataOwnerId !== (await this.dataOwnerApi.getCurrentDataOwnerId()))\n throw new Error('You can initialise confidential delegations only for the current data owner')\n let updatedPatient = patient\n if (!patient.rev) {\n updatedPatient = await this.createPatientWithUser(user, patient)\n if (!updatedPatient) throw new Error('Could not create patient')\n }\n const initialised = await this.crypto.confidential.initialiseConfidentialSecretId(updatedPatient, EntityWithDelegationTypeName.Patient, (x) =>\n this.bulkSharePatients(x)\n )\n if (initialised) {\n return initialised\n } else {\n return updatedPatient\n }\n }\n\n createPatient(body?: models.Patient): never {\n throw new Error('Cannot call a method that returns patients without providing a user for de/encryption')\n }\n\n createPatientWithUser(user: models.User, body?: models.Patient): Promise<models.Patient | any> {\n return body\n ? this.encrypt(user, [_.cloneDeep(this.completeNames(body))])\n .then((pats) => super.createPatient(pats[0]))\n .then(async (patient: Patient) => {\n /**\n * This code is a workaround for the fact that the backend is adding empty delegations to the patient when it is created.\n */\n\n const patientDelegations = patient.delegations\n\n if (patientDelegations != undefined && Object.keys(patientDelegations).length > 0) {\n const areDelegationsEmpty = Object\n .values(patientDelegations)\n .every((delegation) => delegation.length === 0)\n\n if (areDelegationsEmpty) {\n return await this.modifyPatientRaw(\n new Patient({\n ...patient,\n delegations: {},\n })\n )\n }\n }\n return patient\n })\n .then((p) => this.decrypt(user, [p]))\n .then((pats) => pats[0])\n : Promise.resolve(null)\n }\n\n filterBy(\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n skip?: number,\n sort?: string,\n desc?: boolean,\n body?: models.FilterChainPatient\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n filterByWithUser(\n user: models.User,\n filterChain: models.FilterChainPatient,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n skip?: number,\n sort?: string,\n desc?: boolean\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .filterPatientsBy(startKey, startDocumentId, limit, skip, sort, desc, filterChain)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n findByAccessLogUserAfterDate(\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n findByAccessLogUserAfterDateWithUser(\n user: models.User,\n userId: string,\n accessType?: string,\n startDate?: number,\n startKey?: string,\n startDocumentId?: string,\n limit?: number\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .findByAccessLogUserAfterDate(userId, accessType, startDate, startKey, startDocumentId, limit)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n findByAccessLogUserAfterDate_1(externalId: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n findByExternalIdWithUser(user: models.User, externalId: string): Promise<models.Patient | any> {\n return super\n .findByExternalId(externalId)\n .then((pats) => this.decrypt(user, [pats]))\n .then((x) => x[0])\n }\n\n findByNameBirthSsinAuto(\n healthcarePartyId?: string,\n filterValue?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n findByNameBirthSsinAutoWithUser(\n user: models.User,\n healthcarePartyId?: string,\n filterValue?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .findByNameBirthSsinAuto(healthcarePartyId, filterValue, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n fuzzySearch(firstName?: string, lastName?: string, dateOfBirth?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n fuzzySearchWithUser(user: models.User, firstName?: string, lastName?: string, dateOfBirth?: number): Promise<Array<models.Patient> | any> {\n return super.fuzzySearch(firstName, lastName, dateOfBirth).then((pats) => this.decrypt(user, pats))\n }\n\n getPatient(patientId: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n getPatientRaw(patientId: string): Promise<models.Patient | any> {\n return super.getPatient(patientId)\n }\n\n getPatientWithUser(user: models.User, patientId: string): Promise<models.Patient | any> {\n return super\n .getPatient(patientId)\n .then((p) => this.tryDecryptOrReturnOriginal([p]))\n .then((pats) => pats[0].entity)\n }\n\n getPotentiallyEncryptedPatientWithUser(user: models.User, patientId: string): Promise<{ patient: models.Patient; decrypted: boolean }> {\n return super\n .getPatient(patientId)\n .then((p) => this.tryDecryptOrReturnOriginal([p]))\n .then((pats) => ({ patient: pats[0].entity, decrypted: pats[0].decrypted }))\n }\n\n getPatients(body?: models.ListOfIds): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n getPatientsWithUser(user: models.User, body?: models.ListOfIds): Promise<Array<models.Patient> | any> {\n return super.getPatients(body).then((pats) => this.decrypt(user, pats))\n }\n\n listDeletedPatients(startDate?: number, endDate?: number, desc?: boolean, startKey?: string, startDocumentId?: string, limit?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listDeletedPatientsWithUser(\n user: models.User,\n startDate?: number,\n endDate?: number,\n desc?: boolean,\n startKey?: string,\n startDocumentId?: string,\n limit?: number\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listDeletedPatients(startDate, endDate, desc, startDocumentId, startKey, limit)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listDeletedPatients_2(firstName?: string, lastName?: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listDeletedPatientsByNameWithUser(user: models.User, firstName?: string, lastName?: string): Promise<Array<models.Patient> | any> {\n return super.listDeletedPatientsByName(firstName, lastName).then((rows) => this.decrypt(user, rows, false))\n }\n\n listOfMergesAfter(date: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listOfMergesAfterWithUser(user: models.User, date: number): Promise<Array<models.Patient> | any> {\n return super.listOfMergesAfter(date).then((pats) => this.decrypt(user, pats, false))\n }\n\n listOfPatientsModifiedAfter(date: number, startKey?: number, startDocumentId?: string, limit?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listOfPatientsModifiedAfterWithUser(\n user: models.User,\n date: number,\n startKey?: number,\n startDocumentId?: string,\n limit?: number\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listOfPatientsModifiedAfter(date, startKey, startDocumentId, limit)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listPatients(hcPartyId?: string, sortField?: string, startKey?: string, startDocumentId?: string, limit?: number, sortDirection?: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listPatientsWithUser(\n user: models.User,\n hcPartyId?: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listPatients(hcPartyId, sortField, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listPatientsByHcParty(\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listPatientsByHcPartyWithUser(\n user: models.User,\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listPatientsByHcParty(hcPartyId, sortField, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n listPatientsOfHcParty(\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n listPatientsOfHcPartyWithUser(\n user: models.User,\n hcPartyId: string,\n sortField?: string,\n startKey?: string,\n startDocumentId?: string,\n limit?: number,\n sortDirection?: string\n ): Promise<models.PaginatedListPatient | any> {\n return super\n .listPatientsOfHcParty(hcPartyId, sortField, startKey, startDocumentId, limit, sortDirection)\n .then((pl) => this.decrypt(user, pl.rows!, false).then((dr) => Object.assign(pl, { rows: dr })))\n }\n\n mergeInto(toId: string, fromIds: string): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n mergeIntoWithUser(user: models.User, toId: string, fromIds: string): Promise<models.Patient | any> {\n return super\n .mergeInto(toId, fromIds)\n .then((p) => this.decrypt(user, [p]))\n .then((pats) => pats[0])\n }\n\n modifyPatient(body?: models.Patient): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n /**\n * @internal this method is for internal use only and may be changed without notice.\n */\n modifyPatientRaw(body?: models.Patient): Promise<models.Patient | any> {\n return super.modifyPatient(body)\n }\n\n modifyPatientWithUser(user: models.User, body?: models.Patient): Promise<models.Patient | null> {\n return body ? this.modifyPatientAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : Promise.resolve(null)\n }\n\n private modifyPatientAs(dataOwner: string, body: models.Patient): Promise<models.Patient> {\n return this.encryptAs(dataOwner, [_.cloneDeep(this.completeNames(body))])\n .then((pats) => super.modifyPatient(pats[0]))\n .then((p) => this.decryptAs(dataOwner, [p]))\n .then((pats) => pats[0])\n }\n\n modifyPatientReferral(patientId: string, referralId: string, start?: number, end?: number): never {\n throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption')\n }\n\n modifyPatientReferralWithUser(\n user: models.User,\n patientId: string,\n referralId: string,\n start?: number,\n end?: number\n ): Promise<models.Patient | any> {\n return super\n .modifyPatientReferral(patientId, referralId, start, end)\n .then((p) => this.decrypt(user, [p]))\n .then((pats) => pats[0])\n }\n\n encrypt(user: models.User, pats: Array<models.Patient>): Promise<Array<models.Patient>> {\n const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user)\n return this.encryptAs(dataOwnerId, pats)\n }\n\n private encryptAs(dataOwner: string, pats: Array<models.Patient>): Promise<Array<models.Patient>> {\n return this.crypto.xapi.tryEncryptEntities(\n pats,\n EntityWithDelegationTypeName.Patient,\n this.encryptedFields,\n true,\n false,\n (x) => new models.Patient(x)\n )\n }\n\n // If patient can't be decrypted returns patient with encrypted data.\n decrypt(user: models.User, patients: Array<models.Patient>, fillDelegations = true): Promise<Array<models.Patient>> {\n return this.decryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), patients, fillDelegations)\n }\n\n private decryptAs(dataOwner: string, patients: Array<models.Patient>, fillDelegations = true): Promise<Array<models.Patient>> {\n return this.tryDecryptOrReturnOriginal(patients).then((ps) => ps.map((p) => p.entity))\n }\n\n async tryDecryptOrReturnOriginal(patients: Array<models.Patient>): Promise<{ entity: models.Patient; decrypted: boolean }[]> {\n return (await this.crypto.xapi.tryDecryptEntities(patients, EntityWithDelegationTypeName.Patient, (x) => new models.Patient(x))).map((p) => {\n if (p.entity.picture && !(p.entity.picture instanceof ArrayBuffer)) {\n return {\n entity: new models.Patient({\n ...p.entity,\n picture: b64_2ab(p.entity.picture),\n }),\n decrypted: p.decrypted,\n }\n } else return p\n })\n }\n\n /**\n * @deprecated replace with {@link shareAllDataOfPatient}\n */\n async share(\n user: models.User,\n patId: string,\n ownerId: string,\n delegateIds: Array<string>,\n delegationTags: { [key: string]: Array<string> },\n usingPost: boolean = false\n ): Promise<{\n patient: models.Patient | null\n statuses: { [key: string]: { success: boolean | null; error: Error | null } }\n } | null> {\n return this.shareAllDataOfPatient(user, patId, ownerId, delegateIds, delegationTags, usingPost)\n }\n\n async shareAllDataOfPatient(\n user: models.User,\n patId: string,\n ownerId: string,\n delegateIds: Array<string>,\n delegationTags: { [key: string]: Array<string> },\n usingPost: boolean = false\n ): Promise<{\n patient: models.Patient | null\n statuses: { [key: string]: { success: boolean | null; error: Error | null } }\n } | null> {\n const allTags: string[] = _.uniq(_.flatMap(Object.values(delegationTags)))\n const status = {\n contacts: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n forms: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n healthElements: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n invoices: {\n success: allTags.includes('financialInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n documents: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n classifications: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n calendarItems: {\n success: allTags.includes('medicalInformation') || allTags.includes('all') ? false : null,\n error: null,\n modified: 0,\n },\n patient: { success: false, error: null, modified: 0 } as {\n success: boolean\n error: Error | null\n },\n }\n const hcp = await this.hcpartyApi.getHealthcareParty(ownerId)\n const parentId = hcp.parentId\n let patient = await retry(() => this.getPatientWithUser(user, patId))\n const patientWithInitialisedEncryption = await this.crypto.xapi.ensureEncryptionKeysInitialised(patient, EntityWithDelegationTypeName.Patient)\n if (patientWithInitialisedEncryption) {\n patient = await this.modifyPatientWithUser(user, patientWithInitialisedEncryption)\n }\n\n if (!patient) {\n status.patient = {\n success: false,\n error: new Error('Patient does not exist or cannot initialise encryption keys'),\n }\n return { patient: patient, statuses: status }\n }\n\n const delSfks = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, ownerId)\n const ecKeys = await this.crypto.xapi.encryptionKeysOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, ownerId)\n\n if (delSfks.length) {\n const retrievedHealthElements = await retry(() =>\n (usingPost\n ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((hes) =>\n parentId\n ? (usingPost\n ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))\n : hes\n )\n )\n const retrievedForms = await retry(() =>\n (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((frms) =>\n parentId\n ? (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))\n : frms\n )\n )\n const retrievedContacts = await retry(() =>\n (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(ownerId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ctcs) =>\n parentId\n ? (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(parentId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))\n : ctcs\n )\n )\n const retrievedInvoices = await retry(() =>\n (usingPost\n ? this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ivs) =>\n parentId\n ? this.invoiceApi\n .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))\n : ivs\n )\n )\n const retrievedClassifications = await retry(() =>\n this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n .then((cls) =>\n parentId\n ? this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))\n : cls\n )\n )\n const retrievedCalendarItems = await retry(() =>\n (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((cls) =>\n parentId\n ? (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))\n : cls\n )\n )\n const isMedicalInfoTags = (tags: string[]) => tags.includes('medicalInformation') || tags.includes('all')\n const isFinancialInfoTags = (tags: string[]) => tags.includes('financialInformation') || tags.includes('all')\n const doShareEntitiesAndUpdateStatus = async (\n entities: models.IcureStub[],\n entitiesType: EntityWithDelegationTypeName,\n status: {\n success: boolean | null\n error: null | Error\n modified: number\n },\n tagsCondition: (tags: string[]) => boolean,\n doShareMinimal: (request: BulkShareOrUpdateMetadataParams) => Promise<MinimalEntityBulkShareResult[]>\n ): Promise<void> => {\n const delegatesToApply = delegateIds.filter((delegateId) => tagsCondition(delegationTags[delegateId]))\n if (entities.length && delegatesToApply.length) {\n const requests: {\n entity: IcureStub\n dataForDelegates: {\n [delegateId: string]: {\n shareSecretIds: string[]\n shareEncryptionKeys: string[]\n shareOwningEntityIds: string[]\n requestedPermissions: RequestedPermissionEnum\n }\n }\n }[] = []\n for (const entity of entities) {\n const currentEntityRequests: {\n [delegateId: string]: {\n shareSecretIds: string[]\n shareEncryptionKeys: string[]\n shareOwningEntityIds: string[]\n requestedPermissions: RequestedPermissionEnum\n }\n } = {}\n const secretIds = await this.crypto.xapi.secretIdsOf({ entity, type: entitiesType }, undefined)\n const encryptionKeys = await this.crypto.xapi.encryptionKeysOf({ entity, type: entitiesType }, undefined)\n const request = {\n shareSecretIds: secretIds,\n shareEncryptionKeys: encryptionKeys,\n shareOwningEntityIds: [patient.id!],\n requestedPermissions: RequestedPermissionEnum.MAX_WRITE,\n }\n for (const delegateId of delegatesToApply) {\n currentEntityRequests[delegateId] = request\n }\n requests.push({ dataForDelegates: currentEntityRequests, entity })\n }\n await this.crypto.xapi\n .bulkShareOrUpdateEncryptedEntityMetadataNoEntities(entitiesType, requests, (x) => doShareMinimal(x))\n .then((shareResult) => {\n status.modified = new Set(shareResult.successfulUpdates.map((x) => x.entityId)).size\n status.success = shareResult.updateErrors.length === 0\n if (!status.success) {\n const errorMsg = `Error while sharing (some) entities of type ${entitiesType} for patient ${patient.id} : ${JSON.stringify(\n shareResult.updateErrors\n )}`\n console.error(errorMsg)\n status.error = new Error(errorMsg)\n }\n })\n .catch((e) => {\n status.success = false\n status.error = e\n })\n } else {\n status.success = true\n }\n }\n await doShareEntitiesAndUpdateStatus(\n retrievedHealthElements,\n EntityWithDelegationTypeName.HealthElement,\n status.healthElements,\n isMedicalInfoTags,\n (x) => this.helementApi.bulkShareHealthElementsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(retrievedContacts, EntityWithDelegationTypeName.Contact, status.contacts, isMedicalInfoTags, (x) =>\n this.contactApi.bulkShareContactsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(retrievedInvoices, EntityWithDelegationTypeName.Invoice, status.invoices, isFinancialInfoTags, (x) =>\n this.invoiceApi.bulkShareInvoicesMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(\n retrievedClassifications,\n EntityWithDelegationTypeName.Classification,\n status.classifications,\n isMedicalInfoTags,\n (x) => this.classificationApi.bulkShareClassificationsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(\n retrievedCalendarItems,\n EntityWithDelegationTypeName.CalendarItem,\n status.calendarItems,\n isMedicalInfoTags,\n (x) => this.calendarItemApi.bulkShareCalendarItemsMinimal(x)\n )\n await doShareEntitiesAndUpdateStatus(retrievedForms, EntityWithDelegationTypeName.Form, status.forms, isMedicalInfoTags, (x) =>\n this.formApi.bulkShareFormsMinimal(x)\n )\n }\n const sharePatientDataRequest = {\n shareSecretIds: delSfks,\n shareEncryptionKeys: ecKeys,\n shareOwningEntityIds: [],\n requestedPermissions: RequestedPermissionEnum.MAX_WRITE,\n }\n const sharePatientRequest = {\n entity: patient,\n dataForDelegates: Object.fromEntries(delegateIds.map((delegateId) => [delegateId, sharePatientDataRequest])),\n }\n return await this.crypto.xapi\n .bulkShareOrUpdateEncryptedEntityMetadata(EntityWithDelegationTypeName.Patient, [sharePatientRequest], (x) => this.bulkSharePatients(x))\n .then((shareResult) => {\n if (shareResult.updatedEntities.length && !shareResult.updateErrors.length) {\n status.patient.success = true\n return { patient: shareResult.updatedEntities[0], statuses: status }\n } else {\n const errorMsg = `Error while sharing patient with id ${patient.id} : ${JSON.stringify(shareResult.updateErrors)}`\n console.error(errorMsg)\n status.patient.error = new Error(errorMsg)\n status.patient.success = false\n return { patient: shareResult.updatedEntities[0] ?? patient, statuses: status }\n }\n })\n .catch((e) => {\n status.patient.error = e\n status.patient.success = false\n return { patient, statuses: status }\n })\n }\n\n export(user: models.User, patId: string, ownerId: string, usingPost: boolean = false): Promise<{ id: string }> {\n return this.hcpartyApi.getHealthcareParty(ownerId).then((hcp) => {\n const parentId = hcp.parentId\n\n return retry(() => this.getPatientWithUser(user, patId))\n .then(async (patient: models.Patient) => {\n const initialised = await this.crypto.xapi.ensureEncryptionKeysInitialised(patient, EntityWithDelegationTypeName.Patient)\n if (!initialised) {\n return patient\n } else {\n return await this.modifyPatientWithUser(user, initialised)\n }\n })\n .then(async (patient: models.Patient | null) => {\n if (!patient) {\n return Promise.resolve({ id: patId })\n }\n const delSfks = await this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, ownerId)\n return delSfks.length\n ? Promise.all([\n retry(() =>\n (usingPost\n ? this.helementApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n : this.helementApi.findByHCPartyPatientSecretFKeysArray(ownerId, delSfks)\n ).then((hes) =>\n parentId\n ? (usingPost\n ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))\n : hes\n )\n ) as Promise<Array<models.IcureStub>>,\n retry(() =>\n (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((frms) =>\n parentId\n ? (usingPost\n ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))\n : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))\n : frms\n )\n ) as Promise<Array<models.Form>>,\n retry(() =>\n (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(ownerId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ctcs) =>\n parentId\n ? (usingPost\n ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(parentId, undefined, undefined, _.uniq(delSfks))\n : this.contactApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))\n ).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))\n : ctcs\n )\n ) as Promise<Array<models.Contact>>,\n retry(() =>\n (usingPost\n ? this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))\n : this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n ).then((ivs) =>\n parentId\n ? this.invoiceApi\n .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))\n : ivs\n )\n ) as Promise<Array<models.IcureStub>>,\n retry(() =>\n this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))\n .then((cls) =>\n parentId\n ? this.classificationApi\n .findClassificationsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))\n .then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))\n : cls\n )\n ) as Promise<Array<models.Classification>>,\n retry(async () => {\n const delegationSFKs = _.uniq(delSfks).join(',')\n try {\n let calendarItems = await (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(',')))\n\n if (parentId) {\n const moreCalendarItems = await (usingPost\n ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))\n : this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(',')))\n calendarItems = _.uniqBy(calendarItems.concat(moreCalendarItems), 'id')\n }\n\n return calendarItems\n } catch (ex) {\n console.log(`exception occured exporting calendarItem for ownerId: ${ownerId} - ${ex}`)\n //throw ex\n }\n }) as Promise<Array<models.CalendarItem>>,\n ]).then(([hes, frms, ctcs, ivs, cls, cis]) => {\n const docIds: { [key: string]: number } = {}\n ctcs.forEach(\n (c: models.Contact) =>\n c.services &&\n c.services.forEach((s) => s.content && Object.values(s.content).forEach((c) => c && c.documentId && (docIds[c.documentId] = 1)))\n )\n\n return retry(() => this.documentApi.getDocuments(new ListOfIds({ ids: Object.keys(docIds) }))).then((docs: Array<Document>) => {\n return {\n id: patId,\n patient: patient,\n contacts: ctcs,\n forms: frms,\n healthElements: hes,\n invoices: ivs,\n classifications: cls,\n calItems: cis,\n documents: docs,\n }\n })\n })\n : Promise.resolve({\n id: patId,\n patient: patient,\n contacts: [],\n forms: [],\n healthElements: [],\n invoices: [],\n classifications: [],\n calItems: [],\n documents: [],\n })\n })\n })\n }\n\n checkInami(inami: string): boolean {\n const num_inami = inami.replace(new RegExp('[^(0-9)]', 'g'), '')\n\n const checkDigit = num_inami.substring(6, 2)\n const numSansCheck = num_inami.substring(0, 6)\n let retour = false\n\n //modulo du niss\n const modINAMI = parseInt(numSansCheck) % 97\n\n //obtention du num de check 97 - le resultat du mod\n const checkDigit_2 = 97 - modINAMI\n\n if (parseInt(checkDigit) == checkDigit_2) {\n retour = true\n }\n return retour\n }\n\n isValidSsin(ssin: string) {\n ssin = ssin.replace(new RegExp('[^(0-9)]', 'g'), '')\n let isValidNiss = false\n\n const normalNumber =\n /^[0-9][0-9](([0][0-9])|([1][0-2]))(([0-2][0-9])|([3][0-1]))(([0-9]{2}[1-9])|([0-9][1-9][0-9])|([1-9][0-9]{2}))(([0-8][0-9])|([9][0-7]))$/.test(\n ssin\n )\n const bisNumber = /^[0-9][0-9](([2][0-9])|([3][0-2]))(([0-2][0-9])|([3][0-1]))[0-9]{3}(([0-8][0-9])|([9][0-7]))$/.test(ssin)\n const terNumber = /^[0-9][0-9](([4][0-9])|([5][0-2]))(([0-2][0-9])|([3][0-1]))[0-9]{3}(([0-8][0-9])|([9][0-7]))$/.test(ssin)\n\n if (normalNumber || bisNumber || terNumber) {\n isValidNiss =\n 97 - (Number(ssin.substring(0, 9)) % 97) === Number(ssin.substring(9, 2))\n ? true\n : 97 - (Number('2' + ssin.substring(0, 9)) % 97) === Number(ssin.substring(9, 2))\n }\n\n return isValidNiss\n }\n\n async getPatientIdOfChildDocumentForHcpAndHcpParents(\n childDocument: models.Invoice | models.CalendarItem | models.Contact | models.AccessLog,\n hcpId: string,\n childDocumentType: EntityWithDelegationTypeName\n ): Promise<string> {\n const parentIdsArray = await this.crypto.xapi.owningEntityIdsOf({ entity: childDocument, type: childDocumentType }, hcpId)\n\n const multipleParentIds = _.uniq(parentIdsArray).length > 1\n\n if (multipleParentIds) {\n throw 'Child document with id ' + childDocument.id + ' contains multiple parent ids in its CFKs for hcpId: ' + hcpId\n }\n\n const parentId = _.first(parentIdsArray)\n\n if (!parentId) {\n throw 'Parent id is empty in CFK of child document with id ' + childDocument.id + ' for hcpId: ' + hcpId\n }\n\n let patient: models.Patient = await super.getPatient(parentId!)\n\n let mergeLevel = 0\n const maxMergeLevel = 10\n while (patient.mergeToPatientId) {\n mergeLevel++\n if (mergeLevel === maxMergeLevel) {\n throw 'Too many merged levels for parent (Patient) of child document ' + childDocument.id + ' ; hcpId: ' + hcpId\n }\n\n patient = await super.getPatient(patient.mergeToPatientId!)\n }\n\n return patient.id!\n }\n\n /**\n * @return if the logged data owner has write access to the content of the given patient\n */\n async hasWriteAccess(patient: models.Patient): Promise<boolean> {\n return this.crypto.xapi.hasWriteAccess({ entity: patient, type: EntityWithDelegationTypeName.Patient })\n }\n\n /**\n * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param delegateId the id of the data owner which will be granted access to the patient.\n * @param patient the patient to share.\n * @param shareSecretIds the secret ids of the Patient that the delegate will be given access to. Allows the delegate to search for data where the\n * shared Patient is the owning entity id.\n * @param options optional parameters to customize the sharing behaviour:\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * patient does not have encrypted content.\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return the updated entity\n */\n async shareWith(\n delegateId: string,\n patient: models.Patient,\n shareSecretIds: string[],\n options: {\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n } = {}\n ): Promise<models.Patient> {\n return this.shareWithMany(patient, { [delegateId]: { ...options, shareSecretIds: shareSecretIds } })\n }\n\n /**\n * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param patient the patient 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 the secret ids of the Patient that the delegate will be given access to. Allows the delegate to search for data where the\n * shared Patient is the owning entity id.\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * patient does not have encrypted content.\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return the updated entity\n */\n async shareWithMany(\n patient: models.Patient,\n delegates: {\n [delegateIds: string]: {\n shareSecretIds: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<models.Patient> {\n return (await this.tryShareWithMany(patient, delegates)).updatedEntityOrThrow\n }\n\n /**\n * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also\n * the encrypted content, with read-only or read-write permissions.\n * @param patient the patient 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 the secret ids of the Patient that the delegate will be given access to. Allows the delegate to search for data where the\n * shared Patient is the owning entity id.\n * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted\n * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a\n * patient does not have encrypted content.\n * {@link ShareMetadataBehaviour.IF_AVAILABLE}).\n * - requestedPermissions: the requested permissions for the delegate, defaults to {@link RequestedPermissionEnum.MAX_WRITE}.\n * @return a promise which will contain the result of the operation: the updated entity if the operation was successful or details of the error if\n * the operation failed.\n */\n async tryShareWithMany(\n patient: models.Patient,\n delegates: {\n [delegateIds: string]: {\n shareSecretIds: string[]\n requestedPermissions?: RequestedPermissionEnum\n shareEncryptionKey?: ShareMetadataBehaviour // Defaults to ShareMetadataBehaviour.IF_AVAILABLE\n }\n }\n ): Promise<ShareResult<models.Patient>> {\n const self = await this.dataOwnerApi.getCurrentDataOwnerId()\n // All entities should have an encryption key.\n const entityWithEncryptionKey = await this.crypto.xapi.ensureEncryptionKeysInitialised(patient, EntityWithDelegationTypeName.Patient)\n const updatedEntity = entityWithEncryptionKey ? await this.modifyPatientAs(self, entityWithEncryptionKey) : patient\n return this.crypto.xapi\n .simpleShareOrUpdateEncryptedEntityMetadata(\n {\n entity: updatedEntity,\n type: EntityWithDelegationTypeName.Patient,\n },\n Object.fromEntries(\n Object.entries(delegates).map(([delegateId, options]) => [\n delegateId,\n {\n requestedPermissions: options.requestedPermissions,\n shareEncryptionKeys: options.shareEncryptionKey,\n shareOwningEntityIds: ShareMetadataBehaviour.NEVER,\n shareSecretIds: options.shareSecretIds,\n },\n ])\n ),\n (x) => this.bulkSharePatients(x)\n )\n .then((r) => r.mapSuccessAsync((e) => this.decryptAs(self, [e]).then((es) => es[0])))\n }\n\n /**\n * @param patient a patient\n * @return all the decryptable secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the\n * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.\n */\n decryptSecretIdsOf(patient: models.Patient): Promise<string[]> {\n return this.crypto.xapi.secretIdsOf({ entity: patient, type: EntityWithDelegationTypeName.Patient }, undefined)\n }\n\n /**\n * @param patient a patient\n * @return the confidential secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the\n * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.\n */\n decryptConfidentialSecretIdsOf(patient: models.Patient): Promise<string[]> {\n return this.crypto.confidential.getConfidentialSecretIds({ entity: patient, type: EntityWithDelegationTypeName.Patient }, undefined)\n }\n\n /**\n * @param patient a patient\n * @return the non-confidential secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the\n * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.\n */\n decryptNonConfidentialSecretIdsOf(patient: models.Patient): Promise<string[]> {\n return this.crypto.confidential.getSecretIdsSharedWithParents({ entity: patient, type: EntityWithDelegationTypeName.Patient })\n }\n\n getDataOwnersWithAccessTo(\n entity: models.Patient\n ): Promise<{ permissionsByDataOwnerId: { [p: string]: AccessLevelEnum }; hasUnknownAnonymousDataOwners: boolean }> {\n return this.crypto.delegationsDeAnonymization.getDataOwnersWithAccessTo({ entity, type: EntityWithDelegationTypeName.Patient })\n }\n\n getEncryptionKeysOf(entity: models.Patient): Promise<string[]> {\n return this.crypto.xapi.encryptionKeysOf({ entity, type: EntityWithDelegationTypeName.Patient }, undefined)\n }\n\n /**\n * Merge two patients into one. This method performs the following operations:\n * - The `from` patient will be soft-deleted, and it will point to the `into` patient. Only the `deletionDate` and `mergeToPatientId` fields of the\n * patient will be changed (automatically by this method). Note that the value of {@link from} is only used to verify that the client is aware of\n * the last version of the `from` patient: any changes to its content and/or metadata compared to what is actually stored in the database will be\n * ignored.\n * - The metadata of the `into` patient will be automatically updated to contain also the metadata of the `from` patient and to keep track of the\n * merge:\n * - the `mergedIds` will be updated to contain the `from` patient id\n * - all secret ids of the `from` patient will be added to the `into` patient\n * - all data owners (including anonymous data owners) with access to the `from` patient will have the same access to the merged `into` patient\n * (unless they already had greater access to the `into` patient, in which case they keep the greater access)\n * - The content of the `into` patient will be updated to match the content (name, address, note, ...) of the provided {@link mergedInto} parameter.\n * Note that since the metadata is automatically updated by this method you must not change the metadata of the `mergedInto` patient\n * (`delegations`, mergedInto`, ...): if there is any change between the metadata of the provided `mergedInto` patient and the stored patient this\n * method will fail with an error.\n *\n * In case the revisions of {@link from} and/or {@link mergedInto} does not match the latest revisions for these patients in the database this\n * method will fail without soft-deleting the `from` patient and without updating the `into` patient with the merged content and metadata. You will\n * have to retrieve the updated versions of both patients before retrying the merge.\n *\n * Finally, note that this method only merges existing data, and does not perform any automatic sharing of the data. The secret ids and encryption\n * keys will not be shared with users that had access only to one of the entity, you will have to use the {@link shareWith} method after the merge\n * if you want to do so.\n * For example consider hcps A, B with access to P' and hcps A, C with access to P'', and we merge P'' into P'. After the merge:\n * - A has access to all secret ids of the merged patient and to the encryption key of the merged patient\n * - B has access to the encryption key of the merged patient (since it is the same as in P'), but only to the secret id which was originally from\n * the unmerged P'\n * - C has no access to the encryption key of the merged patient, and has access only to the secret id which was originally from the unmerged P''\n *\n * @param from the original, unmodified `from` patient. Its content will be unchanged and its metadata will be automatically updated by this method\n * to reflect the merge.\n * @param mergedInto the `into` patient with updated content result of the merge with the `from` patient, as specified by your application logic.\n * The metadata of the `mergedInto` patient must not differ from the metadata of the stored version of the patient, since it will be automatically\n * updated by the method.\n * @return the updated `into` patient.\n */\n async mergePatients(from: Patient, mergedInto: Patient): Promise<Patient> {\n const encryptedMerged = (await this.encryptAs(await this.dataOwnerApi.getCurrentDataOwnerId(), [mergedInto]))[0]\n const merged = await super.baseMergePatients(from.id!, from.rev!, encryptedMerged)\n return (await this.tryDecryptOrReturnOriginal([merged]))[0].entity\n }\n\n async subscribeToPatientEvents(\n eventTypes: ('CREATE' | 'UPDATE' | 'DELETE')[],\n filter: AbstractFilter<Patient> | undefined,\n eventFired: (patient: Patient) => Promise<void>,\n options: SubscriptionOptions = {}\n ): Promise<Connection> {\n const currentUser = await this.userApi.getCurrentUser()\n return subscribeToEntityEvents(\n this.host,\n this.authApi,\n EntityWithDelegationTypeName.Patient,\n eventTypes,\n filter,\n eventFired,\n options,\n async (encrypted) => (await this.decrypt(currentUser, [encrypted]))[0]\n ).then((rs) => new ConnectionImpl(rs))\n }\n\n createDelegationDeAnonymizationMetadata(entity: Patient, delegates: string[]): Promise<void> {\n return this.crypto.delegationsDeAnonymization.createOrUpdateDeAnonymizationInfo({ entity, type: EntityWithDelegationTypeName.Patient }, delegates)\n }\n\n /**\n * Initializes the exchange data towards a newly invited patient. This allows the doctor to share data with the\n * patient even if the patient has not yet initialized a keypair for himself.\n *\n * This method should be used only if the patient has not yet initialized a keypair for himself. If the patient has\n * already initialized a keypair this method does nothing and returns false. In this case the exchange data will be\n * automatically created the first time you share data with the patient, and your implementation of the crypto\n * strategies will be used to validate the public keys of the patient.\n *\n * Once exchange data is initialized you can use the {@link IccRecoveryXApi.createExchangeDataRecoveryInfo} to\n * generate a key that the patient will be able to use on his first login to immediately gain access to the exchange\n * data (through the {@link IccRecoveryXApi.recoverExchangeData} method).\n *\n * @param patientId the id of the newly invited patient.\n * @return true if exchange data was initialized, false if the patient already has a key pair and the exchange data\n * will be initialized in the standard way (automatically on the first time data is shared with the user).\n */\n async forceInitialiseExchangeDataToNewlyInvitedPatient(patientId: string): Promise<boolean> {\n const patient = await super.getPatient(patientId)\n if (this.dataOwnerApi.getHexPublicKeysOf(patient).size) return false\n await this.crypto.exchangeData.getOrCreateEncryptionDataTo(patientId, true)\n return true\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("isomorphic-fetch");
|
|
13
|
+
require("mocha");
|
|
14
|
+
const test_utils_1 = require("../../utils/test_utils");
|
|
15
|
+
const mocha_1 = require("mocha");
|
|
16
|
+
const types_1 = require("@icure/test-setup/types");
|
|
17
|
+
const icc_x_api_1 = require("../../../icc-x-api");
|
|
18
|
+
const crypto_1 = require("crypto");
|
|
19
|
+
const HealthcareParty_1 = require("../../../icc-api/model/HealthcareParty");
|
|
20
|
+
const TestApi_1 = require("../../utils/TestApi");
|
|
21
|
+
const chai_1 = require("chai");
|
|
22
|
+
(0, test_utils_1.setLocalStorage)(fetch);
|
|
23
|
+
describe('SDL in an environment with soft-deleted data owners', function () {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
this.timeout(600000);
|
|
26
|
+
let env;
|
|
27
|
+
let masterApi;
|
|
28
|
+
let primitives;
|
|
29
|
+
// Test values, not real data
|
|
30
|
+
const pubKeyHex = '30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001'; // pragma: allowlist secret
|
|
31
|
+
const privKeyHex = '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001028201000189beeb385a9652e212e03f4e5ca84579f7b5e4aeb2a893e3fbae54db4babf8f2285692fbb206a171e3a32d889a83b4dcc2d725084d8b1c1bc58548f88e2c1b890187c23293c73163cafa82e43490d080558c78ebc8fab2ddda5b829efa1b0813ecb9a24bf22eb54e47a532aacdd70d587b59bac79c146d7759e8c52aeb774603f4b282e699aca98793aa0086233a8aafc8fad58b62df011f33c1dcc6efdfc9aa51f4f11ea450ba5e02f9b69de33c756f3504ff086d2e58c25db871e3c021ee3720837466bb41d886bd4300eeac41742206110158578315d29a527b520e11ec6f7e98558931bdde63a4402635473244fa9764bb3527ff33473ff08f63b3a94102818100c8032014c593f8aecc15287d3dfd6143c75e8fb27faf7944fa030016b26fa5133d8e0d13a5244bcd6155ba29258a498e44fef239dc75dee9db4756c9a2b2be93cf2c67049ff2b2f5cbf949960e44e3fc56c90a66485ec22079a0eb864100404e0d7ea96f21ced9793633d87c49056be4c507768d51c310f69605befec087bbcd02818100d380b7a8cbc5a87c5d91e1497949acfe3c61671b31bc4c54f2f8e8cd8e709a617b49d1e7d6c0333fbb42af119db8660d1a58165e716b976bebdb12104c0dba951719f8c6711e84b704bcdd80248a767609680e4ff125126a23bbee5362f88d881c5c24c5ff0400edde1dd7044fd0d5d06a9cda33a1004daad7df8aa2eb63a5b90281801d0ab721ccfe8b617628ac546327e373a0034f0230201e8fb16db61995973874eebf2d8ee8afb881fddc20c7d0b79fae94be2015deb90ec10e21f1ac1d7faec46f9496f0c8f8c89b801e965cbf7da94cfe9cfa7197988abf8469a5493d2ef8275d36430bebf0c90b1c9fb2937956dc2fbf9c31ce9b4ca3adea62b334f267c3110281806453facb275e6bbe12e4d0697a0f68f070d40384f2e2cf92bc6f367fcbc1be79df71f51074de577133f33df8ad487ba05b8ecd8d9f5fda44676d53f4471f7c129d12c4dfdd690cab84a3d2aea6a6c7ead62b761e95d57016c93caca101a1c6017af27abf316944c79145b66965333b39d258f568e846ac910e360c1d9c6b788102818100879751ba5fe91d86410037ca9df05b2bb689734af710ab50a75b1aa1083dd596f295d710ba630c9fbfe6dcdedd8f0fca22595f8723376e72721c01275572692ebd2d5b39d5715ea052ed0968a9dabb76f7eef7c4c894a5031ae237772c21b62a43322e324c793fccf8b3abe340ca029e54255ed735549918352f3abaaf0850b7'; // pragma: allowlist secret
|
|
32
|
+
const deletedOtherId = 'dc88f05e-6f9f-4203-bc8d-59b1737322f4'; // pragma: allowlist secret
|
|
33
|
+
const exchangeKeySelf = '6aac0c669a4423d5fed7c8d5a434ddf70e8f9ab34db8104cf88d810a535f2701'; // pragma: allowlist secret
|
|
34
|
+
const exchangeKeyOther = '24a58ab4837d2a7dbed477abf03c87816dfbae113604a1e3d93093194291907e'; // pragma: allowlist secret
|
|
35
|
+
function makeTestHcp(props) {
|
|
36
|
+
const hcpId = primitives.randomUuid();
|
|
37
|
+
return new HealthcareParty_1.HealthcareParty({
|
|
38
|
+
id: hcpId,
|
|
39
|
+
name: `Test-${primitives.randomUuid()}`,
|
|
40
|
+
hcPartyKeys: props.includeHcPartyKeys
|
|
41
|
+
? {
|
|
42
|
+
[hcpId]: [
|
|
43
|
+
'785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69',
|
|
44
|
+
'785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret
|
|
45
|
+
],
|
|
46
|
+
'dc88f05e-6f9f-4203-bc8d-59b1737322f4': [
|
|
47
|
+
// pragma: allowlist secret
|
|
48
|
+
'9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7',
|
|
49
|
+
'27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret
|
|
50
|
+
],
|
|
51
|
+
}
|
|
52
|
+
: {},
|
|
53
|
+
aesExchangeKeys: props.includeAesExchangeKeys
|
|
54
|
+
? {
|
|
55
|
+
// pragma: allowlist nextline secret
|
|
56
|
+
'30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001': {
|
|
57
|
+
[hcpId]: {
|
|
58
|
+
// pragma: allowlist secret
|
|
59
|
+
ccc08799369fcd6d68d8250203010001: '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret
|
|
60
|
+
},
|
|
61
|
+
'dc88f05e-6f9f-4203-bc8d-59b1737322f4': {
|
|
62
|
+
// pragma: allowlist secret
|
|
63
|
+
// pragma: allowlist secret
|
|
64
|
+
ccc08799369fcd6d68d8250203010001: '9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7',
|
|
65
|
+
// pragma: allowlist nextline secret
|
|
66
|
+
'0c8b6fa8a116ecfee683b10203010001': '27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
: {},
|
|
71
|
+
publicKey: pubKeyHex,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
(0, mocha_1.before)(function () {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
|
|
77
|
+
env = yield initializer.execute((0, types_1.getEnvVariables)());
|
|
78
|
+
masterApi = yield test_utils_1.TestUtils.initMasterApi(env);
|
|
79
|
+
primitives = masterApi.cryptoApi.primitives;
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
function doLegacyKeysTestWithDeletedDataOwner(hcp) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
const userPw = primitives.randomUuid();
|
|
85
|
+
const user = yield masterApi.userApi.createUser({
|
|
86
|
+
id: primitives.randomUuid(),
|
|
87
|
+
email: `${primitives.randomUuid()}@test.icure.com`,
|
|
88
|
+
passwordHash: userPw,
|
|
89
|
+
healthcarePartyId: hcp.id,
|
|
90
|
+
});
|
|
91
|
+
const hcpKeypair = yield primitives.RSA.importKeyPair('pkcs8', (0, icc_x_api_1.hex2ua)(privKeyHex), 'spki', (0, icc_x_api_1.hex2ua)(pubKeyHex), icc_x_api_1.ShaVersion.Sha1);
|
|
92
|
+
const testApi = yield (0, TestApi_1.TestApi)(env.iCureUrl, user.email, userPw, crypto_1.webcrypto, hcpKeypair);
|
|
93
|
+
const selfKeys = yield testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id, hcp.id);
|
|
94
|
+
(0, chai_1.expect)(selfKeys.length).to.eq(1);
|
|
95
|
+
const selfKeyHex = (0, icc_x_api_1.ua2hex)(yield primitives.AES.exportKey(selfKeys[0], 'raw'));
|
|
96
|
+
(0, chai_1.expect)(selfKeyHex).to.eq(exchangeKeySelf);
|
|
97
|
+
const delegateKeys = yield testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id, deletedOtherId);
|
|
98
|
+
(0, chai_1.expect)(delegateKeys.length).to.eq(1);
|
|
99
|
+
const delegateKeysHex = (0, icc_x_api_1.ua2hex)(yield primitives.AES.exportKey(delegateKeys[0], 'raw'));
|
|
100
|
+
(0, chai_1.expect)(delegateKeysHex).to.eq(exchangeKeyOther);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
it('hcp with hcPartyKeys to soft-deleted user', () => __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
const hcp = yield masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeHcPartyKeys: true }));
|
|
105
|
+
yield doLegacyKeysTestWithDeletedDataOwner(hcp);
|
|
106
|
+
}));
|
|
107
|
+
it('hcp with aesExchangeKeys to soft-deleted user', () => __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
const hcp = yield masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeAesExchangeKeys: true }));
|
|
109
|
+
yield doLegacyKeysTestWithDeletedDataOwner(hcp);
|
|
110
|
+
}));
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=soft-deleted-data-owners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft-deleted-data-owners.js","sourceRoot":"","sources":["../../../../test/icc-x-api/crypto/soft-deleted-data-owners.ts"],"names":[],"mappings":"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","sourcesContent":["import 'isomorphic-fetch'\nimport 'mocha'\nimport { createNewHcpApi, getEnvironmentInitializer, setLocalStorage, TestUtils } from '../../utils/test_utils'\nimport { before } from 'mocha'\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { CryptoPrimitives, hex2ua, IcureApi, ShaVersion, ua2hex } from '../../../icc-x-api'\nimport { randomUUID, webcrypto } from 'crypto'\nimport { HealthcareParty } from '../../../icc-api/model/HealthcareParty'\nimport { TestApi } from '../../utils/TestApi'\nimport { he } from 'date-fns/locale'\nimport { expect } from 'chai'\n\nsetLocalStorage(fetch)\n\ndescribe('SDL in an environment with soft-deleted data owners', async function () {\n this.timeout(600000)\n let env: TestVars\n let masterApi: IcureApi\n let primitives: CryptoPrimitives\n\n // Test values, not real data\n const pubKeyHex =\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001' // pragma: allowlist secret\n const privKeyHex =\n '308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001028201000189beeb385a9652e212e03f4e5ca84579f7b5e4aeb2a893e3fbae54db4babf8f2285692fbb206a171e3a32d889a83b4dcc2d725084d8b1c1bc58548f88e2c1b890187c23293c73163cafa82e43490d080558c78ebc8fab2ddda5b829efa1b0813ecb9a24bf22eb54e47a532aacdd70d587b59bac79c146d7759e8c52aeb774603f4b282e699aca98793aa0086233a8aafc8fad58b62df011f33c1dcc6efdfc9aa51f4f11ea450ba5e02f9b69de33c756f3504ff086d2e58c25db871e3c021ee3720837466bb41d886bd4300eeac41742206110158578315d29a527b520e11ec6f7e98558931bdde63a4402635473244fa9764bb3527ff33473ff08f63b3a94102818100c8032014c593f8aecc15287d3dfd6143c75e8fb27faf7944fa030016b26fa5133d8e0d13a5244bcd6155ba29258a498e44fef239dc75dee9db4756c9a2b2be93cf2c67049ff2b2f5cbf949960e44e3fc56c90a66485ec22079a0eb864100404e0d7ea96f21ced9793633d87c49056be4c507768d51c310f69605befec087bbcd02818100d380b7a8cbc5a87c5d91e1497949acfe3c61671b31bc4c54f2f8e8cd8e709a617b49d1e7d6c0333fbb42af119db8660d1a58165e716b976bebdb12104c0dba951719f8c6711e84b704bcdd80248a767609680e4ff125126a23bbee5362f88d881c5c24c5ff0400edde1dd7044fd0d5d06a9cda33a1004daad7df8aa2eb63a5b90281801d0ab721ccfe8b617628ac546327e373a0034f0230201e8fb16db61995973874eebf2d8ee8afb881fddc20c7d0b79fae94be2015deb90ec10e21f1ac1d7faec46f9496f0c8f8c89b801e965cbf7da94cfe9cfa7197988abf8469a5493d2ef8275d36430bebf0c90b1c9fb2937956dc2fbf9c31ce9b4ca3adea62b334f267c3110281806453facb275e6bbe12e4d0697a0f68f070d40384f2e2cf92bc6f367fcbc1be79df71f51074de577133f33df8ad487ba05b8ecd8d9f5fda44676d53f4471f7c129d12c4dfdd690cab84a3d2aea6a6c7ead62b761e95d57016c93caca101a1c6017af27abf316944c79145b66965333b39d258f568e846ac910e360c1d9c6b788102818100879751ba5fe91d86410037ca9df05b2bb689734af710ab50a75b1aa1083dd596f295d710ba630c9fbfe6dcdedd8f0fca22595f8723376e72721c01275572692ebd2d5b39d5715ea052ed0968a9dabb76f7eef7c4c894a5031ae237772c21b62a43322e324c793fccf8b3abe340ca029e54255ed735549918352f3abaaf0850b7' // pragma: allowlist secret\n const deletedOtherId = 'dc88f05e-6f9f-4203-bc8d-59b1737322f4' // pragma: allowlist secret\n const exchangeKeySelf = '6aac0c669a4423d5fed7c8d5a434ddf70e8f9ab34db8104cf88d810a535f2701' // pragma: allowlist secret\n const exchangeKeyOther = '24a58ab4837d2a7dbed477abf03c87816dfbae113604a1e3d93093194291907e' // pragma: allowlist secret\n function makeTestHcp(props: { includeHcPartyKeys?: boolean; includeAesExchangeKeys?: boolean }): HealthcareParty {\n const hcpId = primitives.randomUuid()\n return new HealthcareParty({\n id: hcpId,\n name: `Test-${primitives.randomUuid()}`,\n hcPartyKeys: props.includeHcPartyKeys\n ? {\n [hcpId]: [\n '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret\n '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret\n ],\n 'dc88f05e-6f9f-4203-bc8d-59b1737322f4': [\n // pragma: allowlist secret\n '9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7', // pragma: allowlist secret\n '27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret\n ],\n }\n : {},\n aesExchangeKeys: props.includeAesExchangeKeys\n ? {\n // pragma: allowlist nextline secret\n '30820122300d06092a864886f70d01010105000382010f003082010a0282010100a53f247f466c8f4e39d04ac72e260949f66d0e6f0aa2875d670f3d7f6c7f45ecbfe8ce31a26abbca8008d75d135339a739ca3e0ee058b9595722db46701cd0dfbb9ef4f96d1ac337cf78fe4449a26be244020464d44ff0d3bf0b7bcb53666750fa76298e832386eb6e5a6e15d2e366e5c8e53acf0a6ecf20a43fd752f708797e58aaa60ceec23cf3ddc5eacca6630a068ef0e7ea52bfdec756456124610b5bcce6025e2cd4a03eb54a7bc2076531348136671102a89ea3a275147b273bfb17f11b759f20c2068c5ba4fa081cc7087b582300d8acb7c6bcc2b8485290d7c165f855180176662fa08af735e64091086d6d5d1f6a2fb1ccc08799369fcd6d68d8250203010001':\n {\n [hcpId]: {\n // pragma: allowlist secret\n ccc08799369fcd6d68d8250203010001:\n '785fd227c9a4bb185adea3070fdc571696df3f5e513ba7fe3e5f50b0cf5a449def0cbc7e806a626945c441adcd09feaf6c6bf3da6460347efc620be3b81bdbf3804cabdfdeac3f4d5417db0191a3a1032e57670be7db630256c862db0ed87a67454c8660cb30e7bd8bf3d3ec218dae2107616933e3882200add851ae49cb2ec731f0425f1cea7d69a530d6debff6c60e1663733c946e48ac800a70044ecc32bb5cbe184484e4bb6ac3ad42435e80d6c3d2b8684d1cfff9fe77bdb3fdaae71482f018945d878175a12407af3b9ef245cc6128ea956292f8e7f5e2d74368de42445675326b7e1dbd7990502cb098b1abef8e33f3d353a332912221d0039f787c69', // pragma: allowlist secret\n },\n 'dc88f05e-6f9f-4203-bc8d-59b1737322f4': {\n // pragma: allowlist secret\n // pragma: allowlist secret\n ccc08799369fcd6d68d8250203010001:\n '9e8ce2e76f0716a5ff537ea56c6ec7725ed067afc3a8c1eb8ef63f5a6c6de1a901c651c433f558224be3ea6e09748c2dfa535b0d9114a5058126db7803a21ba99dc9877b372e6fbbdacf6d8e3410ee93c985959ab4f0267acf562619fee7723f050542ecfc1642dcf6f5d678994d58d8c83d8be65b5f399af19205777216d9eb28ecbb00c5ce57f253973403845f98b94d86361cccaeb33772aa491b9c1dc1fc95c0a9f74b2d26e895a4ff80d9b32fd318ea42088e6249f027a2b6afe98bd9dece83dc24e454a8a62e78b88952f38a87cdb580dda47c87496e44a5fde0e9886289aeded4a404411a1e28d28fc09fd305f4f43e0bce0c3605eb419b2795be70e7', // pragma: allowlist secret\n // pragma: allowlist nextline secret\n '0c8b6fa8a116ecfee683b10203010001':\n '27511848a060104b0b92447df4a6e1a11de92d65892b6d07104eab6add3ce57f664a1fd2431e509818a232e0601f0621ecf35df4492c53b18ceb21747a51cd863852c586fa9f3a0dd4e19b1038540ecc63724115cbb6909793a1ffceea4498dc7ae5e9fd4120912c13b276639036a6d859a2cc836b267aaeb33a876c8d40caa5ae4c5fde2122b1d3107f074ad28c38be6a96b5c899d5fda2e66c8bef4a541c41f177e868d8e521b35be07b96def15a6b15cd5a8d1e6fc2df3ce6fbd280d315082160054d904f71cd8b4d3822a2812a1a5224390ec4591319c0bad98429ccadba3f04f9b602d92a9e95f367bdd03fe5c943d4bc9ea595be27f53797b3d7c00f03', // pragma: allowlist secret\n },\n },\n }\n : {},\n publicKey: pubKeyHex,\n })\n }\n\n before(async function () {\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n masterApi = await TestUtils.initMasterApi(env)\n primitives = masterApi.cryptoApi.primitives\n })\n\n async function doLegacyKeysTestWithDeletedDataOwner(hcp: HealthcareParty) {\n const userPw = primitives.randomUuid()\n const user = await masterApi.userApi.createUser({\n id: primitives.randomUuid(),\n email: `${primitives.randomUuid()}@test.icure.com`,\n passwordHash: userPw,\n healthcarePartyId: hcp.id!,\n })\n const hcpKeypair = await primitives.RSA.importKeyPair('pkcs8', hex2ua(privKeyHex), 'spki', hex2ua(pubKeyHex), ShaVersion.Sha1)\n const testApi = await TestApi(env.iCureUrl, user.email!, userPw, webcrypto as any, hcpKeypair)\n const selfKeys = await testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id!, hcp.id!)\n expect(selfKeys.length).to.eq(1)\n const selfKeyHex = ua2hex(await primitives.AES.exportKey(selfKeys[0], 'raw'))\n expect(selfKeyHex).to.eq(exchangeKeySelf)\n const delegateKeys = await testApi.cryptoApi.exchangeKeys.getDecryptionExchangeKeysFor(hcp.id!, deletedOtherId)\n expect(delegateKeys.length).to.eq(1)\n const delegateKeysHex = ua2hex(await primitives.AES.exportKey(delegateKeys[0], 'raw'))\n expect(delegateKeysHex).to.eq(exchangeKeyOther)\n }\n\n it('hcp with hcPartyKeys to soft-deleted user', async () => {\n const hcp = await masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeHcPartyKeys: true }))\n await doLegacyKeysTestWithDeletedDataOwner(hcp)\n })\n\n it('hcp with aesExchangeKeys to soft-deleted user', async () => {\n const hcp = await masterApi.healthcarePartyApi.createHealthcareParty(makeTestHcp({ includeAesExchangeKeys: true }))\n await doLegacyKeysTestWithDeletedDataOwner(hcp)\n })\n})\n"]}
|
|
@@ -154,5 +154,12 @@ describe('icc-x-patient-api Tests', () => {
|
|
|
154
154
|
(0, chai_1.expect)(decodedPicture[i]).to.equal(pictureAB[i]);
|
|
155
155
|
}
|
|
156
156
|
}));
|
|
157
|
+
it('A patient created with v8 + should have no auto-fixed delegations', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
var _a;
|
|
159
|
+
const api = yield initApi(env, test_utils_1.hcp1Username);
|
|
160
|
+
const user = yield api.userApi.getCurrentUser();
|
|
161
|
+
const patient = yield api.patientApi.createPatientWithUser(user, yield api.patientApi.newInstance(user, { firstName: 'Giovanni', lastName: 'Giorgio', preferredUserId: user.id }));
|
|
162
|
+
(0, chai_1.expect)(Object.keys((_a = patient.delegations) !== null && _a !== void 0 ? _a : {}).length == 0).to.be.true;
|
|
163
|
+
}));
|
|
157
164
|
});
|
|
158
165
|
//# sourceMappingURL=icc-patient-x-api-test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icc-patient-x-api-test.js","sourceRoot":"","sources":["../../../test/icc-x-api/icc-patient-x-api-test.ts"],"names":[],"mappings":"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","sourcesContent":["import { before } from 'mocha'\n\nimport 'isomorphic-fetch'\n\nimport { Patient } from '../../icc-api/model/Patient'\nimport { assert, expect } from 'chai'\nimport { randomBytes, randomUUID } from 'crypto'\nimport { getEnvironmentInitializer, hcp1Username, hcp2Username, hcp3Username, setLocalStorage, TestUtils } from '../utils/test_utils'\nimport initApi = TestUtils.initApi\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { EntityWithDelegationTypeName, ua2b64 } from '../../icc-x-api'\n\nsetLocalStorage(fetch)\nlet env: TestVars\n\ndescribe('icc-x-patient-api Tests', () => {\n before(async function () {\n this.timeout(600000)\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n })\n\n it('CreatePatientWithUser Success for HCP', async () => {\n // Given\n const {\n userApi: userApiForHcp,\n dataOwnerApi: dataOwnerApiForHcp,\n patientApi: patientApiForHcp,\n cryptoApi: cryptoApiForHcp,\n } = await initApi(env, hcp1Username)\n\n const hcpUser = await userApiForHcp.getCurrentUser()\n\n const patientToCreate = await patientApiForHcp.newInstance(\n hcpUser,\n new Patient({\n id: randomUUID(),\n firstName: 'John',\n lastName: 'Snow',\n note: 'Winter is coming',\n })\n )\n\n // When\n const createdPatient = await patientApiForHcp.createPatientWithUser(hcpUser, patientToCreate)\n\n // Then\n const readPatient = await patientApiForHcp.getPatientWithUser(hcpUser, createdPatient.id!)\n assert(readPatient != null)\n assert(readPatient.id != null)\n assert(readPatient.note == patientToCreate.note)\n assert(readPatient.firstName == patientToCreate.firstName)\n assert(readPatient.lastName == patientToCreate.lastName)\n expect(\n await cryptoApiForHcp.xapi.encryptionKeysOf({ entity: readPatient, type: EntityWithDelegationTypeName.Patient }, undefined)\n ).to.have.length(1)\n expect(await patientApiForHcp.decryptSecretIdsOf(readPatient)).to.have.length(1)\n })\n\n it('Share with should work as expected', async () => {\n const api1 = await initApi(env!, hcp1Username)\n const user1 = await api1.userApi.getCurrentUser()\n const api2 = await initApi(env!, hcp2Username)\n const user2 = await api2.userApi.getCurrentUser()\n const encryptedField = 'Something encrypted'\n const entity = await api1.patientApi.createPatientWithUser(\n user1,\n await api1.patientApi.newInstance(user1, { firstName: 'Gigio', lastName: 'Bagigio', note: encryptedField })\n )\n expect(entity.note).to.be.equal(encryptedField)\n const secretIds = await api1.patientApi.decryptSecretIdsOf(entity)\n await api2.patientApi\n .getPatientWithUser(user2, entity.id)\n .then(() => {\n throw new Error('Should not be able to get the entity')\n })\n .catch(() => {\n /* expected */\n })\n await api1.patientApi.shareWith(user2.healthcarePartyId!, entity, secretIds)\n const retrieved = await api2.patientApi.getPatientWithUser(user2, entity.id)\n expect(retrieved.note).to.be.equal(encryptedField)\n expect(await api2.patientApi.decryptSecretIdsOf(retrieved)).to.have.members(secretIds)\n })\n\n it('Merge patients should work as expected', async () => {\n const api1 = await initApi(env!, hcp1Username)\n const user1 = await api1.userApi.getCurrentUser()\n const api2 = await initApi(env!, hcp2Username)\n const user2 = await api2.userApi.getCurrentUser()\n const api3 = await initApi(env!, hcp3Username)\n const user3 = await api3.userApi.getCurrentUser()\n const mergedFirstName = 'Gigio'\n const mergedLastName = 'Bagigio'\n const mergedAlias = 'Luigio'\n const mergedNote = 'A secret note'\n const patientFrom = await api1.patientApi.createPatientWithUser(\n user1,\n await api1.patientApi.newInstance(\n user1,\n {\n firstName: mergedFirstName,\n lastName: 'From',\n note: 'A',\n },\n { additionalDelegates: { [user2.healthcarePartyId!]: 'WRITE' } }\n )\n )\n const patientFromSecretIds = await api1.patientApi.decryptSecretIdsOf(patientFrom)\n expect(patientFromSecretIds).to.have.lengthOf(1)\n const patientInto = await api1.patientApi.createPatientWithUser(\n user1,\n await api1.patientApi.newInstance(\n user1,\n {\n firstName: 'Into',\n lastName: mergedLastName,\n note: 'B',\n },\n { additionalDelegates: { [user3.healthcarePartyId!]: 'WRITE' } }\n )\n )\n const patientIntoSecretIds = await api1.patientApi.decryptSecretIdsOf(patientInto)\n expect(patientFromSecretIds).to.have.lengthOf(1)\n expect(patientIntoSecretIds[0]).to.not.equal(patientFromSecretIds[0])\n const mergedInto = {\n ...patientInto,\n firstName: mergedFirstName,\n lastName: mergedLastName,\n alias: mergedAlias,\n note: mergedNote,\n }\n const mergedPatient = await api1.patientApi.mergePatients(patientFrom, mergedInto)\n expect(mergedPatient.firstName).to.equal(mergedFirstName)\n expect(mergedPatient.lastName).to.equal(mergedLastName)\n expect(mergedPatient.alias).to.equal(mergedAlias)\n expect(mergedPatient.note).to.equal(mergedNote)\n expect(await api1.patientApi.decryptSecretIdsOf(mergedPatient)).to.have.members([...patientFromSecretIds, ...patientIntoSecretIds])\n const retrievedByDelegateWithAccessToInto = await api3.patientApi.getPatientWithUser(user3, patientInto.id!)\n expect(retrievedByDelegateWithAccessToInto.firstName).to.equal(mergedFirstName)\n expect(retrievedByDelegateWithAccessToInto.lastName).to.equal(mergedLastName)\n expect(retrievedByDelegateWithAccessToInto.alias).to.equal(mergedAlias)\n expect(retrievedByDelegateWithAccessToInto.note).to.equal(mergedNote)\n expect(await api3.patientApi.decryptSecretIdsOf(retrievedByDelegateWithAccessToInto)).to.have.members(patientIntoSecretIds)\n const retrievedByDelegateWithAccessToFrom = await api2.patientApi.getPatientWithUser(user2, patientInto.id!)\n expect(retrievedByDelegateWithAccessToFrom.firstName).to.equal(mergedFirstName)\n expect(retrievedByDelegateWithAccessToFrom.lastName).to.equal(mergedLastName)\n expect(retrievedByDelegateWithAccessToFrom.alias).to.equal(mergedAlias)\n expect(retrievedByDelegateWithAccessToFrom.note).to.be.undefined // No access to new encryption key yet\n expect(await api2.patientApi.decryptSecretIdsOf(retrievedByDelegateWithAccessToFrom)).to.have.members(patientFromSecretIds)\n })\n\n it('Patient picture should be automatically decoded from base64 on initialisation.', async () => {\n const pictureAB = randomBytes(100)\n const pictureBase64 = ua2b64(pictureAB)\n const patient = new Patient({ picture: pictureBase64 })\n expect(patient.picture).to.not.be.undefined\n expect(patient.picture instanceof ArrayBuffer || ArrayBuffer.isView(patient.picture)).to.be.true\n const decodedPicture = new Uint8Array(patient.picture!)\n expect(decodedPicture).to.have.length(pictureAB.length)\n for (let i = 0; i < pictureAB.length; i++) {\n expect(decodedPicture[i]).to.equal(pictureAB[i])\n }\n })\n\n it('Creating a new Patient instance using a patient with decoded picture should not lose the picture data', async () => {\n const pictureAB = randomBytes(100)\n const patient = new Patient({ picture: new Uint8Array(pictureAB) })\n expect(patient.picture).to.not.be.undefined\n expect(patient.picture instanceof ArrayBuffer || ArrayBuffer.isView(patient.picture)).to.be.true\n const decodedPicture = new Uint8Array(patient.picture!)\n expect(decodedPicture).to.have.length(pictureAB.length)\n for (let i = 0; i < pictureAB.length; i++) {\n expect(decodedPicture[i]).to.equal(pictureAB[i])\n }\n })\n\n it('A Patient with picture data should be created and retrieved correctly', async () => {\n const pictureAB = randomBytes(100)\n const api = await initApi(env!, hcp1Username)\n const user = await api.userApi.getCurrentUser()\n const patient = await api.patientApi.createPatientWithUser(\n user,\n await api.patientApi.newInstance(user, { firstName: 'Giovanni', lastName: 'Giorgio', picture: new Uint8Array(pictureAB) })\n )\n expect(patient.picture).to.not.be.undefined\n expect(patient.picture instanceof ArrayBuffer || ArrayBuffer.isView(patient.picture)).to.be.true\n const decodedPicture = new Uint8Array(patient.picture!)\n expect(decodedPicture).to.have.length(pictureAB.length)\n for (let i = 0; i < pictureAB.length; i++) {\n expect(decodedPicture[i]).to.equal(pictureAB[i])\n }\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"icc-patient-x-api-test.js","sourceRoot":"","sources":["../../../test/icc-x-api/icc-patient-x-api-test.ts"],"names":[],"mappings":"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","sourcesContent":["import { before } from 'mocha'\n\nimport 'isomorphic-fetch'\n\nimport { Patient } from '../../icc-api/model/Patient'\nimport { assert, expect } from 'chai'\nimport { randomBytes, randomUUID } from 'crypto'\nimport { getEnvironmentInitializer, hcp1Username, hcp2Username, hcp3Username, setLocalStorage, TestUtils } from '../utils/test_utils'\nimport initApi = TestUtils.initApi\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\nimport { EntityWithDelegationTypeName, ua2b64 } from '../../icc-x-api'\n\nsetLocalStorage(fetch)\nlet env: TestVars\n\ndescribe('icc-x-patient-api Tests', () => {\n before(async function () {\n this.timeout(600000)\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n })\n\n it('CreatePatientWithUser Success for HCP', async () => {\n // Given\n const {\n userApi: userApiForHcp,\n dataOwnerApi: dataOwnerApiForHcp,\n patientApi: patientApiForHcp,\n cryptoApi: cryptoApiForHcp,\n } = await initApi(env, hcp1Username)\n\n const hcpUser = await userApiForHcp.getCurrentUser()\n\n const patientToCreate = await patientApiForHcp.newInstance(\n hcpUser,\n new Patient({\n id: randomUUID(),\n firstName: 'John',\n lastName: 'Snow',\n note: 'Winter is coming',\n })\n )\n\n // When\n const createdPatient = await patientApiForHcp.createPatientWithUser(hcpUser, patientToCreate)\n\n // Then\n const readPatient = await patientApiForHcp.getPatientWithUser(hcpUser, createdPatient.id!)\n assert(readPatient != null)\n assert(readPatient.id != null)\n assert(readPatient.note == patientToCreate.note)\n assert(readPatient.firstName == patientToCreate.firstName)\n assert(readPatient.lastName == patientToCreate.lastName)\n expect(\n await cryptoApiForHcp.xapi.encryptionKeysOf({ entity: readPatient, type: EntityWithDelegationTypeName.Patient }, undefined)\n ).to.have.length(1)\n expect(await patientApiForHcp.decryptSecretIdsOf(readPatient)).to.have.length(1)\n })\n\n it('Share with should work as expected', async () => {\n const api1 = await initApi(env!, hcp1Username)\n const user1 = await api1.userApi.getCurrentUser()\n const api2 = await initApi(env!, hcp2Username)\n const user2 = await api2.userApi.getCurrentUser()\n const encryptedField = 'Something encrypted'\n const entity = await api1.patientApi.createPatientWithUser(\n user1,\n await api1.patientApi.newInstance(user1, { firstName: 'Gigio', lastName: 'Bagigio', note: encryptedField })\n )\n expect(entity.note).to.be.equal(encryptedField)\n const secretIds = await api1.patientApi.decryptSecretIdsOf(entity)\n await api2.patientApi\n .getPatientWithUser(user2, entity.id)\n .then(() => {\n throw new Error('Should not be able to get the entity')\n })\n .catch(() => {\n /* expected */\n })\n await api1.patientApi.shareWith(user2.healthcarePartyId!, entity, secretIds)\n const retrieved = await api2.patientApi.getPatientWithUser(user2, entity.id)\n expect(retrieved.note).to.be.equal(encryptedField)\n expect(await api2.patientApi.decryptSecretIdsOf(retrieved)).to.have.members(secretIds)\n })\n\n it('Merge patients should work as expected', async () => {\n const api1 = await initApi(env!, hcp1Username)\n const user1 = await api1.userApi.getCurrentUser()\n const api2 = await initApi(env!, hcp2Username)\n const user2 = await api2.userApi.getCurrentUser()\n const api3 = await initApi(env!, hcp3Username)\n const user3 = await api3.userApi.getCurrentUser()\n const mergedFirstName = 'Gigio'\n const mergedLastName = 'Bagigio'\n const mergedAlias = 'Luigio'\n const mergedNote = 'A secret note'\n const patientFrom = await api1.patientApi.createPatientWithUser(\n user1,\n await api1.patientApi.newInstance(\n user1,\n {\n firstName: mergedFirstName,\n lastName: 'From',\n note: 'A',\n },\n { additionalDelegates: { [user2.healthcarePartyId!]: 'WRITE' } }\n )\n )\n const patientFromSecretIds = await api1.patientApi.decryptSecretIdsOf(patientFrom)\n expect(patientFromSecretIds).to.have.lengthOf(1)\n const patientInto = await api1.patientApi.createPatientWithUser(\n user1,\n await api1.patientApi.newInstance(\n user1,\n {\n firstName: 'Into',\n lastName: mergedLastName,\n note: 'B',\n },\n { additionalDelegates: { [user3.healthcarePartyId!]: 'WRITE' } }\n )\n )\n const patientIntoSecretIds = await api1.patientApi.decryptSecretIdsOf(patientInto)\n expect(patientFromSecretIds).to.have.lengthOf(1)\n expect(patientIntoSecretIds[0]).to.not.equal(patientFromSecretIds[0])\n const mergedInto = {\n ...patientInto,\n firstName: mergedFirstName,\n lastName: mergedLastName,\n alias: mergedAlias,\n note: mergedNote,\n }\n const mergedPatient = await api1.patientApi.mergePatients(patientFrom, mergedInto)\n expect(mergedPatient.firstName).to.equal(mergedFirstName)\n expect(mergedPatient.lastName).to.equal(mergedLastName)\n expect(mergedPatient.alias).to.equal(mergedAlias)\n expect(mergedPatient.note).to.equal(mergedNote)\n expect(await api1.patientApi.decryptSecretIdsOf(mergedPatient)).to.have.members([...patientFromSecretIds, ...patientIntoSecretIds])\n const retrievedByDelegateWithAccessToInto = await api3.patientApi.getPatientWithUser(user3, patientInto.id!)\n expect(retrievedByDelegateWithAccessToInto.firstName).to.equal(mergedFirstName)\n expect(retrievedByDelegateWithAccessToInto.lastName).to.equal(mergedLastName)\n expect(retrievedByDelegateWithAccessToInto.alias).to.equal(mergedAlias)\n expect(retrievedByDelegateWithAccessToInto.note).to.equal(mergedNote)\n expect(await api3.patientApi.decryptSecretIdsOf(retrievedByDelegateWithAccessToInto)).to.have.members(patientIntoSecretIds)\n const retrievedByDelegateWithAccessToFrom = await api2.patientApi.getPatientWithUser(user2, patientInto.id!)\n expect(retrievedByDelegateWithAccessToFrom.firstName).to.equal(mergedFirstName)\n expect(retrievedByDelegateWithAccessToFrom.lastName).to.equal(mergedLastName)\n expect(retrievedByDelegateWithAccessToFrom.alias).to.equal(mergedAlias)\n expect(retrievedByDelegateWithAccessToFrom.note).to.be.undefined // No access to new encryption key yet\n expect(await api2.patientApi.decryptSecretIdsOf(retrievedByDelegateWithAccessToFrom)).to.have.members(patientFromSecretIds)\n })\n\n it('Patient picture should be automatically decoded from base64 on initialisation.', async () => {\n const pictureAB = randomBytes(100)\n const pictureBase64 = ua2b64(pictureAB)\n const patient = new Patient({ picture: pictureBase64 })\n expect(patient.picture).to.not.be.undefined\n expect(patient.picture instanceof ArrayBuffer || ArrayBuffer.isView(patient.picture)).to.be.true\n const decodedPicture = new Uint8Array(patient.picture!)\n expect(decodedPicture).to.have.length(pictureAB.length)\n for (let i = 0; i < pictureAB.length; i++) {\n expect(decodedPicture[i]).to.equal(pictureAB[i])\n }\n })\n\n it('Creating a new Patient instance using a patient with decoded picture should not lose the picture data', async () => {\n const pictureAB = randomBytes(100)\n const patient = new Patient({ picture: new Uint8Array(pictureAB) })\n expect(patient.picture).to.not.be.undefined\n expect(patient.picture instanceof ArrayBuffer || ArrayBuffer.isView(patient.picture)).to.be.true\n const decodedPicture = new Uint8Array(patient.picture!)\n expect(decodedPicture).to.have.length(pictureAB.length)\n for (let i = 0; i < pictureAB.length; i++) {\n expect(decodedPicture[i]).to.equal(pictureAB[i])\n }\n })\n\n it('A Patient with picture data should be created and retrieved correctly', async () => {\n const pictureAB = randomBytes(100)\n const api = await initApi(env!, hcp1Username)\n const user = await api.userApi.getCurrentUser()\n const patient = await api.patientApi.createPatientWithUser(\n user,\n await api.patientApi.newInstance(user, { firstName: 'Giovanni', lastName: 'Giorgio', picture: new Uint8Array(pictureAB) })\n )\n expect(patient.picture).to.not.be.undefined\n expect(patient.picture instanceof ArrayBuffer || ArrayBuffer.isView(patient.picture)).to.be.true\n const decodedPicture = new Uint8Array(patient.picture!)\n expect(decodedPicture).to.have.length(pictureAB.length)\n for (let i = 0; i < pictureAB.length; i++) {\n expect(decodedPicture[i]).to.equal(pictureAB[i])\n }\n })\n\n it('A patient created with v8 + should have no auto-fixed delegations', async () => {\n const api = await initApi(env!, hcp1Username)\n const user = await api.userApi.getCurrentUser()\n const patient: Patient = await api.patientApi.createPatientWithUser(\n user,\n await api.patientApi.newInstance(user, { firstName: 'Giovanni', lastName: 'Giorgio', preferredUserId: user.id })\n )\n expect(Object.keys(patient.delegations ?? {}).length == 0).to.be.true\n })\n})\n"]}
|