@gerege-systems/eid-mongolia-sdk 0.9.1 → 0.10.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 +65 -4
- package/dist/{browser-B_XtyuFG.d.cts → browser-BWCDj8xO.d.cts} +104 -5
- package/dist/{browser-B_XtyuFG.d.ts → browser-BWCDj8xO.d.ts} +104 -5
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/{chunk-NXDKQZIW.js → chunk-YDVPZMAL.js} +71 -2
- package/dist/index.cjs +547 -43
- package/dist/index.d.cts +331 -5
- package/dist/index.d.ts +331 -5
- package/dist/index.js +468 -37
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -154,6 +154,17 @@ console.log(who.documentNumber, who.subject); // баталгаажсан ирг
|
|
|
154
154
|
const { name, serialNumber } = who.parsedSubject; // "Болд Бат", "PNOMN-12345678" (givenName/surname/commonName/country…)
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
+
Session-ий `person` блок (CA бүртгэлээс — гэрчилгээнд байдаггүй кирилл нэр, төрсөн огноо, хүйс) гарын үсэгт **ордоггүй** —
|
|
158
|
+
гэрчилгээний `SERIALNUMBER`-тэй тулгаж байж итгэнэ:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { personMatchesCertificate } from "@gerege-systems/eid-mongolia-sdk";
|
|
162
|
+
if (personMatchesCertificate(result.person, who.parsedSubject)) {
|
|
163
|
+
const { firstName, lastName /* ЭЦГИЙН нэр */, familyName /* УРГИЙН овог */, civilId, regNo, birthDate, gender, geID } = result.person!;
|
|
164
|
+
}
|
|
165
|
+
// result.raw — серверийн түүхий JSON (SDK задлаагүй талбарт)
|
|
166
|
+
```
|
|
167
|
+
|
|
157
168
|
Subject-ийн талбарууд (`parsedSubject`, `validateSign`-д ч мөн) нь `parseSubject(cert)`-ээс — OID 2.5.4.42/4/3/5/6/10/97,
|
|
158
169
|
UTF8String/PrintableString/BMPString. `parseSubject` нь зөвхөн задлалт: баталгаажаагүй гэрчилгээний нэрэнд бүү итгэ.
|
|
159
170
|
|
|
@@ -182,6 +193,8 @@ const sig = eid.validator.validateSign(result, digest); // digest-ийн эср
|
|
|
182
193
|
console.log(sig.signatureValueB64, sig.subject);
|
|
183
194
|
```
|
|
184
195
|
|
|
196
|
+
`SignOptions.fileName` — баримтын нэр CA-ийн /verify хуудас, иргэний түүхэнд харагдана (заавал биш).
|
|
197
|
+
|
|
185
198
|
Device-link / push-оор эхлүүлсэн sign session-д эхлүүлсэн урсгалаа `expectedFlowType`-оор тулга (`validateAuth`-тай
|
|
186
199
|
ижил: зөрвөл `ValidationError`). Гуравдах параметр нь `hashAlgorithm` мөр (хуучин хэлбэр) эсвэл объект:
|
|
187
200
|
|
|
@@ -238,10 +251,38 @@ try {
|
|
|
238
251
|
(харуулсан урсгалаа). Гарын үсэгтэй PDF-ийг
|
|
239
252
|
`pdf.document()`-ийн оронд `pdf.documentVerified(sessionId, r.pdf)`-аар тат — `READY` + `outSha256` тулгалтыг хийнэ.
|
|
240
253
|
|
|
254
|
+
Түр алдаа — `ApiError.retryable` үнэн, `retryAfterMs`-ийн (CA-ийн `Retry-After`, секунд эсвэл огноо) дараа давтана:
|
|
255
|
+
prepare 429 `PDF_PREPARE_BUSY`, 503 `LTV_UNAVAILABLE` / `TSA_UNAVAILABLE`; document 503 `DOCUMENT_PENDING`,
|
|
256
|
+
`TSA_UNAVAILABLE`, `LTV_UNAVAILABLE` (`RETRYABLE_ERROR_CODES`). `headers` — хариуны header. PDF дуудлагын хугацаа
|
|
257
|
+
`pdfTimeoutMs` (анхдагч 80000).
|
|
258
|
+
|
|
241
259
|
Олон талт гэрээ: А байгууллагын гаралтыг өөрчлөлтгүй Б-ийн `prepare`-д (`docID`, өөр `onBehalfOf`) илгээнэ.
|
|
242
260
|
Session-ий `onBehalfOf` блок (`role`/`rightType`) нь хариу угсрах үеийн бүртгэл; `pdf.signer.onBehalfOf`/`claimedRole`
|
|
243
261
|
нь баримтад бичигдсэн утга.
|
|
244
262
|
|
|
263
|
+
## 3b. Иргэний PKI самбар (`PKI_READ` эрх)
|
|
264
|
+
|
|
265
|
+
`eid.person.certificates(etsi)` · `devices` · `activity(etsi, { flow, limit, offset })` · `summary` · `children` — иргэн
|
|
266
|
+
сүүлийн 24 цагт танай RP-ээр нэвтэрсэн байх ёстой (эс бөгөөс `ForbiddenError`). Хариу бүрт `raw`.
|
|
267
|
+
|
|
268
|
+
## 3c. USB токен
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
import { verifyTokenCertificates, tokenAuthDigest, tokenLimitOf } from "@gerege-systems/eid-mongolia-sdk";
|
|
272
|
+
|
|
273
|
+
// гэрчилгээ олголт (TOKEN_ISSUE эрх) — иргэн утсаараа PIN2-оор батална
|
|
274
|
+
const st = await eid.token.issueCertificate({ signerEtsi, csrAuth, csrSign, tokenSerial: "EP2003-0042A1" }); // onBehalfOf алга = хувийн
|
|
275
|
+
// … eid.session.poll(st.sessionId) → result.tokenCertificate?.status === "ISSUED"
|
|
276
|
+
const res = await eid.token.certificateResult(st.sessionId);
|
|
277
|
+
verifyTokenCertificates(res, csrAuth, csrSign); // гэрчилгээ бүр CSR-ийн түлхүүртэй
|
|
278
|
+
// 409 TOKEN_LIMIT_REACHED → tokenLimitOf(err): { kind, limit, organization? }
|
|
279
|
+
|
|
280
|
+
// токеноор нэвтрэх (AUTH эрх)
|
|
281
|
+
const ch = await eid.token.authChallenge();
|
|
282
|
+
const digest = tokenAuthDigest(ch.rpUUID, ch.challenge); // токен CKM_ECDSA → түүхий r||s
|
|
283
|
+
const who = await eid.token.authVerify(ch.challengeId, authCertDer, rs);
|
|
284
|
+
```
|
|
285
|
+
|
|
245
286
|
## 4. QR ба ижил төхөөрөмж — device link v3
|
|
246
287
|
|
|
247
288
|
Иргэн өөр төхөөрөмжийн дэлгэц дээрх **QR**-ийг утсаараа уншина, эсвэл RP-ийн сайт/аппыг eID апптай **ижил
|
|
@@ -345,18 +386,25 @@ OK ирж болзошгүй. Иймд `ResponseValidator`:
|
|
|
345
386
|
зөвхөн SHA-256 digest зурдаг (өөр hash хүссэн session-д сервер гарын үсэг гаргахгүй), тиймээс SHA-384/512
|
|
346
387
|
хүссэн session-д `ecdsa-with-SHA256` хариу ирвэл хуурамч гэж татгалзана.
|
|
347
388
|
|
|
348
|
-
|
|
389
|
+
5. Цуцлалт — `trust.revocation` (OCSP/CRL hook) → `checkRevocation`, эсвэл `checkRevocationStatus` (`"good"` /
|
|
390
|
+
`"unchecked"` (soft-fail) / `"skipped"` (hook алга)).
|
|
391
|
+
6. Нэмэлт (сонголттой): `allowedIssuerSkis: [CITIZEN_ISSUING_CA_SKI]` — зөвхөн иргэний Issuing CA (04)-ийн гэрчилгээ;
|
|
392
|
+
`checkKeyUsage: true` — auth → clientAuth, sign → nonRepudiation (CA-ийн профайл); `schemeName` — CA-ийн
|
|
393
|
+
`acsp_scheme_name` (анхдагч `smart-id`).
|
|
394
|
+
|
|
395
|
+
Аль нэг алхам бүтэлгүйтвэл `ValidationError` шиднэ — хариунд **итгэхгүй**. Алдааны текстэд иргэний нэр, PNOMN, РД
|
|
396
|
+
ордоггүй (`NetworkError.op`-д замыг `/etsi/…` болгоно) — шууд лог руу бичиж болно.
|
|
349
397
|
|
|
350
398
|
## Алдааны төрлүүд
|
|
351
399
|
|
|
352
400
|
| Алдаа | Утга |
|
|
353
401
|
|---|---|
|
|
354
|
-
| `AuthenticationError` | 401 — API secret
|
|
402
|
+
| `AuthenticationError` | 401 — API secret буруу/байхгүй; CA-ийн JSON бол `.serverMessage` (+ `.code`), proxy-ийнх бол алга (`.body`, `.headers`) |
|
|
355
403
|
| `ForbiddenError` | 403 — IP allowlist / mTLS / RP-ийн эрх; onBehalfOf татгалзвал `.code` (`OnBehalfErrorCode`) |
|
|
356
404
|
| `SessionFailedError` | endResult ≠ OK (TIMEOUT, USER_REFUSED…) — `.endResult`-оор салга |
|
|
357
405
|
| `ValidationError` | cert chain/signature/level шалгалт бүтэлгүйтсэн |
|
|
358
|
-
| `ApiError` | бусад HTTP алдаа (`.status`, `.body`, серверийн `.code` — ж: 404 `ORG_NOT_FOUND`) |
|
|
359
|
-
| `NetworkError` | timeout/сүлжээ |
|
|
406
|
+
| `ApiError` | бусад HTTP алдаа (`.status`, `.body`, серверийн `.code`, `.retryAfterMs`, `.headers`, `.retryable` — ж: 404 `ORG_NOT_FOUND`) |
|
|
407
|
+
| `NetworkError` | timeout/сүлжээ (`.op` — таних тэмдэггүй зам, `.timeout`) |
|
|
360
408
|
| `EidOidcError` | «eID-ээр нэвтрэх» (OIDC) — `.code`: `access_denied`, `login_required`, `state_mismatch`, `invalid_grant`, `invalid_id_token`, `server_error` … |
|
|
361
409
|
| `DeviceLinkError` | device-link холбоос угсрах боломжгүй (`deviceLinkBase` https биш, token/secret/lang хэлбэр, төрөлд хэрэгтэй талбар дутуу) |
|
|
362
410
|
|
|
@@ -377,3 +425,16 @@ npm install
|
|
|
377
425
|
npm run lint # tsc --noEmit
|
|
378
426
|
npm test # build + node --test
|
|
379
427
|
```
|
|
428
|
+
|
|
429
|
+
### Гэрээний шалгалт
|
|
430
|
+
|
|
431
|
+
SDK-ийн дууддаг RP-API зам бүр (`src/contract.ts`) live [`/.well-known/eid`](https://rp.eidmongolia.mn/.well-known/eid)-ийн
|
|
432
|
+
`endpoints`-д байх ёстой; OIDC-ийн хүлээдэг утгууд (issuer, `ES256`, PKCE `S256`, `client_secret_basic`, `EidIdTokenClaims`-ийн
|
|
433
|
+
талбарууд) [discovery](https://login.eidmongolia.mn/.well-known/openid-configuration)-тэй таарах ёстой. Discovery-д
|
|
434
|
+
байгаа ч SDK хамраагүй замууд WARN (fail биш). Сүлжээ шаарддаг тул `npm test`-д ордоггүй:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
npm run test:contract
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
CI: `.github/workflows/contract.yml` — PR, `main` push, өдөр бүр 00:00 UTC, гараар.
|
|
@@ -135,6 +135,46 @@ interface SessionResult {
|
|
|
135
135
|
* угсарсан объект). {@link PdfSessionBlock}.
|
|
136
136
|
*/
|
|
137
137
|
pdf?: PdfSessionBlock | null;
|
|
138
|
+
/**
|
|
139
|
+
* COMPLETE+OK auth session-ий `person` блок (CA бүртгэлээс: кирилл нэр, төрсөн огноо, хүйс — гэрчилгээнд байдаггүй).
|
|
140
|
+
* Зөвхөн session эзэмшигч RP-д; CA иргэнийг олоогүй бол null. ГАРЫН ҮСЭГТ ОРДОГГҮЙ — validateAuth-ийн дараа
|
|
141
|
+
* {@link personMatchesCertificate}-ээр гэрчилгээний SERIALNUMBER (`PNOMN-<civilId>`)-тэй тулгаж л хэрэглэнэ.
|
|
142
|
+
*/
|
|
143
|
+
person?: PersonBlock | null;
|
|
144
|
+
/** USB токены гэрчилгээ олголтын session-ий `tokenCertificate` блок (`token.issueCertificate`); бусад урсгалд null. */
|
|
145
|
+
tokenCertificate?: TokenCertSessionBlock | null;
|
|
146
|
+
/** Серверийн хариуны түүхий JSON (`parseSessionResult`-ийн оролт) — SDK задлаагүй талбарт. */
|
|
147
|
+
raw?: unknown;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Session-ий `person` блок (CA `dto.PersonBlock`). Нэршил core.gerege.mn-тэй нэг мөр — гурван нэр ӨӨР ойлголт:
|
|
151
|
+
* `firstName` = нэр, `lastName` = ЭЦГИЙН нэр (гэрчилгээнд ордог), `familyName` = УРГИЙН овог (гэрчилгээнд ОРОХГҮЙ).
|
|
152
|
+
* Мэдэгдэхгүй талбар undefined — RP заавал байх талбар гэж үзэхгүй.
|
|
153
|
+
*/
|
|
154
|
+
interface PersonBlock {
|
|
155
|
+
firstName?: string;
|
|
156
|
+
lastName?: string;
|
|
157
|
+
familyName?: string;
|
|
158
|
+
firstNameEn?: string;
|
|
159
|
+
lastNameEn?: string;
|
|
160
|
+
civilId?: string;
|
|
161
|
+
regNo?: string;
|
|
162
|
+
/** YYYY-MM-DD (цаг/бүсгүй). */
|
|
163
|
+
birthDate?: string;
|
|
164
|
+
/** M | F | X. */
|
|
165
|
+
gender?: string;
|
|
166
|
+
/** core.gerege.mn-ий дотоод дугаар; байхгүй = тулгагдаагүй. */
|
|
167
|
+
geID?: number;
|
|
168
|
+
}
|
|
169
|
+
/** Токены гэрчилгээ олголтын төлөв. */
|
|
170
|
+
type TokenCertStatus = "PENDING" | "ISSUED" | "FAILED" | "EXPIRED";
|
|
171
|
+
/** GET /session/{id}-ийн `tokenCertificate` (TOKEN_CERT §Төлөв). */
|
|
172
|
+
interface TokenCertSessionBlock {
|
|
173
|
+
status: TokenCertStatus | string;
|
|
174
|
+
/** FAILED үед: endResult (USER_REFUSED, TIMEOUT …) эсвэл CSR_DIGEST_MISMATCH, TOKEN_LIMIT_REACHED г.м. */
|
|
175
|
+
errorCode?: string;
|
|
176
|
+
authSerialHex?: string;
|
|
177
|
+
signSerialHex?: string;
|
|
138
178
|
}
|
|
139
179
|
/** PDF баримтын төлөв: PENDING → READY (эсвэл FAILED / EXPIRED). */
|
|
140
180
|
type PdfDocumentStatus = "PENDING" | "READY" | "FAILED" | "EXPIRED";
|
|
@@ -259,8 +299,32 @@ declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROption
|
|
|
259
299
|
declare class EidError extends Error {
|
|
260
300
|
constructor(message: string);
|
|
261
301
|
}
|
|
262
|
-
/** HTTP
|
|
302
|
+
/** HTTP хариуны нэмэлт мэдээлэл (алдааны төрлүүдэд). */
|
|
303
|
+
interface HttpErrorInit {
|
|
304
|
+
/** Хариуны header-ууд. */
|
|
305
|
+
headers?: Headers;
|
|
306
|
+
/** Retry-After (секунд эсвэл HTTP-огноо задалсан), мс; байхгүй/буруу бол undefined. */
|
|
307
|
+
retryAfterMs?: number;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. CA-ийн өөрийн 401 нь JSON `{"error"[,"code"]}` —
|
|
311
|
+
* `serverMessage` (ба байвал `code`) бөглөгдөнө; JSON биш (proxy / nginx) бол хоёул undefined — үүгээр CA-ийн 401-ийг
|
|
312
|
+
* proxy-ийнхоос ялгана.
|
|
313
|
+
*/
|
|
263
314
|
declare class AuthenticationError extends EidError {
|
|
315
|
+
/** Серверийн `{"code"}`; байхгүй / JSON биш (proxy) бол undefined. */
|
|
316
|
+
readonly code?: string;
|
|
317
|
+
/** Серверийн `{"error"}` текст (логт); JSON биш (proxy) бол undefined. */
|
|
318
|
+
readonly serverMessage?: string;
|
|
319
|
+
/** Хариуны бие (таслагдаагүй текст). */
|
|
320
|
+
readonly body?: string;
|
|
321
|
+
readonly headers?: Headers;
|
|
322
|
+
constructor(message: string, init?: {
|
|
323
|
+
code?: string;
|
|
324
|
+
serverMessage?: string;
|
|
325
|
+
body?: string;
|
|
326
|
+
headers?: Headers;
|
|
327
|
+
});
|
|
264
328
|
}
|
|
265
329
|
/**
|
|
266
330
|
* HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй, RP-д эрх алга, эсвэл onBehalfOf-ийн төлөөлөл татгалзсан.
|
|
@@ -269,9 +333,12 @@ declare class AuthenticationError extends EidError {
|
|
|
269
333
|
declare class ForbiddenError extends EidError {
|
|
270
334
|
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
271
335
|
readonly code?: string | undefined;
|
|
336
|
+
readonly headers?: Headers;
|
|
337
|
+
/** Retry-After (мс), байхгүй бол undefined. */
|
|
338
|
+
readonly retryAfterMs?: number;
|
|
272
339
|
constructor(message: string,
|
|
273
340
|
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
274
|
-
code?: string | undefined);
|
|
341
|
+
code?: string | undefined, init?: HttpErrorInit);
|
|
275
342
|
}
|
|
276
343
|
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
277
344
|
declare class ApiError extends EidError {
|
|
@@ -279,10 +346,31 @@ declare class ApiError extends EidError {
|
|
|
279
346
|
readonly body: string;
|
|
280
347
|
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
281
348
|
readonly code?: string | undefined;
|
|
349
|
+
readonly headers?: Headers;
|
|
350
|
+
/**
|
|
351
|
+
* Retry-After (мс, секунд эсвэл HTTP-огноо задалсан); байхгүй/буруу бол undefined. CA түр алдаанд (429
|
|
352
|
+
* PDF_PREPARE_BUSY / RATE_LIMITED, 503 DOCUMENT_PENDING / TSA_UNAVAILABLE / LTV_UNAVAILABLE г.м.) тавина.
|
|
353
|
+
*/
|
|
354
|
+
readonly retryAfterMs?: number;
|
|
282
355
|
constructor(status: number, body: string,
|
|
283
356
|
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
284
|
-
code?: string | undefined);
|
|
357
|
+
code?: string | undefined, init?: HttpErrorInit);
|
|
358
|
+
/**
|
|
359
|
+
* CA-ийн түр алдаа ({@link RETRYABLE_ERROR_CODES}-ийн нэг, эсвэл 429/503 + Retry-After): `retryAfterMs`-ийн дараа
|
|
360
|
+
* ижил хүсэлтийг давтаж болно.
|
|
361
|
+
*/
|
|
362
|
+
get retryable(): boolean;
|
|
285
363
|
}
|
|
364
|
+
/**
|
|
365
|
+
* CA-ийн түр (давтаж болох) алдааны кодууд — `ApiError.code`. PDF_PREPARE_BUSY (429 prepare, Retry-After 5),
|
|
366
|
+
* DOCUMENT_PENDING (503 document, 5), TSA_UNAVAILABLE (503, 30), LTV_UNAVAILABLE (503, 60), RATE_LIMITED (429 токен),
|
|
367
|
+
* STATE_UNAVAILABLE (503 токен), ISSUANCE_PENDING (503 токены үр дүн, 5).
|
|
368
|
+
*/
|
|
369
|
+
type RetryableErrorCode = "PDF_PREPARE_BUSY" | "DOCUMENT_PENDING" | "TSA_UNAVAILABLE" | "LTV_UNAVAILABLE" | "RATE_LIMITED" | "STATE_UNAVAILABLE" | "ISSUANCE_PENDING";
|
|
370
|
+
/** {@link RetryableErrorCode}-ийн бүх утга. */
|
|
371
|
+
declare const RETRYABLE_ERROR_CODES: readonly RetryableErrorCode[];
|
|
372
|
+
/** RFC 9110 §10.2.3: delay-seconds эсвэл HTTP-date → мс. Буруу / өнгөрсөн / 24 цагаас их → undefined. */
|
|
373
|
+
declare function parseRetryAfter(value: string | null | undefined, now?: number): number | undefined;
|
|
286
374
|
/**
|
|
287
375
|
* Байгууллагын нэрийн өмнөөс (`onBehalfOf`) урсгалын татгалзлын кодууд — `ForbiddenError.code` /
|
|
288
376
|
* `ApiError.code`-д ирнэ. 403: REPRESENTATION_DENIED (идэвхтэй төлөөлөгч биш), REPRESENTATION_PENDING (PIN2-оор
|
|
@@ -293,8 +381,19 @@ declare class ApiError extends EidError {
|
|
|
293
381
|
type OnBehalfErrorCode = "REPRESENTATION_DENIED" | "REPRESENTATION_PENDING" | "REPRESENTATION_EXPIRED" | "ORG_NOT_ACTIVE" | "SIGNER_UNIDENTIFIED" | "ORG_NOT_FOUND" | "REPRESENTATION_REVOKED";
|
|
294
382
|
/** {@link OnBehalfErrorCode}-ийн бүх утга (runtime шалгалтад). */
|
|
295
383
|
declare const ON_BEHALF_ERROR_CODES: readonly OnBehalfErrorCode[];
|
|
296
|
-
/**
|
|
384
|
+
/**
|
|
385
|
+
* Сүлжээ/timeout — upstream хариу өгсөнгүй. Мессеж ба `op`-д хувь хүний таних тэмдэг ОРОХГҮЙ (замын `/etsi/{…}`,
|
|
386
|
+
* `/document/{…}` → `…`) — шууд лог руу бичиж болно.
|
|
387
|
+
*/
|
|
297
388
|
declare class NetworkError extends EidError {
|
|
389
|
+
/** "GET /session/…" (таних тэмдэг хасагдсан зам). */
|
|
390
|
+
readonly op?: string;
|
|
391
|
+
/** Хүсэлт хугацаа хэтэрсэн. */
|
|
392
|
+
readonly timeout?: boolean;
|
|
393
|
+
constructor(message: string, init?: {
|
|
394
|
+
op?: string;
|
|
395
|
+
timeout?: boolean;
|
|
396
|
+
});
|
|
298
397
|
}
|
|
299
398
|
/**
|
|
300
399
|
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
@@ -318,4 +417,4 @@ declare class ValidationError extends EidError {
|
|
|
318
417
|
declare class DeviceLinkError extends EidError {
|
|
319
418
|
}
|
|
320
419
|
|
|
321
|
-
export { type AcspContext as A, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type HashAlgorithm as H, type Interaction as I, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type
|
|
420
|
+
export { type AcspContext as A, isMobileUserAgent as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, openOrShowQR as G, type HashAlgorithm as H, type Interaction as I, parseRetryAfter as J, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, ValidationError as V, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, DeviceLinkError as f, type DeviceLinkInput as g, type EndResult as h, ForbiddenError as i, type HttpErrorInit as j, type NavigatorLike as k, NetworkError as l, type OnBehalfErrorCode as m, type OpenOrShowQROptions as n, type OrgResult as o, type PdfDocumentStatus as p, type PdfSigner as q, RETRYABLE_ERROR_CODES as r, type Representation as s, type RetryableErrorCode as t, SessionFailedError as u, type SessionState as v, type SignatureAlgorithmParameters as w, type SignatureProtocol as x, type TokenCertStatus as y, deviceLink as z };
|
|
@@ -135,6 +135,46 @@ interface SessionResult {
|
|
|
135
135
|
* угсарсан объект). {@link PdfSessionBlock}.
|
|
136
136
|
*/
|
|
137
137
|
pdf?: PdfSessionBlock | null;
|
|
138
|
+
/**
|
|
139
|
+
* COMPLETE+OK auth session-ий `person` блок (CA бүртгэлээс: кирилл нэр, төрсөн огноо, хүйс — гэрчилгээнд байдаггүй).
|
|
140
|
+
* Зөвхөн session эзэмшигч RP-д; CA иргэнийг олоогүй бол null. ГАРЫН ҮСЭГТ ОРДОГГҮЙ — validateAuth-ийн дараа
|
|
141
|
+
* {@link personMatchesCertificate}-ээр гэрчилгээний SERIALNUMBER (`PNOMN-<civilId>`)-тэй тулгаж л хэрэглэнэ.
|
|
142
|
+
*/
|
|
143
|
+
person?: PersonBlock | null;
|
|
144
|
+
/** USB токены гэрчилгээ олголтын session-ий `tokenCertificate` блок (`token.issueCertificate`); бусад урсгалд null. */
|
|
145
|
+
tokenCertificate?: TokenCertSessionBlock | null;
|
|
146
|
+
/** Серверийн хариуны түүхий JSON (`parseSessionResult`-ийн оролт) — SDK задлаагүй талбарт. */
|
|
147
|
+
raw?: unknown;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Session-ий `person` блок (CA `dto.PersonBlock`). Нэршил core.gerege.mn-тэй нэг мөр — гурван нэр ӨӨР ойлголт:
|
|
151
|
+
* `firstName` = нэр, `lastName` = ЭЦГИЙН нэр (гэрчилгээнд ордог), `familyName` = УРГИЙН овог (гэрчилгээнд ОРОХГҮЙ).
|
|
152
|
+
* Мэдэгдэхгүй талбар undefined — RP заавал байх талбар гэж үзэхгүй.
|
|
153
|
+
*/
|
|
154
|
+
interface PersonBlock {
|
|
155
|
+
firstName?: string;
|
|
156
|
+
lastName?: string;
|
|
157
|
+
familyName?: string;
|
|
158
|
+
firstNameEn?: string;
|
|
159
|
+
lastNameEn?: string;
|
|
160
|
+
civilId?: string;
|
|
161
|
+
regNo?: string;
|
|
162
|
+
/** YYYY-MM-DD (цаг/бүсгүй). */
|
|
163
|
+
birthDate?: string;
|
|
164
|
+
/** M | F | X. */
|
|
165
|
+
gender?: string;
|
|
166
|
+
/** core.gerege.mn-ий дотоод дугаар; байхгүй = тулгагдаагүй. */
|
|
167
|
+
geID?: number;
|
|
168
|
+
}
|
|
169
|
+
/** Токены гэрчилгээ олголтын төлөв. */
|
|
170
|
+
type TokenCertStatus = "PENDING" | "ISSUED" | "FAILED" | "EXPIRED";
|
|
171
|
+
/** GET /session/{id}-ийн `tokenCertificate` (TOKEN_CERT §Төлөв). */
|
|
172
|
+
interface TokenCertSessionBlock {
|
|
173
|
+
status: TokenCertStatus | string;
|
|
174
|
+
/** FAILED үед: endResult (USER_REFUSED, TIMEOUT …) эсвэл CSR_DIGEST_MISMATCH, TOKEN_LIMIT_REACHED г.м. */
|
|
175
|
+
errorCode?: string;
|
|
176
|
+
authSerialHex?: string;
|
|
177
|
+
signSerialHex?: string;
|
|
138
178
|
}
|
|
139
179
|
/** PDF баримтын төлөв: PENDING → READY (эсвэл FAILED / EXPIRED). */
|
|
140
180
|
type PdfDocumentStatus = "PENDING" | "READY" | "FAILED" | "EXPIRED";
|
|
@@ -259,8 +299,32 @@ declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROption
|
|
|
259
299
|
declare class EidError extends Error {
|
|
260
300
|
constructor(message: string);
|
|
261
301
|
}
|
|
262
|
-
/** HTTP
|
|
302
|
+
/** HTTP хариуны нэмэлт мэдээлэл (алдааны төрлүүдэд). */
|
|
303
|
+
interface HttpErrorInit {
|
|
304
|
+
/** Хариуны header-ууд. */
|
|
305
|
+
headers?: Headers;
|
|
306
|
+
/** Retry-After (секунд эсвэл HTTP-огноо задалсан), мс; байхгүй/буруу бол undefined. */
|
|
307
|
+
retryAfterMs?: number;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. CA-ийн өөрийн 401 нь JSON `{"error"[,"code"]}` —
|
|
311
|
+
* `serverMessage` (ба байвал `code`) бөглөгдөнө; JSON биш (proxy / nginx) бол хоёул undefined — үүгээр CA-ийн 401-ийг
|
|
312
|
+
* proxy-ийнхоос ялгана.
|
|
313
|
+
*/
|
|
263
314
|
declare class AuthenticationError extends EidError {
|
|
315
|
+
/** Серверийн `{"code"}`; байхгүй / JSON биш (proxy) бол undefined. */
|
|
316
|
+
readonly code?: string;
|
|
317
|
+
/** Серверийн `{"error"}` текст (логт); JSON биш (proxy) бол undefined. */
|
|
318
|
+
readonly serverMessage?: string;
|
|
319
|
+
/** Хариуны бие (таслагдаагүй текст). */
|
|
320
|
+
readonly body?: string;
|
|
321
|
+
readonly headers?: Headers;
|
|
322
|
+
constructor(message: string, init?: {
|
|
323
|
+
code?: string;
|
|
324
|
+
serverMessage?: string;
|
|
325
|
+
body?: string;
|
|
326
|
+
headers?: Headers;
|
|
327
|
+
});
|
|
264
328
|
}
|
|
265
329
|
/**
|
|
266
330
|
* HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй, RP-д эрх алга, эсвэл onBehalfOf-ийн төлөөлөл татгалзсан.
|
|
@@ -269,9 +333,12 @@ declare class AuthenticationError extends EidError {
|
|
|
269
333
|
declare class ForbiddenError extends EidError {
|
|
270
334
|
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
271
335
|
readonly code?: string | undefined;
|
|
336
|
+
readonly headers?: Headers;
|
|
337
|
+
/** Retry-After (мс), байхгүй бол undefined. */
|
|
338
|
+
readonly retryAfterMs?: number;
|
|
272
339
|
constructor(message: string,
|
|
273
340
|
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
274
|
-
code?: string | undefined);
|
|
341
|
+
code?: string | undefined, init?: HttpErrorInit);
|
|
275
342
|
}
|
|
276
343
|
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
277
344
|
declare class ApiError extends EidError {
|
|
@@ -279,10 +346,31 @@ declare class ApiError extends EidError {
|
|
|
279
346
|
readonly body: string;
|
|
280
347
|
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
281
348
|
readonly code?: string | undefined;
|
|
349
|
+
readonly headers?: Headers;
|
|
350
|
+
/**
|
|
351
|
+
* Retry-After (мс, секунд эсвэл HTTP-огноо задалсан); байхгүй/буруу бол undefined. CA түр алдаанд (429
|
|
352
|
+
* PDF_PREPARE_BUSY / RATE_LIMITED, 503 DOCUMENT_PENDING / TSA_UNAVAILABLE / LTV_UNAVAILABLE г.м.) тавина.
|
|
353
|
+
*/
|
|
354
|
+
readonly retryAfterMs?: number;
|
|
282
355
|
constructor(status: number, body: string,
|
|
283
356
|
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
284
|
-
code?: string | undefined);
|
|
357
|
+
code?: string | undefined, init?: HttpErrorInit);
|
|
358
|
+
/**
|
|
359
|
+
* CA-ийн түр алдаа ({@link RETRYABLE_ERROR_CODES}-ийн нэг, эсвэл 429/503 + Retry-After): `retryAfterMs`-ийн дараа
|
|
360
|
+
* ижил хүсэлтийг давтаж болно.
|
|
361
|
+
*/
|
|
362
|
+
get retryable(): boolean;
|
|
285
363
|
}
|
|
364
|
+
/**
|
|
365
|
+
* CA-ийн түр (давтаж болох) алдааны кодууд — `ApiError.code`. PDF_PREPARE_BUSY (429 prepare, Retry-After 5),
|
|
366
|
+
* DOCUMENT_PENDING (503 document, 5), TSA_UNAVAILABLE (503, 30), LTV_UNAVAILABLE (503, 60), RATE_LIMITED (429 токен),
|
|
367
|
+
* STATE_UNAVAILABLE (503 токен), ISSUANCE_PENDING (503 токены үр дүн, 5).
|
|
368
|
+
*/
|
|
369
|
+
type RetryableErrorCode = "PDF_PREPARE_BUSY" | "DOCUMENT_PENDING" | "TSA_UNAVAILABLE" | "LTV_UNAVAILABLE" | "RATE_LIMITED" | "STATE_UNAVAILABLE" | "ISSUANCE_PENDING";
|
|
370
|
+
/** {@link RetryableErrorCode}-ийн бүх утга. */
|
|
371
|
+
declare const RETRYABLE_ERROR_CODES: readonly RetryableErrorCode[];
|
|
372
|
+
/** RFC 9110 §10.2.3: delay-seconds эсвэл HTTP-date → мс. Буруу / өнгөрсөн / 24 цагаас их → undefined. */
|
|
373
|
+
declare function parseRetryAfter(value: string | null | undefined, now?: number): number | undefined;
|
|
286
374
|
/**
|
|
287
375
|
* Байгууллагын нэрийн өмнөөс (`onBehalfOf`) урсгалын татгалзлын кодууд — `ForbiddenError.code` /
|
|
288
376
|
* `ApiError.code`-д ирнэ. 403: REPRESENTATION_DENIED (идэвхтэй төлөөлөгч биш), REPRESENTATION_PENDING (PIN2-оор
|
|
@@ -293,8 +381,19 @@ declare class ApiError extends EidError {
|
|
|
293
381
|
type OnBehalfErrorCode = "REPRESENTATION_DENIED" | "REPRESENTATION_PENDING" | "REPRESENTATION_EXPIRED" | "ORG_NOT_ACTIVE" | "SIGNER_UNIDENTIFIED" | "ORG_NOT_FOUND" | "REPRESENTATION_REVOKED";
|
|
294
382
|
/** {@link OnBehalfErrorCode}-ийн бүх утга (runtime шалгалтад). */
|
|
295
383
|
declare const ON_BEHALF_ERROR_CODES: readonly OnBehalfErrorCode[];
|
|
296
|
-
/**
|
|
384
|
+
/**
|
|
385
|
+
* Сүлжээ/timeout — upstream хариу өгсөнгүй. Мессеж ба `op`-д хувь хүний таних тэмдэг ОРОХГҮЙ (замын `/etsi/{…}`,
|
|
386
|
+
* `/document/{…}` → `…`) — шууд лог руу бичиж болно.
|
|
387
|
+
*/
|
|
297
388
|
declare class NetworkError extends EidError {
|
|
389
|
+
/** "GET /session/…" (таних тэмдэг хасагдсан зам). */
|
|
390
|
+
readonly op?: string;
|
|
391
|
+
/** Хүсэлт хугацаа хэтэрсэн. */
|
|
392
|
+
readonly timeout?: boolean;
|
|
393
|
+
constructor(message: string, init?: {
|
|
394
|
+
op?: string;
|
|
395
|
+
timeout?: boolean;
|
|
396
|
+
});
|
|
298
397
|
}
|
|
299
398
|
/**
|
|
300
399
|
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
@@ -318,4 +417,4 @@ declare class ValidationError extends EidError {
|
|
|
318
417
|
declare class DeviceLinkError extends EidError {
|
|
319
418
|
}
|
|
320
419
|
|
|
321
|
-
export { type AcspContext as A, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type HashAlgorithm as H, type Interaction as I, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type
|
|
420
|
+
export { type AcspContext as A, isMobileUserAgent as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, openOrShowQR as G, type HashAlgorithm as H, type Interaction as I, parseRetryAfter as J, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, ValidationError as V, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, DeviceLinkError as f, type DeviceLinkInput as g, type EndResult as h, ForbiddenError as i, type HttpErrorInit as j, type NavigatorLike as k, NetworkError as l, type OnBehalfErrorCode as m, type OpenOrShowQROptions as n, type OrgResult as o, type PdfDocumentStatus as p, type PdfSigner as q, RETRYABLE_ERROR_CODES as r, type Representation as s, type RetryableErrorCode as t, SessionFailedError as u, type SessionState as v, type SignatureAlgorithmParameters as w, type SignatureProtocol as x, type TokenCertStatus as y, deviceLink as z };
|
package/dist/browser.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { f as DeviceLinkError, g as DeviceLinkInput, D as DeviceLinkSession, E as EidError, k as NavigatorLike, n as OpenOrShowQROptions, z as deviceLink, B as isMobileUserAgent, G as openOrShowQR } from './browser-BWCDj8xO.cjs';
|
package/dist/browser.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { f as DeviceLinkError, g as DeviceLinkInput, D as DeviceLinkSession, E as EidError, k as NavigatorLike, n as OpenOrShowQROptions, z as deviceLink, B as isMobileUserAgent, G as openOrShowQR } from './browser-BWCDj8xO.js';
|
package/dist/browser.js
CHANGED
|
@@ -6,25 +6,79 @@ var EidError = class extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
8
|
var AuthenticationError = class extends EidError {
|
|
9
|
+
/** Серверийн `{"code"}`; байхгүй / JSON биш (proxy) бол undefined. */
|
|
10
|
+
code;
|
|
11
|
+
/** Серверийн `{"error"}` текст (логт); JSON биш (proxy) бол undefined. */
|
|
12
|
+
serverMessage;
|
|
13
|
+
/** Хариуны бие (таслагдаагүй текст). */
|
|
14
|
+
body;
|
|
15
|
+
headers;
|
|
16
|
+
constructor(message, init) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.code = init?.code;
|
|
19
|
+
this.serverMessage = init?.serverMessage;
|
|
20
|
+
this.body = init?.body;
|
|
21
|
+
this.headers = init?.headers;
|
|
22
|
+
}
|
|
9
23
|
};
|
|
10
24
|
var ForbiddenError = class extends EidError {
|
|
11
|
-
constructor(message, code) {
|
|
25
|
+
constructor(message, code, init) {
|
|
12
26
|
super(message);
|
|
13
27
|
this.code = code;
|
|
28
|
+
this.headers = init?.headers;
|
|
29
|
+
this.retryAfterMs = init?.retryAfterMs;
|
|
14
30
|
}
|
|
15
31
|
code;
|
|
32
|
+
headers;
|
|
33
|
+
/** Retry-After (мс), байхгүй бол undefined. */
|
|
34
|
+
retryAfterMs;
|
|
16
35
|
};
|
|
17
36
|
var ApiError = class extends EidError {
|
|
18
|
-
constructor(status, body, code) {
|
|
37
|
+
constructor(status, body, code, init) {
|
|
19
38
|
super(`RP-API ${status}: ${body}`);
|
|
20
39
|
this.status = status;
|
|
21
40
|
this.body = body;
|
|
22
41
|
this.code = code;
|
|
42
|
+
this.headers = init?.headers;
|
|
43
|
+
this.retryAfterMs = init?.retryAfterMs;
|
|
23
44
|
}
|
|
24
45
|
status;
|
|
25
46
|
body;
|
|
26
47
|
code;
|
|
48
|
+
headers;
|
|
49
|
+
/**
|
|
50
|
+
* Retry-After (мс, секунд эсвэл HTTP-огноо задалсан); байхгүй/буруу бол undefined. CA түр алдаанд (429
|
|
51
|
+
* PDF_PREPARE_BUSY / RATE_LIMITED, 503 DOCUMENT_PENDING / TSA_UNAVAILABLE / LTV_UNAVAILABLE г.м.) тавина.
|
|
52
|
+
*/
|
|
53
|
+
retryAfterMs;
|
|
54
|
+
/**
|
|
55
|
+
* CA-ийн түр алдаа ({@link RETRYABLE_ERROR_CODES}-ийн нэг, эсвэл 429/503 + Retry-After): `retryAfterMs`-ийн дараа
|
|
56
|
+
* ижил хүсэлтийг давтаж болно.
|
|
57
|
+
*/
|
|
58
|
+
get retryable() {
|
|
59
|
+
if (this.code && RETRYABLE_ERROR_CODES.includes(this.code)) return true;
|
|
60
|
+
return (this.status === 429 || this.status === 503) && (this.retryAfterMs ?? 0) > 0;
|
|
61
|
+
}
|
|
27
62
|
};
|
|
63
|
+
var RETRYABLE_ERROR_CODES = [
|
|
64
|
+
"PDF_PREPARE_BUSY",
|
|
65
|
+
"DOCUMENT_PENDING",
|
|
66
|
+
"TSA_UNAVAILABLE",
|
|
67
|
+
"LTV_UNAVAILABLE",
|
|
68
|
+
"RATE_LIMITED",
|
|
69
|
+
"STATE_UNAVAILABLE",
|
|
70
|
+
"ISSUANCE_PENDING"
|
|
71
|
+
];
|
|
72
|
+
function parseRetryAfter(value, now = Date.now()) {
|
|
73
|
+
const v = (value ?? "").trim();
|
|
74
|
+
if (!v) return void 0;
|
|
75
|
+
if (/^-?\d+$/.test(v)) {
|
|
76
|
+
const n = Number(v);
|
|
77
|
+
return n > 0 && n <= 86400 ? n * 1e3 : void 0;
|
|
78
|
+
}
|
|
79
|
+
const t = Date.parse(v);
|
|
80
|
+
return Number.isNaN(t) || t <= now ? void 0 : t - now;
|
|
81
|
+
}
|
|
28
82
|
var ON_BEHALF_ERROR_CODES = [
|
|
29
83
|
"REPRESENTATION_DENIED",
|
|
30
84
|
"REPRESENTATION_PENDING",
|
|
@@ -35,7 +89,19 @@ var ON_BEHALF_ERROR_CODES = [
|
|
|
35
89
|
"REPRESENTATION_REVOKED"
|
|
36
90
|
];
|
|
37
91
|
var NetworkError = class extends EidError {
|
|
92
|
+
/** "GET /session/…" (таних тэмдэг хасагдсан зам). */
|
|
93
|
+
op;
|
|
94
|
+
/** Хүсэлт хугацаа хэтэрсэн. */
|
|
95
|
+
timeout;
|
|
96
|
+
constructor(message, init) {
|
|
97
|
+
super(message);
|
|
98
|
+
this.op = init?.op;
|
|
99
|
+
this.timeout = init?.timeout;
|
|
100
|
+
}
|
|
38
101
|
};
|
|
102
|
+
function maskPath(path) {
|
|
103
|
+
return path.split(/[?#]/)[0].replace(/\/(etsi|document)\/[^/?#\s]+/g, "/$1/\u2026");
|
|
104
|
+
}
|
|
39
105
|
var SessionFailedError = class extends EidError {
|
|
40
106
|
constructor(endResult) {
|
|
41
107
|
super(`Session \u0430\u043C\u0436\u0438\u043B\u0442\u0433\u04AF\u0439: ${endResult}`);
|
|
@@ -95,8 +161,11 @@ export {
|
|
|
95
161
|
AuthenticationError,
|
|
96
162
|
ForbiddenError,
|
|
97
163
|
ApiError,
|
|
164
|
+
RETRYABLE_ERROR_CODES,
|
|
165
|
+
parseRetryAfter,
|
|
98
166
|
ON_BEHALF_ERROR_CODES,
|
|
99
167
|
NetworkError,
|
|
168
|
+
maskPath,
|
|
100
169
|
SessionFailedError,
|
|
101
170
|
ValidationError,
|
|
102
171
|
DeviceLinkError,
|