eimzo-sign-core 0.1.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/src/client.ts ADDED
@@ -0,0 +1,456 @@
1
+ import { EimzoError, toEimzoError } from './errors'
2
+ import type {
3
+ AuditEvent,
4
+ BatchSignItem,
5
+ Cert,
6
+ CertType,
7
+ EimzoClientOptions,
8
+ EimzoVersion,
9
+ SignBatchOptions,
10
+ SignDoc,
11
+ } from './types'
12
+ import { nowIso, normalizeSerial, throwIfAborted, withTimeout } from './util'
13
+ import { getBase64, getCapiws, rawClient } from './vendor'
14
+ import type { RawCapiResponse, RawCert } from './raw-types'
15
+
16
+ const DEFAULT_TIMEOUT_MS = 30_000
17
+ const DEFAULT_KEY_LOAD_TIMEOUT_MS = 120_000
18
+ const DEFAULT_MIN_VERSION: EimzoVersion = { major: 3, minor: 37 }
19
+
20
+ /**
21
+ * E-IMZO bilan ishlashning framework-agnostik yadrosi.
22
+ *
23
+ * Kafolatlar:
24
+ * - har chaqiruvda timeout bor (osilib qolmaydi);
25
+ * - `signBatch` kalitni BIR MARTA yuklaydi (parol bir marta so'raladi);
26
+ * - har imzodan keyin seriya raqami tanlangan sertifikatga tekshiriladi;
27
+ * - sessiya tugagach yuklangan kalit holati JS'da saqlanmaydi;
28
+ * - `console` ga hech narsa yozilmaydi — hammasi `onAudit` orqali.
29
+ */
30
+ export class EimzoClient {
31
+ private readonly apiKeys: ReadonlyArray<readonly [string, string]>
32
+ private readonly timeoutMs: number
33
+ private readonly keyLoadTimeoutMs: number
34
+ private readonly minVersion: EimzoVersion
35
+ private readonly onAudit?: (event: AuditEvent) => void
36
+
37
+ /** Faqat joriy sessiya davomida to'ldiriladi; `signBatch` oxirida tozalanadi. */
38
+ private activeKeySerial: string | null = null
39
+
40
+ constructor(options: EimzoClientOptions) {
41
+ if (!Array.isArray(options?.apiKeys) || options.apiKeys.length === 0) {
42
+ throw new EimzoError(
43
+ 'E_MISCONFIGURED',
44
+ "EimzoClient: 'apiKeys' berilishi shart ([[domen, kalit], ...]).",
45
+ )
46
+ }
47
+ this.apiKeys = options.apiKeys
48
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS
49
+ this.keyLoadTimeoutMs = options.keyLoadTimeoutMs ?? DEFAULT_KEY_LOAD_TIMEOUT_MS
50
+ this.minVersion = options.minVersion ?? DEFAULT_MIN_VERSION
51
+ this.onAudit = options.onAudit
52
+ }
53
+
54
+ // ─── Commanda: o'rnatish ────────────────────────────────────────────────
55
+
56
+ /**
57
+ * Versiyani tekshiradi va domen API kalitlarini o'rnatadi.
58
+ * Har imzolash seansidan oldin (yoki ilova yuklanganda bir marta) chaqiring.
59
+ */
60
+ async install(): Promise<EimzoVersion> {
61
+ const version = await this.checkVersion()
62
+
63
+ if (!isVersionAtLeast(version, this.minVersion)) {
64
+ throw new EimzoError(
65
+ 'E_VERSION_LOW',
66
+ `E-IMZO ${version.major}.${version.minor} — kamida ` +
67
+ `${this.minVersion.major}.${this.minVersion.minor} talab qilinadi.`,
68
+ )
69
+ }
70
+
71
+ rawClient.API_KEYS = this.apiKeys.flatMap(([domain, key]) => [domain, key])
72
+ await this.installApiKeys()
73
+ return version
74
+ }
75
+
76
+ checkVersion(): Promise<EimzoVersion> {
77
+ return withTimeout<EimzoVersion>(
78
+ this.timeoutMs,
79
+ () =>
80
+ new EimzoError(
81
+ 'E_NOT_INSTALLED',
82
+ "E-IMZO dasturi javob bermadi (versiya so'rovi). Dastur ishga tushganini tekshiring.",
83
+ ),
84
+ (resolve, reject) => {
85
+ rawClient.checkVersion(
86
+ (major, minor) => {
87
+ this.audit({ type: 'version_checked', ts: nowIso(), major, minor })
88
+ resolve({ major, minor })
89
+ },
90
+ (error) =>
91
+ reject(
92
+ new EimzoError('E_NOT_INSTALLED', 'E-IMZO dasturi topilmadi.', {
93
+ cause: error,
94
+ }),
95
+ ),
96
+ )
97
+ },
98
+ )
99
+ }
100
+
101
+ private installApiKeys(): Promise<void> {
102
+ return withTimeout<void>(
103
+ this.timeoutMs,
104
+ () => new EimzoError('E_TIMEOUT', "API kalitlari o'rnatilmadi (javob yo'q)."),
105
+ (resolve, reject) => {
106
+ rawClient.installApiKeys(
107
+ () => resolve(),
108
+ (error) =>
109
+ reject(
110
+ new EimzoError(
111
+ 'E_API_KEY_REJECTED',
112
+ "Domen API kaliti rad etildi. Domen va kalit juftligini tekshiring.",
113
+ { cause: error },
114
+ ),
115
+ ),
116
+ )
117
+ },
118
+ )
119
+ }
120
+
121
+ // ─── So'rov: sertifikatlar ───────────────────────────────────────────────
122
+
123
+ /** Foydalanuvchining barcha kalitlari (disk + token). ID-karta bunga kirmaydi. */
124
+ listCerts(): Promise<Cert[]> {
125
+ return withTimeout<Cert[]>(
126
+ this.timeoutMs,
127
+ () => new EimzoError('E_TIMEOUT', "Sertifikatlar ro'yxati javob bermadi."),
128
+ (resolve, reject) => {
129
+ rawClient.listAllUserKeys(
130
+ (cert, index) => `${cert.serialNumber}-${index}`,
131
+ (_id, cert) => cert,
132
+ (items) => {
133
+ const certs = (items as RawCert[]).map((raw) => normalizeCert(raw))
134
+ this.audit({ type: 'certs_listed', ts: nowIso(), count: certs.length })
135
+ resolve(certs)
136
+ },
137
+ (error) =>
138
+ reject(
139
+ new EimzoError('E_NO_CERTS', "Sertifikatlarni o'qib bo'lmadi.", {
140
+ cause: error,
141
+ }),
142
+ ),
143
+ )
144
+ },
145
+ )
146
+ }
147
+
148
+ /** ID-karta o'quvchiga ulanganmi. Timeout'da `false` qaytaradi (xato tashlamaydi). */
149
+ isIdCardPlugged(): Promise<boolean> {
150
+ return new Promise<boolean>((resolve) => {
151
+ let settled = false
152
+ const finish = (value: boolean): void => {
153
+ if (settled) return
154
+ settled = true
155
+ clearTimeout(timer)
156
+ resolve(value)
157
+ }
158
+ const timer = setTimeout(() => finish(false), this.timeoutMs)
159
+ try {
160
+ rawClient.idCardIsPLuggedIn(
161
+ (plugged) => finish(Boolean(plugged)),
162
+ () => finish(false),
163
+ )
164
+ } catch {
165
+ finish(false)
166
+ }
167
+ })
168
+ }
169
+
170
+ /** ID-karta uchun "sertifikat" o'rnini bosuvchi belgili obyekt. */
171
+ static idCardCert(): Cert {
172
+ const far = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000)
173
+ return {
174
+ serialNumber: 'IDCARD',
175
+ CN: 'ID card',
176
+ TIN: '',
177
+ UID: '',
178
+ O: '',
179
+ T: '',
180
+ validFrom: new Date(0),
181
+ validTo: far,
182
+ type: 'idcard',
183
+ raw: null,
184
+ }
185
+ }
186
+
187
+ // ─── Commanda: partiyali imzolash ───────────────────────────────────────
188
+
189
+ /**
190
+ * Bitta sertifikat bilan bir nechta hujjatni imzolaydi.
191
+ *
192
+ * Oqim:
193
+ * 1. Kalitni bir marta yuklaydi (`idcard` bo'lsa — yuklamaydi).
194
+ * 2. Har hujjat uchun `create_pkcs7` ni KETMA-KET chaqiradi (parallel EMAS —
195
+ * CAPIWS bitta soket).
196
+ * 3. Har natijada `signer_serial_number` ni tekshiradi.
197
+ * 4. Yakunda kalit holatini tozalaydi.
198
+ *
199
+ * Bitta hujjat xato bersa — massivda `ok:false` bilan qoladi, qolganlari davom etadi.
200
+ * Foydalanuvchi bekor qilsa (`signal`) — `E_CANCELLED` tashlanadi.
201
+ */
202
+ async signBatch(
203
+ cert: Cert,
204
+ docs: readonly SignDoc[],
205
+ options: SignBatchOptions = {},
206
+ ): Promise<BatchSignItem[]> {
207
+ if (docs.length === 0) {
208
+ throw new EimzoError('E_MISCONFIGURED', "Imzolash uchun hujjat berilmadi.")
209
+ }
210
+ assertUniqueIds(docs)
211
+ const { signal, onProgress } = options
212
+ throwIfAborted(signal)
213
+
214
+ const base64 = getBase64()
215
+ const keyId = await this.acquireKey(cert, signal)
216
+
217
+ const results: BatchSignItem[] = []
218
+ let signed = 0
219
+ let failed = 0
220
+
221
+ try {
222
+ for (let i = 0; i < docs.length; i += 1) {
223
+ throwIfAborted(signal)
224
+ const doc = docs[i]!
225
+ onProgress?.({ done: i, total: docs.length, currentId: doc.id })
226
+ this.audit({
227
+ type: 'sign_started',
228
+ ts: nowIso(),
229
+ serial: cert.serialNumber,
230
+ docId: doc.id,
231
+ })
232
+
233
+ try {
234
+ const raw = await this.createPkcs7(keyId, base64.encode(doc.content), signal)
235
+ const signerSerial = String(raw['signer_serial_number'] ?? '')
236
+
237
+ if (
238
+ cert.type !== 'idcard' &&
239
+ normalizeSerial(signerSerial) !== normalizeSerial(cert.serialNumber)
240
+ ) {
241
+ throw new EimzoError(
242
+ 'E_SERIAL_MISMATCH',
243
+ 'Imzolangan sertifikat seriyasi tanlangandan farq qiladi.',
244
+ )
245
+ }
246
+
247
+ results.push({
248
+ id: doc.id,
249
+ ok: true,
250
+ pkcs7_64: String(raw['pkcs7_64'] ?? ''),
251
+ signature_hex: String(raw['signature_hex'] ?? ''),
252
+ signer_serial_number: signerSerial,
253
+ })
254
+ signed += 1
255
+ this.audit({
256
+ type: 'sign_ok',
257
+ ts: nowIso(),
258
+ serial: cert.serialNumber,
259
+ docId: doc.id,
260
+ })
261
+ } catch (error) {
262
+ // Bekor qilish — butun partiyani to'xtatadi.
263
+ if (EimzoError.is(error, 'E_CANCELLED')) throw error
264
+
265
+ const err = toEimzoError(error, 'E_SIGN_FAILED', 'Hujjatni imzolab bo\'lmadi.')
266
+ results.push({ id: doc.id, ok: false, error: err })
267
+ failed += 1
268
+ this.audit({
269
+ type: 'sign_failed',
270
+ ts: nowIso(),
271
+ docId: doc.id,
272
+ code: err.code,
273
+ })
274
+ }
275
+ }
276
+
277
+ onProgress?.({ done: docs.length, total: docs.length })
278
+ return results
279
+ } finally {
280
+ // Kalitni JS holatida ushlab turmaymiz. E-IMZO dasturi kalitni o'z
281
+ // ichida qisqa TTL bilan eslaydi; biz unga tayanmaymiz.
282
+ this.activeKeySerial = null
283
+ this.audit({
284
+ type: 'session_ended',
285
+ ts: nowIso(),
286
+ serial: cert.serialNumber,
287
+ signed,
288
+ failed,
289
+ })
290
+ }
291
+ }
292
+
293
+ /** Yagona hujjatni imzolash — `signBatch` ustidagi qulaylik. */
294
+ async sign(
295
+ cert: Cert,
296
+ content: string,
297
+ options: SignBatchOptions = {},
298
+ ): Promise<BatchSignItem> {
299
+ const [item] = await this.signBatch(cert, [{ id: 'single', content }], options)
300
+ return item!
301
+ }
302
+
303
+ // ─── Ichki ─────────────────────────────────────────────────────────────
304
+
305
+ private async acquireKey(cert: Cert, signal?: AbortSignal): Promise<string> {
306
+ if (cert.type === 'idcard') return 'idcard'
307
+ try {
308
+ return await this.loadKey(cert, signal)
309
+ } catch (error) {
310
+ throw toEimzoError(
311
+ error,
312
+ 'E_KEY_LOAD_CANCELLED',
313
+ 'Kalit yuklanmadi yoki bekor qilindi.',
314
+ )
315
+ }
316
+ }
317
+
318
+ private loadKey(cert: Cert, signal?: AbortSignal): Promise<string> {
319
+ return withTimeout<string>(
320
+ this.keyLoadTimeoutMs,
321
+ () =>
322
+ new EimzoError(
323
+ 'E_KEY_LOAD_CANCELLED',
324
+ "Kalit yuklash javob bermadi (parol oynasi ochilmadi yoki yopilmadi).",
325
+ ),
326
+ (resolve, reject) => {
327
+ rawClient.loadKey(
328
+ cert.raw as RawCert,
329
+ (id) => {
330
+ this.activeKeySerial = cert.serialNumber
331
+ this.audit({
332
+ type: 'key_loaded',
333
+ ts: nowIso(),
334
+ serial: cert.serialNumber,
335
+ })
336
+ resolve(id)
337
+ },
338
+ (error) =>
339
+ reject(
340
+ new EimzoError('E_KEY_LOAD_CANCELLED', 'Kalit yuklanmadi.', {
341
+ cause: error,
342
+ }),
343
+ ),
344
+ )
345
+ },
346
+ signal,
347
+ )
348
+ }
349
+
350
+ private createPkcs7(
351
+ keyId: string,
352
+ contentBase64: string,
353
+ signal?: AbortSignal,
354
+ ): Promise<RawCapiResponse> {
355
+ return withTimeout<RawCapiResponse>(
356
+ this.timeoutMs,
357
+ () => new EimzoError('E_TIMEOUT', "Imzolash javob bermadi (create_pkcs7)."),
358
+ (resolve, reject) => {
359
+ let capiws
360
+ try {
361
+ capiws = getCapiws()
362
+ } catch (error) {
363
+ reject(error)
364
+ return
365
+ }
366
+ capiws.callFunction(
367
+ {
368
+ plugin: 'pkcs7',
369
+ name: 'create_pkcs7',
370
+ arguments: [contentBase64, keyId, 'no'],
371
+ },
372
+ (_event, data) => {
373
+ if (data && data.success) {
374
+ resolve(data)
375
+ } else {
376
+ reject(
377
+ new EimzoError(
378
+ 'E_SIGN_FAILED',
379
+ reasonOf(data) || 'E-IMZO imzolashni rad etdi.',
380
+ { cause: data },
381
+ ),
382
+ )
383
+ }
384
+ },
385
+ (error) =>
386
+ reject(
387
+ new EimzoError('E_TRANSPORT', "E-IMZO bilan aloqa uzildi.", {
388
+ cause: error,
389
+ }),
390
+ ),
391
+ )
392
+ },
393
+ signal,
394
+ )
395
+ }
396
+
397
+ private audit(event: AuditEvent): void {
398
+ if (!this.onAudit) return
399
+ try {
400
+ this.onAudit(event)
401
+ } catch {
402
+ // Audit hook consumer kodida yashaydi — uning xatosi kutubxonani buzmasin.
403
+ }
404
+ }
405
+ }
406
+
407
+ // ─── Modul yordamchilari ──────────────────────────────────────────────────
408
+
409
+ function isVersionAtLeast(actual: EimzoVersion, min: EimzoVersion): boolean {
410
+ if (actual.major !== min.major) return actual.major > min.major
411
+ return actual.minor >= min.minor
412
+ }
413
+
414
+ function reasonOf(data: RawCapiResponse | undefined | null): string {
415
+ return data && typeof data.reason === 'string' ? data.reason : ''
416
+ }
417
+
418
+ const KNOWN_TYPES: ReadonlySet<CertType> = new Set(['pfx', 'ftjc', 'idcard'])
419
+
420
+ function normalizeCert(raw: RawCert): Cert {
421
+ return {
422
+ serialNumber: normalizeSerial(raw.serialNumber),
423
+ CN: str(raw.CN),
424
+ TIN: str(raw.TIN),
425
+ UID: str(raw.UID),
426
+ O: str(raw.O),
427
+ T: str(raw.T),
428
+ validFrom: toDate(raw.validFrom),
429
+ validTo: toDate(raw.validTo),
430
+ type: KNOWN_TYPES.has(raw.type as CertType) ? (raw.type as CertType) : 'pfx',
431
+ raw,
432
+ }
433
+ }
434
+
435
+ function str(value: unknown): string {
436
+ return value == null ? '' : String(value)
437
+ }
438
+
439
+ function toDate(value: string | Date | undefined): Date {
440
+ if (value instanceof Date) return value
441
+ const d = new Date(String(value ?? ''))
442
+ return Number.isNaN(d.getTime()) ? new Date(0) : d
443
+ }
444
+
445
+ function assertUniqueIds(docs: readonly SignDoc[]): void {
446
+ const seen = new Set<string>()
447
+ for (const doc of docs) {
448
+ if (!doc.id) {
449
+ throw new EimzoError('E_MISCONFIGURED', 'Har bir hujjatda id bo\'lishi shart.')
450
+ }
451
+ if (seen.has(doc.id)) {
452
+ throw new EimzoError('E_MISCONFIGURED', `Hujjat id'si takrorlangan: ${doc.id}`)
453
+ }
454
+ seen.add(doc.id)
455
+ }
456
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * E-IMZO xatolarining barqaror kontrakti.
3
+ *
4
+ * Chaqiruvchi kod HAR DOIM `error.code` bo'yicha shox tanlaydi — xabar matnini
5
+ * hech qachon parslamaydi (matn i18n bilan o'zgaradi).
6
+ */
7
+ export type EimzoErrorCode =
8
+ /** E-IMZO dasturi ishga tushmagan yoki javob bermayapti. */
9
+ | 'E_NOT_INSTALLED'
10
+ /** E-IMZO versiyasi talab qilinganidan past. */
11
+ | 'E_VERSION_LOW'
12
+ /** Domen uchun API kaliti rad etildi (noto'g'ri kalit yoki domen). */
13
+ | 'E_API_KEY_REJECTED'
14
+ /** Foydalanuvchida sertifikat/kalit topilmadi yoki ro'yxatni o'qib bo'lmadi. */
15
+ | 'E_NO_CERTS'
16
+ /** Kalit yuklanmadi — ko'pincha foydalanuvchi parol oynasini yopgan. */
17
+ | 'E_KEY_LOAD_CANCELLED'
18
+ /** Imzolangan sertifikatning seriya raqami tanlangandan farq qiladi. XAVFSIZLIK. */
19
+ | 'E_SERIAL_MISMATCH'
20
+ /** `create_pkcs7` muvaffaqiyatsiz tugadi. */
21
+ | 'E_SIGN_FAILED'
22
+ /** E-IMZO belgilangan vaqt ichida javob bermadi. */
23
+ | 'E_TIMEOUT'
24
+ /** Foydalanuvchi yoki idle-taymer amalni bekor qildi. */
25
+ | 'E_CANCELLED'
26
+ /** Lokal soket / transport xatosi. */
27
+ | 'E_TRANSPORT'
28
+ /** Kutubxona noto'g'ri sozlangan (masalan, apiKeys berilmagan). */
29
+ | 'E_MISCONFIGURED'
30
+
31
+ export interface EimzoErrorOptions {
32
+ cause?: unknown
33
+ }
34
+
35
+ export class EimzoError extends Error {
36
+ readonly code: EimzoErrorCode
37
+ /** Asl sabab (vendor xatosi, CAPIWS javobi va h.k.). ES2022 `Error.cause` bilan bir xil nom. */
38
+ readonly cause?: unknown
39
+
40
+ constructor(code: EimzoErrorCode, message: string, options?: EimzoErrorOptions) {
41
+ super(message)
42
+ this.name = 'EimzoError'
43
+ this.code = code
44
+ this.cause = options?.cause
45
+ // TS -> eski target'da instanceof ishlashi uchun
46
+ Object.setPrototypeOf(this, EimzoError.prototype)
47
+ }
48
+
49
+ /** `EimzoError.is(e)` yoki `EimzoError.is(e, 'E_TIMEOUT')`. */
50
+ static is(error: unknown, code?: EimzoErrorCode): error is EimzoError {
51
+ return (
52
+ error instanceof EimzoError && (code === undefined || error.code === code)
53
+ )
54
+ }
55
+
56
+ /** Bekor qilingan (foydalanuvchi voz kechgan) — odatda jimgina o'tiladi. */
57
+ static isCancelled(error: unknown): boolean {
58
+ return (
59
+ EimzoError.is(error, 'E_CANCELLED') ||
60
+ EimzoError.is(error, 'E_KEY_LOAD_CANCELLED')
61
+ )
62
+ }
63
+ }
64
+
65
+ /** Noma'lum qiymatni EimzoError'ga keltiradi (allaqachon EimzoError bo'lsa — o'zini qaytaradi). */
66
+ export function toEimzoError(
67
+ error: unknown,
68
+ fallbackCode: EimzoErrorCode,
69
+ fallbackMessage: string,
70
+ ): EimzoError {
71
+ if (EimzoError.is(error)) return error
72
+ return new EimzoError(fallbackCode, fallbackMessage, { cause: error })
73
+ }
package/src/index.ts ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * eimzo-sign-core — E-IMZO imzolashning framework-agnostik yadrosi.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { EimzoClient } from 'eimzo-sign-core'
7
+ *
8
+ * const eimzo = new EimzoClient({
9
+ * apiKeys: [['example.uz', '<E-IMZO tomonidan berilgan kalit>']],
10
+ * onAudit: (e) => auditLog.write(e),
11
+ * })
12
+ *
13
+ * await eimzo.install()
14
+ * const certs = await eimzo.listCerts()
15
+ * const results = await eimzo.signBatch(certs[0], [
16
+ * { id: 'doc-1', content: xml1 },
17
+ * { id: 'doc-2', content: xml2 },
18
+ * ])
19
+ * ```
20
+ */
21
+ export { EimzoClient } from './client'
22
+ export { EimzoError, toEimzoError } from './errors'
23
+ export type { EimzoErrorCode, EimzoErrorOptions } from './errors'
24
+
25
+ export type {
26
+ AuditEvent,
27
+ BatchProgress,
28
+ BatchSignItem,
29
+ Cert,
30
+ CertType,
31
+ EimzoClientOptions,
32
+ EimzoVersion,
33
+ SignBatchOptions,
34
+ SignDoc,
35
+ SignResult,
36
+ } from './types'
37
+
38
+ export {
39
+ certExpiresSoon,
40
+ certIsExpired,
41
+ certIsNotYetValid,
42
+ certIsUsable,
43
+ dedupeCerts,
44
+ sortCerts,
45
+ } from './cert-utils'
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Vendored E-IMZO SDK'ning XOM (raw) API shakllari.
3
+ * Bu tiplar faqat `client.ts` ichida ishlatiladi; tashqariga chiqmaydi.
4
+ * Tashqi API uchun `types.ts` ga qarang.
5
+ */
6
+
7
+ export interface RawCapiResponse {
8
+ success: boolean
9
+ reason?: string
10
+ [key: string]: unknown
11
+ }
12
+
13
+ export interface RawCapiws {
14
+ URL?: string
15
+ callFunction(
16
+ funcDef: { plugin?: string; name: string; arguments: unknown[] },
17
+ callback: (event: unknown, data: RawCapiResponse) => void,
18
+ error: (e: unknown) => void,
19
+ ): void
20
+ }
21
+
22
+ export interface RawCert {
23
+ disk?: string
24
+ path?: string
25
+ name?: string
26
+ alias?: string
27
+ serialNumber: string
28
+ validFrom: string | Date
29
+ validTo: string | Date
30
+ CN?: string
31
+ TIN?: string
32
+ UID?: string
33
+ O?: string
34
+ T?: string
35
+ type?: string
36
+ }
37
+
38
+ export interface RawEimzoClient {
39
+ API_KEYS: string[]
40
+
41
+ checkVersion(
42
+ success: (major: number, minor: number) => void,
43
+ fail: (error: unknown, message?: unknown) => void,
44
+ ): void
45
+
46
+ installApiKeys(success: () => void, fail: (error: unknown) => void): void
47
+
48
+ idCardIsPLuggedIn(
49
+ success: (plugged: boolean) => void,
50
+ fail: (error: unknown) => void,
51
+ ): void
52
+
53
+ listAllUserKeys(
54
+ itemIdGen: (cert: RawCert, index: number) => string,
55
+ itemUiGen: (id: string, cert: RawCert) => unknown,
56
+ success: (items: unknown[], firstId: string | null) => void,
57
+ fail: (error: unknown, reason?: unknown) => void,
58
+ ): void
59
+
60
+ loadKey(
61
+ cert: RawCert,
62
+ success: (id: string) => void,
63
+ fail: (error: unknown) => void,
64
+ ): void
65
+ }