@gerege-systems/eid-mongolia-sdk 0.8.0 → 0.8.1

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 CHANGED
@@ -4,8 +4,10 @@
4
4
  (authentication) ба хууль ёсны цахим гарын үсэг (qualified signature) хийлгэх Node.js/TypeScript сан.
5
5
  RP-API v3, Smart-ID нийцтэй. Бүрэн баримт: <https://developer.eidmongolia.mn/>.
6
6
 
7
- > ⚠️ Зөвхөн **backend**-д ажиллана (`@gerege-systems/eid-mongolia-sdk/browser`-ийн legacy device-link туслахаас бусад).
8
- > API secret (`rp_sk_…`) браузер/гар утсанд хэзээ ч задлахгүй.
7
+ > ⚠️ SDK **backend**-д ажиллана: бүх дуудлага API secret (`rp_sk_…`)-ээр баталгаажна, secret-ийг браузер/гар утсанд
8
+ > хэзээ ч задлахгүй. Браузерт зөвхөн таны backend-ийн өгсөн холбоос/QR/товч харагдана — «eID-ээр нэвтрэх» товч ч
9
+ > энгийн холбоос, `code` → `id_token` солих нь backend-д (§1a). `@gerege-systems/eid-mongolia-sdk/browser`-ийн
10
+ > legacy device-link туслахууд 2026-10-07-оос ажиллахгүй (§4).
9
11
 
10
12
  ## Суулгах
11
13
 
@@ -17,9 +19,11 @@ Node.js ≥ 22 (global `fetch`, `node:crypto`).
17
19
 
18
20
  ## 1. RP бүртгүүлэх
19
21
 
