@gerege-systems/eid-mongolia-sdk 0.12.0 → 0.13.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 CHANGED
@@ -40,7 +40,24 @@ native апп дангаараа token endpoint-ийг дуудаж чадахг
40
40
  **Бүртгэл.** `client_id` = таны RP UUID (`relyingPartyUUID`), `client_secret` = RP API secret (`rp_sk_…`).
41
41
  RP-д `AUTH` эрх, OIDC асаалттай, `redirect_uri` (https, ≤ 10) бүртгэлтэй байна — authorize/token-ий `redirect_uri`
42
42
  бүртгэлтэйтэй **тэмдэгт бүрээрээ** таарах ёстой. Иргэний ETSI дугаар (`pnomn` claim) хэрэгтэй бол `PNOMN` эрх
43
- хүсэж, `scope: "openid pnomn"`. Token endpoint-д RP-ийн IP allowlist мөрдөгдөнө; `requireMtls` RP OIDC ашиглахгүй.
43
+ хүсэж, `scope: "openid pnomn"`. Token endpoint-д RP-ийн IP allowlist мөрдөгдөнө.
44
+
45
+ **mTLS-тэй RP (`require_mtls`).** `login.` хост mTLS хийдэггүй тул ийм RP-ийн code солих хүсэлт
46
+ `login.eidmongolia.mn/oauth2/token` дээр `401 invalid_client` авна. Discovery-ийн `mtls_endpoint_aliases.token_endpoint`
47
+ (RFC 8705 §5, `https://rp.eidmongolia.mn/oauth2/token`) руу RP-API-д хэрэглэдэг **ижил client cert**-ээр явуулна:
48
+ `useMtlsEndpointAliases: true` + `dispatcher` (RP-API client-ийнхтэй ижил undici `Agent`). Discovery-д alias байхгүй
49
+ бол `token_endpoint` руу буцна; alias https биш бол `discovery_failed`. mTLS-гүй RP флаг тавихгүй.
50
+
51
+ ```ts
52
+ import { Agent } from "undici";
53
+ const oidc = new EidOidcClient({
54
+ clientId: process.env.EID_RP_UUID!,
55
+ clientSecret: process.env.EID_SECRET!,
56
+ redirectUri: "https://bank.example.mn/auth/eid/callback",
57
+ dispatcher: new Agent({ connect: { cert: clientCertPem, key: clientKeyPem } }), // RP-API-ийн cert
58
+ useMtlsEndpointAliases: true, // token → https://rp.eidmongolia.mn/oauth2/token
59
+ });
60
+ ```
44
61
 
