@gerege-systems/eid-mongolia-sdk 0.14.1 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -272,10 +272,16 @@ RAW_DIGEST_SIGNATURE-д `flowType` гарын үсэгт ордоггүй (зө
272
272
  холбоосыг backend-д `buildDeviceLink(deviceLinkInput(s, "QR", "mon"))` (auth/cert session-д ч мөн). `s.sign`
273
273
  (`SignContext`: digest, hash, алгоритм, interactions, callback)-ийг session-тэй хамт серверт хадгал.
274
274
 
275
- **`expiresAt`** (ms epoch) — sign / certificate-choice session-ий *тооцоолсон* дуусах мөч: CA session start хариунд
276
- хугацаа буцаадаггүй (зөвхөн `sessionID`), CA-ийн анхдагч 600с (`DEFAULT_SIGN_SESSION_TTL_MS`; CA админ 60–1800с болгож
277
- болно → `signSessionTtlMs`). Хүсэлтээс өмнөх цагаас тооцдог тул CA-ийнхаас хойно хэзээ ч биш; эцсийн үнэн нь
278
- `GET /session` (`TIMEOUT`).
275
+ **`expiresAt`** (ms epoch) — session дуусах мөч: CA-ийн session start хариуны `expiresAt` (RFC 3339; auth / sign /
276
+ certificate-choice бүгдэд, 2026-10-14-өөс). Хуучин CA (талбаргүй) үед sign / certificate-choice-д SDK тооцоолно — CA-ийн
277
+ анхдагч 600с (`DEFAULT_SIGN_SESSION_TTL_MS`; CA админ 60–1800с болгож болно → `signSessionTtlMs`), auth-д undefined.
278
+ Эцсийн үнэн нь `GET /session` (`TIMEOUT`).
279
+
280
+ **Session эхлэх алдаа** (`ApiError`-ийн дэд анги, `.code`-той): `NoSigningCertificateError` — 409
281
+ `NO_SIGNING_CERTIFICATE` (sign / certificate-choice start, `/pdf/sign/prepare`: иргэнд идэвхтэй төхөөрөмж / хүчинтэй
282
+ гарын үсгийн гэрчилгээ алга, session үүсээгүй); `CertChoiceInvalidError` — 409 `CERT_CHOICE_INVALID` (linked sign-ийн
283
+ certificate-choice хүчингүй / хуучирсан / ашиглагдсан → cert-choice-ийг дахин эхлүүл); `RequestInvalidError` — 400
284
+ `REQUEST_INVALID` (ж: linked-д `linkedSessionID` дутуу).
279
285
 
280
286
  ### 3.1. Гэрчилгээг урьдчилж мэдэх (client-side PAdES / CMS)
281
287
 
@@ -522,6 +528,9 @@ OK ирж болзошгүй. Иймд `ResponseValidator`:
522
528
  | `ForbiddenError` | 403 — IP allowlist / mTLS / RP-ийн эрх; onBehalfOf татгалзвал `.code` (`OnBehalfErrorCode`) |
523
529
  | `SessionFailedError` | endResult ≠ OK (TIMEOUT, USER_REFUSED…) — `.endResult`-оор салга |
524
530
  | `ValidationError` | cert chain/signature/level шалгалт бүтэлгүйтсэн |
531
+ | `NoSigningCertificateError` | 409 `NO_SIGNING_CERTIFICATE` — гарын үсгийн гэрчилгээ / төхөөрөмж алга (sign, cert-choice start, PDF prepare); `ApiError`-ийн дэд анги |
532
+ | `CertChoiceInvalidError` | 409 `CERT_CHOICE_INVALID` — linked sign-ийн certificate-choice хүчингүй; `ApiError`-ийн дэд анги |
533
+ | `RequestInvalidError` | 400 `REQUEST_INVALID` — хүсэлт буруу (ж: `linkedSessionID` дутуу); `ApiError`-ийн дэд анги |
525
534
  | `ApiError` | бусад HTTP алдаа (`.status`, `.body`, серверийн `.code`, `.retryAfterMs`, `.headers`, `.retryable` — ж: 404 `ORG_NOT_FOUND`) |
526
535
  | `ResponseTooLargeError` | хариу SDK-ийн хязгаараас их (JSON 4 MiB, PDF `pdfMaxBytes`) — `.op`, `.limit` |
527
536
  | `NetworkError` | timeout/сүлжээ (`.op` — таних тэмдэггүй зам, `.timeout`) |
@@ -94,8 +94,9 @@ interface SignContext {
94
94
  }
95
95
  /**
96
96
  * CA-ийн SIGNATURE ба CERTIFICATE_CHOICE session-ий анхдагч хүчинтэй хугацаа (мс; `EID_SIGN_SESSION_TTL_SECONDS` = 600).
97
- * CA-ийн админ «Системийн тохиргоо»-нд 60–1800 секундэд өөрчилж болно; session start хариунд CA хугацааг буцаадаггүй
98
- * (зөвхөн `sessionID`) тул SDK үүнийг `ClientConfig.signSessionTtlMs`-ээр тооцоолно.
97
+ * CA-ийн админ «Системийн тохиргоо»-нд 60–1800 секундэд өөрчилж болно. CA 2026-10-14-өөс session start хариунд
98
+ * `expiresAt` (RFC 3339) буцаадаг — SDK түүнийг ашиглана; хуучин CA (талбаргүй) үед л `ClientConfig.signSessionTtlMs`-ээр
99
+ * тооцоолно ({@link startExpiry}).
99
100
  */
100
101
  declare const DEFAULT_SIGN_SESSION_TTL_MS = 600000;
101
102
  /**
@@ -104,6 +105,10 @@ declare const DEFAULT_SIGN_SESSION_TTL_MS = 600000;
104
105
  * эхлүүлэх» шийдвэрт л — эцсийн үнэн нь `GET /session` (`TIMEOUT`).
105
106
  */
106
107
  declare function sessionExpiry(sentAtMs: number, ttlMs?: number): number;
108
+ /** CA-ийн `expiresAt` (RFC 3339) → ms epoch; байхгүй / задрахгүй бол undefined. */
109
+ declare function parseExpiresAt(v: unknown): number | undefined;
110
+ /** Session start-ын дуусах мөч: CA-ийн `expiresAt` байвал түүнийг, үгүй бол {@link sessionExpiry} (тооцоолол). */
111
+ declare function startExpiry(raw: unknown, sentAtMs: number, ttlMs?: number): number;
107
112
  /**
108
113
  * Device-link (QR/Web2App/App2App) session. Иргэн QR уншиж эсвэл товч дарж нэгдэнэ.
109
114
  * `sessionToken`, `sessionSecret`-ийг ЗӨВХӨН backend-д хадгална — браузер руу бүү гарга.
@@ -136,7 +141,10 @@ interface DeviceLinkSession {
136
141
  sign?: SignContext;
137
142
  /** Certificate-choice session-ий хүсэлтэд илгээсэн нэр (cert холбоосын authCode-д). */
138
143
  relyingPartyName?: string;
139
- /** Sign / certificate-choice session-ий ТООЦООЛСОН дуусах мөч (ms epoch, {@link sessionExpiry}); auth-д undefined. */
144
+ /**
145
+ * Session дуусах мөч (ms epoch): CA-ийн start хариуны `expiresAt`; хуучин CA-д sign / certificate-choice-д тооцоолсон
146
+ * ({@link startExpiry}), auth-д undefined.
147
+ */
140
148
  expiresAt?: number;
141
149
  }
