@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 +25 -6
- package/dist/{browser-B_xuB7Rt.d.cts → browser-C6JHm0lR.d.cts} +6 -0
- package/dist/{browser-B_xuB7Rt.d.ts → browser-C6JHm0lR.d.ts} +6 -0
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/index.cjs +21 -7
- package/dist/index.d.cts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +21 -7
- package/package.json +1 -1
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
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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 {
|
package/dist/browser.d.cts
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-
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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.
|
|
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",
|