@icure/api 5.0.31 → 5.0.32

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.
@@ -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 | null;
377
- getKeychainValidityDateInBrowserLocalStorage(id: string): string | null;
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, exportedKeyPair);
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
- localStorage.setItem(this.keychainLocalStoreIdPrefix + id, (0, binary_utils_1.b2a)(new Uint8Array(keychain).reduce((data, byte) => data + String.fromCharCode(byte), '')));
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
- localStorage.setItem(this.keychainLocalStoreIdPrefix + id, keyChainB64);
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
- localStorage.removeItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1102
+ this._storage.deleteItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1099
1103
  }
1100
1104
  else {
1101
- localStorage.setItem(this.keychainValidityDateLocalStoreIdPrefix + id, date);
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 localStorage.getItem(this.keychainLocalStoreIdPrefix + id);
1211
+ return this._storage.getItem(this.keychainLocalStoreIdPrefix + id);
1208
1212
  }
1209
1213
  getKeychainValidityDateInBrowserLocalStorage(id) {
1210
- return localStorage.getItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1214
+ return this._storage.getItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1211
1215
  }
1212
1216
  // noinspection JSUnusedGlobalSymbols
1213
1217
  loadKeychainFromBrowserLocalStorage(id) {
1214
- const lsItem = localStorage.getItem('org.taktik.icure.ehealth.keychain.' + id);
1215
- return lsItem !== null ? (0, binary_utils_1.b64_2uas)(lsItem) : null;
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 = (_a = (publicKeyFingerPrint && localStorage.getItem(this.rsaLocalStoreIdPrefix + id + '.' + publicKeyFingerPrint.slice(-32)))) !== null && _a !== void 0 ? _a : localStorage.getItem(this.rsaLocalStoreIdPrefix + id);
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 JSON.parse(item);
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 jwkKey = localStorage.getItem(this.rsaLocalStoreIdPrefix + id);
1260
- if (jwkKey) {
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.log('Error in RSA.importKeyPair: ' + err);
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.log(message);
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.log(message);
1268
+ console.error(message);
1277
1269
  reject(Error(message));
1278
1270
  }
1279
1271
  }