142
150
  /** Session poll-ийн нэгтгэсэн үр дүн (validator-т орох түүхий материал). */
@@ -418,6 +426,23 @@ declare class ApiError extends EidError {
418
426
  */
419
427
  get retryable(): boolean;
420
428
  }
429
+ /**
430
+ * 409 `NO_SIGNING_CERTIFICATE` — иргэнд (баримтад) идэвхтэй төхөөрөмж / SIGN credential / хүчинтэй гарын үсгийн
431
+ * гэрчилгээ алга: sign ба certificate-choice session start, `/pdf/sign/prepare`. Session үүсээгүй. Танихгүй
432
+ * лавлагаанд ч ижил хариу (бүртгэл задлахгүй) — хэрэглэгчид «eID гарын үсгийн гэрчилгээгүй» гэж харуулна.
433
+ */
434
+ declare class NoSigningCertificateError extends ApiError {
435
+ }
436
+ /**
437
+ * 409 `CERT_CHOICE_INVALID` — linked sign-ийн `linkedSessionID` (certificate-choice) хүчингүй: өөр RP, COMPLETE+OK биш,
438
+ * өөр documentNumber, 5 минутаас хуучин, гэрчилгээ солигдсон, эсвэл аль хэдийн ашиглагдсан. Certificate-choice-ийг
439
+ * дахин эхлүүлнэ.
440
+ */
441
+ declare class CertChoiceInvalidError extends ApiError {
442
+ }
443
+ /** 400 `REQUEST_INVALID` — хүсэлтийн бие/талбар буруу (ж: linked sign-д `linkedSessionID` дутуу). Програмын алдаа. */
444
+ declare class RequestInvalidError extends ApiError {
445
+ }
421
446
  /**
422
447
  * CA-ийн түр (давтаж болох) алдааны кодууд — `ApiError.code`. PDF_PREPARE_BUSY (429 prepare, Retry-After 5),
423
448
  * DOCUMENT_PENDING (503 document, 5), TSA_UNAVAILABLE (503, 30), LTV_UNAVAILABLE (503, 60), RATE_LIMITED (429 токен),
@@ -483,4 +508,4 @@ declare class ValidationError extends EidError {
483
508
  declare class DeviceLinkError extends EidError {
484
509
  }
485
510
 
486
- export { type AcspContext as A, type SignatureProtocol as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type TokenCertStatus as G, type HashAlgorithm as H, type Interaction as I, deviceLink as J, isMobileUserAgent as K, openOrShowQR as L, parseRetryAfter as M, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, sessionExpiry as Q, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, ValidationError as V, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, DEFAULT_SIGN_SESSION_TTL_MS as f, DeviceLinkError as g, type DeviceLinkInput as h, type EndResult as i, ForbiddenError as j, type HttpErrorInit as k, type NavigatorLike as l, NetworkError as m, type OnBehalfErrorCode as n, type OpenOrShowQROptions as o, type OrgResult as p, type PdfDocumentStatus as q, type PdfSigner as r, RETRYABLE_ERROR_CODES as s, type Representation as t, ResponseTooLargeError as u, type RetryableErrorCode as v, SessionFailedError as w, type SessionState as x, type SignContext as y, type SignatureAlgorithmParameters as z };
511
+ export { type AcspContext as A, type SessionState as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type SignContext as G, type HashAlgorithm as H, type Interaction as I, type SignatureAlgorithmParameters as J, type SignatureProtocol as K, type TokenCertStatus as L, deviceLink as M, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, isMobileUserAgent as Q, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, openOrShowQR as U, ValidationError as V, parseExpiresAt as W, parseRetryAfter as X, sessionExpiry as Y, startExpiry as Z, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, CertChoiceInvalidError as f, DEFAULT_SIGN_SESSION_TTL_MS as g, DeviceLinkError as h, type DeviceLinkInput as i, type EndResult as j, ForbiddenError as k, type HttpErrorInit as l, type NavigatorLike as m, NetworkError as n, NoSigningCertificateError as o, type OnBehalfErrorCode as p, type OpenOrShowQROptions as q, type OrgResult as r, type PdfDocumentStatus as s, type PdfSigner as t, RETRYABLE_ERROR_CODES as u, type Representation as v, RequestInvalidError as w, ResponseTooLargeError as x, type RetryableErrorCode as y, SessionFailedError as z };
@@ -94,8 +94,9 @@ interface SignContext {
94
94
  }
95
95
  /**
96
96
  * CA-ийн SIGNATURE ба CERTIFICATE_CHOICE session-ий анхдагч хүчинтэй хугацаа (мс; `EID_SIGN_SESSION_TTL_SECONDS` = 600).
97
- * CA-ийн админ «Системийн тохиргоо»-нд 60–1800 секундэд өөрчилж болно; session start хариунд CA хугацааг буцаадаггүй
98
- * (зөвхөн `sessionID`) тул SDK үүнийг `ClientConfig.signSessionTtlMs`-ээр тооцоолно.
97
+ * CA-ийн админ «Системийн тохиргоо»-нд 60–1800 секундэд өөрчилж болно. CA 2026-10-14-өөс session start хариунд
98
+ * `expiresAt` (RFC 3339) буцаадаг — SDK түүнийг ашиглана; хуучин CA (талбаргүй) үед л `ClientConfig.signSessionTtlMs`-ээр
99
+ * тооцоолно ({@link startExpiry}).
99
100
  */
