@gerege-systems/eid-mongolia-sdk 0.10.0 → 0.12.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 +25 -4
- package/dist/{browser-BWCDj8xO.d.cts → browser-B_xuB7Rt.d.cts} +24 -3
- package/dist/{browser-BWCDj8xO.d.ts → browser-B_xuB7Rt.d.ts} +24 -3
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/{chunk-YDVPZMAL.js → chunk-QPJDZLHR.js} +10 -0
- package/dist/index.cjs +252 -30
- package/dist/index.d.cts +81 -6
- package/dist/index.d.ts +81 -6
- package/dist/index.js +243 -31
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
AuthenticationError: () => AuthenticationError,
|
|
26
26
|
CITIZEN_ISSUING_CA_SKI: () => CITIZEN_ISSUING_CA_SKI,
|
|
27
27
|
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
|
|
28
|
+
DEFAULT_PDF_MAX_BYTES: () => DEFAULT_PDF_MAX_BYTES,
|
|
28
29
|
DEFAULT_PDF_TIMEOUT_MS: () => DEFAULT_PDF_TIMEOUT_MS,
|
|
29
30
|
DeviceLinkError: () => DeviceLinkError,
|
|
30
31
|
EID_ACR_ADVANCED: () => EID_ACR_ADVANCED,
|
|
@@ -42,6 +43,7 @@ __export(index_exports, {
|
|
|
42
43
|
PdfApi: () => PdfApi,
|
|
43
44
|
PersonApi: () => PersonApi,
|
|
44
45
|
RETRYABLE_ERROR_CODES: () => RETRYABLE_ERROR_CODES,
|
|
46
|
+
ResponseTooLargeError: () => ResponseTooLargeError,
|
|
45
47
|
ResponseValidator: () => ResponseValidator,
|
|
46
48
|
SessionApi: () => SessionApi,
|
|
47
49
|
SessionFailedError: () => SessionFailedError,
|
|
@@ -174,6 +176,15 @@ var NetworkError = class extends EidError {
|
|
|
174
176
|
this.timeout = init?.timeout;
|
|
175
177
|
}
|
|
176
178
|
};
|
|
179
|
+
var ResponseTooLargeError = class extends EidError {
|
|
180
|
+
constructor(op, limit) {
|
|
181
|
+
super(`${op}: \u0445\u0430\u0440\u0438\u0443 ${limit} \u0431\u0430\u0439\u0442\u0430\u0430\u0441 \u0438\u0445`);
|
|
182
|
+
this.op = op;
|
|
183
|
+
this.limit = limit;
|
|
184
|
+
}
|
|
185
|
+
op;
|
|
186
|
+
limit;
|
|
187
|
+
};
|
|
177
188
|
function maskPath(path) {
|
|
178
189
|
return path.split(/[?#]/)[0].replace(/\/(etsi|document)\/[^/?#\s]+/g, "/$1/\u2026");
|
|
179
190
|
}
|
|
@@ -191,6 +202,7 @@ var DeviceLinkError = class extends EidError {
|
|
|
191
202
|
|
|
192
203
|
// src/http.ts
|
|
193
204
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
205
|
+
var MAX_JSON_BYTES = 4 << 20;
|
|
194
206
|
var Http = class {
|
|
195
207
|
constructor(cfg) {
|
|
196
208
|
this.cfg = cfg;
|
|
@@ -206,14 +218,14 @@ var Http = class {
|
|
|
206
218
|
postMultipart(path, form, timeoutMs) {
|
|
207
219
|
return this.json("POST", path, form, void 0, timeoutMs);
|
|
208
220
|
}
|
|
209
|
-
/** GET — хариуг байтаар (ж: гарын үсэгтэй PDF). */
|
|
210
|
-
async getBytes(path, timeoutMs) {
|
|
221
|
+
/** GET — хариуг байтаар (ж: гарын үсэгтэй PDF), `maxBytes` хүртэл; хэтэрвэл {@link ResponseTooLargeError}. */
|
|
222
|
+
async getBytes(path, timeoutMs, maxBytes = 64 << 20) {
|
|
211
223
|
const res = await this.send("GET", path, void 0, void 0, timeoutMs);
|
|
212
|
-
return
|
|
224
|
+
return readLimited(res, maxBytes, `GET ${maskPath(path)}`);
|
|
213
225
|
}
|
|
214
226
|
async json(method, path, body, contentType, timeoutMs) {
|
|
215
227
|
const res = await this.send(method, path, body, contentType, timeoutMs);
|
|
216
|
-
const text = await res
|
|
228
|
+
const text = new TextDecoder().decode(await readLimited(res, MAX_JSON_BYTES, `${method} ${maskPath(path)}`));
|
|
217
229
|
return text ? JSON.parse(text) : {};
|
|
218
230
|
}
|
|
219
231
|
async send(method, path, body, contentType, timeoutMs) {
|
|
@@ -223,7 +235,8 @@ var Http = class {
|
|
|
223
235
|
method,
|
|
224
236
|
headers: {
|
|
225
237
|
Authorization: `Bearer ${this.cfg.apiSecret}`,
|
|
226
|
-
...contentType ? { "Content-Type": contentType } : {}
|
|
238
|
+
...contentType ? { "Content-Type": contentType } : {},
|
|
239
|
+
...this.cfg.language ? { "Accept-Language": this.cfg.language } : {}
|
|
227
240
|
},
|
|
228
241
|
body,
|
|
229
242
|
signal: AbortSignal.timeout(timeoutMs ?? this.cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS)
|
|
@@ -258,6 +271,34 @@ var Http = class {
|
|
|
258
271
|
throw new ApiError(res.status, text, code, { headers, retryAfterMs });
|
|
259
272
|
}
|
|
260
273
|
};
|
|
274
|
+
async function readLimited(res, limit, op) {
|
|
275
|
+
const declared = Number(res.headers.get("content-length") ?? NaN);
|
|
276
|
+
if (declared > limit) {
|
|
277
|
+
await res.body?.cancel().catch(() => void 0);
|
|
278
|
+
throw new ResponseTooLargeError(op, limit);
|
|
279
|
+
}
|
|
280
|
+
if (!res.body) return new Uint8Array(0);
|
|
281
|
+
const reader = res.body.getReader();
|
|
282
|
+
const chunks = [];
|
|
283
|
+
let total = 0;
|
|
284
|
+
for (; ; ) {
|
|
285
|
+
const { done, value } = await reader.read();
|
|
286
|
+
if (done) break;
|
|
287
|
+
total += value.byteLength;
|
|
288
|
+
if (total > limit) {
|
|
289
|
+
await reader.cancel().catch(() => void 0);
|
|
290
|
+
throw new ResponseTooLargeError(op, limit);
|
|
291
|
+
}
|
|
292
|
+
chunks.push(value);
|
|
293
|
+
}
|
|
294
|
+
const out = new Uint8Array(total);
|
|
295
|
+
let off = 0;
|
|
296
|
+
for (const c of chunks) {
|
|
297
|
+
out.set(c, off);
|
|
298
|
+
off += c.byteLength;
|
|
299
|
+
}
|
|
300
|
+
return out;
|
|
301
|
+
}
|
|
261
302
|
function errorBody(text) {
|
|
262
303
|
try {
|
|
263
304
|
const v = JSON.parse(text);
|
|
@@ -294,7 +335,10 @@ var RP_ROUTES = {
|
|
|
294
335
|
};
|
|
295
336
|
var RP_ROUTES_UNDISCOVERED = {
|
|
296
337
|
tokenAuthChallenge: { method: "POST", path: "/token/auth/challenge" },
|
|
297
|
-
tokenAuthVerify: { method: "POST", path: "/token/auth/verify" }
|
|
338
|
+
tokenAuthVerify: { method: "POST", path: "/token/auth/verify" },
|
|
339
|
+
pdfTokenPrepare: { method: "POST", path: "/pdf/token/prepare" },
|
|
340
|
+
pdfTokenFinalize: { method: "POST", path: "/pdf/token/{signingID}/finalize" },
|
|
341
|
+
pdfTokenDocument: { method: "GET", path: "/pdf/token/{signingID}/document" }
|
|
298
342
|
};
|
|
299
343
|
function routePath(route, ...args) {
|
|
300
344
|
let i = 0;
|
|
@@ -602,10 +646,12 @@ function parseOrg(raw) {
|
|
|
602
646
|
const o = asRecord(raw);
|
|
603
647
|
const etsi = str(o.orgEtsi);
|
|
604
648
|
if (!etsi) return null;
|
|
649
|
+
const roleLabel = str(o.roleLabel);
|
|
605
650
|
return {
|
|
606
651
|
orgEtsi: etsi,
|
|
607
652
|
orgName: str(o.orgName),
|
|
608
653
|
role: str(o.role),
|
|
654
|
+
...roleLabel ? { roleLabel } : {},
|
|
609
655
|
rightType: str(o.rightType)
|
|
610
656
|
};
|
|
611
657
|
}
|
|
@@ -642,6 +688,7 @@ var SessionApi = class {
|
|
|
642
688
|
|
|
643
689
|
// src/pdf.ts
|
|
644
690
|
var import_node_crypto2 = require("crypto");
|
|
691
|
+
var DEFAULT_PDF_MAX_BYTES = 64 << 20;
|
|
645
692
|
var DEFAULT_PDF_TIMEOUT_MS = 8e4;
|
|
646
693
|
function rec3(v) {
|
|
647
694
|
return v && typeof v === "object" ? v : {};
|
|
@@ -674,7 +721,7 @@ var PdfApi = class {
|
|
|
674
721
|
const form = new FormData();
|
|
675
722
|
form.append("request", new Blob([JSON.stringify(request)], { type: "application/json" }));
|
|
676
723
|
form.append("pdf", new Blob([input.pdf], { type: "application/pdf" }), input.fileName);
|
|
677
|
-
const r = rec3(await this.http.postMultipart(routePath(RP_ROUTES.pdfPrepare), form, this.
|
|
724
|
+
const r = rec3(await this.http.postMultipart(routePath(RP_ROUTES.pdfPrepare), form, this.timeout));
|
|
678
725
|
const receivedAt = Date.now();
|
|
679
726
|
const vc = rec3(r.vc).value;
|
|
680
727
|
const dl = rec3(r.deviceLink);
|
|
@@ -701,7 +748,75 @@ var PdfApi = class {
|
|
|
701
748
|
* дараа дахин татна (`retryable`).
|
|
702
749
|
*/
|
|
703
750
|
document(sessionId) {
|
|
704
|
-
return this.http.getBytes(routePath(RP_ROUTES.pdfDocument, sessionId), this.
|
|
751
|
+
return this.http.getBytes(routePath(RP_ROUTES.pdfDocument, sessionId), this.timeout, this.maxBytes);
|
|
752
|
+
}
|
|
753
|
+
get timeout() {
|
|
754
|
+
return this.defaults.timeoutMs ?? DEFAULT_PDF_TIMEOUT_MS;
|
|
755
|
+
}
|
|
756
|
+
get maxBytes() {
|
|
757
|
+
return this.defaults.maxBytes ?? DEFAULT_PDF_MAX_BYTES;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* USB токены PAdES (CA docs/PADES_SIGNING.md §16.5, TOKEN_CERT.md) — session / утас оролцохгүй. POST /pdf/token/prepare
|
|
761
|
+
* (multipart: `request` JSON + `pdf`), SIGN эрх. Дараа нь токеноор `hashToSign`-ийг CKM_ECDSA (prehashed, P-256)-аар
|
|
762
|
+
* зурж {@link tokenFinalize}. Түр алдаа: `ApiError` 429 PDF_PREPARE_BUSY / RATE_LIMITED, 503 TSA_UNAVAILABLE /
|
|
763
|
+
* LTV_UNAVAILABLE / STATE_UNAVAILABLE (`retryable`). Гэрчилгээ токенд холбогдоогүй / цуцлагдсан → 409
|
|
764
|
+
* TOKEN_CERT_INVALID. Зам нь CA-д бий ч `/.well-known/eid`-д хараахан алга (гэрээний тест WARN).
|
|
765
|
+
*/
|
|
766
|
+
async tokenPrepare(input) {
|
|
767
|
+
if (!input.pdf?.length || !input.certificate?.length || !input.signerEtsi?.trim() || !input.fileName?.trim()) {
|
|
768
|
+
throw new Error("eid: pdf token: pdf, certificate, signerEtsi, fileName \u0448\u0430\u0430\u0440\u0434\u043B\u0430\u0433\u0430\u0442\u0430\u0439");
|
|
769
|
+
}
|
|
770
|
+
const request = {
|
|
771
|
+
relyingPartyUUID: this.creds.rpUUID,
|
|
772
|
+
relyingPartyName: this.creds.rpName,
|
|
773
|
+
signer: { etsi: input.signerEtsi.trim() },
|
|
774
|
+
certificate: Buffer.from(input.certificate).toString("base64"),
|
|
775
|
+
fileName: input.fileName
|
|
776
|
+
};
|
|
777
|
+
if (input.docID?.trim()) request.docID = input.docID.trim();
|
|
778
|
+
if (input.onBehalfOf?.trim()) request.onBehalfOf = input.onBehalfOf.trim();
|
|
779
|
+
const form = new FormData();
|
|
780
|
+
form.append("request", new Blob([JSON.stringify(request)], { type: "application/json" }));
|
|
781
|
+
form.append("pdf", new Blob([input.pdf], { type: "application/pdf" }), input.fileName);
|
|
782
|
+
const raw = await this.http.postMultipart(routePath(RP_ROUTES_UNDISCOVERED.pdfTokenPrepare), form, this.timeout);
|
|
783
|
+
const r = rec3(raw);
|
|
784
|
+
const hashToSign = new Uint8Array(Buffer.from(String(r.hashToSign ?? ""), "base64"));
|
|
785
|
+
if (!r.signingID || hashToSign.length !== 32) {
|
|
786
|
+
throw new ValidationError("pdf token prepare: signingID / hashToSign (32 \u0431\u0430\u0439\u0442) \u0431\u0443\u0440\u0443\u0443");
|
|
787
|
+
}
|
|
788
|
+
return {
|
|
789
|
+
signingId: String(r.signingID),
|
|
790
|
+
docId: String(r.docID ?? ""),
|
|
791
|
+
hashToSign,
|
|
792
|
+
hashAlgorithm: String(r.hashAlgorithm ?? ""),
|
|
793
|
+
signatureAlgorithm: String(r.signatureAlgorithm ?? ""),
|
|
794
|
+
signatureFormat: String(r.signatureFormat ?? ""),
|
|
795
|
+
expiresAt: String(r.expiresAt ?? ""),
|
|
796
|
+
raw
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* POST /pdf/token/{signingID}/finalize `{signature: base64 түүхий r||s}` — `signature` 64 байт (P-256 r||s, DER БИШ).
|
|
801
|
+
* Амжвал READY баримтын блок (`outSha256` — {@link tokenDocument}-оор татсан файлтай тулга). READY-ээс хойш идэмпотент.
|
|
802
|
+
* Алдаа: 400 SIGNATURE_INVALID (3 удаа → FAILED), 409 DOCUMENT_FAILED, 410 DOCUMENT_EXPIRED, 503 DOCUMENT_PENDING /
|
|
803
|
+
* TSA_UNAVAILABLE / LTV_UNAVAILABLE — ижил гарын үсгийг `retryAfterMs`-ийн дараа дахин илгээнэ.
|
|
804
|
+
*/
|
|
805
|
+
async tokenFinalize(signingId, signature) {
|
|
806
|
+
if (signature?.length !== 64) throw new Error("eid: pdf token: signature \u043D\u044C \u0442\u04AF\u04AF\u0445\u0438\u0439 r||s 64 \u0431\u0430\u0439\u0442 \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439 (P-256, DER \u0431\u0438\u0448)");
|
|
807
|
+
const r = await this.http.post(
|
|
808
|
+
routePath(RP_ROUTES_UNDISCOVERED.pdfTokenFinalize, signingId),
|
|
809
|
+
{ signature: Buffer.from(signature).toString("base64") },
|
|
810
|
+
this.timeout
|
|
811
|
+
);
|
|
812
|
+
return r;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* GET /pdf/token/{signingID}/document — гарын үсэгтэй PDF (зөвхөн үүсгэсэн RP, expiresAt хүртэл), `pdfMaxBytes`
|
|
816
|
+
* хүртэл. SHA-256-ийг {@link tokenFinalize}-ийн `outSha256`-тай заавал тулга.
|
|
817
|
+
*/
|
|
818
|
+
tokenDocument(signingId) {
|
|
819
|
+
return this.http.getBytes(routePath(RP_ROUTES_UNDISCOVERED.pdfTokenDocument, signingId), this.timeout, this.maxBytes);
|
|
705
820
|
}
|
|
706
821
|
/**
|
|
707
822
|
* {@link document} + тулгалт: татсан байтын SHA-256 нь session poll-ийн `pdf.outSha256`-тай тэнцүү байх ёстой.
|
|
@@ -735,7 +850,7 @@ var OrganizationApi = class {
|
|
|
735
850
|
async getRepresentations(personEtsi) {
|
|
736
851
|
const raw = await this.http.get(routePath(RP_ROUTES.orgRepresentations, personEtsi));
|
|
737
852
|
const list = Array.isArray(raw.representations) ? raw.representations : [];
|
|
738
|
-
return { personEtsi: String(raw.personEtsi ?? personEtsi), representations: list };
|
|
853
|
+
return { personEtsi: String(raw.personEtsi ?? personEtsi), representations: list, raw };
|
|
739
854
|
}
|
|
740
855
|
};
|
|
741
856
|
|
|
@@ -887,6 +1002,10 @@ function parseSubject(cert) {
|
|
|
887
1002
|
return out;
|
|
888
1003
|
}
|
|
889
1004
|
function certExtension(der, oid) {
|
|
1005
|
+
return certExtensions(der).find((e) => e.oid === oid)?.value;
|
|
1006
|
+
}
|
|
1007
|
+
function certExtensions(der) {
|
|
1008
|
+
const out = [];
|
|
890
1009
|
const top = tlv(der, 0, der.length);
|
|
891
1010
|
const tbs = tlv(der, top.start, top.end);
|
|
892
1011
|
let f = tlv(der, tbs.start, tbs.end);
|
|
@@ -900,16 +1019,20 @@ function certExtension(der, oid) {
|
|
|
900
1019
|
const ext = tlv(der, ep, seq.end);
|
|
901
1020
|
const id = tlv(der, ext.start, ext.end);
|
|
902
1021
|
let v = tlv(der, id.end, ext.end);
|
|
903
|
-
|
|
1022
|
+
let critical = false;
|
|
1023
|
+
if (v.tag === 1) {
|
|
1024
|
+
critical = v.end > v.start && der[v.start] !== 0;
|
|
1025
|
+
v = tlv(der, v.end, ext.end);
|
|
1026
|
+
}
|
|
904
1027
|
if (v.tag !== 4) throw new ValidationError("extension: extnValue OCTET STRING \u0431\u0438\u0448");
|
|
905
|
-
|
|
1028
|
+
out.push({ oid: oidOf(der, id), critical, value: der.subarray(v.start, v.end) });
|
|
906
1029
|
ep = ext.end;
|
|
907
1030
|
}
|
|
908
|
-
return
|
|
1031
|
+
return out;
|
|
909
1032
|
}
|
|
910
1033
|
pos = t.end;
|
|
911
1034
|
}
|
|
912
|
-
return
|
|
1035
|
+
return out;
|
|
913
1036
|
}
|
|
914
1037
|
|
|
915
1038
|
// src/token.ts
|
|
@@ -1259,7 +1382,7 @@ var ResponseValidator = class {
|
|
|
1259
1382
|
);
|
|
1260
1383
|
}
|
|
1261
1384
|
} else {
|
|
1262
|
-
this.verifyChain(leaf);
|
|
1385
|
+
this.verifyChain(leaf, protocol === "ACSP_V2" ? EKU_CLIENT_AUTH : EKU_EMAIL_PROTECTION);
|
|
1263
1386
|
}
|
|
1264
1387
|
this.checkIssuer(leaf);
|
|
1265
1388
|
return leaf;
|
|
@@ -1303,21 +1426,40 @@ var ResponseValidator = class {
|
|
|
1303
1426
|
const need = rank[this.requiredLevel] ?? 2;
|
|
1304
1427
|
if (got < need) throw new ValidationError(`\u0413\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 \u0442\u04AF\u0432\u0448\u0438\u043D \u0445\u04AF\u0440\u044D\u043B\u0446\u044D\u0445\u0433\u04AF\u0439: ${level} < ${this.requiredLevel}`);
|
|
1305
1428
|
}
|
|
1306
|
-
/**
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1429
|
+
/**
|
|
1430
|
+
* RFC 5280 замын шалгалт (Go SDK-ийн `x509.Certificate.Verify`-тэй ижил дүрэм): leaf-ээс trust anchor хүртэлх
|
|
1431
|
+
* замыг intermediates/anchors-оос (backtracking-тай) угсарна. Issuer бүр: subject = child.issuer, AKI/SKI таарах,
|
|
1432
|
+
* гарын үсэг, CA (basicConstraints CA:TRUE), KeyUsage тавьсан бол keyCertSign, **pathLenConstraint** (доорх
|
|
1433
|
+
* завсрын CA-ийн тоо), хүчинтэй хугацаа, EKU тавьсан бол `usage` / anyExtendedKeyUsage агуулах. Leaf болон CA
|
|
1434
|
+
* бүрийн үл таних **critical extension** → татгалзана. **Name constraints**-ийг SDK үнэлдэггүй — гинжинд байвал
|
|
1435
|
+
* fail-closed (CA-ийн бодит гинж 01–04-т алга). Цаг = now, leaf-ийн хүчинтэй хугацаанд хавчсан (`clockSkewMs`-ийн
|
|
1436
|
+
* хүрээнд; leaf-ийн хугацааг checkValidity шалгасан). certificatePolicies шалгахгүй (Go-той ижил).
|
|
1437
|
+
*/
|
|
1438
|
+
verifyChain(leaf, usage) {
|
|
1439
|
+
const now = Math.min(Math.max(Date.now(), Date.parse(leaf.validFrom)), Date.parse(leaf.validTo));
|
|
1440
|
+
const leafReason = criticalReason(leaf) ?? ekuReason(leaf, usage);
|
|
1441
|
+
if (leafReason) throw new ValidationError(`\u0413\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 \u0433\u0438\u043D\u0436 \u0445\u04AF\u0447\u0438\u043D\u0433\u04AF\u0439: ${leafReason}`);
|
|
1442
|
+
let reason;
|
|
1443
|
+
const extend = (cur, cas) => {
|
|
1444
|
+
if (cas.length >= 8) return false;
|
|
1445
|
+
for (const [cand, isAnchor] of [
|
|
1446
|
+
...this.anchors.map((c) => [c, true]),
|
|
1447
|
+
...this.intermediates.map((c) => [c, false])
|
|
1448
|
+
]) {
|
|
1449
|
+
if (cas.includes(cand) || !signedBy(cur, cand)) continue;
|
|
1450
|
+
const bad = caReason(cand, cas.length, now, usage);
|
|
1451
|
+
if (bad) {
|
|
1452
|
+
reason ??= bad;
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
if (isAnchor || extend(cand, [...cas, cand])) return true;
|
|
1313
1456
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
throw new ValidationError("\u0413\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 \u0438\u0442\u0433\u044D\u043B\u0446\u043B\u0438\u0439\u043D \u0433\u0438\u043D\u0436 trust anchor (Root CA) \u0445\u04AF\u0440\u0441\u044D\u043D\u0433\u04AF\u0439");
|
|
1457
|
+
return false;
|
|
1458
|
+
};
|
|
1459
|
+
if (extend(leaf, [])) return;
|
|
1460
|
+
throw new ValidationError(
|
|
1461
|
+
reason ? `\u0413\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 \u0433\u0438\u043D\u0436 \u0445\u04AF\u0447\u0438\u043D\u0433\u04AF\u0439: ${reason}` : "\u0413\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 \u0438\u0442\u0433\u044D\u043B\u0446\u043B\u0438\u0439\u043D \u0433\u0438\u043D\u0436 trust anchor (Root CA) \u0445\u04AF\u0440\u0441\u044D\u043D\u0433\u04AF\u0439"
|
|
1462
|
+
);
|
|
1321
1463
|
}
|
|
1322
1464
|
/** leaf-ийн шууд issuer-ийг trust pool-оос буцаана (revocation шалгагчид issuer хэрэгтэй). */
|
|
1323
1465
|
findIssuer(leaf) {
|
|
@@ -1528,6 +1670,79 @@ function authorityKeyId(cert) {
|
|
|
1528
1670
|
function isCa(cert) {
|
|
1529
1671
|
return cert.ca === true;
|
|
1530
1672
|
}
|
|
1673
|
+
var EKU_ANY = "2.5.29.37.0";
|
|
1674
|
+
var EKU_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2";
|
|
1675
|
+
var EKU_EMAIL_PROTECTION = "1.3.6.1.5.5.7.3.4";
|
|
1676
|
+
var OID_NAME_CONSTRAINTS = "2.5.29.30";
|
|
1677
|
+
var HANDLED_CRITICAL = /* @__PURE__ */ new Set([
|
|
1678
|
+
"2.5.29.14",
|
|
1679
|
+
// subjectKeyIdentifier
|
|
1680
|
+
"2.5.29.15",
|
|
1681
|
+
// keyUsage
|
|
1682
|
+
"2.5.29.17",
|
|
1683
|
+
// subjectAltName
|
|
1684
|
+
"2.5.29.19",
|
|
1685
|
+
// basicConstraints
|
|
1686
|
+
"2.5.29.30",
|
|
1687
|
+
// nameConstraints (CA-д — caReason fail-closed)
|
|
1688
|
+
"2.5.29.31",
|
|
1689
|
+
// cRLDistributionPoints
|
|
1690
|
+
"2.5.29.32",
|
|
1691
|
+
// certificatePolicies
|
|
1692
|
+
"2.5.29.35",
|
|
1693
|
+
// authorityKeyIdentifier
|
|
1694
|
+
"2.5.29.37",
|
|
1695
|
+
// extKeyUsage
|
|
1696
|
+
"1.3.6.1.5.5.7.1.1"
|
|
1697
|
+
// authorityInfoAccess
|
|
1698
|
+
]);
|
|
1699
|
+
function signedBy(child, cand) {
|
|
1700
|
+
if (child.issuer !== cand.subject) return false;
|
|
1701
|
+
const aki = authorityKeyId(child);
|
|
1702
|
+
const ski = subjectKeyId(cand);
|
|
1703
|
+
if (aki && ski && aki !== ski) return false;
|
|
1704
|
+
try {
|
|
1705
|
+
return child.verify(cand.publicKey);
|
|
1706
|
+
} catch {
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
function criticalReason(cert) {
|
|
1711
|
+
return certExtensions(cert.raw).some((e) => e.critical && !HANDLED_CRITICAL.has(e.oid)) ? "\u04AF\u043B \u0442\u0430\u043D\u0438\u0445 critical extension" : void 0;
|
|
1712
|
+
}
|
|
1713
|
+
function ekuReason(cert, usage) {
|
|
1714
|
+
const eku = extKeyUsage(cert);
|
|
1715
|
+
return eku.length && !eku.includes(usage) && !eku.includes(EKU_ANY) ? "\u0433\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 ExtKeyUsage \u044D\u043D\u044D \u04AF\u0439\u043B\u0434\u044D\u043B\u0434 \u0442\u043E\u0445\u0438\u0440\u043E\u0445\u0433\u04AF\u0439 (\u0433\u0438\u043D\u0436\u0438\u0439\u043D EKU)" : void 0;
|
|
1716
|
+
}
|
|
1717
|
+
function caReason(ca, below, now, usage) {
|
|
1718
|
+
if (!isCa(ca)) return "\u0437\u0430\u0432\u0441\u0440\u044B\u043D \u0433\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D CA \u0431\u0438\u0448 \u044D\u0441\u0432\u044D\u043B keyCertSign \u044D\u0440\u0445\u0433\u04AF\u0439";
|
|
1719
|
+
if (certExtension(ca.raw, "2.5.29.15") && !(keyUsageBits(ca) & 4)) return "CA-\u0438\u0439\u043D KeyUsage-\u0434 keyCertSign \u0430\u043B\u0433\u0430";
|
|
1720
|
+
const from = Date.parse(ca.validFrom);
|
|
1721
|
+
const to = Date.parse(ca.validTo);
|
|
1722
|
+
if (Number.isNaN(from) || Number.isNaN(to) || now < from || now > to) {
|
|
1723
|
+
return "\u0433\u0438\u043D\u0436\u0438\u0439\u043D \u0433\u044D\u0440\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0438\u0439 \u0445\u0443\u0433\u0430\u0446\u0430\u0430 \u0434\u0443\u0443\u0441\u0441\u0430\u043D \u044D\u0441\u0432\u044D\u043B \u0445\u04AF\u0447\u0438\u043D\u0442\u044D\u0439 \u0431\u043E\u043B\u043E\u043E\u0433\u04AF\u0439";
|
|
1724
|
+
}
|
|
1725
|
+
const pathLen = basicConstraintsPathLen(ca);
|
|
1726
|
+
if (pathLen !== void 0 && below > pathLen) return "pathLenConstraint \u0437\u04E9\u0440\u0447\u0441\u04E9\u043D (\u0437\u0430\u0432\u0441\u0440\u044B\u043D CA \u0445\u044D\u0442 \u043E\u043B\u043E\u043D)";
|
|
1727
|
+
if (certExtension(ca.raw, OID_NAME_CONSTRAINTS)) return "CA-\u0434 name constraints \u0431\u0430\u0439\u043D\u0430 (SDK \u04AF\u043D\u044D\u043B\u0434\u044D\u0433\u0433\u04AF\u0439 \u2014 fail-closed)";
|
|
1728
|
+
return criticalReason(ca) ?? ekuReason(ca, usage);
|
|
1729
|
+
}
|
|
1730
|
+
function basicConstraintsPathLen(cert) {
|
|
1731
|
+
const v = certExtension(cert.raw, "2.5.29.19");
|
|
1732
|
+
if (!v) return void 0;
|
|
1733
|
+
const seq = tlv(v, 0, v.length);
|
|
1734
|
+
for (let p = seq.start; p < seq.end; ) {
|
|
1735
|
+
const t = tlv(v, p, seq.end);
|
|
1736
|
+
if (t.tag === 2) {
|
|
1737
|
+
if (t.end - t.start > 4 || (v[t.start] & 128) !== 0) throw new ValidationError("basicConstraints: pathLen \u0431\u0443\u0440\u0443\u0443");
|
|
1738
|
+
let n = 0;
|
|
1739
|
+
for (let i = t.start; i < t.end; i++) n = n * 256 + v[i];
|
|
1740
|
+
return n;
|
|
1741
|
+
}
|
|
1742
|
+
p = t.end;
|
|
1743
|
+
}
|
|
1744
|
+
return void 0;
|
|
1745
|
+
}
|
|
1531
1746
|
|
|
1532
1747
|
// src/client.ts
|
|
1533
1748
|
var DEFAULT_BASE_URL = "https://rp.eidmongolia.mn";
|
|
@@ -1564,12 +1779,17 @@ var EidClient = class {
|
|
|
1564
1779
|
apiSecret: cfg.credentials.apiSecret,
|
|
1565
1780
|
timeoutMs: cfg.timeoutMs,
|
|
1566
1781
|
dispatcher: cfg.dispatcher,
|
|
1567
|
-
fetchImpl: cfg.fetchImpl
|
|
1782
|
+
fetchImpl: cfg.fetchImpl,
|
|
1783
|
+
language: cfg.language?.trim() || void 0
|
|
1568
1784
|
});
|
|
1569
1785
|
const level = cfg.defaultCertificateLevel ?? "QUALIFIED";
|
|
1570
1786
|
this.auth = new AuthApi(http, cfg.credentials, { certificateLevel: level });
|
|
1571
1787
|
this.sign = new SignApi(http, cfg.credentials, { certificateLevel: level });
|
|
1572
|
-
this.pdf = new PdfApi(http, cfg.credentials, {
|
|
1788
|
+
this.pdf = new PdfApi(http, cfg.credentials, {
|
|
1789
|
+
certificateLevel: level,
|
|
1790
|
+
timeoutMs: cfg.pdfTimeoutMs ?? DEFAULT_PDF_TIMEOUT_MS,
|
|
1791
|
+
maxBytes: cfg.pdfMaxBytes && cfg.pdfMaxBytes > 0 ? cfg.pdfMaxBytes : DEFAULT_PDF_MAX_BYTES
|
|
1792
|
+
});
|
|
1573
1793
|
this.organization = new OrganizationApi(http);
|
|
1574
1794
|
this.person = new PersonApi(http);
|
|
1575
1795
|
this.token = new TokenApi(http, cfg.credentials);
|
|
@@ -1973,6 +2193,7 @@ function callbackParams(input) {
|
|
|
1973
2193
|
AuthenticationError,
|
|
1974
2194
|
CITIZEN_ISSUING_CA_SKI,
|
|
1975
2195
|
DEFAULT_BASE_URL,
|
|
2196
|
+
DEFAULT_PDF_MAX_BYTES,
|
|
1976
2197
|
DEFAULT_PDF_TIMEOUT_MS,
|
|
1977
2198
|
DeviceLinkError,
|
|
1978
2199
|
EID_ACR_ADVANCED,
|
|
@@ -1990,6 +2211,7 @@ function callbackParams(input) {
|
|
|
1990
2211
|
PdfApi,
|
|
1991
2212
|
PersonApi,
|
|
1992
2213
|
RETRYABLE_ERROR_CODES,
|
|
2214
|
+
ResponseTooLargeError,
|
|
1993
2215
|
ResponseValidator,
|
|
1994
2216
|
SessionApi,
|
|
1995
2217
|
SessionFailedError,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RpCredentials, C as CertificateLevel, I as Interaction, S as SignatureAlgorithm, H as HashAlgorithm, N as NotificationSession, D as DeviceLinkSession, a as SessionResult, P as PersonBlock, b as PdfSessionBlock, c as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-
|
|
2
|
-
export { d as ApiError, e as AuthenticationError, f as DeviceLinkError, g as DeviceLinkInput, h as EndResult, i as ForbiddenError, j as HttpErrorInit, k as NavigatorLike, l as NetworkError, O as ON_BEHALF_ERROR_CODES, m as OnBehalfErrorCode, n as OpenOrShowQROptions, o as OrgResult, p as PdfDocumentStatus, q as PdfSigner, r as RETRYABLE_ERROR_CODES, s as Representation, t as
|
|
1
|
+
import { R as RpCredentials, C as CertificateLevel, I as Interaction, S as SignatureAlgorithm, H as HashAlgorithm, N as NotificationSession, D as DeviceLinkSession, a as SessionResult, P as PersonBlock, b as PdfSessionBlock, c as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-B_xuB7Rt.cjs';
|
|
2
|
+
export { d as ApiError, e as AuthenticationError, f as DeviceLinkError, g as DeviceLinkInput, h as EndResult, i as ForbiddenError, j as HttpErrorInit, k as NavigatorLike, l as NetworkError, O as ON_BEHALF_ERROR_CODES, m as OnBehalfErrorCode, n as OpenOrShowQROptions, o as OrgResult, p as PdfDocumentStatus, q as PdfSigner, r as RETRYABLE_ERROR_CODES, s as Representation, t as ResponseTooLargeError, u as RetryableErrorCode, v as SessionFailedError, w as SessionState, x as SignatureAlgorithmParameters, y as SignatureProtocol, T as TokenCertSessionBlock, z as TokenCertStatus, V as ValidationError, B as deviceLink, G as isMobileUserAgent, J as openOrShowQR, K as parseRetryAfter } from './browser-B_xuB7Rt.cjs';
|
|
3
3
|
import { X509Certificate, KeyObject } from 'node:crypto';
|
|
4
4
|
|
|
5
5
|
interface HttpConfig {
|
|
@@ -17,6 +17,8 @@ interface HttpConfig {
|
|
|
17
17
|
dispatcher?: unknown;
|
|
18
18
|
/** Тест/custom орчинд fetch-ийг орлуулах (default — global fetch). */
|
|
19
19
|
fetchImpl?: typeof fetch;
|
|
20
|
+
/** `Accept-Language` header-ийн утга (ж: "en"); хоосон бол илгээхгүй. */
|
|
21
|
+
language?: string;
|
|
20
22
|
}
|
|
21
23
|
declare class Http {
|
|
22
24
|
private readonly cfg;
|
|
@@ -25,8 +27,8 @@ declare class Http {
|
|
|
25
27
|
get(path: string, timeoutMs?: number): Promise<unknown>;
|
|
26
28
|
/** multipart/form-data POST (Content-Type-ийг boundary-тай нь fetch тавина). JSON хариу. */
|
|
27
29
|
postMultipart(path: string, form: FormData, timeoutMs?: number): Promise<unknown>;
|
|
28
|
-
/** GET — хариуг байтаар (ж: гарын үсэгтэй PDF). */
|
|
29
|
-
getBytes(path: string, timeoutMs?: number): Promise<Uint8Array>;
|
|
30
|
+
/** GET — хариуг байтаар (ж: гарын үсэгтэй PDF), `maxBytes` хүртэл; хэтэрвэл {@link ResponseTooLargeError}. */
|
|
31
|
+
getBytes(path: string, timeoutMs?: number, maxBytes?: number): Promise<Uint8Array>;
|
|
30
32
|
private json;
|
|
31
33
|
private send;
|
|
32
34
|
}
|
|
@@ -153,7 +155,11 @@ interface PdfDefaults {
|
|
|
153
155
|
certificateLevel: CertificateLevel;
|
|
154
156
|
/** prepare / document дуудлагын хугацаа (мс); анхдагч {@link DEFAULT_PDF_TIMEOUT_MS}. */
|
|
155
157
|
timeoutMs?: number;
|
|
158
|
+
/** document / tokenDocument-ийн санах ойд унших дээд хэмжээ (байт); анхдагч {@link DEFAULT_PDF_MAX_BYTES}. */
|
|
159
|
+
maxBytes?: number;
|
|
156
160
|
}
|
|
161
|
+
/** Гарын үсэгтэй PDF татахад санах ойд уншиж болох анхдагч дээд хэмжээ (64 MiB) — `ClientConfig.pdfMaxBytes`. */
|
|
162
|
+
declare const DEFAULT_PDF_MAX_BYTES: number;
|
|
157
163
|
/**
|
|
158
164
|
* PAdES prepare / баримт татах нэг дуудлагын анхдагч хугацаа (мс). CA prepare нь ≤ 10 MiB уншиж, өмнөх гарын үсэг +
|
|
159
165
|
* LTV өгөгдөл шалгаад push эхлүүлдэг; баримт татахад угсралтыг ≤ 30с хүлээдэг (PADES_SIGNING §3.4). 80с нь хоёуланд
|
|
@@ -209,6 +215,35 @@ interface PdfPrepareSession {
|
|
|
209
215
|
/** SDK хариу хүлээн авсан мөч (ms epoch) — QR-ийн `receivedAt` ({@link buildDeviceLink}). */
|
|
210
216
|
receivedAt: number;
|
|
211
217
|
}
|
|
218
|
+
/** USB токены PAdES — POST /pdf/token/prepare-ийн оролт. */
|
|
219
|
+
interface PdfTokenPrepareInput {
|
|
220
|
+
/** Эх PDF (≤ 10 223 616 байт). */
|
|
221
|
+
pdf: Uint8Array;
|
|
222
|
+
/** Баримтын нэр (≤ 120 тэмдэгт, заавал). */
|
|
223
|
+
fileName: string;
|
|
224
|
+
/** Иргэний ETSI (`PNOMN-…`) — токены гэрчилгээний SERIALNUMBER-тэй таарна. */
|
|
225
|
+
signerEtsi: string;
|
|
226
|
+
/** Токены SIGN гэрчилгээ (DER): eID Mongolia Issuing CA-аас, ACTIVE токенд холбогдсон. */
|
|
227
|
+
certificate: Uint8Array;
|
|
228
|
+
/** Олон гарын үсэгтэй баримтын docID (заавал биш, UUID). */
|
|
229
|
+
docID?: string;
|
|
230
|
+
/** Байгууллагын токенд ЗААВАЛ тухайн байгууллага (`NTRMN-…`); хувийн токенд хоосон. Зөрвөл 403 TOKEN_ORG_MISMATCH. */
|
|
231
|
+
onBehalfOf?: string;
|
|
232
|
+
}
|
|
233
|
+
/** POST /pdf/token/prepare-ийн хариу. */
|
|
234
|
+
interface PdfTokenPrepareSession {
|
|
235
|
+
signingId: string;
|
|
236
|
+
docId: string;
|
|
237
|
+
/** Токеноор зурах 32 байт (SHA-256 DTBS): CKM_ECDSA (prehashed) → түүхий r||s (64 байт). */
|
|
238
|
+
hashToSign: Uint8Array;
|
|
239
|
+
hashAlgorithm: string;
|
|
240
|
+
signatureAlgorithm: string;
|
|
241
|
+
/** "RAW_RS". */
|
|
242
|
+
signatureFormat: string;
|
|
243
|
+
/** tokenFinalize-ийн эцсийн хугацаа (prepare-ээс 10 мин), ISO-8601. */
|
|
244
|
+
expiresAt: string;
|
|
245
|
+
raw: unknown;
|
|
246
|
+
}
|
|
212
247
|
declare class PdfApi {
|
|
213
248
|
private readonly http;
|
|
214
249
|
private readonly creds;
|
|
@@ -226,6 +261,28 @@ declare class PdfApi {
|
|
|
226
261
|
* дараа дахин татна (`retryable`).
|
|
227
262
|
*/
|
|
228
263
|
document(sessionId: string): Promise<Uint8Array>;
|
|
264
|
+
private get timeout();
|
|
265
|
+
private get maxBytes();
|
|
266
|
+
/**
|
|
267
|
+
* USB токены PAdES (CA docs/PADES_SIGNING.md §16.5, TOKEN_CERT.md) — session / утас оролцохгүй. POST /pdf/token/prepare
|
|
268
|
+
* (multipart: `request` JSON + `pdf`), SIGN эрх. Дараа нь токеноор `hashToSign`-ийг CKM_ECDSA (prehashed, P-256)-аар
|
|
269
|
+
* зурж {@link tokenFinalize}. Түр алдаа: `ApiError` 429 PDF_PREPARE_BUSY / RATE_LIMITED, 503 TSA_UNAVAILABLE /
|
|
270
|
+
* LTV_UNAVAILABLE / STATE_UNAVAILABLE (`retryable`). Гэрчилгээ токенд холбогдоогүй / цуцлагдсан → 409
|
|
271
|
+
* TOKEN_CERT_INVALID. Зам нь CA-д бий ч `/.well-known/eid`-д хараахан алга (гэрээний тест WARN).
|
|
272
|
+
*/
|
|
273
|
+
tokenPrepare(input: PdfTokenPrepareInput): Promise<PdfTokenPrepareSession>;
|
|
274
|
+
/**
|
|
275
|
+
* POST /pdf/token/{signingID}/finalize `{signature: base64 түүхий r||s}` — `signature` 64 байт (P-256 r||s, DER БИШ).
|
|
276
|
+
* Амжвал READY баримтын блок (`outSha256` — {@link tokenDocument}-оор татсан файлтай тулга). READY-ээс хойш идэмпотент.
|
|
277
|
+
* Алдаа: 400 SIGNATURE_INVALID (3 удаа → FAILED), 409 DOCUMENT_FAILED, 410 DOCUMENT_EXPIRED, 503 DOCUMENT_PENDING /
|
|
278
|
+
* TSA_UNAVAILABLE / LTV_UNAVAILABLE — ижил гарын үсгийг `retryAfterMs`-ийн дараа дахин илгээнэ.
|
|
279
|
+
*/
|
|
280
|
+
tokenFinalize(signingId: string, signature: Uint8Array): Promise<PdfSessionBlock>;
|
|
281
|
+
/**
|
|
282
|
+
* GET /pdf/token/{signingID}/document — гарын үсэгтэй PDF (зөвхөн үүсгэсэн RP, expiresAt хүртэл), `pdfMaxBytes`
|
|
283
|
+
* хүртэл. SHA-256-ийг {@link tokenFinalize}-ийн `outSha256`-тай заавал тулга.
|
|
284
|
+
*/
|
|
285
|
+
tokenDocument(signingId: string): Promise<Uint8Array>;
|
|
229
286
|
/**
|
|
230
287
|
* {@link document} + тулгалт: татсан байтын SHA-256 нь session poll-ийн `pdf.outSha256`-тай тэнцүү байх ёстой.
|
|
231
288
|
* `expected` — poll-ийн `result.pdf` блок (`documentStatus` READY + `outSha256` заавал) эсвэл SHA-256 hex.
|
|
@@ -696,7 +753,15 @@ declare class ResponseValidator {
|
|
|
696
753
|
private checkIssuer;
|
|
697
754
|
private checkValidity;
|
|
698
755
|
private checkLevel;
|
|
699
|
-
/**
|
|
756
|
+
/**
|
|
757
|
+
* RFC 5280 замын шалгалт (Go SDK-ийн `x509.Certificate.Verify`-тэй ижил дүрэм): leaf-ээс trust anchor хүртэлх
|
|
758
|
+
* замыг intermediates/anchors-оос (backtracking-тай) угсарна. Issuer бүр: subject = child.issuer, AKI/SKI таарах,
|
|
759
|
+
* гарын үсэг, CA (basicConstraints CA:TRUE), KeyUsage тавьсан бол keyCertSign, **pathLenConstraint** (доорх
|
|
760
|
+
* завсрын CA-ийн тоо), хүчинтэй хугацаа, EKU тавьсан бол `usage` / anyExtendedKeyUsage агуулах. Leaf болон CA
|
|
761
|
+
* бүрийн үл таних **critical extension** → татгалзана. **Name constraints**-ийг SDK үнэлдэггүй — гинжинд байвал
|
|
762
|
+
* fail-closed (CA-ийн бодит гинж 01–04-т алга). Цаг = now, leaf-ийн хүчинтэй хугацаанд хавчсан (`clockSkewMs`-ийн
|
|
763
|
+
* хүрээнд; leaf-ийн хугацааг checkValidity шалгасан). certificatePolicies шалгахгүй (Go-той ижил).
|
|
764
|
+
*/
|
|
700
765
|
private verifyChain;
|
|
701
766
|
/** leaf-ийн шууд issuer-ийг trust pool-оос буцаана (revocation шалгагчид issuer хэрэгтэй). */
|
|
702
767
|
private findIssuer;
|
|
@@ -734,10 +799,20 @@ interface ClientConfig {
|
|
|
734
799
|
timeoutMs?: number;
|
|
735
800
|
/** PAdES prepare / баримт татах дуудлагын хугацаа (мс). Анхдагч 80000 ({@link DEFAULT_PDF_TIMEOUT_MS}). */
|
|
736
801
|
pdfTimeoutMs?: number;
|
|
802
|
+
/**
|
|
803
|
+
* `pdf.document` / `pdf.tokenDocument`-ийн санах ойд унших дээд хэмжээ (байт). Анхдагч 64 MiB
|
|
804
|
+
* ({@link DEFAULT_PDF_MAX_BYTES}); хэтэрвэл `ResponseTooLargeError`.
|
|
805
|
+
*/
|
|
806
|
+
pdfMaxBytes?: number;
|
|
737
807
|
/** undici Dispatcher (mTLS client cert). */
|
|
738
808
|
dispatcher?: unknown;
|
|
739
809
|
/** fetch орлуулагч (тест). */
|
|
740
810
|
fetchImpl?: typeof fetch;
|
|
811
|
+
/**
|
|
812
|
+
* Хүнд харуулах текстийн хэл (`roleLabel` г.м.) — дуудлага бүрд `Accept-Language` болж илгээгдэнэ (`"mn"` | `"en"`).
|
|
813
|
+
* Анхдагч: илгээхгүй (сервер mn).
|
|
814
|
+
*/
|
|
815
|
+
language?: string;
|
|
741
816
|
/** Trust anchor (Root CA) — validator-д. Production-д ЗААВАЛ. */
|
|
742
817
|
trust?: TrustConfig;
|
|
743
818
|
}
|
|
@@ -989,4 +1064,4 @@ declare class EidOidcClient {
|
|
|
989
1064
|
/** PKCE S256: `BASE64URL(SHA-256(ASCII(code_verifier)))` (RFC 7636 §4.2). */
|
|
990
1065
|
declare function pkceChallenge(codeVerifier: string): Promise<string>;
|
|
991
1066
|
|
|
992
|
-
export { AcspContext, type AcspV2Params, type ActivityCounts, type ActivityItem, type ActivityQuery, AuthApi, type AuthDefaults, type AuthOptions, type BuildDeviceLinkInput, CITIZEN_ISSUING_CA_SKI, type CertCounts, type CertSubject, CertificateLevel, type ClientConfig, type CreateAuthorizationOptions, DEFAULT_BASE_URL, DEFAULT_PDF_TIMEOUT_MS, DeviceLinkSession, type DeviceLinkSessionType, type DeviceLinkType, EID_ACR_ADVANCED, EID_ACR_QUALIFIED, EID_OIDC_ISSUER, type EidAuthorization, type EidCallbackChecks, type EidCallbackResult, EidClient, EidError, type EidIdTokenClaims, EidOidcClient, type EidOidcClientConfig, type EidOidcDiscovery, EidOidcError, type EidOidcErrorCode, FlowType, HashAlgorithm, Http, type HttpConfig, Interaction, NotificationSession, OrganizationApi, PdfApi, type PdfDefaults, type PdfPrepareInput, type PdfPrepareSession, PdfSessionBlock, type PdfSignerRef, type PersonActivity, PersonApi, PersonBlock, type PersonCertificate, type PersonCertificates, type PersonChild, type PersonChildren, type PersonDevice, type PersonDevices, type PersonSummary, type QrDeviceLinkTickerOptions, RepresentationsResponse, ResponseValidator, type RevocationChecker, type RevocationOutcome, type RevocationStatus, RpCredentials, SessionApi, SessionResult, SignApi, type SignDefaults, type SignOptions, SignatureAlgorithm, TokenApi, type TokenAuthChallenge, type TokenAuthResult, type TokenCertInput, type TokenCertItem, type TokenCertResult, type TokenCertStart, type TokenIdentity, type TokenLimit, type TokenOrganization, type TrustConfig, type ValidateAuthOptions, type ValidateSignOptions, type VerifiedIdentity, type VerifiedSignature, acspV2Digest, buildAcspV2Payload, buildDeviceLink, interactionsToBase64, parseSessionResult, parseSubject, personMatchesCertificate, pkceChallenge, qrDeviceLinkTicker, randomChallenge, resolveBaseUrl, sha256Base64, tokenAuthDigest, tokenLimitOf, userChallengeOf, verifyPayloadSignature, verifyPrehashedSignature, verifyTokenCertificates };
|
|
1067
|
+
export { AcspContext, type AcspV2Params, type ActivityCounts, type ActivityItem, type ActivityQuery, AuthApi, type AuthDefaults, type AuthOptions, type BuildDeviceLinkInput, CITIZEN_ISSUING_CA_SKI, type CertCounts, type CertSubject, CertificateLevel, type ClientConfig, type CreateAuthorizationOptions, DEFAULT_BASE_URL, DEFAULT_PDF_MAX_BYTES, DEFAULT_PDF_TIMEOUT_MS, DeviceLinkSession, type DeviceLinkSessionType, type DeviceLinkType, EID_ACR_ADVANCED, EID_ACR_QUALIFIED, EID_OIDC_ISSUER, type EidAuthorization, type EidCallbackChecks, type EidCallbackResult, EidClient, EidError, type EidIdTokenClaims, EidOidcClient, type EidOidcClientConfig, type EidOidcDiscovery, EidOidcError, type EidOidcErrorCode, FlowType, HashAlgorithm, Http, type HttpConfig, Interaction, NotificationSession, OrganizationApi, PdfApi, type PdfDefaults, type PdfPrepareInput, type PdfPrepareSession, PdfSessionBlock, type PdfSignerRef, type PdfTokenPrepareInput, type PdfTokenPrepareSession, type PersonActivity, PersonApi, PersonBlock, type PersonCertificate, type PersonCertificates, type PersonChild, type PersonChildren, type PersonDevice, type PersonDevices, type PersonSummary, type QrDeviceLinkTickerOptions, RepresentationsResponse, ResponseValidator, type RevocationChecker, type RevocationOutcome, type RevocationStatus, RpCredentials, SessionApi, SessionResult, SignApi, type SignDefaults, type SignOptions, SignatureAlgorithm, TokenApi, type TokenAuthChallenge, type TokenAuthResult, type TokenCertInput, type TokenCertItem, type TokenCertResult, type TokenCertStart, type TokenIdentity, type TokenLimit, type TokenOrganization, type TrustConfig, type ValidateAuthOptions, type ValidateSignOptions, type VerifiedIdentity, type VerifiedSignature, acspV2Digest, buildAcspV2Payload, buildDeviceLink, interactionsToBase64, parseSessionResult, parseSubject, personMatchesCertificate, pkceChallenge, qrDeviceLinkTicker, randomChallenge, resolveBaseUrl, sha256Base64, tokenAuthDigest, tokenLimitOf, userChallengeOf, verifyPayloadSignature, verifyPrehashedSignature, verifyTokenCertificates };
|