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/README.md +62 -0
- package/dist/index.cjs +1340 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +247 -0
- package/dist/index.d.ts +247 -0
- package/dist/index.js +1330 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
- package/src/cert-utils.ts +53 -0
- package/src/client.ts +456 -0
- package/src/errors.ts +73 -0
- package/src/index.ts +45 -0
- package/src/raw-types.ts +65 -0
- package/src/types.ts +112 -0
- package/src/util.ts +69 -0
- package/src/vendor/VENDOR.md +59 -0
- package/src/vendor/e-imzo-client.js +477 -0
- package/src/vendor/e-imzo.js +483 -0
- package/src/vendor/index.ts +46 -0
- package/src/vendor/vendor.d.ts +15 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { EimzoErrorCode } from './errors'
|
|
2
|
+
|
|
3
|
+
/** Sertifikat turi. `idcard` — ID-karta (alohida oqim, `loadKey` chaqirilmaydi). */
|
|
4
|
+
export type CertType = 'pfx' | 'ftjc' | 'idcard'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Normallashtirilgan sertifikat. `raw` — vendor xom obyekti, `loadKey` ga
|
|
8
|
+
* o'zgarishsiz uzatiladi (undan tashqarida foydalanmang).
|
|
9
|
+
*/
|
|
10
|
+
export interface Cert {
|
|
11
|
+
serialNumber: string
|
|
12
|
+
/** CN — egasi (F.I.Sh yoki tashkilot rahbari). */
|
|
13
|
+
CN: string
|
|
14
|
+
/** STIR / JSHSHIR. */
|
|
15
|
+
TIN: string
|
|
16
|
+
UID: string
|
|
17
|
+
/** Tashkilot nomi (jismoniy shaxs kalitida bo'sh). */
|
|
18
|
+
O: string
|
|
19
|
+
T: string
|
|
20
|
+
validFrom: Date
|
|
21
|
+
validTo: Date
|
|
22
|
+
type: CertType
|
|
23
|
+
/** @internal vendor xom obyekti */
|
|
24
|
+
raw: unknown
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface EimzoVersion {
|
|
28
|
+
major: number
|
|
29
|
+
minor: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface EimzoClientOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Domen API kalitlari: `[[domen, kalit], ...]`.
|
|
35
|
+
* E-IMZO tomonidan har domen uchun beriladi.
|
|
36
|
+
*
|
|
37
|
+
* MUHIM: kutubxonada default YO'Q. Ilova (consumer) o'z kalitlarini
|
|
38
|
+
* shu yerda beradi; prod kalitlari kutubxona kodiga yozilmaydi.
|
|
39
|
+
*/
|
|
40
|
+
apiKeys: ReadonlyArray<readonly [domain: string, key: string]>
|
|
41
|
+
|
|
42
|
+
/** Har bir CAPIWS chaqiruvi uchun timeout, ms. Default: 30000. */
|
|
43
|
+
timeoutMs?: number
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Kalit yuklash (parol kiritish) uchun alohida, uzunroq timeout, ms.
|
|
47
|
+
* Default: 120000.
|
|
48
|
+
*/
|
|
49
|
+
keyLoadTimeoutMs?: number
|
|
50
|
+
|
|
51
|
+
/** Minimal talab qilinadigan E-IMZO versiyasi. Default: 3.37. */
|
|
52
|
+
minVersion?: EimzoVersion
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Audit hook. Kutubxona HECH QACHON `console` ga yozmaydi — barcha
|
|
56
|
+
* kuzatuv shu yerdan o'tadi. Ilova buni o'z jurnaliga / SIEM'ga yozadi.
|
|
57
|
+
* Hook'dagi istisno kutubxonani buzmaydi (yutiladi).
|
|
58
|
+
*
|
|
59
|
+
* DIQQAT: `AuditEvent` ataylab minimal — faqat `serial` va `docId`.
|
|
60
|
+
* CN / TIN / JSHSHIR / imzo bloblari uzatilmaydi.
|
|
61
|
+
*/
|
|
62
|
+
onAudit?: (event: AuditEvent) => void
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Imzolanadigan bitta hujjat. */
|
|
66
|
+
export interface SignDoc {
|
|
67
|
+
/** Ilova ichidagi barqaror identifikator (natijani hujjatga bog'lash uchun). */
|
|
68
|
+
id: string
|
|
69
|
+
/** Imzolanadigan XOM kontent (matn / XML / base64). Base64 kodlashni kutubxona bajaradi. */
|
|
70
|
+
content: string
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Bitta hujjat bo'yicha imzo natijasi. */
|
|
74
|
+
export interface SignResult {
|
|
75
|
+
id: string
|
|
76
|
+
pkcs7_64: string
|
|
77
|
+
signature_hex: string
|
|
78
|
+
signer_serial_number: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Partiyadagi bitta element — muvaffaqiyat yoki xato. */
|
|
82
|
+
export type BatchSignItem =
|
|
83
|
+
| ({ id: string; ok: true } & Omit<SignResult, 'id'>)
|
|
84
|
+
| { id: string; ok: false; error: import('./errors').EimzoError }
|
|
85
|
+
|
|
86
|
+
export interface BatchProgress {
|
|
87
|
+
/** Tugagan hujjatlar soni. */
|
|
88
|
+
done: number
|
|
89
|
+
/** Jami hujjatlar. */
|
|
90
|
+
total: number
|
|
91
|
+
/** Hozir imzolanayotgan hujjat id'si (tugagach — undefined). */
|
|
92
|
+
currentId?: string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface SignBatchOptions {
|
|
96
|
+
/** Tashqi bekor qilish signali (idle-taymer, modal yopilishi). */
|
|
97
|
+
signal?: AbortSignal
|
|
98
|
+
/** Har bir hujjatdan oldin/keyin chaqiriladi. */
|
|
99
|
+
onProgress?: (progress: BatchProgress) => void
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Audit hodisalari. Ataylab minimal maydonlar — shaxsiy ma'lumot yo'q.
|
|
104
|
+
*/
|
|
105
|
+
export type AuditEvent =
|
|
106
|
+
| { type: 'version_checked'; ts: string; major: number; minor: number }
|
|
107
|
+
| { type: 'certs_listed'; ts: string; count: number }
|
|
108
|
+
| { type: 'key_loaded'; ts: string; serial: string }
|
|
109
|
+
| { type: 'sign_started'; ts: string; serial: string; docId: string }
|
|
110
|
+
| { type: 'sign_ok'; ts: string; serial: string; docId: string }
|
|
111
|
+
| { type: 'sign_failed'; ts: string; docId: string; code: EimzoErrorCode }
|
|
112
|
+
| { type: 'session_ended'; ts: string; serial: string; signed: number; failed: number }
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { EimzoError } from './errors'
|
|
2
|
+
|
|
3
|
+
export function nowIso(): string {
|
|
4
|
+
return new Date().toISOString()
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Seriya raqamlarini solishtirish uchun normallashtirish (registr + bo'shliqlar). */
|
|
8
|
+
export function normalizeSerial(value: unknown): string {
|
|
9
|
+
return String(value ?? '')
|
|
10
|
+
.toUpperCase()
|
|
11
|
+
.replace(/\s+/g, '')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function throwIfAborted(signal?: AbortSignal): void {
|
|
15
|
+
if (signal?.aborted) {
|
|
16
|
+
throw new EimzoError('E_CANCELLED', 'Amal bekor qilindi')
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Callback uslubidagi vendor chaqiruvini timeout bilan Promise'ga o'raydi.
|
|
22
|
+
* `settle` bir martagina ishlaydi (double-resolve himoyasi).
|
|
23
|
+
*/
|
|
24
|
+
export function withTimeout<T>(
|
|
25
|
+
timeoutMs: number,
|
|
26
|
+
timeoutError: () => EimzoError,
|
|
27
|
+
executor: (
|
|
28
|
+
resolve: (value: T) => void,
|
|
29
|
+
reject: (error: unknown) => void,
|
|
30
|
+
) => void,
|
|
31
|
+
signal?: AbortSignal,
|
|
32
|
+
): Promise<T> {
|
|
33
|
+
return new Promise<T>((resolve, reject) => {
|
|
34
|
+
let settled = false
|
|
35
|
+
|
|
36
|
+
const cleanup = (): void => {
|
|
37
|
+
clearTimeout(timer)
|
|
38
|
+
signal?.removeEventListener('abort', onAbort)
|
|
39
|
+
}
|
|
40
|
+
const settleResolve = (value: T): void => {
|
|
41
|
+
if (settled) return
|
|
42
|
+
settled = true
|
|
43
|
+
cleanup()
|
|
44
|
+
resolve(value)
|
|
45
|
+
}
|
|
46
|
+
const settleReject = (error: unknown): void => {
|
|
47
|
+
if (settled) return
|
|
48
|
+
settled = true
|
|
49
|
+
cleanup()
|
|
50
|
+
reject(error)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const onAbort = (): void =>
|
|
54
|
+
settleReject(new EimzoError('E_CANCELLED', 'Amal bekor qilindi'))
|
|
55
|
+
const timer = setTimeout(() => settleReject(timeoutError()), timeoutMs)
|
|
56
|
+
|
|
57
|
+
if (signal?.aborted) {
|
|
58
|
+
settleReject(new EimzoError('E_CANCELLED', 'Amal bekor qilindi'))
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
signal?.addEventListener('abort', onAbort)
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
executor(settleResolve, settleReject)
|
|
65
|
+
} catch (error) {
|
|
66
|
+
settleReject(error)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Vendored E-IMZO SDK fayllari
|
|
2
|
+
|
|
3
|
+
Bu papkadagi fayllar **E-IMZO'ning rasmiy brauzer SDK'sidan** olingan.
|
|
4
|
+
Ta'minot zanjiri (supply-chain) xavfsizligi uchun ular repozitoriyga qo'lda kiritilgan,
|
|
5
|
+
`npm` orqali emas.
|
|
6
|
+
|
|
7
|
+
| Fayl | Manba | Versiya | Holati | SHA-256 |
|
|
8
|
+
|---|---|---|---|---|
|
|
9
|
+
| `e-imzo.js` | https://e-imzo.uz | `< to'ldiring >` | 4 qatorlik patch (pastga qarang) | `751b0ca8592db0e37bd6f095161b1766651a47951e01cf13a4c68e1373fb1cc3` |
|
|
10
|
+
| `e-imzo-client.js` | https://e-imzo.uz | `< to'ldiring >` | O'zgartirilmagan | `b02a60e05854d305081affcf69785d4f185b130aadc2506d7de62a9d873b120c` |
|
|
11
|
+
|
|
12
|
+
## `e-imzo.js` ga kiritilgan patch
|
|
13
|
+
|
|
14
|
+
Sabab: rasmiy fayl klassik `<script>` sifatida yozilgan — top-level `this` global
|
|
15
|
+
obyekt deb faraz qiladi, `CAPIWS` ni **implicit global** deб e'lon qiladi va modul
|
|
16
|
+
yuklanganda `window.location` ni o'qiydi. ESM bundler (tsup/esbuild) ichida
|
|
17
|
+
`this === undefined`, implicit global taqiqlangan, SSR/Node'da esa `window` yo'q.
|
|
18
|
+
Quyidagi 4 ta o'zgarish kiritildi. **Xatti-harakat brauzerda o'zgarmaydi**,
|
|
19
|
+
`eval` / `new Function` ishlatilmaydi.
|
|
20
|
+
|
|
21
|
+
```diff
|
|
22
|
+
- 375: window.Base64 = global.Base64;
|
|
23
|
+
+ 375: if (typeof window !== 'undefined') window.Base64 = global.Base64;
|
|
24
|
+
|
|
25
|
+
- 376: })(this);
|
|
26
|
+
+ 376: })(typeof globalThis !== 'undefined' ? globalThis : this);
|
|
27
|
+
|
|
28
|
+
- 378: CAPIWS = (typeof EIMZOEXT !== 'undefined') ? EIMZOEXT : {
|
|
29
|
+
+ 378: globalThis.CAPIWS = (typeof EIMZOEXT !== 'undefined') ? EIMZOEXT : {
|
|
30
|
+
|
|
31
|
+
379: URL: (
|
|
32
|
+
- window.location.protocol.toLowerCase() === "https:"
|
|
33
|
+
+ (typeof window !== 'undefined' ? window.location.protocol : '').toLowerCase() === "https:"
|
|
34
|
+
? "wss://127.0.0.1:64443" : "ws://127.0.0.1:64646") + "/service/cryptapi",
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Yangilash tartibi
|
|
38
|
+
|
|
39
|
+
1. Rasmiy SDK'dan yangi faylni yuklab oling.
|
|
40
|
+
2. `git diff` bilan o'zgarishlarni ko'zdan kechiring (yangi tarmoq manzillari,
|
|
41
|
+
`eval` / `Function` / `innerHTML` / `document.write` paydo bo'lmaganini tekshiring).
|
|
42
|
+
3. Yuqoridagi 3 patchни qayta qo'llang.
|
|
43
|
+
4. `shasum -a 256 e-imzo.js e-imzo-client.js` — jadvalни yangilang.
|
|
44
|
+
5. `pnpm --filter eimzo-sign-core test` — kontrakt testlari o'tishини tasdiqlang.
|
|
45
|
+
6. Alohida commit: `chore(vendor): E-IMZO SDK x.y.z ga yangilash`.
|
|
46
|
+
|
|
47
|
+
CI `verify-vendor` bosqichi jadvaldagi SHA-256 bilan haqiqiy fayлларни solиштиради —
|
|
48
|
+
mos kelmаса build to'xtаyди.
|
|
49
|
+
|
|
50
|
+
## Ma'lum xususiyatlar (audit uchun)
|
|
51
|
+
|
|
52
|
+
- `e-imzo-client.js` `Date.prototype` va `String.prototype` ga metod qo'shади
|
|
53
|
+
(`yyyymmdd`, `ddmmyyyy`, `splitKeep`). Bu rasmiy SDK xatti-harakати.
|
|
54
|
+
- `e-imzo.js` global `CAPIWS` va `window.Base64` ni o'rnатади.
|
|
55
|
+
- Tashqи tarmoqqа chiqмайди; faqat lokal soket:
|
|
56
|
+
`ws://127.0.0.1:64646` (http) / `wss://127.0.0.1:64443` (https).
|
|
57
|
+
- `eval` / `new Function` / `document.write` / `innerHTML` ishlатилмайди.
|
|
58
|
+
- SSR eslатма: `e-imzo.js` modul yuklанганда `window.location.protocol` ni o'qийди —
|
|
59
|
+
paketни faqat brauzер muhitида import qiling (Vue qatlами buni ta'минлайди).
|