@icure/api 6.4.0 → 7.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/icc-api/api/IccDeviceApi.d.ts +1 -1
  2. package/icc-api/api/IccDeviceApi.js.map +1 -1
  3. package/icc-api/api/IccDoctemplateApi.js.map +1 -1
  4. package/icc-api/api/IccDocumentTemplateApi.js.map +1 -1
  5. package/icc-api/api/IccHcpartyApi.d.ts +1 -1
  6. package/icc-api/api/IccHcpartyApi.js.map +1 -1
  7. package/icc-api/api/IccPatientApi.d.ts +1 -1
  8. package/icc-api/api/IccPatientApi.js.map +1 -1
  9. package/icc-api/model/MaintenanceTask.d.ts +6 -5
  10. package/icc-api/model/MaintenanceTask.js +5 -0
  11. package/icc-api/model/MaintenanceTask.js.map +1 -1
  12. package/icc-api/model/User.d.ts +23 -1
  13. package/icc-api/model/User.js +21 -0
  14. package/icc-api/model/User.js.map +1 -1
  15. package/icc-api/model/models.d.ts +14 -0
  16. package/icc-api/model/models.js.map +1 -1
  17. package/icc-x-api/crypto/AES.d.ts +2 -0
  18. package/icc-x-api/crypto/AES.js +12 -0
  19. package/icc-x-api/crypto/AES.js.map +1 -1
  20. package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +122 -0
  21. package/icc-x-api/crypto/BaseExchangeKeysManager.js +356 -0
  22. package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -0
  23. package/icc-x-api/crypto/ConfidentialEntities.d.ts +58 -0
  24. package/icc-x-api/crypto/ConfidentialEntities.js +99 -0
  25. package/icc-x-api/crypto/ConfidentialEntities.js.map +1 -0
  26. package/icc-x-api/crypto/CryptoPrimitives.d.ts +31 -0
  27. package/icc-x-api/crypto/CryptoPrimitives.js +55 -0
  28. package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -0
  29. package/icc-x-api/crypto/CryptoStrategies.d.ts +82 -0
  30. package/icc-x-api/crypto/CryptoStrategies.js +3 -0
  31. package/icc-x-api/crypto/CryptoStrategies.js.map +1 -0
  32. package/icc-x-api/crypto/EntitiesEncryption.d.ts +254 -0
  33. package/icc-x-api/crypto/EntitiesEncryption.js +700 -0
  34. package/icc-x-api/crypto/EntitiesEncryption.js.map +1 -0
  35. package/icc-x-api/crypto/ExchangeKeysManager.d.ts +56 -0
  36. package/icc-x-api/crypto/ExchangeKeysManager.js +147 -0
  37. package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -0
  38. package/icc-x-api/crypto/KeyManager.d.ts +103 -0
  39. package/icc-x-api/crypto/KeyManager.js +288 -0
  40. package/icc-x-api/crypto/KeyManager.js.map +1 -0
  41. package/icc-x-api/crypto/KeyRecovery.d.ts +34 -0
  42. package/icc-x-api/crypto/KeyRecovery.js +253 -0
  43. package/icc-x-api/crypto/KeyRecovery.js.map +1 -0
  44. package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +28 -0
  45. package/icc-x-api/crypto/LegacyCryptoStrategies.js +22 -0
  46. package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -0
  47. package/icc-x-api/crypto/RSA.d.ts +19 -20
  48. package/icc-x-api/crypto/RSA.js +30 -1
  49. package/icc-x-api/crypto/RSA.js.map +1 -1
  50. package/icc-x-api/crypto/ShamirKeysManager.d.ts +43 -0
  51. package/icc-x-api/crypto/ShamirKeysManager.js +150 -0
  52. package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -0
  53. package/icc-x-api/crypto/ShareMetadataBehaviour.d.ts +19 -0
  54. package/icc-x-api/crypto/ShareMetadataBehaviour.js +24 -0
  55. package/icc-x-api/crypto/ShareMetadataBehaviour.js.map +1 -0
  56. package/icc-x-api/crypto/TransferKeysManager.d.ts +29 -0
  57. package/icc-x-api/crypto/TransferKeysManager.js +121 -0
  58. package/icc-x-api/crypto/TransferKeysManager.js.map +1 -0
  59. package/icc-x-api/crypto/utils.d.ts +46 -0
  60. package/icc-x-api/crypto/utils.js +128 -0
  61. package/icc-x-api/crypto/utils.js.map +1 -1
  62. package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.d.ts +11 -0
  63. package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.js +11 -0
  64. package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.js.map +1 -1
  65. package/icc-x-api/filters/DeviceByHcPartyFilter.d.ts +11 -0
  66. package/icc-x-api/filters/DeviceByHcPartyFilter.js +11 -0
  67. package/icc-x-api/filters/DeviceByHcPartyFilter.js.map +1 -1
  68. package/icc-x-api/filters/DeviceByIdsFilter.d.ts +11 -0
  69. package/icc-x-api/filters/DeviceByIdsFilter.js +11 -0
  70. package/icc-x-api/filters/DeviceByIdsFilter.js.map +1 -1
  71. package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.d.ts +11 -0
  72. package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.js +11 -0
  73. package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.js.map +1 -1
  74. package/icc-x-api/icc-accesslog-x-api.d.ts +49 -4
  75. package/icc-x-api/icc-accesslog-x-api.js +112 -102
  76. package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
  77. package/icc-x-api/icc-calendar-item-x-api.d.ts +53 -5
  78. package/icc-x-api/icc-calendar-item-x-api.js +112 -100
  79. package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
  80. package/icc-x-api/icc-classification-x-api.d.ts +45 -2
  81. package/icc-x-api/icc-classification-x-api.js +89 -41
  82. package/icc-x-api/icc-classification-x-api.js.map +1 -1
  83. package/icc-x-api/icc-contact-x-api.d.ts +57 -19
  84. package/icc-x-api/icc-contact-x-api.js +149 -154
  85. package/icc-x-api/icc-contact-x-api.js.map +1 -1
  86. package/icc-x-api/icc-crypto-x-api.d.ts +266 -366
  87. package/icc-x-api/icc-crypto-x-api.js +416 -1327
  88. package/icc-x-api/icc-crypto-x-api.js.map +1 -1
  89. package/icc-x-api/icc-data-owner-x-api.d.ts +110 -11
  90. package/icc-x-api/icc-data-owner-x-api.js +188 -14
  91. package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
  92. package/icc-x-api/icc-doctemplate-x-api.js +3 -3
  93. package/icc-x-api/icc-doctemplate-x-api.js.map +1 -1
  94. package/icc-x-api/icc-document-x-api.d.ts +76 -5
  95. package/icc-x-api/icc-document-x-api.js +137 -59
  96. package/icc-x-api/icc-document-x-api.js.map +1 -1
  97. package/icc-x-api/icc-form-x-api.d.ts +47 -7
  98. package/icc-x-api/icc-form-x-api.js +85 -86
  99. package/icc-x-api/icc-form-x-api.js.map +1 -1
  100. package/icc-x-api/icc-hcparty-x-api.d.ts +1 -1
  101. package/icc-x-api/icc-hcparty-x-api.js +1 -1
  102. package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
  103. package/icc-x-api/icc-helement-x-api.d.ts +50 -3
  104. package/icc-x-api/icc-helement-x-api.js +101 -118
  105. package/icc-x-api/icc-helement-x-api.js.map +1 -1
  106. package/icc-x-api/icc-icure-maintenance-x-api.d.ts +31 -0
  107. package/icc-x-api/icc-icure-maintenance-x-api.js +124 -0
  108. package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -0
  109. package/icc-x-api/icc-invoice-x-api.d.ts +45 -5
  110. package/icc-x-api/icc-invoice-x-api.js +89 -64
  111. package/icc-x-api/icc-invoice-x-api.js.map +1 -1
  112. package/icc-x-api/icc-maintenance-task-x-api.d.ts +38 -6
  113. package/icc-x-api/icc-maintenance-task-x-api.js +73 -102
  114. package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
  115. package/icc-x-api/icc-message-x-api.d.ts +55 -2
  116. package/icc-x-api/icc-message-x-api.js +92 -33
  117. package/icc-x-api/icc-message-x-api.js.map +1 -1
  118. package/icc-x-api/icc-patient-x-api.d.ts +67 -7
  119. package/icc-x-api/icc-patient-x-api.js +409 -473
  120. package/icc-x-api/icc-patient-x-api.js.map +1 -1
  121. package/icc-x-api/icc-receipt-x-api.d.ts +49 -5
  122. package/icc-x-api/icc-receipt-x-api.js +85 -47
  123. package/icc-x-api/icc-receipt-x-api.js.map +1 -1
  124. package/icc-x-api/icc-time-table-x-api.d.ts +34 -10
  125. package/icc-x-api/icc-time-table-x-api.js +61 -18
  126. package/icc-x-api/icc-time-table-x-api.js.map +1 -1
  127. package/icc-x-api/index.d.ts +30 -1
  128. package/icc-x-api/index.js +112 -49
  129. package/icc-x-api/index.js.map +1 -1
  130. package/icc-x-api/maintenance/KeyPairUpdateRequest.d.ts +35 -0
  131. package/icc-x-api/maintenance/KeyPairUpdateRequest.js +54 -0
  132. package/icc-x-api/maintenance/KeyPairUpdateRequest.js.map +1 -0
  133. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.d.ts +9 -0
  134. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js +23 -0
  135. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js.map +1 -0
  136. package/icc-x-api/storage/IcureStorageFacade.d.ts +55 -0
  137. package/icc-x-api/storage/IcureStorageFacade.js +95 -0
  138. package/icc-x-api/storage/IcureStorageFacade.js.map +1 -0
  139. package/icc-x-api/storage/StorageEntryKeysFactory.d.ts +31 -0
  140. package/icc-x-api/storage/StorageEntryKeysFactory.js +3 -0
  141. package/icc-x-api/storage/StorageEntryKeysFactory.js.map +1 -0
  142. package/icc-x-api/utils/collection-utils.d.ts +8 -0
  143. package/icc-x-api/utils/collection-utils.js +26 -0
  144. package/icc-x-api/utils/collection-utils.js.map +1 -0
  145. package/icc-x-api/utils/crypto-utils.d.ts +8 -1
  146. package/icc-x-api/utils/crypto-utils.js +19 -3
  147. package/icc-x-api/utils/crypto-utils.js.map +1 -1
  148. package/icc-x-api/utils/graph-utils.d.ts +45 -0
  149. package/icc-x-api/utils/graph-utils.js +203 -0
  150. package/icc-x-api/utils/graph-utils.js.map +1 -0
  151. package/icc-x-api/utils/lru-temporised-async-cache.d.ts +27 -0
  152. package/icc-x-api/utils/lru-temporised-async-cache.js +120 -0
  153. package/icc-x-api/utils/lru-temporised-async-cache.js.map +1 -0
  154. package/package.json +1 -1