45
62
  ```ts
46
63
  import { EidOidcClient, EidOidcError } from "@gerege-systems/eid-mongolia-sdk";
@@ -219,7 +236,7 @@ import { ForbiddenError, ApiError, ON_BEHALF_ERROR_CODES } from "@gerege-systems
219
236
  // 1. Иргэн сүүлийн 24 цагт танай RP-ээр нэвтэрсэн байх ёстой.
220
237
  const { representations } = await eid.organization.getRepresentations("PNOMN-12345678");
221
238
  // → [{ orgEtsi: "NTRMN-6235972", orgName: "Гэрэгэ Системс ХХК", role: "ceo", roleLabel: "Гүйцэтгэх захирал",
222
- // rightType: "ADMIN", … }]
239
+ // rightType: "ADMIN", rightTypeLabel: "Админ", source: "REGISTRY", sourceLabel: "Улсын бүртгэл", … }]
223
240
 
224
241
  // 2. PDF (PAdES, CA угсарна) — санал болгох урсгал.
225
242
  try {
@@ -259,12 +276,14 @@ prepare 429 `PDF_PREPARE_BUSY`, 503 `LTV_UNAVAILABLE` / `TSA_UNAVAILABLE`; docum
259
276
  хүртэл уншина; хэтэрвэл `ResponseTooLargeError`. JSON хариу 4 MiB-ээс хэтэрвэл мөн `ResponseTooLargeError` (таслахгүй).
260
277
  `getRepresentations`-ийн `raw` — серверийн түүхий JSON.
261
278
 
262
- **Албан тушаал харуулахдаа `roleLabel` ашигла** (representations болон session-ий `onBehalfOf`) — `role` нь машин
263
- утга (`ceo` / `founder` / `stakeholder` эсвэл MANAGER-т бичсэн текст), өөрөө орчуулахгүй. Хэл: `new EidClient({ …,
264
- language: "en" })` → дуудлага бүрд `Accept-Language`; анхдагч илгээхгүй (сервер mn). Хуучин CA-д `roleLabel` байхгүй.
279
+ **Хүнд харуулахдаа `roleLabel` / `rightTypeLabel` / `sourceLabel` ашигла** (representations болон session-ий
280
+ `onBehalfOf`; `onBehalfOf`-д `source` байхгүй тул зөвхөн `roleLabel` / `rightTypeLabel`) — `role` (`ceo` / `founder` /
281
+ `stakeholder` эсвэл MANAGER-т бичсэн текст), `rightType` (`ADMIN` | `MANAGER`), `source` (`REGISTRY` | `MANUAL`) нь
282
+ машин утга, өөрөө орчуулахгүй. Хэл: `new EidClient({ …, language: "en" })` → дуудлага бүрд `Accept-Language`; анхдагч
283
+ илгээхгүй (сервер mn). Хуучин CA-д эдгээр талбар байхгүй.
265
284
 
266
285
  Олон талт гэрээ: А байгууллагын гаралтыг өөрчлөлтгүй Б-ийн `prepare`-д (`docID`, өөр `onBehalfOf`) илгээнэ.
267
- Session-ий `onBehalfOf` блок (`role`/`roleLabel`/`rightType`) нь хариу угсрах үеийн бүртгэл; `pdf.signer.onBehalfOf`/`claimedRole`
286
+ Session-ий `onBehalfOf` блок (`role`/`roleLabel`/`rightType`/`rightTypeLabel`) нь хариу угсрах үеийн бүртгэл; `pdf.signer.onBehalfOf`/`claimedRole`
268
287
  нь баримтад бичигдсэн утга.
269
288
 
270
289
  ## 3b. Иргэний PKI самбар (`PKI_READ` эрх)
@@ -223,7 +223,11 @@ interface Representation {
223
223
  */
224
224
  roleLabel?: string;
225
225
  rightType: "ADMIN" | "MANAGER" | string;
226
+ /** Эрхийн төрлийн хүнд харуулах нэр (ADMIN → «Админ», MANAGER → «Гарын үсэг зурагч»; хэл нь `roleLabel`-тэй ижил). Хуучин CA-д байхгүй. */
227
+ rightTypeLabel?: string;
226
228
  source: "REGISTRY" | "MANUAL" | string;
229
+ /** Эх үүсвэрийн хүнд харуулах нэр (REGISTRY → «Улсын бүртгэл», MANUAL → «Захирал нэмсэн»; хэл нь `roleLabel`-тэй ижил). Хуучин CA-д байхгүй. */
230
+ sourceLabel?: string;
227
231
  /** ISO 8601. */
228
232
  validFrom: string;
229
233
  /** ISO 8601; байхгүй = хугацаагүй. */
@@ -247,6 +251,8 @@ interface OrgResult {
247
251
  roleLabel?: string;
248
252
  /** ADMIN | MANAGER. Эрх хураагдсан бол null. */
249
253
  rightType: string | null;
254
+ /** Эрхийн төрлийн хүнд харуулах нэр ({@link Representation.rightTypeLabel}). Эрх хураагдсан / хуучин CA бол байхгүй. */
255
+ rightTypeLabel?: string;
250
256
  }
251
257
  /** RP-ийн нэвтрэх мэдээлэл — бүх дуудлагад хэрэгтэй таних тэмдэг + secret. */
252
258
  interface RpCredentials {
@@ -223,7 +223,11 @@ interface Representation {
223
223
  */
224
224
  roleLabel?: string;
225
225
  rightType: "ADMIN" | "MANAGER" | string;
226
+ /** Эрхийн төрлийн хүнд харуулах нэр (ADMIN → «Админ», MANAGER → «Гарын үсэг зурагч»; хэл нь `roleLabel`-тэй ижил). Хуучин CA-д байхгүй. */
227
+ rightTypeLabel?: string;
226
228
  source: "REGISTRY" | "MANUAL" | string;
229
+ /** Эх үүсвэрийн хүнд харуулах нэр (REGISTRY → «Улсын бүртгэл», MANUAL → «Захирал нэмсэн»; хэл нь `roleLabel`-тэй ижил). Хуучин CA-д байхгүй. */
230
+ sourceLabel?: string;
227
231
  /** ISO 8601. */
228
232
  validFrom: string;
229
233
  /** ISO 8601; байхгүй = хугацаагүй. */
@@ -247,6 +251,8 @@ interface OrgResult {
247
251
  roleLabel?: string;
248
252
  /** ADMIN | MANAGER. Эрх хураагдсан бол null. */
249
253
  rightType: string | null;
254
+ /** Эрхийн төрлийн хүнд харуулах нэр ({@link Representation.rightTypeLabel}). Эрх хураагдсан / хуучин CA бол байхгүй. */
255
+ rightTypeLabel?: string;
250
256
  }
251
257
  /** RP-ийн нэвтрэх мэдээлэл — бүх дуудлагад хэрэгтэй таних тэмдэг + secret. */
252
258
  interface RpCredentials {
@@ -1 +1 @@
1
- export { f as DeviceLinkError, g as DeviceLinkInput, D as DeviceLinkSession, E as EidError, k as NavigatorLike, n as OpenOrShowQROptions, B as deviceLink, G as isMobileUserAgent, J as openOrShowQR } from './browser-B_xuB7Rt.cjs';
1
+ export { f as DeviceLinkError, g as DeviceLinkInput, D as DeviceLinkSession, E as EidError, k as NavigatorLike, n as OpenOrShowQROptions, B as deviceLink, G as isMobileUserAgent, J as openOrShowQR } from './browser-C6JHm0lR.cjs';
package/dist/browser.d.ts CHANGED
@@ -1 +1 @@
1
- export { f as DeviceLinkError, g as DeviceLinkInput, D as DeviceLinkSession, E as EidError, k as NavigatorLike, n as OpenOrShowQROptions, B as deviceLink, G as isMobileUserAgent, J as openOrShowQR } from './browser-B_xuB7Rt.js';
1
+ export { f as DeviceLinkError, g as DeviceLinkInput, D as DeviceLinkSession, E as EidError, k as NavigatorLike, n as OpenOrShowQROptions, B as deviceLink, G as isMobileUserAgent, J as openOrShowQR } from './browser-C6JHm0lR.js';
package/dist/index.cjs CHANGED
@@ -647,12 +647,14 @@ function parseOrg(raw) {
647
647
  const etsi = str(o.orgEtsi);
648
648
  if (!etsi) return null;
649
649
  const roleLabel = str(o.roleLabel);
650
+ const rightTypeLabel = str(o.rightTypeLabel);
650
651
  return {
651
652
  orgEtsi: etsi,
652
653
  orgName: str(o.orgName),
653
654
  role: str(o.role),
654
655
  ...roleLabel ? { roleLabel } : {},
655
- rightType: str(o.rightType)
656
+ rightType: str(o.rightType),
657
+ ...rightTypeLabel ? { rightTypeLabel } : {}
656
658
  };
657
659
  }
658
660
  var SessionApi = class {
@@ -2032,7 +2034,7 @@ var EidOidcClient = class {
2032
2034
  async exchangeCode(code, codeVerifier) {
2033
2035
  const d = await this.discover();
2034
2036
  const basic = Buffer.from(formEncode(this.cfg.clientId) + ":" + formEncode(this.cfg.clientSecret)).toString("base64");
2035
- const res = await this.fetch(d.token_endpoint, {
2037
+ const res = await this.fetch(this.tokenEndpoint(d), {
2036
2038
  method: "POST",
2037
2039
  headers: {
2038
2040
  Authorization: "Basic " + basic,
@@ -2064,6 +2066,16 @@ var EidOidcClient = class {
2064
2066
  }
2065
2067
  return j.id_token;
2066
2068
  }
2069
+ /** Code солих endpoint: `useMtlsEndpointAliases` + alias байвал alias (RFC 8705 §5), эс бөгөөс `token_endpoint`. */
2070
+ tokenEndpoint(d) {
2071
+ if (!this.cfg.useMtlsEndpointAliases) return d.token_endpoint;
2072
+ const alias = d.mtls_endpoint_aliases?.token_endpoint;
2073
+ if (alias === void 0) return d.token_endpoint;
2074
+ if (typeof alias !== "string" || !alias.startsWith("https://")) {
2075
+ throw new EidOidcError("discovery_failed", "OIDC discovery: mtls_endpoint_aliases.token_endpoint \u0431\u0443\u0440\u0443\u0443");
2076
+ }
2077
+ return alias;
2078
+ }
2067
2079
  /**
2068
2080
  * id_token шалгана: JWKS (`kid`, cache; танихгүй kid → нэг удаа дахин татна) ES256 гарын үсэг, `iss`, `aud`
2069
2081
  * (= clientId; олон aud бол `azp`), `exp`/`iat` (±60 сек), `nonce`. Амжилтгүй бол `invalid_id_token`.
@@ -2140,12 +2152,14 @@ var EidOidcClient = class {
2140
2152
  }
2141
2153
  async fetch(url, init) {
2142
2154
  const f = this.cfg.fetchImpl ?? fetch;
2155
+ const req = {
2156
+ ...init,
2157
+ redirect: "error",
2158
+ signal: AbortSignal.timeout(this.cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS2)
2159
+ };
2160
+ if (this.cfg.dispatcher) req.dispatcher = this.cfg.dispatcher;
2143
2161
  try {
2144
- return await f(url, {
2145
- ...init,
2146
- redirect: "error",
2147
- signal: AbortSignal.timeout(this.cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS2)
2148
- });
2162
+ return await f(url, req);
2149
2163
  } catch (e) {
2150
2164
  const err = e;
2151
2165
  if (err.name === "TimeoutError" || err.name === "AbortError") {
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-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';
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-C6JHm0lR.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-C6JHm0lR.cjs';
3
3
  import { X509Certificate, KeyObject } from 'node:crypto';
4
4
 
5
5
  interface HttpConfig {
@@ -965,6 +965,17 @@ interface EidOidcClientConfig {
965
965
  scope?: string;
966
966
  /** HTTP timeout (мс), анхдагч 10000. */
967
967
  timeoutMs?: number;
968
+ /**
969
+ * undici Dispatcher (mTLS client cert) — RP-API client-ийн `dispatcher`-тэй ижил:
970
+ * `new Agent({ connect: { cert, key } })`. Дамжуулсан бол OIDC-ийн бүх fetch-д хэрэглэнэ. Зөвхөн Node орчинд.
971
+ */
972
+ dispatcher?: unknown;
973
+ /**
974
+ * RFC 8705 §5: `true` бол code солих хүсэлт discovery-ийн `mtls_endpoint_aliases.token_endpoint` руу явна
975
+ * (`require_mtls`-тэй RP — `dispatcher`-т RP-ийн client cert заавал). Discovery-д alias байхгүй бол
976
+ * `token_endpoint` руу буцна; alias https биш бол `discovery_failed`. Анхдагч `false`.
977
+ */
978
+ useMtlsEndpointAliases?: boolean;
968
979
  /** fetch орлуулагч (тест). */
969
980
  fetchImpl?: typeof fetch;
970
981
  }
@@ -973,6 +984,8 @@ interface EidOidcDiscovery {
973
984
  authorization_endpoint: string;
974
985
  token_endpoint: string;
975
986
  jwks_uri: string;
987
+ /** RFC 8705 §5 — mTLS-тэй client-ийн endpoint-ууд (ж: `token_endpoint` → `https://rp.eidmongolia.mn/oauth2/token`). */
988
+ mtls_endpoint_aliases?: Record<string, string>;
976
989
  [k: string]: unknown;
