@icure/api 5.0.24 → 5.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/icc-x-api/filters/HealthcarePartyByTagCodeFilter.d.ts +21 -0
- package/icc-x-api/filters/HealthcarePartyByTagCodeFilter.js +24 -0
- package/icc-x-api/filters/HealthcarePartyByTagCodeFilter.js.map +1 -0
- package/icc-x-api/filters/PatientByHcPartyGenderEducationProfession.js.map +1 -1
- package/icc-x-api/filters/filters.d.ts +1 -0
- package/icc-x-api/filters/filters.js +1 -0
- package/icc-x-api/filters/filters.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +1 -1
- package/icc-x-api/icc-accesslog-x-api.js +1 -1
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.d.ts +1 -1
- package/icc-x-api/icc-calendar-item-x-api.js +1 -1
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.js +1 -1
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-crypto-x-api.d.ts +25 -1
- package/icc-x-api/icc-crypto-x-api.js +202 -83
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.js +1 -1
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.js +1 -1
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.js +1 -1
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-invoice-x-api.js +1 -1
- package/icc-x-api/icc-invoice-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.js +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.js +1 -1
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-receipt-x-api.js +1 -1
- package/icc-x-api/icc-receipt-x-api.js.map +1 -1
- package/icc-x-api/icc-user-x-api.js.map +1 -1
- package/icc-x-api/index.js +1 -1
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/utils/functional-util.d.ts +1 -0
- package/icc-x-api/utils/functional-util.js +19 -1
- package/icc-x-api/utils/functional-util.js.map +1 -1
- package/package.json +1 -1
|
@@ -415,8 +415,9 @@ class IccCryptoXApi {
|
|
|
415
415
|
const { owner: modifiedOwner, aesExchangeKeys } = yield this.getOrCreateHcPartyKeys(owner, ownerId);
|
|
416
416
|
const importedAESHcPartyKey = yield this.decryptAnyAesExchangeKeyForOwner(aesExchangeKeys, ownerId, ownerId, ownerId, publicKeys);
|
|
417
417
|
const encryptedDelegation = yield this._AES.encrypt(importedAESHcPartyKey.key, (0, binary_utils_1.string2ua)(createdObject.id + ':' + secretId).buffer, importedAESHcPartyKey.rawKey);
|
|
418
|
-
const encryptedSecretForeignKey = parentObject
|
|
419
|
-
this._AES.encrypt(importedAESHcPartyKey.key, (0, binary_utils_1.string2ua)(createdObject.id + ':' + parentObject.id).buffer, importedAESHcPartyKey.rawKey)
|
|
418
|
+
const encryptedSecretForeignKey = parentObject
|
|
419
|
+
? yield this._AES.encrypt(importedAESHcPartyKey.key, (0, binary_utils_1.string2ua)(createdObject.id + ':' + parentObject.id).buffer, importedAESHcPartyKey.rawKey)
|
|
420
|
+
: undefined;
|
|
420
421
|
return {
|
|
421
422
|
owner: modifiedOwner,
|
|
422
423
|
delegations: _.fromPairs([
|
|
@@ -431,8 +432,8 @@ class IccCryptoXApi {
|
|
|
431
432
|
],
|
|
432
433
|
],
|
|
433
434
|
]),
|
|
434
|
-
cryptedForeignKeys: (encryptedSecretForeignKey
|
|
435
|
-
_.fromPairs([
|
|
435
|
+
cryptedForeignKeys: (encryptedSecretForeignKey
|
|
436
|
+
? _.fromPairs([
|
|
436
437
|
[
|
|
437
438
|
ownerId,
|
|
438
439
|
[
|
|
@@ -443,8 +444,8 @@ class IccCryptoXApi {
|
|
|
443
444
|
},
|
|
444
445
|
],
|
|
445
446
|
],
|
|
446
|
-
])
|
|
447
|
-
{},
|
|
447
|
+
])
|
|
448
|
+
: _) || {},
|
|
448
449
|
secretForeignKeys: (secretForeignKeyOfParent && [secretForeignKeyOfParent]) || [],
|
|
449
450
|
secretId: secretId,
|
|
450
451
|
};
|
|
@@ -670,50 +671,46 @@ class IccCryptoXApi {
|
|
|
670
671
|
return __awaiter(this, arguments, void 0, function* () {
|
|
671
672
|
this.throwDetailedExceptionForInvalidParameter('modifiedObject.id', modifiedObject.id, 'appendEncryptionKeys', arguments); //modifiedObject should never be null
|
|
672
673
|
this.throwDetailedExceptionForInvalidParameter('secretEncryptionKeyOfObject', secretEncryptionKeyOfObject, 'appendEncryptionKeys', arguments);
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
d: {
|
|
703
|
-
owner: ownerId,
|
|
704
|
-
delegatedTo: delegateId,
|
|
705
|
-
key: (0, binary_utils_1.ua2hex)(encryptedEncryptionKey),
|
|
706
|
-
},
|
|
707
|
-
k: modifiedObject.id + ':' + secretEncryptionKeyOfObject,
|
|
674
|
+
const owner = (yield this.getDataOwner(ownerId)).dataOwner;
|
|
675
|
+
const publicKeys = yield this.getPublicKeys();
|
|
676
|
+
const { owner: modifiedOwner, aesExchangeKeys } = yield this.getOrCreateHcPartyKeys(owner, delegateId);
|
|
677
|
+
modifiedObject = (modifiedObject === null || modifiedObject === void 0 ? void 0 : modifiedObject.id) === owner.id ? modifiedOwner : modifiedObject;
|
|
678
|
+
const importedAESHcPartyKey = yield this.decryptAnyAesExchangeKeyForOwner(aesExchangeKeys, ownerId, ownerId, delegateId, publicKeys);
|
|
679
|
+
const previousDecryptedEncryptionKeys = yield Promise.all(((modifiedObject.encryptionKeys || {})[delegateId] || []).map((d) => (d.key &&
|
|
680
|
+
d.owner === ownerId &&
|
|
681
|
+
this._AES.decrypt(importedAESHcPartyKey.key, (0, binary_utils_1.hex2ua)(d.key), importedAESHcPartyKey.rawKey).catch(() => {
|
|
682
|
+
console.log(`Cannot decrypt encryption key from ${d.owner} to ${d.delegatedTo} for object with id ${modifiedObject.id}:`, modifiedObject);
|
|
683
|
+
return Promise.resolve();
|
|
684
|
+
})) ||
|
|
685
|
+
Promise.resolve()));
|
|
686
|
+
const encryptedEncryptionKey = yield this._AES.encrypt(importedAESHcPartyKey.key, (0, binary_utils_1.string2ua)(modifiedObject.id + ':' + secretEncryptionKeyOfObject));
|
|
687
|
+
//try to limit the extent of the modifications to the delegations by preserving the redundant encryption keys already present and removing duplicates
|
|
688
|
+
//For delegate delegateId, we create:
|
|
689
|
+
// 1. an array of objects { d : {owner,delegatedTo,encrypted(key)}} with one object for the existing encryption keys and the new key concatenated
|
|
690
|
+
// 2. an array of objects { k : decrypted(key)} with one object for the existing delegations and the new key concatenated
|
|
691
|
+
// We merge them to get one array of objects: { d: {owner,delegatedTo,encrypted(key)}, k: decrypted(key)}
|
|
692
|
+
const encryptionKeysCryptedDecrypted = _.merge(((modifiedObject.encryptionKeys || {})[delegateId] || []).map((d) => ({
|
|
693
|
+
d,
|
|
694
|
+
})), (previousDecryptedEncryptionKeys || []).map((dd) => (dd ? (0, binary_utils_1.ua2string)(dd) : null)).map((k) => ({ k })))
|
|
695
|
+
.filter(({ d, k }) => !!k || d.owner !== ownerId) //Only keep the ones created by us that can still be decrypted
|
|
696
|
+
.map(({ d, k }) => ({ d, k: k || this.randomUuid() }))
|
|
697
|
+
.concat([
|
|
698
|
+
{
|
|
699
|
+
d: {
|
|
700
|
+
owner: ownerId,
|
|
701
|
+
delegatedTo: delegateId,
|
|
702
|
+
key: (0, binary_utils_1.ua2hex)(encryptedEncryptionKey),
|
|
708
703
|
},
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
704
|
+
k: modifiedObject.id + ':' + secretEncryptionKeyOfObject,
|
|
705
|
+
},
|
|
706
|
+
]);
|
|
707
|
+
const allEncryptionKeys = _.cloneDeep(modifiedObject.encryptionKeys || {});
|
|
708
|
+
allEncryptionKeys[delegateId] = _.uniqBy(encryptionKeysCryptedDecrypted, (x) => x.k).map((x) => x.d);
|
|
709
|
+
return {
|
|
710
|
+
modifiedObject: modifiedObject,
|
|
711
|
+
encryptionKeys: allEncryptionKeys,
|
|
712
|
+
secretId: secretEncryptionKeyOfObject,
|
|
713
|
+
};
|
|
717
714
|
});
|
|
718
715
|
}
|
|
719
716
|
/**
|
|
@@ -731,25 +728,18 @@ class IccCryptoXApi {
|
|
|
731
728
|
addDelegationsAndEncryptionKeys(
|
|
732
729
|
//TODO: suggested name: updateChildGenericDelegationsFromDelegatorToDelegate
|
|
733
730
|
parent, child, ownerId, delegateId, secretDelegationKey, secretEncryptionKey) {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
}))
|
|
747
|
-
: Promise.resolve({
|
|
748
|
-
extendedSPKsAndCFKs: extendedChildObjectSPKsAndCFKs,
|
|
749
|
-
extendedEKs: { encryptionKeys: {} },
|
|
750
|
-
}))
|
|
751
|
-
.then(({ extendedSPKsAndCFKs: extendedChildObjectSPKsAndCFKs, extendedEKs: extendedChildObjectEKs }) => {
|
|
752
|
-
return _.assign(extendedChildObjectSPKsAndCFKs.modifiedObject, {
|
|
731
|
+
return __awaiter(this, arguments, void 0, function* () {
|
|
732
|
+
if (parent)
|
|
733
|
+
this.throwDetailedExceptionForInvalidParameter('parent.id', parent.id, 'addDelegationsAndEncryptionKeys', arguments);
|
|
734
|
+
this.throwDetailedExceptionForInvalidParameter('child.id', child.id, 'addDelegationsAndEncryptionKeys', arguments);
|
|
735
|
+
const extendedChildObjectSPKsAndCFKs = secretDelegationKey
|
|
736
|
+
? yield this.extendedDelegationsAndCryptedForeignKeys(child, parent, ownerId, delegateId, secretDelegationKey)
|
|
737
|
+
: { modifiedObject: child, delegations: {}, cryptedForeignKeys: {}, secretId: null };
|
|
738
|
+
const extendedChildObjectEKs = secretEncryptionKey
|
|
739
|
+
? yield this.appendEncryptionKeys(extendedChildObjectSPKsAndCFKs.modifiedObject, ownerId, delegateId, secretEncryptionKey)
|
|
740
|
+
: { encryptionKeys: {}, modifiedObject: extendedChildObjectSPKsAndCFKs.modifiedObject };
|
|
741
|
+
const latestObject = extendedChildObjectEKs.modifiedObject;
|
|
742
|
+
return _.assign(latestObject, {
|
|
753
743
|
// Conservative version ... We might want to be more aggressive with the deduplication of keys
|
|
754
744
|
// For each delegate, we are going to concatenate to the src (the new delegations), the object in dest (the current delegations)
|
|
755
745
|
// for which we do not find an equivalent delegation (same delegator, same delegate)
|
|
@@ -890,7 +880,14 @@ class IccCryptoXApi {
|
|
|
890
880
|
});
|
|
891
881
|
return this.decryptKeyInDelegationLikes(delegations[dataOwnerId], collatedAesKeysFromDelegatorToHcpartyId, objectId);
|
|
892
882
|
})
|
|
893
|
-
: Promise.resolve([]))
|
|
883
|
+
: Promise.resolve([]))
|
|
884
|
+
.then((extractedKeys) => __awaiter(this, void 0, void 0, function* () {
|
|
885
|
+
if (extractedKeys.length == 0) {
|
|
886
|
+
return yield this._extractDelegationsKeysUsingDataOwnerDelegateAesExchangeKeys(hcp, delegations, objectId);
|
|
887
|
+
}
|
|
888
|
+
return extractedKeys;
|
|
889
|
+
}))
|
|
890
|
+
.then((extractedKeys) => __awaiter(this, void 0, void 0, function* () {
|
|
894
891
|
var _a;
|
|
895
892
|
const parentExtractedKeys = hcp.parentId
|
|
896
893
|
? yield this.extractKeysFromDelegationsForHcpHierarchy(hcp.parentId, objectId, delegations)
|
|
@@ -902,6 +899,56 @@ class IccCryptoXApi {
|
|
|
902
899
|
throw e;
|
|
903
900
|
});
|
|
904
901
|
}
|
|
902
|
+
/**
|
|
903
|
+
* This method covers the use case when a DataOwner found back access to its data, and needs to use the delegations of its delegates instead
|
|
904
|
+
* of its own ones
|
|
905
|
+
*
|
|
906
|
+
* @param dataOwner The current data owner from whom we want to decrypt the aesExchangeKeys
|
|
907
|
+
* @param delegations The object delegations to decrypt
|
|
908
|
+
* @param objectId The object to decrypt id
|
|
909
|
+
* @private
|
|
910
|
+
*/
|
|
911
|
+
_extractDelegationsKeysUsingDataOwnerDelegateAesExchangeKeys(dataOwner, delegations, objectId) {
|
|
912
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
913
|
+
// Find other keys through aesExchangeKeys
|
|
914
|
+
const dataOwnerPubKeys = yield this.getPublicKeys();
|
|
915
|
+
const keysToDecrypt = (0, utils_1.fold)(Object.entries(dataOwner.aesExchangeKeys), {}, (acc, [pub, aesForPub]) => {
|
|
916
|
+
Object.entries(aesForPub).forEach(([delegateId, aesKeys]) => {
|
|
917
|
+
if (delegateId != dataOwner.id) {
|
|
918
|
+
const aesAcc = {};
|
|
919
|
+
Object.entries(aesKeys)
|
|
920
|
+
.filter(([encrPubKey]) => dataOwnerPubKeys.some((pubKey) => pubKey.slice(-32) == encrPubKey))
|
|
921
|
+
.forEach(([pubKeyFingerprint, aesEncr]) => {
|
|
922
|
+
aesAcc[pubKeyFingerprint] = aesEncr;
|
|
923
|
+
});
|
|
924
|
+
if (acc[delegateId] == undefined) {
|
|
925
|
+
acc[delegateId] = {};
|
|
926
|
+
}
|
|
927
|
+
acc[delegateId][pub] = aesAcc;
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
return acc;
|
|
931
|
+
});
|
|
932
|
+
const decryptedAndImportedAesHcPartyKeys = yield (0, utils_1.foldAsync)(Object.entries(keysToDecrypt), [], (delKeysAcc, [delegateId, keysForDelegate]) => __awaiter(this, void 0, void 0, function* () {
|
|
933
|
+
try {
|
|
934
|
+
delKeysAcc.push(yield this.decryptAnyAesExchangeKeyForOwner(keysForDelegate, dataOwner.id, dataOwner.id, delegateId, dataOwnerPubKeys));
|
|
935
|
+
}
|
|
936
|
+
catch (e) {
|
|
937
|
+
console.log(`Could not decrypt aesExchangeKeys for delegate ${delegateId}`);
|
|
938
|
+
}
|
|
939
|
+
return delKeysAcc;
|
|
940
|
+
}));
|
|
941
|
+
const collatedAesKeysFromDelegatorToHcpartyId = decryptedAndImportedAesHcPartyKeys.reduce((map, k) => { var _a; return (Object.assign(Object.assign({}, map), { [k.delegatorId]: ((_a = map[k.delegatorId]) !== null && _a !== void 0 ? _a : []).concat([k]) })); }, {});
|
|
942
|
+
const delegateIdsWithNewExtractedAesKeys = Object.keys(keysToDecrypt);
|
|
943
|
+
const delegationsToDecrypt = (0, utils_1.fold)(Object.entries(delegations), [], (acc, [delegateId, del]) => {
|
|
944
|
+
if (delegateIdsWithNewExtractedAesKeys.find((id) => id == delegateId) != undefined) {
|
|
945
|
+
acc.push(...delegations[delegateId]);
|
|
946
|
+
}
|
|
947
|
+
return acc;
|
|
948
|
+
});
|
|
949
|
+
return this.decryptKeyInDelegationLikes(delegationsToDecrypt, collatedAesKeysFromDelegatorToHcpartyId, objectId);
|
|
950
|
+
});
|
|
951
|
+
}
|
|
905
952
|
/**
|
|
906
953
|
* Gets an array of generic secret IDs decrypted from a list of generic delegations (SPKs, CFKs, EKs) `delegationsArray`
|
|
907
954
|
* If a particular generic delegation thows an exception when decrypted, the return value for it's secret ID will be 'false' and a message is logged to console
|
|
@@ -997,7 +1044,7 @@ class IccCryptoXApi {
|
|
|
997
1044
|
}
|
|
998
1045
|
const publicKey = this.getPublicKeyFromPrivateKey(privateKey, dataOwner);
|
|
999
1046
|
const keyPair = yield this._RSA.importKeyPair('jwk', privateKey, 'jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(publicKey)));
|
|
1000
|
-
this.rsaKeyPairs[
|
|
1047
|
+
this.rsaKeyPairs[publicKey.slice(-32)] = keyPair;
|
|
1001
1048
|
const exportedKeyPair = yield this._RSA.exportKeys(keyPair, 'jwk', 'jwk');
|
|
1002
1049
|
return this.storeKeyPair(`${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
|
|
1003
1050
|
});
|
|
@@ -1217,6 +1264,66 @@ class IccCryptoXApi {
|
|
|
1217
1264
|
}
|
|
1218
1265
|
});
|
|
1219
1266
|
}
|
|
1267
|
+
/**
|
|
1268
|
+
* When a user lost his keys, people to whom he shared information may call this method to give access back to him, re-encrypting their common
|
|
1269
|
+
* AES key using the new user public key.
|
|
1270
|
+
*
|
|
1271
|
+
* @param delegateUser Delegate Data Owner User, in charge of giving access back to the person who previously gave him some access
|
|
1272
|
+
* @param ownerId Id of the data owner to which we would like to give access back
|
|
1273
|
+
* @param ownerNewPublicKey New Data Owner Public Key we want to use to re-encrypt previously created AES key
|
|
1274
|
+
*
|
|
1275
|
+
* @return The DataOwner, updated by the delegateUser to add the new encrypted AES Key using the new provided public key
|
|
1276
|
+
*/
|
|
1277
|
+
giveAccessBackTo(delegateUser, ownerId, ownerNewPublicKey) {
|
|
1278
|
+
var _a, _b, _c, _d;
|
|
1279
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1280
|
+
const delegateId = (_b = (_a = delegateUser.healthcarePartyId) !== null && _a !== void 0 ? _a : delegateUser.patientId) !== null && _b !== void 0 ? _b : delegateUser.deviceId;
|
|
1281
|
+
if (!delegateId) {
|
|
1282
|
+
throw new Error(`DelegateUser ${delegateUser.id} must be a data Owner`);
|
|
1283
|
+
}
|
|
1284
|
+
const delegatePublicKeys = yield this.getPublicKeys();
|
|
1285
|
+
const newPubKeyCryptoKey = yield this._RSA.importKey('jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(ownerNewPublicKey)), ['encrypt']);
|
|
1286
|
+
const dataOwnerToUpdate = yield this.getDataOwner(ownerId);
|
|
1287
|
+
const newAesExchangeKeys = yield (0, utils_1.foldAsync)(Object.entries((_c = dataOwnerToUpdate.dataOwner.aesExchangeKeys) !== null && _c !== void 0 ? _c : {}), (_d = dataOwnerToUpdate.dataOwner.aesExchangeKeys) !== null && _d !== void 0 ? _d : {}, (pubAcc, [pubKey, newAesExcKeys]) => __awaiter(this, void 0, void 0, function* () {
|
|
1288
|
+
var _e;
|
|
1289
|
+
const existingKeys = (_e = pubAcc[pubKey]) !== null && _e !== void 0 ? _e : {};
|
|
1290
|
+
pubAcc[pubKey] = yield (0, utils_1.foldAsync)(Object.entries(newAesExcKeys), existingKeys, (delAcc, [delId, delKeys]) => __awaiter(this, void 0, void 0, function* () {
|
|
1291
|
+
if (delId == delegateId && pubKey != ownerNewPublicKey) {
|
|
1292
|
+
// Add the AES Key encrypted with the new public key in the aesExchangeKeys
|
|
1293
|
+
try {
|
|
1294
|
+
// First, we decrypt it using the delegate RSA Public Key
|
|
1295
|
+
const encrAesKeyInfo = yield this.decryptHcPartyKey(delegateId, dataOwnerToUpdate.dataOwner.id, delegateId, pubKey, delKeys, delegatePublicKeys).then((delegatorAndKeys) => __awaiter(this, void 0, void 0, function* () {
|
|
1296
|
+
// Then, we encrypt it using the owner new RSA Public Key (provided in argument)
|
|
1297
|
+
return yield this.encryptAesKeyOnlyForProvidedKeys(delegatorAndKeys === null || delegatorAndKeys === void 0 ? void 0 : delegatorAndKeys.rawKey, dataOwnerToUpdate, [newPubKeyCryptoKey])
|
|
1298
|
+
.then((encrAes) => Object.values(encrAes)[0])
|
|
1299
|
+
.then((encrAesInfo) => {
|
|
1300
|
+
return { pubKeyUsedToEncryptAes: Object.keys(encrAesInfo)[0], encryptedAes: Object.values(encrAesInfo)[0] };
|
|
1301
|
+
});
|
|
1302
|
+
}));
|
|
1303
|
+
delKeys[encrAesKeyInfo.pubKeyUsedToEncryptAes] = encrAesKeyInfo.encryptedAes;
|
|
1304
|
+
}
|
|
1305
|
+
catch (e) {
|
|
1306
|
+
console.log(`${delegateId} could not re-encrypt AES Key of ${dataOwnerToUpdate.dataOwner.id}`);
|
|
1307
|
+
}
|
|
1308
|
+
finally {
|
|
1309
|
+
delAcc[delId] = delKeys;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
else {
|
|
1313
|
+
// Otherwise, we don't transform the aesExchangeKeys for this delegate
|
|
1314
|
+
delAcc[delId] = delKeys;
|
|
1315
|
+
}
|
|
1316
|
+
return delAcc;
|
|
1317
|
+
}));
|
|
1318
|
+
return pubAcc;
|
|
1319
|
+
}));
|
|
1320
|
+
// After adding the potential new aesExchangeKeys, we save the updated data owner
|
|
1321
|
+
return this._saveDataOwner({
|
|
1322
|
+
type: dataOwnerToUpdate.type,
|
|
1323
|
+
dataOwner: Object.assign(Object.assign({}, dataOwnerToUpdate.dataOwner), { aesExchangeKeys: newAesExchangeKeys }),
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1220
1327
|
addNewKeyPairForOwnerId(maintenanceTasksApi, user, ownerId, generateTransferKey = true) {
|
|
1221
1328
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1222
1329
|
return this.addNewKeyPairForOwner(maintenanceTasksApi, user, yield this.getDataOwner(ownerId), generateTransferKey);
|
|
@@ -1234,7 +1341,22 @@ class IccCryptoXApi {
|
|
|
1234
1341
|
}).then((dataOwnerWithUpdatedAesKeys) => generateTransferKey
|
|
1235
1342
|
? this.createOrUpdateTransferKeysFor(dataOwnerWithUpdatedAesKeys, gen, { pubKey: publicKey, privKey: privateKey })
|
|
1236
1343
|
: dataOwnerWithUpdatedAesKeys);
|
|
1237
|
-
const modifiedDataOwnerAndType = ownerType
|
|
1344
|
+
const modifiedDataOwnerAndType = yield this._saveDataOwner({ type: ownerType, dataOwner: ownerToUpdate });
|
|
1345
|
+
const sentMaintenanceTasks = yield this.sendMaintenanceTasks(maintenanceTasksApi, user, modifiedDataOwnerAndType.dataOwner, publicKey);
|
|
1346
|
+
return {
|
|
1347
|
+
dataOwner: sentMaintenanceTasks.length
|
|
1348
|
+
? yield this.retrieveDataOwnerInfoAfterPotentialUpdate(modifiedDataOwnerAndType.dataOwner)
|
|
1349
|
+
: modifiedDataOwnerAndType.dataOwner,
|
|
1350
|
+
publicKey: publicKeyHex,
|
|
1351
|
+
privateKey: (0, binary_utils_1.ua2hex)((yield this.RSA.exportKey(privateKey, 'pkcs8'))),
|
|
1352
|
+
};
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
_saveDataOwner(dataOwner) {
|
|
1356
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1357
|
+
const ownerType = dataOwner.type;
|
|
1358
|
+
const ownerToUpdate = dataOwner.dataOwner;
|
|
1359
|
+
return ownerType === 'hcp'
|
|
1238
1360
|
? yield (this.dataOwnerCache[ownerToUpdate.id] = this.hcpartyBaseApi
|
|
1239
1361
|
.modifyHealthcareParty(ownerToUpdate)
|
|
1240
1362
|
.then((x) => ({ type: 'hcp', dataOwner: x })))
|
|
@@ -1245,14 +1367,6 @@ class IccCryptoXApi {
|
|
|
1245
1367
|
: yield (this.dataOwnerCache[ownerToUpdate.id] = this.deviceBaseApi
|
|
1246
1368
|
.updateDevice(ownerToUpdate)
|
|
1247
1369
|
.then((x) => ({ type: 'device', dataOwner: x })));
|
|
1248
|
-
const sentMaintenanceTasks = yield this.sendMaintenanceTasks(maintenanceTasksApi, user, modifiedDataOwnerAndType.dataOwner, publicKey);
|
|
1249
|
-
return {
|
|
1250
|
-
dataOwner: sentMaintenanceTasks.length
|
|
1251
|
-
? yield this.retrieveDataOwnerInfoAfterPotentialUpdate(modifiedDataOwnerAndType.dataOwner)
|
|
1252
|
-
: modifiedDataOwnerAndType.dataOwner,
|
|
1253
|
-
publicKey: publicKeyHex,
|
|
1254
|
-
privateKey: (0, binary_utils_1.ua2hex)((yield this.RSA.exportKey(privateKey, 'pkcs8'))),
|
|
1255
|
-
};
|
|
1256
1370
|
});
|
|
1257
1371
|
}
|
|
1258
1372
|
createOrUpdateAesExchangeKeysFor(cdo, decryptedAesExchangeKey, keyToEncrypt) {
|
|
@@ -1285,11 +1399,16 @@ class IccCryptoXApi {
|
|
|
1285
1399
|
encryptAesKeyFor(aesKey, dataOwner, doNewPublicKey) {
|
|
1286
1400
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1287
1401
|
const dataOwnerAllPubKeys = [doNewPublicKey].concat(yield this.getDataOwnerPublicKeys(dataOwner));
|
|
1288
|
-
|
|
1289
|
-
|
|
1402
|
+
return this.encryptAesKeyOnlyForProvidedKeys(aesKey, dataOwner, dataOwnerAllPubKeys);
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
encryptAesKeyOnlyForProvidedKeys(aesKey, dataOwner, dataOwnerPubKeys) {
|
|
1406
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1407
|
+
const encryptedAesForDataOwner = yield (0, utils_1.foldAsync)(dataOwnerPubKeys, {}, (encrAes, pubKey) => __awaiter(this, void 0, void 0, function* () {
|
|
1290
1408
|
encrAes[(0, binary_utils_1.ua2hex)(yield this.RSA.exportKey(pubKey, 'spki')).slice(-32)] = (0, binary_utils_1.ua2hex)(yield this._RSA.encrypt(pubKey, (0, binary_utils_1.hex2ua)(aesKey)));
|
|
1291
|
-
|
|
1292
|
-
|
|
1409
|
+
return encrAes;
|
|
1410
|
+
}));
|
|
1411
|
+
return { [dataOwner.id]: encryptedAesForDataOwner };
|
|
1293
1412
|
});
|
|
1294
1413
|
}
|
|
1295
1414
|
retrieveDataOwnerInfoAfterPotentialUpdate(dataOwnerToUpdate) {
|