@@ -15,10 +15,10 @@ const _ = require("lodash");
15
15
  const models = require("../icc-api/model/models");
16
16
  const models_1 = require("../icc-api/model/models");
17
17
  const ModelHelper_1 = require("../icc-api/model/ModelHelper");
18
- const binary_utils_1 = require("./utils/binary-utils");
19
18
  const person_util_1 = require("./utils/person-util");
20
19
  const utils_1 = require("./utils");
21
20
  const AuthenticationProvider_1 = require("./auth/AuthenticationProvider");
21
+ const ShareMetadataBehaviour_1 = require("./crypto/ShareMetadataBehaviour");
22
22
  // noinspection JSUnusedGlobalSymbols
23
23
  class IccPatientXApi extends icc_api_1.IccPatientApi {
24
24
  constructor(host, headers, crypto, contactApi, formApi, helementApi, invoiceApi, documentApi, hcpartyApi, classificationApi, dataOwnerApi, calendarItemaApi, encryptedKeys = ['note'], authenticationProvider = new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl = typeof window !== 'undefined'
@@ -39,19 +39,42 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
39
39
  this.dataOwnerApi = dataOwnerApi;
40
40
  this.encryptedKeys = encryptedKeys;
41
41
  }
42
- // noinspection JSUnusedGlobalSymbols
43
- newInstance(user, p = {}, delegates = []) {
44
- const patient = _.extend({
45
- id: this.crypto.randomUuid(),
46
- _type: 'org.taktik.icure.entities.Patient',
47
- created: new Date().getTime(),
48
- modified: new Date().getTime(),
49
- responsible: this.dataOwnerApi.getDataOwnerOf(user),
50
- author: user.id,
51
- codes: [],
52
- tags: [],
53
- }, p || {});
54
- return this.initDelegationsAndEncryptionKeys(patient, user, undefined, delegates);
42
+ /**
43
+ * Creates a new instance of patient with initialised encryption metadata (not in the database).
44
+ * @param user the current user.
45
+ * @param p initialised data for the patient. Metadata such as id, creation data, etc. will be automatically initialised, but you can specify
46
+ * other kinds of data or overwrite generated metadata with this. You can't specify encryption metadata.
47
+ * @param options optional parameters:
48
+ * - additionalDelegates: delegates which will have access to the entity in addition to the current data owner and delegates from the
49
+ * 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
50
+ * auto-delegations, in such case the access level specified here will be used. Currently only WRITE access is supported, but in future also read
51
+ * access will be possible.
52
+ * @return a new instance of patient.
53
+ */
54
+ newInstance(user, p = {}, options = {}) {
55
+ var _a, _b, _c, _d, _e;
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const patient = _.extend({
58
+ id: this.crypto.primitives.randomUuid(),
59
+ _type: 'org.taktik.icure.entities.Patient',
60
+ created: new Date().getTime(),
61
+ modified: new Date().getTime(),
62
+ responsible: this.dataOwnerApi.getDataOwnerIdOf(user),
63
+ author: user.id,
64
+ codes: [],
65
+ tags: [],
66
+ }, p || {});
67
+ const ownerId = this.dataOwnerApi.getDataOwnerIdOf(user);
68
+ if (ownerId !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
69
+ throw new Error('Can only initialise entities as current data owner.');
70
+ const extraDelegations = [
71
+ ...Object.keys((_a = options.additionalDelegates) !== null && _a !== void 0 ? _a : {}),
72
+ ...((_c = (_b = user.autoDelegations) === null || _b === void 0 ? void 0 : _b.all) !== null && _c !== void 0 ? _c : []),
73
+ ...((_e = (_d = user.autoDelegations) === null || _d === void 0 ? void 0 : _d.medicalInformation) !== null && _e !== void 0 ? _e : []),
74
+ ];
75
+ const initialisationInfo = yield this.crypto.entities.entityWithInitialisedEncryptedMetadata(patient, undefined, undefined, true, extraDelegations);
76
+ return new models.Patient(initialisationInfo.updatedEntity);
77
+ });
55
78
  }
56
79
  completeNames(patient) {
57
80
  var _a;
@@ -77,57 +100,29 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
77
100
  }
78
101
  return finalPatient;
79
102
  }