977
990
  }
978
991
  interface CreateAuthorizationOptions {
@@ -1050,6 +1063,8 @@ declare class EidOidcClient {
1050
1063
  handleCallback(input: string | URL | URLSearchParams, checks: EidCallbackChecks): Promise<EidCallbackResult>;
1051
1064
  /** `POST token_endpoint` (client_secret_basic, RFC 6749 §2.3.1) → id_token. */
1052
1065
  private exchangeCode;
1066
+ /** Code солих endpoint: `useMtlsEndpointAliases` + alias байвал alias (RFC 8705 §5), эс бөгөөс `token_endpoint`. */
1067
+ private tokenEndpoint;
1053
1068
  /**
1054
1069
  * id_token шалгана: JWKS (`kid`, cache; танихгүй kid → нэг удаа дахин татна) ES256 гарын үсэг, `iss`, `aud`
1055
1070
  * (= clientId; олон aud бол `azp`), `exp`/`iat` (±60 сек), `nonce`. Амжилтгүй бол `invalid_id_token`.
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, P as PersonBlock, b as PdfSessionBlock, c as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-B_xuB7Rt.js';
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.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, P as PersonBlock, b as PdfSessionBlock, c as RepresentationsResponse, A as AcspContext, F as FlowType, E as EidError } from './browser-C6JHm0lR.js';
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-C6JHm0lR.js';
3
3
  import { X509Certificate, KeyObject } from 'node:crypto';
4
4
 
5
5
  interface HttpConfig {
@@ -965,6 +965,17 @@ interface EidOidcClientConfig {
965
965
  scope?: string;
966
966
  /** HTTP timeout (мс), анхдагч 10000. */
967
967
  timeoutMs?: number;
968
+ /**
969
+ * undici Dispatcher (mTLS client cert) — RP-API client-ийн `dispatcher`-тэй ижил:
970
+ * `new Agent({ connect: { cert, key } })`. Дамжуулсан бол OIDC-ийн бүх fetch-д хэрэглэнэ. Зөвхөн Node орчинд.
971
+ */
972
+ dispatcher?: unknown;
973
+ /**
974
+ * RFC 8705 §5: `true` бол code солих хүсэлт discovery-ийн `mtls_endpoint_aliases.token_endpoint` руу явна
975
+ * (`require_mtls`-тэй RP — `dispatcher`-т RP-ийн client cert заавал). Discovery-д alias байхгүй бол
976
+ * `token_endpoint` руу буцна; alias https биш бол `discovery_failed`. Анхдагч `false`.
977
+ */
978
+ useMtlsEndpointAliases?: boolean;
968
979
  /** fetch орлуулагч (тест). */
969
980
  fetchImpl?: typeof fetch;
970
981
  }
@@ -973,6 +984,8 @@ interface EidOidcDiscovery {
973
984
  authorization_endpoint: string;
974
985
  token_endpoint: string;
975
986
  jwks_uri: string;
987
+ /** RFC 8705 §5 — mTLS-тэй client-ийн endpoint-ууд (ж: `token_endpoint` → `https://rp.eidmongolia.mn/oauth2/token`). */
988
+ mtls_endpoint_aliases?: Record<string, string>;
976
989
  [k: string]: unknown;
977
990
  }
978
991
  interface CreateAuthorizationOptions {
@@ -1050,6 +1063,8 @@ declare class EidOidcClient {
1050
1063
  handleCallback(input: string | URL | URLSearchParams, checks: EidCallbackChecks): Promise<EidCallbackResult>;
1051
1064
  /** `POST token_endpoint` (client_secret_basic, RFC 6749 §2.3.1) → id_token. */
1052
1065
  private exchangeCode;
1066
+ /** Code солих endpoint: `useMtlsEndpointAliases` + alias байвал alias (RFC 8705 §5), эс бөгөөс `token_endpoint`. */
1067
+ private tokenEndpoint;
1053
1068
  /**
1054
1069
  * id_token шалгана: JWKS (`kid`, cache; танихгүй kid → нэг удаа дахин татна) ES256 гарын үсэг, `iss`, `aud`
1055
1070
  * (= clientId; олон aud бол `azp`), `exp`/`iat` (±60 сек), `nonce`. Амжилтгүй бол `invalid_id_token`.
package/dist/index.js CHANGED
@@ -464,12 +464,14 @@ function parseOrg(raw) {
464
464
  const etsi = str(o.orgEtsi);
465
465
  if (!etsi) return null;
466
466
  const roleLabel = str(o.roleLabel);
467
+ const rightTypeLabel = str(o.rightTypeLabel);
467
468
  return {
468
469
  orgEtsi: etsi,
469
470
  orgName: str(o.orgName),
470
471
  role: str(o.role),
471
472
  ...roleLabel ? { roleLabel } : {},
472
- rightType: str(o.rightType)
473
+ rightType: str(o.rightType),
474
+ ...rightTypeLabel ? { rightTypeLabel } : {}
473
475
  };
474
476
  }
475
477
  var SessionApi = class {
@@ -1807,7 +1809,7 @@ var EidOidcClient = class {
1807
1809
  async exchangeCode(code, codeVerifier) {
1808
1810
  const d = await this.discover();
1809
1811
  const basic = Buffer.from(formEncode(this.cfg.clientId) + ":" + formEncode(this.cfg.clientSecret)).toString("base64");
1810
- const res = await this.fetch(d.token_endpoint, {
1812
+ const res = await this.fetch(this.tokenEndpoint(d), {
1811
1813
  method: "POST",
1812
1814
  headers: {
1813
1815
  Authorization: "Basic " + basic,
@@ -1839,6 +1841,16 @@ var EidOidcClient = class {
1839
1841
  }
1840
1842
  return j.id_token;
1841
1843
  }
1844
+ /** Code солих endpoint: `useMtlsEndpointAliases` + alias байвал alias (RFC 8705 §5), эс бөгөөс `token_endpoint`. */
1845
+ tokenEndpoint(d) {
1846
+ if (!this.cfg.useMtlsEndpointAliases) return d.token_endpoint;
1847
+ const alias = d.mtls_endpoint_aliases?.token_endpoint;
1848
+ if (alias === void 0) return d.token_endpoint;
1849
+ if (typeof alias !== "string" || !alias.startsWith("https://")) {
1850
+ throw new EidOidcError("discovery_failed", "OIDC discovery: mtls_endpoint_aliases.token_endpoint \u0431\u0443\u0440\u0443\u0443");
1851
+ }
1852
+ return alias;
1853
+ }
1842
1854
  /**
1843
1855
  * id_token шалгана: JWKS (`kid`, cache; танихгүй kid → нэг удаа дахин татна) ES256 гарын үсэг, `iss`, `aud`
1844
1856
  * (= clientId; олон aud бол `azp`), `exp`/`iat` (±60 сек), `nonce`. Амжилтгүй бол `invalid_id_token`.
@@ -1915,12 +1927,14 @@ var EidOidcClient = class {
1915
1927
  }
1916
1928
  async fetch(url, init) {
1917
1929
  const f = this.cfg.fetchImpl ?? fetch;
1930
+ const req = {
1931
+ ...init,
1932
+ redirect: "error",
1933
+ signal: AbortSignal.timeout(this.cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS2)
1934
+ };
1935
+ if (this.cfg.dispatcher) req.dispatcher = this.cfg.dispatcher;
1918
1936
  try {
1919
- return await f(url, {
1920
- ...init,
1921
- redirect: "error",
1922
- signal: AbortSignal.timeout(this.cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS2)
1923
- });
1937
+ return await f(url, req);
1924
1938
  } catch (e) {
1925
1939
  const err = e;
1926
1940
  if (err.name === "TimeoutError" || err.name === "AbortError") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gerege-systems/eid-mongolia-sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "e-ID Mongolia Relying Party SDK — иргэнээр утсаар нь нэвтрэлт ба хууль ёсны цахим гарын үсэг (RP-API v3, Smart-ID нийцтэй).",
5
5
  "license": "MIT",
6
6
  "type": "module",