@icure/api 8.0.63 → 8.0.65

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 (135) hide show
  1. package/icc-api/api/internal/IccExchangeDataApi.d.ts +2 -0
  2. package/icc-api/api/internal/IccExchangeDataApi.js +10 -0
  3. package/icc-api/api/internal/IccExchangeDataApi.js.map +1 -1
  4. package/icc-api/iccApi.d.ts +0 -1
  5. package/icc-api/iccApi.js +0 -1
  6. package/icc-api/iccApi.js.map +1 -1
  7. package/icc-api/index.d.ts +0 -1
  8. package/icc-api/index.js +0 -1
  9. package/icc-api/index.js.map +1 -1
  10. package/icc-x-api/crypto/AccessControlSecretUtils.d.ts +4 -13
  11. package/icc-x-api/crypto/AccessControlSecretUtils.js +19 -29
  12. package/icc-x-api/crypto/AccessControlSecretUtils.js.map +1 -1
  13. package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +6 -2
  14. package/icc-x-api/crypto/BaseExchangeDataManager.js +26 -9
  15. package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -1
  16. package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +2 -3
  17. package/icc-x-api/crypto/BaseExchangeKeysManager.js +8 -16
  18. package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
  19. package/icc-x-api/crypto/CryptoPrimitives.d.ts +2 -0
  20. package/icc-x-api/crypto/CryptoPrimitives.js +3 -0
  21. package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -1
  22. package/icc-x-api/crypto/DelegationsDeAnonymization.d.ts +3 -3
  23. package/icc-x-api/crypto/DelegationsDeAnonymization.js +7 -7
  24. package/icc-x-api/crypto/DelegationsDeAnonymization.js.map +1 -1
  25. package/icc-x-api/crypto/ExchangeDataManager.d.ts +19 -29
  26. package/icc-x-api/crypto/ExchangeDataManager.js +200 -225
  27. package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -1
  28. package/icc-x-api/crypto/ExchangeDataMapManager.js +6 -4
  29. package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -1
  30. package/icc-x-api/crypto/ExchangeKeysManager.d.ts +4 -16
  31. package/icc-x-api/crypto/ExchangeKeysManager.js +44 -41
  32. package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -1
  33. package/icc-x-api/crypto/ExtendedApisUtils.d.ts +47 -25
  34. package/icc-x-api/crypto/ExtendedApisUtils.js.map +1 -1
  35. package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +19 -18
  36. package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +213 -134
  37. package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -1
  38. package/icc-x-api/crypto/HMACUtils.d.ts +2 -2
  39. package/icc-x-api/crypto/HMACUtils.js +3 -4
  40. package/icc-x-api/crypto/HMACUtils.js.map +1 -1
  41. package/icc-x-api/crypto/NativeCryptoPrimitivesBridge.d.ts +1 -0
  42. package/icc-x-api/crypto/NativeCryptoPrimitivesBridge.js +5 -0
  43. package/icc-x-api/crypto/NativeCryptoPrimitivesBridge.js.map +1 -1
  44. package/icc-x-api/crypto/SecureDelegationsManager.d.ts +0 -1
  45. package/icc-x-api/crypto/SecureDelegationsManager.js +17 -49
  46. package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -1
  47. package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +59 -90
  48. package/icc-x-api/crypto/SecurityMetadataDecryptor.js +470 -56
  49. package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -1
  50. package/icc-x-api/crypto/ShamirKeysManager.js +1 -1
  51. package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -1
  52. package/icc-x-api/crypto/TransferKeysManager.d.ts +1 -3
  53. package/icc-x-api/crypto/TransferKeysManager.js +2 -4
  54. package/icc-x-api/crypto/TransferKeysManager.js.map +1 -1
  55. package/icc-x-api/icc-accesslog-x-api.d.ts +2 -2
  56. package/icc-x-api/icc-accesslog-x-api.js +7 -3
  57. package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
  58. package/icc-x-api/icc-calendar-item-x-api.js +4 -2
  59. package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
  60. package/icc-x-api/icc-contact-x-api.d.ts +0 -1
  61. package/icc-x-api/icc-contact-x-api.js +33 -48
  62. package/icc-x-api/icc-contact-x-api.js.map +1 -1
  63. package/icc-x-api/icc-crypto-x-api.js +1 -1
  64. package/icc-x-api/icc-crypto-x-api.js.map +1 -1
  65. package/icc-x-api/icc-document-x-api.d.ts +2 -2
  66. package/icc-x-api/icc-document-x-api.js +45 -42
  67. package/icc-x-api/icc-document-x-api.js.map +1 -1
  68. package/icc-x-api/icc-form-x-api.js +3 -1
  69. package/icc-x-api/icc-form-x-api.js.map +1 -1
  70. package/icc-x-api/icc-hcparty-x-api.d.ts +1 -1
  71. package/icc-x-api/icc-hcparty-x-api.js +62 -25
  72. package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
  73. package/icc-x-api/icc-helement-x-api.js +4 -4
  74. package/icc-x-api/icc-helement-x-api.js.map +1 -1
  75. package/icc-x-api/icc-maintenance-task-x-api.js +4 -2
  76. package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
  77. package/icc-x-api/icc-message-x-api.js +4 -2
  78. package/icc-x-api/icc-message-x-api.js.map +1 -1
  79. package/icc-x-api/icc-patient-x-api.js +5 -7
  80. package/icc-x-api/icc-patient-x-api.js.map +1 -1
  81. package/icc-x-api/icc-topic-x-api.js +2 -2
  82. package/icc-x-api/icc-topic-x-api.js.map +1 -1
  83. package/icc-x-api/index.d.ts +1 -2
  84. package/icc-x-api/index.js +7 -13
  85. package/icc-x-api/index.js.map +1 -1
  86. package/icc-x-api/utils/crypto-utils.d.ts +6 -4
  87. package/icc-x-api/utils/crypto-utils.js +27 -6
  88. package/icc-x-api/utils/crypto-utils.js.map +1 -1
  89. package/icc-x-api/utils/simple-lru-cache.d.ts +19 -0
  90. package/icc-x-api/utils/simple-lru-cache.js +90 -0
  91. package/icc-x-api/utils/simple-lru-cache.js.map +1 -0
  92. package/package.json +4 -2
  93. package/test/icc-x-api/crud/entities-crud-test-interface.js +0 -8
  94. package/test/icc-x-api/crud/entities-crud-test-interface.js.map +1 -1
  95. package/test/icc-x-api/crypto/exchange-data-manager-test.js +74 -92
  96. package/test/icc-x-api/crypto/exchange-data-manager-test.js.map +1 -1
  97. package/test/icc-x-api/crypto/legacy-metadata-migration-test.js.map +1 -1
  98. package/test/icc-x-api/crypto/secure-delegations-manager-test.js +27 -15
  99. package/test/icc-x-api/crypto/secure-delegations-manager-test.js.map +1 -1
  100. package/test/icc-x-api/icc-hcparty-x-api-test.d.ts +1 -0
  101. package/test/icc-x-api/icc-hcparty-x-api-test.js +55 -0
  102. package/test/icc-x-api/icc-hcparty-x-api-test.js.map +1 -0
  103. package/test/utils/FakeEncryptionKeysManager.d.ts +1 -0
  104. package/test/utils/FakeEncryptionKeysManager.js +11 -0
  105. package/test/utils/FakeEncryptionKeysManager.js.map +1 -1
  106. package/test/utils/FakeExchangeDataApi.d.ts +4 -2
  107. package/test/utils/FakeExchangeDataApi.js +24 -6
  108. package/test/utils/FakeExchangeDataApi.js.map +1 -1
  109. package/test/utils/FakeExchangeDataManager.d.ts +10 -10
  110. package/test/utils/FakeExchangeDataManager.js +12 -22
  111. package/test/utils/FakeExchangeDataManager.js.map +1 -1
  112. package/icc-api/api/IccArticleApi.d.ts +0 -72
  113. package/icc-api/api/IccArticleApi.js +0 -149
  114. package/icc-api/api/IccArticleApi.js.map +0 -1
  115. package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.d.ts +0 -33
  116. package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js +0 -141
  117. package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js.map +0 -1
  118. package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.d.ts +0 -46
  119. package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js +0 -312
  120. package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js.map +0 -1
  121. package/icc-x-api/crypto/UserSignatureKeysManager.d.ts +0 -26
  122. package/icc-x-api/crypto/UserSignatureKeysManager.js +0 -78
  123. package/icc-x-api/crypto/UserSignatureKeysManager.js.map +0 -1
  124. package/test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.d.ts +0 -1
  125. package/test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.js +0 -393
  126. package/test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.js.map +0 -1
  127. package/test/icc-x-api/crypto/security-metadata-decryptor-chain-test.d.ts +0 -1
  128. package/test/icc-x-api/crypto/security-metadata-decryptor-chain-test.js +0 -213
  129. package/test/icc-x-api/crypto/security-metadata-decryptor-chain-test.js.map +0 -1
  130. package/test/icc-x-api/crypto/signature-keys-manager-test.d.ts +0 -1
  131. package/test/icc-x-api/crypto/signature-keys-manager-test.js +0 -44
  132. package/test/icc-x-api/crypto/signature-keys-manager-test.js.map +0 -1
  133. package/test/utils/FakeSignatureKeysManager.d.ts +0 -16
  134. package/test/utils/FakeSignatureKeysManager.js +0 -54
  135. package/test/utils/FakeSignatureKeysManager.js.map +0 -1