80
- initDelegationsAndEncryptionKeys(patient, user, secretForeignKey = undefined, delegates = []) {
103
+ /**
104
+ * @deprecated replace with {@link initConfidentialSecretId}
105
+ */
106
+ initConfidentialDelegation(patient, user) {
81
107
  return __awaiter(this, void 0, void 0, function* () {
82
- function updatePatientWithDataOwnerIfSame(dataOwner) {
83
- if (dataOwner.id === patient.id) {
84
- _.extend(patient, {
85
- rev: dataOwner.rev,
86
- publicKey: dataOwner.publicKey,
87
- aesExchangeKeys: dataOwner.aesExchangeKeys,
88
- hcPartyKeys: dataOwner.hcPartyKeys
89
- });
90
- }
91
- }
92
- const dataOwnerId = this.dataOwnerApi.getDataOwnerOf(user);
93
- const dels = yield this.crypto.initObjectDelegations(patient, null, dataOwnerId, null);
94
- updatePatientWithDataOwnerIfSame(dels.owner);
95
- const eks = yield this.crypto.initEncryptionKeys(patient, dataOwnerId);
96
- updatePatientWithDataOwnerIfSame(eks.modifiedOwner);
97
- patient.delegations = dels.delegations;
98
- patient.encryptionKeys = eks.encryptionKeys;
99
- let promise = Promise.resolve(patient);
100
- _.uniq(delegates.concat(user.autoDelegations ? (user.autoDelegations.all || []).concat(user.autoDelegations.medicalInformation || []) : [])).forEach((delegateId) => (promise = promise.then((patient) => this.crypto.addDelegationsAndEncryptionKeys(null, patient, dataOwnerId, delegateId, dels.secretId, eks.secretId).catch((e) => {
101
- console.log(e);
102
- return patient;
103
- }))));
104
- (user.autoDelegations && user.autoDelegations.anonymousMedicalInformation ? user.autoDelegations.anonymousMedicalInformation : []).forEach((delegateId) => (promise = promise.then((patient) => this.crypto.addDelegationsAndEncryptionKeys(null, patient, dataOwnerId, delegateId, null, eks.secretId).catch((e) => {
105
- console.log(e);
106
- return patient;
107
- }))));
108
- return promise;
108
+ return this.initConfidentialSecretId(patient, user);
109
109
  });
110
110
  }
111
- initConfidentialDelegation(patient, user) {
112
- const dataOwnerId = this.dataOwnerApi.getDataOwnerOf(user);
113
- return this.crypto.extractPreferredSfk(patient, dataOwnerId, true).then((k) => {
114
- if (!k) {
115
- const secretId = this.crypto.randomUuid();
116
- return this.crypto
117
- .decryptAndImportAesHcPartyKeysForDelegators([dataOwnerId], dataOwnerId)
118
- .then((hcPartyKeys) => {
119
- return this.crypto.AES.encrypt(hcPartyKeys[0].key, (0, binary_utils_1.string2ua)(patient.id + ':' + secretId).buffer);
120
- })
121
- .then((newDelegation) => {
122
- ;
123
- (patient.delegations[dataOwnerId] || (patient.delegations[dataOwnerId] = [])).push(new models_1.Delegation({
124
- owner: dataOwnerId,
125
- delegatedTo: dataOwnerId,
126
- tag: 'confidential',
127
- key: (0, binary_utils_1.ua2hex)(newDelegation),
128
- }));
129
- return patient.rev ? this.modifyPatientWithUser(user, patient) : this.createPatientWithUser(user, patient);
130
- });
111
+ /**
112
+ * 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
113
+ * database.
114
+ * @param patient the patient for which you want to initialise the confidential secret id.
115
+ * @param user the current user.
116
+ * @return the updated patient or the original patient if no change was necessary.
117
+ */
118
+ initConfidentialSecretId(patient, user) {
119
+ return __awaiter(this, void 0, void 0, function* () {
120
+ const dataOwnerId = this.dataOwnerApi.getDataOwnerIdOf(user);
121
+ if (dataOwnerId !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
122
+ throw new Error('You can initialise confidential delegations only for the current data owner');
123
+ const initialised = yield this.crypto.confidential.entityWithInitialisedConfidentialSecretId(patient);
124
+ if (initialised) {
125
+ return initialised.rev ? this.modifyPatientWithUser(user, initialised) : this.createPatientWithUser(user, initialised);
131
126
  }
132
127
  else {
133
128
  return patient;
@@ -193,14 +188,14 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
193
188
  getPatientWithUser(user, patientId) {
194
189
  return super
195
190
  .getPatient(patientId)
196
- .then((p) => this.tryDecryptOrReturnOriginal(user, [p], false))
197
- .then((pats) => pats[0].patient);
191
+ .then((p) => this.tryDecryptOrReturnOriginal(this.dataOwnerApi.getDataOwnerIdOf(user), [p], false))
192
+ .then((pats) => pats[0].entity);
198
193
  }
199
194
  getPotentiallyEncryptedPatientWithUser(user, patientId) {
200
195
  return super
201
196
  .getPatient(patientId)
202
- .then((p) => this.tryDecryptOrReturnOriginal(user, [p], false))
203
- .then((pats) => pats[0]);
197
+ .then((p) => this.tryDecryptOrReturnOriginal(this.dataOwnerApi.getDataOwnerIdOf(user), [p], false))
198
+ .then((pats) => ({ patient: pats[0].entity, decrypted: pats[0].decrypted }));
204
199
  }
205
200
  getPatients(body) {
206
201
  throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption');
@@ -276,16 +271,13 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
276
271
  return super.modifyPatient(body);
277
272
  }
278
273
  modifyPatientWithUser(user, body) {
279
- return body
280
- ? this.tryEncrypt(user, [_.cloneDeep(this.completeNames(body))], false)
281
- .then((pats) => super.modifyPatient(pats[0]))
282
- .then((p) => this.decrypt(user, [p]))
283
- .then((pats) => {
284
- var _a;
285
- ((_a = pats[0]) === null || _a === void 0 ? void 0 : _a.id) && this.crypto.emptyHcpCache(pats[0].id);
286
- return pats[0];
287
- })
288
- : Promise.resolve(null);
274
+ return body ? this.modifyAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : Promise.resolve(null);
275
+ }
276
+ modifyAs(dataOwner, body) {
277
+ return this.encryptAs(dataOwner, [_.cloneDeep(this.completeNames(body))])
278
+ .then((pats) => super.modifyPatient(pats[0]))
279
+ .then((p) => this.tryDecryptOrReturnOriginal(dataOwner, [p]))
280
+ .then((pats) => pats[0].entity);
289
281
  }
290
282
  modifyPatientReferral(patientId, referralId, start, end) {
291
283
  throw new Error('Cannot call a method that returns contacts without providing a user for de/encryption');
@@ -294,134 +286,48 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
294
286
  return super
295
287
  .modifyPatientReferral(patientId, referralId, start, end)
296
288
  .then((p) => this.decrypt(user, [p]))
297
- .then((pats) => {
298
- var _a;
299
- ((_a = pats[0]) === null || _a === void 0 ? void 0 : _a.id) && this.crypto.emptyHcpCache(pats[0].id);
300
- return pats[0];
301
- });
289
+ .then((pats) => pats[0]);
302
290
  }
303
291
  encrypt(user, pats) {
304
- return this.tryEncrypt(user, pats, true);
305
- }
306
- tryEncrypt(user, pats, requireAccessibleKey) {
307
- const dataOwnerId = this.dataOwnerApi.getDataOwnerOf(user);
308
- return Promise.all(pats.map((p) => __awaiter(this, void 0, void 0, function* () {
309
- const patientWithInitialisedEks = (p.encryptionKeys && Object.values(p.encryptionKeys).some((v) => !!v.length)
310
- ? p
311
- : yield this.initEncryptionKeys(user, p));
312
- const seks = yield this.crypto.extractKeysFromDelegationsForHcpHierarchy(dataOwnerId, patientWithInitialisedEks.id, patientWithInitialisedEks.encryptionKeys).catch((e) => { console.error(e); throw e; });
313
- if (seks.extractedKeys.length) {
314
- const key = yield this.crypto.AES.importKey('raw', (0, binary_utils_1.hex2ua)(seks.extractedKeys[0].replace(/-/g, '')));
315
- return (0, utils_1.crypt)(patientWithInitialisedEks, (obj) => this.crypto.AES.encrypt(key, (0, binary_utils_1.utf8_2ua)(JSON.stringify(obj, (k, v) => {
316
- return v instanceof ArrayBuffer || v instanceof Uint8Array
317
- ? (0, binary_utils_1.b2a)(new Uint8Array(v).reduce((d, b) => d + String.fromCharCode(b), ''))
318
- : v;
319
- }))), this.encryptedKeys);
320
- }
321
- else if (requireAccessibleKey) {
322
- throw new Error(`Current data owner can't access any key of patient ${p.id}.`);
323
- }
324
- else {
325
- const cryptedCopyWithRandomKey = yield (0, utils_1.crypt)(_.cloneDeep(patientWithInitialisedEks), (obj) => __awaiter(this, void 0, void 0, function* () { return Promise.resolve(new ArrayBuffer(1)); }), this.encryptedKeys);
326
- if (!_.isEqual(_.omitBy(Object.assign(Object.assign({}, cryptedCopyWithRandomKey), { encryptedSelf: undefined }), _.isNil), _.omitBy(Object.assign(Object.assign({}, patientWithInitialisedEks), { encryptedSelf: undefined }), _.isNil))) {
327
- throw Error("You can't modify encrypted data of a patient if you don't have access to his encryption key.");
328
- }
329
- return patientWithInitialisedEks;
330
- }
331
- })));
292
+ return this.encryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), pats);
293
+ }
294
+ encryptAs(dataOwnerId, pats) {
295
+ return Promise.all(pats.map((p) => this.crypto.entities.tryEncryptEntity(p, dataOwnerId, this.encryptedKeys, true, false, (x) => new models.Patient(x))));
332
296
  }
333
297
  // If patient can't be decrypted returns patient with encrypted data.
334
298
  decrypt(user, patients, fillDelegations = true) {
335
- return this.tryDecryptOrReturnOriginal(user, patients, fillDelegations).then((ps) => ps.map((p) => p.patient));
336
- }
337
- tryDecryptOrReturnOriginal(user, patients, fillDelegations = true) {
338
- return __awaiter(this, void 0, void 0, function* () {
339
- const dataOwnerId = this.dataOwnerApi.getDataOwnerOf(user);
340
- const ids = yield (user.healthcarePartyId ? this.hcpartyApi.getHealthcarePartyHierarchyIds(user.healthcarePartyId) : Promise.resolve([dataOwnerId]));
341
- //First check that we have no dangling delegation
342
- const patsWithMissingDelegations = patients.filter((p) => p.delegations &&
343
- ids.some((id) => p.delegations[id] && !p.delegations[id].length) &&
344
- !Object.values(p.delegations).some((d) => d.length > 0));
345
- const acc = fillDelegations
346
- ? yield patsWithMissingDelegations.reduce((acc, p) => __awaiter(this, void 0, void 0, function* () {
347
- const pats = yield acc;
348
- const pat = yield this.initDelegationsAndEncryptionKeys(p, user);
349
- const mp = yield this.modifyPatientWithUser(user, pat);
350
- return Object.assign(Object.assign({}, pats), { [pat.id]: mp || pat });
351
- }), Promise.resolve({}))
352
- : {};
353
- return Promise.all(patients
354
- .map((p) => acc[p.id] || p)
355
- .map((p) => __awaiter(this, void 0, void 0, function* () {
356
- const decryptedPatient = yield ids.reduce((decP, hcpId) => __awaiter(this, void 0, void 0, function* () {
357
- var _a;
358
- return ((_a = (yield decP)) !== null && _a !== void 0 ? _a : (p.encryptedSelf
359
- ? yield this.crypto
360
- .extractKeysFromDelegationsForHcpHierarchy(hcpId, p.id, _.size(p.encryptionKeys) ? p.encryptionKeys : p.delegations)
361
- .then(({ extractedKeys: sfks }) => {
362
- if (!sfks || !sfks.length) {
363
- return Promise.resolve(undefined);
364
- }
365
- return this.crypto.AES.importKey('raw', (0, binary_utils_1.hex2ua)(sfks[0].replace(/-/g, ''))).then((key) => (0, utils_1.decrypt)(p, (ec) => this.crypto.AES.decrypt(key, ec)
366
- .then((dec) => {
367
- const jsonContent = dec && (0, binary_utils_1.ua2utf8)(dec);
368
- try {
369
- return JSON.parse(jsonContent);
370
- }
371
- catch (e) {
372
- console.log('Cannot parse patient', p.id, jsonContent || 'Invalid content');
373
- return Promise.resolve(undefined);
374
- }
375
- })
376
- .catch((err) => {
377
- console.log('Cannot decrypt patient', p.id, err);
378
- return Promise.resolve(undefined);
379
- })).then((p) => {
380
- if (p.picture && !(p.picture instanceof ArrayBuffer)) {
381
- p.picture = (0, ModelHelper_1.b64_2ab)(p.picture);
382
- }
383
- return p;
384
- }));
385
- })
386
- : p));
387
- }), Promise.resolve(undefined));
388
- return decryptedPatient ? { patient: decryptedPatient, decrypted: true } : { patient: p, decrypted: false };
389
- })));
390
- });
391
- }
392
- /** By default, an encryptionKey will be added for every hcp in the autoDelegations of the provided user.
393
- * In optional field additionalDelegateIds, you can ask the method to create encryptionKeys for additional hcps */
394
- initEncryptionKeys(user, pat, additionalDelegateIds) {
395
- const dataOwnerId = this.dataOwnerApi.getDataOwnerOf(user);
396
- const userAutoDelegations = user.autoDelegations ? (user.autoDelegations.all || []).concat(user.autoDelegations.medicalInformation || []) : [];
397
- return this.crypto.initEncryptionKeys(pat, dataOwnerId).then((eks) => {
398
- let promise = Promise.resolve(_.extend(pat.id === eks.modifiedOwner.id ? eks.modifiedOwner : pat, {
399
- encryptionKeys: eks.encryptionKeys,
400
- }));
401
- new Set([...userAutoDelegations, ...(additionalDelegateIds || [])]).forEach((delegateId) => (promise = promise.then((patient) => this.crypto
402
- .appendEncryptionKeys(patient, dataOwnerId, delegateId, eks.secretId)
403
- .then((extraEks) => {
404
- return _.extend(extraEks.modifiedObject, {
405
- encryptionKeys: extraEks.encryptionKeys,
406
- });
407
- })
408
- .catch((e) => {
409
- console.log(e.message);
410
- return patient;
411
- }))));
412
- return promise;
413
- });
299
+ return this.tryDecryptOrReturnOriginal(this.dataOwnerApi.getDataOwnerIdOf(user), patients, fillDelegations).then((ps) => ps.map((p) => p.entity));
300
+ }
301
+ tryDecryptOrReturnOriginal(dataOwnerId, patients, fillDelegations = true) {
302
+ return Promise.all(patients.map((p) => __awaiter(this, void 0, void 0, function* () {
303
+ return yield this.crypto.entities
304
+ .decryptEntity(p, dataOwnerId, (x) => new models.Patient(x))
305
+ .then((p) => {
306
+ if (p.entity.picture && !(p.entity.picture instanceof ArrayBuffer)) {
307
+ return {
308
+ entity: new models.Patient(Object.assign(Object.assign({}, p.entity), { picture: (0, ModelHelper_1.b64_2ab)(p.entity.picture) })),
309
+ decrypted: p.decrypted,
310
+ };
311
+ }
312
+ else
313
+ return p;
314
+ });
315
+ })));
414
316
  }
415
317
  share(user, patId, ownerId, delegateIds, delegationTags, usingPost = false) {
416
318
  const addDelegationsAndKeys = (dtos, markerPromise, delegateId, patient) => {
417
- return dtos.reduce((p, x) => p.then(() => Promise.all([this.crypto.extractDelegationsSFKs(x, ownerId), this.crypto.extractEncryptionsSKs(x, ownerId)]).then(([sfks, eks]) => {
418
- //console.log(`share ${x.id} to ${delegateId}`)
419
- return this.crypto
420
- .addDelegationsAndEncryptionKeys(patient, x, ownerId, delegateId, sfks.extractedKeys[0], eks.extractedKeys[0])
319
+ return dtos.reduce((p, x) => p.then(() => __awaiter(this, void 0, void 0, function* () {
320
+ const secretIds = yield this.crypto.entities.secretIdsOf(x, ownerId);
321
+ const encryptionKeys = yield this.crypto.entities.encryptionKeysOf(x, ownerId);
322
+ const parentIds = yield this.crypto.entities.owningEntityIdsOf(x, ownerId);
323
+ const updatedX = yield this.crypto.entities
324
+ .entityWithExtendedEncryptedMetadata(x, delegateId, secretIds, encryptionKeys, parentIds, [])
421
325
  .catch((e) => {
422
326
  console.log(e);
423
327
  return x;
424
328
  });
329
+ _.assign(x, updatedX);
330
+ return x;
425
331
  })), markerPromise);
426
332
  };
427
333
  const allTags = _.uniq(_.flatMap(Object.values(delegationTags)));
@@ -474,8 +380,10 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
474
380
  return (0, utils_1.retry)(() => this.getPatientWithUser(user, patId))
475
381
  .then((patient) => patient.encryptionKeys && Object.keys(patient.encryptionKeys || {}).length
476
382
  ? Promise.resolve(patient)
477
- : this.initEncryptionKeys(user, patient).then((patient) => this.modifyPatientWithUser(user, patient)))
478
- .then((patient) => {
383
+ : this.crypto.entities
384
+ .ensureEncryptionKeysInitialised(patient)
385
+ .then((patient) => this.modifyPatientWithUser(user, patient)))
386
+ .then((patient) => __awaiter(this, void 0, void 0, function* () {
479
387
  if (!patient) {
480
388
  status.patient = {
481
389
  success: false,
@@ -483,253 +391,234 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
483
391
  };
484
392
  return Promise.resolve({ patient: patient, statuses: status });
485
393
  }
486
- return this.crypto.extractDelegationsSFKsAndEncryptionSKs(patient, ownerId).then(([delSfks, ecKeys]) => {
487
- return delSfks.length
488
- ? Promise.all([
489
- (0, utils_1.retry)(() => (usingPost ? this.helementApi
490
- .findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks)) : this.helementApi
491
- .findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(',')))
492
- .then((hes) => parentId
493
- ? (usingPost ? this.helementApi
494
- .findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks)) : this.helementApi
495
- .findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))
496
- : hes)),
497
- (0, utils_1.retry)(() => (usingPost ? this.formApi
498
- .findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks)) : this.formApi
499
- .findFormsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((frms) => parentId
500
- ? (usingPost ? this.formApi
501
- .findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks)) : this.formApi
502
- .findFormsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))
503
- : frms)),
504
- (0, utils_1.retry)(() => (usingPost ? this.contactApi
505
- .findByHCPartyPatientSecretFKeysUsingPost(ownerId, undefined, undefined, _.uniq(delSfks)) : this.contactApi
506
- .findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((ctcs) => parentId
507
- ? (usingPost ? this.contactApi
508
- .findByHCPartyPatientSecretFKeysUsingPost(parentId, undefined, undefined, _.uniq(delSfks)) : this.contactApi
509
- .findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))
510
- : ctcs)),
511
- (0, utils_1.retry)(() => (usingPost ? this.invoiceApi
512
- .findInvoicesDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks)) : this.invoiceApi
513
- .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((ivs) => parentId
514
- ? this.invoiceApi
515
- .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))
516
- .then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))
517
- : ivs)),
518
- (0, utils_1.retry)(() => this.classificationApi
519
- .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))
520
- .then((cls) => parentId
521
- ? this.classificationApi
522
- .findClassificationsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))
523
- .then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))
524
- : cls)),
525
- (0, utils_1.retry)(() => (usingPost ? this.calendarItemApi
526
- .findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks)) : this.calendarItemApi
527
- .findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((cls) => parentId
528
- ? (usingPost ? this.calendarItemApi
529
- .findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks)) : this.calendarItemApi
530
- .findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))).then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))
531
- : cls)),
532
- ]).then(([hes, frms, ctcs, ivs, cls, cis]) => {
533
- const cloneKeysAndDelegations = function (x) {
534
- return {
535
- delegations: shareDelegations ? _.clone(x.delegations) : undefined,
536
- cryptedForeignKeys: shareCryptedForeignKeys ? _.clone(x.cryptedForeignKeys) : undefined,
537
- encryptionKeys: shareEncryptionKeys ? _.clone(x.encryptionKeys) : undefined,
538
- };
394
+ const delSfks = yield this.crypto.entities.secretIdsOf(patient, ownerId);
395
+ const ecKeys = yield this.crypto.entities.encryptionKeysOf(patient, ownerId);
396
+ return delSfks.length
397
+ ? Promise.all([
398
+ (0, utils_1.retry)(() => (usingPost
399
+ ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))
400
+ : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((hes) => parentId
401
+ ? (usingPost
402
+ ? this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))
403
+ : this.helementApi.findHealthElementsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))
404
+ : hes)),
405
+ (0, utils_1.retry)(() => (usingPost
406
+ ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))
407
+ : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((frms) => parentId
408
+ ? (usingPost
409
+ ? this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))
410
+ : this.formApi.findFormsDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))
411
+ : frms)),
412
+ (0, utils_1.retry)(() => (usingPost
413
+ ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(ownerId, undefined, undefined, _.uniq(delSfks))
414
+ : this.contactApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((ctcs) => parentId
415
+ ? (usingPost
416
+ ? this.contactApi.findByHCPartyPatientSecretFKeysUsingPost(parentId, undefined, undefined, _.uniq(delSfks))
417
+ : this.contactApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))
418
+ : ctcs)),
419
+ (0, utils_1.retry)(() => (usingPost
420
+ ? this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))
421
+ : this.invoiceApi.findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((ivs) => parentId
422
+ ? this.invoiceApi
423
+ .findInvoicesDelegationsStubsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))
424
+ .then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))
425
+ : ivs)),
426
+ (0, utils_1.retry)(() => this.classificationApi
427
+ .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))
428
+ .then((cls) => parentId
429
+ ? this.classificationApi
430
+ .findClassificationsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))
431
+ .then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))
432
+ : cls)),
433
+ (0, utils_1.retry)(() => (usingPost
434
+ ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))
435
+ : this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((cls) => parentId
436
+ ? (usingPost
437
+ ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))
438
+ : this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))).then((moreCls) => _.uniqBy(cls.concat(moreCls), 'id'))
439
+ : cls)),
440
+ ]).then(([hes, frms, ctcs, ivs, cls, cis]) => {
441
+ const cloneKeysAndDelegations = function (x) {
442
+ return {
443
+ delegations: shareDelegations ? _.clone(x.delegations) : undefined,
444
+ cryptedForeignKeys: shareCryptedForeignKeys ? _.clone(x.cryptedForeignKeys) : undefined,
445
+ encryptionKeys: shareEncryptionKeys ? _.clone(x.encryptionKeys) : undefined,
539
446
  };
540
- const ctcsStubs = ctcs.map((c) => (Object.assign({ id: c.id, rev: c.rev }, cloneKeysAndDelegations(c))));
541
- const oHes = hes.map((x) => _.assign(new models_1.IcureStub({}), x, cloneKeysAndDelegations(x)));
542
- const oFrms = frms.map((x) => _.assign(new models_1.IcureStub({}), x, cloneKeysAndDelegations(x)));
543
- const oCtcsStubs = ctcsStubs.map((x) => _.assign({}, x, cloneKeysAndDelegations(x)));
544
- const oIvs = ivs.map((x) => _.assign(new models_1.Invoice({}), x, cloneKeysAndDelegations(x)));
545
- const oCls = cls.map((x) => _.assign(new models_1.Classification({}), x, cloneKeysAndDelegations(x)));
546
- const oCis = cis.map((x) => _.assign(new models_1.CalendarItem({}), x, cloneKeysAndDelegations(x)));
547
- const docIds = {};
548
- ctcs.forEach((c) => c.services &&
549
- c.services.forEach((s) => s.content && Object.values(s.content).forEach((c) => c && c.documentId && (docIds[c.documentId] = 1))));
550
- return (0, utils_1.retry)(() => this.documentApi.getDocuments(new models_1.ListOfIds({ ids: Object.keys(docIds) }))).then((docs) => {
551
- const oDocs = docs.map((x) => _.assign({}, x, cloneKeysAndDelegations(x)));
552
- let markerPromise = Promise.resolve(null);
553
- delegateIds.forEach((delegateId) => {
554
- const tags = delegationTags[delegateId];
555
- markerPromise = markerPromise.then(() => {
556
- //Share patient
557
- //console.log(`share ${patient.id} to ${delegateId}`)
558
- return shareAnonymously
559
- ? patient
560
- : this.crypto
561
- .addDelegationsAndEncryptionKeys(null, patient, ownerId, delegateId, delSfks[0], ecKeys[0])
562
- .then((patient) => __awaiter(this, void 0, void 0, function* () {
563
- if (delSfks.length > 1) {
564
- return delSfks.slice(1).reduce((patientPromise, delSfk) => __awaiter(this, void 0, void 0, function* () {
565
- const patient = yield patientPromise;
566
- return shareAnonymously
567
- ? patient
568
- : this.crypto
569
- .addDelegationsAndEncryptionKeys(null, patient, ownerId, delegateId, delSfk, null)
570
- .catch((e) => {
571
- console.log(e);
572
- return patient;
573
- });
574
- }), Promise.resolve(patient));
575
- }
576
- return patient;
577
- }))
578
- .catch((e) => {
579
- console.log(e);
580
- return patient;
581
- });
447
+ };
448
+ const ctcsStubs = ctcs.map((c) => (Object.assign({ id: c.id, rev: c.rev }, cloneKeysAndDelegations(c))));
449
+ const oHes = hes.map((x) => _.assign(new models_1.IcureStub({}), x, cloneKeysAndDelegations(x)));
450
+ const oFrms = frms.map((x) => _.assign(new models_1.IcureStub({}), x, cloneKeysAndDelegations(x)));
451
+ const oCtcsStubs = ctcsStubs.map((x) => _.assign({}, x, cloneKeysAndDelegations(x)));
452
+ const oIvs = ivs.map((x) => _.assign(new models_1.Invoice({}), x, cloneKeysAndDelegations(x)));
453
+ const oCls = cls.map((x) => _.assign(new models_1.Classification({}), x, cloneKeysAndDelegations(x)));
454
+ const oCis = cis.map((x) => _.assign(new models_1.CalendarItem({}), x, cloneKeysAndDelegations(x)));
455
+ const docIds = {};
456
+ ctcs.forEach((c) => c.services &&
457
+ c.services.forEach((s) => s.content && Object.values(s.content).forEach((c) => c && c.documentId && (docIds[c.documentId] = 1))));
458
+ return (0, utils_1.retry)(() => this.documentApi.getDocuments(new models_1.ListOfIds({ ids: Object.keys(docIds) }))).then((docs) => {
459
+ const oDocs = docs.map((x) => _.assign({}, x, cloneKeysAndDelegations(x)));
460
+ let markerPromise = Promise.resolve(null);
461
+ delegateIds.forEach((delegateId) => {
462
+ const tags = delegationTags[delegateId];
463
+ markerPromise = markerPromise.then(() => __awaiter(this, void 0, void 0, function* () {
464
+ //Share patient
465
+ const updatedPatient = yield this.crypto.entities
466
+ .entityWithExtendedEncryptedMetadata(patient, delegateId, delSfks, ecKeys, [], [])
467
+ .catch((e) => {
468
+ console.log(e);
469
+ return patient;
582
470
  });
583
- (tags.includes('medicalInformation') || tags.includes('anonymousMedicalInformation') || tags.includes('all')) &&
584
- (markerPromise = addDelegationsAndKeys(hes, markerPromise, delegateId, patient));
585
- (tags.includes('medicalInformation') || tags.includes('all')) &&
586
- (markerPromise = addDelegationsAndKeys(frms, markerPromise, delegateId, patient));
587
- (tags.includes('medicalInformation') || tags.includes('anonymousMedicalInformation') || tags.includes('all')) &&
588
- (markerPromise = addDelegationsAndKeys(ctcsStubs, markerPromise, delegateId, patient));
589
- (tags.includes('medicalInformation') || tags.includes('all')) &&
590
- (markerPromise = addDelegationsAndKeys(cls, markerPromise, delegateId, patient));
591
- (tags.includes('medicalInformation') || tags.includes('all')) &&
592
- (markerPromise = addDelegationsAndKeys(cis, markerPromise, delegateId, patient));
593
- (tags.includes('financialInformation') || tags.includes('all')) &&
594
- (markerPromise = addDelegationsAndKeys(ivs, markerPromise, delegateId, patient));
595
- (tags.includes('medicalInformation') || tags.includes('all')) &&
596
- (markerPromise = addDelegationsAndKeys(docs, markerPromise, delegateId, null));
597
- });
598
- return markerPromise
599
- .then(() => {
600
- //console.log("scd")
601
- return (((allTags.includes('medicalInformation') || allTags.includes('anonymousMedicalInformation') || allTags.includes('all')) &&
602
- ctcsStubs &&
603
- ctcsStubs.length &&
604
- !_.isEqual(oCtcsStubs, ctcsStubs) &&
605
- this.contactApi
606
- .setContactsDelegations(ctcsStubs)
607
- .then(() => {
608
- status.contacts.success = true;
609
- status.contacts.modified += ctcsStubs.length;
610
- })
611
- .catch((e) => (status.contacts.error = e))) ||
612
- Promise.resolve((status.contacts.success = true)));
613
- })
614
- .then(() => {
615
- //console.log("shed")
616
- return (((allTags.includes('medicalInformation') || allTags.includes('anonymousMedicalInformation') || allTags.includes('all')) &&
617
- hes &&
618
- hes.length &&
619
- !_.isEqual(oHes, hes) &&
620
- this.helementApi
621
- .setHealthElementsDelegations(hes)
622
- .then(() => {
623
- status.healthElements.success = true;
624
- status.healthElements.modified += hes.length;
625
- })
626
- .catch((e) => (status.healthElements.error = e))) ||
627
- Promise.resolve((status.healthElements.success = true)));
628
- })
629
- .then(() => {
630
- //console.log("sfd")
631
- return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
632
- frms &&
633
- frms.length &&
634
- !_.isEqual(oFrms, frms) &&
635
- this.formApi
636
- .setFormsDelegations(frms)
637
- .then(() => {
638
- status.forms.success = true;
639
- status.forms.modified += frms.length;
640
- })
641
- .catch((e) => (status.forms.error = e))) ||
642
- Promise.resolve((status.forms.success = true)));
643
- })
644
- .then(() => {
645
- //console.log("sid")
646
- return (((allTags.includes('financialInformation') || allTags.includes('all')) &&
647
- ivs &&
648
- ivs.length &&
649
- !_.isEqual(oIvs, ivs) &&
650
- this.invoiceApi
651
- .setInvoicesDelegations(ivs)
652
- .then(() => {
653
- status.invoices.success = true;
654
- status.invoices.modified += ivs.length;
655
- })
656
- .catch((e) => (status.invoices.error = e))) ||
657
- Promise.resolve((status.invoices.success = true)));
658
- })
659
- .then(() => {
660
- //console.log("sdd")
661
- return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
662
- docs &&
663
- docs.length &&
664
- !_.isEqual(oDocs, docs) &&
665
- this.documentApi
666
- .setDocumentsDelegations(docs)
667
- .then(() => {
668
- status.documents.success = true;
669
- status.documents.modified += docs.length;
670
- })
671
- .catch((e) => (status.documents.error = e))) ||
672
- Promise.resolve((status.documents.success = true)));
673
- })
674
- .then(() => {
675
- //console.log("scld")
676
- return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
677
- cls &&
678
- cls.length &&
679
- !_.isEqual(oCls, cls) &&
680
- this.classificationApi
681
- .setClassificationsDelegations(cls)
682
- .then(() => {
683
- status.classifications.success = true;
684
- status.classifications.modified += cls.length;
685
- })
686
- .catch((e) => (status.classifications.error = e))) ||
687
- Promise.resolve((status.classifications.success = true)));
688
- })
689
- .then(() => {
690
- //console.log("scid")
691
- return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
692
- cis &&
693
- cis.length &&
694
- !_.isEqual(oCis, cis) &&
695
- this.calendarItemApi
696
- .setCalendarItemsDelegations(cis)
697
- .then(() => {
698
- status.calendarItems.success = true;
699
- status.calendarItems.modified += cis.length;
700
- })
701
- .catch((e) => (status.calendarItems.error = e))) ||
702
- Promise.resolve((status.calendarItems.success = true)));
703
- })
704
- .then(() => this.modifyPatientWithUser(user, patient))
705
- .then((p) => {
706
- status.patient.success = true;
707
- console.log(`c: ${status.contacts.modified}, he: ${status.healthElements.modified}, docs: ${status.documents.modified}, frms: ${status.forms.modified}, ivs: ${status.invoices.modified}, cis: ${status.calendarItems.modified}, cls: ${status.classifications.modified}`);
708
- return { patient: p, statuses: status };
709
- })
710
- .catch((e) => {
711
- status.patient.error = e;
712
- return { patient: patient, statuses: status };
713
- });
471
+ return _.assign(patient, updatedPatient);
472
+ }));
473
+ (tags.includes('medicalInformation') || tags.includes('anonymousMedicalInformation') || tags.includes('all')) &&
474
+ (markerPromise = addDelegationsAndKeys(hes, markerPromise, delegateId, patient));
475
+ (tags.includes('medicalInformation') || tags.includes('all')) &&
476
+ (markerPromise = addDelegationsAndKeys(frms, markerPromise, delegateId, patient));
477
+ (tags.includes('medicalInformation') || tags.includes('anonymousMedicalInformation') || tags.includes('all')) &&
478
+ (markerPromise = addDelegationsAndKeys(ctcsStubs, markerPromise, delegateId, patient));
479
+ (tags.includes('medicalInformation') || tags.includes('all')) &&
480
+ (markerPromise = addDelegationsAndKeys(cls, markerPromise, delegateId, patient));
481
+ (tags.includes('medicalInformation') || tags.includes('all')) &&
482
+ (markerPromise = addDelegationsAndKeys(cis, markerPromise, delegateId, patient));
483
+ (tags.includes('financialInformation') || tags.includes('all')) &&
484
+ (markerPromise = addDelegationsAndKeys(ivs, markerPromise, delegateId, patient));
485
+ (tags.includes('medicalInformation') || tags.includes('all')) &&
486
+ (markerPromise = addDelegationsAndKeys(docs, markerPromise, delegateId, null));
487
+ });
488
+ return markerPromise
489
+ .then(() => {
490
+ //console.log("scd")
491
+ return (((allTags.includes('medicalInformation') || allTags.includes('anonymousMedicalInformation') || allTags.includes('all')) &&
492
+ ctcsStubs &&
493
+ ctcsStubs.length &&
494
+ !_.isEqual(oCtcsStubs, ctcsStubs) &&
495
+ this.contactApi
496
+ .setContactsDelegations(ctcsStubs)
497
+ .then(() => {
498
+ status.contacts.success = true;
499
+ status.contacts.modified += ctcsStubs.length;
500
+ })
501
+ .catch((e) => (status.contacts.error = e))) ||
502
+ Promise.resolve((status.contacts.success = true)));
503
+ })
504
+ .then(() => {
505
+ //console.log("shed")
506
+ return (((allTags.includes('medicalInformation') || allTags.includes('anonymousMedicalInformation') || allTags.includes('all')) &&
507
+ hes &&
508
+ hes.length &&
509
+ !_.isEqual(oHes, hes) &&
510
+ this.helementApi
511
+ .setHealthElementsDelegations(hes)
512
+ .then(() => {
513
+ status.healthElements.success = true;
514
+ status.healthElements.modified += hes.length;
515
+ })
516
+ .catch((e) => (status.healthElements.error = e))) ||
517
+ Promise.resolve((status.healthElements.success = true)));
518
+ })
519
+ .then(() => {
520
+ //console.log("sfd")
521
+ return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
522
+ frms &&
523
+ frms.length &&
524
+ !_.isEqual(oFrms, frms) &&
525
+ this.formApi
526
+ .setFormsDelegations(frms)
527
+ .then(() => {
528
+ status.forms.success = true;
529
+ status.forms.modified += frms.length;
530
+ })
531
+ .catch((e) => (status.forms.error = e))) ||
532
+ Promise.resolve((status.forms.success = true)));
533
+ })
534
+ .then(() => {
535
+ //console.log("sid")
536
+ return (((allTags.includes('financialInformation') || allTags.includes('all')) &&
537
+ ivs &&
538
+ ivs.length &&
539
+ !_.isEqual(oIvs, ivs) &&
540
+ this.invoiceApi
541
+ .setInvoicesDelegations(ivs)
542
+ .then(() => {
543
+ status.invoices.success = true;
544
+ status.invoices.modified += ivs.length;
545
+ })
546
+ .catch((e) => (status.invoices.error = e))) ||
547
+ Promise.resolve((status.invoices.success = true)));
548
+ })
549
+ .then(() => {
550
+ //console.log("sdd")
551
+ return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
552
+ docs &&
553
+ docs.length &&
554
+ !_.isEqual(oDocs, docs) &&
555
+ this.documentApi
556
+ .setDocumentsDelegations(docs)
557
+ .then(() => {
558
+ status.documents.success = true;
559
+ status.documents.modified += docs.length;
560
+ })
561
+ .catch((e) => (status.documents.error = e))) ||
562
+ Promise.resolve((status.documents.success = true)));
563
+ })
564
+ .then(() => {
565
+ //console.log("scld")
566
+ return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
567
+ cls &&
568
+ cls.length &&
569
+ !_.isEqual(oCls, cls) &&
570
+ this.classificationApi
571
+ .setClassificationsDelegations(cls)
572
+ .then(() => {
573
+ status.classifications.success = true;
574
+ status.classifications.modified += cls.length;
575
+ })
576
+ .catch((e) => (status.classifications.error = e))) ||
577
+ Promise.resolve((status.classifications.success = true)));
578
+ })
579
+ .then(() => {
580
+ //console.log("scid")
581
+ return (((allTags.includes('medicalInformation') || allTags.includes('all')) &&
582
+ cis &&
583
+ cis.length &&
584
+ !_.isEqual(oCis, cis) &&
585
+ this.calendarItemApi
586
+ .setCalendarItemsDelegations(cis)
587
+ .then(() => {
588
+ status.calendarItems.success = true;
589
+ status.calendarItems.modified += cis.length;
590
+ })
591
+ .catch((e) => (status.calendarItems.error = e))) ||
592
+ Promise.resolve((status.calendarItems.success = true)));
593
+ })
594
+ .then(() => this.modifyPatientWithUser(user, patient))
595
+ .then((p) => {
596
+ status.patient.success = true;
597
+ console.log(`c: ${status.contacts.modified}, he: ${status.healthElements.modified}, docs: ${status.documents.modified}, frms: ${status.forms.modified}, ivs: ${status.invoices.modified}, cis: ${status.calendarItems.modified}, cls: ${status.classifications.modified}`);
598
+ return { patient: p, statuses: status };
599
+ })
600
+ .catch((e) => {
601
+ status.patient.error = e;
602
+ return { patient: patient, statuses: status };
714
603
  });