100
101
  declare const DEFAULT_SIGN_SESSION_TTL_MS = 600000;
101
102
  /**
@@ -104,6 +105,10 @@ declare const DEFAULT_SIGN_SESSION_TTL_MS = 600000;
104
105
  * эхлүүлэх» шийдвэрт л — эцсийн үнэн нь `GET /session` (`TIMEOUT`).
105
106
  */
106
107
  declare function sessionExpiry(sentAtMs: number, ttlMs?: number): number;
108
+ /** CA-ийн `expiresAt` (RFC 3339) → ms epoch; байхгүй / задрахгүй бол undefined. */
109
+ declare function parseExpiresAt(v: unknown): number | undefined;
110
+ /** Session start-ын дуусах мөч: CA-ийн `expiresAt` байвал түүнийг, үгүй бол {@link sessionExpiry} (тооцоолол). */
111
+ declare function startExpiry(raw: unknown, sentAtMs: number, ttlMs?: number): number;
107
112
  /**
108
113
  * Device-link (QR/Web2App/App2App) session. Иргэн QR уншиж эсвэл товч дарж нэгдэнэ.
109
114
  * `sessionToken`, `sessionSecret`-ийг ЗӨВХӨН backend-д хадгална — браузер руу бүү гарга.
@@ -136,7 +141,10 @@ interface DeviceLinkSession {
136
141
  sign?: SignContext;
137
142
  /** Certificate-choice session-ий хүсэлтэд илгээсэн нэр (cert холбоосын authCode-д). */
138
143
  relyingPartyName?: string;
139
- /** Sign / certificate-choice session-ий ТООЦООЛСОН дуусах мөч (ms epoch, {@link sessionExpiry}); auth-д undefined. */
144
+ /**
145
+ * Session дуусах мөч (ms epoch): CA-ийн start хариуны `expiresAt`; хуучин CA-д sign / certificate-choice-д тооцоолсон
146
+ * ({@link startExpiry}), auth-д undefined.
147
+ */
140
148
  expiresAt?: number;
141
149
  }
142
150
  /** Session poll-ийн нэгтгэсэн үр дүн (validator-т орох түүхий материал). */
@@ -418,6 +426,23 @@ declare class ApiError extends EidError {
418
426
  */
419
427
  get retryable(): boolean;
420
428
  }