@@ -1,393 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const mocha_1 = require("mocha");
13
- const CryptoPrimitives_1 = require("../../../icc-x-api/crypto/CryptoPrimitives");
14
- const crypto_1 = require("crypto");
15
- const FakeEncryptionKeysManager_1 = require("../../utils/FakeEncryptionKeysManager");
16
- const SecureDelegationsSecurityMetadataDecryptor_1 = require("../../../icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor");
17
- const SecureDelegationsEncryption_1 = require("../../../icc-x-api/crypto/SecureDelegationsEncryption");
18
- const FakeExchangeDataManager_1 = require("../../utils/FakeExchangeDataManager");
19
- const EntityWithDelegationTypeName_1 = require("../../../icc-x-api/utils/EntityWithDelegationTypeName");
20
- const ExchangeData_1 = require("../../../icc-api/model/internal/ExchangeData");
21
- const chai_1 = require("chai");
22
- const IcureStub_1 = require("../../../icc-api/model/IcureStub");
23
- const SecureDelegation_1 = require("../../../icc-api/model/SecureDelegation");
24
- const icc_x_api_1 = require("../../../icc-x-api");
25
- const SecurityMetadata_1 = require("../../../icc-api/model/SecurityMetadata");
26
- const collection_utils_1 = require("../../../icc-x-api/utils/collection-utils");
27
- const FakeExchangeDataMapManager_1 = require("../../utils/FakeExchangeDataMapManager");
28
- var AccessLevel = SecureDelegation_1.SecureDelegation.AccessLevelEnum;
29
- (0, mocha_1.describe)('Secure delegations security metadata decryptor', function () {
30
- return __awaiter(this, void 0, void 0, function* () {
31
- const primitives = new CryptoPrimitives_1.WebCryptoPrimitives(crypto_1.webcrypto);
32
- const expectedType = EntityWithDelegationTypeName_1.EntityWithDelegationTypeName.AccessLog;
33
- const expectedSfks = [primitives.randomUuid(), primitives.randomUuid()];
34
- let encryptionKeysManager;
35
- let exchangeData;
36
- let exchangeDataMap;
37
- let decryptor;
38
- let secureDelegationsEncryption;
39
- class SecureDelegationWithEncryptedExchangeId extends SecureDelegation_1.SecureDelegation {
40
- constructor(json) {
41
- super(json);
42
- Object.assign(this, json);
43
- }
44
- }
45
- function cacheExchangeDataMaps(secureDelegations) {
46
- return __awaiter(this, void 0, void 0, function* () {
47
- yield exchangeDataMap.createExchangeDataMaps(Object.entries(secureDelegations).reduce((p, [hash, secDel]) => {
48
- return Object.assign(Object.assign({}, p), { [hash]: secDel.encryptedExchangeDataId });
49
- }, {}));
50
- });
51
- }
52
- function initialiseComponents() {
53
- return __awaiter(this, void 0, void 0, function* () {
54
- encryptionKeysManager = yield FakeEncryptionKeysManager_1.FakeEncryptionKeysManager.create(primitives, [], [yield primitives.RSA.generateKeyPair(icc_x_api_1.ShaVersion.Sha256)]);
55
- exchangeData = new FakeExchangeDataManager_1.FakeDecryptionExchangeDataManager(expectedType, expectedSfks, new CryptoPrimitives_1.WebCryptoPrimitives(crypto_1.webcrypto));
56
- exchangeDataMap = new FakeExchangeDataMapManager_1.FakeExchangeDataMapManager();
57
- secureDelegationsEncryption = new SecureDelegationsEncryption_1.SecureDelegationsEncryption(encryptionKeysManager, primitives);
58
- decryptor = new SecureDelegationsSecurityMetadataDecryptor_1.SecureDelegationsSecurityMetadataDecryptor(exchangeData, exchangeDataMap, secureDelegationsEncryption, undefined); // data owner api not used in these tests
59
- });
60
- }
61
- function randomHash() {
62
- return __awaiter(this, void 0, void 0, function* () {
63
- return (0, icc_x_api_1.ua2hex)(yield primitives.sha256(primitives.randomBytes(4)));
64
- });
65
- }
66
- function createExchangeDataAndSecureDelegationEncryptedData(exchangeDataDelegator, exchangeDataDelegate) {
67
- return __awaiter(this, void 0, void 0, function* () {
68
- const exchangeKey = yield primitives.AES.generateCryptoKey(false);
69
- const exchangeData = new ExchangeData_1.ExchangeData({
70
- id: primitives.randomUuid(),
71
- delegator: exchangeDataDelegator,
72
- delegate: exchangeDataDelegate,
73
- exchangeKey: { ignored: 'in this test' },
74
- accessControlSecret: { ignored: 'in this test' },
75
- sharedSignatureKey: { ignored: 'in this test' },
76
- delegatorSignature: { ignored: 'in this test' },
77
- sharedSignature: 'ignored in this test',
78
- });
79
- const expectedDecryptedData = {
80
- secretIds: [primitives.randomUuid(), primitives.randomUuid()],
81
- encryptionKeys: [yield primitives.AES.generateCryptoKey(true), yield primitives.AES.generateCryptoKey(true)],
82
- owningEntityIds: [primitives.randomUuid(), primitives.randomUuid()],
83
- };
84
- const secureDelegationEncryptedData = {
85
- secretIds: yield Promise.all(expectedDecryptedData.secretIds.map((x) => secureDelegationsEncryption.encryptSecretId(x, exchangeKey))),
86
- encryptionKeys: yield Promise.all(expectedDecryptedData.encryptionKeys.map((x) => secureDelegationsEncryption.encryptEncryptionKey(x, exchangeKey))),
87
- owningEntityIds: yield Promise.all(expectedDecryptedData.owningEntityIds.map((x) => secureDelegationsEncryption.encryptOwningEntityId(x, exchangeKey))),
88
- };
89
- return { exchangeKey, exchangeData, expectedDecryptedData, secureDelegationEncryptedData };
90
- });
91
- }
92
- function entityWithSecurityMetadata(securityMetadata) {
93
- return {
94
- entity: new IcureStub_1.IcureStub({
95
- secretForeignKeys: expectedSfks,
96
- securityMetadata,
97
- }),
98
- type: expectedType,
99
- };
100
- }
101
- function toSortedJson(data) {
102
- return JSON.stringify({
103
- decrypted: data.decrypted,
104
- dataOwnersWithAccess: [...data.dataOwnersWithAccess].sort(),
105
- });
106
- }
107
- function verifyCanDecryptEntityData(entity, dataOwnerHierarchySubset, expected) {
108
- return __awaiter(this, void 0, void 0, function* () {
109
- const actualSecretIds = (yield (0, collection_utils_1.asyncGeneratorToArray)(decryptor.decryptSecretIdsOf(entity, dataOwnerHierarchySubset))).map(toSortedJson);
110
- const actualOwningEntityIds = (yield (0, collection_utils_1.asyncGeneratorToArray)(decryptor.decryptOwningEntityIdsOf(entity, dataOwnerHierarchySubset))).map(toSortedJson);
111
- const actualEncryptionKeys = (yield (0, collection_utils_1.asyncGeneratorToArray)(decryptor.decryptEncryptionKeysOf(entity, dataOwnerHierarchySubset))).map(toSortedJson);
112
- const expectedSecretIds = [];
113
- const expectedOwningEntityIds = [];
114
- const expectedEncryptionKeys = [];
115
- for (const data of expected) {
116
- data.expectedDecryptedData.secretIds.forEach((x) => expectedSecretIds.push(toSortedJson({ decrypted: x, dataOwnersWithAccess: [data.exchangeData.delegate, data.exchangeData.delegator] })));
117
- data.expectedDecryptedData.owningEntityIds.forEach((x) => expectedOwningEntityIds.push(toSortedJson({ decrypted: x, dataOwnersWithAccess: [data.exchangeData.delegate, data.exchangeData.delegator] })));
118
- data.expectedDecryptedData.encryptionKeys.forEach((x) => expectedEncryptionKeys.push(toSortedJson({ decrypted: x, dataOwnersWithAccess: [data.exchangeData.delegate, data.exchangeData.delegator] })));
119
- }
120
- (0, chai_1.expect)(actualSecretIds).to.have.members(expectedSecretIds);
121
- (0, chai_1.expect)(actualOwningEntityIds).to.have.members(expectedOwningEntityIds);
122
- (0, chai_1.expect)(actualEncryptionKeys).to.have.members(expectedEncryptionKeys);
123
- });
124
- }
125
- it('should be able to decrypt data from a secure delegation accessible by hash if the hash is cached', function () {
126
- return __awaiter(this, void 0, void 0, function* () {
127
- yield initialiseComponents();
128
- const self = primitives.randomUuid();
129
- const createdData1 = yield createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid());
130
- const createdData2 = yield createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), self);
131
- const delegation1 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData1.secureDelegationEncryptedData), { delegator: undefined, delegate: undefined, exchangeDataId: undefined, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
132
- const delegation2 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData2.secureDelegationEncryptedData), { delegator: undefined, delegate: undefined, exchangeDataId: undefined, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
133
- const hash1 = yield randomHash();
134
- const hash2 = yield randomHash();
135
- const hash3 = yield randomHash();
136
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
137
- secureDelegations: { [hash1]: delegation1, [hash2]: delegation2 },
138
- keysEquivalences: { [hash3]: hash2 },
139
- }));
140
- exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [hash1] });
141
- exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [hash3] });
142
- yield verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2]);
143
- });
144
- });
145
- it('should be able to decrypt data from a secure delegation with clear text id where the delegator or delegate are in dataOwnersHierarchySubset', function () {
146
- return __awaiter(this, void 0, void 0, function* () {
147
- yield initialiseComponents();
148
- const self = primitives.randomUuid();
149
- const other1 = primitives.randomUuid();
150
- const other2 = primitives.randomUuid();
151
- const createdData1 = yield createExchangeDataAndSecureDelegationEncryptedData(self, other1);
152
- const createdData2 = yield createExchangeDataAndSecureDelegationEncryptedData(other2, self);
153
- const delegation1 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData1.secureDelegationEncryptedData), { delegator: self, delegate: other1, exchangeDataId: createdData1.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
154
- const delegation2 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData2.secureDelegationEncryptedData), { delegator: other2, delegate: self, exchangeDataId: createdData2.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
155
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
156
- secureDelegations: { [yield randomHash()]: delegation1, [yield randomHash()]: delegation2 },
157
- }));
158
- exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] }, true);
159
- exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [] });
160
- yield verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2]);
161
- });
162
- });
163
- it('should be able to decrypt data from a secure delegation with encrypted id if the keys to decrypt the id are available and the delegator or delegate is in dataOwnersHierarchySubset', function () {
164
- return __awaiter(this, void 0, void 0, function* () {
165
- yield initialiseComponents();
166
- const self = primitives.randomUuid();
167
- const createdData1 = yield createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid());
168
- const createdData2 = yield createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), self);
169
- const encryptionKeys = Object.fromEntries(Object.entries(encryptionKeysManager.getDecryptionKeys()).map(([fp, pair]) => [fp, pair.publicKey]));
170
- const delegation1 = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData1.secureDelegationEncryptedData), { delegator: self, encryptedExchangeDataId: yield secureDelegationsEncryption.encryptExchangeDataId(createdData1.exchangeData.id, encryptionKeys), permissions: AccessLevel.WRITE }));
171
- const delegation2 = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData2.secureDelegationEncryptedData), { delegate: self, encryptedExchangeDataId: yield secureDelegationsEncryption.encryptExchangeDataId(createdData2.exchangeData.id, encryptionKeys), permissions: AccessLevel.WRITE }));
172
- const secureDelegations = { [yield randomHash()]: delegation1, [yield randomHash()]: delegation2 };
173
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
174
- secureDelegations: secureDelegations,
175
- }));
176
- exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] }, true);
177
- exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [] });
178
- yield cacheExchangeDataMaps(secureDelegations);
179
- yield verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2]);
180
- });
181
- });
182
- it('should be able to decrypt data from secure delegations accessible by encrypted or cleartext id', function () {
183
- return __awaiter(this, void 0, void 0, function* () {
184
- yield initialiseComponents();
185
- const self = primitives.randomUuid();
186
- const other1 = primitives.randomUuid();
187
- const other2 = primitives.randomUuid();
188
- const createdData1 = yield createExchangeDataAndSecureDelegationEncryptedData(self, other1);
189
- const createdData2 = yield createExchangeDataAndSecureDelegationEncryptedData(other2, self);
190
- const createdData3 = yield createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid());
191
- const createdData4 = yield createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), self);
192
- const encryptionKeys = Object.fromEntries(Object.entries(encryptionKeysManager.getDecryptionKeys()).map(([fp, pair]) => [fp, pair.publicKey]));
193
- const delegation1 = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData1.secureDelegationEncryptedData), { delegator: self, delegate: other1, exchangeDataId: createdData1.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
194
- const delegation2 = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData2.secureDelegationEncryptedData), { delegator: other2, delegate: self, exchangeDataId: createdData2.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
195
- const delegation3 = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData3.secureDelegationEncryptedData), { delegator: self, encryptedExchangeDataId: yield secureDelegationsEncryption.encryptExchangeDataId(createdData3.exchangeData.id, encryptionKeys), permissions: AccessLevel.WRITE }));
196
- const delegation4 = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData4.secureDelegationEncryptedData), { delegate: self, encryptedExchangeDataId: yield secureDelegationsEncryption.encryptExchangeDataId(createdData4.exchangeData.id, encryptionKeys), permissions: AccessLevel.WRITE }));
197
- const secureDelegations = {
198
- [yield randomHash()]: delegation1,
199
- [yield randomHash()]: delegation2,
200
- [yield randomHash()]: delegation3,
201
- [yield randomHash()]: delegation4,
202
- };
203
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
204
- secureDelegations: secureDelegations,
205
- }));
206
- exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] }, true);
207
- exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [] });
208
- exchangeData.cacheFakeData(createdData3.exchangeData, { exchangeKey: createdData3.exchangeKey, hashes: [] }, true);
209
- exchangeData.cacheFakeData(createdData4.exchangeData, { exchangeKey: createdData4.exchangeKey, hashes: [] });
210
- yield cacheExchangeDataMaps(secureDelegations);
211
- yield verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2, createdData3, createdData4]);
212
- });
213
- });
214
- // Note: mixed scenario where part of secure delegation is accessible by hash and part by id (clear-text or encrypted) is not realistic and not tested
215
- it('should ignore delegations accessible by id where the neither the delegator nor delegate are in dataOwnersHierarchySubset', function () {
216
- return __awaiter(this, void 0, void 0, function* () {
217
- yield initialiseComponents();
218
- const createdData1 = yield createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), primitives.randomUuid());
219
- const createdData2 = yield createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), primitives.randomUuid());
220
- const delegation1 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData1.secureDelegationEncryptedData), { delegator: primitives.randomUuid(), delegate: primitives.randomUuid(), exchangeDataId: createdData1.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
221
- const delegation2 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData2.secureDelegationEncryptedData), { delegator: primitives.randomUuid(), delegate: primitives.randomUuid(), exchangeDataId: createdData2.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
222
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
223
- secureDelegations: { [yield randomHash()]: delegation1, [yield randomHash()]: delegation2 },
224
- }));
225
- yield verifyCanDecryptEntityData(entity, [primitives.randomUuid()], []);
226
- });
227
- });
228
- it('should ignore secure delegation with encrypted id if the keys to decrypt the id are not available', function () {
229
- return __awaiter(this, void 0, void 0, function* () {
230
- yield initialiseComponents();
231
- const self = primitives.randomUuid();
232
- const createdData = yield createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid());
233
- const newKey = yield primitives.RSA.generateKeyPair(icc_x_api_1.ShaVersion.Sha256);
234
- const newKeyFp = (0, icc_x_api_1.ua2hex)(yield primitives.RSA.exportKey(newKey.publicKey, 'spki')).slice(-32);
235
- const delegation = new SecureDelegationWithEncryptedExchangeId(Object.assign(Object.assign({}, createdData.secureDelegationEncryptedData), { delegator: self, encryptedExchangeDataId: yield secureDelegationsEncryption.encryptExchangeDataId(createdData.exchangeData.id, {
236
- [newKeyFp]: newKey.publicKey,
237
- }), permissions: AccessLevel.WRITE }));
238
- const secureDelegation = { [yield randomHash()]: delegation };
239
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
240
- secureDelegations: secureDelegation,
241
- }));
242
- exchangeData.cacheFakeData(createdData.exchangeData, { exchangeKey: createdData.exchangeKey, hashes: [] });
243
- yield cacheExchangeDataMaps(secureDelegation);
244
- yield verifyCanDecryptEntityData(entity, [self], []);
245
- });
246
- });
247
- it('should ignore secure delegations corresponding to exchange data which could not be decrypted', function () {
248
- return __awaiter(this, void 0, void 0, function* () {
249
- yield initialiseComponents();
250
- const self = primitives.randomUuid();
251
- const other1 = primitives.randomUuid();
252
- const other2 = primitives.randomUuid();
253
- const createdData1 = yield createExchangeDataAndSecureDelegationEncryptedData(self, other1);
254
- const createdData2 = yield createExchangeDataAndSecureDelegationEncryptedData(other2, self);
255
- const delegation1 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData1.secureDelegationEncryptedData), { delegator: self, delegate: other1, exchangeDataId: createdData1.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
256
- const delegation2 = new SecureDelegation_1.SecureDelegation(Object.assign(Object.assign({}, createdData2.secureDelegationEncryptedData), { delegator: other2, delegate: self, exchangeDataId: createdData2.exchangeData.id, encryptedExchangeDataId: undefined, permissions: AccessLevel.WRITE }));
257
- const entity = entityWithSecurityMetadata(new SecurityMetadata_1.SecurityMetadata({
258
- secureDelegations: { [yield randomHash()]: delegation1, [yield randomHash()]: delegation2 },
259
- }));
260
- exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] });
261
- exchangeData.cacheFakeData(createdData2.exchangeData, undefined);
262
- yield verifyCanDecryptEntityData(entity, [self], [createdData1]);
263
- });
264
- });
265
- it('should give an error if dataOwnersHierarchySubset is empty', function () {
266
- return __awaiter(this, void 0, void 0, function* () {
267
- yield initialiseComponents();
268
- const entity = {
269
- entity: new IcureStub_1.IcureStub({ secretForeignKeys: expectedSfks }),
270
- type: expectedType,
271
- };
272
- let failed = 0;
273
- try {
274
- decryptor.decryptEncryptionKeysOf(entity, []);
275
- }
276
- catch (e) {
277
- console.log(e);
278
- failed++;
279
- }
280
- try {
281
- decryptor.decryptSecretIdsOf(entity, []);
282
- }
283
- catch (e) {
284
- console.log(e);
285
- failed++;
286
- }
287
- try {
288
- decryptor.decryptOwningEntityIdsOf(entity, []);
289
- }
290
- catch (e) {
291
- console.log(e);
292
- failed++;
293
- }
294
- try {
295
- yield decryptor.getEntityAccessLevel(entity, []);
296
- }
297
- catch (e) {
298
- console.log(e);
299
- failed++;
300
- }
301
- (0, chai_1.expect)(failed).to.equal(4);
302
- });
303
- });
304
- it('should return the best access level with directly accessible secure delegations', function () {
305
- return __awaiter(this, void 0, void 0, function* () {
306
- yield initialiseComponents();
307
- const dataOwnerA = primitives.randomUuid();
308
- const dataOwnerB = primitives.randomUuid();
309
- const secureDelegationWriteA = new SecureDelegation_1.SecureDelegation({ delegator: dataOwnerA, permissions: AccessLevel.WRITE });
310
- const secureDelegationReadA = new SecureDelegation_1.SecureDelegation({ delegate: dataOwnerA, permissions: AccessLevel.READ });
311
- const secureDelegationWriteB = new SecureDelegation_1.SecureDelegation({ delegate: dataOwnerB, permissions: AccessLevel.WRITE });
312
- const secureDelegationReadB = new SecureDelegation_1.SecureDelegation({ delegator: dataOwnerB, permissions: AccessLevel.READ });
313
- const secureDelegationWriteOther = new SecureDelegation_1.SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.WRITE });
314
- const secureDelegationReadOther = new SecureDelegation_1.SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.READ });
315
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
316
- secureDelegations: {
317
- [yield randomHash()]: secureDelegationReadA,
318
- [yield randomHash()]: secureDelegationWriteOther,
319
- [yield randomHash()]: secureDelegationWriteB,
320
- },
321
- }), [dataOwnerA])).to.equal(AccessLevel.READ);
322
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
323
- secureDelegations: {
324
- [yield randomHash()]: secureDelegationReadA,
325
- [yield randomHash()]: secureDelegationWriteOther,
326
- [yield randomHash()]: secureDelegationWriteB,
327
- },
328
- }), [dataOwnerB])).to.equal(AccessLevel.WRITE);
329
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
330
- secureDelegations: {
331
- [yield randomHash()]: secureDelegationReadOther,
332
- [yield randomHash()]: secureDelegationWriteB,
333
- },
334
- }), [dataOwnerA])).to.equal(undefined);
335
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
336
- secureDelegations: {
337
- [yield randomHash()]: secureDelegationReadA,
338
- [yield randomHash()]: secureDelegationWriteOther,
339
- [yield randomHash()]: secureDelegationWriteB,
340
- },
341
- }), [dataOwnerA, dataOwnerB])).to.equal(AccessLevel.WRITE);
342
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
343
- secureDelegations: {
344
- [yield randomHash()]: secureDelegationReadA,
345
- [yield randomHash()]: secureDelegationReadB,
346
- [yield randomHash()]: secureDelegationWriteOther,
347
- },
348
- }), [dataOwnerA, dataOwnerB])).to.equal(AccessLevel.READ);
349
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
350
- secureDelegations: {
351
- [yield randomHash()]: secureDelegationWriteA,
352
- },
353
- }), [dataOwnerA, dataOwnerB])).to.equal(AccessLevel.WRITE);
354
- });
355
- });
356
- it('should return the best access level with secure delegations accessible through hash', function () {
357
- return __awaiter(this, void 0, void 0, function* () {
358
- const hashA = yield randomHash();
359
- const hashB = yield randomHash();
360
- const secureDelegationWriteA = [hashA, new SecureDelegation_1.SecureDelegation({ permissions: AccessLevel.WRITE })];
361
- const secureDelegationReadA = [hashA, new SecureDelegation_1.SecureDelegation({ permissions: AccessLevel.READ })];
362
- const secureDelegationWriteB = [hashB, new SecureDelegation_1.SecureDelegation({ permissions: AccessLevel.WRITE })];
363
- const secureDelegationReadB = [hashB, new SecureDelegation_1.SecureDelegation({ permissions: AccessLevel.READ })];
364
- const secureDelegationWriteOther = [
365
- yield randomHash(),
366
- new SecureDelegation_1.SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.WRITE }),
367
- ];
368
- const secureDelegationReadOther = [
369
- yield randomHash(),
370
- new SecureDelegation_1.SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.READ }),
371
- ];
372
- function testWithEntriesAndHashes(entries, hashes, expectedLevel) {
373
- return __awaiter(this, void 0, void 0, function* () {
374
- yield initialiseComponents();
375
- for (const hash of hashes) {
376
- exchangeData.cacheFakeData({}, { exchangeKey: {}, hashes: [hash] });
377
- }
378
- (0, chai_1.expect)(yield decryptor.getEntityAccessLevel(entityWithSecurityMetadata({
379
- secureDelegations: Object.fromEntries(entries),
380
- }), [primitives.randomUuid()])).to.equal(expectedLevel);
381
- });
382
- }
383
- yield testWithEntriesAndHashes([secureDelegationReadA, secureDelegationWriteB, secureDelegationWriteOther], [hashA], AccessLevel.READ);
384
- yield testWithEntriesAndHashes([secureDelegationReadA, secureDelegationWriteB, secureDelegationWriteOther], [hashB], AccessLevel.WRITE);
385
- yield testWithEntriesAndHashes([secureDelegationWriteB, secureDelegationReadOther], [hashA], undefined);
386
- yield testWithEntriesAndHashes([secureDelegationReadA, secureDelegationWriteB, secureDelegationWriteOther], [hashA, hashB], AccessLevel.WRITE);
387
- yield testWithEntriesAndHashes([secureDelegationReadA, secureDelegationReadB, secureDelegationWriteOther], [hashA, hashB], AccessLevel.READ);
388
- yield testWithEntriesAndHashes([secureDelegationWriteA], [hashA, hashB], AccessLevel.WRITE);
389
- });
390
- });
391
- });
392
- });
393
- //# sourceMappingURL=secure-delegations-metadata-decryptor-test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"secure-delegations-metadata-decryptor-test.js","sourceRoot":"","sources":["../../../../test/icc-x-api/crypto/secure-delegations-metadata-decryptor-test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe } from 'mocha'\nimport { CryptoPrimitives, WebCryptoPrimitives } from '../../../icc-x-api/crypto/CryptoPrimitives'\nimport { webcrypto } from 'crypto'\nimport { FakeEncryptionKeysManager } from '../../utils/FakeEncryptionKeysManager'\nimport { SecureDelegationsSecurityMetadataDecryptor } from '../../../icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor'\nimport { SecureDelegationsEncryption } from '../../../icc-x-api/crypto/SecureDelegationsEncryption'\nimport { FakeDecryptionExchangeDataManager } from '../../utils/FakeExchangeDataManager'\nimport { EncryptedEntityWithType, EntityWithDelegationTypeName } from '../../../icc-x-api/utils/EntityWithDelegationTypeName'\nimport { ExchangeData } from '../../../icc-api/model/internal/ExchangeData'\nimport { expect } from 'chai'\nimport { IcureStub } from '../../../icc-api/model/IcureStub'\nimport { SecureDelegation } from '../../../icc-api/model/SecureDelegation'\nimport { ShaVersion, ua2hex } from '../../../icc-x-api'\nimport { SecurityMetadata } from '../../../icc-api/model/SecurityMetadata'\nimport { asyncGeneratorToArray } from '../../../icc-x-api/utils/collection-utils'\nimport { FakeExchangeDataMapManager } from '../../utils/FakeExchangeDataMapManager'\nimport AccessLevel = SecureDelegation.AccessLevelEnum\n\ndescribe('Secure delegations security metadata decryptor', async function () {\n const primitives = new WebCryptoPrimitives(webcrypto as any)\n const expectedType: EntityWithDelegationTypeName = EntityWithDelegationTypeName.AccessLog\n const expectedSfks = [primitives.randomUuid(), primitives.randomUuid()]\n let encryptionKeysManager: FakeEncryptionKeysManager\n let exchangeData: FakeDecryptionExchangeDataManager\n let exchangeDataMap: FakeExchangeDataMapManager\n let decryptor: SecureDelegationsSecurityMetadataDecryptor\n let secureDelegationsEncryption: SecureDelegationsEncryption\n\n class SecureDelegationWithEncryptedExchangeId extends SecureDelegation {\n constructor(json: JSON | any) {\n super(json)\n Object.assign(this as SecureDelegationWithEncryptedExchangeId, json)\n }\n\n encryptedExchangeDataId!: { [fp: string]: string }\n }\n\n async function cacheExchangeDataMaps(secureDelegations: { [hash: string]: SecureDelegationWithEncryptedExchangeId }) {\n await exchangeDataMap.createExchangeDataMaps(\n Object.entries(secureDelegations).reduce((p, [hash, secDel]) => {\n return {\n ...p,\n [hash]: secDel.encryptedExchangeDataId,\n }\n }, {} as { [hash: string]: { [fp: string]: string } })\n )\n }\n\n async function initialiseComponents() {\n encryptionKeysManager = await FakeEncryptionKeysManager.create(primitives, [], [await primitives.RSA.generateKeyPair(ShaVersion.Sha256)])\n exchangeData = new FakeDecryptionExchangeDataManager(expectedType, expectedSfks, new WebCryptoPrimitives(webcrypto as any))\n exchangeDataMap = new FakeExchangeDataMapManager()\n secureDelegationsEncryption = new SecureDelegationsEncryption(encryptionKeysManager, primitives)\n decryptor = new SecureDelegationsSecurityMetadataDecryptor(exchangeData, exchangeDataMap, secureDelegationsEncryption, undefined as any) // data owner api not used in these tests\n }\n\n async function randomHash(): Promise<string> {\n return ua2hex(await primitives.sha256(primitives.randomBytes(4)))\n }\n\n async function createExchangeDataAndSecureDelegationEncryptedData(\n exchangeDataDelegator: string,\n exchangeDataDelegate: string\n ): Promise<{\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n secureDelegationEncryptedData: {\n secretIds: string[]\n encryptionKeys: string[]\n owningEntityIds: string[]\n }\n expectedDecryptedData: {\n secretIds: string[]\n encryptionKeys: string[]\n owningEntityIds: string[]\n }\n }> {\n const exchangeKey = await primitives.AES.generateCryptoKey(false)\n const exchangeData = new ExchangeData({\n id: primitives.randomUuid(),\n delegator: exchangeDataDelegator,\n delegate: exchangeDataDelegate,\n exchangeKey: { ignored: 'in this test' },\n accessControlSecret: { ignored: 'in this test' },\n sharedSignatureKey: { ignored: 'in this test' },\n delegatorSignature: { ignored: 'in this test' },\n sharedSignature: 'ignored in this test',\n })\n const expectedDecryptedData = {\n secretIds: [primitives.randomUuid(), primitives.randomUuid()],\n encryptionKeys: [await primitives.AES.generateCryptoKey(true), await primitives.AES.generateCryptoKey(true)],\n owningEntityIds: [primitives.randomUuid(), primitives.randomUuid()],\n }\n const secureDelegationEncryptedData = {\n secretIds: await Promise.all(expectedDecryptedData.secretIds.map((x) => secureDelegationsEncryption.encryptSecretId(x, exchangeKey))),\n encryptionKeys: await Promise.all(\n expectedDecryptedData.encryptionKeys.map((x) => secureDelegationsEncryption.encryptEncryptionKey(x, exchangeKey))\n ),\n owningEntityIds: await Promise.all(\n expectedDecryptedData.owningEntityIds.map((x) => secureDelegationsEncryption.encryptOwningEntityId(x, exchangeKey))\n ),\n }\n return { exchangeKey, exchangeData, expectedDecryptedData, secureDelegationEncryptedData }\n }\n\n function entityWithSecurityMetadata(securityMetadata: SecurityMetadata): EncryptedEntityWithType {\n return {\n entity: new IcureStub({\n secretForeignKeys: expectedSfks,\n securityMetadata,\n }),\n type: expectedType,\n }\n }\n\n function toSortedJson(data: { decrypted: string; dataOwnersWithAccess: string[] }): string {\n return JSON.stringify({\n decrypted: data.decrypted,\n dataOwnersWithAccess: [...data.dataOwnersWithAccess].sort(),\n })\n }\n\n async function verifyCanDecryptEntityData(\n entity: EncryptedEntityWithType,\n dataOwnerHierarchySubset: string[],\n expected: {\n exchangeData: ExchangeData\n expectedDecryptedData: {\n secretIds: string[]\n encryptionKeys: string[]\n owningEntityIds: string[]\n }\n }[]\n ) {\n const actualSecretIds = (await asyncGeneratorToArray(decryptor.decryptSecretIdsOf(entity, dataOwnerHierarchySubset))).map(toSortedJson)\n const actualOwningEntityIds = (await asyncGeneratorToArray(decryptor.decryptOwningEntityIdsOf(entity, dataOwnerHierarchySubset))).map(\n toSortedJson\n )\n const actualEncryptionKeys = (await asyncGeneratorToArray(decryptor.decryptEncryptionKeysOf(entity, dataOwnerHierarchySubset))).map(toSortedJson)\n const expectedSecretIds: string[] = []\n const expectedOwningEntityIds: string[] = []\n const expectedEncryptionKeys: string[] = []\n for (const data of expected) {\n data.expectedDecryptedData.secretIds.forEach((x) =>\n expectedSecretIds.push(toSortedJson({ decrypted: x, dataOwnersWithAccess: [data.exchangeData.delegate, data.exchangeData.delegator] }))\n )\n data.expectedDecryptedData.owningEntityIds.forEach((x) =>\n expectedOwningEntityIds.push(toSortedJson({ decrypted: x, dataOwnersWithAccess: [data.exchangeData.delegate, data.exchangeData.delegator] }))\n )\n data.expectedDecryptedData.encryptionKeys.forEach((x) =>\n expectedEncryptionKeys.push(toSortedJson({ decrypted: x, dataOwnersWithAccess: [data.exchangeData.delegate, data.exchangeData.delegator] }))\n )\n }\n expect(actualSecretIds).to.have.members(expectedSecretIds)\n expect(actualOwningEntityIds).to.have.members(expectedOwningEntityIds)\n expect(actualEncryptionKeys).to.have.members(expectedEncryptionKeys)\n }\n\n it('should be able to decrypt data from a secure delegation accessible by hash if the hash is cached', async function () {\n await initialiseComponents()\n const self = primitives.randomUuid()\n const createdData1 = await createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid())\n const createdData2 = await createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), self)\n const delegation1 = new SecureDelegation({\n ...createdData1.secureDelegationEncryptedData,\n delegator: undefined,\n delegate: undefined,\n exchangeDataId: undefined,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const delegation2 = new SecureDelegation({\n ...createdData2.secureDelegationEncryptedData,\n delegator: undefined,\n delegate: undefined,\n exchangeDataId: undefined,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const hash1 = await randomHash()\n const hash2 = await randomHash()\n const hash3 = await randomHash()\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: { [hash1]: delegation1, [hash2]: delegation2 },\n keysEquivalences: { [hash3]: hash2 },\n })\n )\n exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [hash1] })\n exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [hash3] })\n await verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2])\n })\n\n it('should be able to decrypt data from a secure delegation with clear text id where the delegator or delegate are in dataOwnersHierarchySubset', async function () {\n await initialiseComponents()\n const self = primitives.randomUuid()\n const other1 = primitives.randomUuid()\n const other2 = primitives.randomUuid()\n const createdData1 = await createExchangeDataAndSecureDelegationEncryptedData(self, other1)\n const createdData2 = await createExchangeDataAndSecureDelegationEncryptedData(other2, self)\n const delegation1 = new SecureDelegation({\n ...createdData1.secureDelegationEncryptedData,\n delegator: self,\n delegate: other1,\n exchangeDataId: createdData1.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const delegation2 = new SecureDelegation({\n ...createdData2.secureDelegationEncryptedData,\n delegator: other2,\n delegate: self,\n exchangeDataId: createdData2.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: { [await randomHash()]: delegation1, [await randomHash()]: delegation2 },\n })\n )\n exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] }, true)\n exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [] })\n await verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2])\n })\n\n it('should be able to decrypt data from a secure delegation with encrypted id if the keys to decrypt the id are available and the delegator or delegate is in dataOwnersHierarchySubset', async function () {\n await initialiseComponents()\n const self = primitives.randomUuid()\n const createdData1 = await createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid())\n const createdData2 = await createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), self)\n const encryptionKeys = Object.fromEntries(Object.entries(encryptionKeysManager.getDecryptionKeys()).map(([fp, pair]) => [fp, pair.publicKey]))\n const delegation1 = new SecureDelegationWithEncryptedExchangeId({\n ...createdData1.secureDelegationEncryptedData,\n delegator: self,\n encryptedExchangeDataId: await secureDelegationsEncryption.encryptExchangeDataId(createdData1.exchangeData.id!, encryptionKeys),\n permissions: AccessLevel.WRITE,\n })\n const delegation2 = new SecureDelegationWithEncryptedExchangeId({\n ...createdData2.secureDelegationEncryptedData,\n delegate: self,\n encryptedExchangeDataId: await secureDelegationsEncryption.encryptExchangeDataId(createdData2.exchangeData.id!, encryptionKeys),\n permissions: AccessLevel.WRITE,\n })\n const secureDelegations = { [await randomHash()]: delegation1, [await randomHash()]: delegation2 }\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: secureDelegations,\n })\n )\n exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] }, true)\n exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [] })\n await cacheExchangeDataMaps(secureDelegations)\n await verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2])\n })\n\n it('should be able to decrypt data from secure delegations accessible by encrypted or cleartext id', async function () {\n await initialiseComponents()\n const self = primitives.randomUuid()\n const other1 = primitives.randomUuid()\n const other2 = primitives.randomUuid()\n const createdData1 = await createExchangeDataAndSecureDelegationEncryptedData(self, other1)\n const createdData2 = await createExchangeDataAndSecureDelegationEncryptedData(other2, self)\n const createdData3 = await createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid())\n const createdData4 = await createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), self)\n const encryptionKeys = Object.fromEntries(Object.entries(encryptionKeysManager.getDecryptionKeys()).map(([fp, pair]) => [fp, pair.publicKey]))\n const delegation1 = new SecureDelegationWithEncryptedExchangeId({\n ...createdData1.secureDelegationEncryptedData,\n delegator: self,\n delegate: other1,\n exchangeDataId: createdData1.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const delegation2 = new SecureDelegationWithEncryptedExchangeId({\n ...createdData2.secureDelegationEncryptedData,\n delegator: other2,\n delegate: self,\n exchangeDataId: createdData2.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const delegation3 = new SecureDelegationWithEncryptedExchangeId({\n ...createdData3.secureDelegationEncryptedData,\n delegator: self,\n encryptedExchangeDataId: await secureDelegationsEncryption.encryptExchangeDataId(createdData3.exchangeData.id!, encryptionKeys),\n permissions: AccessLevel.WRITE,\n })\n const delegation4 = new SecureDelegationWithEncryptedExchangeId({\n ...createdData4.secureDelegationEncryptedData,\n delegate: self,\n encryptedExchangeDataId: await secureDelegationsEncryption.encryptExchangeDataId(createdData4.exchangeData.id!, encryptionKeys),\n permissions: AccessLevel.WRITE,\n })\n const secureDelegations = {\n [await randomHash()]: delegation1,\n [await randomHash()]: delegation2,\n [await randomHash()]: delegation3,\n [await randomHash()]: delegation4,\n }\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: secureDelegations,\n })\n )\n exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] }, true)\n exchangeData.cacheFakeData(createdData2.exchangeData, { exchangeKey: createdData2.exchangeKey, hashes: [] })\n exchangeData.cacheFakeData(createdData3.exchangeData, { exchangeKey: createdData3.exchangeKey, hashes: [] }, true)\n exchangeData.cacheFakeData(createdData4.exchangeData, { exchangeKey: createdData4.exchangeKey, hashes: [] })\n await cacheExchangeDataMaps(secureDelegations)\n await verifyCanDecryptEntityData(entity, [self], [createdData1, createdData2, createdData3, createdData4])\n })\n\n // Note: mixed scenario where part of secure delegation is accessible by hash and part by id (clear-text or encrypted) is not realistic and not tested\n\n it('should ignore delegations accessible by id where the neither the delegator nor delegate are in dataOwnersHierarchySubset', async function () {\n await initialiseComponents()\n const createdData1 = await createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), primitives.randomUuid())\n const createdData2 = await createExchangeDataAndSecureDelegationEncryptedData(primitives.randomUuid(), primitives.randomUuid())\n const delegation1 = new SecureDelegation({\n ...createdData1.secureDelegationEncryptedData,\n delegator: primitives.randomUuid(),\n delegate: primitives.randomUuid(),\n exchangeDataId: createdData1.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const delegation2 = new SecureDelegation({\n ...createdData2.secureDelegationEncryptedData,\n delegator: primitives.randomUuid(),\n delegate: primitives.randomUuid(),\n exchangeDataId: createdData2.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: { [await randomHash()]: delegation1, [await randomHash()]: delegation2 },\n })\n )\n await verifyCanDecryptEntityData(entity, [primitives.randomUuid()], [])\n })\n\n it('should ignore secure delegation with encrypted id if the keys to decrypt the id are not available', async function () {\n await initialiseComponents()\n const self = primitives.randomUuid()\n const createdData = await createExchangeDataAndSecureDelegationEncryptedData(self, primitives.randomUuid())\n const newKey = await primitives.RSA.generateKeyPair(ShaVersion.Sha256)\n const newKeyFp = ua2hex(await primitives.RSA.exportKey(newKey.publicKey, 'spki')).slice(-32)\n const delegation = new SecureDelegationWithEncryptedExchangeId({\n ...createdData.secureDelegationEncryptedData,\n delegator: self,\n encryptedExchangeDataId: await secureDelegationsEncryption.encryptExchangeDataId(createdData.exchangeData.id!, {\n [newKeyFp]: newKey.publicKey,\n }),\n permissions: AccessLevel.WRITE,\n })\n const secureDelegation = { [await randomHash()]: delegation }\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: secureDelegation,\n })\n )\n exchangeData.cacheFakeData(createdData.exchangeData, { exchangeKey: createdData.exchangeKey, hashes: [] })\n await cacheExchangeDataMaps(secureDelegation)\n await verifyCanDecryptEntityData(entity, [self], [])\n })\n\n it('should ignore secure delegations corresponding to exchange data which could not be decrypted', async function () {\n await initialiseComponents()\n const self = primitives.randomUuid()\n const other1 = primitives.randomUuid()\n const other2 = primitives.randomUuid()\n const createdData1 = await createExchangeDataAndSecureDelegationEncryptedData(self, other1)\n const createdData2 = await createExchangeDataAndSecureDelegationEncryptedData(other2, self)\n const delegation1 = new SecureDelegation({\n ...createdData1.secureDelegationEncryptedData,\n delegator: self,\n delegate: other1,\n exchangeDataId: createdData1.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const delegation2 = new SecureDelegation({\n ...createdData2.secureDelegationEncryptedData,\n delegator: other2,\n delegate: self,\n exchangeDataId: createdData2.exchangeData.id,\n encryptedExchangeDataId: undefined,\n permissions: AccessLevel.WRITE,\n })\n const entity = entityWithSecurityMetadata(\n new SecurityMetadata({\n secureDelegations: { [await randomHash()]: delegation1, [await randomHash()]: delegation2 },\n })\n )\n exchangeData.cacheFakeData(createdData1.exchangeData, { exchangeKey: createdData1.exchangeKey, hashes: [] })\n exchangeData.cacheFakeData(createdData2.exchangeData, undefined)\n await verifyCanDecryptEntityData(entity, [self], [createdData1])\n })\n\n it('should give an error if dataOwnersHierarchySubset is empty', async function () {\n await initialiseComponents()\n const entity = {\n entity: new IcureStub({ secretForeignKeys: expectedSfks }),\n type: expectedType,\n }\n let failed = 0\n try {\n decryptor.decryptEncryptionKeysOf(entity, [])\n } catch (e) {\n console.log(e)\n failed++\n }\n try {\n decryptor.decryptSecretIdsOf(entity, [])\n } catch (e) {\n console.log(e)\n failed++\n }\n try {\n decryptor.decryptOwningEntityIdsOf(entity, [])\n } catch (e) {\n console.log(e)\n failed++\n }\n try {\n await decryptor.getEntityAccessLevel(entity, [])\n } catch (e) {\n console.log(e)\n failed++\n }\n expect(failed).to.equal(4)\n })\n\n it('should return the best access level with directly accessible secure delegations', async function () {\n await initialiseComponents()\n const dataOwnerA = primitives.randomUuid()\n const dataOwnerB = primitives.randomUuid()\n const secureDelegationWriteA = new SecureDelegation({ delegator: dataOwnerA, permissions: AccessLevel.WRITE })\n const secureDelegationReadA = new SecureDelegation({ delegate: dataOwnerA, permissions: AccessLevel.READ })\n const secureDelegationWriteB = new SecureDelegation({ delegate: dataOwnerB, permissions: AccessLevel.WRITE })\n const secureDelegationReadB = new SecureDelegation({ delegator: dataOwnerB, permissions: AccessLevel.READ })\n const secureDelegationWriteOther = new SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.WRITE })\n const secureDelegationReadOther = new SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.READ })\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: {\n [await randomHash()]: secureDelegationReadA,\n [await randomHash()]: secureDelegationWriteOther,\n [await randomHash()]: secureDelegationWriteB,\n },\n }),\n [dataOwnerA]\n )\n ).to.equal(AccessLevel.READ)\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: {\n [await randomHash()]: secureDelegationReadA,\n [await randomHash()]: secureDelegationWriteOther,\n [await randomHash()]: secureDelegationWriteB,\n },\n }),\n [dataOwnerB]\n )\n ).to.equal(AccessLevel.WRITE)\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: {\n [await randomHash()]: secureDelegationReadOther,\n [await randomHash()]: secureDelegationWriteB,\n },\n }),\n [dataOwnerA]\n )\n ).to.equal(undefined)\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: {\n [await randomHash()]: secureDelegationReadA,\n [await randomHash()]: secureDelegationWriteOther,\n [await randomHash()]: secureDelegationWriteB,\n },\n }),\n [dataOwnerA, dataOwnerB]\n )\n ).to.equal(AccessLevel.WRITE)\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: {\n [await randomHash()]: secureDelegationReadA,\n [await randomHash()]: secureDelegationReadB,\n [await randomHash()]: secureDelegationWriteOther,\n },\n }),\n [dataOwnerA, dataOwnerB]\n )\n ).to.equal(AccessLevel.READ)\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: {\n [await randomHash()]: secureDelegationWriteA,\n },\n }),\n [dataOwnerA, dataOwnerB]\n )\n ).to.equal(AccessLevel.WRITE)\n })\n\n it('should return the best access level with secure delegations accessible through hash', async function () {\n const hashA = await randomHash()\n const hashB = await randomHash()\n const secureDelegationWriteA: [string, SecureDelegation] = [hashA, new SecureDelegation({ permissions: AccessLevel.WRITE })]\n const secureDelegationReadA: [string, SecureDelegation] = [hashA, new SecureDelegation({ permissions: AccessLevel.READ })]\n const secureDelegationWriteB: [string, SecureDelegation] = [hashB, new SecureDelegation({ permissions: AccessLevel.WRITE })]\n const secureDelegationReadB: [string, SecureDelegation] = [hashB, new SecureDelegation({ permissions: AccessLevel.READ })]\n const secureDelegationWriteOther: [string, SecureDelegation] = [\n await randomHash(),\n new SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.WRITE }),\n ]\n const secureDelegationReadOther: [string, SecureDelegation] = [\n await randomHash(),\n new SecureDelegation({ delegator: primitives.randomUuid(), permissions: AccessLevel.READ }),\n ]\n\n async function testWithEntriesAndHashes(entries: [string, SecureDelegation][], hashes: string[], expectedLevel: AccessLevel | undefined) {\n await initialiseComponents()\n for (const hash of hashes) {\n exchangeData.cacheFakeData({} as any, { exchangeKey: {} as any, hashes: [hash] })\n }\n expect(\n await decryptor.getEntityAccessLevel(\n entityWithSecurityMetadata({\n secureDelegations: Object.fromEntries(entries),\n }),\n [primitives.randomUuid()]\n )\n ).to.equal(expectedLevel)\n }\n\n await testWithEntriesAndHashes([secureDelegationReadA, secureDelegationWriteB, secureDelegationWriteOther], [hashA], AccessLevel.READ)\n await testWithEntriesAndHashes([secureDelegationReadA, secureDelegationWriteB, secureDelegationWriteOther], [hashB], AccessLevel.WRITE)\n await testWithEntriesAndHashes([secureDelegationWriteB, secureDelegationReadOther], [hashA], undefined)\n await testWithEntriesAndHashes([secureDelegationReadA, secureDelegationWriteB, secureDelegationWriteOther], [hashA, hashB], AccessLevel.WRITE)\n await testWithEntriesAndHashes([secureDelegationReadA, secureDelegationReadB, secureDelegationWriteOther], [hashA, hashB], AccessLevel.READ)\n await testWithEntriesAndHashes([secureDelegationWriteA], [hashA, hashB], AccessLevel.WRITE)\n })\n})\n"]}