715
- })
716
- : (allTags.includes('anonymousMedicalInformation')
717
- ? Promise.resolve(patient)
718
- : this.modifyPatientWithUser(user, _.assign(patient, {
719
- delegations: _.assign(patient.delegations, delegateIds
720
- .filter((id) => !patient.delegations || !patient.delegations[id]) //If there are delegations do not modify
721
- .reduce((acc, del) => Object.assign(acc, _.fromPairs([[del, []]])), patient.delegations || {})),
722
- })))
723
- .then((p) => {
724
- status.patient.success = true;
725
- return { patient: p, statuses: status };
726
- })
727
- .catch((e) => {
728
- status.patient.error = e;
729
- return { patient: patient, statuses: status };
730
604
  });
731
- });
732
- });
605
+ })
606
+ : (allTags.includes('anonymousMedicalInformation')
607
+ ? Promise.resolve(patient)
608
+ : this.modifyPatientWithUser(user, _.assign(patient, {
609
+ delegations: _.assign(patient.delegations, delegateIds
610
+ .filter((id) => !patient.delegations || !patient.delegations[id]) //If there are delegations do not modify
611
+ .reduce((acc, del) => Object.assign(acc, _.fromPairs([[del, []]])), patient.delegations || {})),
612
+ })))
613
+ .then((p) => {
614
+ status.patient.success = true;
615
+ return { patient: p, statuses: status };
616
+ })
617
+ .catch((e) => {
618
+ status.patient.error = e;
619
+ return { patient: patient, statuses: status };
620
+ });
621
+ }));
733
622
  });