429
+ /**
430
+ * 409 `NO_SIGNING_CERTIFICATE` — иргэнд (баримтад) идэвхтэй төхөөрөмж / SIGN credential / хүчинтэй гарын үсгийн
431
+ * гэрчилгээ алга: sign ба certificate-choice session start, `/pdf/sign/prepare`. Session үүсээгүй. Танихгүй
432
+ * лавлагаанд ч ижил хариу (бүртгэл задлахгүй) — хэрэглэгчид «eID гарын үсгийн гэрчилгээгүй» гэж харуулна.
433
+ */
434
+ declare class NoSigningCertificateError extends ApiError {
435
+ }
436
+ /**
437
+ * 409 `CERT_CHOICE_INVALID` — linked sign-ийн `linkedSessionID` (certificate-choice) хүчингүй: өөр RP, COMPLETE+OK биш,
438
+ * өөр documentNumber, 5 минутаас хуучин, гэрчилгээ солигдсон, эсвэл аль хэдийн ашиглагдсан. Certificate-choice-ийг
439
+ * дахин эхлүүлнэ.
440
+ */
441
+ declare class CertChoiceInvalidError extends ApiError {
442
+ }
443
+ /** 400 `REQUEST_INVALID` — хүсэлтийн бие/талбар буруу (ж: linked sign-д `linkedSessionID` дутуу). Програмын алдаа. */
444
+ declare class RequestInvalidError extends ApiError {
445
+ }
421
446
  /**
422
447
  * CA-ийн түр (давтаж болох) алдааны кодууд — `ApiError.code`. PDF_PREPARE_BUSY (429 prepare, Retry-After 5),
423
448
  * DOCUMENT_PENDING (503 document, 5), TSA_UNAVAILABLE (503, 30), LTV_UNAVAILABLE (503, 60), RATE_LIMITED (429 токен),
@@ -483,4 +508,4 @@ declare class ValidationError extends EidError {
483
508
  declare class DeviceLinkError extends EidError {
484
509
  }
485
510
 
486
- export { type AcspContext as A, type SignatureProtocol as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type TokenCertStatus as G, type HashAlgorithm as H, type Interaction as I, deviceLink as J, isMobileUserAgent as K, openOrShowQR as L, parseRetryAfter as M, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, sessionExpiry as Q, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, ValidationError as V, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, DEFAULT_SIGN_SESSION_TTL_MS as f, DeviceLinkError as g, type DeviceLinkInput as h, type EndResult as i, ForbiddenError as j, type HttpErrorInit as k, type NavigatorLike as l, NetworkError as m, type OnBehalfErrorCode as n, type OpenOrShowQROptions as o, type OrgResult as p, type PdfDocumentStatus as q, type PdfSigner as r, RETRYABLE_ERROR_CODES as s, type Representation as t, ResponseTooLargeError as u, type RetryableErrorCode as v, SessionFailedError as w, type SessionState as x, type SignContext as y, type SignatureAlgorithmParameters as z };
511
+ export { type AcspContext as A, type SessionState as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type SignContext as G, type HashAlgorithm as H, type Interaction as I, type SignatureAlgorithmParameters as J, type SignatureProtocol as K, type TokenCertStatus as L, deviceLink as M, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, isMobileUserAgent as Q, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, openOrShowQR as U, ValidationError as V, parseExpiresAt as W, parseRetryAfter as X, sessionExpiry as Y, startExpiry as Z, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, CertChoiceInvalidError as f, DEFAULT_SIGN_SESSION_TTL_MS as g, DeviceLinkError as h, type DeviceLinkInput as i, type EndResult as j, ForbiddenError as k, type HttpErrorInit as l, type NavigatorLike as m, NetworkError as n, NoSigningCertificateError as o, type OnBehalfErrorCode as p, type OpenOrShowQROptions as q, type OrgResult as r, type PdfDocumentStatus as s, type PdfSigner as t, RETRYABLE_ERROR_CODES as u, type Representation as v, RequestInvalidError as w, ResponseTooLargeError as x, type RetryableErrorCode as y, SessionFailedError as z };
@@ -1 +1 @@
1
- export { g as DeviceLinkError, h as DeviceLinkInput, D as DeviceLinkSession, E as EidError, l as NavigatorLike, o as OpenOrShowQROptions, J as deviceLink, K as isMobileUserAgent, L as openOrShowQR } from './browser-CuMH5IVG.cjs';
1
+ export { h as DeviceLinkError, i as DeviceLinkInput, D as DeviceLinkSession, E as EidError, m as NavigatorLike, q as OpenOrShowQROptions, M as deviceLink, Q as isMobileUserAgent, U as openOrShowQR } from './browser-CSZjH9Xs.cjs';
package/dist/browser.d.ts CHANGED
@@ -1 +1 @@
1
- export { g as DeviceLinkError, h as DeviceLinkInput, D as DeviceLinkSession, E as EidError, l as NavigatorLike, o as OpenOrShowQROptions, J as deviceLink, K as isMobileUserAgent, L as openOrShowQR } from './browser-CuMH5IVG.js';
1
+ export { h as DeviceLinkError, i as DeviceLinkInput, D as DeviceLinkSession, E as EidError, m as NavigatorLike, q as OpenOrShowQROptions, M as deviceLink, Q as isMobileUserAgent, U as openOrShowQR } from './browser-CSZjH9Xs.js';
package/dist/browser.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  deviceLink,
5
5
  isMobileUserAgent,
6
6
  openOrShowQR
7
- } from "./chunk-QPJDZLHR.js";
7
+ } from "./chunk-DXVHOZO7.js";
8
8
  export {
9
9
  DeviceLinkError,
10
10
  EidError,
@@ -60,6 +60,12 @@ var ApiError = class extends EidError {
60
60
  return (this.status === 429 || this.status === 503) && (this.retryAfterMs ?? 0) > 0;
61
61
  }
62
62
  };
63
+ var NoSigningCertificateError = class extends ApiError {
64
+ };
65
+ var CertChoiceInvalidError = class extends ApiError {
66
+ };
67
+ var RequestInvalidError = class extends ApiError {
68
+ };
63
69
  var RETRYABLE_ERROR_CODES = [
64
70
  "PDF_PREPARE_BUSY",
65
71
  "DOCUMENT_PENDING",
@@ -170,6 +176,9 @@ export {
170
176
  AuthenticationError,
171
177
  ForbiddenError,
172
178
  ApiError,
179
+ NoSigningCertificateError,
180
+ CertChoiceInvalidError,
181
+ RequestInvalidError,
173
182
  RETRYABLE_ERROR_CODES,
174
183
  parseRetryAfter,
175
184
  ON_BEHALF_ERROR_CODES,
package/dist/index.cjs CHANGED
@@ -24,6 +24,7 @@ __export(index_exports, {
24
24
  AuthApi: () => AuthApi,
25
25
  AuthenticationError: () => AuthenticationError,
26
26
  CITIZEN_ISSUING_CA_SKI: () => CITIZEN_ISSUING_CA_SKI,
27
+ CertChoiceInvalidError: () => CertChoiceInvalidError,
27
28
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
28
29
  DEFAULT_PDF_MAX_BYTES: () => DEFAULT_PDF_MAX_BYTES,
29
30
  DEFAULT_PDF_TIMEOUT_MS: () => DEFAULT_PDF_TIMEOUT_MS,
@@ -34,11 +35,13 @@ __export(index_exports, {
34
35
  ForbiddenError: () => ForbiddenError,
35
36
  Http: () => Http,
36
37
  NetworkError: () => NetworkError,
38
+ NoSigningCertificateError: () => NoSigningCertificateError,
37
39
  ON_BEHALF_ERROR_CODES: () => ON_BEHALF_ERROR_CODES,
38
40
  OrganizationApi: () => OrganizationApi,
39
41
  PdfApi: () => PdfApi,
40
42
  PersonApi: () => PersonApi,
41
43
  RETRYABLE_ERROR_CODES: () => RETRYABLE_ERROR_CODES,
44
+ RequestInvalidError: () => RequestInvalidError,
42
45
  ResponseTooLargeError: () => ResponseTooLargeError,
43
46
  ResponseValidator: () => ResponseValidator,
44
47
  SessionApi: () => SessionApi,
@@ -57,6 +60,7 @@ __export(index_exports, {
57
60
  isMobileUserAgent: () => isMobileUserAgent,
58
61
  memoryLoginStore: () => memoryLoginStore,
59
62
  openOrShowQR: () => openOrShowQR,
63
+ parseExpiresAt: () => parseExpiresAt,
60
64
  parseRetryAfter: () => parseRetryAfter,
61
65
  parseSessionResult: () => parseSessionResult,
62
66
  parseSubject: () => parseSubject,
@@ -66,6 +70,7 @@ __export(index_exports, {
66
70
  resolveBaseUrl: () => resolveBaseUrl,
67
71
  sessionExpiry: () => sessionExpiry,
68
72
  sha256Base64: () => sha256Base64,
73
+ startExpiry: () => startExpiry,
69
74
  tokenAuthDigest: () => tokenAuthDigest,
70
75
  tokenLimitOf: () => tokenLimitOf,
71
76
  userChallengeOf: () => userChallengeOf,
@@ -138,6 +143,12 @@ var ApiError = class extends EidError {
138
143
  return (this.status === 429 || this.status === 503) && (this.retryAfterMs ?? 0) > 0;
139
144
  }
140
145
  };
146
+ var NoSigningCertificateError = class extends ApiError {
147
+ };
148
+ var CertChoiceInvalidError = class extends ApiError {
149
+ };
150
+ var RequestInvalidError = class extends ApiError {
151
+ };
141
152
  var RETRYABLE_ERROR_CODES = [
142
153
  "PDF_PREPARE_BUSY",
143
154
  "DOCUMENT_PENDING",
@@ -269,7 +280,8 @@ var Http = class {
269
280
  { headers, retryAfterMs }
270
281
  );
271
282
  }
272
- throw new ApiError(res.status, text, code, { headers, retryAfterMs });
283
+ const Typed = code === "NO_SIGNING_CERTIFICATE" ? NoSigningCertificateError : code === "CERT_CHOICE_INVALID" ? CertChoiceInvalidError : code === "REQUEST_INVALID" ? RequestInvalidError : ApiError;
284
+ throw new Typed(res.status, text, code, { headers, retryAfterMs });
273
285
  }
274
286
  };
275
287
  async function readLimited(res, limit, op) {
@@ -395,6 +407,21 @@ function acspV2Digest(p, hashAlgorithm) {
395
407
  return (0, import_node_crypto.createHash)(nodeHash(hashAlgorithm)).update(buildAcspV2Payload(p)).digest();
396
408
  }
397
409
 
410
+ // src/types.ts
411
+ var DEFAULT_SIGN_SESSION_TTL_MS = 6e5;
412
+ function sessionExpiry(sentAtMs, ttlMs) {
413
+ return sentAtMs + (ttlMs && ttlMs > 0 ? ttlMs : DEFAULT_SIGN_SESSION_TTL_MS);
414
+ }
415
+ function parseExpiresAt(v) {
416
+ if (typeof v !== "string" || !/^\d{4}-\d{2}-\d{2}T/.test(v)) return void 0;
417
+ const t = Date.parse(v);
418
+ return Number.isFinite(t) ? t : void 0;
419
+ }
420
+ function startExpiry(raw, sentAtMs, ttlMs) {
421
+ const r = raw && typeof raw === "object" ? raw : {};
422
+ return parseExpiresAt(r.expiresAt) ?? sessionExpiry(sentAtMs, ttlMs);
423
+ }
424
+
398
425
  // src/auth.ts
399
426
  function rec(v) {
400
427
  return v && typeof v === "object" ? v : {};
@@ -440,11 +467,19 @@ var AuthApi = class {
440
467
  parseNotification(raw, acsp) {
441
468
  const r = rec(raw);
442
469
  const vc = rec(r.vc).value;
443
- return { sessionId: String(r.sessionID), vc: vc != null ? String(vc) : null, rpChallenge: acsp.rpChallenge, acsp };
470
+ const expiresAt = parseExpiresAt(r.expiresAt);
471
+ return {
472
+ sessionId: String(r.sessionID),
473
+ vc: vc != null ? String(vc) : null,
474
+ rpChallenge: acsp.rpChallenge,
475
+ acsp,
476
+ ...expiresAt !== void 0 ? { expiresAt } : {}
477
+ };
444
478
  }
445
479
  parseDeviceLink(raw, acsp) {
446
480
  const r = rec(raw);
447
481
  const vc = typeof r.vc === "object" && r.vc !== null ? rec(r.vc).value : r.vc;
482
+ const expiresAt = parseExpiresAt(r.expiresAt);
448
483
  return {
449
484
  sessionId: String(r.sessionID),
450
485
  sessionToken: r.sessionToken != null ? String(r.sessionToken) : null,
@@ -454,7 +489,8 @@ var AuthApi = class {
454
489
  rpChallenge: acsp.rpChallenge,
455
490
  acsp,
456
491
  receivedAt: Date.now(),
457
- sessionType: "auth"
492
+ sessionType: "auth",
493
+ ...expiresAt !== void 0 ? { expiresAt } : {}
458
494
  };
459
495
  }
460
496
  /** Push — РД/иргэний дугаар/ETSI-ээр (сервер төрлийг таьна). Иргэний утас руу мэдэгдэл очно. */
