@icure/api 7.1.34 → 7.1.35
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/IccAuthApi.d.ts +1 -0
- package/icc-api/api/IccAuthApi.js +1 -0
- package/icc-api/api/IccAuthApi.js.map +1 -1
- package/icc-x-api/index.d.ts +22 -29
- package/icc-x-api/index.js +60 -38
- package/icc-x-api/index.js.map +1 -1
- package/package.json +1 -1
- package/test/icc-api/api/IccDocumentApi.d.ts +1 -0
- package/test/icc-api/api/IccDocumentApi.js +200 -0
- package/test/icc-api/api/IccDocumentApi.js.map +1 -0
- package/test/icc-api/api/IccGroupApi.d.ts +1 -0
- package/test/icc-api/api/IccGroupApi.js +50 -0
- package/test/icc-api/api/IccGroupApi.js.map +1 -0
- package/test/icc-api/api/IccRoleApi.d.ts +1 -0
- package/test/icc-api/api/IccRoleApi.js +34 -0
- package/test/icc-api/api/IccRoleApi.js.map +1 -0
- package/test/icc-api/api/IccUserApi.d.ts +1 -0
- package/test/icc-api/api/IccUserApi.js +80 -0
- package/test/icc-api/api/IccUserApi.js.map +1 -0
- package/test/icc-api/e2e/IccCalendarItemApi.d.ts +1 -0
- package/test/icc-api/e2e/IccCalendarItemApi.js +45 -0
- package/test/icc-api/e2e/IccCalendarItemApi.js.map +1 -0
- package/test/icc-api/model/modelHelpersTest.d.ts +1 -0
- package/test/icc-api/model/modelHelpersTest.js +45 -0
- package/test/icc-api/model/modelHelpersTest.js.map +1 -0
- package/test/icc-x-api/auth/group-switch-test.d.ts +1 -0
- package/test/icc-x-api/auth/group-switch-test.js +81 -0
- package/test/icc-x-api/auth/group-switch-test.js.map +1 -0
- package/test/icc-x-api/auth/jwt-concurrency-test.d.ts +2 -0
- package/test/icc-x-api/auth/jwt-concurrency-test.js +113 -0
- package/test/icc-x-api/auth/jwt-concurrency-test.js.map +1 -0
- package/test/icc-x-api/auth/smart-auth-provider-test.d.ts +1 -0
- package/test/icc-x-api/auth/smart-auth-provider-test.js +222 -0
- package/test/icc-x-api/auth/smart-auth-provider-test.js.map +1 -0
- package/test/icc-x-api/crypto/KeyManager-test.d.ts +1 -0
- package/test/icc-x-api/crypto/KeyManager-test.js +225 -0
- package/test/icc-x-api/crypto/KeyManager-test.js.map +1 -0
- package/test/icc-x-api/crypto/concurrency.d.ts +1 -0
- package/test/icc-x-api/crypto/concurrency.js +35 -0
- package/test/icc-x-api/crypto/concurrency.js.map +1 -0
- package/test/icc-x-api/crypto/crypto-utils.d.ts +1 -0
- package/test/icc-x-api/crypto/crypto-utils.js +80 -0
- package/test/icc-x-api/crypto/crypto-utils.js.map +1 -0
- package/test/icc-x-api/crypto/cryptoTest.d.ts +2 -0
- package/test/icc-x-api/crypto/cryptoTest.js +275 -0
- package/test/icc-x-api/crypto/cryptoTest.js.map +1 -0
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.d.ts +1 -0
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js +132 -0
- package/test/icc-x-api/crypto/delegate-ci-to-patient-with-missing-keys-test.js.map +1 -0
- package/test/icc-x-api/crypto/full-crypto-test.d.ts +1 -0
- package/test/icc-x-api/crypto/full-crypto-test.js +458 -0
- package/test/icc-x-api/crypto/full-crypto-test.js.map +1 -0
- package/test/icc-x-api/crypto/shamir.d.ts +2 -0
- package/test/icc-x-api/crypto/shamir.js +156 -0
- package/test/icc-x-api/crypto/shamir.js.map +1 -0
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.d.ts +1 -0
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js +75 -0
- package/test/icc-x-api/crypto/share-to-newly-created-patient-from-hcp.js.map +1 -0
- package/test/icc-x-api/data-compatibility-test-7to6.d.ts +1 -0
- package/test/icc-x-api/data-compatibility-test-7to6.js +343 -0
- package/test/icc-x-api/data-compatibility-test-7to6.js.map +1 -0
- package/test/icc-x-api/entity-with-attachments-api-test.d.ts +1 -0
- package/test/icc-x-api/entity-with-attachments-api-test.js +142 -0
- package/test/icc-x-api/entity-with-attachments-api-test.js.map +1 -0
- package/test/icc-x-api/filters/filters.d.ts +1 -0
- package/test/icc-x-api/filters/filters.js +49 -0
- package/test/icc-x-api/filters/filters.js.map +1 -0
- package/test/icc-x-api/icc-accesslog-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-accesslog-x-api.js +121 -0
- package/test/icc-x-api/icc-accesslog-x-api.js.map +1 -0
- package/test/icc-x-api/icc-auth-api.d.ts +1 -0
- package/test/icc-x-api/icc-auth-api.js +46 -0
- package/test/icc-x-api/icc-auth-api.js.map +1 -0
- package/test/icc-x-api/icc-calendar-item-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-calendar-item-x-api.js +146 -0
- package/test/icc-x-api/icc-calendar-item-x-api.js.map +1 -0
- package/test/icc-x-api/icc-contact-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-contact-x-api.js +311 -0
- package/test/icc-x-api/icc-contact-x-api.js.map +1 -0
- package/test/icc-x-api/icc-form-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-form-x-api.js +331 -0
- package/test/icc-x-api/icc-form-x-api.js.map +1 -0
- package/test/icc-x-api/icc-helement-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-helement-x-api-test.js +158 -0
- package/test/icc-x-api/icc-helement-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-invoice-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-invoice-x-api.js +115 -0
- package/test/icc-x-api/icc-invoice-x-api.js.map +1 -0
- package/test/icc-x-api/icc-maintenance-task-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-maintenance-task-x-api-test.js +230 -0
- package/test/icc-x-api/icc-maintenance-task-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-patient-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-patient-x-api-test.js +169 -0
- package/test/icc-x-api/icc-patient-x-api-test.js.map +1 -0
- package/test/icc-x-api/icc-time-table-x-api.d.ts +1 -0
- package/test/icc-x-api/icc-time-table-x-api.js +110 -0
- package/test/icc-x-api/icc-time-table-x-api.js.map +1 -0
- package/test/icc-x-api/icc-user-x-api-test.d.ts +1 -0
- package/test/icc-x-api/icc-user-x-api-test.js +108 -0
- package/test/icc-x-api/icc-user-x-api-test.js.map +1 -0
- package/test/icc-x-api/icureapi-group-test.d.ts +1 -0
- package/test/icc-x-api/icureapi-group-test.js +130 -0
- package/test/icc-x-api/icureapi-group-test.js.map +1 -0
- package/test/icc-x-api/patient-user.d.ts +2 -0
- package/test/icc-x-api/patient-user.js +117 -0
- package/test/icc-x-api/patient-user.js.map +1 -0
- package/test/icc-x-api/storage/storage.d.ts +1 -0
- package/test/icc-x-api/storage/storage.js +50 -0
- package/test/icc-x-api/storage/storage.js.map +1 -0
- package/test/icc-x-api/subscription-apis.d.ts +2 -0
- package/test/icc-x-api/subscription-apis.js +498 -0
- package/test/icc-x-api/subscription-apis.js.map +1 -0
- package/test/icc-x-api/test-api-no-parent.d.ts +1 -0
- package/test/icc-x-api/test-api-no-parent.js +79 -0
- package/test/icc-x-api/test-api-no-parent.js.map +1 -0
- package/test/icc-x-api/test-legacy-data-support.d.ts +1 -0
- package/test/icc-x-api/test-legacy-data-support.js +231 -0
- package/test/icc-x-api/test-legacy-data-support.js.map +1 -0
- package/test/icc-x-api/utils/crypto-utils-test.d.ts +1 -0
- package/test/icc-x-api/utils/crypto-utils-test.js +586 -0
- package/test/icc-x-api/utils/crypto-utils-test.js.map +1 -0
- package/test/icc-x-api/utils/graph-test.d.ts +1 -0
- package/test/icc-x-api/utils/graph-test.js +54 -0
- package/test/icc-x-api/utils/graph-test.js.map +1 -0
- package/test/support/CSM-185.d.ts +1 -0
- package/test/support/CSM-185.js +120 -0
- package/test/support/CSM-185.js.map +1 -0
- package/test/support/CSM-87.d.ts +0 -0
- package/test/support/CSM-87.js +21 -0
- package/test/support/CSM-87.js.map +1 -0
- package/test/support/CSM-93.d.ts +1 -0
- package/test/support/CSM-93.js +111 -0
- package/test/support/CSM-93.js.map +1 -0
- package/test/utils/TestApi.d.ts +3 -0
- package/test/utils/TestApi.js +27 -0
- package/test/utils/TestApi.js.map +1 -0
- package/test/utils/TestCollectionUtils.d.ts +1 -0
- package/test/utils/TestCollectionUtils.js +109 -0
- package/test/utils/TestCollectionUtils.js.map +1 -0
- package/test/utils/TestCryptoStrategies.d.ts +37 -0
- package/test/utils/TestCryptoStrategies.js +72 -0
- package/test/utils/TestCryptoStrategies.js.map +1 -0
- package/test/utils/TestStorage.d.ts +31 -0
- package/test/utils/TestStorage.js +88 -0
- package/test/utils/TestStorage.js.map +1 -0
- package/test/utils/test_utils.d.ts +60 -0
- package/test/utils/test_utils.js +313 -0
- package/test/utils/test_utils.js.map +1 -0
|
@@ -0,0 +1,458 @@
|
|
|
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 icc_x_api_1 = require("../../../icc-x-api");
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
const Patient_1 = require("../../../icc-api/model/Patient");
|
|
15
|
+
const Contact_1 = require("../../../icc-api/model/Contact");
|
|
16
|
+
const HealthElement_1 = require("../../../icc-api/model/HealthElement");
|
|
17
|
+
const CalendarItem_1 = require("../../../icc-api/model/CalendarItem");
|
|
18
|
+
const models_1 = require("../../../icc-api/model/models");
|
|
19
|
+
const mocha_1 = require("mocha");
|
|
20
|
+
const crypto_1 = require("crypto");
|
|
21
|
+
require("isomorphic-fetch");
|
|
22
|
+
const chai_1 = require("chai");
|
|
23
|
+
const test_utils_1 = require("../../utils/test_utils");
|
|
24
|
+
const TestApi_1 = require("../../utils/TestApi");
|
|
25
|
+
const CryptoPrimitives_1 = require("../../../icc-x-api/crypto/CryptoPrimitives");
|
|
26
|
+
const TestStorage_1 = require("../../utils/TestStorage");
|
|
27
|
+
const TestCryptoStrategies_1 = require("../../utils/TestCryptoStrategies");
|
|
28
|
+
const MaintenanceTaskAfterDateFilter_1 = require("../../../icc-x-api/filters/MaintenanceTaskAfterDateFilter");
|
|
29
|
+
const KeyPairUpdateRequest_1 = require("../../../icc-x-api/maintenance/KeyPairUpdateRequest");
|
|
30
|
+
var initMasterApi = test_utils_1.TestUtils.initMasterApi;
|
|
31
|
+
const types_1 = require("@icure/test-setup/types");
|
|
32
|
+
(0, test_utils_1.setLocalStorage)(fetch);
|
|
33
|
+
const facades = {
|
|
34
|
+
Patient: {
|
|
35
|
+
create: (api, r) => __awaiter(void 0, void 0, void 0, function* () { return api.patientApi.createPatientWithUser(yield api.userApi.getCurrentUser(), r); }),
|
|
36
|
+
get: (api, id) => __awaiter(void 0, void 0, void 0, function* () { return api.patientApi.getPatientWithUser(yield api.userApi.getCurrentUser(), id); }),
|
|
37
|
+
share: (api, p, r, doId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
const user = yield api.userApi.getCurrentUser();
|
|
39
|
+
const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user);
|
|
40
|
+
const shared = yield api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(r, doId, yield api.cryptoApi.entities.secretIdsOf(r), yield api.cryptoApi.entities.encryptionKeysOf(r), p ? [p.id] : []);
|
|
41
|
+
return shared ? api.patientApi.modifyPatientWithUser(yield api.userApi.getCurrentUser(), shared) : r;
|
|
42
|
+
}),
|
|
43
|
+
isDecrypted: (entityToCheck) => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
return entityToCheck.note != undefined;
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
Contact: {
|
|
48
|
+
create: (api, r) => __awaiter(void 0, void 0, void 0, function* () { return api.contactApi.createContactWithUser(yield api.userApi.getCurrentUser(), r); }),
|
|
49
|
+
get: (api, id) => __awaiter(void 0, void 0, void 0, function* () { return api.contactApi.getContactWithUser(yield api.userApi.getCurrentUser(), id); }),
|
|
50
|
+
share: (api, p, r, doId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
const user = yield api.userApi.getCurrentUser();
|
|
52
|
+
const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user);
|
|
53
|
+
const shared = yield api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(r, doId, yield api.cryptoApi.entities.secretIdsOf(r), yield api.cryptoApi.entities.encryptionKeysOf(r), p ? [p.id] : []);
|
|
54
|
+
return shared ? api.contactApi.modifyContactWithUser(yield api.userApi.getCurrentUser(), shared) : r;
|
|
55
|
+
}),
|
|
56
|
+
isDecrypted: (entityToCheck) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
return ((_a = entityToCheck.services) === null || _a === void 0 ? void 0 : _a[0].content) != undefined && Object.entries((_b = entityToCheck.services) === null || _b === void 0 ? void 0 : _b[0].content).length > 0;
|
|
59
|
+
}),
|
|
60
|
+
},
|
|
61
|
+
HealthElement: {
|
|
62
|
+
create: (api, r) => __awaiter(void 0, void 0, void 0, function* () { return api.healthcareElementApi.createHealthElementWithUser(yield api.userApi.getCurrentUser(), r); }),
|
|
63
|
+
get: (api, id) => __awaiter(void 0, void 0, void 0, function* () { return api.healthcareElementApi.getHealthElementWithUser(yield api.userApi.getCurrentUser(), id); }),
|
|
64
|
+
share: (api, p, r, doId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
const user = yield api.userApi.getCurrentUser();
|
|
66
|
+
const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user);
|
|
67
|
+
const shared = yield api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(r, doId, yield api.cryptoApi.entities.secretIdsOf(r), yield api.cryptoApi.entities.encryptionKeysOf(r), p ? [p.id] : []);
|
|
68
|
+
return shared ? api.healthcareElementApi.modifyHealthElementWithUser(yield api.userApi.getCurrentUser(), shared) : r;
|
|
69
|
+
}),
|
|
70
|
+
isDecrypted: (entityToCheck) => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
return entityToCheck.descr != undefined;
|
|
72
|
+
}),
|
|
73
|
+
},
|
|
74
|
+
CalendarItem: {
|
|
75
|
+
create: (api, r) => __awaiter(void 0, void 0, void 0, function* () { return api.calendarItemApi.createCalendarItemWithHcParty(yield api.userApi.getCurrentUser(), r); }),
|
|
76
|
+
get: (api, id) => __awaiter(void 0, void 0, void 0, function* () { return api.calendarItemApi.getCalendarItemWithUser(yield api.userApi.getCurrentUser(), id); }),
|
|
77
|
+
share: (api, p, r, doId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
const user = yield api.userApi.getCurrentUser();
|
|
79
|
+
const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user);
|
|
80
|
+
const shared = yield api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(r, doId, yield api.cryptoApi.entities.secretIdsOf(r), yield api.cryptoApi.entities.encryptionKeysOf(r), p ? [p.id] : []);
|
|
81
|
+
return shared ? api.calendarItemApi.modifyCalendarItemWithHcParty(yield api.userApi.getCurrentUser(), shared) : r;
|
|
82
|
+
}),
|
|
83
|
+
isDecrypted: (entityToCheck) => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
return entityToCheck.title != undefined;
|
|
85
|
+
}),
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
const patientFacades = Object.entries(facades)
|
|
89
|
+
.filter((f) => f[0] !== 'Patient')
|
|
90
|
+
.reduce((prev, curr) => (Object.assign(Object.assign({}, prev), { [curr[0]]: curr[1] })), {});
|
|
91
|
+
const users = [];
|
|
92
|
+
const primitives = new CryptoPrimitives_1.CryptoPrimitives(crypto_1.webcrypto);
|
|
93
|
+
let delegateUser = undefined;
|
|
94
|
+
let delegateHcp = undefined;
|
|
95
|
+
let delegateHcpPassword = undefined;
|
|
96
|
+
let userGivingAccessBack = undefined;
|
|
97
|
+
let userGivingAccessBackPassword = undefined;
|
|
98
|
+
let hcpGivingAccessBack = undefined;
|
|
99
|
+
const entities = {
|
|
100
|
+
Patient: ({ patientApi }, id, user, _, delegateIds) => {
|
|
101
|
+
return patientApi.newInstance(user, new Patient_1.Patient({ id, firstName: 'test', lastName: 'test', note: 'data', dateOfBirth: 20000101 }), {
|
|
102
|
+
additionalDelegates: Object.fromEntries((delegateIds !== null && delegateIds !== void 0 ? delegateIds : []).map((id) => [id, 'WRITE'])),
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
Contact: ({ contactApi }, id, user, patient, delegateIds) => {
|
|
106
|
+
return contactApi.newInstance(user, patient, new Contact_1.Contact({ id, services: [new models_1.Service({ label: 'svc', content: { fr: { stringValue: 'data' } } })] }), {
|
|
107
|
+
confidential: false,
|
|
108
|
+
additionalDelegates: Object.fromEntries((delegateIds !== null && delegateIds !== void 0 ? delegateIds : []).map((id) => [id, 'WRITE'])),
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
HealthElement: ({ healthcareElementApi }, id, user, patient, delegateIds) => {
|
|
112
|
+
return healthcareElementApi.newInstance(user, patient, new HealthElement_1.HealthElement({ id, descr: 'HE' }), {
|
|
113
|
+
confidential: false,
|
|
114
|
+
additionalDelegates: Object.fromEntries((delegateIds !== null && delegateIds !== void 0 ? delegateIds : []).map((id) => [id, 'WRITE'])),
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
CalendarItem: ({ calendarItemApi }, id, user, patient, delegateIds) => {
|
|
118
|
+
return calendarItemApi.newInstancePatient(user, patient, new CalendarItem_1.CalendarItem({ id, title: 'CI' }), {
|
|
119
|
+
additionalDelegates: Object.fromEntries((delegateIds !== null && delegateIds !== void 0 ? delegateIds : []).map((id) => [id, 'WRITE'])),
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
const userDefinitions = {
|
|
124
|
+
'one available key and one lost key recoverable through transfer keys': (user, password, originalKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
+
const newKey = yield primitives.RSA.generateKeyPair();
|
|
126
|
+
const apiWithOnlyNewKey = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: user.login, password }, new TestCryptoStrategies_1.TestCryptoStrategies(newKey, {
|
|
127
|
+
[(0, icc_x_api_1.ua2hex)(yield primitives.RSA.exportKey(originalKey.publicKey, 'spki')).slice(-32)]: true,
|
|
128
|
+
}), crypto_1.webcrypto, fetch, {
|
|
129
|
+
storage: new TestStorage_1.TestStorage(),
|
|
130
|
+
keyStorage: new TestStorage_1.TestKeyStorage(),
|
|
131
|
+
});
|
|
132
|
+
const apis = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: user.login, password }, new TestCryptoStrategies_1.TestCryptoStrategies(originalKey, {
|
|
133
|
+
[(0, icc_x_api_1.ua2hex)(yield primitives.RSA.exportKey(newKey.publicKey, 'spki')).slice(-32)]: true,
|
|
134
|
+
}), crypto_1.webcrypto, fetch, {
|
|
135
|
+
storage: new TestStorage_1.TestStorage(),
|
|
136
|
+
keyStorage: new TestStorage_1.TestKeyStorage(),
|
|
137
|
+
});
|
|
138
|
+
(0, chai_1.expect)(Object.keys(apis.cryptoApi.userKeysManager.getDecryptionKeys())).to.have.length(2);
|
|
139
|
+
return { user, apis, didLoseKey: false };
|
|
140
|
+
}),
|
|
141
|
+
'two available keys': (user, password, originalKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
142
|
+
var _c;
|
|
143
|
+
const newKey = yield primitives.RSA.generateKeyPair();
|
|
144
|
+
const apiWithOnlyNewKey = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: user.login, password }, new TestCryptoStrategies_1.TestCryptoStrategies(newKey), crypto_1.webcrypto, fetch, {
|
|
145
|
+
storage: new TestStorage_1.TestStorage(),
|
|
146
|
+
keyStorage: new TestStorage_1.TestKeyStorage(),
|
|
147
|
+
});
|
|
148
|
+
const keyStrings = yield Promise.all([originalKey, newKey].map((pair) => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
|
+
return ({
|
|
150
|
+
publicKey: (0, icc_x_api_1.ua2hex)(yield primitives.RSA.exportKey(pair.publicKey, 'spki')),
|
|
151
|
+
privateKey: (0, icc_x_api_1.ua2hex)(yield primitives.RSA.exportKey(pair.privateKey, 'pkcs8')),
|
|
152
|
+
});
|
|
153
|
+
})));
|
|
154
|
+
const storage = yield (0, TestStorage_1.testStorageWithKeys)([{ dataOwnerId: (_c = user.healthcarePartyId) !== null && _c !== void 0 ? _c : user.patientId, pairs: keyStrings }]);
|
|
155
|
+
const apis = yield icc_x_api_1.IcureApi.initialise(env.iCureUrl, { username: user.login, password }, new TestCryptoStrategies_1.TestCryptoStrategies(), crypto_1.webcrypto, fetch, {
|
|
156
|
+
storage: storage.storage,
|
|
157
|
+
keyStorage: storage.keyStorage,
|
|
158
|
+
entryKeysFactory: storage.keyFactory,
|
|
159
|
+
});
|
|
160
|
+
return { user, apis, didLoseKey: false };
|
|
161
|
+
}),
|
|
162
|
+
'a single available key in old format': (user, password, originalKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
163
|
+
return ({
|
|
164
|
+
user,
|
|
165
|
+
apis: yield (0, TestApi_1.TestApi)(env.iCureUrl, user.login, password, crypto_1.webcrypto, originalKey),
|
|
166
|
+
didLoseKey: false,
|
|
167
|
+
});
|
|
168
|
+
}),
|
|
169
|
+
'one lost key and one available key': (user, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
170
|
+
const newKeyPair = yield primitives.RSA.generateKeyPair();
|
|
171
|
+
const apis = yield (0, TestApi_1.TestApi)(env.iCureUrl, user.login, password, crypto_1.webcrypto, newKeyPair);
|
|
172
|
+
yield apis.icureMaintenanceTaskApi.createMaintenanceTasksForNewKeypair(user, newKeyPair);
|
|
173
|
+
return { user, apis, didLoseKey: true };
|
|
174
|
+
}),
|
|
175
|
+
'one lost key and one upgraded available key thanks to delegate who gave access back to previous data': (user, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
176
|
+
const newKeyPair = yield primitives.RSA.generateKeyPair();
|
|
177
|
+
const api = yield (0, TestApi_1.TestApi)(env.iCureUrl, user.login, password, crypto_1.webcrypto, newKeyPair);
|
|
178
|
+
yield api.icureMaintenanceTaskApi.createMaintenanceTasksForNewKeypair(user, newKeyPair);
|
|
179
|
+
const giveAccessBackApi = apis['givingAccessBack'];
|
|
180
|
+
const keyPairUpdateRequests = (yield giveAccessBackApi.maintenanceTaskApi.filterMaintenanceTasksByWithUser(userGivingAccessBack, undefined, undefined, new models_1.FilterChainMaintenanceTask({
|
|
181
|
+
filter: new MaintenanceTaskAfterDateFilter_1.MaintenanceTaskAfterDateFilter({
|
|
182
|
+
date: new Date().getTime() - 100000,
|
|
183
|
+
}),
|
|
184
|
+
}))).rows.map((x) => KeyPairUpdateRequest_1.KeyPairUpdateRequest.fromMaintenanceTask(x));
|
|
185
|
+
const concernedRequest = keyPairUpdateRequests.find((x) => { var _a; return x.concernedDataOwnerId === ((_a = user.healthcarePartyId) !== null && _a !== void 0 ? _a : user.patientId); });
|
|
186
|
+
if (!concernedRequest)
|
|
187
|
+
throw new Error('Could not find maintenance task');
|
|
188
|
+
yield giveAccessBackApi.icureMaintenanceTaskApi.applyKeyPairUpdate(concernedRequest);
|
|
189
|
+
yield api.cryptoApi.forceReload();
|
|
190
|
+
return { user, apis: api, didLoseKey: true };
|
|
191
|
+
}),
|
|
192
|
+
};
|
|
193
|
+
function createPartialsForHcp(entityFacades, entityCreators, user, password) {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
+
const key = yield primitives.RSA.generateKeyPair();
|
|
196
|
+
const api1 = yield (0, TestApi_1.TestApi)(env.iCureUrl, user.login, password, crypto_1.webcrypto, key);
|
|
197
|
+
yield Object.entries(entityFacades).reduce((p, f) => __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
yield p;
|
|
199
|
+
const type = f[0];
|
|
200
|
+
const facade = f[1];
|
|
201
|
+
const parent = type !== 'Patient' ? yield api1.patientApi.getPatientWithUser(user, `partial-${user.id}-Patient`) : undefined;
|
|
202
|
+
const record = yield entityCreators[type](api1, `partial-${user.id}-${type}`, user, parent, [hcpGivingAccessBack.id]);
|
|
203
|
+
yield facade.create(api1, record);
|
|
204
|
+
}), Promise.resolve());
|
|
205
|
+
return key;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
function createPartialsForPatient(entityFacades, entityCreators, user, password, patientCreatorUser, patientCreatorApis) {
|
|
209
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
210
|
+
const key = yield primitives.RSA.generateKeyPair();
|
|
211
|
+
const api1 = yield (0, TestApi_1.TestApi)(env.iCureUrl, user.login, password, crypto_1.webcrypto, key);
|
|
212
|
+
const pat = yield patientCreatorApis.patientApi.getPatientWithUser(patientCreatorUser, user.patientId);
|
|
213
|
+
yield patientCreatorApis.patientApi.modifyPatientWithUser(patientCreatorUser, yield patientCreatorApis.cryptoApi.entities.entityWithExtendedEncryptedMetadata(pat, user.patientId, yield patientCreatorApis.cryptoApi.entities.secretIdsOf(pat), yield patientCreatorApis.cryptoApi.entities.encryptionKeysOf(pat), []));
|
|
214
|
+
yield Object.entries(entityFacades)
|
|
215
|
+
.filter((it) => it[0] !== 'Patient')
|
|
216
|
+
.reduce((p, f) => __awaiter(this, void 0, void 0, function* () {
|
|
217
|
+
yield p;
|
|
218
|
+
const type = f[0];
|
|
219
|
+
const facade = f[1];
|
|
220
|
+
const parent = yield api1.patientApi.getPatientWithUser(user, user.patientId);
|
|
221
|
+
const record = yield entityCreators[type](api1, `partial-${user.id}-${type}`, user, parent, [hcpGivingAccessBack.id]);
|
|
222
|
+
yield facade.create(api1, record);
|
|
223
|
+
}), Promise.resolve());
|
|
224
|
+
return key;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
let env;
|
|
228
|
+
let apis;
|
|
229
|
+
(0, mocha_1.describe)('Full crypto test - Creation scenarios', function () {
|
|
230
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
+
(0, mocha_1.before)(function () {
|
|
232
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
233
|
+
this.timeout(6000000);
|
|
234
|
+
const initializer = yield (0, test_utils_1.getEnvironmentInitializer)();
|
|
235
|
+
env = yield initializer.execute((0, types_1.getEnvVariables)());
|
|
236
|
+
const api = yield initMasterApi(env);
|
|
237
|
+
const user = yield api.userApi.getCurrentUser();
|
|
238
|
+
const dataOwnerId = api.dataOwnerApi.getDataOwnerIdOf(user);
|
|
239
|
+
const { userApi, patientApi, healthcarePartyApi, cryptoApi } = api;
|
|
240
|
+
delegateHcp = yield healthcarePartyApi.createHealthcareParty(new models_1.HealthcareParty({ id: (0, uuid_1.v4)(), firstName: 'test', lastName: 'test' }));
|
|
241
|
+
delegateUser = yield userApi.createUser(new models_1.User({
|
|
242
|
+
id: `user-${(0, uuid_1.v4)()}-hcp`,
|
|
243
|
+
login: `hcp-delegate-${(0, uuid_1.v4)()}`,
|
|
244
|
+
status: 'ACTIVE',
|
|
245
|
+
healthcarePartyId: delegateHcp.id,
|
|
246
|
+
}));
|
|
247
|
+
delegateHcpPassword = yield userApi.getToken(delegateUser.id, (0, uuid_1.v4)());
|
|
248
|
+
hcpGivingAccessBack = yield healthcarePartyApi.createHealthcareParty(new models_1.HealthcareParty({ id: (0, uuid_1.v4)(), firstName: 'test', lastName: 'test' }));
|
|
249
|
+
userGivingAccessBack = yield userApi.createUser(new models_1.User({
|
|
250
|
+
id: `user-${(0, uuid_1.v4)()}-hcp`,
|
|
251
|
+
login: `hcp-giving-access-back-${(0, uuid_1.v4)()}`,
|
|
252
|
+
status: 'ACTIVE',
|
|
253
|
+
healthcarePartyId: hcpGivingAccessBack.id,
|
|
254
|
+
}));
|
|
255
|
+
userGivingAccessBackPassword = yield userApi.getToken(userGivingAccessBack.id, (0, uuid_1.v4)());
|
|
256
|
+
apis = {
|
|
257
|
+
delegate: yield (0, TestApi_1.TestApi)(env.iCureUrl, delegateUser.login, delegateHcpPassword, crypto_1.webcrypto),
|
|
258
|
+
givingAccessBack: yield (0, TestApi_1.TestApi)(env.iCureUrl, userGivingAccessBack.login, userGivingAccessBackPassword, crypto_1.webcrypto),
|
|
259
|
+
};
|
|
260
|
+
yield Object.entries(userDefinitions).reduce((p, [login, creationProcess]) => __awaiter(this, void 0, void 0, function* () {
|
|
261
|
+
yield p;
|
|
262
|
+
const newPatientEmail = (0, test_utils_1.getTempEmail)();
|
|
263
|
+
const patientToCreate = yield patientApi.newInstance(user, new Patient_1.Patient({ id: (0, uuid_1.v4)(), firstName: 'test', lastName: 'test' }));
|
|
264
|
+
const patient = yield patientApi.createPatientWithUser(user, patientToCreate);
|
|
265
|
+
const newHcpEmail = (0, test_utils_1.getTempEmail)();
|
|
266
|
+
const hcp = yield healthcarePartyApi.createHealthcareParty(new models_1.HealthcareParty({ id: (0, uuid_1.v4)(), firstName: 'test', lastName: 'test' }));
|
|
267
|
+
const newPatientUser = yield userApi.createUser(new models_1.User({
|
|
268
|
+
id: `user-${(0, uuid_1.v4)()}-patient`,
|
|
269
|
+
name: `patient-${login}`,
|
|
270
|
+
login: newPatientEmail,
|
|
271
|
+
email: newPatientEmail,
|
|
272
|
+
status: 'ACTIVE',
|
|
273
|
+
patientId: patient.id,
|
|
274
|
+
}));
|
|
275
|
+
const newPatientUserPassword = yield userApi.getToken(newPatientUser.id, (0, uuid_1.v4)());
|
|
276
|
+
const newHcpUser = yield userApi.createUser(new models_1.User({
|
|
277
|
+
id: `user-${(0, uuid_1.v4)()}-hcp`,
|
|
278
|
+
login: newHcpEmail,
|
|
279
|
+
email: newHcpEmail,
|
|
280
|
+
name: `hcp-${login}`,
|
|
281
|
+
status: 'ACTIVE',
|
|
282
|
+
healthcarePartyId: hcp.id,
|
|
283
|
+
}));
|
|
284
|
+
const newHcpUserPassword = yield userApi.getToken(newHcpUser.id, (0, uuid_1.v4)());
|
|
285
|
+
const originalKeyPat = yield createPartialsForPatient(facades, entities, newPatientUser, newPatientUserPassword, user, api);
|
|
286
|
+
const originalKeyHcp = yield createPartialsForHcp(facades, entities, newHcpUser, newHcpUserPassword);
|
|
287
|
+
const patDetails = yield creationProcess(newPatientUser, newPatientUserPassword, originalKeyPat);
|
|
288
|
+
const hcpDetails = yield creationProcess(newHcpUser, newHcpUserPassword, originalKeyHcp);
|
|
289
|
+
users.push({ user: patDetails.user, password: newPatientUserPassword });
|
|
290
|
+
apis[patDetails.user.name] = patDetails.apis;
|
|
291
|
+
users.push({ user: hcpDetails.user, password: newHcpUserPassword });
|
|
292
|
+
apis[hcpDetails.user.name] = hcpDetails.apis;
|
|
293
|
+
// Give access back to own sfks of patient
|
|
294
|
+
if (patDetails.didLoseKey) {
|
|
295
|
+
const keyPairUpdateRequests = (yield api.maintenanceTaskApi.filterMaintenanceTasksByWithUser(user, undefined, undefined, new models_1.FilterChainMaintenanceTask({
|
|
296
|
+
filter: new MaintenanceTaskAfterDateFilter_1.MaintenanceTaskAfterDateFilter({
|
|
297
|
+
date: new Date().getTime() - 100000,
|
|
298
|
+
}),
|
|
299
|
+
}))).rows.map((x) => KeyPairUpdateRequest_1.KeyPairUpdateRequest.fromMaintenanceTask(x));
|
|
300
|
+
const dataOwnerWithLostKey = newPatientUser.patientId;
|
|
301
|
+
const concernedRequest = keyPairUpdateRequests.find((x) => x.concernedDataOwnerId === dataOwnerWithLostKey);
|
|
302
|
+
if (!concernedRequest)
|
|
303
|
+
throw new Error('Could not find maintenance task to regive access back to own sfks');
|
|
304
|
+
yield api.icureMaintenanceTaskApi.applyKeyPairUpdate(concernedRequest);
|
|
305
|
+
yield patDetails.apis.cryptoApi.forceReload();
|
|
306
|
+
}
|
|
307
|
+
}), Promise.resolve());
|
|
308
|
+
yield users
|
|
309
|
+
.filter((it) => it.user.id.endsWith('patient'))
|
|
310
|
+
.map((it) => it.user)
|
|
311
|
+
.reduce((prev, it) => __awaiter(this, void 0, void 0, function* () {
|
|
312
|
+
yield prev;
|
|
313
|
+
const otherUsers = users.filter((u) => u.user.id.endsWith('patient') && u.user.id !== it.id).map((u) => u.user);
|
|
314
|
+
yield otherUsers.reduce((p, u) => __awaiter(this, void 0, void 0, function* () {
|
|
315
|
+
var _a;
|
|
316
|
+
yield p;
|
|
317
|
+
const patientToShare = yield facades.Patient.get(api, it.patientId);
|
|
318
|
+
const sharedPatient = yield facades.Patient.share(api, null, patientToShare, u.patientId);
|
|
319
|
+
(0, chai_1.expect)(Object.keys((_a = sharedPatient.delegations) !== null && _a !== void 0 ? _a : {})).to.contain(u.patientId);
|
|
320
|
+
return Promise.resolve();
|
|
321
|
+
}), Promise.resolve());
|
|
322
|
+
return Promise.resolve();
|
|
323
|
+
}), Promise.resolve());
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
['patient', 'hcp'].forEach((uType) => {
|
|
327
|
+
Object.keys(userDefinitions).forEach((uId) => {
|
|
328
|
+
Object.entries(facades).forEach((f) => {
|
|
329
|
+
(0, mocha_1.it)(`Create ${f[0]} as a ${uType} with ${uId}`, function () {
|
|
330
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
331
|
+
if (f[0] === 'Patient' && uType === 'patient') {
|
|
332
|
+
this.skip();
|
|
333
|
+
}
|
|
334
|
+
const { user } = users.find((it) => it.user.name === `${uType}-${uId}`);
|
|
335
|
+
const facade = f[1];
|
|
336
|
+
const api = apis[`${uType}-${uId}`];
|
|
337
|
+
const parent = f[0] !== 'Patient'
|
|
338
|
+
? uType === 'patient'
|
|
339
|
+
? yield api.patientApi.getPatientWithUser(user, user.patientId)
|
|
340
|
+
: yield api.patientApi.getPatientWithUser(user, `${user.id}-Patient`)
|
|
341
|
+
: undefined;
|
|
342
|
+
const record = yield entities[f[0]](api, `${user.id}-${f[0]}`, user, parent);
|
|
343
|
+
const entity = yield facade.create(api, record);
|
|
344
|
+
const retrieved = yield facade.get(api, entity.id);
|
|
345
|
+
(0, chai_1.expect)(entity.id).to.be.not.null;
|
|
346
|
+
(0, chai_1.expect)(entity.rev).to.equal(retrieved.rev);
|
|
347
|
+
(0, chai_1.expect)(yield facade.isDecrypted(entity)).to.equal(true);
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
(0, mocha_1.it)(`Create ${f[0]} as delegate with delegation for ${uType} with ${uId}`, function () {
|
|
351
|
+
var _a, _b;
|
|
352
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
353
|
+
const { user } = users.find((it) => it.user.name === `${uType}-${uId}`);
|
|
354
|
+
const facade = f[1];
|
|
355
|
+
const api = apis['delegate'];
|
|
356
|
+
const patApi = apis[`${uType}-${uId}`];
|
|
357
|
+
const dataOwnerId = api.dataOwnerApi.getDataOwnerIdOf(user);
|
|
358
|
+
const dataOwner = (yield patApi.dataOwnerApi.getCryptoActorStub(dataOwnerId)).stub;
|
|
359
|
+
const parent = f[0] !== 'Patient' ? yield api.patientApi.getPatientWithUser(delegateUser, `delegate-${user.id}-Patient`) : undefined;
|
|
360
|
+
const record = yield entities[f[0]](api, `delegate-${user.id}-${f[0]}`, delegateUser, parent, [
|
|
361
|
+
((_b = (_a = user.patientId) !== null && _a !== void 0 ? _a : user.healthcarePartyId) !== null && _b !== void 0 ? _b : user.deviceId),
|
|
362
|
+
]);
|
|
363
|
+
const entity = yield facade.create(api, record);
|
|
364
|
+
const retrieved = yield facade.get(api, entity.id);
|
|
365
|
+
const hcp = yield api.healthcarePartyApi.getCurrentHealthcareParty();
|
|
366
|
+
const shareKeys = hcp.aesExchangeKeys[hcp.publicKey][dataOwnerId];
|
|
367
|
+
if (Object.keys(shareKeys).length > 2) {
|
|
368
|
+
delete shareKeys[dataOwner.publicKey.slice(-32)];
|
|
369
|
+
}
|
|
370
|
+
hcp.aesExchangeKeys = Object.assign(Object.assign({}, hcp.aesExchangeKeys), { [hcp.publicKey]: Object.assign(Object.assign({}, hcp.aesExchangeKeys[hcp.publicKey]), { [dataOwnerId]: shareKeys }) });
|
|
371
|
+
yield api.healthcarePartyApi.modifyHealthcareParty(hcp);
|
|
372
|
+
(0, chai_1.expect)(entity.id).to.be.not.null;
|
|
373
|
+
(0, chai_1.expect)(entity.rev).to.equal(retrieved.rev);
|
|
374
|
+
(0, chai_1.expect)(yield facade.isDecrypted(entity)).to.equal(true);
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
(0, mocha_1.describe)('Full crypto test - Read/Share scenarios', function () {
|
|
383
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
384
|
+
;
|
|
385
|
+
['patient', 'hcp'].forEach((uType) => {
|
|
386
|
+
Object.keys(userDefinitions).forEach((uId) => {
|
|
387
|
+
Object.entries(facades).forEach((f) => {
|
|
388
|
+
(0, mocha_1.it)(`Read ${f[0]} as the initial ${uType} with ${uId}`, function () {
|
|
389
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
390
|
+
if (f[0] === 'Patient' && uType === 'patient') {
|
|
391
|
+
this.skip();
|
|
392
|
+
}
|
|
393
|
+
const { user } = users.find((it) => it.user.name === `${uType}-${uId}`);
|
|
394
|
+
const facade = f[1];
|
|
395
|
+
const api = apis[`${uType}-${uId}`];
|
|
396
|
+
const entity = yield facade.get(api, `partial-${user.id}-${f[0]}`);
|
|
397
|
+
(0, chai_1.expect)(entity.id).to.equal(`partial-${user.id}-${f[0]}`);
|
|
398
|
+
(0, chai_1.expect)(yield facade.isDecrypted(entity)).to.equal(!uId.includes('one lost key and one available key') /* data shared only with lost key... So false */);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
(0, mocha_1.it)(`Read ${f[0]} as a ${uType} with ${uId}`, function () {
|
|
402
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
403
|
+
if (f[0] === 'Patient' && uType === 'patient') {
|
|
404
|
+
this.skip();
|
|
405
|
+
}
|
|
406
|
+
const { user } = users.find((it) => it.user.name === `${uType}-${uId}`);
|
|
407
|
+
const facade = f[1];
|
|
408
|
+
const api = apis[`${uType}-${uId}`];
|
|
409
|
+
const entity = yield facade.get(api, `${user.id}-${f[0]}`);
|
|
410
|
+
(0, chai_1.expect)(entity.id).to.equal(`${user.id}-${f[0]}`);
|
|
411
|
+
(0, chai_1.expect)(yield facade.isDecrypted(entity)).to.equal(true);
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
(0, mocha_1.it)(`Read ${f[0]} shared by delegate as a ${uType} with ${uId}`, () => __awaiter(this, void 0, void 0, function* () {
|
|
415
|
+
const { user } = users.find((it) => it.user.name === `${uType}-${uId}`);
|
|
416
|
+
const facade = f[1];
|
|
417
|
+
const api = apis[`${uType}-${uId}`];
|
|
418
|
+
const entity = yield facade.get(api, `delegate-${user.id}-${f[0]}`);
|
|
419
|
+
(0, chai_1.expect)(entity.id).to.equal(`delegate-${user.id}-${f[0]}`);
|
|
420
|
+
(0, chai_1.expect)(yield facade.isDecrypted(entity)).to.equal(true);
|
|
421
|
+
}));
|
|
422
|
+
['patient', 'hcp'].forEach((duType) => {
|
|
423
|
+
Object.keys(userDefinitions).forEach((duId) => {
|
|
424
|
+
(0, mocha_1.it)(`Share ${f[0]} as a ${uType} with ${uId} to a ${duType} with ${duId}`, function () {
|
|
425
|
+
var _a;
|
|
426
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
427
|
+
if (f[0] === 'Patient' && uType === 'patient') {
|
|
428
|
+
this.skip();
|
|
429
|
+
}
|
|
430
|
+
const { user } = users.find((it) => it.user.name === `${uType}-${uId}`);
|
|
431
|
+
const { user: delUser } = users.find((it) => it.user.name === `${duType}-${duId}`);
|
|
432
|
+
const delegateDoId = (_a = delUser.healthcarePartyId) !== null && _a !== void 0 ? _a : delUser.patientId;
|
|
433
|
+
const facade = f[1];
|
|
434
|
+
const api = apis[`${uType}-${uId}`];
|
|
435
|
+
const delApi = apis[`${duType}-${duId}`];
|
|
436
|
+
const parent = f[0] !== 'Patient'
|
|
437
|
+
? uType === 'patient'
|
|
438
|
+
? yield api.patientApi.getPatientWithUser(user, user.patientId)
|
|
439
|
+
: yield api.patientApi.getPatientWithUser(user, `${user.id}-Patient`)
|
|
440
|
+
: undefined;
|
|
441
|
+
const retrievedEntity = yield facade.get(api, `${user.id}-${f[0]}`);
|
|
442
|
+
const entity = yield facade.share(api, parent, retrievedEntity, delegateDoId);
|
|
443
|
+
const retrieved = yield facade.get(api, entity.id);
|
|
444
|
+
(0, chai_1.expect)(entity.rev).to.equal(retrieved.rev);
|
|
445
|
+
(0, chai_1.expect)(Object.keys(entity.delegations)).to.contain(delegateDoId);
|
|
446
|
+
const obj = yield facade.get(delApi, `${user.id}-${f[0]}`);
|
|
447
|
+
(0, chai_1.expect)(Object.keys(obj.delegations)).to.contain(delegateDoId);
|
|
448
|
+
(0, chai_1.expect)(yield facade.isDecrypted(obj)).to.equal(true);
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
//# sourceMappingURL=full-crypto-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-crypto-test.js","sourceRoot":"","sources":["../../../../test/icc-x-api/crypto/full-crypto-test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Apis, IcureApi, ua2hex } from '../../../icc-x-api'\nimport { v4 as uuid } from 'uuid'\nimport { Patient } from '../../../icc-api/model/Patient'\nimport { Contact } from '../../../icc-api/model/Contact'\nimport { HealthElement } from '../../../icc-api/model/HealthElement'\nimport { CalendarItem } from '../../../icc-api/model/CalendarItem'\nimport { EncryptedEntity, EncryptedParentEntity, FilterChainMaintenanceTask, HealthcareParty, Service, User } from '../../../icc-api/model/models'\nimport { before, describe, it } from 'mocha'\n\nimport { webcrypto } from 'crypto'\nimport 'isomorphic-fetch'\n\nimport { expect } from 'chai'\nimport { getEnvironmentInitializer, getTempEmail, setLocalStorage, TestUtils } from '../../utils/test_utils'\nimport { TestApi } from '../../utils/TestApi'\nimport { KeyPair } from '../../../icc-x-api/crypto/RSA'\nimport { CryptoPrimitives } from '../../../icc-x-api/crypto/CryptoPrimitives'\nimport { TestKeyStorage, TestStorage, testStorageWithKeys } from '../../utils/TestStorage'\nimport { TestCryptoStrategies } from '../../utils/TestCryptoStrategies'\nimport { MaintenanceTaskAfterDateFilter } from '../../../icc-x-api/filters/MaintenanceTaskAfterDateFilter'\nimport { KeyPairUpdateRequest } from '../../../icc-x-api/maintenance/KeyPairUpdateRequest'\nimport initMasterApi = TestUtils.initMasterApi\nimport { getEnvVariables, TestVars } from '@icure/test-setup/types'\n\nsetLocalStorage(fetch)\n\ntype TestedEntity = 'Patient' | 'Contact' | 'HealthElement' | 'CalendarItem'\n\ninterface EntityFacade<T extends EncryptedEntity> {\n create: (api: Apis, record: Omit<T, 'rev'>) => Promise<T>\n get: (api: Apis, id: string) => Promise<T>\n share: (api: Apis, parent: EncryptedParentEntity | null, record: T, dataOwnerId: string) => Promise<T>\n isDecrypted: (entityToCheck: T) => Promise<boolean>\n}\n\ntype EntityCreator<T> = (api: Apis, id: string, user: User, patient?: Patient, delegateIds?: string[]) => Promise<T>\n\ninterface EntityFacades {\n Patient: EntityFacade<Patient>\n Contact: EntityFacade<Contact>\n HealthElement: EntityFacade<HealthElement>\n CalendarItem: EntityFacade<CalendarItem>\n}\n\ninterface EntityCreators {\n Patient: EntityCreator<Patient>\n Contact: EntityCreator<Contact>\n HealthElement: EntityCreator<HealthElement>\n CalendarItem: EntityCreator<CalendarItem>\n}\n\nconst facades: EntityFacades = {\n Patient: {\n create: async (api, r) => api.patientApi.createPatientWithUser(await api.userApi.getCurrentUser(), r),\n get: async (api, id) => api.patientApi.getPatientWithUser(await api.userApi.getCurrentUser(), id),\n share: async (api, p, r, doId) => {\n const user = await api.userApi.getCurrentUser()\n const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user)\n const shared = await api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(\n r,\n doId,\n await api.cryptoApi.entities.secretIdsOf(r),\n await api.cryptoApi.entities.encryptionKeysOf(r),\n p ? [p.id!] : []\n )\n return shared ? api.patientApi.modifyPatientWithUser(await api.userApi.getCurrentUser(), shared) : r\n },\n isDecrypted: async (entityToCheck) => {\n return entityToCheck.note != undefined\n },\n } as EntityFacade<Patient>,\n Contact: {\n create: async (api, r) => api.contactApi.createContactWithUser(await api.userApi.getCurrentUser(), r),\n get: async (api, id) => api.contactApi.getContactWithUser(await api.userApi.getCurrentUser(), id),\n share: async (api, p, r, doId) => {\n const user = await api.userApi.getCurrentUser()\n const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user)\n const shared = await api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(\n r,\n doId,\n await api.cryptoApi.entities.secretIdsOf(r),\n await api.cryptoApi.entities.encryptionKeysOf(r),\n p ? [p.id!] : []\n )\n return shared ? api.contactApi.modifyContactWithUser(await api.userApi.getCurrentUser(), shared) : r\n },\n isDecrypted: async (entityToCheck) => {\n return entityToCheck.services?.[0].content != undefined && Object.entries(entityToCheck.services?.[0].content).length > 0\n },\n } as EntityFacade<Contact>,\n HealthElement: {\n create: async (api, r) => api.healthcareElementApi.createHealthElementWithUser(await api.userApi.getCurrentUser(), r),\n get: async (api, id) => api.healthcareElementApi.getHealthElementWithUser(await api.userApi.getCurrentUser(), id),\n share: async (api, p, r, doId) => {\n const user = await api.userApi.getCurrentUser()\n const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user)\n const shared = await api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(\n r,\n doId,\n await api.cryptoApi.entities.secretIdsOf(r),\n await api.cryptoApi.entities.encryptionKeysOf(r),\n p ? [p.id!] : []\n )\n return shared ? api.healthcareElementApi.modifyHealthElementWithUser(await api.userApi.getCurrentUser(), shared) : r\n },\n isDecrypted: async (entityToCheck) => {\n return entityToCheck.descr != undefined\n },\n } as EntityFacade<HealthElement>,\n CalendarItem: {\n create: async (api, r) => api.calendarItemApi.createCalendarItemWithHcParty(await api.userApi.getCurrentUser(), r),\n get: async (api, id) => api.calendarItemApi.getCalendarItemWithUser(await api.userApi.getCurrentUser(), id),\n share: async (api, p, r, doId) => {\n const user = await api.userApi.getCurrentUser()\n const ownerId = api.dataOwnerApi.getDataOwnerIdOf(user)\n const shared = await api.cryptoApi.entities.entityWithExtendedEncryptedMetadata(\n r,\n doId,\n await api.cryptoApi.entities.secretIdsOf(r),\n await api.cryptoApi.entities.encryptionKeysOf(r),\n p ? [p.id!] : []\n )\n return shared ? api.calendarItemApi.modifyCalendarItemWithHcParty(await api.userApi.getCurrentUser(), shared) : r\n },\n isDecrypted: async (entityToCheck) => {\n return entityToCheck.title != undefined\n },\n } as EntityFacade<CalendarItem>,\n}\nconst patientFacades = Object.entries(facades)\n .filter((f) => f[0] !== 'Patient')\n .reduce((prev, curr) => ({ ...prev, [curr[0]]: curr[1] }), {})\n\nconst users: { user: User; password: string }[] = []\nconst primitives = new CryptoPrimitives(webcrypto as any)\nlet delegateUser: User | undefined = undefined\nlet delegateHcp: HealthcareParty | undefined = undefined\nlet delegateHcpPassword: string | undefined = undefined\n\nlet userGivingAccessBack: User | undefined = undefined\nlet userGivingAccessBackPassword: string | undefined = undefined\nlet hcpGivingAccessBack: HealthcareParty | undefined = undefined\n\nconst entities: EntityCreators = {\n Patient: ({ patientApi }, id, user, _, delegateIds) => {\n return patientApi.newInstance(user, new Patient({ id, firstName: 'test', lastName: 'test', note: 'data', dateOfBirth: 20000101 }), {\n additionalDelegates: Object.fromEntries((delegateIds ?? []).map((id) => [id, 'WRITE'])),\n })\n },\n Contact: ({ contactApi }, id, user, patient, delegateIds) => {\n return contactApi.newInstance(\n user,\n patient!,\n new Contact({ id, services: [new Service({ label: 'svc', content: { fr: { stringValue: 'data' } } })] }),\n {\n confidential: false,\n additionalDelegates: Object.fromEntries((delegateIds ?? []).map((id) => [id, 'WRITE'])),\n }\n )\n },\n HealthElement: ({ healthcareElementApi }, id, user, patient, delegateIds) => {\n return healthcareElementApi.newInstance(user, patient!, new HealthElement({ id, descr: 'HE' }), {\n confidential: false,\n additionalDelegates: Object.fromEntries((delegateIds ?? []).map((id) => [id, 'WRITE'])),\n })\n },\n CalendarItem: ({ calendarItemApi }, id, user, patient, delegateIds) => {\n return calendarItemApi.newInstancePatient(user, patient!, new CalendarItem({ id, title: 'CI' }), {\n additionalDelegates: Object.fromEntries((delegateIds ?? []).map((id) => [id, 'WRITE'])),\n })\n },\n}\n\nconst userDefinitions: Record<\n string,\n (user: User, password: string, pair: KeyPair<CryptoKey>) => Promise<{ user: User; apis: Apis; didLoseKey: boolean }>\n> = {\n 'one available key and one lost key recoverable through transfer keys': async (user, password, originalKey) => {\n const newKey = await primitives.RSA.generateKeyPair()\n const apiWithOnlyNewKey = await IcureApi.initialise(\n env!.iCureUrl,\n { username: user.login!, password },\n new TestCryptoStrategies(newKey, {\n [ua2hex(await primitives.RSA.exportKey(originalKey.publicKey, 'spki')).slice(-32)]: true,\n }),\n webcrypto as any,\n fetch,\n {\n storage: new TestStorage(),\n keyStorage: new TestKeyStorage(),\n }\n )\n const apis = await IcureApi.initialise(\n env!.iCureUrl,\n { username: user.login!, password },\n new TestCryptoStrategies(originalKey, {\n [ua2hex(await primitives.RSA.exportKey(newKey.publicKey, 'spki')).slice(-32)]: true,\n }),\n webcrypto as any,\n fetch,\n {\n storage: new TestStorage(),\n keyStorage: new TestKeyStorage(),\n }\n )\n expect(Object.keys(apis.cryptoApi.userKeysManager.getDecryptionKeys())).to.have.length(2)\n return { user, apis, didLoseKey: false }\n },\n 'two available keys': async (user, password, originalKey) => {\n const newKey = await primitives.RSA.generateKeyPair()\n const apiWithOnlyNewKey = await IcureApi.initialise(\n env!.iCureUrl,\n { username: user.login!, password },\n new TestCryptoStrategies(newKey),\n webcrypto as any,\n fetch,\n {\n storage: new TestStorage(),\n keyStorage: new TestKeyStorage(),\n }\n )\n const keyStrings = await Promise.all(\n [originalKey, newKey].map(async (pair) => ({\n publicKey: ua2hex(await primitives.RSA.exportKey(pair.publicKey, 'spki')),\n privateKey: ua2hex(await primitives.RSA.exportKey(pair.privateKey, 'pkcs8')),\n }))\n )\n const storage = await testStorageWithKeys([{ dataOwnerId: user.healthcarePartyId ?? user.patientId!, pairs: keyStrings }])\n const apis = await IcureApi.initialise(env!.iCureUrl, { username: user.login!, password }, new TestCryptoStrategies(), webcrypto as any, fetch, {\n storage: storage.storage,\n keyStorage: storage.keyStorage,\n entryKeysFactory: storage.keyFactory,\n })\n return { user, apis, didLoseKey: false }\n },\n 'a single available key in old format': async (user, password, originalKey) => ({\n user,\n apis: await TestApi(env.iCureUrl, user.login!, password, webcrypto as any, originalKey),\n didLoseKey: false,\n }),\n 'one lost key and one available key': async (user, password) => {\n const newKeyPair = await primitives.RSA.generateKeyPair()\n const apis = await TestApi(env.iCureUrl, user.login!, password, webcrypto as any, newKeyPair)\n await apis.icureMaintenanceTaskApi.createMaintenanceTasksForNewKeypair(user, newKeyPair)\n return { user, apis, didLoseKey: true }\n },\n 'one lost key and one upgraded available key thanks to delegate who gave access back to previous data': async (user, password) => {\n const newKeyPair = await primitives.RSA.generateKeyPair()\n const api = await TestApi(env.iCureUrl, user.login!, password, webcrypto as any, newKeyPair)\n await api.icureMaintenanceTaskApi.createMaintenanceTasksForNewKeypair(user, newKeyPair)\n const giveAccessBackApi = apis['givingAccessBack']\n const keyPairUpdateRequests = (\n await giveAccessBackApi.maintenanceTaskApi.filterMaintenanceTasksByWithUser(\n userGivingAccessBack!,\n undefined,\n undefined,\n new FilterChainMaintenanceTask({\n filter: new MaintenanceTaskAfterDateFilter({\n date: new Date().getTime() - 100000,\n }),\n })\n )\n ).rows!.map((x) => KeyPairUpdateRequest.fromMaintenanceTask(x))\n const concernedRequest = keyPairUpdateRequests.find((x) => x.concernedDataOwnerId === (user.healthcarePartyId ?? user.patientId))\n if (!concernedRequest) throw new Error('Could not find maintenance task')\n await giveAccessBackApi.icureMaintenanceTaskApi.applyKeyPairUpdate(concernedRequest)\n\n await api.cryptoApi.forceReload()\n\n return { user, apis: api, didLoseKey: true }\n },\n}\n\nasync function createPartialsForHcp(\n entityFacades: EntityFacades,\n entityCreators: EntityCreators,\n user: User,\n password: string\n): Promise<KeyPair<CryptoKey>> {\n const key = await primitives.RSA.generateKeyPair()\n const api1 = await TestApi(env!.iCureUrl, user.login!, password, webcrypto as any, key)\n await Object.entries(entityFacades).reduce(async (p, f) => {\n await p\n const type = f[0]\n const facade = f[1]\n const parent = type !== 'Patient' ? await api1.patientApi.getPatientWithUser(user, `partial-${user.id}-Patient`) : undefined\n const record = await entityCreators[type as TestedEntity](api1, `partial-${user.id}-${type}`, user, parent, [hcpGivingAccessBack!.id!])\n await facade.create(api1, record)\n }, Promise.resolve())\n return key\n}\n\nasync function createPartialsForPatient(\n entityFacades: EntityFacades,\n entityCreators: EntityCreators,\n user: User,\n password: string,\n patientCreatorUser: User,\n patientCreatorApis: Apis\n): Promise<KeyPair<CryptoKey>> {\n const key = await primitives.RSA.generateKeyPair()\n const api1 = await TestApi(env!.iCureUrl, user.login!, password, webcrypto as any, key)\n const pat = await patientCreatorApis.patientApi.getPatientWithUser(patientCreatorUser, user.patientId!)\n await patientCreatorApis.patientApi.modifyPatientWithUser(\n patientCreatorUser,\n await patientCreatorApis.cryptoApi.entities.entityWithExtendedEncryptedMetadata(\n pat,\n user.patientId!,\n await patientCreatorApis.cryptoApi.entities.secretIdsOf(pat),\n await patientCreatorApis.cryptoApi.entities.encryptionKeysOf(pat),\n []\n )\n )\n await Object.entries(entityFacades)\n .filter((it) => it[0] !== 'Patient')\n .reduce(async (p, f) => {\n await p\n const type = f[0]\n const facade = f[1]\n const parent = await api1.patientApi.getPatientWithUser(user, user.patientId!)\n const record = await entityCreators[type as TestedEntity](api1, `partial-${user.id}-${type}`, user, parent, [hcpGivingAccessBack!.id!])\n await facade.create(api1, record)\n }, Promise.resolve())\n return key\n}\n\nlet env: TestVars\nlet apis: { [key: string]: Apis }\n\ndescribe('Full crypto test - Creation scenarios', async function () {\n before(async function () {\n this.timeout(6000000)\n const initializer = await getEnvironmentInitializer()\n env = await initializer.execute(getEnvVariables())\n\n const api = await initMasterApi(env!)\n const user = await api.userApi.getCurrentUser()\n const dataOwnerId = api.dataOwnerApi.getDataOwnerIdOf(user)\n\n const { userApi, patientApi, healthcarePartyApi, cryptoApi } = api\n\n delegateHcp = await healthcarePartyApi.createHealthcareParty(new HealthcareParty({ id: uuid(), firstName: 'test', lastName: 'test' }))\n delegateUser = await userApi.createUser(\n new User({\n id: `user-${uuid()}-hcp`,\n login: `hcp-delegate-${uuid()}`,\n status: 'ACTIVE',\n healthcarePartyId: delegateHcp.id,\n })\n )\n delegateHcpPassword = await userApi.getToken(delegateUser!.id!, uuid())\n\n hcpGivingAccessBack = await healthcarePartyApi.createHealthcareParty(new HealthcareParty({ id: uuid(), firstName: 'test', lastName: 'test' }))\n userGivingAccessBack = await userApi.createUser(\n new User({\n id: `user-${uuid()}-hcp`,\n login: `hcp-giving-access-back-${uuid()}`,\n status: 'ACTIVE',\n healthcarePartyId: hcpGivingAccessBack.id,\n })\n )\n userGivingAccessBackPassword = await userApi.getToken(userGivingAccessBack!.id!, uuid())\n\n apis = {\n delegate: await TestApi(env.iCureUrl!, delegateUser.login!, delegateHcpPassword, webcrypto as any),\n givingAccessBack: await TestApi(env.iCureUrl!, userGivingAccessBack.login!, userGivingAccessBackPassword, webcrypto as any),\n }\n\n await Object.entries(userDefinitions).reduce(async (p, [login, creationProcess]) => {\n await p\n const newPatientEmail = getTempEmail()\n const patientToCreate = await patientApi.newInstance(user, new Patient({ id: uuid(), firstName: 'test', lastName: 'test' }))\n const patient = await patientApi.createPatientWithUser(user, patientToCreate)\n\n const newHcpEmail = getTempEmail()\n const hcp = await healthcarePartyApi.createHealthcareParty(new HealthcareParty({ id: uuid(), firstName: 'test', lastName: 'test' }))\n\n const newPatientUser = await userApi.createUser(\n new User({\n id: `user-${uuid()}-patient`,\n name: `patient-${login}`,\n login: newPatientEmail,\n email: newPatientEmail,\n status: 'ACTIVE',\n patientId: patient.id,\n })\n )\n const newPatientUserPassword = await userApi.getToken(newPatientUser!.id!, uuid())\n\n const newHcpUser = await userApi.createUser(\n new User({\n id: `user-${uuid()}-hcp`,\n login: newHcpEmail,\n email: newHcpEmail,\n name: `hcp-${login}`,\n status: 'ACTIVE',\n healthcarePartyId: hcp.id,\n })\n )\n const newHcpUserPassword = await userApi.getToken(newHcpUser!.id!, uuid())\n\n const originalKeyPat = await createPartialsForPatient(facades, entities, newPatientUser, newPatientUserPassword, user, api)\n const originalKeyHcp = await createPartialsForHcp(facades, entities, newHcpUser, newHcpUserPassword)\n\n const patDetails = await creationProcess(newPatientUser, newPatientUserPassword, originalKeyPat)\n const hcpDetails = await creationProcess(newHcpUser, newHcpUserPassword, originalKeyHcp)\n\n users.push({ user: patDetails.user, password: newPatientUserPassword })\n apis[patDetails.user.name!] = patDetails.apis\n users.push({ user: hcpDetails.user, password: newHcpUserPassword })\n apis[hcpDetails.user.name!] = hcpDetails.apis\n\n // Give access back to own sfks of patient\n if (patDetails.didLoseKey) {\n const keyPairUpdateRequests = (\n await api.maintenanceTaskApi.filterMaintenanceTasksByWithUser(\n user,\n undefined,\n undefined,\n new FilterChainMaintenanceTask({\n filter: new MaintenanceTaskAfterDateFilter({\n date: new Date().getTime() - 100000,\n }),\n })\n )\n ).rows!.map((x) => KeyPairUpdateRequest.fromMaintenanceTask(x))\n const dataOwnerWithLostKey = newPatientUser.patientId!\n const concernedRequest = keyPairUpdateRequests.find((x) => x.concernedDataOwnerId === dataOwnerWithLostKey)\n if (!concernedRequest) throw new Error('Could not find maintenance task to regive access back to own sfks')\n await api.icureMaintenanceTaskApi.applyKeyPairUpdate(concernedRequest)\n await patDetails.apis.cryptoApi.forceReload()\n }\n }, Promise.resolve())\n\n await users\n .filter((it) => it.user.id!.endsWith('patient'))\n .map((it) => it.user)\n .reduce(async (prev, it) => {\n await prev\n const otherUsers = users.filter((u) => u.user.id!.endsWith('patient') && u.user.id !== it.id).map((u) => u.user)\n\n await otherUsers.reduce(async (p, u) => {\n await p\n const patientToShare = await facades.Patient.get(api, it.patientId!)\n const sharedPatient = await facades.Patient.share(api, null, patientToShare, u.patientId!)\n expect(Object.keys(sharedPatient.delegations ?? {})).to.contain(u.patientId!)\n return Promise.resolve()\n }, Promise.resolve())\n\n return Promise.resolve()\n }, Promise.resolve())\n })\n ;['patient', 'hcp'].forEach((uType) => {\n Object.keys(userDefinitions).forEach((uId) => {\n Object.entries(facades).forEach((f) => {\n it(`Create ${f[0]} as a ${uType} with ${uId}`, async function () {\n if (f[0] === 'Patient' && uType === 'patient') {\n this.skip()\n }\n const { user } = users.find((it) => it.user.name === `${uType}-${uId}`)!\n const facade: EntityFacade<any> = f[1]\n const api = apis[`${uType}-${uId}`]\n\n const parent =\n f[0] !== 'Patient'\n ? uType === 'patient'\n ? await api.patientApi.getPatientWithUser(user, user.patientId!)\n : await api.patientApi.getPatientWithUser(user, `${user.id}-Patient`)\n : undefined\n const record = await entities[f[0] as TestedEntity](api, `${user.id}-${f[0]}`, user, parent)\n const entity = await facade.create(api, record)\n const retrieved = await facade.get(api, entity.id)\n\n expect(entity.id).to.be.not.null\n expect(entity.rev).to.equal(retrieved.rev)\n expect(await facade.isDecrypted(entity)).to.equal(true)\n })\n it(`Create ${f[0]} as delegate with delegation for ${uType} with ${uId}`, async function () {\n const { user } = users.find((it) => it.user.name === `${uType}-${uId}`)!\n const facade: EntityFacade<any> = f[1]\n\n const api = apis['delegate']\n const patApi = apis[`${uType}-${uId}`]\n const dataOwnerId = api.dataOwnerApi.getDataOwnerIdOf(user)\n const dataOwner = (await patApi.dataOwnerApi.getCryptoActorStub(dataOwnerId))!.stub\n\n const parent = f[0] !== 'Patient' ? await api.patientApi.getPatientWithUser(delegateUser!, `delegate-${user.id}-Patient`) : undefined\n\n const record = await entities[f[0] as TestedEntity](api, `delegate-${user.id}-${f[0]}`, delegateUser!, parent, [\n (user.patientId ?? user.healthcarePartyId ?? user.deviceId)!,\n ])\n const entity = await facade.create(api, record)\n const retrieved = await facade.get(api, entity.id)\n const hcp = await api.healthcarePartyApi.getCurrentHealthcareParty()\n\n const shareKeys = hcp.aesExchangeKeys![hcp.publicKey!][dataOwnerId]\n if (Object.keys(shareKeys).length > 2) {\n delete shareKeys[dataOwner.publicKey!.slice(-32)]\n }\n hcp.aesExchangeKeys = { ...hcp.aesExchangeKeys, [hcp.publicKey!]: { ...hcp.aesExchangeKeys![hcp.publicKey!], [dataOwnerId]: shareKeys } }\n await api.healthcarePartyApi.modifyHealthcareParty(hcp)\n\n expect(entity.id).to.be.not.null\n expect(entity.rev).to.equal(retrieved.rev)\n expect(await facade.isDecrypted(entity)).to.equal(true)\n })\n })\n })\n })\n})\n\ndescribe('Full crypto test - Read/Share scenarios', async function () {\n ;['patient', 'hcp'].forEach((uType) => {\n Object.keys(userDefinitions).forEach((uId) => {\n Object.entries(facades).forEach((f) => {\n it(`Read ${f[0]} as the initial ${uType} with ${uId}`, async function () {\n if (f[0] === 'Patient' && uType === 'patient') {\n this.skip()\n }\n const { user } = users.find((it) => it.user.name === `${uType}-${uId}`)!\n const facade = f[1]\n const api = apis[`${uType}-${uId}`]\n\n const entity = await facade.get(api, `partial-${user.id}-${f[0]}`)\n expect(entity.id).to.equal(`partial-${user.id}-${f[0]}`)\n expect(await facade.isDecrypted(entity)).to.equal(\n !uId.includes('one lost key and one available key') /* data shared only with lost key... So false */\n )\n })\n it(`Read ${f[0]} as a ${uType} with ${uId}`, async function () {\n if (f[0] === 'Patient' && uType === 'patient') {\n this.skip()\n }\n const { user } = users.find((it) => it.user.name === `${uType}-${uId}`)!\n const facade = f[1]\n const api = apis[`${uType}-${uId}`]\n\n const entity = await facade.get(api, `${user.id}-${f[0]}`)\n expect(entity.id).to.equal(`${user.id}-${f[0]}`)\n expect(await facade.isDecrypted(entity)).to.equal(true)\n })\n it(`Read ${f[0]} shared by delegate as a ${uType} with ${uId}`, async () => {\n const { user } = users.find((it) => it.user.name === `${uType}-${uId}`)!\n const facade = f[1]\n const api = apis[`${uType}-${uId}`]\n\n const entity = await facade.get(api, `delegate-${user.id}-${f[0]}`)\n expect(entity.id).to.equal(`delegate-${user.id}-${f[0]}`)\n expect(await facade.isDecrypted(entity)).to.equal(true)\n })\n ;['patient', 'hcp'].forEach((duType) => {\n Object.keys(userDefinitions).forEach((duId) => {\n it(`Share ${f[0]} as a ${uType} with ${uId} to a ${duType} with ${duId}`, async function () {\n if (f[0] === 'Patient' && uType === 'patient') {\n this.skip()\n }\n const { user } = users.find((it) => it.user.name === `${uType}-${uId}`)!\n const { user: delUser } = users.find((it) => it.user.name === `${duType}-${duId}`)!\n const delegateDoId = delUser.healthcarePartyId ?? delUser.patientId\n const facade = f[1]\n const api = apis[`${uType}-${uId}`]\n const delApi = apis[`${duType}-${duId}`]\n\n const parent =\n f[0] !== 'Patient'\n ? uType === 'patient'\n ? await api.patientApi.getPatientWithUser(user, user.patientId!)\n : await api.patientApi.getPatientWithUser(user, `${user.id}-Patient`)\n : undefined\n const retrievedEntity = await facade.get(api, `${user.id}-${f[0]}`)\n const entity = await facade.share(api, parent, retrievedEntity, delegateDoId)\n const retrieved = await facade.get(api, entity.id)\n expect(entity.rev).to.equal(retrieved.rev)\n expect(Object.keys(entity.delegations)).to.contain(delegateDoId)\n\n const obj = await facade.get(delApi, `${user.id}-${f[0]}`)\n expect(Object.keys(obj.delegations)).to.contain(delegateDoId)\n expect(await facade.isDecrypted(obj)).to.equal(true)\n })\n })\n })\n })\n })\n })\n})\n"]}
|