734
623
  }
735
624
  export(user, patId, ownerId, usingPost = false) {
@@ -738,41 +627,44 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
738
627
  return (0, utils_1.retry)(() => this.getPatientWithUser(user, patId))
739
628
  .then((patient) => patient.encryptionKeys && Object.keys(patient.encryptionKeys || {}).length
740
629
  ? Promise.resolve(patient)
741
- : this.initEncryptionKeys(user, patient).then((patient) => this.modifyPatientWithUser(user, patient)))
742
- .then((patient) => {
630
+ : this.crypto.entities
631
+ .ensureEncryptionKeysInitialised(patient)
632
+ .then((patient) => this.modifyPatientWithUser(user, patient)))
633
+ .then((patient) => __awaiter(this, void 0, void 0, function* () {
743
634
  if (!patient) {
744
635
  return Promise.resolve({ id: patId });
745
636
  }
746
- return this.crypto.extractDelegationsSFKsAndEncryptionSKs(patient, ownerId).then(([delSfks, ecKeys]) => {
637
+ const delSfks = yield this.crypto.entities.secretIdsOf(patient, ownerId);
638
+ return Promise.resolve().then(() => {
747
639
  return delSfks.length
748
640
  ? Promise.all([
749
- (0, utils_1.retry)(() => (usingPost ? this.helementApi
750
- .findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks)) : this.helementApi
751
- .findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((hes) => parentId
641
+ (0, utils_1.retry)(() => (usingPost
642
+ ? this.helementApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))
643
+ : this.helementApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((hes) => parentId
752
644
  ? this.helementApi
753
645
  .findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))
754
646
  .then((moreHes) => _.uniqBy(hes.concat(moreHes), 'id'))
755
647
  : hes)),
756
- (0, utils_1.retry)(() => (usingPost ? this.formApi
757
- .findFormsByHCPartyPatientForeignKeysUsingPost(ownerId, undefined, undefined, undefined, _.uniq(delSfks)) : this.formApi
758
- .findFormsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((frms) => parentId
759
- ? (usingPost ? this.formApi
760
- .findFormsByHCPartyPatientForeignKeysUsingPost(parentId, undefined, undefined, undefined, _.uniq(delSfks)) : this.formApi
761
- .findFormsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))
648
+ (0, utils_1.retry)(() => (usingPost
649
+ ? this.formApi.findFormsByHCPartyPatientForeignKeysUsingPost(ownerId, undefined, undefined, undefined, _.uniq(delSfks))
650
+ : this.formApi.findFormsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((frms) => parentId
651
+ ? (usingPost
652
+ ? this.formApi.findFormsByHCPartyPatientForeignKeysUsingPost(parentId, undefined, undefined, undefined, _.uniq(delSfks))
653
+ : this.formApi.findFormsByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreFrms) => _.uniqBy(frms.concat(moreFrms), 'id'))
762
654
  : frms)),
763
- (0, utils_1.retry)(() => (usingPost ? this.contactApi
764
- .findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks)) : this.contactApi
765
- .findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((ctcs) => parentId
766
- ? (usingPost ? this.contactApi
767
- .findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks)) : this.contactApi
768
- .findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))
655
+ (0, utils_1.retry)(() => (usingPost
656
+ ? this.contactApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))
657
+ : this.contactApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(','))).then((ctcs) => parentId
658
+ ? (usingPost
659
+ ? this.contactApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))
660
+ : this.contactApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(','))).then((moreCtcs) => _.uniqBy(ctcs.concat(moreCtcs), 'id'))
769
661
  : ctcs)),
770
- (0, utils_1.retry)(() => (usingPost ? this.invoiceApi
771
- .findInvoicesByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks)) : this.invoiceApi
772
- .findInvoicesByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((ivs) => parentId
773
- ? (usingPost ? this.invoiceApi
774
- .findInvoicesByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks)) : this.invoiceApi
775
- .findInvoicesByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))
662
+ (0, utils_1.retry)(() => (usingPost
663
+ ? this.invoiceApi.findInvoicesByHCPartyPatientForeignKeysUsingPost(ownerId, _.uniq(delSfks))
664
+ : this.invoiceApi.findInvoicesByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))).then((ivs) => parentId
665
+ ? (usingPost
666
+ ? this.invoiceApi.findInvoicesByHCPartyPatientForeignKeysUsingPost(parentId, _.uniq(delSfks))
667
+ : this.invoiceApi.findInvoicesByHCPartyPatientForeignKeys(parentId, _.uniq(delSfks).join(','))).then((moreIvs) => _.uniqBy(ivs.concat(moreIvs), 'id'))
776
668
  : ivs)),
