Агуулгыг алгасах

Windows Desktop клиент — Developer гарын авлага

eID платформын Windows (C# / WinUI 3) desktop клиент — гар утасны e-ID Mongolia апп-аар QR / РД push нэвтрэлт, USB токен (смарт карт) удирдлага, хэрэглэгчийн хяналтын самбар, байгууллагын төлөөлөл, гэрчилгээ баталгаажуулалтыг хийх ширээний програм. Эх код: desktop/windows-app/ (Clean Architecture, .NET solution eIDMongolia.Desktop.sln).

First-party client — rewire дууссан. Энэ клиент нь gerege v1 desktop-оос импортлогдож eID Mongolia болгон rebrand хийгдсэн (eIDMongolia.* namespace, MSIX identity mn.eidmongol.desktop). macOS клиент (DESKTOP_MACOS.md) болон iOS апп-тай яг ижил зарчмаар энэ бол RP биш — клиентэд ямар ч RP secret, RP UUID, device HMAC нууц, удаан насладаг bearer token байхгүй. Бүх дуудлага web backend-ийн нийтийн /api/* route-уудаар (browser-тэй яг ижил зам) дамжина; Go RP-API (/v3/*)-ийн RP_API_SECRET-ийг зөвхөн web сервер (web/src/lib/rpclient.ts) барьдаг. Хуучин gerege-ийн шууд-backend (/web2app/v1, /rp/v1, device-HMAC, Bearer session) загвараас /api/* руу шилжүүлэх ажил дууссан; дэлгэрэнгүй буулгалт: desktop/windows-app/BACKEND-INTEGRATION.md.

1. Юу хийдэг вэ

Кодоос батлагдсан боломжууд (Views/Pages/*, Infrastructure/*). Нэвтрэлтийн дараа sidebar-т Home · Dashboard · Organizations · Tokens · Verify цэсүүд гарна (нэвтрэхээс өмнө зөвхөн Login) — ShellViewModel.BuildMenu():

  • Нэвтрэлт (LoginPage / LoginViewModel, CitizenAuthService) — хоёр идэвхтэй горим:
  • РД / иргэний дугаараар push — утас руу мэдэгдэл илгээж PIN1-ээр баталгаажуулна (POST /api/login-notify).
  • QR — QR код харуулж (QRCoder-оор рендэр), утсаар скан хийлгэнэ (POST /api/start).
  • USB токен удирдлага (TokensPage / TokenDetailPage) — залгагдсан смарт карт / токенуудыг илрүүлэх, төлөв (Blank/Initialized/Provisioned/ Enrolled) харах, түлхүүр үүсгэх, PIN удирдлага. Токены стек нь бие даасан (Windows CNG + PKCS#11, §6 үз).
  • Хяналтын самбар (DashboardPage / DashboardService) — нэвтэрсэн иргэний гэрчилгээ / төхөөрөмж / идэвхийн тоолол, нэр (/api/dashboard, /api/devices, /api/activity).
  • Байгууллага (OrganizationsPage / OrgService) — нэвтэрсэн иргэний төлөөлж чадах ACTIVE байгууллагуудын жагсаалт (/api/representations).
  • Баталгаажуулалт (VerifyPage / VerifyViewModel) — гэрчилгээг PEM paste эсвэл файлаар клиент талд (ICertificateService.ParsePem/ParseFile) задлаж, subject / хүчинтэй хугацаа / validity-г харуулна. Backend дуудлагагүй (macOS-той адил).

Note — PDF гарын үсэг зурах UI одоогоор алга. First-party PDF-signing service нь бэлэн (RpAuthServicePOST /api/sign-pdf-start, PDF-ийн SHA-256 digest-ийг клиент өөрөө тооцно), гэвч түүнийг дуудах ViewModel / Page байхгүйIRpAuthService-ийг DI-д бүртгэснээс өөр газар хэрэглэдэггүй, sidebar-т Sign цэс алга. Мөн RpAuthService нь тамгалагдсан PDF-ийг татаж авдаг /api/sign-pdf-download-ийг дууддаггүй (зөвхөн raw signature авдаг). Иймд Windows тал дээр PDF-д гарын үсэг зурах бүрэн урсгал одоогоор байхгүй — macOS клиент дээр л бүтэн ажилладаг. USB-токен нэвтрэлт мөн идэвхгүй (§5, stub).

2. Архитектур

2.1. Clean Architecture давхаргууд

Solution нь дөрвөн эх давхарга + WinUI entry point + тестээс бүрдэнэ (eIDMongolia.Desktop.sln):

Төсөл Үүрэг Хамаарал
eIDMongolia.Domain Entity, value object, Result<T>, ApiError, токены төрлүүд. Гадаад хамааралгүй.
eIDMongolia.Application Use-case abstraction (IBackendApi, ICitizenAuthService, ICryptoTokenProvider, …), eIDMongoliaOptions. Domain
eIDMongolia.Infrastructure HTTP клиент, cert pinning, DPAPI vault, Windows Hello, PKCS#11 / CNG токен провайдер. Windows TFM. Application, Domain
eIDMongolia.Presentation ViewModel-ууд (CommunityToolkit.Mvvm), navigation, validation. UI framework-оос хараат бус. Application, Domain
eIDMongolia.Client WinUI 3 entry pointApp.xaml, MainWindow, Views/Pages/*, Generic Host bootstrap (Hosting/AppHost.cs). бүх дээрх давхарга
eIDMongolia.UnitTests xUnit тест. бүх src төсөл

Reference граф: Client → Presentation, Infrastructure, Application, Domain; Presentation → Application, Domain; Infrastructure → Application, Domain; Application → Domain.

Тодотгол — Client бол HTTP клиент БИШ. Нэрнээс үл хамааран eIDMongolia.Client нь WinUI 3 UI/entry point давхарга. Бодит HTTP клиент нь Infrastructure/Http/BackendApiClient.cs болон Infrastructure/Auth/*Service.cs файлуудад байдаг.

Хост: Microsoft.Extensions.Hosting Generic Host — DI, Configuration, Options, Serilog. Bootstrap Client/Hosting/AppHost.cs.

2.2. Backend-тэй холбогдох — first-party /api/*

Infrastructure/DependencyInjection.cs дотор нэрлэсэн HttpClient (eIDMongolia.Backend) тохируулна: BaseUrl (web origin), TLS 1.3, cert-pinning primary handler, дараа нь AddStandardResilienceHandler (Polly retry). Device-HMAC signer болон Bearer-attach handler нь pipeline-д холбогдоогүй — first-party загварт хэрэггүй. Клиент нь web/src/app/api/* (Next.js) route-уудыг browser шиг шууд дууддаг:

Route Метод Зориулалт Service
/api/health GET Серверийн эрүүл мэнд (live=ready) BackendApiClient
/api/login-notify POST РД/иргэний дугаараар push нэвтрэлт CitizenAuthService
/api/start POST QR нэвтрэлт эхлүүлэх CitizenAuthService
/api/status GET Long-poll (?sessionId=&pollToken=) CitizenAuthService, RpAuthService
/api/sign-pdf-start POST PDF digest-д гарын үсэг эхлүүлэх (service бэлэн, UI алга) RpAuthService
/api/dashboard POST {personId} → cert/төхөөрөмж/идэвхийн тоолол + нэр DashboardService
/api/devices POST {personId} → бүртгэлтэй төхөөрөмжүүд DashboardService
/api/activity POST {personId} → RP-scoped session түүх DashboardService
/api/representations POST {personId} → төлөөлж чадах ACTIVE байгууллага OrgService

Эдгээр /api/* route-ууд нь Go RP-API-ийн /v3/*-руу web сервер дээр first-party RP Bearer-ээр proxy хийгддэг (personId = нэвтэрсэн иргэний civil_id / etsi, identity cache-аас). pollToken нь session эхлүүлэгчид л олгогддог бөгөөд /api/status-аас PII (нэр / иргэний дугаар) авахад заавал шаардлагатай.

Identity bridge (impedance mismatch-ийн шийдэл). /api/status нь session_token / user_id буцаадаггүй; амжилттай нэвтрэхэд cert subject-оос name + idNumber шууд ирдэг. Иймд CitizenAuthService.PollAsync нь энэ identity-г ISessionIdentityCache-д хадгалж, session бүрд синтетик SessionToken(=sessionId) + UserId(GUID) үүсгэнэ; UserProfileService, DashboardService, OrgService нь personId-г энэ cache-аас уншина (/me endpoint байхгүй).

Хараахан эквивалент /api/* route байхгүй тул honest stub (crash биш — ApiError.Internal("…not_available_on_first_party_backend") буцааж, UI цэвэрхэн унана):

  • USB-токен нэвтрэлт (CitizenAuthService.InitiateTokenChallengeAsync / VerifyTokenAsync) — web backend дээр token/challenge·token/verify алга.
  • Гэрчилгээ enroll (CertEnrollmentService).
  • Байгууллагын WRITE үйлдлүүд (OrgService-ийн lookup / register / members / name-en / X-Road CSR) — зөвхөн ListAsync жинхэнэ.

Хуучин handler-ууд tree-д үлдсэн. gerege-ийн /web2app/v1 device-HMAC (HmacSigningHandler) болон Bearer-attach (BearerAuthHandler) класс-ууд эх модонд хэвээр байгаа ч HTTP pipeline-д холбогдоогүй — ирээдүйн шууд-backend build-д лавлагаа болгож үлдээв. Тэднээс юу ч хамаардаггүй.

Тохиргоог eIDMongoliaOptions-оос уншина (appsettings.json + appsettings.{ENV}.json overlay + EIDMNG_ prefix-тэй env). Prod-д BaseUrl=https://eidmongolia.mn; dev overlay (appsettings.Development.json)-д BaseUrl=http://localhost:3000, RequireCertificatePinning=false, RequireWindowsHello=false. CertificateSpkiPins болон XRoadClient нь first-party загварт хоосон / null.

3. Урьдчилсан нөхцөл

Кодоос батлагдсан (Directory.Packages.props, *.csproj):

  • .NET 8 (LTS), C# latest (12); TreatWarningsAsErrors=true, nullable + implicit usings идэвхтэй.
  • eIDMongolia.Client TFM: net8.0-windows10.0.26100.0 (TargetPlatformMinVersion 10.0.17763.0) — өөрөөр хэлбэл Windows 10 1809+, build-д Windows 11 SDK (26100) шаардлагатай.
  • Windows App SDK 2.0.1 + WinUI 3 (UseWinUI=true).
  • Visual Studio 2022 17.10+, Windows application development workload; эсвэл dotnet CLI.
  • Platform: x86 / x64 / ARM64.
  • USB токен ашиглах бол хостод PKCS#11 модуль суусан байх (OpenSC opensc-pkcs11.dll эсвэл Feitian eps2003csp11.dll) — заавал биш, байхгүй бол токены хэсэг л идэвхгүй болно.

4. Build ба ажиллуулах

cd desktop/windows-app
dotnet restore eIDMongolia.Desktop.sln
dotnet build eIDMongolia.Desktop.sln -c Debug /p:Platform=x64
dotnet test tests/eIDMongolia.UnitTests/eIDMongolia.UnitTests.csproj

Visual Studio-д: eIDMongolia.Desktop.sln нээж, eIDMongolia.Client-ийг startup project болгоод F5.

Хоёр гүйцэтгэлийн горим (eIDMongolia.Client.csproj):

  • EidMsix тохируулаагүй → unpackaged single-file exe (dev, dotnet run).
  • EidMsix=truepackaged MSIX (publish / pack-msix.ps1, §8).

Note — build/run зөвхөн Windows дээр. Infrastructure давхарга нь Windows TFM (WinUI, CNG, DPAPI, PKCS#11) тул macOS/Linux дээр build хийгдэхгүй. CI-д Windows runner дээр бүрэн build + test + MSIX багцлалт хийгддэг (§7).

Тохиргоо

src/eIDMongolia.Client/appsettings.json нь канон тохиргоо; appsettings.Development.json overlay-гаар dev утга. Env-ээр override:

$env:EIDMNG_eIDMongolia__Backend__BaseUrl = "https://<staging>"

Бүх утга eIDMongoliaOptions-д bind хийгдэж DataAnnotations-оор эхэнд шалгагдана.

5. Гол урсгалууд

Нэвтрэлт (CitizenAuthService)

РД push: POST /api/login-notify {register}{sessionId, vc, pollToken}. register нь РД / civil-id / PNOMN-… — сервер алийг ч resolve хийдэг. Утас руу push (rate limit ~3/60с per target). Дараа poll.

QR: POST /api/start {}{sessionId, qr, deviceLinkBase, vc, pollToken}. qr (==sessionId)-ийг QR болгож (QRCoder) харуулна.

Poll (хоёуланд нийтлэг): GET /api/status?sessionId=&pollToken=. Сервер ~1с барьж буцаадаг, ViewModel дахин poll хийнэ. Локал session state machine (server/internal/domain/enums.go): state = RUNNING (үргэлжлүүл) | COMPLETE (терминал); endResult = OK | TIMEOUT | USER_REFUSED* | WRONG_VC | FAILED | …. OK дээр identity (name, idNumber, certificateLevel) inline ирнэ (bearer / cert PEM байхгүй) → identity cache-д хадгалагдана.

USB токен нэвтрэлт (M9.B) — идэвхгүй (stub). InitiateTokenChallengeAsync / VerifyTokenAsync нь ApiError.Internal("token_login_not_available_on_first_party_backend") буцаана — web backend дээр token/challenge·token/verify эквивалент байхгүй. "Токен" login таб цэвэрхэн degrade хийнэ.

Logout: сервер талд цуцлах session/bearer байхгүй — зөвхөн identity cache + локал session store-ийг цэвэрлэнэ.

PDF гарын үсэг (RpAuthService) — service бэлэн, UI алга

InitiateAsync нь PDF bytes-ийн SHA-256 digest-ийг локал тооцоод POST /api/sign-pdf-start {etsi, digestB64, fileName, callbackUrl} дуудна; PollAsync нь /api/status-аар (sessionId → pollToken-ийг per-session ConcurrentDictionary-д threading) төлвийг хардаг. OK дээр signatureValueB64 inline ирнэ. Гэвч энэ service-ийг дуудах ViewModel / Page одоогоор байхгүй, мөн тамгалагдсан PDF-ийг татдаг /api/sign-pdf-download-ийг дууддаггүй (§1 note үз).

Хяналтын самбар / Байгууллага

DashboardService.LoadAsync/api/dashboard + /api/devices + /api/activity (personId нь identity cache-аас). OrgService.ListAsync/api/representations (нэвтэрсэн иргэний ACTIVE төлөөлөл). Бусад org үйлдэл stub.

Баталгаажуулалт (VerifyPage)

Гэрчилгээг PEM paste эсвэл файлаар клиент талд задалж (ICertificateService), subject / хүчинтэй хугацаа / validity-г харуулна — backend шаардлагагүй.

6. USB token / смарт карт (self-contained)

Windows клиент нь USB токен / смарт картыг өөрийн дотоод хэрэгжүүлэлтээр дэмждэг (Infrastructure/Tokens/). (USB-токен нэвтрэлт нь first-party backend дээр эквивалентгүй тул идэвхгүй — §5; гэвч токен удирдлага бүрэн ажиллана.)

  • Windows CNG (Tokens/Cng/WindowsCngTokenProvider.cs) — Microsoft Base Smart Card Crypto Provider ашиглан Windows өөрөө PIN dialog харуулна.
  • PKCS#11 (Tokens/Pkcs11/Pkcs11TokenProvider.cs, Pkcs11Interop 5.2.0) — олдсон модуль тус бүрт нэг провайдер бүртгэдэг (OpenSC opensc-pkcs11.dll + Feitian eps2003csp11.dll зэрэг зэрэгцэн). Модулийн замыг TokenOptions.Pkcs11ModuleCandidates-аас (literal → System32 → ProgramFiles дарааллаар) resolve хийнэ; Pkcs11ModulePath override-оор ганц DLL заах боломжтой. TokenRegistry нь public key fingerprint-ээр давхар харагдсан ижил картыг dedupe хийдэг.

Токены төлөвийн машин (Domain/Tokens/TokenTypes.cs): Blank → Initialized → Provisioned → Enrolled. Enroll зам (SO PIN init → user PIN → keypair → CSR) нь CertEnrollmentService-д хүрдэг боловч тэр нь одоогоор stub (§2.2).

Note — gerege-token-kit-тэй холбоогүй. macOS клиент нь Swift SPM package desktop/gerege-token-kit/-ийг ашигладаг. Windows клиент түүнийг хэрэглэдэггүй — өөрийн C# CNG + Pkcs11Interop стек нь бие даасан.

7. CI / CD

Windows workflow: .github/workflows/windows-app.yml. desktop/windows-app/** эсвэл workflow өөрчлөгдөхөд ажиллана. Хоёр job:

Job Runner Trigger Юу хийдэг
build windows-latest (GitHub-hosted) push main / PR / dispatch restore → build (Debug) → test → dev-cert self-sign → MSIX багцлаж артефакт (eid-mongolia-windows-msix) болгон upload
selfhosted [self-hosted, windows-signing] (win11-build, 38.180.136.249) зөвхөн workflow_dispatch build → test → dev-cert self-sign → MSIX → signed .msix + public .cer-ийг deploy/downloads/-д commit → push

selfhosted job нь signed багцыг deploy/downloads/-руу git-ээр нийтэлдэг (forced-command SSH тул scp боломжгүй — staging ci-deploy git reset --hard-аар авч nginx /download/-д үйлчилнэ). Одоо dev-cert-ээр self-signed; жинхэнэ EV/OV cert ирэхэд New-DevCert.ps1-ийг орлуулна.

Note — build одоо ногоон. Хуучин "macOS/CI дээр build хийгддэггүй" төлөв хоцрогдсон: /api/* rewire + pipeline адаптаци дууссаны дараа solution нь CI Windows runner дээр бүрэн build + test + MSIX багцлалт хийдэг.

8. Packaging (MSIX / .appinstaller)

Бүрэн pipeline: tools/README.md. Товчхон (tools/*.ps1):

# 1) Машин тус бүрт нэг удаа (admin) — dev код-гарын үсгийн cert үүсгэнэ
.\tools\dev-cert\New-DevCert.ps1

# 2) Build + sign MSIX → artifacts/
.\tools\pack-msix.ps1 -Configuration Release -Platform x64 -Version 0.1.0.0

# 3) Локал суулгах
Add-AppPackage -Path .\artifacts\eid-mongolia-setup.msix
  • MSIX багцлалт нь WinApp SDK-ийн single-project MSIX MSBuild tooling-оор хийгддэг (dotnet publish -p:EidMsix=true); дотор нь makeappx/signtool-ийг Microsoft.Windows.SDK.BuildTools[.MSIX] NuGet багцаас авдаг тул системд Windows SDK суулгах шаардлагагүй. pack-msix.ps1 нь signtool-ийг PATH → Windows SDK → NuGet BuildTools дарааллаар resolve хийж signtool sign /tr <timestamp>-оор гарын үсэг зурна.
  • Гаралт: artifacts/eid-mongolia-setup.msix (тогтмол нэр — веб татах линк ба CI-д ашиглагдана) + artifacts/<Name>_<Version>_<Platform>.msix (versioned archive).
  • publish-appinstaller.ps1.appinstaller template-ийг рендэрлэж Windows-native auto-update тохируулна (launch дээр URL шалгаж, гарахад чимээгүй шинэчилдэг).
  • Publisher DN: CN=Gerege Systems LLC, O=Gerege Systems LLC, C=MN (Package.appxmanifest <Identity Publisher=…>, MSIX Name mn.eidmongol.desktop). Код-гарын үсгийн cert-ийн subject DN нь үүнтэй яг таарах ёстойNew-DevCert.ps1 ижил subject ашигладаг. Production-д Microsoft Trusted Root Program-д багтдаг EV/OV cert (DigiCert / GlobalSign / Sectigo) хэрэглэнэ. PFX-ийг хэзээ ч commit хийхгүй.

9. Татаж суулгах (эцсийн хэрэглэгч)

Signed MSIX + итгүүлэх cert нь /download/-д амьд (nginx deploy/nginx/staging.conf location ^~ /download/deploy/downloads/; веб дэх татах товч web/src/components/landing/DesktopAppSection.tsx, web/src/app/solutions/page.tsx):

Файл Веб линк
Windows суулгагч https://eidmongolia.mn/download/eid-mongolia-setup.msix
Итгүүлэх public cert https://eidmongolia.mn/download/eid-mongolia.cer

Одоогийн .msix нь dev-cert-ээр self-signed. Суулгахын өмнө eid-mongolia.cer-ийг Trusted People (эсвэл Trusted Root)-д итгүүлнэ: .cer-ийг татаж → давхар товшоод Install CertificateLocal MachineTrusted People. Дараа .msix-ийг давхар товшиж суулгана. Production-д жинхэнэ EV/OV cert ирэхэд энэ гар итгүүлэлт шаардагдахгүй.

10. Аюулгүй байдлын анхны утгууд

SecurityOptions + Infrastructure/Security/*-аас:

Асуудал Механизм
TLS TLS 1.3 (pinning идэвхтэй үед зөвхөн 1.3; эсрэг тохиолдолд 1.2+1.3)
Cert pinning SPKI-SHA256 (SpkiPinValidator, CertificateSpkiPins); RequireCertificatePinning (dev=false)
Секрет Windows DPAPI vault (DataProtectionSecretVault)
Biometric Windows Hello (WindowsHelloService), RequireWindowsHello (prod=true)
Idle lock IdleLockService (IdleTimeoutSeconds, default 900с)
Clipboard ClipboardService авто-цэвэрлэлт (ClipboardClearSeconds)
RASP RaspService — debug/tamper probe snapshot
Логгинг Serilog → Console + Debug + rolling file (%LOCALAPPDATA%/eIDMongolia/logs/)

Note — device-HMAC pipeline-д холбогдоогүй. Хуучин gerege /mobile/* device-HMAC гарын үсэг (HmacSigner + тест) кодод хэвээр байгаа боловч first-party загварт HTTP pipeline-д залгагдаагүй (§2.2).

11. Тест

tests/eIDMongolia.UnitTests — xUnit + FluentAssertions + NSubstitute. Одоогоор бодит тест нь Security/HmacSignerTests.cs (+ placeholder) — тестийн хамрах хүрээ хязгаарлагдмал, апп шинэ болохыг харуулна. CI-д (windows-app.yml) dotnet test-ээр ажилладаг.

12. Эх код (холбоос)

  • Windows апп: https://github.com/gerege-systems/eid-platform-mn/tree/main/desktop/windows-app
  • Backend интеграцийн буулгалт: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/BACKEND-INTEGRATION.md
  • HTTP клиент: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/Http/BackendApiClient.cs
  • Иргэний нэвтрэлт: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/Auth/CitizenAuthService.cs
  • PDF гарын үсэг (service): https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/Auth/RpAuthService.cs
  • Dashboard: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/Dashboard/DashboardService.cs
  • Байгууллага: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/Org/OrgService.cs
  • DI / HttpClient тохиргоо: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/DependencyInjection.cs
  • MSIX manifest: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Client/Package.appxmanifest
  • PKCS#11 токен: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/src/eIDMongolia.Infrastructure/Tokens/Pkcs11/Pkcs11TokenProvider.cs
  • Packaging: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/windows-app/tools/README.md
  • CI workflow: https://github.com/gerege-systems/eid-platform-mn/blob/main/.github/workflows/windows-app.yml
  • macOS клиент (зэрэгцүүлэл): DESKTOP_MACOS.md