@it-enterprise/digital-signature 1.1.0 → 1.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@it-enterprise/digital-signature",
3
- "version": "1.1.0",
3
+ "version": "1.1.6",
4
4
  "description": "digital signature",
5
5
  "private": false,
6
6
  "main": "src/index.js",
package/readme.md CHANGED
@@ -102,6 +102,7 @@ import auth from '@it-enterprise/jwtauthentication';
102
102
  const ds = new DigitalSignature(
103
103
  new Models.GraphQlSettingProvider(
104
104
  "uk", // Язык ошибок
105
+ userId, // id пользователя (для сохранения ключей и предпочитаемого типа ключа)
105
106
  "https://m.it.ua/GraphQlServer/", // Адрес сервера GraphQl
106
107
  "https://m.it.ua/ws/", // Адрес веб-сервисов
107
108
  auth) // Библиотека @it-enterprise/jwtauthentication
@@ -115,6 +116,7 @@ await ds.initialise();
115
116
  const ds = new DigitalSignature(
116
117
  new Models.DefaultSettingProvider(
117
118
  "uk", // Язык ошибок
119
+ userId, // id пользователя (для сохранения ключей и предпочитаемого типа ключа)
118
120
  location.pathname + "api/ds/", // Путь к API ЕЦП
119
121
  glSign) // Значение глобального параметра GlSign в виде строки или обьекта Models.GlSign
120
122
  );
@@ -211,11 +213,21 @@ const keyInfo = await ds.readPrivateKeySIM(
211
213
  Считывание ключа
212
214
 
213
215
  ```javascript
214
- const depositSign = ds.KSPs[0];
215
- const keyInfo = await ds.readPrivateKeyKSP(
216
+ const keyInfo = await ds.readPrivateKeyDepositsign(
216
217
  // Идентификатор пользователя (номер телефона или email)
217
218
  phone,
218
- depositSign,
219
+ // Получать информацию о сертификатах пользователя.
220
+ // true - поля ownerInfo и certificates будут заполены, но пользователь получит дополнительный запрос на подписание
221
+ // false - поля ownerInfo и certificates будут пустыми, но пользователь не получит дополнительный запрос на подписание
222
+ false);
223
+ ```
224
+
225
+ # Дiя
226
+
227
+ Считывание ключа
228
+
229
+ ```javascript
230
+ const keyInfo = await ds.readPrivateKeyDiia(
219
231
  // Получать информацию о сертификатах пользователя.
220
232
  // true - поля ownerInfo и certificates будут заполены, но пользователь получит дополнительный запрос на подписание
221
233
  // false - поля ownerInfo и certificates будут пустыми, но пользователь не получит дополнительный запрос на подписание
@@ -228,18 +240,16 @@ const keyInfo = await ds.readPrivateKeyKSP(
228
240
 
229
241
  ```javascript
230
242
  await ds.storePrivateKeyInfo(
231
- // Идентификатор пользователя
232
- userId,
233
243
  // Информация о ключе
234
- privateKeyInfo
244
+ privateKeyInfo,
245
+ // Будет ли ключ сохранён после закрытия вкладки
246
+ toLocalStorage,
235
247
  ```
236
248
 
237
249
  Считать сохранённые ключи
238
250
 
239
251
  ```javascript
240
252
  const keyInfo = await ds.getStoredPrivateKeyInfo(
241
- // Идентификатор пользователя
242
- userId,
243
253
  // Тип ключа (необязательно)
244
254
  keyType
245
255
  ```
@@ -248,9 +258,7 @@ const keyInfo = await ds.getStoredPrivateKeyInfo(
248
258
 
249
259
  ```javascript
250
260
  await ds.removeStoredPrivateKeyInfo(
251
- // Идентификатор пользователя
252
- userId,
253
- // Индекс ключа (необязательно)
261
+ // Идентификатор ключа (необязательно)
254
262
  keyId
255
263
  ```
256
264
 
@@ -1,5 +1,5 @@
1
- import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings, EndUserCertificate } from "../euscp/euscp";
2
- import { DigitalSignatureKeyType, PrivateKeyInfo, FilePrivateKeyInfo, HardwarePrivateKeyInfo, MobileIdPrivateKeyInfo, KspPrivateKeyInfo } from "./Models";
1
+ import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings, EndUserCertificate, EndUserKeyMedia } from "../euscp/euscp";
2
+ import { DigitalSignatureKeyType, PrivateKeyInfo, FilePrivateKeyInfo, HardwarePrivateKeyInfo, KspPrivateKeyInfo } from "./Models";
3
3
  import { downloadData, readFile } from "./Utils";
4
4
  import Resourses from "./Resourses.json";
5
5
  import GlSign from "./GlSign";
@@ -34,20 +34,29 @@ export default class DigitalSignature {
34
34
  depositsign.address = "https://depositsign.com/api/v1/it-enterprise/sign-server";
35
35
  depositsign.directAccess = true;
36
36
 
37
- // const diia = new KSPSettings();
38
- // diia.name = "ДіЯ";
39
- // diia.ksp = EndUserConstants.EU_KSP_DIIA;
40
- // diia.directAccess = true;
41
- // diia.mobileAppName = "ДіЯ";
42
- // diia.systemId = "IT-Enterprise";
37
+ const diia = new KSPSettings();
38
+ diia.name = "ДіЯ";
39
+ diia.ksp = EndUserConstants.EU_KSP_DIIA;
40
+ diia.directAccess = true;
41
+ diia.mobileAppName = "ДіЯ";
42
+ diia.address = "https://diia-sign.it.ua/KSPSign";
43
+ diia.systemId = "diia-sign-it-ent";
43
44
 
44
45
  /** @type {KSPSettings} */
45
- this._KSPs = [depositsign];
46
+ this._KSPs = [depositsign, diia];
46
47
 
47
48
  /** @type {PrivateKeyInfo} */
48
49
  this._readedKey = null;
49
50
  }
50
51
 
52
+ get PRIVATE_KEY_TYPE() {
53
+ return "_PrivateKeyType";
54
+ }
55
+
56
+ get PRIVATE_KEY_INFO() {
57
+ return "_PrivateKeyInfo";
58
+ }
59
+
51
60
  /**
52
61
  * Считанный приватный ключ
53
62
  * @type {PrivateKeyInfo}
@@ -83,6 +92,8 @@ export default class DigitalSignature {
83
92
  break;
84
93
  }
85
94
 
95
+ this._preferredKeyType = type;
96
+
86
97
  await this.initialise();
87
98
  this.keyType = type;
88
99
  }
@@ -92,6 +103,7 @@ export default class DigitalSignature {
92
103
  * @returns {Promise<number>} Текущий тип библиотеки
93
104
  */
94
105
  async initialise() {
106
+
95
107
  if (!this._glSign) {
96
108
  this._glSign = await Promise.resolve(this._settingsProvider.getGlSign());
97
109
  }
@@ -110,7 +122,7 @@ export default class DigitalSignature {
110
122
 
111
123
  if (!this._euSign) {
112
124
  this._euSign = this._glSign.PreferHarware ? this._euSignKeyMedia : this._euSignFile;
113
- this.keyType = this._glSign.PreferHarware ? DigitalSignatureKeyType.Token : DigitalSignatureKeyType.File;
125
+ this.keyType = this._glSign.PreferHarware ? DigitalSignatureKeyType.Token : this._preferredKeyType;
114
126
  }
115
127
 
116
128
  const euSign = this._euSign;
@@ -288,6 +300,7 @@ export default class DigitalSignature {
288
300
  ownerInfo,
289
301
  await this._euSign.GetOwnCertificates(),
290
302
  privateKey,
303
+ this.glSign.AllowSavePassword ? password : undefined
291
304
  );
292
305
  return this._readedKey;
293
306
  }
@@ -316,30 +329,31 @@ export default class DigitalSignature {
316
329
  }
317
330
 
318
331
  /**
319
- * Считать ключ через MobileId
320
- * @param {string} phone - Номер телефона
321
- * @param {EndUserConstants.EndUserMobileOperatorID} operatorId - Оператор
322
- * @param {number} keyId - Для Lifecell и Vodafone - физ. (1) или юр. (2) лицо, для Kyivstar - 0
332
+ * Считать ключ с Дiя
333
+ * @param {string} userId - Идентификатор пользователя
323
334
  * @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
324
335
  */
325
- async readPrivateKeySIM(phone, operatorId, keyId, getCerts = false) {
326
- if (this._euSign != this._euSignFile) {
327
- await this.setLibraryType(DigitalSignatureKeyType.MobileID);
328
- }
329
- const ownerInfo = await this._euSign.ReadPrivateKeySIM(phone, operatorId, getCerts, keyId);
330
- if (getCerts && !ownerInfo) {
331
- throw {
332
- message: this._resourses.PrivateKeyNotReaded
333
- };
336
+ async readPrivateKeyDepositsign(userId, getCerts = false) {
337
+ return await this.readPrivateKeyKSP(userId, this.KSPs[0], getCerts);
338
+ }
339
+
340
+ /**
341
+ * Считать ключ с Дiя
342
+ * @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
343
+ */
344
+ async readPrivateKeyDiia(getCerts = false) {
345
+ const diia = "DIIA";
346
+ if (sessionStorage[diia] != "+") {
347
+ try {
348
+ sessionStorage[diia] = await downloadData("https://diia-sign.it.ua/diia/");
349
+ } catch {
350
+ throw {
351
+ message: this._resourses.DiiaError + `<a target="_blank" href="${window.origin}">${window.origin}</a></li><ul>`
352
+ };
353
+ }
334
354
  }
335
- this._readedKey = new MobileIdPrivateKeyInfo(
336
- DigitalSignatureKeyType.MobileID,
337
- ownerInfo,
338
- getCerts ? await this._euSign.GetOwnCertificates() : [],
339
- phone,
340
- operatorId
341
- );
342
- return this._readedKey;
355
+
356
+ return await this.readPrivateKeyKSP(null, this.KSPs[1], getCerts);
343
357
  }
344
358
 
345
359
  /**
@@ -352,7 +366,7 @@ export default class DigitalSignature {
352
366
  if (this._euSign != this._euSignFile) {
353
367
  await this.setLibraryType(DigitalSignatureKeyType.KSP);
354
368
  }
355
- if (typeof ksp !== "string") {
369
+ if (ksp != EndUserConstants.EndUserKSP.DIIA && typeof ksp !== "string") {
356
370
  ksp = ksp.name;
357
371
  }
358
372
  const ownerInfo = await this._euSign.ReadPrivateKeyKSP(userId, ksp, getCerts);
@@ -371,6 +385,26 @@ export default class DigitalSignature {
371
385
  return this._readedKey;
372
386
  }
373
387
 
388
+ /**
389
+ * Коллбэк для идентификации
390
+ * @callback authenticationCallback
391
+ * @param {EndUserConfirmKSPOperationEvent} data - Данные для идентификации (Qr-код, ссылка и тд.)
392
+ */
393
+ /**
394
+ * Добавить коллбэк идентификации для облачных провайдеров
395
+ * @param {authenticationCallback} event - Коллбэк. Вызывается при запросе на подписание.
396
+ */
397
+ async addConfirmKSPOperationEventListener(event) {
398
+ if (this._euSign != this._euSignFile) {
399
+ await this.setLibraryType(DigitalSignatureKeyType.KSP);
400
+ }
401
+
402
+ await this._euSign.AddEventListener(EndUserConstants.EndUserEventType.ConfirmKSPOperation, function(data) {
403
+ data.qrCode = "data:image/bmp;base64," + data.qrCode;
404
+ event(data);
405
+ });
406
+ }
407
+
374
408
  /**
375
409
  * Получить список облачных провайдеров
376
410
  * @returns {KSPSettings[]} Список поддержирживаемых облачных провайдеров
@@ -392,8 +426,7 @@ export default class DigitalSignature {
392
426
  */
393
427
  async resetPrivateKey() {
394
428
  await Promise.all([
395
- this._euSignFile.ResetPrivateKey(),
396
- this._euSignKeyMedia.ResetPrivateKey()
429
+ this._euSign.ResetPrivateKey()
397
430
  ]);
398
431
  this._readedKey = null;
399
432
  }
@@ -427,7 +460,7 @@ export default class DigitalSignature {
427
460
 
428
461
  /**
429
462
  * Подписать данные
430
- * @param {Uint8Array | string | Array<Uint8Array | string>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
463
+ * @param {Uint8Array | string | NamedeData | Array<Uint8Array | string | NamedeData>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
431
464
  * @param {boolean?} internal - Внутренняя или внешняя подпись
432
465
  * @param {boolean?} asByteArray - Возвращать подпись в виде массива байтов. По умолчанию подпись возвращается в виде строки в base64
433
466
  */
@@ -443,7 +476,7 @@ export default class DigitalSignature {
443
476
 
444
477
  /**
445
478
  * Подписать файл
446
- * @param {string | Array<string>} fileUrl - Ссылка на загрузку файла. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
479
+ * @param {string | NamedeData | Array<string | NamedeData>} fileUrl - Ссылка на загрузку файла. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
447
480
  * @param {boolean?} internal - Внутренняя или внешняя подпись
448
481
  * @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
449
482
  */
@@ -454,18 +487,23 @@ export default class DigitalSignature {
454
487
  if (typeof asByteArray !== "boolean") {
455
488
  asByteArray = false;
456
489
  }
490
+ const isNamedData = Array.isArray(fileUrl) && fileUrl.every(url => typeof url === "object") || typeof fileUrl === "object";
457
491
  let data;
458
492
  if (Array.isArray(fileUrl)) {
459
- data = await Promise.all(fileUrl.map(url => downloadData(url, "binary")));
493
+ data = await Promise.all(fileUrl.map(function(url) {
494
+ const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
495
+ return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
496
+ }));
460
497
  } else {
461
- data = await downloadData(fileUrl, "binary");
498
+ const downloadedData = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
499
+ data = isNamedData ? {name: fileUrl.name, val: downloadedData} : downloadedData;
462
500
  }
463
501
  return await this.signData(data, internal, asByteArray);
464
502
  }
465
503
 
466
504
  /**
467
505
  * Подписать хеш
468
- * @param {Uint8Array | string | Array<Uint8Array | string>} hash - Хеш файла. Можно передавать несколько хешей в массиве для наложения нескольких подписей за раз
506
+ * @param {Uint8Array | string | NamedData | Array<Uint8Array | string> | NamedData} hash - Хеш файла. Можно передавать несколько хешей в массиве для наложения нескольких подписей за раз
469
507
  * @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
470
508
  */
471
509
  async signHash(hash, asByteArray) {
@@ -477,18 +515,23 @@ export default class DigitalSignature {
477
515
 
478
516
  /**
479
517
  * Подписать хеш из файла
480
- * @param {string | Array<string>} hashUrl - Ссылка на скачивание хеша. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
518
+ * @param {string | NamedData | Array<string | NamedData>} hashUrl - Ссылка на скачивание хеша. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
481
519
  * @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
482
520
  */
483
521
  async signFileHash(hashUrl, asByteArray) {
484
522
  if (typeof asByteArray !== "boolean") {
485
523
  asByteArray = false;
486
524
  }
525
+ const isNamedData = Array.isArray(hashUrl) && hashUrl.every(url => typeof url === "object") || typeof hashUrl === "object";
487
526
  let hash;
488
527
  if (Array.isArray(hashUrl)) {
489
- hash = await Promise.all(hashUrl.map(url => downloadData(url, "binary")));
528
+ hash = await Promise.all(hashUrl.map(function(url) {
529
+ const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
530
+ return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
531
+ }));
490
532
  } else {
491
- hash = await downloadData(hashUrl, "binary");
533
+ const downloadedData = await downloadData(hashUrl, "binary");
534
+ hash = isNamedData ? {name: hashUrl.name, val: downloadedData} : downloadedData;
492
535
  }
493
536
  return await this.signHash(hash, asByteArray);
494
537
  }
@@ -571,22 +614,27 @@ export default class DigitalSignature {
571
614
 
572
615
  /**
573
616
  * Выполнить подписание данных с проверкой подписи
574
- * @param {Uint8Array | string} data - данные для подписи
617
+ * @param {Uint8Array | string | NamedData} data - данные для подписи
575
618
  * @param {boolean?} internal - Накладывать внутреннюю или внешнюю подпись. По умолчанию накладывается внешняя.
576
619
  */
577
620
  async signDataEx(data, internal) {
578
621
  if (typeof internal !== "boolean") {
579
622
  internal = false;
580
623
  }
581
-
624
+ const isNamedData = typeof data === "object" && !(data instanceof Uint8Array);
582
625
  if (!internal) {
583
- data = await this._euSign.HashData(this._readedKey.getHashAlgo(), data, false);
626
+ const hashedData = await this._euSign.HashData(this._readedKey.getHashAlgo(), isNamedData ? data.val : data, false);
627
+ if(isNamedData) {
628
+ data.val = hashedData;
629
+ } else {
630
+ data = hashedData;
631
+ }
584
632
  }
585
633
  const signature = internal ? await this.signData(data, internal) : await this.signHash(data);
586
- const signatureInfo = internal ? await this.verifyDataInternal(signature, 0) : await this.verifyHash(data, signature);
634
+ const signatureInfo = internal ? await this.verifyDataInternal(isNamedData ? signature.val : signature, 0) : await this.verifyHash(isNamedData ? data.val : data, isNamedData ? signature.val : signature);
587
635
  return {
588
636
  Success: true,
589
- Sign: signature,
637
+ Sign: isNamedData ? signature.val : signature,
590
638
  SignatureInfo: {
591
639
  Success: true,
592
640
  DateTimeStr: signatureInfo.timeInfo.time,
@@ -598,16 +646,23 @@ export default class DigitalSignature {
598
646
 
599
647
  /**
600
648
  * Выполнить подписание с проверкой подписи
601
- * @param {string} fileUrl - ссылка на загрузку файла для подписания
649
+ * @param {string | NamedData} fileUrl - ссылка на загрузку файла для подписания
602
650
  * @param {boolean} hash - подписывать хеш
603
651
  */
604
652
  async signFileEx(fileUrl, hash) {
605
- const data = await downloadData(fileUrl, "binary");
606
- const signature = hash ? await this.signHash(data) : await this.signData(data);
607
- const signatureInfo = hash ? await this.verifyHash(data, signature) : await this.verifyData(data, signature);
653
+ const isNamedData = typeof fileUrl === "object";
654
+ let data = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
655
+ if(!hash) {
656
+ data = await this._euSign.HashData(this._readedKey.getHashAlgo(), data, false);
657
+ if(isNamedData) {
658
+ data = {name: fileUrl.name, val: data};
659
+ }
660
+ }
661
+ const signature = await this.signHash(data);
662
+ const signatureInfo = await this.verifyHash(isNamedData ? data.val : data, isNamedData ? signature.val : signature);
608
663
  return {
609
664
  Success: true,
610
- Sign: signature,
665
+ Sign: isNamedData ? signature.val : signature,
611
666
  SignatureInfo: {
612
667
  Success: true,
613
668
  DateTimeStr: signatureInfo.timeInfo.time,
@@ -619,14 +674,15 @@ export default class DigitalSignature {
619
674
 
620
675
  /**
621
676
  * Выполнить подписание хеша с проверкой подписи
622
- * @param {string} hash - хеш для подписания
677
+ * @param {string | NamedData} hash - хеш для подписания
623
678
  */
624
679
  async signHashEx(hash) {
625
- const signature = await this.signHash(hash);
626
- const signatureInfo = await this.verifyHash(hash, signature);
680
+ const isNamedData = typeof hash === "object";
681
+ const signature = await this.signHash(isNamedData ? hash.val : hash);
682
+ const signatureInfo = await this.verifyHash(isNamedData ? hash.val : hash, isNamedData ? signature.val : signature);
627
683
  return {
628
684
  Success: true,
629
- Sign: signature,
685
+ Sign: isNamedData ? signature.val : signature,
630
686
  SignatureInfo: {
631
687
  Success: true,
632
688
  DateTimeStr: signatureInfo.timeInfo.time,
@@ -690,47 +746,49 @@ export default class DigitalSignature {
690
746
 
691
747
  /**
692
748
  * Сохранить ключ
693
- * @param {string} userId - id пользователя
694
749
  * @param {PrivateKeyInfo} privateKeyInfo - Ключ
750
+ * @param {boolean} toLocalStorage - Будет ли ключ сохранён после закрытия вкладки
695
751
  */
696
- async storePrivateKeyInfo(userId, privateKeyInfo) {
697
- let ls = await this.getStoredPrivateKeyInfo(userId);
698
- let keys = ls.filter(key => key.keyType == privateKeyInfo.keyType);
699
- let push = true;
700
- if(keys.length > 0){
701
- if(privateKeyInfo instanceof FilePrivateKeyInfo || privateKeyInfo instanceof HardwarePrivateKeyInfo){
702
- push = keys.filter(key => key.certificates[0].infoEx.serial == privateKeyInfo.certificates[0].infoEx.serial).length < 1;
703
- }
704
- else if(privateKeyInfo instanceof MobileIdPrivateKeyInfo){
705
- push = keys.filter(key => key.phone == privateKeyInfo.phone).length < 1;
706
- }
707
- else if(privateKeyInfo instanceof KspPrivateKeyInfo){
708
- push = keys.filter(key => key.userId == privateKeyInfo.userId).length < 1;
709
- }
752
+ async storePrivateKeyInfo(privateKeyInfo, toLocalStorage) {
753
+ if(privateKeyInfo.ksp && (privateKeyInfo.ksp == EndUserConstants.EndUserKSP.DIIA || privateKeyInfo.ksp == this.KSPs[1].name)) {
754
+ return;
710
755
  }
711
- if(push){
712
- ls.push(privateKeyInfo);
713
- let data = await this._euSign.ProtectDataByPassword(JSON.stringify(ls), "", true);
714
- localStorage[`${userId}_PrivateKeyInfo`] = data;
756
+
757
+ const storage = toLocalStorage ? localStorage : sessionStorage;
758
+ const keys = await this.getStoredPrivateKeyInfo();
759
+
760
+ if(keys.length == 0 || keys.filter(key => key.id == privateKeyInfo.id).length < 1) {
761
+ const keys = await this.getPrivateKeyInfoFromStorage(toLocalStorage);
762
+ keys.push(privateKeyInfo);
763
+ const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
764
+ storage[this._userId + this.PRIVATE_KEY_INFO] = data;
715
765
  }
716
766
  }
717
767
 
718
768
  /**
719
769
  * Получить сохранённые ключи
720
- * @param {string} userId - Id пользователя
721
770
  * @param {number?} keyType - Вид ключа
722
771
  * @returns {Array<PrivateKeyInfo>} Сохранённые ключи
723
772
  */
724
- async getStoredPrivateKeyInfo(userId, keyType) {
773
+ async getStoredPrivateKeyInfo(keyType) {
774
+ const local = await this.getPrivateKeyInfoFromStorage(true, keyType);
775
+ const session = await this.getPrivateKeyInfoFromStorage(false, keyType);
776
+ return local.concat(session);
777
+ }
778
+
779
+ async getPrivateKeyInfoFromStorage(fromLocalStorage, keyType) {
780
+ const storage = fromLocalStorage ? localStorage : sessionStorage;
781
+ const storedKeys = storage[this._userId + this.PRIVATE_KEY_INFO];
782
+
725
783
  let ls;
726
- let result = [];
727
- if(!localStorage[`${userId}_PrivateKeyInfo`]){
784
+ const result = [];
785
+ if(!storedKeys) {
728
786
  return result;
729
787
  }
730
- let data = await this._euSign.UnprotectDataByPassword(localStorage[`${userId}_PrivateKeyInfo`], "", true);
788
+ const data = await this._euSignFile.UnprotectDataByPassword(storedKeys, "", true);
731
789
  try{
732
790
  ls = JSON.parse(data);
733
- if(keyType >= 0){
791
+ if(keyType >= 0) {
734
792
  ls = ls.filter(key => key.keyType == keyType);
735
793
  }
736
794
  }
@@ -739,26 +797,25 @@ export default class DigitalSignature {
739
797
  }
740
798
 
741
799
  ls.forEach(key => {
742
- if(key.keyType == DigitalSignatureKeyType.File){
800
+ const password = key.password;
801
+ if(key.keyType == DigitalSignatureKeyType.File) {
743
802
  key.privateKey = new Uint8Array(Object.assign(new Array(), key.privateKey));
744
- key = new FilePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.privateKey);
803
+ key = new FilePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.privateKey, key.password);
745
804
  }
746
- else if (key.keyType == DigitalSignatureKeyType.Token){
805
+ else if (key.keyType == DigitalSignatureKeyType.Token) {
747
806
  key = new HardwarePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.keyMedia);
748
807
  }
749
- else if (key.keyType == DigitalSignatureKeyType.MobileID){
750
- key = new MobileIdPrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.phone, key.operatorId);
751
- }
752
- else if (key.keyType == DigitalSignatureKeyType.KSP){
808
+ else if (key.keyType == DigitalSignatureKeyType.KSP) {
753
809
  key = new KspPrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.userId, key.ksp);
754
810
  }
755
- let certs = [];
756
- key.certificates.forEach(cert =>{
757
- let certObj = Object.assign(new EndUserCertificate(), cert);
811
+ const certs = [];
812
+ key.certificates.forEach(cert => {
813
+ const certObj = Object.assign(new EndUserCertificate(), cert);
758
814
  certObj.data = new Uint8Array(Object.assign(new Array(), cert.data));
759
815
  certs.push(certObj);
760
816
  });
761
817
  key.certificates = certs;
818
+ key.password = password;
762
819
  result.push(key);
763
820
  });
764
821
  return result;
@@ -766,22 +823,56 @@ export default class DigitalSignature {
766
823
 
767
824
  /**
768
825
  * Удалить сохранённые ключи
769
- * @param {string} userId - id пользователя
770
- * @param {number?} keyId - Идекс ключа
826
+ * @param {string} keyId - Идентификатор ключа
771
827
  */
772
- async removeStoredPrivateKeyInfo(userId, keyId) {
773
- if(!keyId && keyId < 0){
774
- localStorage.removeItem(`${userId}_PrivateKeyInfo`);
828
+ async removeStoredPrivateKeyInfo(keyId) {
829
+ if (keyId === undefined) {
830
+ localStorage.removeItem(this._userId + this.PRIVATE_KEY_INFO);
831
+ sessionStorage.removeItem(this._userId + this.PRIVATE_KEY_INFO);
775
832
  }
776
833
  else{
777
- let ls = await this.getStoredPrivateKeyInfo(userId);
778
- ls.splice(keyId, 1);
779
- let data = await this._euSign.ProtectDataByPassword(JSON.stringify(ls), "", true);
780
- localStorage[`${userId}_PrivateKeyInfo`] = data;
834
+ const localStoredKeys = await this.getPrivateKeyInfoFromStorage(true);
835
+ const sessionStoredKeys = await this.getPrivateKeyInfoFromStorage(false);
836
+ const storage = localStoredKeys.filter(item => item.id == keyId).length > 0 ? localStorage : sessionStorage;
837
+ const keys = storage == localStorage ? localStoredKeys : sessionStoredKeys;
838
+ const keyIndex = keys.findIndex((element) => element.id == keyId);
839
+
840
+ if(keyIndex > -1) {
841
+ keys.splice(keyIndex, 1);
842
+ const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
843
+ storage[this._userId + this.PRIVATE_KEY_INFO] = data;
844
+ }
845
+ }
846
+ }
847
+
848
+ /**
849
+ * Получить предпочитаемый тип ключа
850
+ */
851
+ get _preferredKeyType () {
852
+ const keyType = parseInt(localStorage[this._userId + this.PRIVATE_KEY_TYPE]);
853
+ if (typeof keyType === "number" && keyType > -1) {
854
+ return keyType;
855
+ } else {
856
+ localStorage[this._userId + this.PRIVATE_KEY_TYPE] = DigitalSignatureKeyType.File;
857
+ return DigitalSignatureKeyType.File;
858
+ }
859
+ }
860
+
861
+ /**
862
+ * Задать предпочитаемый тип ключа
863
+ * @param {DigitalSignatureKeyType | number} keyType - Тип ключа
864
+ */
865
+ set _preferredKeyType (keyType) {
866
+ if (typeof keyType === "number" && keyType > -1) {
867
+ localStorage[this._userId + this.PRIVATE_KEY_TYPE] = keyType;
781
868
  }
782
869
  }
783
870
 
784
871
  get _resourses() {
785
872
  return Resourses[this._settings.language];
786
873
  }
874
+
875
+ get _userId () {
876
+ return typeof this._settings.userId === "function" ? this._settings.userId() : this._settings.userId;
877
+ }
787
878
  }
package/src/GlSign.js CHANGED
@@ -48,7 +48,7 @@ export default class GlSign {
48
48
  this.IdleTimeout = parseInt(this._getZoneValue(settingArray, 12));
49
49
  this.DeviceType = this._getZoneValue(settingArray, 13);
50
50
  this.PreferHarware = this._getZoneValue(settingArray, 16);
51
- this.HideMobileId = this._getZoneValue(settingArray, 17);
51
+ this.HideMobileId = true;
52
52
 
53
53
  this.UseProxy = this._getSubZoneValue(settingArray, 19, ",", 1) === "+";
54
54
  this.ProxyAddress = this._getSubZoneValue(settingArray, 19, ",", 2);
@@ -85,6 +85,3 @@ export default class GlSign {
85
85
  return this._getZoneValue(subZones, subzone);
86
86
  }
87
87
  }
88
-
89
-
90
-