@icure/api 5.0.31 → 5.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/icc-x-api/icc-crypto-x-api.d.ts +7 -12
- package/icc-x-api/icc-crypto-x-api.js +25 -33
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +4 -0
- package/icc-x-api/index.js +5 -1
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/storage/KeyStorageFacade.d.ts +37 -0
- package/icc-x-api/storage/KeyStorageFacade.js +3 -0
- package/icc-x-api/storage/KeyStorageFacade.js.map +1 -0
- package/icc-x-api/storage/KeyStorageImpl.d.ts +17 -0
- package/icc-x-api/storage/KeyStorageImpl.js +34 -0
- package/icc-x-api/storage/KeyStorageImpl.js.map +1 -0
- package/icc-x-api/storage/LocalStorageImpl.d.ts +10 -0
- package/icc-x-api/storage/LocalStorageImpl.js +25 -0
- package/icc-x-api/storage/LocalStorageImpl.js.map +1 -0
- package/icc-x-api/storage/StorageFacade.d.ts +19 -0
- package/icc-x-api/storage/StorageFacade.js +3 -0
- package/icc-x-api/storage/StorageFacade.js.map +1 -0
- package/package.json +1 -1
|
@@ -4,6 +4,8 @@ import { RSAUtils } from './crypto/RSA';
|
|
|
4
4
|
import { ShamirClass } from './crypto/shamir';
|
|
5
5
|
import { Delegation, Device, Document, EncryptedEntity, EncryptedParentEntity, HealthcareParty, Patient, User } from '../icc-api/model/models';
|
|
6
6
|
import { IccMaintenanceTaskXApi } from './icc-maintenance-task-x-api';
|
|
7
|
+
import { StorageFacade } from './storage/StorageFacade';
|
|
8
|
+
import { KeyStorageFacade } from './storage/KeyStorageFacade';
|
|
7
9
|
interface DelegatorAndKeys {
|
|
8
10
|
delegatorId: string;
|
|
9
11
|
key: CryptoKey;
|
|
@@ -64,10 +66,12 @@ export declare class IccCryptoXApi {
|
|
|
64
66
|
private readonly _AES;
|
|
65
67
|
private readonly _RSA;
|
|
66
68
|
private readonly _shamir;
|
|
69
|
+
private readonly _storage;
|
|
70
|
+
private readonly _keyStorage;
|
|
67
71
|
constructor(host: string, headers: {
|
|
68
72
|
[key: string]: string;
|
|
69
73
|
}, hcpartyBaseApi: IccHcpartyApi, //Init with a hcparty x api for better performances
|
|
70
|
-
patientBaseApi: IccPatientApi, deviceBaseApi: IccDeviceApi, crypto?: Crypto);
|
|
74
|
+
patientBaseApi: IccPatientApi, deviceBaseApi: IccDeviceApi, crypto?: Crypto, storage?: StorageFacade<string>, keyStorage?: KeyStorageFacade);
|
|
71
75
|
loadAllKeysFromLocalStorage(dataOwnerId: string): Promise<void>;
|
|
72
76
|
getCachedRsaKeyPairForFingerprint(dataOwnerId: string, pubKeyOrFingerprint: string): Promise<{
|
|
73
77
|
publicKey: CryptoKey;
|
|
@@ -373,18 +377,9 @@ export declare class IccCryptoXApi {
|
|
|
373
377
|
remote: boolean;
|
|
374
378
|
local: boolean;
|
|
375
379
|
}>;
|
|
376
|
-
getKeychainInBrowserLocalStorageAsBase64(id: string): string |
|
|
377
|
-
getKeychainValidityDateInBrowserLocalStorage(id: string): string |
|
|
380
|
+
getKeychainInBrowserLocalStorageAsBase64(id: string): string | undefined;
|
|
381
|
+
getKeychainValidityDateInBrowserLocalStorage(id: string): string | undefined;
|
|
378
382
|
loadKeychainFromBrowserLocalStorage(id: string): Uint8Array[] | null;
|
|
379
|
-
/**
|
|
380
|
-
*
|
|
381
|
-
* @param id
|
|
382
|
-
* @param keyPair should be JWK
|
|
383
|
-
*/
|
|
384
|
-
storeKeyPair(id: string, keyPair: {
|
|
385
|
-
publicKey: any;
|
|
386
|
-
privateKey: any;
|
|
387
|
-
}): void;
|
|
388
383
|
/**
|
|
389
384
|
* loads the RSA key pair (hcparty) in JWK from local storage, not imported
|
|
390
385
|
*
|
|
@@ -17,9 +17,11 @@ const _ = require("lodash");
|
|
|
17
17
|
const models_1 = require("../icc-api/model/models");
|
|
18
18
|
const binary_utils_1 = require("./utils/binary-utils");
|
|
19
19
|
const utils_1 = require("./utils");
|
|
20
|
+
const LocalStorageImpl_1 = require("./storage/LocalStorageImpl");
|
|
21
|
+
const KeyStorageImpl_1 = require("./storage/KeyStorageImpl");
|
|
20
22
|
class IccCryptoXApi {
|
|
21
23
|
constructor(host, headers, hcpartyBaseApi, //Init with a hcparty x api for better performances
|
|
22
|
-
patientBaseApi, deviceBaseApi, crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : {}) {
|
|
24
|
+
patientBaseApi, deviceBaseApi, crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : {}, storage, keyStorage) {
|
|
23
25
|
this.hcPartyKeysCache = {};
|
|
24
26
|
//[delegateId][delegatorId] = delegateEncryptedHcPartyKey
|
|
25
27
|
//for each delegate, it stores the list of delegators and the corresponding delegateEncryptedHcPartyKey (shared HcPartyKey, from delegator to delegate, encrypted with the RSA key of the delegate)
|
|
@@ -40,6 +42,8 @@ class IccCryptoXApi {
|
|
|
40
42
|
this._AES = new AES_1.AESUtils(crypto);
|
|
41
43
|
this._RSA = new RSA_1.RSAUtils(crypto);
|
|
42
44
|
this._shamir = new shamir_1.ShamirClass(crypto);
|
|
45
|
+
this._storage = storage || new LocalStorageImpl_1.LocalStorageImpl();
|
|
46
|
+
this._keyStorage = keyStorage || new KeyStorageImpl_1.KeyStorageImpl(this._storage);
|
|
43
47
|
}
|
|
44
48
|
get crypto() {
|
|
45
49
|
return this._crypto;
|
|
@@ -181,7 +185,7 @@ class IccCryptoXApi {
|
|
|
181
185
|
const importedPrivateKey = yield this._RSA.importKey('pkcs8', (0, binary_utils_1.hex2ua)(decryptedPrivatedKey), ['decrypt']);
|
|
182
186
|
const importedPublicKey = yield this._RSA.importKey('spki', (0, binary_utils_1.hex2ua)(hcp.publicKey), ['encrypt']);
|
|
183
187
|
const exportedKeyPair = yield this._RSA.exportKeys({ publicKey: importedPublicKey, privateKey: importedPrivateKey }, 'jwk', 'jwk');
|
|
184
|
-
this.storeKeyPair(hcp.id
|
|
188
|
+
this._keyStorage.storeKeyPair(`${this.rsaLocalStoreIdPrefix}${hcp.id}`, exportedKeyPair);
|
|
185
189
|
}
|
|
186
190
|
catch (e) {
|
|
187
191
|
console.log('Cannot decrypt shamir RSA key');
|
|
@@ -1047,7 +1051,7 @@ class IccCryptoXApi {
|
|
|
1047
1051
|
const keyPair = yield this._RSA.importKeyPair('jwk', privateKeyInJwk, 'jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(publicKey)));
|
|
1048
1052
|
this.rsaKeyPairs[publicKey.slice(-32)] = keyPair;
|
|
1049
1053
|
const exportedKeyPair = yield this._RSA.exportKeys(keyPair, 'jwk', 'jwk');
|
|
1050
|
-
return this.storeKeyPair(`${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
|
|
1054
|
+
return this._keyStorage.storeKeyPair(`${this.rsaLocalStoreIdPrefix}${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
|
|
1051
1055
|
});
|
|
1052
1056
|
}
|
|
1053
1057
|
loadKeyPairsAsJwkInBrowserLocalStorage(healthcarePartyId, privateKey) {
|
|
@@ -1064,7 +1068,7 @@ class IccCryptoXApi {
|
|
|
1064
1068
|
const keyPair = yield this._RSA.importKeyPair('jwk', privateKey, 'jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(publicKey)));
|
|
1065
1069
|
this.rsaKeyPairs[publicKey.slice(-32)] = keyPair;
|
|
1066
1070
|
const exportedKeyPair = yield this._RSA.exportKeys(keyPair, 'jwk', 'jwk');
|
|
1067
|
-
return this.storeKeyPair(`${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
|
|
1071
|
+
return this._keyStorage.storeKeyPair(`${this.rsaLocalStoreIdPrefix}${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
|
|
1068
1072
|
});
|
|
1069
1073
|
}
|
|
1070
1074
|
// noinspection JSUnusedGlobalSymbols
|
|
@@ -1085,20 +1089,20 @@ class IccCryptoXApi {
|
|
|
1085
1089
|
}
|
|
1086
1090
|
// noinspection JSUnusedGlobalSymbols
|
|
1087
1091
|
saveKeychainInBrowserLocalStorage(id, keychain) {
|
|
1088
|
-
|
|
1092
|
+
this._storage.setItem(this.keychainLocalStoreIdPrefix + id, (0, binary_utils_1.b2a)(new Uint8Array(keychain).reduce((data, byte) => data + String.fromCharCode(byte), '')));
|
|
1089
1093
|
}
|
|
1090
1094
|
saveKeychainInBrowserLocalStorageAsBase64(id, keyChainB64) {
|
|
1091
|
-
|
|
1095
|
+
this._storage.setItem(this.keychainLocalStoreIdPrefix + id, keyChainB64);
|
|
1092
1096
|
}
|
|
1093
1097
|
// noinspection JSUnusedGlobalSymbols
|
|
1094
1098
|
saveKeychainValidityDateInBrowserLocalStorage(id, date) {
|
|
1095
1099
|
if (!id)
|
|
1096
1100
|
return;
|
|
1097
1101
|
if (!date) {
|
|
1098
|
-
|
|
1102
|
+
this._storage.deleteItem(this.keychainValidityDateLocalStoreIdPrefix + id);
|
|
1099
1103
|
}
|
|
1100
1104
|
else {
|
|
1101
|
-
|
|
1105
|
+
this._storage.setItem(this.keychainValidityDateLocalStoreIdPrefix + id, date);
|
|
1102
1106
|
}
|
|
1103
1107
|
}
|
|
1104
1108
|
/**
|
|
@@ -1204,28 +1208,15 @@ class IccCryptoXApi {
|
|
|
1204
1208
|
});
|
|
1205
1209
|
}
|
|
1206
1210
|
getKeychainInBrowserLocalStorageAsBase64(id) {
|
|
1207
|
-
return
|
|
1211
|
+
return this._storage.getItem(this.keychainLocalStoreIdPrefix + id);
|
|
1208
1212
|
}
|
|
1209
1213
|
getKeychainValidityDateInBrowserLocalStorage(id) {
|
|
1210
|
-
return
|
|
1214
|
+
return this._storage.getItem(this.keychainValidityDateLocalStoreIdPrefix + id);
|
|
1211
1215
|
}
|
|
1212
1216
|
// noinspection JSUnusedGlobalSymbols
|
|
1213
1217
|
loadKeychainFromBrowserLocalStorage(id) {
|
|
1214
|
-
const lsItem =
|
|
1215
|
-
return lsItem !==
|
|
1216
|
-
}
|
|
1217
|
-
/**
|
|
1218
|
-
*
|
|
1219
|
-
* @param id
|
|
1220
|
-
* @param keyPair should be JWK
|
|
1221
|
-
*/
|
|
1222
|
-
storeKeyPair(id, keyPair) {
|
|
1223
|
-
if (typeof Storage === 'undefined') {
|
|
1224
|
-
console.log('Your browser does not support HTML5 Browser Local Storage !');
|
|
1225
|
-
throw 'Your browser does not support HTML5 Browser Local Storage !';
|
|
1226
|
-
}
|
|
1227
|
-
//TODO encryption
|
|
1228
|
-
localStorage.setItem(this.rsaLocalStoreIdPrefix + id, JSON.stringify(keyPair));
|
|
1218
|
+
const lsItem = this._storage.getItem(this.keychainLocalStoreIdPrefix + id);
|
|
1219
|
+
return lsItem !== undefined ? (0, binary_utils_1.b64_2uas)(lsItem) : null;
|
|
1229
1220
|
}
|
|
1230
1221
|
/**
|
|
1231
1222
|
* loads the RSA key pair (hcparty) in JWK from local storage, not imported
|
|
@@ -1241,11 +1232,13 @@ class IccCryptoXApi {
|
|
|
1241
1232
|
throw 'Your browser does not support HTML5 Browser Local Storage !';
|
|
1242
1233
|
}
|
|
1243
1234
|
//TODO decryption
|
|
1244
|
-
const item =
|
|
1235
|
+
const item = publicKeyFingerPrint
|
|
1236
|
+
? (_a = this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id + '.' + publicKeyFingerPrint.slice(-32))) !== null && _a !== void 0 ? _a : this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id)
|
|
1237
|
+
: this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id);
|
|
1245
1238
|
if (!item) {
|
|
1246
1239
|
console.warn(`No key can be found in local storage for id ${id} and publicKeyFingerPrint ${publicKeyFingerPrint}`);
|
|
1247
1240
|
}
|
|
1248
|
-
return
|
|
1241
|
+
return item;
|
|
1249
1242
|
}
|
|
1250
1243
|
/**
|
|
1251
1244
|
* Loads and imports the RSA key pair (hcparty) from local storage
|
|
@@ -1256,24 +1249,23 @@ class IccCryptoXApi {
|
|
|
1256
1249
|
loadKeyPairImported(id) {
|
|
1257
1250
|
return new Promise((resolve, reject) => {
|
|
1258
1251
|
try {
|
|
1259
|
-
const
|
|
1260
|
-
if (
|
|
1261
|
-
const jwkKeyPair = JSON.parse(jwkKey);
|
|
1252
|
+
const jwkKeyPair = this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id);
|
|
1253
|
+
if (jwkKeyPair !== undefined) {
|
|
1262
1254
|
if (jwkKeyPair.publicKey && jwkKeyPair.privateKey) {
|
|
1263
1255
|
this._RSA.importKeyPair('jwk', jwkKeyPair.privateKey, 'jwk', jwkKeyPair.publicKey).then(resolve, (err) => {
|
|
1264
|
-
console.
|
|
1256
|
+
console.error('Error in RSA.importKeyPair: ' + err);
|
|
1265
1257
|
reject(err);
|
|
1266
1258
|
});
|
|
1267
1259
|
}
|
|
1268
1260
|
else {
|
|
1269
1261
|
const message = 'Error in RSA.importKeyPair: Invalid key';
|
|
1270
|
-
console.
|
|
1262
|
+
console.error(message);
|
|
1271
1263
|
reject(Error(message));
|
|
1272
1264
|
}
|
|
1273
1265
|
}
|
|
1274
1266
|
else {
|
|
1275
1267
|
const message = 'Error in RSA.importKeyPair: Missing key';
|
|
1276
|
-
console.
|
|
1268
|
+
console.error(message);
|
|
1277
1269
|
reject(Error(message));
|
|
1278
1270
|
}
|
|
1279
1271
|
}
|