@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.
- package/icc-api/api/IccDeviceApi.d.ts +1 -1
- package/icc-api/api/IccDeviceApi.js.map +1 -1
- package/icc-api/api/IccDoctemplateApi.js.map +1 -1
- package/icc-api/api/IccDocumentTemplateApi.js.map +1 -1
- package/icc-api/api/IccHcpartyApi.d.ts +1 -1
- package/icc-api/api/IccHcpartyApi.js.map +1 -1
- package/icc-api/api/IccPatientApi.d.ts +1 -1
- package/icc-api/api/IccPatientApi.js.map +1 -1
- package/icc-api/model/MaintenanceTask.d.ts +6 -5
- package/icc-api/model/MaintenanceTask.js +5 -0
- package/icc-api/model/MaintenanceTask.js.map +1 -1
- package/icc-api/model/User.d.ts +23 -1
- package/icc-api/model/User.js +21 -0
- package/icc-api/model/User.js.map +1 -1
- package/icc-api/model/models.d.ts +14 -0
- package/icc-api/model/models.js.map +1 -1
- package/icc-x-api/crypto/AES.d.ts +2 -0
- package/icc-x-api/crypto/AES.js +12 -0
- package/icc-x-api/crypto/AES.js.map +1 -1
- package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +122 -0
- package/icc-x-api/crypto/BaseExchangeKeysManager.js +356 -0
- package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -0
- package/icc-x-api/crypto/ConfidentialEntities.d.ts +58 -0
- package/icc-x-api/crypto/ConfidentialEntities.js +99 -0
- package/icc-x-api/crypto/ConfidentialEntities.js.map +1 -0
- package/icc-x-api/crypto/CryptoPrimitives.d.ts +31 -0
- package/icc-x-api/crypto/CryptoPrimitives.js +55 -0
- package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -0
- package/icc-x-api/crypto/CryptoStrategies.d.ts +82 -0
- package/icc-x-api/crypto/CryptoStrategies.js +3 -0
- package/icc-x-api/crypto/CryptoStrategies.js.map +1 -0
- package/icc-x-api/crypto/EntitiesEncryption.d.ts +254 -0
- package/icc-x-api/crypto/EntitiesEncryption.js +700 -0
- package/icc-x-api/crypto/EntitiesEncryption.js.map +1 -0
- package/icc-x-api/crypto/ExchangeKeysManager.d.ts +56 -0
- package/icc-x-api/crypto/ExchangeKeysManager.js +147 -0
- package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -0
- package/icc-x-api/crypto/KeyManager.d.ts +103 -0
- package/icc-x-api/crypto/KeyManager.js +288 -0
- package/icc-x-api/crypto/KeyManager.js.map +1 -0
- package/icc-x-api/crypto/KeyRecovery.d.ts +34 -0
- package/icc-x-api/crypto/KeyRecovery.js +253 -0
- package/icc-x-api/crypto/KeyRecovery.js.map +1 -0
- package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +28 -0
- package/icc-x-api/crypto/LegacyCryptoStrategies.js +22 -0
- package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -0
- package/icc-x-api/crypto/RSA.d.ts +19 -20
- package/icc-x-api/crypto/RSA.js +30 -1
- package/icc-x-api/crypto/RSA.js.map +1 -1
- package/icc-x-api/crypto/ShamirKeysManager.d.ts +43 -0
- package/icc-x-api/crypto/ShamirKeysManager.js +150 -0
- package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -0
- package/icc-x-api/crypto/ShareMetadataBehaviour.d.ts +19 -0
- package/icc-x-api/crypto/ShareMetadataBehaviour.js +24 -0
- package/icc-x-api/crypto/ShareMetadataBehaviour.js.map +1 -0
- package/icc-x-api/crypto/TransferKeysManager.d.ts +29 -0
- package/icc-x-api/crypto/TransferKeysManager.js +121 -0
- package/icc-x-api/crypto/TransferKeysManager.js.map +1 -0
- package/icc-x-api/crypto/utils.d.ts +46 -0
- package/icc-x-api/crypto/utils.js +128 -0
- package/icc-x-api/crypto/utils.js.map +1 -1
- package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.d.ts +11 -0
- package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.js +11 -0
- package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.js.map +1 -1
- package/icc-x-api/filters/DeviceByHcPartyFilter.d.ts +11 -0
- package/icc-x-api/filters/DeviceByHcPartyFilter.js +11 -0
- package/icc-x-api/filters/DeviceByHcPartyFilter.js.map +1 -1
- package/icc-x-api/filters/DeviceByIdsFilter.d.ts +11 -0
- package/icc-x-api/filters/DeviceByIdsFilter.js +11 -0
- package/icc-x-api/filters/DeviceByIdsFilter.js.map +1 -1
- package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.d.ts +11 -0
- package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.js +11 -0
- package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +49 -4
- package/icc-x-api/icc-accesslog-x-api.js +112 -102
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.d.ts +53 -5
- package/icc-x-api/icc-calendar-item-x-api.js +112 -100
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-classification-x-api.d.ts +45 -2
- package/icc-x-api/icc-classification-x-api.js +89 -41
- package/icc-x-api/icc-classification-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.d.ts +57 -19
- package/icc-x-api/icc-contact-x-api.js +149 -154
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-crypto-x-api.d.ts +266 -366
- package/icc-x-api/icc-crypto-x-api.js +416 -1327
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/icc-data-owner-x-api.d.ts +110 -11
- package/icc-x-api/icc-data-owner-x-api.js +188 -14
- package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
- package/icc-x-api/icc-doctemplate-x-api.js +3 -3
- package/icc-x-api/icc-doctemplate-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.d.ts +76 -5
- package/icc-x-api/icc-document-x-api.js +137 -59
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.d.ts +47 -7
- package/icc-x-api/icc-form-x-api.js +85 -86
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-hcparty-x-api.d.ts +1 -1
- package/icc-x-api/icc-hcparty-x-api.js +1 -1
- package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.d.ts +50 -3
- package/icc-x-api/icc-helement-x-api.js +101 -118
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-icure-maintenance-x-api.d.ts +31 -0
- package/icc-x-api/icc-icure-maintenance-x-api.js +124 -0
- package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -0
- package/icc-x-api/icc-invoice-x-api.d.ts +45 -5
- package/icc-x-api/icc-invoice-x-api.js +89 -64
- package/icc-x-api/icc-invoice-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.d.ts +38 -6
- package/icc-x-api/icc-maintenance-task-x-api.js +73 -102
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-message-x-api.d.ts +55 -2
- package/icc-x-api/icc-message-x-api.js +92 -33
- package/icc-x-api/icc-message-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.d.ts +67 -7
- package/icc-x-api/icc-patient-x-api.js +409 -473
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-receipt-x-api.d.ts +49 -5
- package/icc-x-api/icc-receipt-x-api.js +85 -47
- package/icc-x-api/icc-receipt-x-api.js.map +1 -1
- package/icc-x-api/icc-time-table-x-api.d.ts +34 -10
- package/icc-x-api/icc-time-table-x-api.js +61 -18
- package/icc-x-api/icc-time-table-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +30 -1
- package/icc-x-api/index.js +112 -49
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/maintenance/KeyPairUpdateRequest.d.ts +35 -0
- package/icc-x-api/maintenance/KeyPairUpdateRequest.js +54 -0
- package/icc-x-api/maintenance/KeyPairUpdateRequest.js.map +1 -0
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.d.ts +9 -0
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js +23 -0
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js.map +1 -0
- package/icc-x-api/storage/IcureStorageFacade.d.ts +55 -0
- package/icc-x-api/storage/IcureStorageFacade.js +95 -0
- package/icc-x-api/storage/IcureStorageFacade.js.map +1 -0
- package/icc-x-api/storage/StorageEntryKeysFactory.d.ts +31 -0
- package/icc-x-api/storage/StorageEntryKeysFactory.js +3 -0
- package/icc-x-api/storage/StorageEntryKeysFactory.js.map +1 -0
- package/icc-x-api/utils/collection-utils.d.ts +8 -0
- package/icc-x-api/utils/collection-utils.js +26 -0
- package/icc-x-api/utils/collection-utils.js.map +1 -0
- package/icc-x-api/utils/crypto-utils.d.ts +8 -1
- package/icc-x-api/utils/crypto-utils.js +19 -3
- package/icc-x-api/utils/crypto-utils.js.map +1 -1
- package/icc-x-api/utils/graph-utils.d.ts +45 -0
- package/icc-x-api/utils/graph-utils.js +203 -0
- package/icc-x-api/utils/graph-utils.js.map +1 -0
- package/icc-x-api/utils/lru-temporised-async-cache.d.ts +27 -0
- package/icc-x-api/utils/lru-temporised-async-cache.js +120 -0
- package/icc-x-api/utils/lru-temporised-async-cache.js.map +1 -0
- package/package.json +1 -1
|
@@ -31,79 +31,54 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
31
31
|
this.crypto = crypto;
|
|
32
32
|
this.dataOwnerApi = dataOwnerApi;
|
|
33
33
|
}
|
|
34
|
-
newInstance(user, patient, c, confidential = false, delegates = []) {
|
|
35
|
-
const contact = new models.Contact(_.extend({
|
|
36
|
-
id: this.crypto.randomUuid(),
|
|
37
|
-
_type: 'org.taktik.icure.entities.Contact',
|
|
38
|
-
created: new Date().getTime(),
|
|
39
|
-
modified: new Date().getTime(),
|
|
40
|
-
responsible: this.dataOwnerApi.getDataOwnerOf(user),
|
|
41
|
-
author: user.id,
|
|
42
|
-
codes: [],
|
|
43
|
-
tags: [],
|
|
44
|
-
groupId: this.crypto.randomUuid(),
|
|
45
|
-
subContacts: [],
|
|
46
|
-
services: [],
|
|
47
|
-
openingDate: parseInt(moment().format('YYYYMMDDHHmmss')),
|
|
48
|
-
}, c || {}));
|
|
49
|
-
return this.initDelegationsAndEncryptionKeys(user, patient, contact, confidential, delegates);
|
|
50
|
-
}
|
|
51
34
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
35
|
+
* Creates a new instance of contact with initialised encryption metadata (not in the database).
|
|
36
|
+
* @param user the current user.
|
|
37
|
+
* @param patient the patient this contact refers to.
|
|
38
|
+
* @param c initialised data for the contact. Metadata such as id, creation data, etc. will be automatically initialised, but you can specify other
|
|
39
|
+
* kinds of data or overwrite generated metadata with this. You can't specify encryption metadata.
|
|
40
|
+
* @param options optional parameters:
|
|
41
|
+
* - additionalDelegates: delegates which will have access to the entity in addition to the current data owner and delegates from the
|
|
42
|
+
* auto-delegations. Must be an object which associates each data owner id with the access level to give to that data owner. May overlap with
|
|
43
|
+
* auto-delegations, in such case the access level specified here will be used. Currently only WRITE access is supported, but in future also read
|
|
44
|
+
* access will be possible.
|
|
45
|
+
* - preferredSfk: secret id of the patient to use as the secret foreign key to use for the classification. The default value will be a
|
|
46
|
+
* secret id of patient known by the topmost parent in the current data owner hierarchy.
|
|
47
|
+
* - confidential: if true, the entity will be created as confidential. Confidential entities are not shared with auto-delegations, and the default
|
|
48
|
+
* foreign key used is any key that is not shared with any of the data owner parents. By default entities are created as non-confidential.
|
|
49
|
+
* @return a new instance of contact.
|
|
58
50
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}));
|
|
91
|
-
(user.autoDelegations
|
|
92
|
-
? (user.autoDelegations.all || [])
|
|
93
|
-
.concat(user.autoDelegations.medicalInformation || [])
|
|
94
|
-
.concat(user.autoDelegations.anonymousMedicalInformation || [])
|
|
95
|
-
: []).forEach((delegateId) => (promise = promise.then((contact) => this.crypto
|
|
96
|
-
.appendEncryptionKeys(contact, dataOwnerId, delegateId, eks.secretId)
|
|
97
|
-
.then((extraEks) => {
|
|
98
|
-
return _.extend(extraEks.modifiedObject, {
|
|
99
|
-
encryptionKeys: extraEks.encryptionKeys,
|
|
100
|
-
});
|
|
101
|
-
})
|
|
102
|
-
.catch((e) => {
|
|
103
|
-
console.log(e.message);
|
|
104
|
-
return contact;
|
|
105
|
-
}))));
|
|
106
|
-
return promise;
|
|
51
|
+
newInstance(user, patient, c, options = {}) {
|
|
52
|
+
var _a, _b, _c, _d, _e, _f;
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
const contact = new models.Contact(_.extend({
|
|
55
|
+
id: this.crypto.primitives.randomUuid(),
|
|
56
|
+
_type: 'org.taktik.icure.entities.Contact',
|
|
57
|
+
created: new Date().getTime(),
|
|
58
|
+
modified: new Date().getTime(),
|
|
59
|
+
responsible: this.dataOwnerApi.getDataOwnerIdOf(user),
|
|
60
|
+
author: user.id,
|
|
61
|
+
codes: [],
|
|
62
|
+
tags: [],
|
|
63
|
+
groupId: this.crypto.primitives.randomUuid(),
|
|
64
|
+
subContacts: [],
|
|
65
|
+
services: [],
|
|
66
|
+
openingDate: parseInt(moment().format('YYYYMMDDHHmmss')),
|
|
67
|
+
}, c || {}));
|
|
68
|
+
const ownerId = this.dataOwnerApi.getDataOwnerIdOf(user);
|
|
69
|
+
if (ownerId !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
|
|
70
|
+
throw new Error('Can only initialise entities as current data owner.');
|
|
71
|
+
const sfk = (_a = options.preferredSfk) !== null && _a !== void 0 ? _a : (!!options.confidential
|
|
72
|
+
? yield this.crypto.confidential.getConfidentialSecretId(patient)
|
|
73
|
+
: yield this.crypto.confidential.getAnySecretIdSharedWithParents(patient));
|
|
74
|
+
if (!sfk)
|
|
75
|
+
throw new Error(`Couldn't find any sfk of parent patient ${patient.id} for confidential=${!!options.confidential}`);
|
|
76
|
+
const extraDelegations = [
|
|
77
|
+
...Object.keys((_b = options.additionalDelegates) !== null && _b !== void 0 ? _b : {}),
|
|
78
|
+
...(options.confidential ? [] : [...((_d = (_c = user.autoDelegations) === null || _c === void 0 ? void 0 : _c.all) !== null && _d !== void 0 ? _d : []), ...((_f = (_e = user.autoDelegations) === null || _e === void 0 ? void 0 : _e.medicalInformation) !== null && _f !== void 0 ? _f : [])]),
|
|
79
|
+
];
|
|
80
|
+
const initialisationInfo = yield this.crypto.entities.entityWithInitialisedEncryptedMetadata(contact, patient.id, sfk, true, extraDelegations);
|
|
81
|
+
return new models.Contact(initialisationInfo.updatedEntity);
|
|
107
82
|
});
|
|
108
83
|
}
|
|
109
84
|
/**
|
|
@@ -123,33 +98,35 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
123
98
|
* @param usingPost
|
|
124
99
|
*/
|
|
125
100
|
findBy(hcpartyId, patient, usingPost = false) {
|
|
126
|
-
return this
|
|
127
|
-
|
|
128
|
-
.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
101
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
return yield this.crypto.entities.secretIdsForHcpHierarchyOf(patient).then((keysHierarchy) => keysHierarchy && keysHierarchy.length > 0
|
|
103
|
+
? Promise.all(keysHierarchy
|
|
104
|
+
.reduce((acc, level) => {
|
|
105
|
+
return acc.concat([
|
|
106
|
+
{
|
|
107
|
+
hcpartyId: level.ownerId,
|
|
108
|
+
extractedKeys: level.extracted.filter((key) => !acc.some((previousLevel) => previousLevel.extractedKeys.includes(key))),
|
|
109
|
+
},
|
|
110
|
+
]);
|
|
111
|
+
}, [])
|
|
112
|
+
.filter((l) => l.extractedKeys.length > 0)
|
|
113
|
+
.map(({ hcpartyId, extractedKeys }) => usingPost
|
|
114
|
+
? this.findByHCPartyPatientSecretFKeysArray(hcpartyId, _.uniq(extractedKeys))
|
|
115
|
+
: this.findByHCPartyPatientSecretFKeys(hcpartyId, _.uniq(extractedKeys).join(',')))).then((results) => _.uniqBy(_.flatMap(results), (x) => x.id))
|
|
116
|
+
: Promise.resolve([]));
|
|
117
|
+
});
|
|
141
118
|
}
|
|
142
119
|
findByPatientSFKs(hcpartyId, patients) {
|
|
143
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
144
121
|
const perHcpId = {};
|
|
145
122
|
for (const patient of patients) {
|
|
146
123
|
;
|
|
147
|
-
(yield this.crypto.
|
|
124
|
+
(yield this.crypto.entities.secretIdsForHcpHierarchyOf(patient))
|
|
148
125
|
.reduce((acc, level) => {
|
|
149
126
|
return acc.concat([
|
|
150
127
|
{
|
|
151
|
-
hcpartyId: level.
|
|
152
|
-
extractedKeys: level.
|
|
128
|
+
hcpartyId: level.ownerId,
|
|
129
|
+
extractedKeys: level.extracted.filter((key) => !acc.some((previousLevel) => previousLevel.extractedKeys.includes(key))),
|
|
153
130
|
},
|
|
154
131
|
]);
|
|
155
132
|
}, [])
|
|
@@ -218,36 +195,34 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
218
195
|
var _a;
|
|
219
196
|
return super
|
|
220
197
|
.filterServicesBy(undefined, (_a = serviceIds.ids) === null || _a === void 0 ? void 0 : _a.length, new models_1.FilterChainService({ filter: new ServiceByIdsFilter_1.ServiceByIdsFilter({ ids: serviceIds.ids }) }))
|
|
221
|
-
.then((paginatedList) => { var _a; return this.decryptServices(user.healthcarePartyId || user.patientId, (_a = paginatedList.rows) !== null && _a !== void 0 ? _a : []
|
|
198
|
+
.then((paginatedList) => { var _a; return this.decryptServices(user.healthcarePartyId || user.patientId, (_a = paginatedList.rows) !== null && _a !== void 0 ? _a : []); });
|
|
222
199
|
}
|
|
223
200
|
findByHCPartyFormIdWithUser(user, hcPartyId, formId) {
|
|
224
|
-
return super.findByHCPartyFormId(hcPartyId, formId).then((ctcs) => this.decrypt(this.dataOwnerApi.
|
|
201
|
+
return super.findByHCPartyFormId(hcPartyId, formId).then((ctcs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), ctcs));
|
|
225
202
|
}
|
|
226
203
|
findByHCPartyFormIdsWithUser(user, hcPartyId, body) {
|
|
227
|
-
return super.findByHCPartyFormIds(hcPartyId, body).then((ctcs) => this.decrypt(this.dataOwnerApi.
|
|
204
|
+
return super.findByHCPartyFormIds(hcPartyId, body).then((ctcs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), ctcs));
|
|
228
205
|
}
|
|
229
206
|
getContactWithUser(user, contactId) {
|
|
230
207
|
return super
|
|
231
208
|
.getContact(contactId)
|
|
232
|
-
.then((ctc) => this.decrypt(this.dataOwnerApi.
|
|
209
|
+
.then((ctc) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), [ctc]))
|
|
233
210
|
.then((ctcs) => ctcs[0]);
|
|
234
211
|
}
|
|
235
212
|
getContactsWithUser(user, body) {
|
|
236
|
-
return super.getContacts(body).then((ctcs) => this.decrypt(this.dataOwnerApi.
|
|
213
|
+
return super.getContacts(body).then((ctcs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), ctcs));
|
|
237
214
|
}
|
|
238
215
|
modifyContactWithUser(user, body) {
|
|
239
|
-
const _super = Object.create(null, {
|
|
240
|
-
modifyContact: { get: () => super.modifyContact }
|
|
241
|
-
});
|
|
242
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
243
|
-
return body
|
|
244
|
-
? this.encrypt(user, [_.cloneDeep(body)])
|
|
245
|
-
.then((ctcs) => _super.modifyContact.call(this, ctcs[0]))
|
|
246
|
-
.then((ctc) => this.decrypt(this.dataOwnerApi.getDataOwnerOf(user), [ctc]))
|
|
247
|
-
.then((ctcs) => ctcs[0])
|
|
248
|
-
: null;
|
|
217
|
+
return body ? this.modifyAs(this.dataOwnerApi.getDataOwnerIdOf(user), body) : null;
|
|
249
218
|
});
|
|
250
219
|
}
|
|
220
|
+
modifyAs(dataOwner, contact) {
|
|
221
|
+
return this.encryptAs(dataOwner, [_.cloneDeep(contact)])
|
|
222
|
+
.then((ctcs) => super.modifyContact(ctcs[0]))
|
|
223
|
+
.then((ctc) => this.decrypt(dataOwner, [ctc]))
|
|
224
|
+
.then((ctcs) => ctcs[0]);
|
|
225
|
+
}
|
|
251
226
|
modifyContactsWithUser(user, bodies) {
|
|
252
227
|
const _super = Object.create(null, {
|
|
253
228
|
modifyContacts: { get: () => super.modifyContacts }
|
|
@@ -256,7 +231,7 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
256
231
|
return bodies
|
|
257
232
|
? this.encrypt(user, bodies.map((c) => _.cloneDeep(c)))
|
|
258
233
|
.then((ctcs) => _super.modifyContacts.call(this, ctcs))
|
|
259
|
-
.then((ctcs) => this.decrypt(this.dataOwnerApi.
|
|
234
|
+
.then((ctcs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), ctcs))
|
|
260
235
|
: null;
|
|
261
236
|
});
|
|
262
237
|
}
|
|
@@ -268,7 +243,7 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
268
243
|
return body
|
|
269
244
|
? this.encrypt(user, [_.cloneDeep(body)])
|
|
270
245
|
.then((ctcs) => _super.createContact.call(this, ctcs[0]))
|
|
271
|
-
.then((ctc) => this.decrypt(this.dataOwnerApi.
|
|
246
|
+
.then((ctc) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), [ctc]))
|
|
272
247
|
.then((ctcs) => ctcs[0])
|
|
273
248
|
: null;
|
|
274
249
|
});
|
|
@@ -281,7 +256,7 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
281
256
|
return bodies
|
|
282
257
|
? this.encrypt(user, bodies.map((c) => _.cloneDeep(c)))
|
|
283
258
|
.then((ctcs) => _super.createContacts.call(this, ctcs))
|
|
284
|
-
.then((ctcs) => this.decrypt(this.dataOwnerApi.
|
|
259
|
+
.then((ctcs) => this.decrypt(this.dataOwnerApi.getDataOwnerIdOf(user), ctcs))
|
|
285
260
|
: null;
|
|
286
261
|
});
|
|
287
262
|
}
|
|
@@ -309,99 +284,90 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
309
284
|
}))));
|
|
310
285
|
}
|
|
311
286
|
else {
|
|
312
|
-
svc.encryptedSelf = (0, binary_utils_1.b2a)((0, binary_utils_1.ua2string)(yield this.crypto.AES.encrypt(key, (0, binary_utils_1.utf8_2ua)(JSON.stringify({ content: svc.content })), rawKey)));
|
|
287
|
+
svc.encryptedSelf = (0, binary_utils_1.b2a)((0, binary_utils_1.ua2string)(yield this.crypto.primitives.AES.encrypt(key, (0, binary_utils_1.utf8_2ua)(JSON.stringify({ content: svc.content })), rawKey)));
|
|
313
288
|
delete svc.content;
|
|
314
289
|
}
|
|
315
290
|
return svc;
|
|
316
291
|
})));
|
|
317
292
|
}
|
|
318
293
|
encrypt(user, ctcs) {
|
|
319
|
-
|
|
294
|
+
return this.encryptAs(this.dataOwnerApi.getDataOwnerIdOf(user), ctcs);
|
|
295
|
+
}
|
|
296
|
+
encryptAs(hcpartyId, ctcs) {
|
|
320
297
|
const bypassEncryption = false; //Used for debug
|
|
321
298
|
return Promise.all(ctcs.map((ctc) => __awaiter(this, void 0, void 0, function* () {
|
|
322
299
|
const initialisedCtc = bypassEncryption //Prevent encryption for test ctc
|
|
323
300
|
? ctc
|
|
324
|
-
: yield
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
initialisedCtc.services = yield this.encryptServices(key, rawKey, ctc.services || []);
|
|
329
|
-
initialisedCtc.encryptedSelf = (0, binary_utils_1.b2a)((0, binary_utils_1.ua2string)(yield this.crypto.AES.encrypt(key, (0, binary_utils_1.utf8_2ua)(JSON.stringify({ descr: ctc.descr })), rawKey)));
|
|
301
|
+
: yield this.crypto.entities.ensureEncryptionKeysInitialised(ctc);
|
|
302
|
+
const encryptionKey = yield this.crypto.entities.importFirstValidKey(yield this.crypto.entities.encryptionKeysOf(ctc, hcpartyId), ctc.id);
|
|
303
|
+
initialisedCtc.services = yield this.encryptServices(encryptionKey.key, encryptionKey.raw, ctc.services || []);
|
|
304
|
+
initialisedCtc.encryptedSelf = (0, binary_utils_1.b2a)((0, binary_utils_1.ua2string)(yield this.crypto.primitives.AES.encrypt(encryptionKey.key, (0, binary_utils_1.utf8_2ua)(JSON.stringify({ descr: ctc.descr })), encryptionKey.raw)));
|
|
330
305
|
delete initialisedCtc.descr;
|
|
331
306
|
return initialisedCtc;
|
|
332
307
|
})));
|
|
333
308
|
}
|
|
334
309
|
decrypt(hcpartyId, ctcs) {
|
|
335
310
|
return Promise.all(ctcs.map((ctc) => __awaiter(this, void 0, void 0, function* () {
|
|
336
|
-
const
|
|
337
|
-
if (!
|
|
311
|
+
const keys = yield this.crypto.entities.importAllValidKeys(yield this.crypto.entities.encryptionKeysOf(ctc, hcpartyId));
|
|
312
|
+
if (!keys || !keys.length) {
|
|
338
313
|
console.log('Cannot decrypt contact', ctc.id);
|
|
339
314
|
return ctc;
|
|
340
315
|
}
|
|
341
|
-
|
|
342
|
-
const key = yield this.crypto.AES.importKey('raw', (0, binary_utils_1.hex2ua)(rawKey));
|
|
343
|
-
ctc.services = yield this.decryptServices(hcpartyId, ctc.services || [], key, rawKey);
|
|
316
|
+
ctc.services = yield this.decryptServices(hcpartyId, ctc.services || [], keys);
|
|
344
317
|
if (ctc.encryptedSelf) {
|
|
345
318
|
try {
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
jsonContent = dec && (0, binary_utils_1.ua2utf8)(dec);
|
|
350
|
-
jsonContent && _.assign(ctc, JSON.parse(jsonContent));
|
|
319
|
+
const json = yield this.crypto.entities.tryDecryptJson(keys, (0, binary_utils_1.string2ua)((0, binary_utils_1.a2b)(ctc.encryptedSelf)), false);
|
|
320
|
+
if (json) {
|
|
321
|
+
_.assign(ctc, json);
|
|
351
322
|
}
|
|
352
|
-
|
|
353
|
-
console.log('Cannot
|
|
323
|
+
else {
|
|
324
|
+
console.log('Cannot decrypt ctc: no valid key could produce valid json', ctc.id);
|
|
354
325
|
}
|
|
355
326
|
}
|
|
356
|
-
catch (
|
|
357
|
-
console.log('
|
|
327
|
+
catch (e) {
|
|
328
|
+
console.log('Failed to decrypt ctc', ctc.id, e);
|
|
358
329
|
}
|
|
359
330
|
}
|
|
360
331
|
return ctc;
|
|
361
332
|
})));
|
|
362
333
|
}
|
|
363
|
-
decryptServices(hcpartyId, svcs,
|
|
334
|
+
decryptServices(hcpartyId, svcs, keys) {
|
|
364
335
|
return Promise.all(svcs.map((svc) => __awaiter(this, void 0, void 0, function* () {
|
|
365
|
-
if (!
|
|
366
|
-
|
|
367
|
-
key = yield this.crypto.AES.importKey('raw', (0, binary_utils_1.hex2ua)(sfks[0].replace(/-/g, '')));
|
|
336
|
+
if (!keys) {
|
|
337
|
+
keys = yield this.crypto.entities.importAllValidKeys(yield this.crypto.entities.encryptionKeysOf(svc, hcpartyId));
|
|
368
338
|
}
|
|
369
339
|
if (svc.encryptedContent) {
|
|
370
340
|
try {
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
jsonContent = (0, binary_utils_1.ua2utf8)((0, utils_1.truncateTrailingNulls)(new Uint8Array(dec)));
|
|
375
|
-
Object.assign(svc, { content: JSON.parse(jsonContent) });
|
|
341
|
+
const json = yield this.crypto.entities.tryDecryptJson(keys, (0, binary_utils_1.string2ua)((0, binary_utils_1.a2b)(svc.encryptedContent)), true);
|
|
342
|
+
if (json) {
|
|
343
|
+
Object.assign(svc, { content: json });
|
|
376
344
|
}
|
|
377
|
-
|
|
378
|
-
console.log('Cannot
|
|
345
|
+
else {
|
|
346
|
+
console.log('Cannot decrypt service: no valid key could produce valid json', svc.id);
|
|
379
347
|
}
|
|
380
348
|
}
|
|
381
|
-
catch (
|
|
382
|
-
console.log('Cannot decrypt service', svc.id);
|
|
349
|
+
catch (e) {
|
|
350
|
+
console.log('Cannot decrypt service', svc.id, e);
|
|
383
351
|
}
|
|
384
352
|
}
|
|
385
353
|
else if (svc.encryptedSelf) {
|
|
386
354
|
try {
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
jsonContent = (0, binary_utils_1.ua2utf8)((0, utils_1.truncateTrailingNulls)(new Uint8Array(dec)));
|
|
391
|
-
Object.assign(svc, JSON.parse(jsonContent));
|
|
355
|
+
const json = yield this.crypto.entities.tryDecryptJson(keys, (0, binary_utils_1.string2ua)((0, binary_utils_1.a2b)(svc.encryptedSelf)), true);
|
|
356
|
+
if (json) {
|
|
357
|
+
Object.assign(svc, json);
|
|
392
358
|
}
|
|
393
|
-
|
|
394
|
-
console.log('Cannot
|
|
359
|
+
else {
|
|
360
|
+
console.log('Cannot decrypt service: no valid key could produce valid json', svc.id);
|
|
395
361
|
}
|
|
396
362
|
}
|
|
397
|
-
catch (
|
|
398
|
-
console.log('Cannot decrypt service', svc.id);
|
|
363
|
+
catch (e) {
|
|
364
|
+
console.log('Cannot decrypt service', svc.id, e);
|
|
399
365
|
}
|
|
400
366
|
}
|
|
401
367
|
else {
|
|
402
368
|
svc.content = _.fromPairs(yield Promise.all(_.toPairs(svc.content).map((p) => __awaiter(this, void 0, void 0, function* () {
|
|
403
369
|
if (p[1].compoundValue) {
|
|
404
|
-
p[1].compoundValue = yield this.decryptServices(hcpartyId, p[1].compoundValue,
|
|
370
|
+
p[1].compoundValue = yield this.decryptServices(hcpartyId, p[1].compoundValue, keys);
|
|
405
371
|
}
|
|
406
372
|
return p;
|
|
407
373
|
}))));
|
|
@@ -509,7 +475,7 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
509
475
|
const existing = ctc.services.find((s) => s.id === svc.id);
|
|
510
476
|
const promoted = _.extend(_.extend(existing || {}, svc), {
|
|
511
477
|
author: user.id,
|
|
512
|
-
responsible: this.dataOwnerApi.
|
|
478
|
+
responsible: this.dataOwnerApi.getDataOwnerIdOf(user),
|
|
513
479
|
modified: new Date().getTime(),
|
|
514
480
|
});
|
|
515
481
|
if (!existing) {
|
|
@@ -597,11 +563,11 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
597
563
|
service() {
|
|
598
564
|
return {
|
|
599
565
|
newInstance: (user, s) => _.extend({
|
|
600
|
-
id: this.crypto.randomUuid(),
|
|
566
|
+
id: this.crypto.primitives.randomUuid(),
|
|
601
567
|
_type: 'org.taktik.icure.entities.embed.Service',
|
|
602
568
|
created: new Date().getTime(),
|
|
603
569
|
modified: new Date().getTime(),
|
|
604
|
-
responsible: this.dataOwnerApi.
|
|
570
|
+
responsible: this.dataOwnerApi.getDataOwnerIdOf(user),
|
|
605
571
|
author: user.id,
|
|
606
572
|
codes: [],
|
|
607
573
|
tags: [],
|
|
@@ -764,6 +730,35 @@ class IccContactXApi extends icc_api_1.IccContactApi {
|
|
|
764
730
|
};
|
|
765
731
|
return myself;
|
|
766
732
|
}
|
|
733
|
+
/**
|
|
734
|
+
* @param contact a contact
|
|
735
|
+
* @return the id of the patient that the contact refers to, retrieved from the encrypted metadata. Normally there should only be one element
|
|
736
|
+
* in the returned array, but in case of entity merges there could be multiple values.
|
|
737
|
+
*/
|
|
738
|
+
decryptPatientIdOf(contact) {
|
|
739
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
740
|
+
return this.crypto.entities.owningEntityIdsOf(contact, undefined);
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Share an existing contact with other data owners, allowing them to access the non-encrypted data of the contact and optionally also
|
|
745
|
+
* the encrypted content.
|
|
746
|
+
* @param delegateId the id of the data owner which will be granted access to the contact.
|
|
747
|
+
* @param contact the contact to share.
|
|
748
|
+
* @param options optional parameters to customize the sharing behaviour:
|
|
749
|
+
* - shareEncryptionKey: specifies if the encryption key of the access log should be shared with the delegate, giving access to all encrypted
|
|
750
|
+
* content of the entity, excluding other encrypted metadata (defaults to {@link ShareMetadataBehaviour.IF_AVAILABLE}). Note that by default a
|
|
751
|
+
* contact does not have encrypted content.
|
|
752
|
+
* - sharePatientId: specifies if the id of the patient that this contact refers to should be shared with the delegate (defaults to
|
|
753
|
+
* {@link ShareMetadataBehaviour.IF_AVAILABLE}).
|
|
754
|
+
* @return a promise which will contain the updated contact.
|
|
755
|
+
*/
|
|
756
|
+
shareWith(delegateId, contact, options = {}) {
|
|
757
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
758
|
+
const self = yield this.dataOwnerApi.getCurrentDataOwnerId();
|
|
759
|
+
return yield this.modifyAs(self, yield this.crypto.entities.entityWithAutoExtendedEncryptedMetadata(contact, delegateId, undefined, options.shareEncryptionKey, options.sharePatientId));
|
|
760
|
+
});
|
|
761
|
+
}
|
|
767
762
|
}
|
|
768
763
|
exports.IccContactXApi = IccContactXApi;
|
|
769
764
|
//# sourceMappingURL=icc-contact-x-api.js.map
|