@gerege-systems/eid-mongolia-sdk 0.6.1 → 0.8.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 +136 -3
- package/dist/{browser-BU9ShPWO.d.cts → browser-Db82DlYN.d.cts} +80 -3
- package/dist/{browser-BU9ShPWO.d.ts → browser-Db82DlYN.d.ts} +80 -3
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/{chunk-Q5TQMCJC.js → chunk-NXDKQZIW.js} +18 -1
- package/dist/index.cjs +451 -10
- package/dist/index.d.cts +215 -4
- package/dist/index.d.ts +215 -4
- package/dist/index.js +427 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,94 @@ Node.js ≥ 22 (global `fetch`, `node:crypto`).
|
|
|
19
19
|
|
|
20
20
|
`POST https://ca.eidmongolia.mn/v3/rp-applications` (эсвэл [developer.eidmongolia.mn](https://developer.eidmongolia.mn)) —
|
|
21
21
|
оператор баталсны дараа **relyingPartyUUID** ба **API secret** (`rp_sk_…`) олгогдоно; secret **зөвхөн нэг удаа**
|
|
22
|
-
харагдана. Дэлгэрэнгүй: <https://developer.eidmongolia.mn/#
|
|
22
|
+
харагдана. Дэлгэрэнгүй: <https://developer.eidmongolia.mn/#registration>.
|
|
23
|
+
|
|
24
|
+
## 1a. «eID-ээр нэвтрэх» (OpenID Connect)
|
|
25
|
+
|
|
26
|
+
Хамгийн хялбар нэвтрэлт: таны вэбэд нэг товч, нэвтрэх хуудсыг (QR · утсан дээрх аппаар нээх · регистрээр
|
|
27
|
+
мэдэгдэл) eID сервер өөрөө харуулж, гарын үсэг ба гэрчилгээний гинжийг шалгаад танд стандарт OpenID Connect
|
|
28
|
+
(Authorization Code + PKCE `S256`) `id_token` өгнө — Google/Apple нэвтрэлттэй ижил. Утасны хөтчөөс дарахад
|
|
29
|
+
хуудасгүйгээр шууд eID апп нээгдэнэ. Гэрээ: <https://developer.eidmongolia.mn/#oidc>.
|
|
30
|
+
|
|
31
|
+
**Бүртгэл.** `client_id` = таны RP UUID (`relyingPartyUUID`), `client_secret` = RP API secret (`rp_sk_…`).
|
|
32
|
+
RP-д `AUTH` эрх, OIDC асаалттай, `redirect_uri` (https, ≤ 10) бүртгэлтэй байна — authorize/token-ий `redirect_uri`
|
|
33
|
+
бүртгэлтэйтэй **тэмдэгт бүрээрээ** таарах ёстой. Иргэний ETSI дугаар (`pnomn` claim) хэрэгтэй бол `PNOMN` эрх
|
|
34
|
+
хүсэж, `scope: "openid pnomn"`. Token endpoint-д RP-ийн IP allowlist мөрдөгдөнө; `requireMtls` RP OIDC ашиглахгүй.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { EidOidcClient, EidOidcError } from "@gerege-systems/eid-mongolia-sdk";
|
|
38
|
+
|
|
39
|
+
const oidc = new EidOidcClient({
|
|
40
|
+
clientId: process.env.EID_RP_UUID!,
|
|
41
|
+
clientSecret: process.env.EID_SECRET!, // rp_sk_… — зөвхөн backend
|
|
42
|
+
redirectUri: "https://bank.example.mn/auth/eid/callback",
|
|
43
|
+
// issuer анхдагч https://login.eidmongolia.mn, scope анхдагч "openid"
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const TX = "eid_oidc_tx";
|
|
47
|
+
const cookieOpts = { httpOnly: true, secure: true, sameSite: "lax", path: "/auth/eid", maxAge: 600_000 } as const;
|
|
48
|
+
|
|
49
|
+
// GET /auth/eid/login — товчны href
|
|
50
|
+
app.get("/auth/eid/login", async (_req, res) => {
|
|
51
|
+
const a = await oidc.createAuthorization(); // { url, state, nonce, codeVerifier }
|
|
52
|
+
res.cookie(TX, JSON.stringify({ state: a.state, nonce: a.nonce, codeVerifier: a.codeVerifier }), cookieOpts);
|
|
53
|
+
res.set("Cache-Control", "no-store").redirect(302, a.url);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// GET /auth/eid/callback?code&state (эсвэл ?error) — бүртгэлтэй redirect_uri
|
|
57
|
+
app.get("/auth/eid/callback", async (req, res) => {
|
|
58
|
+
const tx = JSON.parse(req.cookies[TX] ?? "null");
|
|
59
|
+
res.clearCookie(TX, { path: "/auth/eid" });
|
|
60
|
+
if (!tx) return res.redirect(303, "/login?error=state");
|
|
61
|
+
try {
|
|
62
|
+
const { claims } = await oidc.handleCallback(req.originalUrl, tx); // state → token → id_token (ES256)
|
|
63
|
+
const user = await users.findOrCreateBySub(claims.sub); // pairwise sub-аар таньна (нэрээр биш)
|
|
64
|
+
await startSession(res, user); // таны session-ийг шинээр үүсгэ (session fixation)
|
|
65
|
+
res.redirect(303, "/");
|
|
66
|
+
} catch (e) {
|
|
67
|
+
const code = e instanceof EidOidcError ? e.code : "server_error"; // access_denied → «дахин оролдоно уу»
|
|
68
|
+
res.redirect(303, `/login?error=${code}`);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Next.js App Router-д ижил: `app/auth/eid/login/route.ts` → `NextResponse.redirect(a.url, 302)` + `res.cookies.set(…)`;
|
|
74
|
+
callback → `oidc.handleCallback(request.nextUrl.searchParams, tx)` (зөвхөн query уншина — прокси ард host хамаагүй).
|
|
75
|
+
|
|
76
|
+
**Товч** — энгийн холбоос (`<a href>` эсвэл form GET). `fetch`/XHR/JS redirect биш: iOS Universal Link зөвхөн
|
|
77
|
+
хэрэглэгчийн tap-аас эхэлсэн redirect гинжид eID аппыг нээнэ.
|
|
78
|
+
|
|
79
|
+
```html
|
|
80
|
+
<a class="eid-login" href="/auth/eid/login">eID-ээр нэвтрэх</a>
|
|
81
|
+
<style>
|
|
82
|
+
.eid-login { display: inline-flex; align-items: center; justify-content: center; min-height: 44px;
|
|
83
|
+
padding: 0 1.25rem; border-radius: 8px; background: #0b3d91; color: #fff; font: 600 1rem/1 system-ui, sans-serif;
|
|
84
|
+
text-decoration: none; }
|
|
85
|
+
.eid-login:focus-visible { outline: 2px solid #0b3d91; outline-offset: 2px; }
|
|
86
|
+
</style>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`createAuthorization({ display: "page" })` — утсан дээр ч нэвтрэх хуудас (QR / push) харуулна (ж: таблет киоск).
|
|
90
|
+
|
|
91
|
+
**`id_token` claims** (`EidIdTokenClaims`): `sub` (pairwise — RP тус бүрд өөр, иргэнд тогтмол), `acr`
|
|
92
|
+
(`urn:eidmongolia:loa:qualified` | `…:advanced`), `auth_time`, `given_name` / `family_name` (латин, гэрчилгээнээс),
|
|
93
|
+
`given_name_mn` / `family_name_mn` (кирилл, байвал), `pnomn` (`pnomn` scope + эрхтэй үед). `id_token` 5 минут
|
|
94
|
+
хүчинтэй; access_token / refresh_token / userinfo байхгүй — нэвтрэлтийн дараа өөрийн session-оо хэрэглэнэ.
|
|
95
|
+
|
|
96
|
+
**Аюулгүй байдал.**
|
|
97
|
+
|
|
98
|
+
- `state`, `nonce`, `codeVerifier`-ийг **хөтчийн session-тэй** (httpOnly, Secure, SameSite=Lax cookie эсвэл server
|
|
99
|
+
session) холбож хадгална; `handleCallback` state-ийг timing-safe тулгаж, таарахгүй бол code-ийг солихгүй
|
|
100
|
+
(`state_mismatch`). Үүнгүйгээр «өөрийн бүртгэлд хохирогчийн eID-ийг холбуулах» (login CSRF) нээлттэй.
|
|
101
|
+
- `handleCallback` / `verifyIdToken` нь ES256 гарын үсэг (JWKS `kid`, cache 1 цаг, танихгүй `kid` → нэг удаа дахин
|
|
102
|
+
татна), `iss`, `aud` (= `clientId`; олон aud бол `azp`), `exp` / `iat` (±60 сек), `nonce`-ийг шалгана.
|
|
103
|
+
`EidOidcError` (`invalid_id_token`) гарвал **итгэхгүй**.
|
|
104
|
+
- Code нэг удаагийн, 60 секунд — callback-ийг дахин ачаалбал `invalid_grant`; хэрэглэгчийг дахин нэвтрүүлнэ.
|
|
105
|
+
- `error_description` (`EidOidcError.description`)-ийг логт бичиж болно, хэрэглэгчид шууд харуулахгүй.
|
|
106
|
+
- **Native апп (RFC 8252):** authorize-ийг системийн хөтчөөр нээнэ — iOS `ASWebAuthenticationSession`
|
|
107
|
+
(`prefersEphemeralWebBrowserSession = false`), Android Custom Tabs. **WebView хориотой.** `redirect_uri` = таны
|
|
108
|
+
https Universal Link / App Link (custom scheme дэмжихгүй). `state` / `nonce` / `codeVerifier` апп-ын санах ойд;
|
|
109
|
+
code-ийг таны backend `client_secret`-ээр солино (`client_secret`-ийг аппад хадгалахгүй).
|
|
23
110
|
|
|
24
111
|
## 2. Нэвтрэлт (push)
|
|
25
112
|
|
|
@@ -67,6 +154,51 @@ const sig = eid.validator.validateSign(result, digest); // digest-ийн эср
|
|
|
67
154
|
console.log(sig.signatureValueB64, sig.subject);
|
|
68
155
|
```
|
|
69
156
|
|
|
157
|
+
## 3a. Байгууллагын нэрийн өмнөөс гарын үсэг (onBehalfOf)
|
|
158
|
+
|
|
159
|
+
Иргэн **өөрийн PIN2 гэрчилгээгээр** зурна; тухайн мөчид байгууллагыг төлөөлөх эрхтэйг eID **өөрийн бүртгэлээр**
|
|
160
|
+
шалгана (Эстонийн загвар). Энэ нь **хувь хүний квалификацтай гарын үсэг** — байгууллагын гэрчилгээ, тамга (e-Seal) биш.
|
|
161
|
+
e-Seal нь зөвхөн хүнгүй, автомат системийн баримтад. Урьдчилсан нөхцөл: байгууллага eID-д `ACTIVE` (захирал
|
|
162
|
+
аппаараа ХУР-аар холбоно), зурагч нь `ADMIN` эсвэл PIN2-оор баталгаажуулсан `MANAGER`, RP-д `SIGN` эрх.
|
|
163
|
+
Дэлгэрэнгүй: [developer.eidmongolia.mn](https://developer.eidmongolia.mn/).
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { ForbiddenError, ApiError, ON_BEHALF_ERROR_CODES } from "@gerege-systems/eid-mongolia-sdk";
|
|
167
|
+
|
|
168
|
+
// 1. Иргэн сүүлийн 24 цагт танай RP-ээр нэвтэрсэн байх ёстой.
|
|
169
|
+
const { representations } = await eid.organization.getRepresentations("PNOMN-12345678");
|
|
170
|
+
// → [{ orgEtsi: "NTRMN-6235972", orgName: "Гэрэгэ Системс ХХК", role: "ceo", rightType: "ADMIN", … }]
|
|
171
|
+
|
|
172
|
+
// 2. PDF (PAdES, CA угсарна) — санал болгох урсгал.
|
|
173
|
+
try {
|
|
174
|
+
const s = await eid.pdf.prepare({
|
|
175
|
+
pdf: pdfBytes, fileName: "Гэрээ №12.pdf",
|
|
176
|
+
signer: { etsi: "PNOMN-12345678" }, flow: "notification",
|
|
177
|
+
onBehalfOf: "NTRMN-6235972",
|
|
178
|
+
});
|
|
179
|
+
showToUser(s.vc);
|
|
180
|
+
const r = await eid.session.waitForResult(s.sessionId);
|
|
181
|
+
// MUST: endResult OK, pdf.documentStatus READY, pdf.signer.onBehalfOf = хүссэн байгууллага,
|
|
182
|
+
// татсан файлын SHA-256 = pdf.outSha256, validation.indication "valid", ltv true.
|
|
183
|
+
if (r.pdf?.documentStatus !== "READY" || r.pdf.signer?.onBehalfOf !== "NTRMN-6235972") throw new Error("…");
|
|
184
|
+
const signed = await eid.pdf.document(s.sessionId);
|
|
185
|
+
console.log(r.pdf.signer.claimedRole); // "Гүйцэтгэх захирал, Гэрэгэ Системс ХХК (NTRMN-6235972)"
|
|
186
|
+
} catch (e) {
|
|
187
|
+
if ((e instanceof ForbiddenError || e instanceof ApiError) && e.code) {
|
|
188
|
+
// REPRESENTATION_DENIED | REPRESENTATION_PENDING | REPRESENTATION_EXPIRED | ORG_NOT_ACTIVE |
|
|
189
|
+
// SIGNER_UNIDENTIFIED (403) · ORG_NOT_FOUND (404) · REPRESENTATION_REVOKED (403, document татах үед)
|
|
190
|
+
}
|
|
191
|
+
throw e;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Raw digest гарын үсэгт ч мөн: eid.sign.digestByEtsi(id, digest, interactions, { onBehalfOf: "NTRMN-6235972" })
|
|
195
|
+
// — CMS/PDF-ийг та угсардаг тул мэдүүлсэн үүргийг (signer-attributes-v2) өөрөө нэмнэ.
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Олон талт гэрээ: А байгууллагын гаралтыг өөрчлөлтгүй Б-ийн `prepare`-д (`docID`, өөр `onBehalfOf`) илгээнэ.
|
|
199
|
+
Session-ий `onBehalfOf` блок (`role`/`rightType`) нь хариу угсрах үеийн бүртгэл; `pdf.signer.onBehalfOf`/`claimedRole`
|
|
200
|
+
нь баримтад бичигдсэн утга.
|
|
201
|
+
|
|
70
202
|
## 4. QR ба ижил төхөөрөмж — device link v3
|
|
71
203
|
|
|
72
204
|
Иргэн өөр төхөөрөмжийн дэлгэц дээрх **QR**-ийг утсаараа уншина, эсвэл RP-ийн сайт/аппыг eID апптай **ижил
|
|
@@ -172,11 +304,12 @@ OK ирж болзошгүй. Иймд `ResponseValidator`:
|
|
|
172
304
|
| Алдаа | Утга |
|
|
173
305
|
|---|---|
|
|
174
306
|
| `AuthenticationError` | 401 — API secret буруу/байхгүй |
|
|
175
|
-
| `ForbiddenError` | 403 — IP allowlist / mTLS
|
|
307
|
+
| `ForbiddenError` | 403 — IP allowlist / mTLS / RP-ийн эрх; onBehalfOf татгалзвал `.code` (`OnBehalfErrorCode`) |
|
|
176
308
|
| `SessionFailedError` | endResult ≠ OK (TIMEOUT, USER_REFUSED…) — `.endResult`-оор салга |
|
|
177
309
|
| `ValidationError` | cert chain/signature/level шалгалт бүтэлгүйтсэн |
|
|
178
|
-
| `ApiError` | бусад HTTP алдаа (`.status`, `.body`) |
|
|
310
|
+
| `ApiError` | бусад HTTP алдаа (`.status`, `.body`, серверийн `.code` — ж: 404 `ORG_NOT_FOUND`) |
|
|
179
311
|
| `NetworkError` | timeout/сүлжээ |
|
|
312
|
+
| `EidOidcError` | «eID-ээр нэвтрэх» (OIDC) — `.code`: `access_denied`, `login_required`, `state_mismatch`, `invalid_grant`, `invalid_id_token`, `server_error` … |
|
|
180
313
|
| `DeviceLinkError` | device-link холбоос угсрах боломжгүй (`deviceLinkBase` https биш, token/secret/lang хэлбэр, төрөлд хэрэгтэй талбар дутуу) |
|
|
181
314
|
|
|
182
315
|
## mTLS (eIDAS qualified орчин)
|
|
@@ -130,6 +130,61 @@ interface SessionResult {
|
|
|
130
130
|
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
131
131
|
*/
|
|
132
132
|
onBehalfOf: OrgResult | null;
|
|
133
|
+
/**
|
|
134
|
+
* PAdES (`POST /pdf/sign/prepare`) session-ий `pdf` блок — PDF урсгал биш бол null (талбар алга = хуучин SDK-аар
|
|
135
|
+
* угсарсан объект). {@link PdfSessionBlock}.
|
|
136
|
+
*/
|
|
137
|
+
pdf?: PdfSessionBlock | null;
|
|
138
|
+
}
|
|
139
|
+
/** PDF баримтын төлөв: PENDING → READY (эсвэл FAILED / EXPIRED). */
|
|
140
|
+
type PdfDocumentStatus = "PENDING" | "READY" | "FAILED" | "EXPIRED";
|
|
141
|
+
/** PAdES гаралтын гарын үсэг зурагч. */
|
|
142
|
+
interface PdfSigner {
|
|
143
|
+
etsi: string;
|
|
144
|
+
certSerial: string;
|
|
145
|
+
/** Байгууллагын нэрийн өмнөөс бол байгууллагын ETSI (`NTRMN-…`) — баримтад бичигдсэн утга. */
|
|
146
|
+
onBehalfOf?: string;
|
|
147
|
+
/** CMS signer-attributes-v2-д бичигдсэн мэдүүлсэн үүрэг: «<албан тушаал>, <нэр> (NTRMN-…)». */
|
|
148
|
+
claimedRole?: string;
|
|
149
|
+
}
|
|
150
|
+
/** GET /session/{id}-ийн `pdf` объект (PAdES, CA угсарна). */
|
|
151
|
+
interface PdfSessionBlock {
|
|
152
|
+
docID: string;
|
|
153
|
+
documentStatus: PdfDocumentStatus | string;
|
|
154
|
+
/** FAILED үед — ж: `REPRESENTATION_REVOKED` (prepare-ээс хойш эрх хасагдсан, баримт үүсээгүй). */
|
|
155
|
+
errorCode?: string;
|
|
156
|
+
/** Гарын үсэгтэй PDF-ийн SHA-256 (hex) — татсан файлтай тулгана. */
|
|
157
|
+
outSha256?: string;
|
|
158
|
+
size?: number;
|
|
159
|
+
expiresAt?: string;
|
|
160
|
+
signatureLevel?: string;
|
|
161
|
+
signer?: PdfSigner;
|
|
162
|
+
validation?: {
|
|
163
|
+
indication: string;
|
|
164
|
+
ltv: boolean;
|
|
165
|
+
signatures: number;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/** Иргэний төлөөлж чадах нэг байгууллага (GET /organization/representations/etsi/{personEtsi}). */
|
|
169
|
+
interface Representation {
|
|
170
|
+
/** `NTRMN-<бүртгэл>` — `onBehalfOf`-д өгөх утга. */
|
|
171
|
+
orgEtsi: string;
|
|
172
|
+
orgRegister: string;
|
|
173
|
+
orgName: string;
|
|
174
|
+
orgNameEn?: string;
|
|
175
|
+
/** Бүртгэлийн албан тушаал (ХУР-аас холбогдсонд `ceo` / `founder`, MANAGER-т ADMIN-ий бичсэн текст). */
|
|
176
|
+
role?: string;
|
|
177
|
+
rightType: "ADMIN" | "MANAGER" | string;
|
|
178
|
+
source: "REGISTRY" | "MANUAL" | string;
|
|
179
|
+
/** ISO 8601. */
|
|
180
|
+
validFrom: string;
|
|
181
|
+
/** ISO 8601; байхгүй = хугацаагүй. */
|
|
182
|
+
validTo?: string;
|
|
183
|
+
}
|
|
184
|
+
/** GET /organization/representations/etsi/{personEtsi} хариу. */
|
|
185
|
+
interface RepresentationsResponse {
|
|
186
|
+
personEtsi: string;
|
|
187
|
+
representations: Representation[];
|
|
133
188
|
}
|
|
134
189
|
/** Session-ий байгууллагын блок — байгууллага + тухайн иргэний эрх (бүртгэлээс real-time). */
|
|
135
190
|
interface OrgResult {
|
|
@@ -206,15 +261,37 @@ declare class EidError extends Error {
|
|
|
206
261
|
/** HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. */
|
|
207
262
|
declare class AuthenticationError extends EidError {
|
|
208
263
|
}
|
|
209
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй, RP-д эрх алга, эсвэл onBehalfOf-ийн төлөөлөл татгалзсан.
|
|
266
|
+
* Сервер `{"error","code"}` буцаасан бол `code` (ж: `REPRESENTATION_DENIED`) — салааллыг үүгээр хийнэ.
|
|
267
|
+
*/
|
|
210
268
|
declare class ForbiddenError extends EidError {
|
|
269
|
+
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
270
|
+
readonly code?: string | undefined;
|
|
271
|
+
constructor(message: string,
|
|
272
|
+
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
273
|
+
code?: string | undefined);
|
|
211
274
|
}
|
|
212
275
|
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
213
276
|
declare class ApiError extends EidError {
|
|
214
277
|
readonly status: number;
|
|
215
278
|
readonly body: string;
|
|
216
|
-
|
|
279
|
+
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
280
|
+
readonly code?: string | undefined;
|
|
281
|
+
constructor(status: number, body: string,
|
|
282
|
+
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
283
|
+
code?: string | undefined);
|
|
217
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Байгууллагын нэрийн өмнөөс (`onBehalfOf`) урсгалын татгалзлын кодууд — `ForbiddenError.code` /
|
|
287
|
+
* `ApiError.code`-д ирнэ. 403: REPRESENTATION_DENIED (идэвхтэй төлөөлөгч биш), REPRESENTATION_PENDING (PIN2-оор
|
|
288
|
+
* баталгаажуулаагүй), REPRESENTATION_EXPIRED (хугацааны гадна), ORG_NOT_ACTIVE, SIGNER_UNIDENTIFIED (anonymous
|
|
289
|
+
* session); 404: ORG_NOT_FOUND; PDF баримт татахад 403 REPRESENTATION_REVOKED (prepare-ээс хойш эрх хасагдсан —
|
|
290
|
+
* баримт үүсээгүй).
|
|
291
|
+
*/
|
|
292
|
+
type OnBehalfErrorCode = "REPRESENTATION_DENIED" | "REPRESENTATION_PENDING" | "REPRESENTATION_EXPIRED" | "ORG_NOT_ACTIVE" | "SIGNER_UNIDENTIFIED" | "ORG_NOT_FOUND" | "REPRESENTATION_REVOKED";
|
|
293
|
+
/** {@link OnBehalfErrorCode}-ийн бүх утга (runtime шалгалтад). */
|
|
294
|
+
declare const ON_BEHALF_ERROR_CODES: readonly OnBehalfErrorCode[];
|
|
218
295
|
/** Сүлжээ/timeout — upstream хариу өгсөнгүй. */
|
|
219
296
|
declare class NetworkError extends EidError {
|
|
220
297
|
}
|
|
@@ -240,4 +317,4 @@ declare class ValidationError extends EidError {
|
|
|
240
317
|
declare class DeviceLinkError extends EidError {
|
|
241
318
|
}
|
|
242
319
|
|
|
243
|
-
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, type
|
|
320
|
+
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 PdfDocumentStatus as P, type RpCredentials as R, type SignatureAlgorithm as S, ValidationError as V, type SessionResult as a, type RepresentationsResponse as b, ApiError as c, AuthenticationError as d, DeviceLinkError as e, type DeviceLinkInput as f, type EndResult as g, ForbiddenError as h, type NavigatorLike as i, NetworkError as j, type OnBehalfErrorCode as k, type OpenOrShowQROptions as l, type OrgResult as m, type PdfSessionBlock as n, type PdfSigner as o, type Representation as p, SessionFailedError as q, type SessionState as r, type SignatureAlgorithmParameters as s, type SignatureProtocol as t, deviceLink as u, isMobileUserAgent as v, openOrShowQR as w };
|
|
@@ -130,6 +130,61 @@ interface SessionResult {
|
|
|
130
130
|
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
131
131
|
*/
|
|
132
132
|
onBehalfOf: OrgResult | null;
|
|
133
|
+
/**
|
|
134
|
+
* PAdES (`POST /pdf/sign/prepare`) session-ий `pdf` блок — PDF урсгал биш бол null (талбар алга = хуучин SDK-аар
|
|
135
|
+
* угсарсан объект). {@link PdfSessionBlock}.
|
|
136
|
+
*/
|
|
137
|
+
pdf?: PdfSessionBlock | null;
|
|
138
|
+
}
|
|
139
|
+
/** PDF баримтын төлөв: PENDING → READY (эсвэл FAILED / EXPIRED). */
|
|
140
|
+
type PdfDocumentStatus = "PENDING" | "READY" | "FAILED" | "EXPIRED";
|
|
141
|
+
/** PAdES гаралтын гарын үсэг зурагч. */
|
|
142
|
+
interface PdfSigner {
|
|
143
|
+
etsi: string;
|
|
144
|
+
certSerial: string;
|
|
145
|
+
/** Байгууллагын нэрийн өмнөөс бол байгууллагын ETSI (`NTRMN-…`) — баримтад бичигдсэн утга. */
|
|
146
|
+
onBehalfOf?: string;
|
|
147
|
+
/** CMS signer-attributes-v2-д бичигдсэн мэдүүлсэн үүрэг: «<албан тушаал>, <нэр> (NTRMN-…)». */
|
|
148
|
+
claimedRole?: string;
|
|
149
|
+
}
|
|
150
|
+
/** GET /session/{id}-ийн `pdf` объект (PAdES, CA угсарна). */
|
|
151
|
+
interface PdfSessionBlock {
|
|
152
|
+
docID: string;
|
|
153
|
+
documentStatus: PdfDocumentStatus | string;
|
|
154
|
+
/** FAILED үед — ж: `REPRESENTATION_REVOKED` (prepare-ээс хойш эрх хасагдсан, баримт үүсээгүй). */
|
|
155
|
+
errorCode?: string;
|
|
156
|
+
/** Гарын үсэгтэй PDF-ийн SHA-256 (hex) — татсан файлтай тулгана. */
|
|
157
|
+
outSha256?: string;
|
|
158
|
+
size?: number;
|
|
159
|
+
expiresAt?: string;
|
|
160
|
+
signatureLevel?: string;
|
|
161
|
+
signer?: PdfSigner;
|
|
162
|
+
validation?: {
|
|
163
|
+
indication: string;
|
|
164
|
+
ltv: boolean;
|
|
165
|
+
signatures: number;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/** Иргэний төлөөлж чадах нэг байгууллага (GET /organization/representations/etsi/{personEtsi}). */
|
|
169
|
+
interface Representation {
|
|
170
|
+
/** `NTRMN-<бүртгэл>` — `onBehalfOf`-д өгөх утга. */
|
|
171
|
+
orgEtsi: string;
|
|
172
|
+
orgRegister: string;
|
|
173
|
+
orgName: string;
|
|
174
|
+
orgNameEn?: string;
|
|
175
|
+
/** Бүртгэлийн албан тушаал (ХУР-аас холбогдсонд `ceo` / `founder`, MANAGER-т ADMIN-ий бичсэн текст). */
|
|
176
|
+
role?: string;
|
|
177
|
+
rightType: "ADMIN" | "MANAGER" | string;
|
|
178
|
+
source: "REGISTRY" | "MANUAL" | string;
|
|
179
|
+
/** ISO 8601. */
|
|
180
|
+
validFrom: string;
|
|
181
|
+
/** ISO 8601; байхгүй = хугацаагүй. */
|
|
182
|
+
validTo?: string;
|
|
183
|
+
}
|
|
184
|
+
/** GET /organization/representations/etsi/{personEtsi} хариу. */
|
|
185
|
+
interface RepresentationsResponse {
|
|
186
|
+
personEtsi: string;
|
|
187
|
+
representations: Representation[];
|
|
133
188
|
}
|
|
134
189
|
/** Session-ий байгууллагын блок — байгууллага + тухайн иргэний эрх (бүртгэлээс real-time). */
|
|
135
190
|
interface OrgResult {
|
|
@@ -206,15 +261,37 @@ declare class EidError extends Error {
|
|
|
206
261
|
/** HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. */
|
|
207
262
|
declare class AuthenticationError extends EidError {
|
|
208
263
|
}
|
|
209
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй, RP-д эрх алга, эсвэл onBehalfOf-ийн төлөөлөл татгалзсан.
|
|
266
|
+
* Сервер `{"error","code"}` буцаасан бол `code` (ж: `REPRESENTATION_DENIED`) — салааллыг үүгээр хийнэ.
|
|
267
|
+
*/
|
|
210
268
|
declare class ForbiddenError extends EidError {
|
|
269
|
+
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
270
|
+
readonly code?: string | undefined;
|
|
271
|
+
constructor(message: string,
|
|
272
|
+
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
273
|
+
code?: string | undefined);
|
|
211
274
|
}
|
|
212
275
|
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
213
276
|
declare class ApiError extends EidError {
|
|
214
277
|
readonly status: number;
|
|
215
278
|
readonly body: string;
|
|
216
|
-
|
|
279
|
+
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
280
|
+
readonly code?: string | undefined;
|
|
281
|
+
constructor(status: number, body: string,
|
|
282
|
+
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
283
|
+
code?: string | undefined);
|
|
217
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Байгууллагын нэрийн өмнөөс (`onBehalfOf`) урсгалын татгалзлын кодууд — `ForbiddenError.code` /
|
|
287
|
+
* `ApiError.code`-д ирнэ. 403: REPRESENTATION_DENIED (идэвхтэй төлөөлөгч биш), REPRESENTATION_PENDING (PIN2-оор
|
|
288
|
+
* баталгаажуулаагүй), REPRESENTATION_EXPIRED (хугацааны гадна), ORG_NOT_ACTIVE, SIGNER_UNIDENTIFIED (anonymous
|
|
289
|
+
* session); 404: ORG_NOT_FOUND; PDF баримт татахад 403 REPRESENTATION_REVOKED (prepare-ээс хойш эрх хасагдсан —
|
|
290
|
+
* баримт үүсээгүй).
|
|
291
|
+
*/
|
|
292
|
+
type OnBehalfErrorCode = "REPRESENTATION_DENIED" | "REPRESENTATION_PENDING" | "REPRESENTATION_EXPIRED" | "ORG_NOT_ACTIVE" | "SIGNER_UNIDENTIFIED" | "ORG_NOT_FOUND" | "REPRESENTATION_REVOKED";
|
|
293
|
+
/** {@link OnBehalfErrorCode}-ийн бүх утга (runtime шалгалтад). */
|
|
294
|
+
declare const ON_BEHALF_ERROR_CODES: readonly OnBehalfErrorCode[];
|
|
218
295
|
/** Сүлжээ/timeout — upstream хариу өгсөнгүй. */
|
|
219
296
|
declare class NetworkError extends EidError {
|
|
220
297
|
}
|
|
@@ -240,4 +317,4 @@ declare class ValidationError extends EidError {
|
|
|
240
317
|
declare class DeviceLinkError extends EidError {
|
|
241
318
|
}
|
|
242
319
|
|
|
243
|
-
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, type
|
|
320
|
+
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 PdfDocumentStatus as P, type RpCredentials as R, type SignatureAlgorithm as S, ValidationError as V, type SessionResult as a, type RepresentationsResponse as b, ApiError as c, AuthenticationError as d, DeviceLinkError as e, type DeviceLinkInput as f, type EndResult as g, ForbiddenError as h, type NavigatorLike as i, NetworkError as j, type OnBehalfErrorCode as k, type OpenOrShowQROptions as l, type OrgResult as m, type PdfSessionBlock as n, type PdfSigner as o, type Representation as p, SessionFailedError as q, type SessionState as r, type SignatureAlgorithmParameters as s, type SignatureProtocol as t, deviceLink as u, isMobileUserAgent as v, openOrShowQR as w };
|
package/dist/browser.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { e as DeviceLinkError, f as DeviceLinkInput, D as DeviceLinkSession, E as EidError, i as NavigatorLike, l as OpenOrShowQROptions, u as deviceLink, v as isMobileUserAgent, w as openOrShowQR } from './browser-Db82DlYN.cjs';
|
package/dist/browser.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { e as DeviceLinkError, f as DeviceLinkInput, D as DeviceLinkSession, E as EidError, i as NavigatorLike, l as OpenOrShowQROptions, u as deviceLink, v as isMobileUserAgent, w as openOrShowQR } from './browser-Db82DlYN.js';
|
package/dist/browser.js
CHANGED
|
@@ -8,16 +8,32 @@ var EidError = class extends Error {
|
|
|
8
8
|
var AuthenticationError = class extends EidError {
|
|
9
9
|
};
|
|
10
10
|
var ForbiddenError = class extends EidError {
|
|
11
|
+
constructor(message, code) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
|
+
code;
|
|
11
16
|
};
|
|
12
17
|
var ApiError = class extends EidError {
|
|
13
|
-
constructor(status, body) {
|
|
18
|
+
constructor(status, body, code) {
|
|
14
19
|
super(`RP-API ${status}: ${body}`);
|
|
15
20
|
this.status = status;
|
|
16
21
|
this.body = body;
|
|
22
|
+
this.code = code;
|
|
17
23
|
}
|
|
18
24
|
status;
|
|
19
25
|
body;
|
|
26
|
+
code;
|
|
20
27
|
};
|
|
28
|
+
var ON_BEHALF_ERROR_CODES = [
|
|
29
|
+
"REPRESENTATION_DENIED",
|
|
30
|
+
"REPRESENTATION_PENDING",
|
|
31
|
+
"REPRESENTATION_EXPIRED",
|
|
32
|
+
"ORG_NOT_ACTIVE",
|
|
33
|
+
"SIGNER_UNIDENTIFIED",
|
|
34
|
+
"ORG_NOT_FOUND",
|
|
35
|
+
"REPRESENTATION_REVOKED"
|
|
36
|
+
];
|
|
21
37
|
var NetworkError = class extends EidError {
|
|
22
38
|
};
|
|
23
39
|
var SessionFailedError = class extends EidError {
|
|
@@ -79,6 +95,7 @@ export {
|
|
|
79
95
|
AuthenticationError,
|
|
80
96
|
ForbiddenError,
|
|
81
97
|
ApiError,
|
|
98
|
+
ON_BEHALF_ERROR_CODES,
|
|
82
99
|
NetworkError,
|
|
83
100
|
SessionFailedError,
|
|
84
101
|
ValidationError,
|