Aller au contenu

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

eID платформын macOS (SwiftUI) desktop клиент — гар утасны e-ID Mongolia апп-аар QR / РД push нэвтрэлт хийж, PDF-д qualified цахим гарын үсэг зурах ширээний програм. Эх код: desktop/macos-app/ (XcodeGen төсөл eIDMongolia).

First-party client. iOS апп-тай яг ижил зарчмаар энэ клиент нь RP биш — клиентэд ямар ч RP secret, RP UUID, бүртгэл байхгүй. Бүх дуудлага өөрийн web backend-ийн нийтийн /api/* route-уудаар (browser-тэй яг ижил зам) дамжина. Go RP-API (/v3/*)-ийн RP_API_SECRET-ийг зөвхөн web сервер (web/src/lib/rpclient.ts) барьдаг. Тиймээс энэ бол RP интеграц БИШ — RP интеграцийг web сервер өөрөө хийдэг, desktop нь түүний нийтийн урд талыг л хэрэглэдэг.

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

  • Нэвтрэлт — QR код эсвэл РД/иргэний дугаараар push илгээж, утасны апп дээр PIN1-ээр баталгаажуулна. Web сервер гарын үсгийг криптограф баталгаажуулаад cert subject-оос нэр + иргэний дугаар + documentNumber-ийг задалж буцаана — desktop өөрөө cert parse хийхгүй.
  • PDF гарын үсэг — PDF сонгоод SHA-256 digest-ийг локал тооцож, утасны апп дээр PIN2-оор зурна. Тамгалагдсан (PAdES/PKCS#7 + баталгаажуулах хуудас) PDF-ийг ~/Downloads-д хадгална.
  • Identity handle — Bearer session байхгүй; нэвтрэлтээс олдсон documentNumber нь identity handle болж Keychain-д хадгалагдана (restore үед Touch ID gate).

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

Клиент нь web app-ийн нийтийн /api/* route-уудыг (web/src/app/api/*) дууддаг. Ашигладаг route-уудыг эх кодоос (Core/Network/Endpoints.swift, Core/Network/APIClient.swift) жагсаавал:

Route Метод Зориулалт
/api/start POST QR session эхлүүлэх → {sessionId, qr, deviceLinkBase, vc, pollToken}
/api/login-notify POST РД/иргэний дугаараар push → {sessionId, vc, pollToken} (rate limit 60с/3)
/api/status GET ?sessionId=&pollToken= long-poll — сервер ~1с барина, клиент давтана
/api/sign-pdf-start POST {etsi, digestB64, fileName, callbackUrl} → PIN2 push → {sessionId, vc, pollToken} (rate limit 60с/3 per etsi)
/api/sign-pdf-download POST multipart file + sessionId + pollToken → тамгалагдсан PDF bytes
/api/health GET Серверийн эрүүл мэнд шалгах

Note. pollToken нь start / login-notify / sign-pdf-start хариунд ирдэг бөгөөд /api/status, /api/sign-pdf-downloadзаавал шаардлагатай. sessionId нь QR-д ил тул дангаараа PII унших эрх олгохгүй — pollToken нь session эхлүүлэгчид л олгогддог (Endpoints.swift, мөр 18-23).

Секрет, RP UUID, RP нэр клиентэд байхгүй (Core/Network/AppConfig.swift). Серверийн суурь URL-ийн эх сурвалжийн дараалал (эхний хоосон биш нь ялна):

Эх сурвалж Тайлбар
UserDefaults["API_BASE_URL_OVERRIDE"] Settings UI-аар тохируулна
env API_BASE_URL Орчны хувьсагч
Default DEBUG: http://localhost:3000, Release: https://eidmongolia.mn

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

  • macOS 14+ (deployment target 14.0)
  • Xcode 16+, Swift 5.10
  • brew install xcodegenproject.yml-аас .xcodeproj үүсгэнэ
  • SPM хамаарлууд: Sparkle 2 (auto-update), ../gerege-token-kit (локал path package)

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

cd desktop/macos-app
xcodegen generate
xcodebuild -project eIDMongolia.xcodeproj -scheme eIDMongolia \
           -configuration Debug -destination 'platform=macOS,arch=arm64' build
open eIDMongolia.xcodeproj    # ⌘R

Чухал. -scheme eIDMongolia ашиглана, -target биш — локал GeregeTokenKit SPM package resolve-д scheme шаардлагатай.

Локал туршилт

DEBUG build-ийн default сервер нь web (:3000). Go API болон web-ийг хоёуланг нь асаана:

cd ../../server && SMARTID_RP_API_SECRET= go run ./cmd/smartid   # Go API :8080
cd ../../web && npm run dev                                       # web :3000

Өөр хаяг руу заахдаа Settings → Сервер (эсвэл env API_BASE_URL). Утасны апп мөн ижил Go серверт заасан байх ёстой.

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

Нэвтрэлт (Features/Login/LoginView.swift)

QR (initQR): 1. POST /api/start{sessionId, qr, vc, pollToken}. 2. qr (= sessionId) утгыг CoreImage-ээр QR болгож харуулна; vc баталгаажуулах кодыг дэлгэцэнд гаргана. 3. Утсаараа QR скан → PIN1-ээр зөвшөөрнө.

РД push (initiateLogin): 1. Хэрэглэгч РД / иргэний дугаар оруулна (register, uppercase болгоно). 2. POST /api/login-notify {register}{sessionId, vc, pollToken}; утас руу push илгээгдэнэ.

Ерөнхий дуусгал (APIClient.waitForAuth): - GET /api/status?sessionId=&pollToken= -г COMPLETE болтол ~400мс завсартай давтана (сервер тал 1с барьдаг). - COMPLETE + OK үед web сервер cert subject-оос name / idNumber (serialNumber → иргэний дугаар)-ийг задалж өгнө. - Үр дүн StoredIdentity (documentNumber, fullName, civilID, certificateLevel) болж Keychain-д хадгалагдана.

PDF гарын үсэг (Features/Sign/SignView.swift)

Web demo хуудастай (web/src/app/demo/page.tsx) яг ижил урсгал:

  1. PDF сонгоно (25 MB хүртэл). Эх PDF-ийн SHA-256 digest-ийг клиент дээр локал тооцно (CryptoKit.SHA256) — stamp хийх ИЖИЛ байт.
  2. POST /api/sign-pdf-start {etsi, digestB64, fileName, callbackUrl:""}{sessionId, vc, pollToken}. etsi = нэвтрэлтээс олдсон иргэний дугаар (civilID, fallback nationalID, uppercase). Утас руу PIN2 push илгээгдэнэ. callbackUrl хоосон — утас тусдаа төхөөрөмж тул Web2App буцалт байхгүй.
  3. GET /api/status?sessionId=&pollToken= poll (auth-тай ижил зам) → COMPLETE/OK.
  4. POST /api/sign-pdf-download (multipart file + sessionId + pollToken) → тамгалагдсан PDF bytes → ~/Downloads/<нэр>_signed.pdf (нэр давхцвал тоон дагавар).

SEC-3: гарын үсгийн урсгалыг эхлүүлэхийн өмнө SecurityGuard.enforce() — tamper/anti-debug шалгалт (Release-д идэвхтэй).

6. USB token kit

desktop/gerege-token-kit/ нь FEITIAN USB токенд зориулсан dependency-free локал SPM package (локал PKCS#11/APDU, сервертэй холбогдохгүй). macOS апп ../gerege-token-kit-ийг path package-аар автоматаар resolve хийж, токены Core/Token/ (TokenManager, TokenProvisioner) болон Tokens feature-д хэрэглэнэ. Дэлгэрэнгүй: USB token kit.

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

  • macOS апп: https://github.com/gerege-systems/eid-platform-mn/tree/main/desktop/macos-app
  • Network давхарга: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/macos-app/Core/Network/Endpoints.swift
  • HTTP client: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/macos-app/Core/Network/APIClient.swift
  • Нэвтрэлт: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/macos-app/Features/Login/LoginView.swift
  • Гарын үсэг: https://github.com/gerege-systems/eid-platform-mn/blob/main/desktop/macos-app/Features/Sign/SignView.swift
  • Компонентын дэлгэрэнгүй: desktop/macos-app/CLAUDE.md, нууцлалын хатуужилт: desktop/macos-app/SECURITY-HARDENING.md