@gerege-systems/eid-mongolia-sdk 0.3.0 → 0.4.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 +39 -1
- package/dist/browser-BS8JwSQk.d.cts +223 -0
- package/dist/browser-BS8JwSQk.d.ts +223 -0
- package/dist/browser.cjs +89 -0
- package/dist/browser.d.cts +1 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +14 -0
- package/dist/chunk-Q5TQMCJC.js +89 -0
- package/dist/index.cjs +54 -0
- package/dist/index.d.cts +3 -169
- package/dist/index.d.ts +3 -169
- package/dist/index.js +19 -31
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
(authentication) ба хууль ёсны цахим гарын үсэг (qualified signature) хийлгэх Node.js/TypeScript сан.
|
|
5
5
|
RP-API v3, Smart-ID нийцтэй. Бүрэн баримт: <https://eidmongolia.mn/developers>.
|
|
6
6
|
|
|
7
|
-
> ⚠️ Зөвхөн **backend**-д
|
|
7
|
+
> ⚠️ Зөвхөн **backend**-д ажиллана (`@gerege-systems/eid-mongolia-sdk/browser`-ийн device-link туслахаас бусад).
|
|
8
|
+
> API secret (`rp_sk_…`) браузер/гар утсанд хэзээ ч задлахгүй.
|
|
8
9
|
|
|
9
10
|
## Суулгах
|
|
10
11
|
|
|
@@ -66,6 +67,42 @@ const sig = eid.validator.validateSign(result, digest); // digest-ийн эср
|
|
|
66
67
|
console.log(sig.signatureValueB64, sig.subject);
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
## 4. Ижил төхөөрөмж (App2App / Web2App)
|
|
71
|
+
|
|
72
|
+
Иргэн RP-ийн сайт/аппыг **eID апптай ижил утсан дээр** нээсэн бол QR уншуулах боломжгүй — device-link
|
|
73
|
+
session эхлүүлээд холбоосоор аппыг шууд нээнэ. Desktop дээр ижил холбоосыг QR болгож харуулна.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// backend — session эхлүүлээд браузерт ЗӨВХӨН sessionId, vc, deviceLinkBase-ийг өгнө (secret/token биш)
|
|
77
|
+
const s = await eid.auth.deviceLinkAnonymous([{ type: "displayTextAndPIN", displayText60: "Хаан Банк-д нэвтрэх" }]);
|
|
78
|
+
res.json({ sessionId: s.sessionId, vc: s.vc, deviceLinkBase: s.deviceLinkBase }); // s.acsp-ийг серверт хадгал
|
|
79
|
+
|
|
80
|
+
// холбоос: `${deviceLinkBase}?sessionId=<uuid>&vc=<5 орон>` (ж: https://ca.eidmongolia.mn/dl?...)
|
|
81
|
+
import { deviceLink } from "@gerege-systems/eid-mongolia-sdk";
|
|
82
|
+
const link = deviceLink(s);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// браузер — node:*-гүй тусдаа entry
|
|
87
|
+
import { openOrShowQR } from "@gerege-systems/eid-mongolia-sdk/browser";
|
|
88
|
+
|
|
89
|
+
button.onclick = () => {
|
|
90
|
+
// session-ийг урьдчилж авсан байна — энд await хийхгүй
|
|
91
|
+
const how = openOrShowQR(session, { showQR: (link) => renderQr(link) }); // "opened" | "qr"
|
|
92
|
+
showVc(session.vc); // иргэний утсан дээрх кодтой тулгуулна (ПИН биш)
|
|
93
|
+
};
|
|
94
|
+
// дараа нь backend: eid.session.waitForResult(sessionId) → eid.validator.validateAuth(result, s.acsp)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- Гар утас (iOS/Android, desktop UA илгээдэг iPadOS ч) бол `location.assign(link)` — Universal Link / App Link
|
|
98
|
+
аппыг нээнэ; бусад үед `showQR(link)`. Илрүүлэгчийг `isMobile: boolean | () => boolean`-оор солино
|
|
99
|
+
(анхдагч `isMobileUserAgent()`).
|
|
100
|
+
- **Click handler дотроос шууд дууд.** iOS урт async гинжийн (fetch → await → …) дараах навигацийг
|
|
101
|
+
хэрэглэгчийн үйлдэл гэж үзэхгүй, Universal Link-ийг алгасаж `/dl` хуудсыг нээдэг — тэр хуудас
|
|
102
|
+
«Аппаар нээх» товч ба App Store / Play холбоосыг санал болгоно (апп суугаагүй үед ч мөн).
|
|
103
|
+
- `deviceLinkBase` хариунд байхгүй, `sessionId` UUID биш, `vc` 5 орон биш бол `DeviceLinkError` — холбоосыг
|
|
104
|
+
таахгүй. Апп руу custom scheme-ээр шууд бүү холбо — зөвхөн `deviceLink()`-ийн https холбоос.
|
|
105
|
+
|
|
69
106
|
## Аюулгүй байдал — яагаад `validator` заавал
|
|
70
107
|
|
|
71
108
|
`endResult === "OK"` гэдэгт **дангаар нь итгэхгүй**. RP-API эвдэрсэн/proxy хийгдсэн бол хуурамч
|
|
@@ -91,6 +128,7 @@ OK ирж болзошгүй. Иймд `ResponseValidator`:
|
|
|
91
128
|
| `ValidationError` | cert chain/signature/level шалгалт бүтэлгүйтсэн |
|
|
92
129
|
| `ApiError` | бусад HTTP алдаа (`.status`, `.body`) |
|
|
93
130
|
| `NetworkError` | timeout/сүлжээ |
|
|
131
|
+
| `DeviceLinkError` | device-link холбоос угсрах боломжгүй (`deviceLinkBase` байхгүй, sessionId/vc буруу) |
|
|
94
132
|
|
|
95
133
|
## mTLS (eIDAS qualified орчин)
|
|
96
134
|
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/** Сертификатын баталгаажуулалтын түвшин (eIDAS LoA). QUALIFIED — хууль ёсны гарын үсэгт. */
|
|
2
|
+
type CertificateLevel = "ADVANCED" | "QUALIFIED" | "QSCD";
|
|
3
|
+
/** Гарын үсгийн протокол: auth → ACSP_V2, sign → RAW_DIGEST_SIGNATURE (Smart-ID v3). */
|
|
4
|
+
type SignatureProtocol = "ACSP_V2" | "RAW_DIGEST_SIGNATURE";
|
|
5
|
+
/** Гарын үсгийн алгоритм. rsassa-pss анхдагч; ecdsa-with-SHA256 — хуучин threshold-ECDSA cert. */
|
|
6
|
+
type SignatureAlgorithm = "rsassa-pss" | "sha256WithRSAEncryption" | "sha384WithRSAEncryption" | "sha512WithRSAEncryption" | "ecdsa-with-SHA256";
|
|
7
|
+
/** Hash алгоритм (Smart-ID v3 нэршил). Хуучин "SHA256" нэршил SDK-д БАЙХГҮЙ. */
|
|
8
|
+
type HashAlgorithm = "SHA-256" | "SHA-384" | "SHA-512";
|
|
9
|
+
/** Урсгалын төрөл — хариуны signature.flowType; RP өөрийн санал болгосонтой тулгана. */
|
|
10
|
+
type FlowType = "QR" | "App2App" | "Web2App" | "Notification";
|
|
11
|
+
/** rsassa-pss хариуны параметр (signature.signatureAlgorithmParameters). */
|
|
12
|
+
interface SignatureAlgorithmParameters {
|
|
13
|
+
hashAlgorithm: HashAlgorithm | string;
|
|
14
|
+
maskGenAlgorithm?: {
|
|
15
|
+
algorithm: string;
|
|
16
|
+
parameters?: {
|
|
17
|
+
hashAlgorithm: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
saltLength?: number;
|
|
21
|
+
trailerField?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Auth session-ийн ACSP_V2 контекст — RP ХҮСЭЛТЭД илгээсэн утгууд. validator энэ + хариугаар
|
|
25
|
+
* payload-ийг дахин угсарна. Session эхлүүлэхэд SDK өөрөө бөглөнө; RP үүнийг хадгална.
|
|
26
|
+
*/
|
|
27
|
+
interface AcspContext {
|
|
28
|
+
rpChallenge: string;
|
|
29
|
+
relyingPartyName: string;
|
|
30
|
+
brokeredRpName: string;
|
|
31
|
+
/** Илгээсэн base64 МӨР (дахин serialize хийхгүй). */
|
|
32
|
+
interactions: string;
|
|
33
|
+
initialCallbackUrl: string;
|
|
34
|
+
/** RP-ийн санал болгосон урсгалууд — хариуны flowType эдгээрийн нэг байх ёстой. */
|
|
35
|
+
flowTypes: FlowType[];
|
|
36
|
+
signatureAlgorithm: SignatureAlgorithm;
|
|
37
|
+
hashAlgorithm: HashAlgorithm;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Interaction — иргэний утсан дээр харагдах харилцан үйлдэл. displayTextAndPIN нь PIN асууж
|
|
41
|
+
* текст харуулна (хамгийн түгээмэл). text60 — 60 тэмдэгт хүртэл; text200 — 200 хүртэл.
|
|
42
|
+
*/
|
|
43
|
+
interface Interaction {
|
|
44
|
+
type: "displayTextAndPIN" | "confirmationMessage" | "confirmationMessageAndVerificationCodeChoice";
|
|
45
|
+
displayText60?: string;
|
|
46
|
+
displayText200?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Session-ийн төлөв. RUNNING — иргэн хариу өгөөгүй; COMPLETE — дууссан (endResult-ыг үз). */
|
|
49
|
+
type SessionState = "RUNNING" | "COMPLETE";
|
|
50
|
+
/**
|
|
51
|
+
* endResult — COMPLETE session-ийн эцсийн үр дүн.
|
|
52
|
+
* OK — амжилттай (signature/cert бэлэн)
|
|
53
|
+
* USER_REFUSED* — иргэн татгалзсан
|
|
54
|
+
* TIMEOUT — иргэн хугацаанд хариу өгөөгүй
|
|
55
|
+
* DOCUMENT_UNUSABLE — гэрчилгээ/төхөөрөмж ашиглах боломжгүй
|
|
56
|
+
* WRONG_VC — баталгаажуулах код таарсангүй
|
|
57
|
+
*/
|
|
58
|
+
type EndResult = "OK" | "USER_REFUSED" | "USER_REFUSED_DISPLAYTEXTANDPIN" | "USER_REFUSED_VC_CHOICE" | "USER_REFUSED_CONFIRMATIONMESSAGE" | "USER_REFUSED_CERT_CHOICE" | "TIMEOUT" | "DOCUMENT_UNUSABLE" | "WRONG_VC" | "PROTOCOL_FAILURE" | string;
|
|
59
|
+
/**
|
|
60
|
+
* Push (notification) session эхлүүлсний хариу. vc — иргэний дэлгэцэд ХАРУУЛАХ 5 оронтой
|
|
61
|
+
* баталгаажуулах код: утсан дээрх кодтой ижил эсэхийг НҮДЭЭР тулгах зориулалттай.
|
|
62
|
+
*
|
|
63
|
+
* VC нь ПИН БИШ — RP нь үүнийг хэрэглэгчээр оруулуулж болохгүй, зөвхөн харуулна. (PIN1 нь
|
|
64
|
+
* 4 оронтой; VC-г 5 оронтой болгосон нь хэрэглэгч андуурч PIN-ий талбарт оруулаад PIN
|
|
65
|
+
* блок болохоос сэргийлсэн зориудын ялгаа.)
|
|
66
|
+
*/
|
|
67
|
+
interface NotificationSession {
|
|
68
|
+
sessionId: string;
|
|
69
|
+
/** Verification Code — иргэний утсан дээр харагдах код. RP UI-даа ижлийг харуулна (man-in-the-middle хамгаалалт). */
|
|
70
|
+
vc: string | null;
|
|
71
|
+
/** RP-ийн илгээсэн санамсаргүй challenge (base64). Хариуны signature-ийг үүний эсрэг шалгана. */
|
|
72
|
+
rpChallenge: string;
|
|
73
|
+
/** Auth session-д validator-т өгөх контекст (sign session-д undefined). */
|
|
74
|
+
acsp?: AcspContext;
|
|
75
|
+
}
|
|
76
|
+
/** Device-link (QR/App2App) session. Иргэн QR уншиж эсвэл deeplink дарж нэгдэнэ. */
|
|
77
|
+
interface DeviceLinkSession {
|
|
78
|
+
sessionId: string;
|
|
79
|
+
sessionToken: string | null;
|
|
80
|
+
sessionSecret: string | null;
|
|
81
|
+
/**
|
|
82
|
+
* QR/App2App/Web2App холбоосын суурь URL (ж: `https://ca.eidmongolia.mn/dl`). Холбоосыг
|
|
83
|
+
* өөрөө угсрахгүй — {@link deviceLink}-ээр.
|
|
84
|
+
*/
|
|
85
|
+
deviceLinkBase: string | null;
|
|
86
|
+
/**
|
|
87
|
+
* Verification Code (5 оронтой) — иргэний утсан дээр харагдах кодтой НҮДЭЭР тулгахад RP UI-д
|
|
88
|
+
* харуулна. ПИН БИШ. Холбоосын `vc` параметрт мөн орно.
|
|
89
|
+
*/
|
|
90
|
+
vc: string | null;
|
|
91
|
+
rpChallenge: string;
|
|
92
|
+
acsp?: AcspContext;
|
|
93
|
+
}
|
|
94
|
+
/** Session poll-ийн нэгтгэсэн үр дүн (validator-т орох түүхий материал). */
|
|
95
|
+
interface SessionResult {
|
|
96
|
+
state: SessionState | string;
|
|
97
|
+
endResult: EndResult | null;
|
|
98
|
+
documentNumber: string | null;
|
|
99
|
+
/** Иргэний X.509 гэрчилгээ (DER, base64). cert chain validation-д орно. */
|
|
100
|
+
certificateDerB64: string | null;
|
|
101
|
+
certificateLevel: CertificateLevel | string | null;
|
|
102
|
+
/** Гарын үсгийн утга (base64). rpChallenge/digest-ийн эсрэг баталгаажна. */
|
|
103
|
+
signatureValueB64: string | null;
|
|
104
|
+
signatureAlgorithm: string | null;
|
|
105
|
+
signatureProtocol: string | null;
|
|
106
|
+
/** ACSP_V2 (auth): серверийн санамсаргүй (base64), утасны challenge (base64url), урсгал. */
|
|
107
|
+
serverRandom: string | null;
|
|
108
|
+
userChallenge: string | null;
|
|
109
|
+
flowType: string | null;
|
|
110
|
+
signatureAlgorithmParameters: SignatureAlgorithmParameters | null;
|
|
111
|
+
interactionTypeUsed: string | null;
|
|
112
|
+
/**
|
|
113
|
+
* Байгууллагын нэрийн өмнөөс (нэвтрэлт эсвэл гарын үсэг) байсан бол — СЕРВЕР төлөөллийн
|
|
114
|
+
* эрхийг session үүсэх үед шалгасны баталгаа. null бол ердийн хувь хүний session.
|
|
115
|
+
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
116
|
+
*/
|
|
117
|
+
onBehalfOf: OrgResult | null;
|
|
118
|
+
}
|
|
119
|
+
/** Session-ий байгууллагын блок — байгууллага + тухайн иргэний эрх (бүртгэлээс real-time). */
|
|
120
|
+
interface OrgResult {
|
|
121
|
+
/** `NTRMN-<улсын бүртгэлийн дугаар>`. */
|
|
122
|
+
orgEtsi: string;
|
|
123
|
+
orgName: string | null;
|
|
124
|
+
/** Албан тушаал (ж: "Захирал"). Эрх хураагдсан бол null. */
|
|
125
|
+
role: string | null;
|
|
126
|
+
/** ADMIN | MANAGER. Эрх хураагдсан бол null. */
|
|
127
|
+
rightType: string | null;
|
|
128
|
+
}
|
|
129
|
+
/** RP-ийн нэвтрэх мэдээлэл — бүх дуудлагад хэрэгтэй таних тэмдэг + secret. */
|
|
130
|
+
interface RpCredentials {
|
|
131
|
+
/** relying_parties-д бүртгэлтэй RP UUID. */
|
|
132
|
+
rpUUID: string;
|
|
133
|
+
/**
|
|
134
|
+
* Дэд системийн нэр (ж: «Интернэт банк») — CA-д session бүрд хадгалагдана, ≤120 тэмдэгт
|
|
135
|
+
* (сервер илүүг таслана). Иргэний утсан дээр харагдах нэр нь RP-ийн бүртгэлийн нэр.
|
|
136
|
+
*/
|
|
137
|
+
rpName: string;
|
|
138
|
+
/** API secret (rp_sk_…). Зөвхөн backend-д хадгална — браузерт ХЭЗЭЭ Ч задлахгүй. */
|
|
139
|
+
apiSecret: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Холбоос угсрахад хэрэгтэй талбарууд — backend хариунаас браузерт зөвхөн эдгээрийг дамжуулна. */
|
|
143
|
+
type DeviceLinkInput = Pick<DeviceLinkSession, "sessionId" | "vc" | "deviceLinkBase">;
|
|
144
|
+
/**
|
|
145
|
+
* Device-link session-ийн холбоос: `${deviceLinkBase}?sessionId=<uuid>&vc=<код>`.
|
|
146
|
+
* QR-д эсвэл «eID аппаар нээх» товчинд тавина.
|
|
147
|
+
*
|
|
148
|
+
* @throws {DeviceLinkError} deviceLinkBase байхгүй / http(s) биш, sessionId UUID биш, vc 5 орон биш.
|
|
149
|
+
*/
|
|
150
|
+
declare function deviceLink(session: DeviceLinkInput): string;
|
|
151
|
+
/** isMobileUserAgent-ийн уншдаг navigator-ийн хэсэг (тестэд орлуулна). */
|
|
152
|
+
interface NavigatorLike {
|
|
153
|
+
userAgent?: string;
|
|
154
|
+
maxTouchPoints?: number;
|
|
155
|
+
userAgentData?: {
|
|
156
|
+
mobile?: boolean;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Анхдагч гар утас/таблет илрүүлэгч: Android, iPhone/iPod/iPad, UA-CH `mobile`, мөн desktop UA
|
|
161
|
+
* илгээдэг iPadOS (Macintosh + мэдрэгч дэлгэц, maxTouchPoints > 1).
|
|
162
|
+
*/
|
|
163
|
+
declare function isMobileUserAgent(nav?: NavigatorLike): boolean;
|
|
164
|
+
interface OpenOrShowQROptions {
|
|
165
|
+
/** Desktop дээр QR харуулах (link-ийг QR болгох нь RP-ийн UI). */
|
|
166
|
+
showQR: (link: string) => void;
|
|
167
|
+
/** Гар утас эсэх — boolean эсвэл функц. Анхдагч {@link isMobileUserAgent}. */
|
|
168
|
+
isMobile?: boolean | (() => boolean);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Браузерт: гар утсан дээр eID аппыг шууд нээнэ (`location.assign(link)` — Universal Link /
|
|
172
|
+
* App Link), бусад үед `showQR(link)` дуудна. Буцаах утга: `"opened"` эсвэл `"qr"`.
|
|
173
|
+
*
|
|
174
|
+
* (!) Товчны click handler дотроос ШУУД (await-гүйгээр) дууд — session-ийг урьдчилж эхлүүлээд
|
|
175
|
+
* хадгал. iOS урт async гинжийн дараах навигацийг хэрэглэгчийн үйлдэл гэж тооцохгүй тул Universal
|
|
176
|
+
* Link-ийг алгасаж /dl хуудсыг нээдэг; тэр хуудас «Аппаар нээх» товч ба store холбоосыг санал болгоно.
|
|
177
|
+
*
|
|
178
|
+
* @throws {DeviceLinkError} холбоос угсрах боломжгүй бол ({@link deviceLink}).
|
|
179
|
+
*/
|
|
180
|
+
declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROptions): "opened" | "qr";
|
|
181
|
+
|
|
182
|
+
/** Бүх SDK алдааны суурь. */
|
|
183
|
+
declare class EidError extends Error {
|
|
184
|
+
constructor(message: string);
|
|
185
|
+
}
|
|
186
|
+
/** HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. */
|
|
187
|
+
declare class AuthenticationError extends EidError {
|
|
188
|
+
}
|
|
189
|
+
/** HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй. Танай серверийн IP бүртгэгдээгүй байж магадгүй. */
|
|
190
|
+
declare class ForbiddenError extends EidError {
|
|
191
|
+
}
|
|
192
|
+
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
193
|
+
declare class ApiError extends EidError {
|
|
194
|
+
readonly status: number;
|
|
195
|
+
readonly body: string;
|
|
196
|
+
constructor(status: number, body: string);
|
|
197
|
+
}
|
|
198
|
+
/** Сүлжээ/timeout — upstream хариу өгсөнгүй. */
|
|
199
|
+
declare class NetworkError extends EidError {
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
203
|
+
* endResult-оор салгаж RP UI-д тохирох мессеж харуулна.
|
|
204
|
+
*/
|
|
205
|
+
declare class SessionFailedError extends EidError {
|
|
206
|
+
readonly endResult: string;
|
|
207
|
+
constructor(endResult: string);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Хариуны баталгаажуулалт бүтэлгүйтсэн — cert chain итгэлцэлгүй, signature challenge-тэй
|
|
211
|
+
* таарсангүй, эсвэл certLevel хүрэлцээгүй. ЭНЭ алдаа гарвал хариунд ИТГЭХГҮЙ
|
|
212
|
+
* (хуурамч/proxy хийгдсэн байж болзошгүй).
|
|
213
|
+
*/
|
|
214
|
+
declare class ValidationError extends EidError {
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Device-link (App2App/Web2App) холбоос угсрах боломжгүй — хариунд `deviceLinkBase` байхгүй,
|
|
218
|
+
* эсвэл sessionId/vc/суурь URL хэлбэр буруу. Session-ийг дахин эхлүүлнэ; холбоосыг таахгүй.
|
|
219
|
+
*/
|
|
220
|
+
declare class DeviceLinkError extends EidError {
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
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 OpenOrShowQROptions as O, type RpCredentials as R, type SignatureAlgorithm as S, ValidationError as V, type SessionResult as a, ApiError as b, AuthenticationError as c, DeviceLinkError as d, type DeviceLinkInput as e, type EndResult as f, ForbiddenError as g, type NavigatorLike as h, NetworkError as i, SessionFailedError as j, type SessionState as k, type SignatureAlgorithmParameters as l, type SignatureProtocol as m, deviceLink as n, isMobileUserAgent as o, openOrShowQR as p };
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/** Сертификатын баталгаажуулалтын түвшин (eIDAS LoA). QUALIFIED — хууль ёсны гарын үсэгт. */
|
|
2
|
+
type CertificateLevel = "ADVANCED" | "QUALIFIED" | "QSCD";
|
|
3
|
+
/** Гарын үсгийн протокол: auth → ACSP_V2, sign → RAW_DIGEST_SIGNATURE (Smart-ID v3). */
|
|
4
|
+
type SignatureProtocol = "ACSP_V2" | "RAW_DIGEST_SIGNATURE";
|
|
5
|
+
/** Гарын үсгийн алгоритм. rsassa-pss анхдагч; ecdsa-with-SHA256 — хуучин threshold-ECDSA cert. */
|
|
6
|
+
type SignatureAlgorithm = "rsassa-pss" | "sha256WithRSAEncryption" | "sha384WithRSAEncryption" | "sha512WithRSAEncryption" | "ecdsa-with-SHA256";
|
|
7
|
+
/** Hash алгоритм (Smart-ID v3 нэршил). Хуучин "SHA256" нэршил SDK-д БАЙХГҮЙ. */
|
|
8
|
+
type HashAlgorithm = "SHA-256" | "SHA-384" | "SHA-512";
|
|
9
|
+
/** Урсгалын төрөл — хариуны signature.flowType; RP өөрийн санал болгосонтой тулгана. */
|
|
10
|
+
type FlowType = "QR" | "App2App" | "Web2App" | "Notification";
|
|
11
|
+
/** rsassa-pss хариуны параметр (signature.signatureAlgorithmParameters). */
|
|
12
|
+
interface SignatureAlgorithmParameters {
|
|
13
|
+
hashAlgorithm: HashAlgorithm | string;
|
|
14
|
+
maskGenAlgorithm?: {
|
|
15
|
+
algorithm: string;
|
|
16
|
+
parameters?: {
|
|
17
|
+
hashAlgorithm: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
saltLength?: number;
|
|
21
|
+
trailerField?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Auth session-ийн ACSP_V2 контекст — RP ХҮСЭЛТЭД илгээсэн утгууд. validator энэ + хариугаар
|
|
25
|
+
* payload-ийг дахин угсарна. Session эхлүүлэхэд SDK өөрөө бөглөнө; RP үүнийг хадгална.
|
|
26
|
+
*/
|
|
27
|
+
interface AcspContext {
|
|
28
|
+
rpChallenge: string;
|
|
29
|
+
relyingPartyName: string;
|
|
30
|
+
brokeredRpName: string;
|
|
31
|
+
/** Илгээсэн base64 МӨР (дахин serialize хийхгүй). */
|
|
32
|
+
interactions: string;
|
|
33
|
+
initialCallbackUrl: string;
|
|
34
|
+
/** RP-ийн санал болгосон урсгалууд — хариуны flowType эдгээрийн нэг байх ёстой. */
|
|
35
|
+
flowTypes: FlowType[];
|
|
36
|
+
signatureAlgorithm: SignatureAlgorithm;
|
|
37
|
+
hashAlgorithm: HashAlgorithm;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Interaction — иргэний утсан дээр харагдах харилцан үйлдэл. displayTextAndPIN нь PIN асууж
|
|
41
|
+
* текст харуулна (хамгийн түгээмэл). text60 — 60 тэмдэгт хүртэл; text200 — 200 хүртэл.
|
|
42
|
+
*/
|
|
43
|
+
interface Interaction {
|
|
44
|
+
type: "displayTextAndPIN" | "confirmationMessage" | "confirmationMessageAndVerificationCodeChoice";
|
|
45
|
+
displayText60?: string;
|
|
46
|
+
displayText200?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Session-ийн төлөв. RUNNING — иргэн хариу өгөөгүй; COMPLETE — дууссан (endResult-ыг үз). */
|
|
49
|
+
type SessionState = "RUNNING" | "COMPLETE";
|
|
50
|
+
/**
|
|
51
|
+
* endResult — COMPLETE session-ийн эцсийн үр дүн.
|
|
52
|
+
* OK — амжилттай (signature/cert бэлэн)
|
|
53
|
+
* USER_REFUSED* — иргэн татгалзсан
|
|
54
|
+
* TIMEOUT — иргэн хугацаанд хариу өгөөгүй
|
|
55
|
+
* DOCUMENT_UNUSABLE — гэрчилгээ/төхөөрөмж ашиглах боломжгүй
|
|
56
|
+
* WRONG_VC — баталгаажуулах код таарсангүй
|
|
57
|
+
*/
|
|
58
|
+
type EndResult = "OK" | "USER_REFUSED" | "USER_REFUSED_DISPLAYTEXTANDPIN" | "USER_REFUSED_VC_CHOICE" | "USER_REFUSED_CONFIRMATIONMESSAGE" | "USER_REFUSED_CERT_CHOICE" | "TIMEOUT" | "DOCUMENT_UNUSABLE" | "WRONG_VC" | "PROTOCOL_FAILURE" | string;
|
|
59
|
+
/**
|
|
60
|
+
* Push (notification) session эхлүүлсний хариу. vc — иргэний дэлгэцэд ХАРУУЛАХ 5 оронтой
|
|
61
|
+
* баталгаажуулах код: утсан дээрх кодтой ижил эсэхийг НҮДЭЭР тулгах зориулалттай.
|
|
62
|
+
*
|
|
63
|
+
* VC нь ПИН БИШ — RP нь үүнийг хэрэглэгчээр оруулуулж болохгүй, зөвхөн харуулна. (PIN1 нь
|
|
64
|
+
* 4 оронтой; VC-г 5 оронтой болгосон нь хэрэглэгч андуурч PIN-ий талбарт оруулаад PIN
|
|
65
|
+
* блок болохоос сэргийлсэн зориудын ялгаа.)
|
|
66
|
+
*/
|
|
67
|
+
interface NotificationSession {
|
|
68
|
+
sessionId: string;
|
|
69
|
+
/** Verification Code — иргэний утсан дээр харагдах код. RP UI-даа ижлийг харуулна (man-in-the-middle хамгаалалт). */
|
|
70
|
+
vc: string | null;
|
|
71
|
+
/** RP-ийн илгээсэн санамсаргүй challenge (base64). Хариуны signature-ийг үүний эсрэг шалгана. */
|
|
72
|
+
rpChallenge: string;
|
|
73
|
+
/** Auth session-д validator-т өгөх контекст (sign session-д undefined). */
|
|
74
|
+
acsp?: AcspContext;
|
|
75
|
+
}
|
|
76
|
+
/** Device-link (QR/App2App) session. Иргэн QR уншиж эсвэл deeplink дарж нэгдэнэ. */
|
|
77
|
+
interface DeviceLinkSession {
|
|
78
|
+
sessionId: string;
|
|
79
|
+
sessionToken: string | null;
|
|
80
|
+
sessionSecret: string | null;
|
|
81
|
+
/**
|
|
82
|
+
* QR/App2App/Web2App холбоосын суурь URL (ж: `https://ca.eidmongolia.mn/dl`). Холбоосыг
|
|
83
|
+
* өөрөө угсрахгүй — {@link deviceLink}-ээр.
|
|
84
|
+
*/
|
|
85
|
+
deviceLinkBase: string | null;
|
|
86
|
+
/**
|
|
87
|
+
* Verification Code (5 оронтой) — иргэний утсан дээр харагдах кодтой НҮДЭЭР тулгахад RP UI-д
|
|
88
|
+
* харуулна. ПИН БИШ. Холбоосын `vc` параметрт мөн орно.
|
|
89
|
+
*/
|
|
90
|
+
vc: string | null;
|
|
91
|
+
rpChallenge: string;
|
|
92
|
+
acsp?: AcspContext;
|
|
93
|
+
}
|
|
94
|
+
/** Session poll-ийн нэгтгэсэн үр дүн (validator-т орох түүхий материал). */
|
|
95
|
+
interface SessionResult {
|
|
96
|
+
state: SessionState | string;
|
|
97
|
+
endResult: EndResult | null;
|
|
98
|
+
documentNumber: string | null;
|
|
99
|
+
/** Иргэний X.509 гэрчилгээ (DER, base64). cert chain validation-д орно. */
|
|
100
|
+
certificateDerB64: string | null;
|
|
101
|
+
certificateLevel: CertificateLevel | string | null;
|
|
102
|
+
/** Гарын үсгийн утга (base64). rpChallenge/digest-ийн эсрэг баталгаажна. */
|
|
103
|
+
signatureValueB64: string | null;
|
|
104
|
+
signatureAlgorithm: string | null;
|
|
105
|
+
signatureProtocol: string | null;
|
|
106
|
+
/** ACSP_V2 (auth): серверийн санамсаргүй (base64), утасны challenge (base64url), урсгал. */
|
|
107
|
+
serverRandom: string | null;
|
|
108
|
+
userChallenge: string | null;
|
|
109
|
+
flowType: string | null;
|
|
110
|
+
signatureAlgorithmParameters: SignatureAlgorithmParameters | null;
|
|
111
|
+
interactionTypeUsed: string | null;
|
|
112
|
+
/**
|
|
113
|
+
* Байгууллагын нэрийн өмнөөс (нэвтрэлт эсвэл гарын үсэг) байсан бол — СЕРВЕР төлөөллийн
|
|
114
|
+
* эрхийг session үүсэх үед шалгасны баталгаа. null бол ердийн хувь хүний session.
|
|
115
|
+
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
116
|
+
*/
|
|
117
|
+
onBehalfOf: OrgResult | null;
|
|
118
|
+
}
|
|
119
|
+
/** Session-ий байгууллагын блок — байгууллага + тухайн иргэний эрх (бүртгэлээс real-time). */
|
|
120
|
+
interface OrgResult {
|
|
121
|
+
/** `NTRMN-<улсын бүртгэлийн дугаар>`. */
|
|
122
|
+
orgEtsi: string;
|
|
123
|
+
orgName: string | null;
|
|
124
|
+
/** Албан тушаал (ж: "Захирал"). Эрх хураагдсан бол null. */
|
|
125
|
+
role: string | null;
|
|
126
|
+
/** ADMIN | MANAGER. Эрх хураагдсан бол null. */
|
|
127
|
+
rightType: string | null;
|
|
128
|
+
}
|
|
129
|
+
/** RP-ийн нэвтрэх мэдээлэл — бүх дуудлагад хэрэгтэй таних тэмдэг + secret. */
|
|
130
|
+
interface RpCredentials {
|
|
131
|
+
/** relying_parties-д бүртгэлтэй RP UUID. */
|
|
132
|
+
rpUUID: string;
|
|
133
|
+
/**
|
|
134
|
+
* Дэд системийн нэр (ж: «Интернэт банк») — CA-д session бүрд хадгалагдана, ≤120 тэмдэгт
|
|
135
|
+
* (сервер илүүг таслана). Иргэний утсан дээр харагдах нэр нь RP-ийн бүртгэлийн нэр.
|
|
136
|
+
*/
|
|
137
|
+
rpName: string;
|
|
138
|
+
/** API secret (rp_sk_…). Зөвхөн backend-д хадгална — браузерт ХЭЗЭЭ Ч задлахгүй. */
|
|
139
|
+
apiSecret: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Холбоос угсрахад хэрэгтэй талбарууд — backend хариунаас браузерт зөвхөн эдгээрийг дамжуулна. */
|
|
143
|
+
type DeviceLinkInput = Pick<DeviceLinkSession, "sessionId" | "vc" | "deviceLinkBase">;
|
|
144
|
+
/**
|
|
145
|
+
* Device-link session-ийн холбоос: `${deviceLinkBase}?sessionId=<uuid>&vc=<код>`.
|
|
146
|
+
* QR-д эсвэл «eID аппаар нээх» товчинд тавина.
|
|
147
|
+
*
|
|
148
|
+
* @throws {DeviceLinkError} deviceLinkBase байхгүй / http(s) биш, sessionId UUID биш, vc 5 орон биш.
|
|
149
|
+
*/
|
|
150
|
+
declare function deviceLink(session: DeviceLinkInput): string;
|
|
151
|
+
/** isMobileUserAgent-ийн уншдаг navigator-ийн хэсэг (тестэд орлуулна). */
|
|
152
|
+
interface NavigatorLike {
|
|
153
|
+
userAgent?: string;
|
|
154
|
+
maxTouchPoints?: number;
|
|
155
|
+
userAgentData?: {
|
|
156
|
+
mobile?: boolean;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Анхдагч гар утас/таблет илрүүлэгч: Android, iPhone/iPod/iPad, UA-CH `mobile`, мөн desktop UA
|
|
161
|
+
* илгээдэг iPadOS (Macintosh + мэдрэгч дэлгэц, maxTouchPoints > 1).
|
|
162
|
+
*/
|
|
163
|
+
declare function isMobileUserAgent(nav?: NavigatorLike): boolean;
|
|
164
|
+
interface OpenOrShowQROptions {
|
|
165
|
+
/** Desktop дээр QR харуулах (link-ийг QR болгох нь RP-ийн UI). */
|
|
166
|
+
showQR: (link: string) => void;
|
|
167
|
+
/** Гар утас эсэх — boolean эсвэл функц. Анхдагч {@link isMobileUserAgent}. */
|
|
168
|
+
isMobile?: boolean | (() => boolean);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Браузерт: гар утсан дээр eID аппыг шууд нээнэ (`location.assign(link)` — Universal Link /
|
|
172
|
+
* App Link), бусад үед `showQR(link)` дуудна. Буцаах утга: `"opened"` эсвэл `"qr"`.
|
|
173
|
+
*
|
|
174
|
+
* (!) Товчны click handler дотроос ШУУД (await-гүйгээр) дууд — session-ийг урьдчилж эхлүүлээд
|
|
175
|
+
* хадгал. iOS урт async гинжийн дараах навигацийг хэрэглэгчийн үйлдэл гэж тооцохгүй тул Universal
|
|
176
|
+
* Link-ийг алгасаж /dl хуудсыг нээдэг; тэр хуудас «Аппаар нээх» товч ба store холбоосыг санал болгоно.
|
|
177
|
+
*
|
|
178
|
+
* @throws {DeviceLinkError} холбоос угсрах боломжгүй бол ({@link deviceLink}).
|
|
179
|
+
*/
|
|
180
|
+
declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROptions): "opened" | "qr";
|
|
181
|
+
|
|
182
|
+
/** Бүх SDK алдааны суурь. */
|
|
183
|
+
declare class EidError extends Error {
|
|
184
|
+
constructor(message: string);
|
|
185
|
+
}
|
|
186
|
+
/** HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. */
|
|
187
|
+
declare class AuthenticationError extends EidError {
|
|
188
|
+
}
|
|
189
|
+
/** HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй. Танай серверийн IP бүртгэгдээгүй байж магадгүй. */
|
|
190
|
+
declare class ForbiddenError extends EidError {
|
|
191
|
+
}
|
|
192
|
+
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
193
|
+
declare class ApiError extends EidError {
|
|
194
|
+
readonly status: number;
|
|
195
|
+
readonly body: string;
|
|
196
|
+
constructor(status: number, body: string);
|
|
197
|
+
}
|
|
198
|
+
/** Сүлжээ/timeout — upstream хариу өгсөнгүй. */
|
|
199
|
+
declare class NetworkError extends EidError {
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
203
|
+
* endResult-оор салгаж RP UI-д тохирох мессеж харуулна.
|
|
204
|
+
*/
|
|
205
|
+
declare class SessionFailedError extends EidError {
|
|
206
|
+
readonly endResult: string;
|
|
207
|
+
constructor(endResult: string);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Хариуны баталгаажуулалт бүтэлгүйтсэн — cert chain итгэлцэлгүй, signature challenge-тэй
|
|
211
|
+
* таарсангүй, эсвэл certLevel хүрэлцээгүй. ЭНЭ алдаа гарвал хариунд ИТГЭХГҮЙ
|
|
212
|
+
* (хуурамч/proxy хийгдсэн байж болзошгүй).
|
|
213
|
+
*/
|
|
214
|
+
declare class ValidationError extends EidError {
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Device-link (App2App/Web2App) холбоос угсрах боломжгүй — хариунд `deviceLinkBase` байхгүй,
|
|
218
|
+
* эсвэл sessionId/vc/суурь URL хэлбэр буруу. Session-ийг дахин эхлүүлнэ; холбоосыг таахгүй.
|
|
219
|
+
*/
|
|
220
|
+
declare class DeviceLinkError extends EidError {
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
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 OpenOrShowQROptions as O, type RpCredentials as R, type SignatureAlgorithm as S, ValidationError as V, type SessionResult as a, ApiError as b, AuthenticationError as c, DeviceLinkError as d, type DeviceLinkInput as e, type EndResult as f, ForbiddenError as g, type NavigatorLike as h, NetworkError as i, SessionFailedError as j, type SessionState as k, type SignatureAlgorithmParameters as l, type SignatureProtocol as m, deviceLink as n, isMobileUserAgent as o, openOrShowQR as p };
|
package/dist/browser.cjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/browser.ts
|
|
21
|
+
var browser_exports = {};
|
|
22
|
+
__export(browser_exports, {
|
|
23
|
+
DeviceLinkError: () => DeviceLinkError,
|
|
24
|
+
EidError: () => EidError,
|
|
25
|
+
deviceLink: () => deviceLink,
|
|
26
|
+
isMobileUserAgent: () => isMobileUserAgent,
|
|
27
|
+
openOrShowQR: () => openOrShowQR
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(browser_exports);
|
|
30
|
+
|
|
31
|
+
// src/errors.ts
|
|
32
|
+
var EidError = class extends Error {
|
|
33
|
+
constructor(message) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = new.target.name;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var DeviceLinkError = class extends EidError {
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// src/devicelink.ts
|
|
42
|
+
var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
43
|
+
var VC_RE = /^[0-9]{5}$/;
|
|
44
|
+
function deviceLink(session) {
|
|
45
|
+
const base = session.deviceLinkBase?.trim();
|
|
46
|
+
if (!base) throw new DeviceLinkError("deviceLink: \u0445\u0430\u0440\u0438\u0443\u043D\u0434 deviceLinkBase \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 device-link session \u044D\u0441\u044D\u0445\u0438\u0439\u0433 \u0448\u0430\u043B\u0433\u0430");
|
|
47
|
+
let u;
|
|
48
|
+
try {
|
|
49
|
+
u = new URL(base);
|
|
50
|
+
} catch {
|
|
51
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase \u0431\u0443\u0440\u0443\u0443 URL: ${base}`);
|
|
52
|
+
}
|
|
53
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") {
|
|
54
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase https URL \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439: ${u.protocol}`);
|
|
55
|
+
}
|
|
56
|
+
if (!SESSION_ID_RE.test(session.sessionId)) throw new DeviceLinkError("deviceLink: sessionId UUID (lowercase) \u0431\u0438\u0448");
|
|
57
|
+
if (session.vc == null || !VC_RE.test(session.vc)) throw new DeviceLinkError("deviceLink: vc 5 \u043E\u0440\u043E\u043D\u0442\u043E\u0439 \u0442\u043E\u043E \u0431\u0438\u0448");
|
|
58
|
+
u.searchParams.set("sessionId", session.sessionId);
|
|
59
|
+
u.searchParams.set("vc", session.vc);
|
|
60
|
+
return u.toString();
|
|
61
|
+
}
|
|
62
|
+
function isMobileUserAgent(nav) {
|
|
63
|
+
const n = nav ?? globalThis.navigator;
|
|
64
|
+
if (!n) return false;
|
|
65
|
+
if (n.userAgentData?.mobile === true) return true;
|
|
66
|
+
const ua = n.userAgent ?? "";
|
|
67
|
+
if (/Android|iPhone|iPod|iPad/i.test(ua)) return true;
|
|
68
|
+
return /Macintosh/.test(ua) && (n.maxTouchPoints ?? 0) > 1;
|
|
69
|
+
}
|
|
70
|
+
function openOrShowQR(session, opts) {
|
|
71
|
+
const link = deviceLink(session);
|
|
72
|
+
const mobile = typeof opts.isMobile === "function" ? opts.isMobile() : opts.isMobile ?? isMobileUserAgent();
|
|
73
|
+
if (mobile) {
|
|
74
|
+
const loc = globalThis.location;
|
|
75
|
+
if (!loc) throw new DeviceLinkError("openOrShowQR: location \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 \u0437\u04E9\u0432\u0445\u04E9\u043D \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0442");
|
|
76
|
+
loc.assign(link);
|
|
77
|
+
return "opened";
|
|
78
|
+
}
|
|
79
|
+
opts.showQR(link);
|
|
80
|
+
return "qr";
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
DeviceLinkError,
|
|
85
|
+
EidError,
|
|
86
|
+
deviceLink,
|
|
87
|
+
isMobileUserAgent,
|
|
88
|
+
openOrShowQR
|
|
89
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { d as DeviceLinkError, e as DeviceLinkInput, D as DeviceLinkSession, E as EidError, h as NavigatorLike, O as OpenOrShowQROptions, n as deviceLink, o as isMobileUserAgent, p as openOrShowQR } from './browser-BS8JwSQk.cjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { d as DeviceLinkError, e as DeviceLinkInput, D as DeviceLinkSession, E as EidError, h as NavigatorLike, O as OpenOrShowQROptions, n as deviceLink, o as isMobileUserAgent, p as openOrShowQR } from './browser-BS8JwSQk.js';
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var EidError = class extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = new.target.name;
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
var AuthenticationError = class extends EidError {
|
|
9
|
+
};
|
|
10
|
+
var ForbiddenError = class extends EidError {
|
|
11
|
+
};
|
|
12
|
+
var ApiError = class extends EidError {
|
|
13
|
+
constructor(status, body) {
|
|
14
|
+
super(`RP-API ${status}: ${body}`);
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.body = body;
|
|
17
|
+
}
|
|
18
|
+
status;
|
|
19
|
+
body;
|
|
20
|
+
};
|
|
21
|
+
var NetworkError = class extends EidError {
|
|
22
|
+
};
|
|
23
|
+
var SessionFailedError = class extends EidError {
|
|
24
|
+
constructor(endResult) {
|
|
25
|
+
super(`Session \u0430\u043C\u0436\u0438\u043B\u0442\u0433\u04AF\u0439: ${endResult}`);
|
|
26
|
+
this.endResult = endResult;
|
|
27
|
+
}
|
|
28
|
+
endResult;
|
|
29
|
+
};
|
|
30
|
+
var ValidationError = class extends EidError {
|
|
31
|
+
};
|
|
32
|
+
var DeviceLinkError = class extends EidError {
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/devicelink.ts
|
|
36
|
+
var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
37
|
+
var VC_RE = /^[0-9]{5}$/;
|
|
38
|
+
function deviceLink(session) {
|
|
39
|
+
const base = session.deviceLinkBase?.trim();
|
|
40
|
+
if (!base) throw new DeviceLinkError("deviceLink: \u0445\u0430\u0440\u0438\u0443\u043D\u0434 deviceLinkBase \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 device-link session \u044D\u0441\u044D\u0445\u0438\u0439\u0433 \u0448\u0430\u043B\u0433\u0430");
|
|
41
|
+
let u;
|
|
42
|
+
try {
|
|
43
|
+
u = new URL(base);
|
|
44
|
+
} catch {
|
|
45
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase \u0431\u0443\u0440\u0443\u0443 URL: ${base}`);
|
|
46
|
+
}
|
|
47
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") {
|
|
48
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase https URL \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439: ${u.protocol}`);
|
|
49
|
+
}
|
|
50
|
+
if (!SESSION_ID_RE.test(session.sessionId)) throw new DeviceLinkError("deviceLink: sessionId UUID (lowercase) \u0431\u0438\u0448");
|
|
51
|
+
if (session.vc == null || !VC_RE.test(session.vc)) throw new DeviceLinkError("deviceLink: vc 5 \u043E\u0440\u043E\u043D\u0442\u043E\u0439 \u0442\u043E\u043E \u0431\u0438\u0448");
|
|
52
|
+
u.searchParams.set("sessionId", session.sessionId);
|
|
53
|
+
u.searchParams.set("vc", session.vc);
|
|
54
|
+
return u.toString();
|
|
55
|
+
}
|
|
56
|
+
function isMobileUserAgent(nav) {
|
|
57
|
+
const n = nav ?? globalThis.navigator;
|
|
58
|
+
if (!n) return false;
|
|
59
|
+
if (n.userAgentData?.mobile === true) return true;
|
|
60
|
+
const ua = n.userAgent ?? "";
|
|
61
|
+
if (/Android|iPhone|iPod|iPad/i.test(ua)) return true;
|
|
62
|
+
return /Macintosh/.test(ua) && (n.maxTouchPoints ?? 0) > 1;
|
|
63
|
+
}
|
|
64
|
+
function openOrShowQR(session, opts) {
|
|
65
|
+
const link = deviceLink(session);
|
|
66
|
+
const mobile = typeof opts.isMobile === "function" ? opts.isMobile() : opts.isMobile ?? isMobileUserAgent();
|
|
67
|
+
if (mobile) {
|
|
68
|
+
const loc = globalThis.location;
|
|
69
|
+
if (!loc) throw new DeviceLinkError("openOrShowQR: location \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 \u0437\u04E9\u0432\u0445\u04E9\u043D \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0442");
|
|
70
|
+
loc.assign(link);
|
|
71
|
+
return "opened";
|
|
72
|
+
}
|
|
73
|
+
opts.showQR(link);
|
|
74
|
+
return "qr";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
EidError,
|
|
79
|
+
AuthenticationError,
|
|
80
|
+
ForbiddenError,
|
|
81
|
+
ApiError,
|
|
82
|
+
NetworkError,
|
|
83
|
+
SessionFailedError,
|
|
84
|
+
ValidationError,
|
|
85
|
+
DeviceLinkError,
|
|
86
|
+
deviceLink,
|
|
87
|
+
isMobileUserAgent,
|
|
88
|
+
openOrShowQR
|
|
89
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
AuthApi: () => AuthApi,
|
|
25
25
|
AuthenticationError: () => AuthenticationError,
|
|
26
26
|
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
|
|
27
|
+
DeviceLinkError: () => DeviceLinkError,
|
|
27
28
|
EidClient: () => EidClient,
|
|
28
29
|
EidError: () => EidError,
|
|
29
30
|
ForbiddenError: () => ForbiddenError,
|
|
@@ -36,7 +37,10 @@ __export(index_exports, {
|
|
|
36
37
|
ValidationError: () => ValidationError,
|
|
37
38
|
acspV2Digest: () => acspV2Digest,
|
|
38
39
|
buildAcspV2Payload: () => buildAcspV2Payload,
|
|
40
|
+
deviceLink: () => deviceLink,
|
|
39
41
|
interactionsToBase64: () => interactionsToBase64,
|
|
42
|
+
isMobileUserAgent: () => isMobileUserAgent,
|
|
43
|
+
openOrShowQR: () => openOrShowQR,
|
|
40
44
|
parseSessionResult: () => parseSessionResult,
|
|
41
45
|
randomChallenge: () => randomChallenge,
|
|
42
46
|
resolveBaseUrl: () => resolveBaseUrl,
|
|
@@ -77,6 +81,8 @@ var SessionFailedError = class extends EidError {
|
|
|
77
81
|
};
|
|
78
82
|
var ValidationError = class extends EidError {
|
|
79
83
|
};
|
|
84
|
+
var DeviceLinkError = class extends EidError {
|
|
85
|
+
};
|
|
80
86
|
|
|
81
87
|
// src/http.ts
|
|
82
88
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
@@ -209,11 +215,13 @@ var AuthApi = class {
|
|
|
209
215
|
}
|
|
210
216
|
parseDeviceLink(raw, acsp) {
|
|
211
217
|
const r = rec(raw);
|
|
218
|
+
const vc = typeof r.vc === "object" && r.vc !== null ? rec(r.vc).value : r.vc;
|
|
212
219
|
return {
|
|
213
220
|
sessionId: String(r.sessionID),
|
|
214
221
|
sessionToken: r.sessionToken != null ? String(r.sessionToken) : null,
|
|
215
222
|
sessionSecret: r.sessionSecret != null ? String(r.sessionSecret) : null,
|
|
216
223
|
deviceLinkBase: r.deviceLinkBase != null ? String(r.deviceLinkBase) : null,
|
|
224
|
+
vc: vc != null ? String(vc) : null,
|
|
217
225
|
rpChallenge: acsp.rpChallenge,
|
|
218
226
|
acsp
|
|
219
227
|
};
|
|
@@ -732,12 +740,55 @@ var EidClient = class {
|
|
|
732
740
|
this.validator = new ResponseValidator(cfg.trust ?? {});
|
|
733
741
|
}
|
|
734
742
|
};
|
|
743
|
+
|
|
744
|
+
// src/devicelink.ts
|
|
745
|
+
var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
746
|
+
var VC_RE = /^[0-9]{5}$/;
|
|
747
|
+
function deviceLink(session) {
|
|
748
|
+
const base = session.deviceLinkBase?.trim();
|
|
749
|
+
if (!base) throw new DeviceLinkError("deviceLink: \u0445\u0430\u0440\u0438\u0443\u043D\u0434 deviceLinkBase \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 device-link session \u044D\u0441\u044D\u0445\u0438\u0439\u0433 \u0448\u0430\u043B\u0433\u0430");
|
|
750
|
+
let u;
|
|
751
|
+
try {
|
|
752
|
+
u = new URL(base);
|
|
753
|
+
} catch {
|
|
754
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase \u0431\u0443\u0440\u0443\u0443 URL: ${base}`);
|
|
755
|
+
}
|
|
756
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") {
|
|
757
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase https URL \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439: ${u.protocol}`);
|
|
758
|
+
}
|
|
759
|
+
if (!SESSION_ID_RE.test(session.sessionId)) throw new DeviceLinkError("deviceLink: sessionId UUID (lowercase) \u0431\u0438\u0448");
|
|
760
|
+
if (session.vc == null || !VC_RE.test(session.vc)) throw new DeviceLinkError("deviceLink: vc 5 \u043E\u0440\u043E\u043D\u0442\u043E\u0439 \u0442\u043E\u043E \u0431\u0438\u0448");
|
|
761
|
+
u.searchParams.set("sessionId", session.sessionId);
|
|
762
|
+
u.searchParams.set("vc", session.vc);
|
|
763
|
+
return u.toString();
|
|
764
|
+
}
|
|
765
|
+
function isMobileUserAgent(nav) {
|
|
766
|
+
const n = nav ?? globalThis.navigator;
|
|
767
|
+
if (!n) return false;
|
|
768
|
+
if (n.userAgentData?.mobile === true) return true;
|
|
769
|
+
const ua = n.userAgent ?? "";
|
|
770
|
+
if (/Android|iPhone|iPod|iPad/i.test(ua)) return true;
|
|
771
|
+
return /Macintosh/.test(ua) && (n.maxTouchPoints ?? 0) > 1;
|
|
772
|
+
}
|
|
773
|
+
function openOrShowQR(session, opts) {
|
|
774
|
+
const link = deviceLink(session);
|
|
775
|
+
const mobile = typeof opts.isMobile === "function" ? opts.isMobile() : opts.isMobile ?? isMobileUserAgent();
|
|
776
|
+
if (mobile) {
|
|
777
|
+
const loc = globalThis.location;
|
|
778
|
+
if (!loc) throw new DeviceLinkError("openOrShowQR: location \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 \u0437\u04E9\u0432\u0445\u04E9\u043D \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0442");
|
|
779
|
+
loc.assign(link);
|
|
780
|
+
return "opened";
|
|
781
|
+
}
|
|
782
|
+
opts.showQR(link);
|
|
783
|
+
return "qr";
|
|
784
|
+
}
|
|
735
785
|
// Annotate the CommonJS export names for ESM import in node:
|
|
736
786
|
0 && (module.exports = {
|
|
737
787
|
ApiError,
|
|
738
788
|
AuthApi,
|
|
739
789
|
AuthenticationError,
|
|
740
790
|
DEFAULT_BASE_URL,
|
|
791
|
+
DeviceLinkError,
|
|
741
792
|
EidClient,
|
|
742
793
|
EidError,
|
|
743
794
|
ForbiddenError,
|
|
@@ -750,7 +801,10 @@ var EidClient = class {
|
|
|
750
801
|
ValidationError,
|
|
751
802
|
acspV2Digest,
|
|
752
803
|
buildAcspV2Payload,
|
|
804
|
+
deviceLink,
|
|
753
805
|
interactionsToBase64,
|
|
806
|
+
isMobileUserAgent,
|
|
807
|
+
openOrShowQR,
|
|
754
808
|
parseSessionResult,
|
|
755
809
|
randomChallenge,
|
|
756
810
|
resolveBaseUrl,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +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, A as AcspContext, F as FlowType } from './browser-BS8JwSQk.cjs';
|
|
2
|
+
export { b as ApiError, c as AuthenticationError, d as DeviceLinkError, e as DeviceLinkInput, E as EidError, f as EndResult, g as ForbiddenError, h as NavigatorLike, i as NetworkError, O as OpenOrShowQROptions, j as SessionFailedError, k as SessionState, l as SignatureAlgorithmParameters, m as SignatureProtocol, V as ValidationError, n as deviceLink, o as isMobileUserAgent, p as openOrShowQR } from './browser-BS8JwSQk.cjs';
|
|
1
3
|
import { X509Certificate, KeyObject } from 'node:crypto';
|
|
2
4
|
|
|
3
5
|
interface HttpConfig {
|
|
@@ -24,139 +26,6 @@ declare class Http {
|
|
|
24
26
|
private request;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
/** Сертификатын баталгаажуулалтын түвшин (eIDAS LoA). QUALIFIED — хууль ёсны гарын үсэгт. */
|
|
28
|
-
type CertificateLevel = "ADVANCED" | "QUALIFIED" | "QSCD";
|
|
29
|
-
/** Гарын үсгийн протокол: auth → ACSP_V2, sign → RAW_DIGEST_SIGNATURE (Smart-ID v3). */
|
|
30
|
-
type SignatureProtocol = "ACSP_V2" | "RAW_DIGEST_SIGNATURE";
|
|
31
|
-
/** Гарын үсгийн алгоритм. rsassa-pss анхдагч; ecdsa-with-SHA256 — хуучин threshold-ECDSA cert. */
|
|
32
|
-
type SignatureAlgorithm = "rsassa-pss" | "sha256WithRSAEncryption" | "sha384WithRSAEncryption" | "sha512WithRSAEncryption" | "ecdsa-with-SHA256";
|
|
33
|
-
/** Hash алгоритм (Smart-ID v3 нэршил). Хуучин "SHA256" нэршил SDK-д БАЙХГҮЙ. */
|
|
34
|
-
type HashAlgorithm = "SHA-256" | "SHA-384" | "SHA-512";
|
|
35
|
-
/** Урсгалын төрөл — хариуны signature.flowType; RP өөрийн санал болгосонтой тулгана. */
|
|
36
|
-
type FlowType = "QR" | "App2App" | "Web2App" | "Notification";
|
|
37
|
-
/** rsassa-pss хариуны параметр (signature.signatureAlgorithmParameters). */
|
|
38
|
-
interface SignatureAlgorithmParameters {
|
|
39
|
-
hashAlgorithm: HashAlgorithm | string;
|
|
40
|
-
maskGenAlgorithm?: {
|
|
41
|
-
algorithm: string;
|
|
42
|
-
parameters?: {
|
|
43
|
-
hashAlgorithm: string;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
saltLength?: number;
|
|
47
|
-
trailerField?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Auth session-ийн ACSP_V2 контекст — RP ХҮСЭЛТЭД илгээсэн утгууд. validator энэ + хариугаар
|
|
51
|
-
* payload-ийг дахин угсарна. Session эхлүүлэхэд SDK өөрөө бөглөнө; RP үүнийг хадгална.
|
|
52
|
-
*/
|
|
53
|
-
interface AcspContext {
|
|
54
|
-
rpChallenge: string;
|
|
55
|
-
relyingPartyName: string;
|
|
56
|
-
brokeredRpName: string;
|
|
57
|
-
/** Илгээсэн base64 МӨР (дахин serialize хийхгүй). */
|
|
58
|
-
interactions: string;
|
|
59
|
-
initialCallbackUrl: string;
|
|
60
|
-
/** RP-ийн санал болгосон урсгалууд — хариуны flowType эдгээрийн нэг байх ёстой. */
|
|
61
|
-
flowTypes: FlowType[];
|
|
62
|
-
signatureAlgorithm: SignatureAlgorithm;
|
|
63
|
-
hashAlgorithm: HashAlgorithm;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Interaction — иргэний утсан дээр харагдах харилцан үйлдэл. displayTextAndPIN нь PIN асууж
|
|
67
|
-
* текст харуулна (хамгийн түгээмэл). text60 — 60 тэмдэгт хүртэл; text200 — 200 хүртэл.
|
|
68
|
-
*/
|
|
69
|
-
interface Interaction {
|
|
70
|
-
type: "displayTextAndPIN" | "confirmationMessage" | "confirmationMessageAndVerificationCodeChoice";
|
|
71
|
-
displayText60?: string;
|
|
72
|
-
displayText200?: string;
|
|
73
|
-
}
|
|
74
|
-
/** Session-ийн төлөв. RUNNING — иргэн хариу өгөөгүй; COMPLETE — дууссан (endResult-ыг үз). */
|
|
75
|
-
type SessionState = "RUNNING" | "COMPLETE";
|
|
76
|
-
/**
|
|
77
|
-
* endResult — COMPLETE session-ийн эцсийн үр дүн.
|
|
78
|
-
* OK — амжилттай (signature/cert бэлэн)
|
|
79
|
-
* USER_REFUSED* — иргэн татгалзсан
|
|
80
|
-
* TIMEOUT — иргэн хугацаанд хариу өгөөгүй
|
|
81
|
-
* DOCUMENT_UNUSABLE — гэрчилгээ/төхөөрөмж ашиглах боломжгүй
|
|
82
|
-
* WRONG_VC — баталгаажуулах код таарсангүй
|
|
83
|
-
*/
|
|
84
|
-
type EndResult = "OK" | "USER_REFUSED" | "USER_REFUSED_DISPLAYTEXTANDPIN" | "USER_REFUSED_VC_CHOICE" | "USER_REFUSED_CONFIRMATIONMESSAGE" | "USER_REFUSED_CERT_CHOICE" | "TIMEOUT" | "DOCUMENT_UNUSABLE" | "WRONG_VC" | "PROTOCOL_FAILURE" | string;
|
|
85
|
-
/**
|
|
86
|
-
* Push (notification) session эхлүүлсний хариу. vc — иргэний дэлгэцэд ХАРУУЛАХ 5 оронтой
|
|
87
|
-
* баталгаажуулах код: утсан дээрх кодтой ижил эсэхийг НҮДЭЭР тулгах зориулалттай.
|
|
88
|
-
*
|
|
89
|
-
* VC нь ПИН БИШ — RP нь үүнийг хэрэглэгчээр оруулуулж болохгүй, зөвхөн харуулна. (PIN1 нь
|
|
90
|
-
* 4 оронтой; VC-г 5 оронтой болгосон нь хэрэглэгч андуурч PIN-ий талбарт оруулаад PIN
|
|
91
|
-
* блок болохоос сэргийлсэн зориудын ялгаа.)
|
|
92
|
-
*/
|
|
93
|
-
interface NotificationSession {
|
|
94
|
-
sessionId: string;
|
|
95
|
-
/** Verification Code — иргэний утсан дээр харагдах код. RP UI-даа ижлийг харуулна (man-in-the-middle хамгаалалт). */
|
|
96
|
-
vc: string | null;
|
|
97
|
-
/** RP-ийн илгээсэн санамсаргүй challenge (base64). Хариуны signature-ийг үүний эсрэг шалгана. */
|
|
98
|
-
rpChallenge: string;
|
|
99
|
-
/** Auth session-д validator-т өгөх контекст (sign session-д undefined). */
|
|
100
|
-
acsp?: AcspContext;
|
|
101
|
-
}
|
|
102
|
-
/** Device-link (QR/App2App) session. Иргэн QR уншиж эсвэл deeplink дарж нэгдэнэ. */
|
|
103
|
-
interface DeviceLinkSession {
|
|
104
|
-
sessionId: string;
|
|
105
|
-
sessionToken: string | null;
|
|
106
|
-
sessionSecret: string | null;
|
|
107
|
-
/** QR/deeplink үүсгэх суурь URL. */
|
|
108
|
-
deviceLinkBase: string | null;
|
|
109
|
-
rpChallenge: string;
|
|
110
|
-
acsp?: AcspContext;
|
|
111
|
-
}
|
|
112
|
-
/** Session poll-ийн нэгтгэсэн үр дүн (validator-т орох түүхий материал). */
|
|
113
|
-
interface SessionResult {
|
|
114
|
-
state: SessionState | string;
|
|
115
|
-
endResult: EndResult | null;
|
|
116
|
-
documentNumber: string | null;
|
|
117
|
-
/** Иргэний X.509 гэрчилгээ (DER, base64). cert chain validation-д орно. */
|
|
118
|
-
certificateDerB64: string | null;
|
|
119
|
-
certificateLevel: CertificateLevel | string | null;
|
|
120
|
-
/** Гарын үсгийн утга (base64). rpChallenge/digest-ийн эсрэг баталгаажна. */
|
|
121
|
-
signatureValueB64: string | null;
|
|
122
|
-
signatureAlgorithm: string | null;
|
|
123
|
-
signatureProtocol: string | null;
|
|
124
|
-
/** ACSP_V2 (auth): серверийн санамсаргүй (base64), утасны challenge (base64url), урсгал. */
|
|
125
|
-
serverRandom: string | null;
|
|
126
|
-
userChallenge: string | null;
|
|
127
|
-
flowType: string | null;
|
|
128
|
-
signatureAlgorithmParameters: SignatureAlgorithmParameters | null;
|
|
129
|
-
interactionTypeUsed: string | null;
|
|
130
|
-
/**
|
|
131
|
-
* Байгууллагын нэрийн өмнөөс (нэвтрэлт эсвэл гарын үсэг) байсан бол — СЕРВЕР төлөөллийн
|
|
132
|
-
* эрхийг session үүсэх үед шалгасны баталгаа. null бол ердийн хувь хүний session.
|
|
133
|
-
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
134
|
-
*/
|
|
135
|
-
onBehalfOf: OrgResult | null;
|
|
136
|
-
}
|
|
137
|
-
/** Session-ий байгууллагын блок — байгууллага + тухайн иргэний эрх (бүртгэлээс real-time). */
|
|
138
|
-
interface OrgResult {
|
|
139
|
-
/** `NTRMN-<улсын бүртгэлийн дугаар>`. */
|
|
140
|
-
orgEtsi: string;
|
|
141
|
-
orgName: string | null;
|
|
142
|
-
/** Албан тушаал (ж: "Захирал"). Эрх хураагдсан бол null. */
|
|
143
|
-
role: string | null;
|
|
144
|
-
/** ADMIN | MANAGER. Эрх хураагдсан бол null. */
|
|
145
|
-
rightType: string | null;
|
|
146
|
-
}
|
|
147
|
-
/** RP-ийн нэвтрэх мэдээлэл — бүх дуудлагад хэрэгтэй таних тэмдэг + secret. */
|
|
148
|
-
interface RpCredentials {
|
|
149
|
-
/** relying_parties-д бүртгэлтэй RP UUID. */
|
|
150
|
-
rpUUID: string;
|
|
151
|
-
/**
|
|
152
|
-
* Дэд системийн нэр (ж: «Интернэт банк») — CA-д session бүрд хадгалагдана, ≤120 тэмдэгт
|
|
153
|
-
* (сервер илүүг таслана). Иргэний утсан дээр харагдах нэр нь RP-ийн бүртгэлийн нэр.
|
|
154
|
-
*/
|
|
155
|
-
rpName: string;
|
|
156
|
-
/** API secret (rp_sk_…). Зөвхөн backend-д хадгална — браузерт ХЭЗЭЭ Ч задлахгүй. */
|
|
157
|
-
apiSecret: string;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
29
|
interface AuthDefaults {
|
|
161
30
|
certificateLevel: CertificateLevel;
|
|
162
31
|
}
|
|
@@ -419,39 +288,4 @@ declare function buildAcspV2Payload(p: AcspV2Params): Buffer;
|
|
|
419
288
|
/** HASH_{hashAlgorithm}(payload). */
|
|
420
289
|
declare function acspV2Digest(p: AcspV2Params, hashAlgorithm: HashAlgorithm | string): Buffer;
|
|
421
290
|
|
|
422
|
-
|
|
423
|
-
declare class EidError extends Error {
|
|
424
|
-
constructor(message: string);
|
|
425
|
-
}
|
|
426
|
-
/** HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. */
|
|
427
|
-
declare class AuthenticationError extends EidError {
|
|
428
|
-
}
|
|
429
|
-
/** HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй. Танай серверийн IP бүртгэгдээгүй байж магадгүй. */
|
|
430
|
-
declare class ForbiddenError extends EidError {
|
|
431
|
-
}
|
|
432
|
-
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
433
|
-
declare class ApiError extends EidError {
|
|
434
|
-
readonly status: number;
|
|
435
|
-
readonly body: string;
|
|
436
|
-
constructor(status: number, body: string);
|
|
437
|
-
}
|
|
438
|
-
/** Сүлжээ/timeout — upstream хариу өгсөнгүй. */
|
|
439
|
-
declare class NetworkError extends EidError {
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
443
|
-
* endResult-оор салгаж RP UI-д тохирох мессеж харуулна.
|
|
444
|
-
*/
|
|
445
|
-
declare class SessionFailedError extends EidError {
|
|
446
|
-
readonly endResult: string;
|
|
447
|
-
constructor(endResult: string);
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Хариуны баталгаажуулалт бүтэлгүйтсэн — cert chain итгэлцэлгүй, signature challenge-тэй
|
|
451
|
-
* таарсангүй, эсвэл certLevel хүрэлцээгүй. ЭНЭ алдаа гарвал хариунд ИТГЭХГҮЙ
|
|
452
|
-
* (хуурамч/proxy хийгдсэн байж болзошгүй).
|
|
453
|
-
*/
|
|
454
|
-
declare class ValidationError extends EidError {
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
export { type AcspContext, type AcspV2Params, ApiError, AuthApi, type AuthDefaults, type AuthOptions, AuthenticationError, type CertificateLevel, type ClientConfig, DEFAULT_BASE_URL, type DeviceLinkSession, EidClient, EidError, type EndResult, type FlowType, ForbiddenError, type HashAlgorithm, Http, type HttpConfig, type Interaction, NetworkError, type NotificationSession, ResponseValidator, type RevocationChecker, type RevocationStatus, type RpCredentials, SessionApi, SessionFailedError, type SessionResult, type SessionState, SignApi, type SignDefaults, type SignOptions, type SignatureAlgorithm, type SignatureAlgorithmParameters, type SignatureProtocol, type TrustConfig, ValidationError, type VerifiedIdentity, type VerifiedSignature, acspV2Digest, buildAcspV2Payload, interactionsToBase64, parseSessionResult, randomChallenge, resolveBaseUrl, sha256Base64, verifyPayloadSignature, verifyPrehashedSignature };
|
|
291
|
+
export { AcspContext, type AcspV2Params, AuthApi, type AuthDefaults, type AuthOptions, CertificateLevel, type ClientConfig, DEFAULT_BASE_URL, DeviceLinkSession, EidClient, FlowType, HashAlgorithm, Http, type HttpConfig, Interaction, NotificationSession, ResponseValidator, type RevocationChecker, type RevocationStatus, RpCredentials, SessionApi, SessionResult, SignApi, type SignDefaults, type SignOptions, SignatureAlgorithm, type TrustConfig, type VerifiedIdentity, type VerifiedSignature, acspV2Digest, buildAcspV2Payload, interactionsToBase64, parseSessionResult, randomChallenge, resolveBaseUrl, sha256Base64, verifyPayloadSignature, verifyPrehashedSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +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, A as AcspContext, F as FlowType } from './browser-BS8JwSQk.js';
|
|
2
|
+
export { b as ApiError, c as AuthenticationError, d as DeviceLinkError, e as DeviceLinkInput, E as EidError, f as EndResult, g as ForbiddenError, h as NavigatorLike, i as NetworkError, O as OpenOrShowQROptions, j as SessionFailedError, k as SessionState, l as SignatureAlgorithmParameters, m as SignatureProtocol, V as ValidationError, n as deviceLink, o as isMobileUserAgent, p as openOrShowQR } from './browser-BS8JwSQk.js';
|
|
1
3
|
import { X509Certificate, KeyObject } from 'node:crypto';
|
|
2
4
|
|
|
3
5
|
interface HttpConfig {
|
|
@@ -24,139 +26,6 @@ declare class Http {
|
|
|
24
26
|
private request;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
/** Сертификатын баталгаажуулалтын түвшин (eIDAS LoA). QUALIFIED — хууль ёсны гарын үсэгт. */
|
|
28
|
-
type CertificateLevel = "ADVANCED" | "QUALIFIED" | "QSCD";
|
|
29
|
-
/** Гарын үсгийн протокол: auth → ACSP_V2, sign → RAW_DIGEST_SIGNATURE (Smart-ID v3). */
|
|
30
|
-
type SignatureProtocol = "ACSP_V2" | "RAW_DIGEST_SIGNATURE";
|
|
31
|
-
/** Гарын үсгийн алгоритм. rsassa-pss анхдагч; ecdsa-with-SHA256 — хуучин threshold-ECDSA cert. */
|
|
32
|
-
type SignatureAlgorithm = "rsassa-pss" | "sha256WithRSAEncryption" | "sha384WithRSAEncryption" | "sha512WithRSAEncryption" | "ecdsa-with-SHA256";
|
|
33
|
-
/** Hash алгоритм (Smart-ID v3 нэршил). Хуучин "SHA256" нэршил SDK-д БАЙХГҮЙ. */
|
|
34
|
-
type HashAlgorithm = "SHA-256" | "SHA-384" | "SHA-512";
|
|
35
|
-
/** Урсгалын төрөл — хариуны signature.flowType; RP өөрийн санал болгосонтой тулгана. */
|
|
36
|
-
type FlowType = "QR" | "App2App" | "Web2App" | "Notification";
|
|
37
|
-
/** rsassa-pss хариуны параметр (signature.signatureAlgorithmParameters). */
|
|
38
|
-
interface SignatureAlgorithmParameters {
|
|
39
|
-
hashAlgorithm: HashAlgorithm | string;
|
|
40
|
-
maskGenAlgorithm?: {
|
|
41
|
-
algorithm: string;
|
|
42
|
-
parameters?: {
|
|
43
|
-
hashAlgorithm: string;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
saltLength?: number;
|
|
47
|
-
trailerField?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Auth session-ийн ACSP_V2 контекст — RP ХҮСЭЛТЭД илгээсэн утгууд. validator энэ + хариугаар
|
|
51
|
-
* payload-ийг дахин угсарна. Session эхлүүлэхэд SDK өөрөө бөглөнө; RP үүнийг хадгална.
|
|
52
|
-
*/
|
|
53
|
-
interface AcspContext {
|
|
54
|
-
rpChallenge: string;
|
|
55
|
-
relyingPartyName: string;
|
|
56
|
-
brokeredRpName: string;
|
|
57
|
-
/** Илгээсэн base64 МӨР (дахин serialize хийхгүй). */
|
|
58
|
-
interactions: string;
|
|
59
|
-
initialCallbackUrl: string;
|
|
60
|
-
/** RP-ийн санал болгосон урсгалууд — хариуны flowType эдгээрийн нэг байх ёстой. */
|
|
61
|
-
flowTypes: FlowType[];
|
|
62
|
-
signatureAlgorithm: SignatureAlgorithm;
|
|
63
|
-
hashAlgorithm: HashAlgorithm;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Interaction — иргэний утсан дээр харагдах харилцан үйлдэл. displayTextAndPIN нь PIN асууж
|
|
67
|
-
* текст харуулна (хамгийн түгээмэл). text60 — 60 тэмдэгт хүртэл; text200 — 200 хүртэл.
|
|
68
|
-
*/
|
|
69
|
-
interface Interaction {
|
|
70
|
-
type: "displayTextAndPIN" | "confirmationMessage" | "confirmationMessageAndVerificationCodeChoice";
|
|
71
|
-
displayText60?: string;
|
|
72
|
-
displayText200?: string;
|
|
73
|
-
}
|
|
74
|
-
/** Session-ийн төлөв. RUNNING — иргэн хариу өгөөгүй; COMPLETE — дууссан (endResult-ыг үз). */
|
|
75
|
-
type SessionState = "RUNNING" | "COMPLETE";
|
|
76
|
-
/**
|
|
77
|
-
* endResult — COMPLETE session-ийн эцсийн үр дүн.
|
|
78
|
-
* OK — амжилттай (signature/cert бэлэн)
|
|
79
|
-
* USER_REFUSED* — иргэн татгалзсан
|
|
80
|
-
* TIMEOUT — иргэн хугацаанд хариу өгөөгүй
|
|
81
|
-
* DOCUMENT_UNUSABLE — гэрчилгээ/төхөөрөмж ашиглах боломжгүй
|
|
82
|
-
* WRONG_VC — баталгаажуулах код таарсангүй
|
|
83
|
-
*/
|
|
84
|
-
type EndResult = "OK" | "USER_REFUSED" | "USER_REFUSED_DISPLAYTEXTANDPIN" | "USER_REFUSED_VC_CHOICE" | "USER_REFUSED_CONFIRMATIONMESSAGE" | "USER_REFUSED_CERT_CHOICE" | "TIMEOUT" | "DOCUMENT_UNUSABLE" | "WRONG_VC" | "PROTOCOL_FAILURE" | string;
|
|
85
|
-
/**
|
|
86
|
-
* Push (notification) session эхлүүлсний хариу. vc — иргэний дэлгэцэд ХАРУУЛАХ 5 оронтой
|
|
87
|
-
* баталгаажуулах код: утсан дээрх кодтой ижил эсэхийг НҮДЭЭР тулгах зориулалттай.
|
|
88
|
-
*
|
|
89
|
-
* VC нь ПИН БИШ — RP нь үүнийг хэрэглэгчээр оруулуулж болохгүй, зөвхөн харуулна. (PIN1 нь
|
|
90
|
-
* 4 оронтой; VC-г 5 оронтой болгосон нь хэрэглэгч андуурч PIN-ий талбарт оруулаад PIN
|
|
91
|
-
* блок болохоос сэргийлсэн зориудын ялгаа.)
|
|
92
|
-
*/
|
|
93
|
-
interface NotificationSession {
|
|
94
|
-
sessionId: string;
|
|
95
|
-
/** Verification Code — иргэний утсан дээр харагдах код. RP UI-даа ижлийг харуулна (man-in-the-middle хамгаалалт). */
|
|
96
|
-
vc: string | null;
|
|
97
|
-
/** RP-ийн илгээсэн санамсаргүй challenge (base64). Хариуны signature-ийг үүний эсрэг шалгана. */
|
|
98
|
-
rpChallenge: string;
|
|
99
|
-
/** Auth session-д validator-т өгөх контекст (sign session-д undefined). */
|
|
100
|
-
acsp?: AcspContext;
|
|
101
|
-
}
|
|
102
|
-
/** Device-link (QR/App2App) session. Иргэн QR уншиж эсвэл deeplink дарж нэгдэнэ. */
|
|
103
|
-
interface DeviceLinkSession {
|
|
104
|
-
sessionId: string;
|
|
105
|
-
sessionToken: string | null;
|
|
106
|
-
sessionSecret: string | null;
|
|
107
|
-
/** QR/deeplink үүсгэх суурь URL. */
|
|
108
|
-
deviceLinkBase: string | null;
|
|
109
|
-
rpChallenge: string;
|
|
110
|
-
acsp?: AcspContext;
|
|
111
|
-
}
|
|
112
|
-
/** Session poll-ийн нэгтгэсэн үр дүн (validator-т орох түүхий материал). */
|
|
113
|
-
interface SessionResult {
|
|
114
|
-
state: SessionState | string;
|
|
115
|
-
endResult: EndResult | null;
|
|
116
|
-
documentNumber: string | null;
|
|
117
|
-
/** Иргэний X.509 гэрчилгээ (DER, base64). cert chain validation-д орно. */
|
|
118
|
-
certificateDerB64: string | null;
|
|
119
|
-
certificateLevel: CertificateLevel | string | null;
|
|
120
|
-
/** Гарын үсгийн утга (base64). rpChallenge/digest-ийн эсрэг баталгаажна. */
|
|
121
|
-
signatureValueB64: string | null;
|
|
122
|
-
signatureAlgorithm: string | null;
|
|
123
|
-
signatureProtocol: string | null;
|
|
124
|
-
/** ACSP_V2 (auth): серверийн санамсаргүй (base64), утасны challenge (base64url), урсгал. */
|
|
125
|
-
serverRandom: string | null;
|
|
126
|
-
userChallenge: string | null;
|
|
127
|
-
flowType: string | null;
|
|
128
|
-
signatureAlgorithmParameters: SignatureAlgorithmParameters | null;
|
|
129
|
-
interactionTypeUsed: string | null;
|
|
130
|
-
/**
|
|
131
|
-
* Байгууллагын нэрийн өмнөөс (нэвтрэлт эсвэл гарын үсэг) байсан бол — СЕРВЕР төлөөллийн
|
|
132
|
-
* эрхийг session үүсэх үед шалгасны баталгаа. null бол ердийн хувь хүний session.
|
|
133
|
-
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
134
|
-
*/
|
|
135
|
-
onBehalfOf: OrgResult | null;
|
|
136
|
-
}
|
|
137
|
-
/** Session-ий байгууллагын блок — байгууллага + тухайн иргэний эрх (бүртгэлээс real-time). */
|
|
138
|
-
interface OrgResult {
|
|
139
|
-
/** `NTRMN-<улсын бүртгэлийн дугаар>`. */
|
|
140
|
-
orgEtsi: string;
|
|
141
|
-
orgName: string | null;
|
|
142
|
-
/** Албан тушаал (ж: "Захирал"). Эрх хураагдсан бол null. */
|
|
143
|
-
role: string | null;
|
|
144
|
-
/** ADMIN | MANAGER. Эрх хураагдсан бол null. */
|
|
145
|
-
rightType: string | null;
|
|
146
|
-
}
|
|
147
|
-
/** RP-ийн нэвтрэх мэдээлэл — бүх дуудлагад хэрэгтэй таних тэмдэг + secret. */
|
|
148
|
-
interface RpCredentials {
|
|
149
|
-
/** relying_parties-д бүртгэлтэй RP UUID. */
|
|
150
|
-
rpUUID: string;
|
|
151
|
-
/**
|
|
152
|
-
* Дэд системийн нэр (ж: «Интернэт банк») — CA-д session бүрд хадгалагдана, ≤120 тэмдэгт
|
|
153
|
-
* (сервер илүүг таслана). Иргэний утсан дээр харагдах нэр нь RP-ийн бүртгэлийн нэр.
|
|
154
|
-
*/
|
|
155
|
-
rpName: string;
|
|
156
|
-
/** API secret (rp_sk_…). Зөвхөн backend-д хадгална — браузерт ХЭЗЭЭ Ч задлахгүй. */
|
|
157
|
-
apiSecret: string;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
29
|
interface AuthDefaults {
|
|
161
30
|
certificateLevel: CertificateLevel;
|
|
162
31
|
}
|
|
@@ -419,39 +288,4 @@ declare function buildAcspV2Payload(p: AcspV2Params): Buffer;
|
|
|
419
288
|
/** HASH_{hashAlgorithm}(payload). */
|
|
420
289
|
declare function acspV2Digest(p: AcspV2Params, hashAlgorithm: HashAlgorithm | string): Buffer;
|
|
421
290
|
|
|
422
|
-
|
|
423
|
-
declare class EidError extends Error {
|
|
424
|
-
constructor(message: string);
|
|
425
|
-
}
|
|
426
|
-
/** HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. */
|
|
427
|
-
declare class AuthenticationError extends EidError {
|
|
428
|
-
}
|
|
429
|
-
/** HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй. Танай серверийн IP бүртгэгдээгүй байж магадгүй. */
|
|
430
|
-
declare class ForbiddenError extends EidError {
|
|
431
|
-
}
|
|
432
|
-
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
433
|
-
declare class ApiError extends EidError {
|
|
434
|
-
readonly status: number;
|
|
435
|
-
readonly body: string;
|
|
436
|
-
constructor(status: number, body: string);
|
|
437
|
-
}
|
|
438
|
-
/** Сүлжээ/timeout — upstream хариу өгсөнгүй. */
|
|
439
|
-
declare class NetworkError extends EidError {
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
443
|
-
* endResult-оор салгаж RP UI-д тохирох мессеж харуулна.
|
|
444
|
-
*/
|
|
445
|
-
declare class SessionFailedError extends EidError {
|
|
446
|
-
readonly endResult: string;
|
|
447
|
-
constructor(endResult: string);
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Хариуны баталгаажуулалт бүтэлгүйтсэн — cert chain итгэлцэлгүй, signature challenge-тэй
|
|
451
|
-
* таарсангүй, эсвэл certLevel хүрэлцээгүй. ЭНЭ алдаа гарвал хариунд ИТГЭХГҮЙ
|
|
452
|
-
* (хуурамч/proxy хийгдсэн байж болзошгүй).
|
|
453
|
-
*/
|
|
454
|
-
declare class ValidationError extends EidError {
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
export { type AcspContext, type AcspV2Params, ApiError, AuthApi, type AuthDefaults, type AuthOptions, AuthenticationError, type CertificateLevel, type ClientConfig, DEFAULT_BASE_URL, type DeviceLinkSession, EidClient, EidError, type EndResult, type FlowType, ForbiddenError, type HashAlgorithm, Http, type HttpConfig, type Interaction, NetworkError, type NotificationSession, ResponseValidator, type RevocationChecker, type RevocationStatus, type RpCredentials, SessionApi, SessionFailedError, type SessionResult, type SessionState, SignApi, type SignDefaults, type SignOptions, type SignatureAlgorithm, type SignatureAlgorithmParameters, type SignatureProtocol, type TrustConfig, ValidationError, type VerifiedIdentity, type VerifiedSignature, acspV2Digest, buildAcspV2Payload, interactionsToBase64, parseSessionResult, randomChallenge, resolveBaseUrl, sha256Base64, verifyPayloadSignature, verifyPrehashedSignature };
|
|
291
|
+
export { AcspContext, type AcspV2Params, AuthApi, type AuthDefaults, type AuthOptions, CertificateLevel, type ClientConfig, DEFAULT_BASE_URL, DeviceLinkSession, EidClient, FlowType, HashAlgorithm, Http, type HttpConfig, Interaction, NotificationSession, ResponseValidator, type RevocationChecker, type RevocationStatus, RpCredentials, SessionApi, SessionResult, SignApi, type SignDefaults, type SignOptions, SignatureAlgorithm, type TrustConfig, type VerifiedIdentity, type VerifiedSignature, acspV2Digest, buildAcspV2Payload, interactionsToBase64, parseSessionResult, randomChallenge, resolveBaseUrl, sha256Base64, verifyPayloadSignature, verifyPrehashedSignature };
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
super(`RP-API ${status}: ${body}`);
|
|
15
|
-
this.status = status;
|
|
16
|
-
this.body = body;
|
|
17
|
-
}
|
|
18
|
-
status;
|
|
19
|
-
body;
|
|
20
|
-
};
|
|
21
|
-
var NetworkError = class extends EidError {
|
|
22
|
-
};
|
|
23
|
-
var SessionFailedError = class extends EidError {
|
|
24
|
-
constructor(endResult) {
|
|
25
|
-
super(`Session \u0430\u043C\u0436\u0438\u043B\u0442\u0433\u04AF\u0439: ${endResult}`);
|
|
26
|
-
this.endResult = endResult;
|
|
27
|
-
}
|
|
28
|
-
endResult;
|
|
29
|
-
};
|
|
30
|
-
var ValidationError = class extends EidError {
|
|
31
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
ApiError,
|
|
3
|
+
AuthenticationError,
|
|
4
|
+
DeviceLinkError,
|
|
5
|
+
EidError,
|
|
6
|
+
ForbiddenError,
|
|
7
|
+
NetworkError,
|
|
8
|
+
SessionFailedError,
|
|
9
|
+
ValidationError,
|
|
10
|
+
deviceLink,
|
|
11
|
+
isMobileUserAgent,
|
|
12
|
+
openOrShowQR
|
|
13
|
+
} from "./chunk-Q5TQMCJC.js";
|
|
32
14
|
|
|
33
15
|
// src/http.ts
|
|
34
16
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
@@ -161,11 +143,13 @@ var AuthApi = class {
|
|
|
161
143
|
}
|
|
162
144
|
parseDeviceLink(raw, acsp) {
|
|
163
145
|
const r = rec(raw);
|
|
146
|
+
const vc = typeof r.vc === "object" && r.vc !== null ? rec(r.vc).value : r.vc;
|
|
164
147
|
return {
|
|
165
148
|
sessionId: String(r.sessionID),
|
|
166
149
|
sessionToken: r.sessionToken != null ? String(r.sessionToken) : null,
|
|
167
150
|
sessionSecret: r.sessionSecret != null ? String(r.sessionSecret) : null,
|
|
168
151
|
deviceLinkBase: r.deviceLinkBase != null ? String(r.deviceLinkBase) : null,
|
|
152
|
+
vc: vc != null ? String(vc) : null,
|
|
169
153
|
rpChallenge: acsp.rpChallenge,
|
|
170
154
|
acsp
|
|
171
155
|
};
|
|
@@ -689,6 +673,7 @@ export {
|
|
|
689
673
|
AuthApi,
|
|
690
674
|
AuthenticationError,
|
|
691
675
|
DEFAULT_BASE_URL,
|
|
676
|
+
DeviceLinkError,
|
|
692
677
|
EidClient,
|
|
693
678
|
EidError,
|
|
694
679
|
ForbiddenError,
|
|
@@ -701,7 +686,10 @@ export {
|
|
|
701
686
|
ValidationError,
|
|
702
687
|
acspV2Digest,
|
|
703
688
|
buildAcspV2Payload,
|
|
689
|
+
deviceLink,
|
|
704
690
|
interactionsToBase64,
|
|
691
|
+
isMobileUserAgent,
|
|
692
|
+
openOrShowQR,
|
|
705
693
|
parseSessionResult,
|
|
706
694
|
randomChallenge,
|
|
707
695
|
resolveBaseUrl,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gerege-systems/eid-mongolia-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "e-ID Mongolia Relying Party SDK — иргэнээр утсаар нь нэвтрэлт ба хууль ёсны цахим гарын үсэг (RP-API v3, Smart-ID нийцтэй).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"import": "./dist/index.js",
|
|
14
14
|
"require": "./dist/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./browser": {
|
|
17
|
+
"types": "./dist/browser.d.ts",
|
|
18
|
+
"import": "./dist/browser.js",
|
|
19
|
+
"require": "./dist/browser.cjs"
|
|
15
20
|
}
|
|
16
21
|
},
|
|
17
22
|
"files": [
|
|
@@ -23,7 +28,7 @@
|
|
|
23
28
|
"node": ">=22"
|
|
24
29
|
},
|
|
25
30
|
"scripts": {
|
|
26
|
-
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|
|
31
|
+
"build": "tsup src/index.ts src/browser.ts --format esm,cjs --dts --clean",
|
|
27
32
|
"test": "npm run build && node --test --experimental-strip-types test/sdk.test.ts",
|
|
28
33
|
"lint": "tsc --noEmit"
|
|
29
34
|
},
|