@@ -483,12 +519,6 @@ var AuthApi = class {
483
519
  }
484
520
  };
485
521
 
486
- // src/types.ts
487
- var DEFAULT_SIGN_SESSION_TTL_MS = 6e5;
488
- function sessionExpiry(sentAtMs, ttlMs) {
489
- return sentAtMs + (ttlMs && ttlMs > 0 ? ttlMs : DEFAULT_SIGN_SESSION_TTL_MS);
490
- }
491
-
492
522
  // src/sign.ts
493
523
  function rec2(v) {
494
524
  return v && typeof v === "object" ? v : {};
@@ -540,7 +570,7 @@ var SignApi = class {
540
570
  vc: vcOf(r),
541
571
  rpChallenge: "",
542
572
  ...sign ? { sign } : {},
543
- expiresAt: sessionExpiry(sent, this.defaults.sessionTtlMs)
573
+ expiresAt: startExpiry(r, sent, this.defaults.sessionTtlMs)
544
574
  };
545
575
  }
546
576
  async deviceLink(path, body, extra) {
@@ -555,7 +585,7 @@ var SignApi = class {
555
585
  rpChallenge: "",
556
586
  receivedAt: Date.now(),
557
587
  ...extra,
558
- expiresAt: sessionExpiry(sent, this.defaults.sessionTtlMs)
588
+ expiresAt: startExpiry(r, sent, this.defaults.sessionTtlMs)
559
589
  };
560
590
  }
