@it-enterprise/digital-signature 1.1.7 → 1.2.0
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/euscp/EndUserConstants.d.ts +44 -22
- package/euscp/EndUserSettings.d.ts +3 -1
- package/euscp/EndUserSignContainerInfo.d.ts +10 -0
- package/euscp/EndUserSignInfo.d.ts +2 -0
- package/euscp/euscp.d.ts +29 -4
- package/euscp/euscp.js +2 -2
- package/package.json +1 -1
- package/src/DigitalSignature.js +369 -193
- package/src/Models.js +89 -118
- package/src/Resourses.json +30 -3
- package/src/Utils.js +57 -1
package/src/Models.js
CHANGED
|
@@ -2,7 +2,7 @@ import { EndUserCertificate, EndUserError, EndUserOwnerInfo, EndUserConstants }
|
|
|
2
2
|
import GlSign from "./GlSign";
|
|
3
3
|
import { downloadData, byteArrayToBase64, base64ToByteArray, signAlgoToHashAlgo, getSupportedSignAlgos } from "./Utils";
|
|
4
4
|
|
|
5
|
-
const LIBRARY_VERSION = "1.3.
|
|
5
|
+
const LIBRARY_VERSION = "1.3.53";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Параметры библиотеки электронной подписи
|
|
@@ -12,14 +12,14 @@ export class DigitalSignatureSettings {
|
|
|
12
12
|
* @param {string} language - Язык. Поддержываемые значения: en, ru, uk
|
|
13
13
|
* @param {string} userId - id пользователя (для сохранения ключей и предпочитаемого типа ключа)
|
|
14
14
|
* @param {string} httpProxyServiceURL - Ссылка на ProxyHandler
|
|
15
|
-
* @param {
|
|
15
|
+
* @param {DefaultCertificatesProvider | WebCalcCertificatesProvider} certificatesProvider - Сервис для получения сертификатов
|
|
16
|
+
* @param {string} libraryUrl - ссылка на WebWorker
|
|
16
17
|
*/
|
|
17
|
-
constructor(language, userId, httpProxyServiceURL, certificatesProvider,
|
|
18
|
-
this.language = language || "
|
|
18
|
+
constructor(language, userId, httpProxyServiceURL, certificatesProvider, libraryUrl) {
|
|
19
|
+
this.language = language || "en";
|
|
19
20
|
this.userId = userId;
|
|
20
21
|
this.httpProxyServiceURL = httpProxyServiceURL;
|
|
21
22
|
this.certificatesProvider = certificatesProvider;
|
|
22
|
-
this.mssServiceURL = mssServiceURL;
|
|
23
23
|
this.libraryUrl = libraryUrl;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -31,10 +31,7 @@ export class DefaultSettingProvider {
|
|
|
31
31
|
/**
|
|
32
32
|
* @param {string} language - Язык ошибок
|
|
33
33
|
* @param {string | function} userId - id пользователя (для сохранения ключей и предпочитаемого типа ключа)
|
|
34
|
-
* @param {string}
|
|
35
|
-
* @param {string} basePath - путь к ProxyHandler
|
|
36
|
-
* @param {string} certificatesPath - путь к папке с сертификатами
|
|
37
|
-
*
|
|
34
|
+
* @param {string} basePath - путь к api ЕЦП
|
|
38
35
|
*/
|
|
39
36
|
constructor(language, userId, basePath) {
|
|
40
37
|
if (typeof basePath !== "string") {
|
|
@@ -56,64 +53,63 @@ export class DefaultSettingProvider {
|
|
|
56
53
|
}
|
|
57
54
|
|
|
58
55
|
async getSettings() {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this._settings = new DigitalSignatureSettings(
|
|
62
|
-
this.language,
|
|
63
|
-
this.userId,
|
|
64
|
-
this.basePath + "/ProxyHandler",
|
|
65
|
-
new UriCertificatesProvider(
|
|
66
|
-
this.basePath + "/files?name=CAs.json",
|
|
67
|
-
this.basePath + "/files?name=CACertificates.p7b"
|
|
68
|
-
),
|
|
69
|
-
this.basePath + "/KSPSign",
|
|
70
|
-
URL.createObjectURL(await downloadData(this.basePath + `/files?name=euscp.worker-${LIBRARY_VERSION}.js`, "blob"))
|
|
71
|
-
);
|
|
56
|
+
if (this._settings) {
|
|
57
|
+
return this._settings;
|
|
72
58
|
}
|
|
73
59
|
|
|
60
|
+
this._settings = new DigitalSignatureSettings(
|
|
61
|
+
this.language,
|
|
62
|
+
this.userId,
|
|
63
|
+
this.basePath + "/ProxyHandler",
|
|
64
|
+
new DefaultCertificatesProvider(
|
|
65
|
+
this.basePath + "/files?name=CAs.json",
|
|
66
|
+
this.basePath + "/files?name=CACertificates.p7b"
|
|
67
|
+
),
|
|
68
|
+
URL.createObjectURL(await downloadData(this.basePath + `/files?name=euscp.worker-${LIBRARY_VERSION}.js`, "blob"))
|
|
69
|
+
);
|
|
70
|
+
|
|
74
71
|
return this._settings;
|
|
75
72
|
}
|
|
76
73
|
}
|
|
77
74
|
|
|
78
|
-
|
|
79
|
-
* Фабрика настроек для библиотеки. Использовать в GraphQl приложениях
|
|
80
|
-
*/
|
|
81
|
-
export class GraphQlSettingProvider {
|
|
75
|
+
export class LegacySettingsProvider {
|
|
82
76
|
/**
|
|
83
77
|
* @param {string} language - Язык ошибок
|
|
84
78
|
* @param {string | function} userId - id пользователя (для сохранения ключей и предпочитаемого типа ключа)
|
|
85
|
-
* @param {string}
|
|
86
|
-
* @param {string}
|
|
87
|
-
* @param {Object} auth - Функция для получения токена авторизации
|
|
79
|
+
* @param {string} basePath - путь к api ЕЦП
|
|
80
|
+
* @param {string} glsign - ПГУ GlSign
|
|
88
81
|
*/
|
|
89
|
-
constructor(language, userId,
|
|
90
|
-
if (typeof
|
|
82
|
+
constructor(language, userId, basePath, glsign) {
|
|
83
|
+
if (typeof basePath !== "string") {
|
|
91
84
|
throw {
|
|
92
85
|
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
93
|
-
message: "
|
|
86
|
+
message: "basePath is not a string"
|
|
94
87
|
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
graphQlUri = graphQlUri.substring(0, graphQlUri.length - 1);
|
|
88
|
+
} else if (basePath.endsWith("/")) {
|
|
89
|
+
basePath = basePath.substring(0, basePath.length - 1);
|
|
98
90
|
}
|
|
99
91
|
|
|
100
92
|
this.language = language;
|
|
101
93
|
this.userId = userId;
|
|
102
|
-
this.
|
|
103
|
-
this.
|
|
104
|
-
this.auth = auth;
|
|
94
|
+
this.basePath = basePath;
|
|
95
|
+
this.glsign = glsign;
|
|
105
96
|
}
|
|
106
97
|
|
|
107
|
-
|
|
108
|
-
return
|
|
98
|
+
getGlSign() {
|
|
99
|
+
return typeof this.glsign === "string" ? new GlSign(this.glsign) : this.glsign;
|
|
109
100
|
}
|
|
110
101
|
|
|
111
102
|
getSettings(testMode) {
|
|
112
|
-
return new DigitalSignatureSettings(
|
|
113
|
-
this.language,
|
|
103
|
+
return new DigitalSignatureSettings(this.language,
|
|
114
104
|
this.userId,
|
|
115
|
-
this.
|
|
116
|
-
new
|
|
105
|
+
this.basePath + "/ProxyHandler",
|
|
106
|
+
new LegacyCertificatesProvider(
|
|
107
|
+
testMode,
|
|
108
|
+
this.basePath + "/Data/version.txt",
|
|
109
|
+
this.basePath + testMode ? "/Data/CAs.test.json" : "/Data/CAs.json",
|
|
110
|
+
this.basePath + testMode ? "/Data/CACertificates.p7b" : "/Data/CACertificates.p7b"
|
|
111
|
+
),
|
|
112
|
+
this.basePath + `/Scripts/euscp.worker.ex-${LIBRARY_VERSION}.js`
|
|
117
113
|
);
|
|
118
114
|
}
|
|
119
115
|
}
|
|
@@ -157,7 +153,7 @@ export class CertificatesProvider {
|
|
|
157
153
|
/**
|
|
158
154
|
* Класс для загрузки сертификатов по ссылкам
|
|
159
155
|
*/
|
|
160
|
-
export class
|
|
156
|
+
export class DefaultCertificatesProvider extends CertificatesProvider {
|
|
161
157
|
/**
|
|
162
158
|
* @param {boolean} testMode - Тестовый режим
|
|
163
159
|
* @param {string} versionUri - Ссылка на файл с текущей версией сертификатов
|
|
@@ -185,83 +181,64 @@ export class UriCertificatesProvider extends CertificatesProvider {
|
|
|
185
181
|
}
|
|
186
182
|
}
|
|
187
183
|
|
|
188
|
-
|
|
189
|
-
* Класс для загрузки сертификатов через GraphQl
|
|
190
|
-
*/
|
|
191
|
-
export class GraphQlCertificatesProvider extends CertificatesProvider {
|
|
184
|
+
export class LegacyCertificatesProvider extends CertificatesProvider {
|
|
192
185
|
/**
|
|
193
|
-
* @param {boolean} testMode -
|
|
194
|
-
* @param {string}
|
|
195
|
-
* @param {string}
|
|
186
|
+
* @param {boolean} testMode - Тестовый режим
|
|
187
|
+
* @param {string} versionUri - Ссылка на файл с текущей версией сертификатов
|
|
188
|
+
* @param {string} CAsUri - Ссылка на файл со списком ЦСК
|
|
189
|
+
* @param {string} CACertificatesUri - Ссылка на файл с корневыми сертификатами ЦСК
|
|
196
190
|
*/
|
|
197
|
-
constructor(testMode,
|
|
191
|
+
constructor(testMode, versionUri, CAsUri, CACertificatesUri) {
|
|
198
192
|
super(testMode);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
203
|
-
message: "wsUri is not string"
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
if (wsUri.endsWith("/")) {
|
|
207
|
-
wsUri = wsUri.substring(0, wsUri.length - 1);
|
|
208
|
-
}
|
|
209
|
-
this.wsUri = wsUri;
|
|
210
|
-
this.graphQlUri = graphQlUri;
|
|
193
|
+
this.versionUri = versionUri;
|
|
194
|
+
this.CAsUri = CAsUri;
|
|
195
|
+
this.CACertificatesUri = CACertificatesUri;
|
|
211
196
|
}
|
|
212
197
|
|
|
213
198
|
async loadCertificates() {
|
|
214
|
-
let CAs = this._getItem("
|
|
215
|
-
CACertificates = this._getItem("
|
|
216
|
-
|
|
217
|
-
CAsVersion = this._getItem("CAsVersion");
|
|
218
|
-
|
|
219
|
-
const version = { VERSIONCAS: CAsVersion, VERSIONCERT: CACertificatesVersion, INCLUDETEST: this.testMode };
|
|
220
|
-
|
|
221
|
-
if (CAs) {
|
|
222
|
-
try {
|
|
223
|
-
CAs = JSON.parse(CAs);
|
|
224
|
-
} catch (error) {
|
|
225
|
-
console.error(error);
|
|
226
|
-
CAs = null;
|
|
227
|
-
version.VERSIONCAS = null;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
199
|
+
let CAs = this._getItem("CA"),
|
|
200
|
+
CACertificates = this._getItem("Certificates"),
|
|
201
|
+
CACertificatesVersion = this._getItem("CAVersion");
|
|
230
202
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
203
|
+
try {
|
|
204
|
+
const currentVersion = await downloadData(this.versionUri);
|
|
205
|
+
if (currentVersion != CACertificatesVersion) {
|
|
206
|
+
CACertificatesVersion = currentVersion;
|
|
207
|
+
CAs = null;
|
|
236
208
|
CACertificates = null;
|
|
237
|
-
version.VERSIONCERT = null;
|
|
238
209
|
}
|
|
239
|
-
}
|
|
240
210
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
211
|
+
if (CAs) {
|
|
212
|
+
try {
|
|
213
|
+
CAs = JSON.parse(CAs);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error(error);
|
|
216
|
+
CAs = null;
|
|
217
|
+
}
|
|
245
218
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
this._setItem("CAs", JSON.stringify(CAs));
|
|
250
|
-
this._setItem("CAsVersion", res.VERSIONCAS);
|
|
219
|
+
if (!CAs) {
|
|
220
|
+
CAs = await downloadData(this.CAsUri, "json");
|
|
221
|
+
this._setItem("CA", JSON.stringify(CAs));
|
|
251
222
|
}
|
|
252
223
|
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
224
|
+
if (CACertificates) {
|
|
225
|
+
try {
|
|
226
|
+
CACertificates = base64ToByteArray(CACertificates);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error(error);
|
|
229
|
+
CACertificates = null;
|
|
230
|
+
}
|
|
257
231
|
}
|
|
258
|
-
|
|
232
|
+
if (!CACertificates) {
|
|
233
|
+
CACertificates = await downloadData(this.CACertificatesUri, "binary");
|
|
234
|
+
this._setItem("Certificates", byteArrayToBase64(CACertificates));
|
|
235
|
+
}
|
|
236
|
+
this._setItem("CAVersion", CACertificatesVersion);
|
|
259
237
|
return { CAs, CACertificates };
|
|
260
238
|
} catch (error) {
|
|
261
|
-
this._removeItem("
|
|
262
|
-
this._removeItem("
|
|
263
|
-
this._removeItem("
|
|
264
|
-
this._removeItem("CACertificatesVersion");
|
|
239
|
+
this._removeItem("CA");
|
|
240
|
+
this._removeItem("CAVersion");
|
|
241
|
+
this._removeItem("Certificates");
|
|
265
242
|
console.error(error);
|
|
266
243
|
throw {
|
|
267
244
|
code: EndUserError.EU_ERROR_DOWNLOAD_FILE,
|
|
@@ -280,7 +257,7 @@ export const DigitalSignatureLibraryTypeSW = 1;
|
|
|
280
257
|
* Типы библиотеки
|
|
281
258
|
*/
|
|
282
259
|
export const DigitalSignatureLibraryType = {
|
|
283
|
-
/** Подпись файловыми ключами */
|
|
260
|
+
/** Подпись файловыми ключами и через облачные сервисы */
|
|
284
261
|
JS: DigitalSignatureLibraryTypeJS,
|
|
285
262
|
/** Подпись аппартными ключами */
|
|
286
263
|
SW: DigitalSignatureLibraryTypeSW
|
|
@@ -290,12 +267,8 @@ export const DigitalSignatureLibraryType = {
|
|
|
290
267
|
export const DigitalSignatureKeyTypeFile = 0;
|
|
291
268
|
/** Аппаратный ключ */
|
|
292
269
|
export const DigitalSignatureKeyTypeToken = 1;
|
|
293
|
-
/** DepositSign */
|
|
294
|
-
export const DigitalSignatureKeyTypeDepositsign = 2;
|
|
295
|
-
/** Дiя */
|
|
296
|
-
export const DigitalSignatureKeyTypeDiia = 3;
|
|
297
270
|
/** Облачный сервис */
|
|
298
|
-
export const DigitalSignatureKeyTypeKSP =
|
|
271
|
+
export const DigitalSignatureKeyTypeKSP = 2;
|
|
299
272
|
|
|
300
273
|
/**
|
|
301
274
|
* Типы ключей
|
|
@@ -303,9 +276,7 @@ export const DigitalSignatureKeyTypeKSP = 4;
|
|
|
303
276
|
export const DigitalSignatureKeyType = {
|
|
304
277
|
File: DigitalSignatureKeyTypeFile,
|
|
305
278
|
Token: DigitalSignatureKeyTypeToken,
|
|
306
|
-
|
|
307
|
-
Diia: DigitalSignatureKeyTypeDiia,
|
|
308
|
-
KSP: DigitalSignatureKeyTypeKSP
|
|
279
|
+
KSP: DigitalSignatureKeyTypeKSP,
|
|
309
280
|
};
|
|
310
281
|
|
|
311
282
|
export class PrivateKeyInfo {
|
|
@@ -376,13 +347,13 @@ export class PrivateKeyInfo {
|
|
|
376
347
|
*/
|
|
377
348
|
getSignAlgo() {
|
|
378
349
|
const certificates = this.certificates;
|
|
379
|
-
if(this
|
|
350
|
+
if (this.keyType === DigitalSignatureKeyTypeKSP) {
|
|
380
351
|
return EndUserConstants.EndUserSignAlgo.DSTU4145WithGOST34311;
|
|
381
352
|
}
|
|
382
|
-
else if(certificates.length > 0) {
|
|
353
|
+
else if (certificates.length > 0) {
|
|
383
354
|
return getSupportedSignAlgos(certificates)[0];
|
|
384
355
|
}
|
|
385
|
-
else{
|
|
356
|
+
else {
|
|
386
357
|
return EndUserConstants.EndUserSignAlgo.Unknown;
|
|
387
358
|
}
|
|
388
359
|
}
|
package/src/Resourses.json
CHANGED
|
@@ -9,7 +9,16 @@
|
|
|
9
9
|
"LibraryInstall": "Інсталяційний пакет web-бібліотеки підпису",
|
|
10
10
|
"LibraryUpdate": "Оновлення web-бібліотеки підпису",
|
|
11
11
|
"PrivateKeyNotReaded": "Особистий ключ не считано.",
|
|
12
|
-
"DiiaError": "Дія.Підпис – сервіс для накладання кваліфікованого електронного підпису за допомогою смартфону і додатку «Дія».<br/>Для можливості використання «Дія.Підпис» у даній інсталяції системи вам необхідно звернутися до свого постачальника.<br/>У зверненні вкажіть наступну інформацію:<br/><ul><li>Посилання: "
|
|
12
|
+
"DiiaError": "Дія.Підпис – сервіс для накладання кваліфікованого електронного підпису за допомогою смартфону і додатку «Дія».<br/>Для можливості використання «Дія.Підпис» у даній інсталяції системи вам необхідно звернутися до свого постачальника.<br/>У зверненні вкажіть наступну інформацію:<br/><ul><li>Посилання: ",
|
|
13
|
+
"XadesError": "Перевірка кваліфікованого електронного підпису, який сформовано у вигляді окремого файлу з розширенням .xml виконується за умов наявності файлу з даними, на які накладено кваліфікований електронний підпис. Ім`я такого файлу зазвичай ідентичне з іменем файлу файлу з розширенням .xml. Оберіть цей файл разом з файлом кваліфікованого електронного підпису.",
|
|
14
|
+
"KSPSignFormatError": "Хмарні сервіси підтримують тільки підписи типу CAdES",
|
|
15
|
+
"BadSignatureType": "Невірний тип підпису",
|
|
16
|
+
"DownloadingRootCertificatesError": "Помилка при завантаженні сертифікатів ЦСК або списку ЦСК. Перевірте наявність налаштувань ЦСК в функції \"Інструменти і налаштування → Електронний підпис → Налаштування ЦСК\" та виконання задачі планувальника UPDATECASCERTIFICATES.",
|
|
17
|
+
"BadParameter": "Невірний параметр",
|
|
18
|
+
"PasswordNotSet": "Не вказано пароль до особистого ключа",
|
|
19
|
+
"ReadPrivateKeyCAAutoDetectError": "Надавач не підтримує автоматичний пошук сертифіката за ос. ключем. Необхідно обрати надавача самостійно",
|
|
20
|
+
"ReadPrivateKeyInvalidCAError": "Ваш сертифікат виданий іншим надавачем та не обслуговується в {0}. Необхідно обрати надавача Вашого сертифіката",
|
|
21
|
+
"ReadPrivateKeyNeedCertificateError": "Надавач {0} не підтримує автоматичний пошук сертифіката за ос. ключем. Необхідно обрати сертифікат(и) ос. ключа"
|
|
13
22
|
},
|
|
14
23
|
"ru": {
|
|
15
24
|
"LibraryNotSupported": "Библиотека web-подписи не поддерживается в вашем браузере или ОС.",
|
|
@@ -21,7 +30,16 @@
|
|
|
21
30
|
"LibraryInstall": "Установочный пакет web-библиотеки подписи",
|
|
22
31
|
"LibraryUpdate": "Обновление web-библиотеки подписи",
|
|
23
32
|
"PrivateKeyNotReaded": "Приватный ключ не считан.",
|
|
24
|
-
"DiiaError": "Дія.Підпис – сервис для наложения квалифицированной электронной подписи с помощью смартфона и приложения «Дія».<br/>Для возможности использования «Дія.Підпис» в данной инсталляции системы вам необходимо обратиться к своему поставщику.<br/>В обращении укажите следующую информацию:<br/><ul><li>Ссылка: "
|
|
33
|
+
"DiiaError": "Дія.Підпис – сервис для наложения квалифицированной электронной подписи с помощью смартфона и приложения «Дія».<br/>Для возможности использования «Дія.Підпис» в данной инсталляции системы вам необходимо обратиться к своему поставщику.<br/>В обращении укажите следующую информацию:<br/><ul><li>Ссылка: ",
|
|
34
|
+
"XadesError": "Проверка квалифицированной электронной подписи, которая сформирована в виде отдельного файла с расширением .xml, выполняется при наличии файла с данными, на которые наложена квалифицированная электронная подпись. Имя такого файла обычно идентично с именем файла с расширением .xml. Выберите этот файл вместе с квалифицированной электронной подписью.",
|
|
35
|
+
"KSPSignFormatError": "Облачные сервисы поддерживают только подписи типа CAdES",
|
|
36
|
+
"BadSignatureType": "Неверный тип подписи",
|
|
37
|
+
"DownloadingRootCertificatesError": "Ошибка при загрузке корневых сертификатов ЦСК, либо списка ЦСК. Проверьте наличие настроек ЦСК в функции \"Инструменты и настройки → Электронная подпись → Настройки ЦСК\" и выполнение задачи планировщика UPDATECASCERTIFICATES.",
|
|
38
|
+
"BadParameter": "Неверный параметр",
|
|
39
|
+
"PasswordNotSet": "Не указан пароль к приватному ключу",
|
|
40
|
+
"ReadPrivateKeyCAAutoDetectError": "Центр сертификации не поддерживает автоматический поиск сертификата по приватному ключу. Необходимо выбрать центр сертификации самостоятельно,",
|
|
41
|
+
"ReadPrivateKeyInvalidCAError": "Ваш сертификат выдан в другом центре сертификации и не обслуживается в {0}. Необходимо выбрать центр сертификации Вашего сертификата,",
|
|
42
|
+
"ReadPrivateKeyNeedCertificateError": "Центр сертификации {0} не поддерживает автоматический поиск сертификата по приватному ключу. Нобходимо указать сертификат(ы) приватного ключа,"
|
|
25
43
|
},
|
|
26
44
|
"en": {
|
|
27
45
|
"LibraryNotSupported": "Web-signature library is not supported in your browser or OS.",
|
|
@@ -33,6 +51,15 @@
|
|
|
33
51
|
"LibraryInstall": "Web-signature library installation package",
|
|
34
52
|
"LibraryUpdate": "Web-signature library update package",
|
|
35
53
|
"PrivateKeyNotReaded": "Private key not readed.",
|
|
36
|
-
"DiiaError": "Дія.Підпис - a service for applying a qualified
|
|
54
|
+
"DiiaError": "Дія.Підпис - a service for applying a qualified digital signature using a smartphone and the application \"Дія\". <br/> To be able to use \"Дія.Підпис\" in this system, you need to contact your provider. <br/> Please include the following information in your request: <br/> <ul> <li> Link: ",
|
|
55
|
+
"XadesError": "The verification of a qualified digital signature, which is formed as a separate file with the extension .xml, is performed under the conditions of the file with the data on which the qualified digital signature is affixed. The name of such a file is usually identical to the filename of the .xml file. Select this file along with the qualified digital signature file.",
|
|
56
|
+
"KSPSignFormatError": "Cloud services only supports CAdES signatures",
|
|
57
|
+
"BadSignatureType": "Invalid signature type",
|
|
58
|
+
"DownloadingRootCertificatesError": "Error occured while downloading root CA certificates or CA list. Check for CA setting in function \"Tools and settings → Electronic signature → CA settings\" and execution of task scheduler UPDATECASCERTIFICATES.",
|
|
59
|
+
"BadParameter": "Invalid parameter",
|
|
60
|
+
"PasswordNotSet": "Private key password not specified.",
|
|
61
|
+
"ReadPrivateKeyCAAutoDetectError": "Certification authority does not support automatic search for a certificate by private key. You need to choose a certification authority yourself.",
|
|
62
|
+
"ReadPrivateKeyInvalidCAError": "Your certificate was issued by a different CA and is not being serviced in {0}. You need to select a certification authority for your certificate.",
|
|
63
|
+
"ReadPrivateKeyNeedCertificateError": "Certification authority {0} does not support automatic search for a certificate by private key. You must specify the certificates of the private key."
|
|
37
64
|
}
|
|
38
65
|
}
|
package/src/Utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EndUserCertificate, EndUserConstants } from "../euscp/euscp";
|
|
1
|
+
import { EndUserCertificate, EndUserConstants, EndUserError } from "../euscp/euscp";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Загрузить данные по ссылке
|
|
@@ -84,6 +84,13 @@ export function makeUrl(url) {
|
|
|
84
84
|
return url;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
export function format(format) {
|
|
88
|
+
const args = Array.prototype.slice.call(arguments, 1);
|
|
89
|
+
return format.replace(/{(\d+)}/g, function (match, number) {
|
|
90
|
+
return typeof args[number] != "undefined" ? args[number] : match;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
87
94
|
export function readFile(file) {
|
|
88
95
|
return new Promise((resolve, reject) => {
|
|
89
96
|
const reader = new FileReader();
|
|
@@ -176,3 +183,52 @@ export function getSupportedSignAlgos(certificates) {
|
|
|
176
183
|
});
|
|
177
184
|
return signAlgos;
|
|
178
185
|
}
|
|
186
|
+
|
|
187
|
+
export function isUrlValid(url) {
|
|
188
|
+
try {
|
|
189
|
+
return !!new URL(url);
|
|
190
|
+
} catch {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function getFileNameFromUrl(url) {
|
|
196
|
+
return new URL(url).pathname.split("/").pop();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function downloadAndSignFiles(fileUrl, signFunc) {
|
|
200
|
+
const isParamValid = (url) => typeof url === "string" && isUrlValid(url) || typeof url === "object" && typeof url.name === "string" && typeof url.val === "string" && isUrlValid(url.val);
|
|
201
|
+
|
|
202
|
+
if (Array.isArray(fileUrl)) {
|
|
203
|
+
if (!fileUrl.every(isParamValid) || !(fileUrl.every(url => typeof url === "string") || fileUrl.every(url => typeof url === "object"))) {
|
|
204
|
+
throw {
|
|
205
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
206
|
+
message: "Bad parameter fileUrl"
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
const returnNamedData = fileUrl.every(url => typeof url === "object");
|
|
210
|
+
|
|
211
|
+
fileUrl = await Promise.all(fileUrl.map(async (url) => typeof url === "object"
|
|
212
|
+
? { name: url.name, val: await downloadData(url.val, "binary") }
|
|
213
|
+
: { name: getFileNameFromUrl(url), val: await downloadData(url, "binary") }));
|
|
214
|
+
|
|
215
|
+
const signs = await signFunc(fileUrl);
|
|
216
|
+
return returnNamedData ? signs : signs.map(sign => sign.val);
|
|
217
|
+
} else {
|
|
218
|
+
if (!isParamValid(fileUrl)) {
|
|
219
|
+
throw {
|
|
220
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
221
|
+
message: "Bad parameter fileUrl"
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const returnNamedData = typeof fileUrl === "object";
|
|
226
|
+
|
|
227
|
+
fileUrl = typeof fileUrl === "object"
|
|
228
|
+
? { name: fileUrl.name, val: await downloadData(fileUrl.val, "binary") }
|
|
229
|
+
: { name: getFileNameFromUrl(fileUrl), val: await downloadData(fileUrl, "binary") };
|
|
230
|
+
|
|
231
|
+
const sign = await signFunc(fileUrl);
|
|
232
|
+
return returnNamedData ? sign : sign.val;
|
|
233
|
+
}
|
|
234
|
+
}
|