777
669
  (0, utils_1.retry)(() => this.classificationApi
778
670
  .findClassificationsByHCPartyPatientForeignKeys(ownerId, _.uniq(delSfks).join(','))
@@ -784,13 +676,13 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
784
676
  (0, utils_1.retry)(() => __awaiter(this, void 0, void 0, function* () {
785
677
  const delegationSFKs = _.uniq(delSfks).join(',');
786
678
  try {
787
- let calendarItems = yield (usingPost ?
788
- this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks)) :
789
- this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(',')));
679
+ let calendarItems = yield (usingPost
680
+ ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(ownerId, _.uniq(delSfks))
681
+ : this.calendarItemApi.findByHCPartyPatientSecretFKeys(ownerId, _.uniq(delSfks).join(',')));
790
682
  if (parentId) {
791
- const moreCalendarItems = yield (usingPost ?
792
- this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks)) :
793
- this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(',')));
683
+ const moreCalendarItems = yield (usingPost
684
+ ? this.calendarItemApi.findByHCPartyPatientSecretFKeysArray(parentId, _.uniq(delSfks))
685
+ : this.calendarItemApi.findByHCPartyPatientSecretFKeys(parentId, _.uniq(delSfks).join(',')));
794
686
  calendarItems = _.uniqBy(calendarItems.concat(moreCalendarItems), 'id');