561
591
  /**
@@ -2491,6 +2521,7 @@ function createEidLogin(opts) {
2491
2521
  AuthApi,
2492
2522
  AuthenticationError,
2493
2523
  CITIZEN_ISSUING_CA_SKI,
2524
+ CertChoiceInvalidError,
2494
2525
  DEFAULT_BASE_URL,
2495
2526
  DEFAULT_PDF_MAX_BYTES,
2496
2527
  DEFAULT_PDF_TIMEOUT_MS,
@@ -2501,11 +2532,13 @@ function createEidLogin(opts) {
2501
2532
  ForbiddenError,
2502
2533
  Http,
2503
2534
  NetworkError,
2535
+ NoSigningCertificateError,
2504
2536
  ON_BEHALF_ERROR_CODES,
2505
2537
  OrganizationApi,
2506
2538
  PdfApi,
2507
2539
  PersonApi,
2508
2540
  RETRYABLE_ERROR_CODES,
2541
+ RequestInvalidError,
2509
2542
  ResponseTooLargeError,
2510
2543
  ResponseValidator,
2511
2544
  SessionApi,
@@ -2524,6 +2557,7 @@ function createEidLogin(opts) {
2524
2557
  isMobileUserAgent,
2525
2558
  memoryLoginStore,
2526
2559
  openOrShowQR,
2560
+ parseExpiresAt,
2527
2561
  parseRetryAfter,
2528
2562
  parseSessionResult,
2529
2563
  parseSubject,
@@ -2533,6 +2567,7 @@ function createEidLogin(opts) {
2533
2567
  resolveBaseUrl,
2534
2568
  sessionExpiry,
2535
2569
  sha256Base64,
2570
+ startExpiry,
2536
2571
  tokenAuthDigest,
2537
2572
  tokenLimitOf,
2538
2573
  userChallengeOf,
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 } from './browser-CuMH5IVG.cjs';
2
- export { d as ApiError, e as AuthenticationError, f as DEFAULT_SIGN_SESSION_TTL_MS, g as DeviceLinkError, h as DeviceLinkInput, E as EidError, i as EndResult, j as ForbiddenError, k as HttpErrorInit, l as NavigatorLike, m as NetworkError, O as ON_BEHALF_ERROR_CODES, n as OnBehalfErrorCode, o as OpenOrShowQROptions, p as OrgResult, q as PdfDocumentStatus, r as PdfSigner, s as RETRYABLE_ERROR_CODES, t as Representation, u as ResponseTooLargeError, v as RetryableErrorCode, w as SessionFailedError, x as SessionState, y as SignContext, z as SignatureAlgorithmParameters, B as SignatureProtocol, T as TokenCertSessionBlock, G as TokenCertStatus, V as ValidationError, J as deviceLink, K as isMobileUserAgent, L as openOrShowQR, M as parseRetryAfter, Q as sessionExpiry } from './browser-CuMH5IVG.cjs';
1
+ import { R as RpCredentials, C as CertificateLevel, I as Interaction, S as SignatureAlgorithm, H as HashAlgorithm, N as NotificationSession, D as DeviceLinkSession, a as SessionResult, P as PersonBlock, b as PdfSessionBlock, c as RepresentationsResponse, A as AcspContext, F as FlowType } from './browser-CSZjH9Xs.cjs';
2
+ export { d as ApiError, e as AuthenticationError, f as CertChoiceInvalidError, g as DEFAULT_SIGN_SESSION_TTL_MS, h as DeviceLinkError, i as DeviceLinkInput, E as EidError, j as EndResult, k as ForbiddenError, l as HttpErrorInit, m as NavigatorLike, n as NetworkError, o as NoSigningCertificateError, O as ON_BEHALF_ERROR_CODES, p as OnBehalfErrorCode, q as OpenOrShowQROptions, r as OrgResult, s as PdfDocumentStatus, t as PdfSigner, u as RETRYABLE_ERROR_CODES, v as Representation, w as RequestInvalidError, x as ResponseTooLargeError, y as RetryableErrorCode, z as SessionFailedError, B as SessionState, G as SignContext, J as SignatureAlgorithmParameters, K as SignatureProtocol, T as TokenCertSessionBlock, L as TokenCertStatus, V as ValidationError, M as deviceLink, Q as isMobileUserAgent, U as openOrShowQR, W as parseExpiresAt, X as parseRetryAfter, Y as sessionExpiry, Z as startExpiry } from './browser-CSZjH9Xs.cjs';
3
3
  import { X509Certificate, KeyObject } from 'node:crypto';
4
4
 
5
5
  interface HttpConfig {
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 } from './browser-CuMH5IVG.js';
2
- export { d as ApiError, e as AuthenticationError, f as DEFAULT_SIGN_SESSION_TTL_MS, g as DeviceLinkError, h as DeviceLinkInput, E as EidError, i as EndResult, j as ForbiddenError, k as HttpErrorInit, l as NavigatorLike, m as NetworkError, O as ON_BEHALF_ERROR_CODES, n as OnBehalfErrorCode, o as OpenOrShowQROptions, p as OrgResult, q as PdfDocumentStatus, r as PdfSigner, s as RETRYABLE_ERROR_CODES, t as Representation, u as ResponseTooLargeError, v as RetryableErrorCode, w as SessionFailedError, x as SessionState, y as SignContext, z as SignatureAlgorithmParameters, B as SignatureProtocol, T as TokenCertSessionBlock, G as TokenCertStatus, V as ValidationError, J as deviceLink, K as isMobileUserAgent, L as openOrShowQR, M as parseRetryAfter, Q as sessionExpiry } from './browser-CuMH5IVG.js';
1
+ import { R as RpCredentials, C as CertificateLevel, I as Interaction, S as SignatureAlgorithm, H as HashAlgorithm, N as NotificationSession, D as DeviceLinkSession, a as SessionResult, P as PersonBlock, b as PdfSessionBlock, c as RepresentationsResponse, A as AcspContext, F as FlowType } from './browser-CSZjH9Xs.js';
2
+ export { d as ApiError, e as AuthenticationError, f as CertChoiceInvalidError, g as DEFAULT_SIGN_SESSION_TTL_MS, h as DeviceLinkError, i as DeviceLinkInput, E as EidError, j as EndResult, k as ForbiddenError, l as HttpErrorInit, m as NavigatorLike, n as NetworkError, o as NoSigningCertificateError, O as ON_BEHALF_ERROR_CODES, p as OnBehalfErrorCode, q as OpenOrShowQROptions, r as OrgResult, s as PdfDocumentStatus, t as PdfSigner, u as RETRYABLE_ERROR_CODES, v as Representation, w as RequestInvalidError, x as ResponseTooLargeError, y as RetryableErrorCode, z as SessionFailedError, B as SessionState, G as SignContext, J as SignatureAlgorithmParameters, K as SignatureProtocol, T as TokenCertSessionBlock, L as TokenCertStatus, V as ValidationError, M as deviceLink, Q as isMobileUserAgent, U as openOrShowQR, W as parseExpiresAt, X as parseRetryAfter, Y as sessionExpiry, Z as startExpiry } from './browser-CSZjH9Xs.js';
3
3
  import { X509Certificate, KeyObject } from 'node:crypto';
4
4
 
5
5
  interface HttpConfig {
package/dist/index.js CHANGED
@@ -1,12 +1,15 @@
1
1
  import {
2
2
  ApiError,
3
3
  AuthenticationError,
4
+ CertChoiceInvalidError,
4
5
  DeviceLinkError,
5
6
  EidError,
6
7
  ForbiddenError,
7
8
  NetworkError,
9
+ NoSigningCertificateError,
8
10
  ON_BEHALF_ERROR_CODES,
9
11
  RETRYABLE_ERROR_CODES,
12
+ RequestInvalidError,
10
13
  ResponseTooLargeError,
11
14
  SessionFailedError,
12
15
  ValidationError,
@@ -15,7 +18,7 @@ import {
15
18
  maskPath,
16
19
  openOrShowQR,
17
20
  parseRetryAfter
18
- } from "./chunk-QPJDZLHR.js";
21
+ } from "./chunk-DXVHOZO7.js";
19
22
 
20
23
  // src/http.ts
21
24
  var DEFAULT_TIMEOUT_MS = 15e3;
@@ -85,7 +88,8 @@ var Http = class {
85
88
  { headers, retryAfterMs }
86
89
  );
87
90
  }
88
- throw new ApiError(res.status, text, code, { headers, retryAfterMs });
91
+ const Typed = code === "NO_SIGNING_CERTIFICATE" ? NoSigningCertificateError : code === "CERT_CHOICE_INVALID" ? CertChoiceInvalidError : code === "REQUEST_INVALID" ? RequestInvalidError : ApiError;
92
+ throw new Typed(res.status, text, code, { headers, retryAfterMs });
89
93
  }
90
94
  };
91
95
  async function readLimited(res, limit, op) {
@@ -211,6 +215,21 @@ function acspV2Digest(p, hashAlgorithm) {
211
215
  return createHash(nodeHash(hashAlgorithm)).update(buildAcspV2Payload(p)).digest();
212
216
  }
213
217
 
218
+ // src/types.ts
219
+ var DEFAULT_SIGN_SESSION_TTL_MS = 6e5;
220
+ function sessionExpiry(sentAtMs, ttlMs) {
221
+ return sentAtMs + (ttlMs && ttlMs > 0 ? ttlMs : DEFAULT_SIGN_SESSION_TTL_MS);
222
+ }
223
+ function parseExpiresAt(v) {
224
+ if (typeof v !== "string" || !/^\d{4}-\d{2}-\d{2}T/.test(v)) return void 0;
225
+ const t = Date.parse(v);
226
+ return Number.isFinite(t) ? t : void 0;
227
+ }
228
+ function startExpiry(raw, sentAtMs, ttlMs) {
229
+ const r = raw && typeof raw === "object" ? raw : {};
230
+ return parseExpiresAt(r.expiresAt) ?? sessionExpiry(sentAtMs, ttlMs);
231
+ }
232
+
214
233
  // src/auth.ts
215
234
  function rec(v) {
216
235
  return v && typeof v === "object" ? v : {};
@@ -256,11 +275,19 @@ var AuthApi = class {
256
275
  parseNotification(raw, acsp) {
257
276
  const r = rec(raw);
258
277
  const vc = rec(r.vc).value;
259
- return { sessionId: String(r.sessionID), vc: vc != null ? String(vc) : null, rpChallenge: acsp.rpChallenge, acsp };
278
+ const expiresAt = parseExpiresAt(r.expiresAt);
279
+ return {
280
+ sessionId: String(r.sessionID),
281
+ vc: vc != null ? String(vc) : null,
282
+ rpChallenge: acsp.rpChallenge,
283
+ acsp,
284
+ ...expiresAt !== void 0 ? { expiresAt } : {}
285
+ };
260
286
  }
261
287
  parseDeviceLink(raw, acsp) {
262
288
  const r = rec(raw);
263
289
  const vc = typeof r.vc === "object" && r.vc !== null ? rec(r.vc).value : r.vc;
290
+ const expiresAt = parseExpiresAt(r.expiresAt);
264
291
  return {
265
292
  sessionId: String(r.sessionID),
266
293
  sessionToken: r.sessionToken != null ? String(r.sessionToken) : null,
@@ -270,7 +297,8 @@ var AuthApi = class {
270
297
  rpChallenge: acsp.rpChallenge,
271
298
  acsp,
272
299
  receivedAt: Date.now(),
273
- sessionType: "auth"
300
+ sessionType: "auth",
301
+ ...expiresAt !== void 0 ? { expiresAt } : {}
274
302
  };
275
303
  }
276
304
  /** Push — РД/иргэний дугаар/ETSI-ээр (сервер төрлийг таьна). Иргэний утас руу мэдэгдэл очно. */
