@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/.eslintrc.js +14 -3
- package/euscp/EndUserConstants.d.ts +50 -0
- package/euscp/euscp.d.ts +90 -1
- package/euscp/euscp.js +2 -2
- package/package.json +1 -1
- package/readme.md +19 -11
- package/src/DigitalSignature.js +191 -100
- package/src/GlSign.js +1 -4
- package/src/Models.js +46 -38
- package/src/Resourses.json +6 -3
- package/.gitlab-ci.yml +0 -12
package/package.json
CHANGED
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
|
|
215
|
-
const keyInfo = await ds.readPrivateKeyKSP(
|
|
216
|
+
const keyInfo = await ds.readPrivateKeyDepositsign(
|
|
216
217
|
// Идентификатор пользователя (номер телефона или email)
|
|
217
218
|
phone,
|
|
218
|
-
|
|
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
|
|
package/src/DigitalSignature.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings, EndUserCertificate } from "../euscp/euscp";
|
|
2
|
-
import { DigitalSignatureKeyType, PrivateKeyInfo, FilePrivateKeyInfo, HardwarePrivateKeyInfo,
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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 :
|
|
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
|
-
* Считать ключ
|
|
320
|
-
* @param {string}
|
|
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
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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
|
-
|
|
336
|
-
|
|
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.
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
606
|
-
|
|
607
|
-
|
|
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
|
|
626
|
-
const
|
|
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(
|
|
697
|
-
|
|
698
|
-
|
|
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
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
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
|
-
|
|
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
|
-
|
|
727
|
-
if(!
|
|
784
|
+
const result = [];
|
|
785
|
+
if(!storedKeys) {
|
|
728
786
|
return result;
|
|
729
787
|
}
|
|
730
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
756
|
-
key.certificates.forEach(cert =>{
|
|
757
|
-
|
|
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}
|
|
770
|
-
* @param {number?} keyId - Идекс ключа
|
|
826
|
+
* @param {string} keyId - Идентификатор ключа
|
|
771
827
|
*/
|
|
772
|
-
async removeStoredPrivateKeyInfo(
|
|
773
|
-
|
|
774
|
-
localStorage.removeItem(
|
|
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
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
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 =
|
|
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
|
-
|