795
687
  }
796
688
  return calendarItems;
@@ -830,13 +722,13 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
830
722
  documents: [],
831
723
  });
832
724
  });
833
- });
725
+ }));
834
726
  });
835
727
  }
836
728
  checkInami(inami) {
837
729
  const num_inami = inami.replace(new RegExp('[^(0-9)]', 'g'), '');
838
- const checkDigit = num_inami.substr(6, 2);
839
- const numSansCheck = num_inami.substr(0, 6);
730
+ const checkDigit = num_inami.substring(6, 2);
731
+ const numSansCheck = num_inami.substring(0, 6);
840
732
  let retour = false;
841
733
  //modulo du niss
842
734
  const modINAMI = parseInt(numSansCheck) % 97;
@@ -855,9 +747,9 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
855
747
  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);
856
748
  if (normalNumber || bisNumber || terNumber) {
857
749
  isValidNiss =
858
- 97 - (Number(ssin.substr(0, 9)) % 97) === Number(ssin.substr(9, 2))
750
+ 97 - (Number(ssin.substring(0, 9)) % 97) === Number(ssin.substring(9, 2))
859
751
  ? true
860
- : 97 - (Number('2' + ssin.substr(0, 9)) % 97) === Number(ssin.substr(9, 2));
752
+ : 97 - (Number('2' + ssin.substring(0, 9)) % 97) === Number(ssin.substring(9, 2));
861
753
  }