20
- `POST https://ca.eidmongolia.mn/v3/rp-applications` (эсвэл [developer.eidmongolia.mn](https://developer.eidmongolia.mn)) —
21
- оператор баталсны дараа **relyingPartyUUID** ба **API secret** (`rp_sk_…`) олгогдоно; secret **зөвхөн нэг удаа**
22
- харагдана. Дэлгэрэнгүй: <https://developer.eidmongolia.mn/#registration>.
22
+ RP-г eID Mongolia-гийн оператор бүртгэнэ — хүсэлтээ <eIDsupport@gerege.com> эсвэл 7777-3773-аар гаргана
23
+ (нийтийн `POST /v3/rp-applications` 2026-10-14-нөөс засвартай: `503 rp_applications_maintenance`). Оператор
24
+ баталсны дараа **relyingPartyUUID** ба **API secret** (`rp_sk_…`) олгогдоно; secret **зөвхөн нэг удаа** харагдана.
25
+ Шаардлагатай мэдээлэл (байгууллага, зорилго `AUTH`/`SIGN`, `callbackHosts`, OIDC redirect URI…):
26
+ <https://developer.eidmongolia.mn/#registration>.
23
27
 
24
28
  ## 1a. «eID-ээр нэвтрэх» (OpenID Connect)
25
29
 
@@ -28,6 +32,11 @@ Node.js ≥ 22 (global `fetch`, `node:crypto`).
28
32
  (Authorization Code + PKCE `S256`) `id_token` өгнө — Google/Apple нэвтрэлттэй ижил. Утасны хөтчөөс дарахад
29
33
  хуудасгүйгээр шууд eID апп нээгдэнэ. Гэрээ: <https://developer.eidmongolia.mn/#oidc>.
30
34
 
35
+ **Хаана юу ажиллах.** Товч нь браузерт (энгийн `<a href>` таны backend-ийн `/auth/eid/login` руу); `EidOidcClient`
36
+ нь backend-д — authorize URL угсрах, callback-д `code`-ийг `client_secret`-ээр `id_token` болгон солих, гарын үсгийг
37
+ шалгах. eID-ийн OIDC client нь одоогоор зөвхөн **confidential client** (`client_secret_basic`): backend-гүй SPA эсвэл
38
+ native апп дангаараа token endpoint-ийг дуудаж чадахгүй — native апп ч `code`-ийг өөрийн backend-ээр солино (доор).
39
+
31
40
  **Бүртгэл.** `client_id` = таны RP UUID (`relyingPartyUUID`), `client_secret` = RP API secret (`rp_sk_…`).
32
41
  RP-д `AUTH` эрх, OIDC асаалттай, `redirect_uri` (https, ≤ 10) бүртгэлтэй байна — authorize/token-ий `redirect_uri`
33
42
  бүртгэлтэйтэй **тэмдэгт бүрээрээ** таарах ёстой. Иргэний ETSI дугаар (`pnomn` claim) хэрэгтэй бол `PNOMN` эрх
@@ -77,15 +86,23 @@ callback → `oidc.handleCallback(request.nextUrl.searchParams, tx)` (зөвхө
77
86
  хэрэглэгчийн tap-аас эхэлсэн redirect гинжид eID аппыг нээнэ.
78
87
 
79
88
  ```html
80
- <a class="eid-login" href="/auth/eid/login">eID-ээр нэвтрэх</a>
89
+ <a class="eid-login" href="/auth/eid/login">
90
+ <img src="/img/eid-mongolia.png" alt="" width="20" height="20">
91
+ eID Mongolia-аар нэвтрэх
92
+ </a>
81
93
  <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; }
94
+ .eid-login { display: inline-flex; align-items: center; justify-content: center; gap: .5rem; min-height: 44px;
95
+ padding: 0 1.25rem; border: 1px solid #d0d5dd; border-radius: 6px; background: #fff; color: #111827;
96
+ font: 500 1rem/1 system-ui, sans-serif; text-decoration: none; }
97
+ .eid-login:hover { background: #f5f7fa; }
98
+ .eid-login:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
86
99
  </style>
87
100
  ```
88
101
 
102
+ Бичвэр «eID Mongolia-аар нэвтрэх», зүүн талд eID Mongolia лого (<https://developer.eidmongolia.mn/logo-96.png>-ийг
103
+ татаж өөрийн хостоос үйлчил). Google/Apple-ийн товч шиг саармаг (цагаан, хүрээтэй) — таны сайтын бусад нэвтрэх
104
+ товчтой зэрэгцэж болно. Жишээ: <https://demo.eidmongolia.mn>.
105
+
89
106
  `createAuthorization({ display: "page" })` — утсан дээр ч нэвтрэх хуудас (QR / push) харуулна (ж: таблет киоск).
90
107
 
91
108
  **`id_token` claims** (`EidIdTokenClaims`): `sub` (pairwise — RP тус бүрд өөр, иргэнд тогтмол), `acr`
@@ -123,7 +140,7 @@ const eid = new EidClient({
123
140
  trust: { trustAnchorsPem: [process.env.EID_NATIONAL_ROOT_CA_PEM!] }, // ← Mongolian National Root CA, production-д ЗААВАЛ
124
141
  });
125
142
 
126
- // ETSI (PNOMN-<иргэний дугаар>) / регистр / иргэний дугаар — аль нь ч болно (сервер таьна)
143
+ // ETSI (PNOMN-<иргэний дугаар>) / регистр / иргэний дугаар — аль нь ч болно (сервер танина)
127
144
  const s = await eid.auth.notificationByEtsi("PNOMN-12345678", [
128
145
  { type: "displayTextAndPIN", displayText60: "Хаан Банк-д нэвтрэх" },
129
146
  ]);
@@ -226,7 +243,8 @@ import { buildDeviceLink, type DeviceLinkSession } from "@gerege-systems/eid-mon
226
243
  // backend — session эхлүүлээд бүх хариуг СЕРВЕРТ хадгална (sessionToken/sessionSecret/receivedAt/acsp)
227
244
  const s = await eid.auth.deviceLinkAnonymous(
228
245
  [{ type: "displayTextAndPIN", displayText60: "Хаан Банк-д нэвтрэх" }],
229
- { callbackUrl: "https://bank.example.mn/eid/callback?state=…" }, // товч харуулах бол
246
+ { callbackUrl: "https://bank.example.mn/auth/eid/callback?state=…" }, // товч харуулах бол; host нь callbackHosts-д,
247
+ // зам нь үргэлж /auth/eid/callback болж нормчлогдоно (зөвхөн query хадгалагдана), https заавал
230
248
  );
231
249
  store.put(s.sessionId, s);
232
250
  res.json({ sessionId: s.sessionId, vc: s.vc }); // браузерт ЗӨВХӨН эдгээр
@@ -275,10 +293,9 @@ eid.validator.validateAuth(result, s.acsp, {
275
293
  QR ба товч хоёуланг харуулсан хуудсанд: callback-аар ирсэн үр дүнг `Web2App`/`App2App`-аар, poll-оор ирснийг
276
294
  `QR`-аар шалга (товчоор нээгдсэн session зөвхөн callback-аар дуусна).
277
295
 
278
- > ⚠️ **Шилжилт.** eID Mongolia 2.2.3 (build 59)-өөс өмнөх апп v3 холбоосыг танихгүй. RP-ийн v3 рүү шилжилтийг
279
- > тохиргооны унтраалгаар (анхдагч legacy) хийж, build 59 store-д гарч `min_version=59` тавигдах мөчид асаана.
280
- > Legacy `deviceLink(session)` (`{deviceLinkBase}?sessionId=…&vc=…`) болон `/browser` entry-ийн
281
- > `openOrShowQR` **deprecated** — тэр мөчөөс сервер статик холбоосыг хүлээн авахгүй.
296
+ > ⚠️ **Legacy холбоос хасагдсан (2026-10-07).** Статик `deviceLink(session)` (`{deviceLinkBase}?sessionId=…&vc=…`)
297
+ > болон `/browser` entry-ийн `openOrShowQR`-ээр нээгдсэн session-д сервер утасны үйлдлийг `DEVICE_LINK_REQUIRED`-аар
298
+ > татгалзана — зөвхөн v3 (`buildDeviceLink`) ажиллана. Аппын доод хувилбар: iOS 2.2.3 (59), Android 70.
282
299
 
283
300
  ## Аюулгүй байдал — яагаад `validator` заавал
284
301
 
@@ -293,7 +310,7 @@ OK ирж болзошгүй. Иймд `ResponseValidator`:
293
310
  - **auth** → ACSP_V2 payload (`smart-id|ACSP_V2|serverRandom|rpChallenge|userChallenge|B64(rpName)|B64(brokeredRpName)|B64(SHA-256(interactions))|interactionTypeUsed|initialCallbackUrl|flowType`, hash = хүсэлтийн `hashAlgorithm`) дээр — `flowType`, `userChallenge`, `serverRandom` ба алгоритмын downgrade-ийг мөн шалгана;
294
311
  `expectedFlowType` өгвөл `flowType` эхлүүлсэн урсгалтай ЯГ таарах, Web2App/App2App-д `userChallengeVerifier` заавал
295
312
  `initialCallbackUrl`-ийг хариуны `signature.initialCallbackUrl`-аас авна (CA урсгалаар шийднэ: QR/Notification →
296
- `""`, Web2App/App2App → таны callback; шилжилтийн үед legacy `/dl` ба push-д таны callback) — зөвхөн `""` эсвэл
313
+ `""`, Web2App/App2App → таны callback) — зөвхөн `""` эсвэл
297
314
  таны илгээсэн callback байхад, Web2App/App2App-д заавал таны callback; өөр утга → татгалзана
298
315
  - **sign** → RP-ийн өгсөн digest дээр
299
316
 
@@ -216,9 +216,8 @@ type DeviceLinkInput = Pick<DeviceLinkSession, "sessionId" | "vc" | "deviceLinkB
216
216
  * QR-д эсвэл «eID аппаар нээх» товчинд тавина.
217
217
  *
218
218
  * @deprecated Legacy статик холбоос — холбоосын төрөл (QR/Web2App) хамгаалагдаагүй, relay-д нээлттэй.
219
- * eID Mongolia 2.2.3 (build 59) гармагц сервер унтраана (`EID_DEVICE_LINK_LEGACY=false`). Шинэ код
220
- * backend-д {@link buildDeviceLink} (v3) ашиглана; build 59-өөс өмнөх апп v3 холбоосыг танихгүй тул
221
- * RP v3 рүү шилжих нь тохиргооны унтраалгаар (анхдагч legacy) хийгдэнэ.
219
+ * Сервер 2026-10-07-нд хассан: ийм холбоосоор нээгдсэн session-д утасны үйлдлийг `DEVICE_LINK_REQUIRED`-аар
220
+ * татгалзана. Backend-д {@link buildDeviceLink} (v3) ашиглана.
222
221
  *
223
222
  * @throws {DeviceLinkError} deviceLinkBase байхгүй / http(s) биш, sessionId UUID биш, vc 5 орон биш.
224
223
  */
@@ -251,6 +250,8 @@ interface OpenOrShowQROptions {
251
250
  * Link-ийг алгасаж /dl хуудсыг нээдэг; тэр хуудас «Аппаар нээх» товч ба store холбоосыг санал болгоно.
252
251
  *
253
252
  * @throws {DeviceLinkError} холбоос угсрах боломжгүй бол ({@link deviceLink}).
253
+ * @deprecated Legacy {@link deviceLink} холбоос дээр тулгуурладаг — сервер 2026-10-07-нд хассан тул ажиллахгүй.
254
+ * QR-ийг backend-ийн `buildDeviceLink` (v3)-ээр, утсан дээр Web2App холбоосыг энгийн `<a href>`-ээр харуулна.
254
255
  */
255
256
  declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROptions): "opened" | "qr";
256
257
 
@@ -216,9 +216,8 @@ type DeviceLinkInput = Pick<DeviceLinkSession, "sessionId" | "vc" | "deviceLinkB
216
216
  * QR-д эсвэл «eID аппаар нээх» товчинд тавина.
217
217
  *
218
218
  * @deprecated Legacy статик холбоос — холбоосын төрөл (QR/Web2App) хамгаалагдаагүй, relay-д нээлттэй.
219
- * eID Mongolia 2.2.3 (build 59) гармагц сервер унтраана (`EID_DEVICE_LINK_LEGACY=false`). Шинэ код
220
- * backend-д {@link buildDeviceLink} (v3) ашиглана; build 59-өөс өмнөх апп v3 холбоосыг танихгүй тул
221
- * RP v3 рүү шилжих нь тохиргооны унтраалгаар (анхдагч legacy) хийгдэнэ.
219
+ * Сервер 2026-10-07-нд хассан: ийм холбоосоор нээгдсэн session-д утасны үйлдлийг `DEVICE_LINK_REQUIRED`-аар
220
+ * татгалзана. Backend-д {@link buildDeviceLink} (v3) ашиглана.
222
221
  *
223
222
  * @throws {DeviceLinkError} deviceLinkBase байхгүй / http(s) биш, sessionId UUID биш, vc 5 орон биш.
224
223
  */
@@ -251,6 +250,8 @@ interface OpenOrShowQROptions {
251
250
  * Link-ийг алгасаж /dl хуудсыг нээдэг; тэр хуудас «Аппаар нээх» товч ба store холбоосыг санал болгоно.
252
251
  *
253
252
  * @throws {DeviceLinkError} холбоос угсрах боломжгүй бол ({@link deviceLink}).
253
+ * @deprecated Legacy {@link deviceLink} холбоос дээр тулгуурладаг — сервер 2026-10-07-нд хассан тул ажиллахгүй.
254
+ * QR-ийг backend-ийн `buildDeviceLink` (v3)-ээр, утсан дээр Web2App холбоосыг энгийн `<a href>`-ээр харуулна.
254
255
  */
255
256
  declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROptions): "opened" | "qr";
256
257
 
@@ -1 +1 @@
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';
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-DqKDj2nB.cjs';
package/dist/browser.d.ts CHANGED
@@ -1 +1 @@
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';
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-DqKDj2nB.js';
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, b as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-Db82DlYN.cjs';
2
- export { c as ApiError, d as AuthenticationError, e as DeviceLinkError, f as DeviceLinkInput, g as EndResult, h as ForbiddenError, i as NavigatorLike, j as NetworkError, O as ON_BEHALF_ERROR_CODES, k as OnBehalfErrorCode, l as OpenOrShowQROptions, m as OrgResult, P as PdfDocumentStatus, n as PdfSessionBlock, o as PdfSigner, p as Representation, q as SessionFailedError, r as SessionState, s as SignatureAlgorithmParameters, t as SignatureProtocol, V as ValidationError, u as deviceLink, v as isMobileUserAgent, w as openOrShowQR } from './browser-Db82DlYN.cjs';
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, b as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-DqKDj2nB.cjs';
2
+ export { c as ApiError, d as AuthenticationError, e as DeviceLinkError, f as DeviceLinkInput, g as EndResult, h as ForbiddenError, i as NavigatorLike, j as NetworkError, O as ON_BEHALF_ERROR_CODES, k as OnBehalfErrorCode, l as OpenOrShowQROptions, m as OrgResult, P as PdfDocumentStatus, n as PdfSessionBlock, o as PdfSigner, p as Representation, q as SessionFailedError, r as SessionState, s as SignatureAlgorithmParameters, t as SignatureProtocol, V as ValidationError, u as deviceLink, v as isMobileUserAgent, w as openOrShowQR } from './browser-DqKDj2nB.cjs';
3
3
  import { X509Certificate, KeyObject } from 'node:crypto';
4
4
 
5
5
  interface HttpConfig {
@@ -218,8 +218,7 @@ interface ValidateAuthOptions {
218
218
  * (verifier-тэй) ирсэн үр дүнг "Web2App"/"App2App"-аар, poll-оор ирснийг "QR"-аар шалга — товчоор
219
219
  * нээгдсэн session poll замаар OK болохгүй, callback-аар л дуусна.
220
220
  *
221
- * ⚠️ Legacy `/dl?sessionId&vc` холбоосонд төрөл хамгаалагдаагүй — build 59 + `min_version=59` хүртэл
222
- * энэ шалгалт relay-ээс бүрэн хамгаалахгүй.
221
+ * Legacy `/dl?sessionId&vc` холбоос 2026-10-07-нд серверээс хасагдсан — төрөл үргэлж authCode-оор хамгаалагдана.
223
222
  */
224
223
  expectedFlowType?: FlowType;
225
224
  /**
package/dist/index.d.ts 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, b as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-Db82DlYN.js';
2
- export { c as ApiError, d as AuthenticationError, e as DeviceLinkError, f as DeviceLinkInput, g as EndResult, h as ForbiddenError, i as NavigatorLike, j as NetworkError, O as ON_BEHALF_ERROR_CODES, k as OnBehalfErrorCode, l as OpenOrShowQROptions, m as OrgResult, P as PdfDocumentStatus, n as PdfSessionBlock, o as PdfSigner, p as Representation, q as SessionFailedError, r as SessionState, s as SignatureAlgorithmParameters, t as SignatureProtocol, V as ValidationError, u as deviceLink, v as isMobileUserAgent, w as openOrShowQR } from './browser-Db82DlYN.js';
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, b as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-DqKDj2nB.js';
2
+ export { c as ApiError, d as AuthenticationError, e as DeviceLinkError, f as DeviceLinkInput, g as EndResult, h as ForbiddenError, i as NavigatorLike, j as NetworkError, O as ON_BEHALF_ERROR_CODES, k as OnBehalfErrorCode, l as OpenOrShowQROptions, m as OrgResult, P as PdfDocumentStatus, n as PdfSessionBlock, o as PdfSigner, p as Representation, q as SessionFailedError, r as SessionState, s as SignatureAlgorithmParameters, t as SignatureProtocol, V as ValidationError, u as deviceLink, v as isMobileUserAgent, w as openOrShowQR } from './browser-DqKDj2nB.js';
3
3
  import { X509Certificate, KeyObject } from 'node:crypto';
4
4
 
5
5
  interface HttpConfig {
@@ -218,8 +218,7 @@ interface ValidateAuthOptions {
218
218
  * (verifier-тэй) ирсэн үр дүнг "Web2App"/"App2App"-аар, poll-оор ирснийг "QR"-аар шалга — товчоор
219
219
  * нээгдсэн session poll замаар OK болохгүй, callback-аар л дуусна.
220
220
  *
221
- * ⚠️ Legacy `/dl?sessionId&vc` холбоосонд төрөл хамгаалагдаагүй — build 59 + `min_version=59` хүртэл
222
- * энэ шалгалт relay-ээс бүрэн хамгаалахгүй.
221
+ * Legacy `/dl?sessionId&vc` холбоос 2026-10-07-нд серверээс хасагдсан — төрөл үргэлж authCode-оор хамгаалагдана.
223
222
  */
224
223
  expectedFlowType?: FlowType;
225
224
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gerege-systems/eid-mongolia-sdk",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "e-ID Mongolia Relying Party SDK — иргэнээр утсаар нь нэвтрэлт ба хууль ёсны цахим гарын үсэг (RP-API v3, Smart-ID нийцтэй).",
5
5
  "license": "MIT",
6
6
  "type": "module",