@@ -299,12 +327,6 @@ var AuthApi = class {
299
327
  }
300
328
  };
301
329
 
302
- // src/types.ts
303
- var DEFAULT_SIGN_SESSION_TTL_MS = 6e5;
304
- function sessionExpiry(sentAtMs, ttlMs) {
305
- return sentAtMs + (ttlMs && ttlMs > 0 ? ttlMs : DEFAULT_SIGN_SESSION_TTL_MS);
306
- }
307
-
308
330
  // src/sign.ts
309
331
  function rec2(v) {
310
332
  return v && typeof v === "object" ? v : {};
@@ -356,7 +378,7 @@ var SignApi = class {
356
378
  vc: vcOf(r),
357
379
  rpChallenge: "",
358
380
  ...sign ? { sign } : {},
359
- expiresAt: sessionExpiry(sent, this.defaults.sessionTtlMs)
381
+ expiresAt: startExpiry(r, sent, this.defaults.sessionTtlMs)
360
382
  };
361
383
  }
362
384
  async deviceLink(path, body, extra) {
@@ -371,7 +393,7 @@ var SignApi = class {
371
393
  rpChallenge: "",
372
394
  receivedAt: Date.now(),
373
395
  ...extra,
374
- expiresAt: sessionExpiry(sent, this.defaults.sessionTtlMs)
396
+ expiresAt: startExpiry(r, sent, this.defaults.sessionTtlMs)
375
397
  };
376
398
  }