862
754
  return isValidNiss;
863
755
  }
@@ -866,7 +758,7 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
866
758
  getPatient: { get: () => super.getPatient }
867
759
  });
868
760
  return __awaiter(this, void 0, void 0, function* () {
869
- const parentIdsArray = (yield this.crypto.extractCryptedFKs(childDocument, hcpId)).extractedKeys;
761
+ const parentIdsArray = yield this.crypto.entities.owningEntityIdsOf(childDocument, hcpId);
870
762
  const multipleParentIds = _.uniq(parentIdsArray).length > 1;
871
763
  if (multipleParentIds) {
872
764
  throw 'Child document with id ' + childDocument.id + ' contains multiple parent ids in its CFKs for hcpId: ' + hcpId;
@@ -888,6 +780,50 @@ class IccPatientXApi extends icc_api_1.IccPatientApi {
888
780
  return patient.id;
889
781
  });
890
782
  }
783
+ /**
784
+ * Share an existing patient with other data owners, allowing them to access the non-encrypted data of the patient and optionally also
785
+ * the encrypted content.
786
+ * @param delegateId the id of the data owner which will be granted access to the patient.
787
+ * @param patient the patient to share.
788
+ * @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
789
+ * shared Patient is the owning entity id.
790
+ * @param options optional parameters to customize the sharing behaviour:
791
+ * - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted
792
+ * content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a
793
+ * patient does not have encrypted content.
794
+ * {@link ShareMetadataBehaviour.IF_AVAILABLE}).
795
+ * @return a promise which will contain the updated patient.
796
+ */
797
+ shareWith(delegateId, patient, shareSecretIds, options = {}) {
798
+ return __awaiter(this, void 0, void 0, function* () {
799
+ const self = yield this.dataOwnerApi.getCurrentDataOwnerId();
800
+ return yield this.modifyAs(self, yield this.crypto.entities.entityWithAutoExtendedEncryptedMetadata(patient, delegateId, shareSecretIds, options.shareEncryptionKey, ShareMetadataBehaviour_1.ShareMetadataBehaviour.IF_AVAILABLE));
801
+ });
802
+ }
803
+ /**
804
+ * @param patient a patient
805
+ * @return all the decryptable secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the
806
+ * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.
807
+ */
808
+ decryptSecretIdsOf(patient) {
809
+ return this.crypto.entities.secretIdsOf(patient, undefined);
810
+ }
811
+ /**
812
+ * @param patient a patient
813
+ * @return the confidential secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the
814
+ * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.
815
+ */
816
+ decryptConfidentialSecretIdsOf(patient) {
817
+ return this.crypto.confidential.getConfidentialSecretIds(patient, undefined);
818
+ }
819
+ /**
820
+ * @param patient a patient
821
+ * @return the non-confidential secret ids of the patient, retrieved from the encrypted metadata. The result may be used to find entities where the
822
+ * patient is the 'owning entity', or in the {@link shareWith} method in order to share it with other data owners.
823
+ */
824
+ decryptNonConfidentialSecretIdsOf(patient) {
825
+ return this.crypto.confidential.getSecretIdsSharedWithParents(patient);
826
+ }
891
827
  }
892
828
  exports.IccPatientXApi = IccPatientXApi;
893
829
  //# sourceMappingURL=icc-patient-x-api.js.map