@islom929/react-eimzo 0.4.3 → 0.4.5

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": "@islom929/react-eimzo",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "React hook for E-IMZO digital signatures. Simple API, zero UI dependencies.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -14,7 +14,8 @@
14
14
  }
15
15
  },
16
16
  "files": [
17
- "dist"
17
+ "dist",
18
+ "src"
18
19
  ],
19
20
  "scripts": {
20
21
  "build": "node scripts/embed-sdk.js && tsup",
@@ -48,13 +49,13 @@
48
49
  "imzo"
49
50
  ],
50
51
  "license": "MIT",
51
- "homepage": "https://github.com/islom929/react-eimzo#readme",
52
+ "homepage": "https://github.com/islom929/react-eimzo-package#readme",
52
53
  "repository": {
53
54
  "type": "git",
54
- "url": "git+https://github.com/islom929/react-eimzo.git"
55
+ "url": "git+https://github.com/islom929/react-eimzo-package.git"
55
56
  },
56
57
  "bugs": {
57
- "url": "https://github.com/islom929/react-eimzo/issues"
58
+ "url": "https://github.com/islom929/react-eimzo-package/issues"
58
59
  },
59
60
  "author": "islom929"
60
61
  }
package/src/e-imzo.js ADDED
@@ -0,0 +1,664 @@
1
+ (function(global) {
2
+ 'use strict';
3
+ var _Base64 = global.Base64;
4
+ var version = "2.1.4";
5
+ var buffer;
6
+ if (typeof module !== 'undefined' && module.exports) {
7
+ buffer = require('buffer').Buffer;
8
+ }
9
+ var b64chars
10
+ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
11
+ var b64tab = function(bin) {
12
+ var t = {};
13
+ for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
14
+ return t;
15
+ }(b64chars);
16
+ var fromCharCode = String.fromCharCode;
17
+ var cb_utob = function(c) {
18
+ if (c.length < 2) {
19
+ var cc = c.charCodeAt(0);
20
+ return cc < 0x80 ? c
21
+ : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
22
+ + fromCharCode(0x80 | (cc & 0x3f)))
23
+ : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
24
+ + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
25
+ + fromCharCode(0x80 | ( cc & 0x3f)));
26
+ } else {
27
+ var cc = 0x10000
28
+ + (c.charCodeAt(0) - 0xD800) * 0x400
29
+ + (c.charCodeAt(1) - 0xDC00);
30
+ return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
31
+ + fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
32
+ + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
33
+ + fromCharCode(0x80 | ( cc & 0x3f)));
34
+ }
35
+ };
36
+ var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
37
+ var utob = function(u) {
38
+ return u.replace(re_utob, cb_utob);
39
+ };
40
+ var cb_encode = function(ccc) {
41
+ var padlen = [0, 2, 1][ccc.length % 3],
42
+ ord = ccc.charCodeAt(0) << 16
43
+ | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
44
+ | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
45
+ chars = [
46
+ b64chars.charAt( ord >>> 18),
47
+ b64chars.charAt((ord >>> 12) & 63),
48
+ padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
49
+ padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
50
+ ];
51
+ return chars.join('');
52
+ };
53
+ var btoa = global.btoa ? function(b) {
54
+ return global.btoa(b);
55
+ } : function(b) {
56
+ return b.replace(/[\s\S]{1,3}/g, cb_encode);
57
+ };
58
+ var _encode = buffer
59
+ ? function (u) { return (new buffer(u)).toString('base64') }
60
+ : function (u) { return btoa(utob(u)) }
61
+ ;
62
+ var encode = function(u, urisafe) {
63
+ return !urisafe
64
+ ? _encode(u)
65
+ : _encode(u).replace(/[+\/]/g, function(m0) {
66
+ return m0 == '+' ? '-' : '_';
67
+ }).replace(/=/g, '');
68
+ };
69
+ var encodeURI = function(u) { return encode(u, true) };
70
+ var re_btou = new RegExp([
71
+ '[\xC0-\xDF][\x80-\xBF]',
72
+ '[\xE0-\xEF][\x80-\xBF]{2}',
73
+ '[\xF0-\xF7][\x80-\xBF]{3}'
74
+ ].join('|'), 'g');
75
+ var cb_btou = function(cccc) {
76
+ switch(cccc.length) {
77
+ case 4:
78
+ var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
79
+ | ((0x3f & cccc.charCodeAt(1)) << 12)
80
+ | ((0x3f & cccc.charCodeAt(2)) << 6)
81
+ | (0x3f & cccc.charCodeAt(3)),
82
+ offset = cp - 0x10000;
83
+ return (fromCharCode((offset >>> 10) + 0xD800)
84
+ + fromCharCode((offset & 0x3FF) + 0xDC00));
85
+ case 3:
86
+ return fromCharCode(
87
+ ((0x0f & cccc.charCodeAt(0)) << 12)
88
+ | ((0x3f & cccc.charCodeAt(1)) << 6)
89
+ | (0x3f & cccc.charCodeAt(2))
90
+ );
91
+ default:
92
+ return fromCharCode(
93
+ ((0x1f & cccc.charCodeAt(0)) << 6)
94
+ | (0x3f & cccc.charCodeAt(1))
95
+ );
96
+ }
97
+ };
98
+ var btou = function(b) {
99
+ return b.replace(re_btou, cb_btou);
100
+ };
101
+ var cb_decode = function(cccc) {
102
+ var len = cccc.length,
103
+ padlen = len % 4,
104
+ n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
105
+ | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
106
+ | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
107
+ | (len > 3 ? b64tab[cccc.charAt(3)] : 0),
108
+ chars = [
109
+ fromCharCode( n >>> 16),
110
+ fromCharCode((n >>> 8) & 0xff),
111
+ fromCharCode( n & 0xff)
112
+ ];
113
+ chars.length -= [0, 0, 2, 1][padlen];
114
+ return chars.join('');
115
+ };
116
+ var atob = global.atob ? function(a) {
117
+ return global.atob(a);
118
+ } : function(a){
119
+ return a.replace(/[\s\S]{1,4}/g, cb_decode);
120
+ };
121
+ var _decode = buffer
122
+ ? function(a) { return (new buffer(a, 'base64')).toString() }
123
+ : function(a) { return btou(atob(a)) };
124
+ var decode = function(a){
125
+ return _decode(
126
+ a.replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })
127
+ .replace(/[^A-Za-z0-9\+\/]/g, '')
128
+ );
129
+ };
130
+ var noConflict = function() {
131
+ var Base64 = global.Base64;
132
+ global.Base64 = _Base64;
133
+ return Base64;
134
+ };
135
+ global.Base64 = {
136
+ VERSION: version,
137
+ atob: atob,
138
+ btoa: btoa,
139
+ fromBase64: decode,
140
+ toBase64: encode,
141
+ utob: utob,
142
+ encode: encode,
143
+ encodeURI: encodeURI,
144
+ btou: btou,
145
+ decode: decode,
146
+ noConflict: noConflict
147
+ };
148
+ if (typeof Object.defineProperty === 'function') {
149
+ var noEnum = function(v){
150
+ return {value:v,enumerable:false,writable:true,configurable:true};
151
+ };
152
+ global.Base64.extendString = function () {
153
+ Object.defineProperty(
154
+ String.prototype, 'fromBase64', noEnum(function () {
155
+ return decode(this)
156
+ }));
157
+ Object.defineProperty(
158
+ String.prototype, 'toBase64', noEnum(function (urisafe) {
159
+ return encode(this, urisafe)
160
+ }));
161
+ Object.defineProperty(
162
+ String.prototype, 'toBase64URI', noEnum(function () {
163
+ return encode(this, true)
164
+ }));
165
+ };
166
+ }
167
+ })(this);
168
+
169
+ CAPIWS = (typeof EIMZOEXT !== 'undefined') ? EIMZOEXT : {
170
+ URL: (window.location.protocol.toLowerCase() === "https:" ? "wss://127.0.0.1:64443" : "ws://127.0.0.1:64646") + "/service/cryptapi",
171
+ callFunction: function(funcDef, callback, error){
172
+ if (!window.WebSocket){
173
+ if(error)
174
+ error();
175
+ return;
176
+ }
177
+ var socket;
178
+ try{
179
+ socket = new WebSocket(this.URL);
180
+ } catch (e){
181
+ error(e);
182
+ }
183
+ socket.onclose = function(e){
184
+ if(error) {
185
+ if(e.code != 1000){
186
+ error(e.code);
187
+ }
188
+ }
189
+ };
190
+ socket.onmessage = function(event){
191
+ var data = JSON.parse(event.data);
192
+ socket.close();
193
+ callback(event,data);
194
+ };
195
+ socket.onopen = function(){
196
+ socket.send(JSON.stringify(funcDef));
197
+ };
198
+ },
199
+ version: function(callback, error){
200
+ if (!window.WebSocket){
201
+ if(error)
202
+ error();
203
+ return;
204
+ }
205
+ var socket;
206
+ try{
207
+ socket = new WebSocket(this.URL);
208
+ } catch (e){
209
+ error(e);
210
+ }
211
+ socket.onclose = function(e){
212
+ if(error) {
213
+ if(e.code != 1000){
214
+ error(e.code);
215
+ }
216
+ }
217
+ };
218
+ socket.onmessage = function(event){
219
+ var data = JSON.parse(event.data);
220
+ socket.close();
221
+ callback(event,data);
222
+ };
223
+ socket.onopen = function(){
224
+ var o = {name: 'version'};
225
+ socket.send(JSON.stringify(o));
226
+ };
227
+ },
228
+ apidoc: function(callback, error){
229
+ if (!window.WebSocket){
230
+ if(error)
231
+ error();
232
+ return;
233
+ }
234
+ var socket;
235
+ try{
236
+ socket = new WebSocket(this.URL);
237
+ } catch (e){
238
+ error(e);
239
+ }
240
+ socket.onclose = function(e){
241
+ if(error) {
242
+ if(e.code != 1000){
243
+ error(e.code);
244
+ }
245
+ }
246
+ };
247
+ socket.onmessage = function(event){
248
+ var data = JSON.parse(event.data);
249
+ socket.close();
250
+ callback(event,data);
251
+ };
252
+ socket.onopen = function(){
253
+ var o = {name: 'apidoc'};
254
+ socket.send(JSON.stringify(o));
255
+ };
256
+ },
257
+ apikey: function(domainAndKey, callback, error){
258
+ if (!window.WebSocket){
259
+ if(error)
260
+ error();
261
+ return;
262
+ }
263
+ var socket;
264
+ try{
265
+ socket = new WebSocket(this.URL);
266
+ } catch (e){
267
+ error(e);
268
+ }
269
+ socket.onclose = function(e){
270
+ if(error) {
271
+ if(e.code != 1000){
272
+ error(e.code);
273
+ }
274
+ }
275
+ };
276
+ socket.onmessage = function(event){
277
+ var data = JSON.parse(event.data);
278
+ socket.close();
279
+ callback(event,data);
280
+ };
281
+ socket.onopen = function(){
282
+ var o = {name: 'apikey', arguments: domainAndKey};
283
+ socket.send(JSON.stringify(o));
284
+ };
285
+ }
286
+ };
287
+
288
+ Date.prototype.yyyymmdd = function () {
289
+ var yyyy = this.getFullYear().toString();
290
+ var mm = (this.getMonth() + 1).toString();
291
+ var dd = this.getDate().toString();
292
+ return yyyy + (mm[1] ? mm : "0" + mm[0]) + (dd[1] ? dd : "0" + dd[0]);
293
+ };
294
+ Date.prototype.ddmmyyyy = function () {
295
+ var yyyy = this.getFullYear().toString();
296
+ var mm = (this.getMonth() + 1).toString();
297
+ var dd = this.getDate().toString();
298
+ return (dd[1] ? dd : "0" + dd[0]) + "." + (mm[1] ? mm : "0" + mm[0]) + "." + yyyy;
299
+ };
300
+ var dates = {
301
+ convert: function (d) {
302
+ return (
303
+ d.constructor === Date ? d :
304
+ d.constructor === Array ? new Date(d[0], d[1], d[2]) :
305
+ d.constructor === Number ? new Date(d) :
306
+ d.constructor === String ? new Date(d) :
307
+ typeof d === "object" ? new Date(d.year, d.month, d.date) :
308
+ NaN
309
+ );
310
+ },
311
+ compare: function (a, b) {
312
+ return (
313
+ isFinite(a = this.convert(a).valueOf()) &&
314
+ isFinite(b = this.convert(b).valueOf()) ?
315
+ (a > b) - (a < b) :
316
+ NaN
317
+ );
318
+ },
319
+ inRange: function (d, start, end) {
320
+ return (
321
+ isFinite(d = this.convert(d).valueOf()) &&
322
+ isFinite(start = this.convert(start).valueOf()) &&
323
+ isFinite(end = this.convert(end).valueOf()) ?
324
+ start <= d && d <= end :
325
+ NaN
326
+ );
327
+ }
328
+ };
329
+ String.prototype.splitKeep = function (splitter, ahead) {
330
+ var self = this;
331
+ var result = [];
332
+ if (splitter != '') {
333
+ function getSubst(value) {
334
+ var substChar = value[0] == '0' ? '1' : '0';
335
+ var subst = '';
336
+ for (var i = 0; i < value.length; i++) {
337
+ subst += substChar;
338
+ }
339
+ return subst;
340
+ };
341
+ var matches = [];
342
+ var replaceName = splitter instanceof RegExp ? "replace" : "replaceAll";
343
+ var r = self[replaceName](splitter, function (m, i, e) {
344
+ matches.push({value: m, index: i});
345
+ return getSubst(m);
346
+ });
347
+ var lastIndex = 0;
348
+ for (var i = 0; i < matches.length; i++) {
349
+ var m = matches[i];
350
+ var nextIndex = ahead == true ? m.index : m.index + m.value.length;
351
+ if (nextIndex != lastIndex) {
352
+ var part = self.substring(lastIndex, nextIndex);
353
+ result.push(part);
354
+ lastIndex = nextIndex;
355
+ }
356
+ };
357
+ if (lastIndex < self.length) {
358
+ var part = self.substring(lastIndex, self.length);
359
+ result.push(part);
360
+ };
361
+ } else {
362
+ result.add(self);
363
+ };
364
+ return result;
365
+ };
366
+
367
+ var EIMZOClient = {
368
+ NEW_API: false,
369
+ NEW_API2: false,
370
+ NEW_API3: false,
371
+ // Add your production domain and API key below:
372
+ // 'yourdomain.uz', 'YOUR_API_KEY_HERE',
373
+ API_KEYS: [
374
+ 'localhost', '96D0C1491615C82B9A54D9989779DF825B690748224C2B04F500F370D51827CE2644D8D4A82C18184D73AB8530BB8ED537269603F61DB0D03D2104ABF789970B',
375
+ '127.0.0.1', 'A7BCFA5D490B351BE0754130DF03A068F855DB4333D43921125B9CF2670EF6A40370C646B90401955E1F7BC9CDBF59CE0B2C5467D820BE189C845D0B79CFC96F'
376
+ ],
377
+ checkVersion: function(success, fail){
378
+ CAPIWS.version(function (event, data) {
379
+ if(data.success === true){
380
+ if(data.major && data.minor){
381
+ var installedVersion = parseInt(data.major) * 100 + parseInt(data.minor);
382
+ EIMZOClient.NEW_API = installedVersion >= 336;
383
+ EIMZOClient.NEW_API2 = installedVersion >= 412;
384
+ EIMZOClient.NEW_API3 = installedVersion >= 486;
385
+ success(data.major, data.minor);
386
+ } else {
387
+ fail(null, 'E-IMZO Version is undefined');
388
+ }
389
+ } else {
390
+ fail(null, data.reason);
391
+ }
392
+ }, function (e) {
393
+ fail(e, null);
394
+ });
395
+ },
396
+ installApiKeys: function(success, fail){
397
+ CAPIWS.apikey(EIMZOClient.API_KEYS, function (event, data) {
398
+ if (data.success) {
399
+ success();
400
+ } else {
401
+ fail(null,data.reason);
402
+ }
403
+ }, function (e) {
404
+ fail(e, null);
405
+ });
406
+ },
407
+ listAllUserKeys: function(itemIdGen, itemUiGen, success, fail){
408
+ var items = [];
409
+ var errors = [];
410
+ if(!EIMZOClient.NEW_API){
411
+ fail(null, 'Please install new version of E-IMZO');
412
+ } else {
413
+ if(EIMZOClient.NEW_API2){
414
+ EIMZOClient._findPfxs2(itemIdGen, itemUiGen, items, errors, function (firstItmId2) {
415
+ if(items.length === 0 && errors.length > 0){
416
+ fail(errors[0].e, errors[0].r);
417
+ } else {
418
+ var firstId = null;
419
+ if (items.length === 1) {
420
+ if (firstItmId2) {
421
+ firstId = firstItmId2;
422
+ }
423
+ }
424
+ success(items, firstId);
425
+ }
426
+ });
427
+ } else {
428
+ EIMZOClient._findPfxs2(itemIdGen, itemUiGen, items, errors, function (firstItmId2) {
429
+ EIMZOClient._findTokens2(itemIdGen, itemUiGen, items, errors, function (firstItmId3) {
430
+ if(items.length === 0 && errors.length > 0){
431
+ fail(errors[0].e, errors[0].r);
432
+ } else {
433
+ var firstId = null;
434
+ if (items.length === 1) {
435
+ if (firstItmId2) {
436
+ firstId = firstItmId2;
437
+ } else if (firstItmId3) {
438
+ firstId = firstItmId3;
439
+ }
440
+ }
441
+ success(items, firstId);
442
+ }
443
+ });
444
+ });
445
+ }
446
+ }
447
+ },
448
+ idCardIsPLuggedIn: function(success, fail){
449
+ if(!EIMZOClient.NEW_API2){
450
+ success(false);
451
+ } else {
452
+ CAPIWS.callFunction({plugin: "idcard", name: "list_readers"}, function (event, data) {
453
+ if (data.success) {
454
+ success(data.readers.length>0);
455
+ } else {
456
+ fail(null, data.reason);
457
+ }
458
+ }, function (e) {
459
+ fail(e, null);
460
+ });
461
+ }
462
+ },
463
+ isBAIKTokenPLuggedIn: function(success, fail){
464
+ if(!EIMZOClient.NEW_API3){
465
+ success(false);
466
+ } else {
467
+ CAPIWS.callFunction({plugin: "baikey", name: "list_tokens"}, function (event, data) {
468
+ if (data.success) {
469
+ success(data.tokens.length>0);
470
+ } else {
471
+ fail(null, data.reason);
472
+ }
473
+ }, function (e) {
474
+ fail(e, null);
475
+ });
476
+ }
477
+ },
478
+ isCKCPLuggedIn: function(success, fail){
479
+ if(!EIMZOClient.NEW_API3){
480
+ success(false);
481
+ } else {
482
+ CAPIWS.callFunction({plugin: "ckc", name: "list_ckc"}, function (event, data) {
483
+ if (data.success) {
484
+ success(data.devices.length>0);
485
+ } else {
486
+ fail(null, data.reason);
487
+ }
488
+ }, function (e) {
489
+ fail(e, null);
490
+ });
491
+ }
492
+ },
493
+ loadKey: function(itemObject, success, fail, verifyPassword){
494
+ if (itemObject) {
495
+ var vo = itemObject;
496
+ if (vo.type === "pfx") {
497
+ CAPIWS.callFunction({plugin: "pfx", name: "load_key", arguments: [vo.disk, vo.path, vo.name, vo.alias]}, function (event, data) {
498
+ if (data.success) {
499
+ var id = data.keyId;
500
+ if(verifyPassword){
501
+ CAPIWS.callFunction({name: "verify_password", plugin: "pfx", arguments: [id]}, function (event, data) {
502
+ if (data.success) {
503
+ success(id);
504
+ } else {
505
+ fail(null, data.reason);
506
+ }
507
+ }, function (e) {
508
+ fail(e, null);
509
+ });
510
+ } else {
511
+ success(id);
512
+ }
513
+ } else {
514
+ fail(null, data.reason);
515
+ }
516
+ }, function (e) {
517
+ fail(e, null);
518
+ });
519
+ } else if (vo.type === "ftjc") {
520
+ CAPIWS.callFunction({plugin: "ftjc", name: "load_key", arguments: [vo.cardUID]}, function (event, data) {
521
+ if (data.success) {
522
+ var id = data.keyId;
523
+ if(verifyPassword){
524
+ CAPIWS.callFunction({plugin: "ftjc", name: "verify_pin", arguments: [id,'1']}, function (event, data) {
525
+ if (data.success) {
526
+ success(id);
527
+ } else {
528
+ fail(null, data.reason);
529
+ }
530
+ }, function (e) {
531
+ fail(e, null);
532
+ });
533
+ } else {
534
+ success(id);
535
+ }
536
+ } else {
537
+ fail(null, data.reason);
538
+ }
539
+ }, function (e) {
540
+ fail(e, null);
541
+ });
542
+ }
543
+ }
544
+ },
545
+ createPkcs7: function(id, data, timestamper, success, fail, detached, isDataBase64Encoded){
546
+ var data64;
547
+ if(isDataBase64Encoded === true){
548
+ data64 = data
549
+ }else {
550
+ data64 = Base64.encode(data);
551
+ }
552
+ if(detached === true){
553
+ detached = 'yes';
554
+ } else {
555
+ detached = 'no';
556
+ }
557
+ CAPIWS.callFunction({plugin: "pkcs7", name: "create_pkcs7", arguments: [data64, id, detached]}, function (event, data) {
558
+ if (data.success) {
559
+ var pkcs7 = data.pkcs7_64;
560
+ success(pkcs7);
561
+ } else {
562
+ fail(null, data.reason);
563
+ }
564
+ }, function (e) {
565
+ fail(e, null);
566
+ });
567
+ },
568
+ _getX500Val: function (s, f) {
569
+ var res = s.splitKeep(/,[A-Z]+=/g, true);
570
+ for (var i in res) {
571
+ var n = res[i].search((i > 0 ? "," : "") + f + "=");
572
+ if (n !== -1) {
573
+ return res[i].slice(n + f.length + 1 + (i > 0 ? 1 : 0));
574
+ }
575
+ }
576
+ return "";
577
+ },
578
+ _findPfxs2: function (itemIdGen, itemUiGen, items, errors, callback) {
579
+ var itmkey0;
580
+ CAPIWS.callFunction({plugin: "pfx", name: "list_all_certificates"}, function (event, data) {
581
+ if (data.success) {
582
+ for (var rec in data.certificates) {
583
+ var el = data.certificates[rec];
584
+ var x500name_ex = el.alias.toUpperCase();
585
+ x500name_ex = x500name_ex.replace("1.2.860.3.16.1.1=", "INN=");
586
+ x500name_ex = x500name_ex.replace("1.2.860.3.16.1.2=", "PINFL=");
587
+ var vo = {
588
+ disk: el.disk,
589
+ path: el.path,
590
+ name: el.name,
591
+ alias: el.alias,
592
+ serialNumber: EIMZOClient._getX500Val(x500name_ex, "SERIALNUMBER"),
593
+ validFrom: new Date(EIMZOClient._getX500Val(x500name_ex, "VALIDFROM").replace(/\./g, "-").replace(" ", "T")),
594
+ validTo: new Date(EIMZOClient._getX500Val(x500name_ex, "VALIDTO").replace(/\./g, "-").replace(" ", "T")),
595
+ CN: EIMZOClient._getX500Val(x500name_ex, "CN"),
596
+ TIN: (EIMZOClient._getX500Val(x500name_ex, "INN") ? EIMZOClient._getX500Val(x500name_ex, "INN") : EIMZOClient._getX500Val(x500name_ex, "UID")),
597
+ UID: EIMZOClient._getX500Val(x500name_ex, "UID"),
598
+ PINFL: EIMZOClient._getX500Val(x500name_ex, "PINFL"),
599
+ O: EIMZOClient._getX500Val(x500name_ex, "O"),
600
+ T: EIMZOClient._getX500Val(x500name_ex, "T"),
601
+ type: 'pfx'
602
+ };
603
+ if (!vo.TIN && !vo.PINFL)
604
+ continue;
605
+ var itmkey = itemIdGen(vo,rec);
606
+ if (!itmkey0) {
607
+ itmkey0 = itmkey;
608
+ }
609
+ var itm = itemUiGen(itmkey, vo);
610
+ items.push(itm);
611
+ }
612
+ } else {
613
+ errors.push({r: data.reason});
614
+ }
615
+ callback(itmkey0);
616
+ }, function (e) {
617
+ errors.push({e: e});
618
+ callback(itmkey0);
619
+ });
620
+ },
621
+ _findTokens2: function (itemIdGen, itemUiGen, items, errors, callback) {
622
+ var itmkey0;
623
+ CAPIWS.callFunction({plugin: "ftjc", name: "list_all_keys", arguments:['']}, function (event, data) {
624
+ if (data.success) {
625
+ for (var rec in data.tokens) {
626
+ var el = data.tokens[rec];
627
+ var x500name_ex = el.info.toUpperCase();
628
+ x500name_ex = x500name_ex.replace("1.2.860.3.16.1.1=", "INN=");
629
+ x500name_ex = x500name_ex.replace("1.2.860.3.16.1.2=", "PINFL=");
630
+ var vo = {
631
+ cardUID: el.cardUID,
632
+ statusInfo: el.statusInfo,
633
+ ownerName: el.ownerName,
634
+ info: el.info,
635
+ serialNumber: EIMZOClient._getX500Val(x500name_ex, "SERIALNUMBER"),
636
+ validFrom: new Date(EIMZOClient._getX500Val(x500name_ex, "VALIDFROM")),
637
+ validTo: new Date(EIMZOClient._getX500Val(x500name_ex, "VALIDTO")),
638
+ CN: EIMZOClient._getX500Val(x500name_ex, "CN"),
639
+ TIN: (EIMZOClient._getX500Val(x500name_ex, "INN") ? EIMZOClient._getX500Val(x500name_ex, "INN") : EIMZOClient._getX500Val(x500name_ex, "UID")),
640
+ UID: EIMZOClient._getX500Val(x500name_ex, "UID"),
641
+ PINFL: EIMZOClient._getX500Val(x500name_ex, "PINFL"),
642
+ O: EIMZOClient._getX500Val(x500name_ex, "O"),
643
+ T: EIMZOClient._getX500Val(x500name_ex, "T"),
644
+ type: 'ftjc'
645
+ };
646
+ if (!vo.TIN && !vo.PINFL)
647
+ continue;
648
+ var itmkey = itemIdGen(vo,rec);
649
+ if (!itmkey0) {
650
+ itmkey0 = itmkey;
651
+ }
652
+ var itm = itemUiGen(itmkey, vo);
653
+ items.push(itm);
654
+ }
655
+ } else {
656
+ errors.push({r: data.reason});
657
+ }
658
+ callback(itmkey0);
659
+ }, function (e) {
660
+ errors.push({e: e});
661
+ callback(itmkey0);
662
+ });
663
+ }
664
+ };
package/src/eimzo.ts ADDED
@@ -0,0 +1,120 @@
1
+ import type { ICertificate } from './types'
2
+ import { SDK_SOURCE } from './sdk-content'
3
+
4
+ let sdkLoaded = false
5
+
6
+ export function loadSDK(): Promise<void> {
7
+ return new Promise((resolve) => {
8
+ if (sdkLoaded || typeof EIMZOClient !== 'undefined') {
9
+ sdkLoaded = true
10
+ resolve()
11
+ return
12
+ }
13
+
14
+ const script = document.createElement('script')
15
+ script.textContent = SDK_SOURCE
16
+ document.head.appendChild(script)
17
+ sdkLoaded = true
18
+ resolve()
19
+ })
20
+ }
21
+
22
+ export function checkVersion(): Promise<{ major: string; minor: string }> {
23
+ return new Promise((resolve, reject) => {
24
+ EIMZOClient.checkVersion(
25
+ (major, minor) => resolve({ major, minor }),
26
+ (e, r) => reject(r || e),
27
+ )
28
+ })
29
+ }
30
+
31
+ export function installApiKeys(apiKeys?: string[]): Promise<void> {
32
+ return new Promise((resolve, reject) => {
33
+ if (apiKeys) {
34
+ EIMZOClient.API_KEYS = [
35
+ ...EIMZOClient.API_KEYS,
36
+ ...apiKeys,
37
+ ]
38
+ }
39
+ EIMZOClient.installApiKeys(
40
+ () => resolve(),
41
+ (e, r) => reject(r || e),
42
+ )
43
+ })
44
+ }
45
+
46
+ export function listAllUserKeys(): Promise<ICertificate[]> {
47
+ return new Promise((resolve, reject) => {
48
+ const certs: ICertificate[] = []
49
+
50
+ EIMZOClient.listAllUserKeys(
51
+ (o, i) => `itm-${o.serialNumber}-${i}`,
52
+ (_itemId, vo) => {
53
+ const cert: ICertificate = {
54
+ ...vo,
55
+ expired: new Date(vo.validTo) < new Date(),
56
+ }
57
+ certs.push(cert)
58
+ return cert
59
+ },
60
+ () => resolve(certs),
61
+ (e, r) => reject(r || e),
62
+ )
63
+ })
64
+ }
65
+
66
+ export function loadKey(cert: ICertificate): Promise<string> {
67
+ return new Promise((resolve, reject) => {
68
+ EIMZOClient.loadKey(
69
+ cert,
70
+ (id) => resolve(id),
71
+ (e, r) => reject(r || e),
72
+ )
73
+ })
74
+ }
75
+
76
+ export function createPkcs7(keyId: string, data: string): Promise<string> {
77
+ return new Promise((resolve, reject) => {
78
+ EIMZOClient.createPkcs7(
79
+ keyId,
80
+ data,
81
+ null,
82
+ (pkcs7) => resolve(pkcs7),
83
+ (e, r) => reject(r || e),
84
+ false,
85
+ )
86
+ })
87
+ }
88
+
89
+ export function checkIdCard(): Promise<boolean> {
90
+ return new Promise((resolve, reject) => {
91
+ EIMZOClient.idCardIsPLuggedIn(
92
+ (plugged) => resolve(plugged),
93
+ (e, r) => reject(r || e),
94
+ )
95
+ })
96
+ }
97
+
98
+ export function checkBaikToken(): Promise<boolean> {
99
+ return new Promise((resolve, reject) => {
100
+ EIMZOClient.isBAIKTokenPLuggedIn(
101
+ (plugged) => resolve(plugged),
102
+ (e, r) => reject(r || e),
103
+ )
104
+ })
105
+ }
106
+
107
+ export function checkCkc(): Promise<boolean> {
108
+ return new Promise((resolve, reject) => {
109
+ EIMZOClient.isCKCPLuggedIn(
110
+ (plugged) => resolve(plugged),
111
+ (e, r) => reject(r || e),
112
+ )
113
+ })
114
+ }
115
+
116
+ export async function install(apiKeys?: string[]): Promise<void> {
117
+ await loadSDK()
118
+ await checkVersion()
119
+ await installApiKeys(apiKeys)
120
+ }
@@ -0,0 +1,71 @@
1
+ /* eslint-disable no-var */
2
+ declare var CAPIWS: {
3
+ URL: string
4
+ callFunction: (
5
+ funcDef: any,
6
+ callback: (event: any, data: any) => void,
7
+ error: (e: any) => void,
8
+ ) => void
9
+ version: (
10
+ callback: (event: any, data: any) => void,
11
+ error: (e: any) => void,
12
+ ) => void
13
+ apikey: (
14
+ domainAndKey: string[],
15
+ callback: (event: any, data: any) => void,
16
+ error: (e: any) => void,
17
+ ) => void
18
+ }
19
+
20
+ declare var EIMZOClient: {
21
+ NEW_API: boolean
22
+ NEW_API2: boolean
23
+ NEW_API3: boolean
24
+ API_KEYS: string[]
25
+ checkVersion: (
26
+ success: (major: string, minor: string) => void,
27
+ fail: (e: any, r: string | null) => void,
28
+ ) => void
29
+ installApiKeys: (
30
+ success: () => void,
31
+ fail: (e: any, r: string | null) => void,
32
+ ) => void
33
+ listAllUserKeys: (
34
+ itemIdGen: (o: any, i: number) => string,
35
+ itemUiGen: (itemId: string, v: any) => any,
36
+ success: (items: any[], firstId: string | null) => void,
37
+ fail: (e: any, r: string | null) => void,
38
+ ) => void
39
+ idCardIsPLuggedIn: (
40
+ success: (plugged: boolean) => void,
41
+ fail: (e: any, r: string | null) => void,
42
+ ) => void
43
+ isBAIKTokenPLuggedIn: (
44
+ success: (plugged: boolean) => void,
45
+ fail: (e: any, r: string | null) => void,
46
+ ) => void
47
+ isCKCPLuggedIn: (
48
+ success: (plugged: boolean) => void,
49
+ fail: (e: any, r: string | null) => void,
50
+ ) => void
51
+ loadKey: (
52
+ itemObject: any,
53
+ success: (id: string) => void,
54
+ fail: (e: any, r: string | null) => void,
55
+ verifyPassword?: boolean,
56
+ ) => void
57
+ createPkcs7: (
58
+ id: string,
59
+ data: string,
60
+ timestamper: any,
61
+ success: (pkcs7: string) => void,
62
+ fail: (e: any, r: string | null) => void,
63
+ detached?: boolean,
64
+ isDataBase64Encoded?: boolean,
65
+ ) => void
66
+ }
67
+
68
+ declare var Base64: {
69
+ encode: (u: string, urisafe?: boolean) => string
70
+ decode: (a: string) => string
71
+ }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { EimzoProvider, useEimzo } from './provider'
2
+ export type {
3
+ ICertificate,
4
+ ISignParams,
5
+ IDeviceStatus,
6
+ IEimzoContext,
7
+ IEimzoProviderProps,
8
+ TKeyType,
9
+ } from './types'
@@ -0,0 +1,115 @@
1
+ import {
2
+ createContext,
3
+ useContext,
4
+ useState,
5
+ useCallback,
6
+ useEffect,
7
+ type ReactNode,
8
+ } from 'react'
9
+ import type {
10
+ ICertificate,
11
+ ISignParams,
12
+ IEimzoContext,
13
+ IDeviceStatus,
14
+ } from './types'
15
+ import * as eimzo from './eimzo'
16
+
17
+ const EimzoContext = createContext<IEimzoContext | null>(null)
18
+
19
+ interface IEimzoProviderProps {
20
+ apiKeys?: string[]
21
+ children: ReactNode
22
+ }
23
+
24
+ export function EimzoProvider({ apiKeys, children }: IEimzoProviderProps) {
25
+ const [isInstalled, setIsInstalled] = useState(false)
26
+ const [isLoading, setIsLoading] = useState(false)
27
+ const [keyList, setKeyList] = useState<ICertificate[]>([])
28
+ const [deviceStatus, setDeviceStatus] = useState<IDeviceStatus>({
29
+ idcard: false,
30
+ baikey: false,
31
+ ckc: false,
32
+ })
33
+
34
+ const checkDevices = useCallback(async () => {
35
+ const [idcard, baikey, ckc] = await Promise.allSettled([
36
+ eimzo.checkIdCard(),
37
+ eimzo.checkBaikToken(),
38
+ eimzo.checkCkc(),
39
+ ])
40
+ setDeviceStatus({
41
+ idcard: idcard.status === 'fulfilled' && idcard.value,
42
+ baikey: baikey.status === 'fulfilled' && baikey.value,
43
+ ckc: ckc.status === 'fulfilled' && ckc.value,
44
+ })
45
+ }, [])
46
+
47
+ useEffect(() => {
48
+ eimzo
49
+ .install(apiKeys)
50
+ .then(async () => {
51
+ setIsInstalled(true)
52
+ await checkDevices()
53
+ })
54
+ .catch(() => setIsInstalled(false))
55
+ }, [])
56
+
57
+ const loadKeys = useCallback(async () => {
58
+ setIsLoading(true)
59
+ try {
60
+ const certs = await eimzo.listAllUserKeys()
61
+ setKeyList(certs)
62
+ } catch (err) {
63
+ console.error('E-IMZO: Failed to load keys', err)
64
+ } finally {
65
+ setIsLoading(false)
66
+ }
67
+ }, [])
68
+
69
+ const sign = useCallback(
70
+ async ({ keyId, data, onSuccess, onError }: ISignParams) => {
71
+ setIsLoading(true)
72
+ try {
73
+ let id: string
74
+
75
+ if (typeof keyId === 'object') {
76
+ id = await eimzo.loadKey(keyId)
77
+ } else {
78
+ id = keyId
79
+ }
80
+
81
+ const pkcs7 = await eimzo.createPkcs7(id, data)
82
+ onSuccess(pkcs7)
83
+ } catch (err) {
84
+ const message = typeof err === 'string' ? err : 'E-IMZO signing failed'
85
+ onError?.(message)
86
+ } finally {
87
+ setIsLoading(false)
88
+ }
89
+ },
90
+ [],
91
+ )
92
+
93
+ return (
94
+ <EimzoContext.Provider
95
+ value={{
96
+ isInstalled,
97
+ isLoading,
98
+ keyList,
99
+ deviceStatus,
100
+ loadKeys,
101
+ sign,
102
+ }}
103
+ >
104
+ {children}
105
+ </EimzoContext.Provider>
106
+ )
107
+ }
108
+
109
+ export function useEimzo() {
110
+ const context = useContext(EimzoContext)
111
+ if (!context) {
112
+ throw new Error('useEimzo must be used within EimzoProvider')
113
+ }
114
+ return context
115
+ }
@@ -0,0 +1 @@
1
+ export const SDK_SOURCE = "(function(global) {\n 'use strict';\n var _Base64 = global.Base64;\n var version = \"2.1.4\";\n var buffer;\n if (typeof module !== 'undefined' && module.exports) {\n buffer = require('buffer').Buffer;\n }\n var b64chars\n = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n var b64tab = function(bin) {\n var t = {};\n for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;\n return t;\n }(b64chars);\n var fromCharCode = String.fromCharCode;\n var cb_utob = function(c) {\n if (c.length < 2) {\n var cc = c.charCodeAt(0);\n return cc < 0x80 ? c\n : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))\n + fromCharCode(0x80 | (cc & 0x3f)))\n : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))\n + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))\n + fromCharCode(0x80 | ( cc & 0x3f)));\n } else {\n var cc = 0x10000\n + (c.charCodeAt(0) - 0xD800) * 0x400\n + (c.charCodeAt(1) - 0xDC00);\n return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))\n + fromCharCode(0x80 | ((cc >>> 12) & 0x3f))\n + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))\n + fromCharCode(0x80 | ( cc & 0x3f)));\n }\n };\n var re_utob = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFFF]|[^\\x00-\\x7F]/g;\n var utob = function(u) {\n return u.replace(re_utob, cb_utob);\n };\n var cb_encode = function(ccc) {\n var padlen = [0, 2, 1][ccc.length % 3],\n ord = ccc.charCodeAt(0) << 16\n | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)\n | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),\n chars = [\n b64chars.charAt( ord >>> 18),\n b64chars.charAt((ord >>> 12) & 63),\n padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),\n padlen >= 1 ? '=' : b64chars.charAt(ord & 63)\n ];\n return chars.join('');\n };\n var btoa = global.btoa ? function(b) {\n return global.btoa(b);\n } : function(b) {\n return b.replace(/[\\s\\S]{1,3}/g, cb_encode);\n };\n var _encode = buffer\n ? function (u) { return (new buffer(u)).toString('base64') }\n : function (u) { return btoa(utob(u)) }\n ;\n var encode = function(u, urisafe) {\n return !urisafe\n ? _encode(u)\n : _encode(u).replace(/[+\\/]/g, function(m0) {\n return m0 == '+' ? '-' : '_';\n }).replace(/=/g, '');\n };\n var encodeURI = function(u) { return encode(u, true) };\n var re_btou = new RegExp([\n '[\\xC0-\\xDF][\\x80-\\xBF]',\n '[\\xE0-\\xEF][\\x80-\\xBF]{2}',\n '[\\xF0-\\xF7][\\x80-\\xBF]{3}'\n ].join('|'), 'g');\n var cb_btou = function(cccc) {\n switch(cccc.length) {\n case 4:\n var cp = ((0x07 & cccc.charCodeAt(0)) << 18)\n | ((0x3f & cccc.charCodeAt(1)) << 12)\n | ((0x3f & cccc.charCodeAt(2)) << 6)\n | (0x3f & cccc.charCodeAt(3)),\n offset = cp - 0x10000;\n return (fromCharCode((offset >>> 10) + 0xD800)\n + fromCharCode((offset & 0x3FF) + 0xDC00));\n case 3:\n return fromCharCode(\n ((0x0f & cccc.charCodeAt(0)) << 12)\n | ((0x3f & cccc.charCodeAt(1)) << 6)\n | (0x3f & cccc.charCodeAt(2))\n );\n default:\n return fromCharCode(\n ((0x1f & cccc.charCodeAt(0)) << 6)\n | (0x3f & cccc.charCodeAt(1))\n );\n }\n };\n var btou = function(b) {\n return b.replace(re_btou, cb_btou);\n };\n var cb_decode = function(cccc) {\n var len = cccc.length,\n padlen = len % 4,\n n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)\n | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)\n | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)\n | (len > 3 ? b64tab[cccc.charAt(3)] : 0),\n chars = [\n fromCharCode( n >>> 16),\n fromCharCode((n >>> 8) & 0xff),\n fromCharCode( n & 0xff)\n ];\n chars.length -= [0, 0, 2, 1][padlen];\n return chars.join('');\n };\n var atob = global.atob ? function(a) {\n return global.atob(a);\n } : function(a){\n return a.replace(/[\\s\\S]{1,4}/g, cb_decode);\n };\n var _decode = buffer\n ? function(a) { return (new buffer(a, 'base64')).toString() }\n : function(a) { return btou(atob(a)) };\n var decode = function(a){\n return _decode(\n a.replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })\n .replace(/[^A-Za-z0-9\\+\\/]/g, '')\n );\n };\n var noConflict = function() {\n var Base64 = global.Base64;\n global.Base64 = _Base64;\n return Base64;\n };\n global.Base64 = {\n VERSION: version,\n atob: atob,\n btoa: btoa,\n fromBase64: decode,\n toBase64: encode,\n utob: utob,\n encode: encode,\n encodeURI: encodeURI,\n btou: btou,\n decode: decode,\n noConflict: noConflict\n };\n if (typeof Object.defineProperty === 'function') {\n var noEnum = function(v){\n return {value:v,enumerable:false,writable:true,configurable:true};\n };\n global.Base64.extendString = function () {\n Object.defineProperty(\n String.prototype, 'fromBase64', noEnum(function () {\n return decode(this)\n }));\n Object.defineProperty(\n String.prototype, 'toBase64', noEnum(function (urisafe) {\n return encode(this, urisafe)\n }));\n Object.defineProperty(\n String.prototype, 'toBase64URI', noEnum(function () {\n return encode(this, true)\n }));\n };\n }\n})(this);\n\nCAPIWS = (typeof EIMZOEXT !== 'undefined') ? EIMZOEXT : {\n URL: (window.location.protocol.toLowerCase() === \"https:\" ? \"wss://127.0.0.1:64443\" : \"ws://127.0.0.1:64646\") + \"/service/cryptapi\",\n callFunction: function(funcDef, callback, error){\n if (!window.WebSocket){\n if(error)\n error();\n return;\n }\n var socket;\n try{\n socket = new WebSocket(this.URL);\n } catch (e){\n error(e);\n }\n socket.onclose = function(e){\n if(error) {\n if(e.code != 1000){\n error(e.code);\n }\n }\n };\n socket.onmessage = function(event){\n var data = JSON.parse(event.data);\n socket.close();\n callback(event,data);\n };\n socket.onopen = function(){\n socket.send(JSON.stringify(funcDef));\n };\n },\n version: function(callback, error){\n if (!window.WebSocket){\n if(error)\n error();\n return;\n }\n var socket;\n try{\n socket = new WebSocket(this.URL);\n } catch (e){\n error(e);\n }\n socket.onclose = function(e){\n if(error) {\n if(e.code != 1000){\n error(e.code);\n }\n }\n };\n socket.onmessage = function(event){\n var data = JSON.parse(event.data);\n socket.close();\n callback(event,data);\n };\n socket.onopen = function(){\n var o = {name: 'version'};\n socket.send(JSON.stringify(o));\n };\n },\n apidoc: function(callback, error){\n if (!window.WebSocket){\n if(error)\n error();\n return;\n }\n var socket;\n try{\n socket = new WebSocket(this.URL);\n } catch (e){\n error(e);\n }\n socket.onclose = function(e){\n if(error) {\n if(e.code != 1000){\n error(e.code);\n }\n }\n };\n socket.onmessage = function(event){\n var data = JSON.parse(event.data);\n socket.close();\n callback(event,data);\n };\n socket.onopen = function(){\n var o = {name: 'apidoc'};\n socket.send(JSON.stringify(o));\n };\n },\n apikey: function(domainAndKey, callback, error){\n if (!window.WebSocket){\n if(error)\n error();\n return;\n }\n var socket;\n try{\n socket = new WebSocket(this.URL);\n } catch (e){\n error(e);\n }\n socket.onclose = function(e){\n if(error) {\n if(e.code != 1000){\n error(e.code);\n }\n }\n };\n socket.onmessage = function(event){\n var data = JSON.parse(event.data);\n socket.close();\n callback(event,data);\n };\n socket.onopen = function(){\n var o = {name: 'apikey', arguments: domainAndKey};\n socket.send(JSON.stringify(o));\n };\n }\n};\n\nDate.prototype.yyyymmdd = function () {\n var yyyy = this.getFullYear().toString();\n var mm = (this.getMonth() + 1).toString();\n var dd = this.getDate().toString();\n return yyyy + (mm[1] ? mm : \"0\" + mm[0]) + (dd[1] ? dd : \"0\" + dd[0]);\n};\nDate.prototype.ddmmyyyy = function () {\n var yyyy = this.getFullYear().toString();\n var mm = (this.getMonth() + 1).toString();\n var dd = this.getDate().toString();\n return (dd[1] ? dd : \"0\" + dd[0]) + \".\" + (mm[1] ? mm : \"0\" + mm[0]) + \".\" + yyyy;\n};\nvar dates = {\n convert: function (d) {\n return (\n d.constructor === Date ? d :\n d.constructor === Array ? new Date(d[0], d[1], d[2]) :\n d.constructor === Number ? new Date(d) :\n d.constructor === String ? new Date(d) :\n typeof d === \"object\" ? new Date(d.year, d.month, d.date) :\n NaN\n );\n },\n compare: function (a, b) {\n return (\n isFinite(a = this.convert(a).valueOf()) &&\n isFinite(b = this.convert(b).valueOf()) ?\n (a > b) - (a < b) :\n NaN\n );\n },\n inRange: function (d, start, end) {\n return (\n isFinite(d = this.convert(d).valueOf()) &&\n isFinite(start = this.convert(start).valueOf()) &&\n isFinite(end = this.convert(end).valueOf()) ?\n start <= d && d <= end :\n NaN\n );\n }\n};\nString.prototype.splitKeep = function (splitter, ahead) {\n var self = this;\n var result = [];\n if (splitter != '') {\n function getSubst(value) {\n var substChar = value[0] == '0' ? '1' : '0';\n var subst = '';\n for (var i = 0; i < value.length; i++) {\n subst += substChar;\n }\n return subst;\n };\n var matches = [];\n var replaceName = splitter instanceof RegExp ? \"replace\" : \"replaceAll\";\n var r = self[replaceName](splitter, function (m, i, e) {\n matches.push({value: m, index: i});\n return getSubst(m);\n });\n var lastIndex = 0;\n for (var i = 0; i < matches.length; i++) {\n var m = matches[i];\n var nextIndex = ahead == true ? m.index : m.index + m.value.length;\n if (nextIndex != lastIndex) {\n var part = self.substring(lastIndex, nextIndex);\n result.push(part);\n lastIndex = nextIndex;\n }\n };\n if (lastIndex < self.length) {\n var part = self.substring(lastIndex, self.length);\n result.push(part);\n };\n } else {\n result.add(self);\n };\n return result;\n};\n\nvar EIMZOClient = {\n NEW_API: false,\n NEW_API2: false,\n NEW_API3: false,\n // Add your production domain and API key below:\n // 'yourdomain.uz', 'YOUR_API_KEY_HERE',\n API_KEYS: [\n 'localhost', '96D0C1491615C82B9A54D9989779DF825B690748224C2B04F500F370D51827CE2644D8D4A82C18184D73AB8530BB8ED537269603F61DB0D03D2104ABF789970B',\n '127.0.0.1', 'A7BCFA5D490B351BE0754130DF03A068F855DB4333D43921125B9CF2670EF6A40370C646B90401955E1F7BC9CDBF59CE0B2C5467D820BE189C845D0B79CFC96F'\n ],\n checkVersion: function(success, fail){\n CAPIWS.version(function (event, data) {\n if(data.success === true){\n if(data.major && data.minor){\n var installedVersion = parseInt(data.major) * 100 + parseInt(data.minor);\n EIMZOClient.NEW_API = installedVersion >= 336;\n EIMZOClient.NEW_API2 = installedVersion >= 412;\n EIMZOClient.NEW_API3 = installedVersion >= 486;\n success(data.major, data.minor);\n } else {\n fail(null, 'E-IMZO Version is undefined');\n }\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n },\n installApiKeys: function(success, fail){\n CAPIWS.apikey(EIMZOClient.API_KEYS, function (event, data) {\n if (data.success) {\n success();\n } else {\n fail(null,data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n },\n listAllUserKeys: function(itemIdGen, itemUiGen, success, fail){\n var items = [];\n var errors = [];\n if(!EIMZOClient.NEW_API){\n fail(null, 'Please install new version of E-IMZO');\n } else {\n if(EIMZOClient.NEW_API2){\n EIMZOClient._findPfxs2(itemIdGen, itemUiGen, items, errors, function (firstItmId2) {\n if(items.length === 0 && errors.length > 0){\n fail(errors[0].e, errors[0].r);\n } else {\n var firstId = null;\n if (items.length === 1) {\n if (firstItmId2) {\n firstId = firstItmId2;\n }\n }\n success(items, firstId);\n }\n });\n } else {\n EIMZOClient._findPfxs2(itemIdGen, itemUiGen, items, errors, function (firstItmId2) {\n EIMZOClient._findTokens2(itemIdGen, itemUiGen, items, errors, function (firstItmId3) {\n if(items.length === 0 && errors.length > 0){\n fail(errors[0].e, errors[0].r);\n } else {\n var firstId = null;\n if (items.length === 1) {\n if (firstItmId2) {\n firstId = firstItmId2;\n } else if (firstItmId3) {\n firstId = firstItmId3;\n }\n }\n success(items, firstId);\n }\n });\n });\n }\n }\n },\n idCardIsPLuggedIn: function(success, fail){\n if(!EIMZOClient.NEW_API2){\n success(false);\n } else {\n CAPIWS.callFunction({plugin: \"idcard\", name: \"list_readers\"}, function (event, data) {\n if (data.success) {\n success(data.readers.length>0);\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n }\n },\n isBAIKTokenPLuggedIn: function(success, fail){\n if(!EIMZOClient.NEW_API3){\n success(false);\n } else {\n CAPIWS.callFunction({plugin: \"baikey\", name: \"list_tokens\"}, function (event, data) {\n if (data.success) {\n success(data.tokens.length>0);\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n }\n },\n isCKCPLuggedIn: function(success, fail){\n if(!EIMZOClient.NEW_API3){\n success(false);\n } else {\n CAPIWS.callFunction({plugin: \"ckc\", name: \"list_ckc\"}, function (event, data) {\n if (data.success) {\n success(data.devices.length>0);\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n }\n },\n loadKey: function(itemObject, success, fail, verifyPassword){\n if (itemObject) {\n var vo = itemObject;\n if (vo.type === \"pfx\") {\n CAPIWS.callFunction({plugin: \"pfx\", name: \"load_key\", arguments: [vo.disk, vo.path, vo.name, vo.alias]}, function (event, data) {\n if (data.success) {\n var id = data.keyId;\n if(verifyPassword){\n CAPIWS.callFunction({name: \"verify_password\", plugin: \"pfx\", arguments: [id]}, function (event, data) {\n if (data.success) {\n success(id);\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n } else {\n success(id);\n }\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n } else if (vo.type === \"ftjc\") {\n CAPIWS.callFunction({plugin: \"ftjc\", name: \"load_key\", arguments: [vo.cardUID]}, function (event, data) {\n if (data.success) {\n var id = data.keyId;\n if(verifyPassword){\n CAPIWS.callFunction({plugin: \"ftjc\", name: \"verify_pin\", arguments: [id,'1']}, function (event, data) {\n if (data.success) {\n success(id);\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n } else {\n success(id);\n }\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n }\n }\n },\n createPkcs7: function(id, data, timestamper, success, fail, detached, isDataBase64Encoded){\n var data64;\n if(isDataBase64Encoded === true){\n data64 = data\n }else {\n data64 = Base64.encode(data);\n }\n if(detached === true){\n detached = 'yes';\n } else {\n detached = 'no';\n }\n CAPIWS.callFunction({plugin: \"pkcs7\", name: \"create_pkcs7\", arguments: [data64, id, detached]}, function (event, data) {\n if (data.success) {\n var pkcs7 = data.pkcs7_64;\n success(pkcs7);\n } else {\n fail(null, data.reason);\n }\n }, function (e) {\n fail(e, null);\n });\n },\n _getX500Val: function (s, f) {\n var res = s.splitKeep(/,[A-Z]+=/g, true);\n for (var i in res) {\n var n = res[i].search((i > 0 ? \",\" : \"\") + f + \"=\");\n if (n !== -1) {\n return res[i].slice(n + f.length + 1 + (i > 0 ? 1 : 0));\n }\n }\n return \"\";\n },\n _findPfxs2: function (itemIdGen, itemUiGen, items, errors, callback) {\n var itmkey0;\n CAPIWS.callFunction({plugin: \"pfx\", name: \"list_all_certificates\"}, function (event, data) {\n if (data.success) {\n for (var rec in data.certificates) {\n var el = data.certificates[rec];\n var x500name_ex = el.alias.toUpperCase();\n x500name_ex = x500name_ex.replace(\"1.2.860.3.16.1.1=\", \"INN=\");\n x500name_ex = x500name_ex.replace(\"1.2.860.3.16.1.2=\", \"PINFL=\");\n var vo = {\n disk: el.disk,\n path: el.path,\n name: el.name,\n alias: el.alias,\n serialNumber: EIMZOClient._getX500Val(x500name_ex, \"SERIALNUMBER\"),\n validFrom: new Date(EIMZOClient._getX500Val(x500name_ex, \"VALIDFROM\").replace(/\\./g, \"-\").replace(\" \", \"T\")),\n validTo: new Date(EIMZOClient._getX500Val(x500name_ex, \"VALIDTO\").replace(/\\./g, \"-\").replace(\" \", \"T\")),\n CN: EIMZOClient._getX500Val(x500name_ex, \"CN\"),\n TIN: (EIMZOClient._getX500Val(x500name_ex, \"INN\") ? EIMZOClient._getX500Val(x500name_ex, \"INN\") : EIMZOClient._getX500Val(x500name_ex, \"UID\")),\n UID: EIMZOClient._getX500Val(x500name_ex, \"UID\"),\n PINFL: EIMZOClient._getX500Val(x500name_ex, \"PINFL\"),\n O: EIMZOClient._getX500Val(x500name_ex, \"O\"),\n T: EIMZOClient._getX500Val(x500name_ex, \"T\"),\n type: 'pfx'\n };\n if (!vo.TIN && !vo.PINFL)\n continue;\n var itmkey = itemIdGen(vo,rec);\n if (!itmkey0) {\n itmkey0 = itmkey;\n }\n var itm = itemUiGen(itmkey, vo);\n items.push(itm);\n }\n } else {\n errors.push({r: data.reason});\n }\n callback(itmkey0);\n }, function (e) {\n errors.push({e: e});\n callback(itmkey0);\n });\n },\n _findTokens2: function (itemIdGen, itemUiGen, items, errors, callback) {\n var itmkey0;\n CAPIWS.callFunction({plugin: \"ftjc\", name: \"list_all_keys\", arguments:['']}, function (event, data) {\n if (data.success) {\n for (var rec in data.tokens) {\n var el = data.tokens[rec];\n var x500name_ex = el.info.toUpperCase();\n x500name_ex = x500name_ex.replace(\"1.2.860.3.16.1.1=\", \"INN=\");\n x500name_ex = x500name_ex.replace(\"1.2.860.3.16.1.2=\", \"PINFL=\");\n var vo = {\n cardUID: el.cardUID,\n statusInfo: el.statusInfo,\n ownerName: el.ownerName,\n info: el.info,\n serialNumber: EIMZOClient._getX500Val(x500name_ex, \"SERIALNUMBER\"),\n validFrom: new Date(EIMZOClient._getX500Val(x500name_ex, \"VALIDFROM\")),\n validTo: new Date(EIMZOClient._getX500Val(x500name_ex, \"VALIDTO\")),\n CN: EIMZOClient._getX500Val(x500name_ex, \"CN\"),\n TIN: (EIMZOClient._getX500Val(x500name_ex, \"INN\") ? EIMZOClient._getX500Val(x500name_ex, \"INN\") : EIMZOClient._getX500Val(x500name_ex, \"UID\")),\n UID: EIMZOClient._getX500Val(x500name_ex, \"UID\"),\n PINFL: EIMZOClient._getX500Val(x500name_ex, \"PINFL\"),\n O: EIMZOClient._getX500Val(x500name_ex, \"O\"),\n T: EIMZOClient._getX500Val(x500name_ex, \"T\"),\n type: 'ftjc'\n };\n if (!vo.TIN && !vo.PINFL)\n continue;\n var itmkey = itemIdGen(vo,rec);\n if (!itmkey0) {\n itmkey0 = itmkey;\n }\n var itm = itemUiGen(itmkey, vo);\n items.push(itm);\n }\n } else {\n errors.push({r: data.reason});\n }\n callback(itmkey0);\n }, function (e) {\n errors.push({e: e});\n callback(itmkey0);\n });\n }\n};\n"
package/src/types.ts ADDED
@@ -0,0 +1,50 @@
1
+ export type TKeyType = 'pfx' | 'ftjc' | 'idcard' | 'baikey' | 'ckc'
2
+
3
+ export interface ICertificate {
4
+ disk: string
5
+ path: string
6
+ name: string
7
+ alias: string
8
+ serialNumber: string
9
+ validFrom: Date
10
+ validTo: Date
11
+ CN: string
12
+ TIN: string
13
+ UID: string
14
+ PINFL: string
15
+ O: string
16
+ T: string
17
+ type: TKeyType
18
+ cardUID?: string
19
+ statusInfo?: string
20
+ ownerName?: string
21
+ info?: string
22
+ expired?: boolean
23
+ }
24
+
25
+ export interface ISignParams {
26
+ keyId: ICertificate | string
27
+ data: string
28
+ onSuccess: (pkcs7: string) => void
29
+ onError?: (error: string) => void
30
+ }
31
+
32
+ export interface IDeviceStatus {
33
+ idcard: boolean
34
+ baikey: boolean
35
+ ckc: boolean
36
+ }
37
+
38
+ export interface IEimzoProviderProps {
39
+ apiKeys?: string[]
40
+ children: React.ReactNode
41
+ }
42
+
43
+ export interface IEimzoContext {
44
+ isInstalled: boolean
45
+ isLoading: boolean
46
+ keyList: ICertificate[]
47
+ deviceStatus: IDeviceStatus
48
+ loadKeys: () => Promise<void>
49
+ sign: (params: ISignParams) => void
50
+ }