377
399
  /**
@@ -2264,6 +2286,7 @@ export {
2264
2286
  AuthApi,
2265
2287
  AuthenticationError,
2266
2288
  CITIZEN_ISSUING_CA_SKI,
2289
+ CertChoiceInvalidError,
2267
2290
  DEFAULT_BASE_URL,
2268
2291
  DEFAULT_PDF_MAX_BYTES,
2269
2292
  DEFAULT_PDF_TIMEOUT_MS,
@@ -2274,11 +2297,13 @@ export {
2274
2297
  ForbiddenError,
2275
2298
  Http,
2276
2299
  NetworkError,
2300
+ NoSigningCertificateError,
2277
2301
  ON_BEHALF_ERROR_CODES,
2278
2302
  OrganizationApi,
2279
2303
  PdfApi,
2280
2304
  PersonApi,
2281
2305
  RETRYABLE_ERROR_CODES,
2306
+ RequestInvalidError,
2282
2307
  ResponseTooLargeError,
2283
2308
  ResponseValidator,
2284
2309
  SessionApi,
@@ -2297,6 +2322,7 @@ export {
2297
2322
  isMobileUserAgent,
2298
2323
  memoryLoginStore,
2299
2324
  openOrShowQR,
2325
+ parseExpiresAt,
2300
2326
  parseRetryAfter,
2301
2327
  parseSessionResult,
2302
2328
  parseSubject,
@@ -2306,6 +2332,7 @@ export {
2306
2332
  resolveBaseUrl,
2307
2333
  sessionExpiry,
2308
2334
  sha256Base64,
2335
+ startExpiry,
2309
2336
  tokenAuthDigest,
2310
2337
  tokenLimitOf,
2311
2338
  userChallengeOf,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gerege-systems/eid-mongolia-sdk",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "e-ID Mongolia Relying Party SDK — иргэнээр утсаар нь нэвтрэлт ба хууль ёсны цахим гарын үсэг (RP-API v3, Smart-ID нийцтэй).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsup src/index.ts src/browser.ts --format esm,cjs --dts --clean && tsup src/button.ts --format esm,cjs --dts --tsconfig tsconfig.button.json",
37
- "test": "npm run build && node --test --experimental-strip-types test/sdk.test.ts test/portal-gaps.test.ts test/chain.test.ts test/qr.test.ts test/login.test.ts test/button.test.ts test/sign-gaps.test.ts",
37
+ "test": "npm run build && node --test --experimental-strip-types test/sdk.test.ts test/portal-gaps.test.ts test/chain.test.ts test/qr.test.ts test/login.test.ts test/button.test.ts test/sign-gaps.test.ts test/session-start.test.ts",
38
38
  "test:contract": "npm run build && node --experimental-strip-types test/contract.test.ts",
39
39
  "lint": "tsc --noEmit && tsc --noEmit -p tsconfig.button.json"
40
40
  },