Skip to content

Releases: AurevionSec/openSylab

OpenSylab v1.1.0 — UX overhaul + hardening

Choose a tag to compare

@AurevionSec AurevionSec released this 07 Jul 13:24
29fb7ef

OpenSylab v1.1.0 — post-1.0 hardening + a full UX overhaul + an outward-presentation pass.

Post-1.0 hardening, a full UX overhaul, and an outward-presentation pass. Backed by
multi-agent audits (a 28-finding bug/inconsistency audit, a ~82-finding UX survey,
and a presentation review). 236 backend + 46 frontend + 8 E2E tests, all green in CI.

Added

  • Toast notifications on every create / update / delete (writes are no longer silent).
  • Read-only detail view (DetailModal) reachable by every role, including VIEWER.
  • Responsive sidebar drawer — off-canvas navigation with a hamburger on small screens.
  • URL-persisted filters & pagination on all list pages (deep-linkable, back-button-safe).
  • Cross-entity navigation — Sample ↔ Order ↔ Result IDs are now links.
  • Shared StatusBadge (rectangular tags) and a useModalA11y focus-trap hook.
  • Playwright end-to-end suite (8 tests: login, navigation, API read, mobile drawer) wired into CI.
  • CITATION.cff and a branded social-preview card.

Changed

  • Activated the design-token layer — the project runs Tailwind v4, which ignored
    tailwind.config.js; a v4 @theme block now makes the Neo-Clinical palette and the
    JetBrains Mono data font actually render.
  • Accessibility — focus-trapped modals with Esc/restore, aria-live error/status
    regions, a skip-to-content link, aria-current navigation, associated form labels.
  • Flat surfaces (borders instead of shadows) per the design language.
  • README rewritten — English-only, ISO 15189 wording tightened to "-oriented", a
    Scope & limitations disclaimer, live CI/release badges, Docker-first quick start.
  • Docs de-staled — correct Docker ports, current versions, complete env-var tables,
    fixed dead links; new docs/README.md index. Fresh 1.0 screenshots.

Fixed

  • Concurrency (critical): serialize the shared SQLite connection with a recursive
    mutex + busy_timeout — concurrent request threads could otherwise collide on
    transactions and corrupt the audit hash chain.
  • RBAC: sample → VALIDATED release now requires ADMIN (matching order/result); the
    JWT effective role is derived from the live DB user, so role changes apply immediately.
  • Audit trail: HL7/FHIR exports now log PHI disclosure; logAudit fails closed
    instead of writing a chain-breaking row on HMAC failure.
  • Data integrity: CSV result import no longer mis-splits quoted fields or coerces
    malformed reference bounds to 0.0; NaN/inf values are no longer flagged NORMAL; the
    result-edit modal recomputes the flag when the value/range changes.
  • Frontend: user roles normalized (fixes blank badges + an edit-dropdown privilege
    hazard); LOGIN_FAILED shown in the audit log; global search routes orders/results
    correctly; a stale token no longer blocks login; list-refetch races guarded; fixed the
    Tailwind-v4 modal-backdrop regression.

Security

  • Externalize Docker Compose secrets to an untracked .env; fix the Dockerfile
    healthcheck; untrack the .vite build cache and debug HTML.

Assets

  • OpenSylab-linux-x86_64 — prebuilt backend binary (Linux x86-64, dynamically linked; needs OpenSSL 3.x + SQLite3 at runtime).
  • sbom-frontend.cdx.json — CycloneDX SBOM of the frontend npm dependencies (383 components).
  • sbom-repo.cdx.json — CycloneDX SBOM of the repository / backend dependencies (via Trivy).
  • SHA256SUMS — checksums; verify with sha256sum -c SHA256SUMS.

Docker: git clone … && cp .env.example .env && docker compose up -dhttp://localhost:9090 (admin/admin, change immediately).
See the CHANGELOG and docs.

OpenSylab v1.0.0

Choose a tag to compare

@AurevionSec AurevionSec released this 05 Jul 10:10
4d4ce73

First 1.0 release of OpenSylab — an open-source, ISO 15189-oriented LIMS for medical diagnostics (C++17 backend + React 19 / TypeScript frontend, MIT).

This release consolidates the post-0.9.0 hardening, governance, architecture, and test work.

Highlights

🔒 Security

  • Resolved all open Dependabot (11) and CodeQL (3) alerts; npm audit clean.
  • Least-privilege CI permissions; PBKDF2-HMAC-SHA256 in the test-data generator.

🏗️ Architecture

  • ApiServer.cpp God-function decomposition (Phase A): ApiRouter::handleRequest reduced from 2781 → 440 lines by extracting every inline route into a dedicated per-route handler method via a shared RouteContext. All ~30 routes (health/openapi, audit, stats, HL7/FHIR, MFA, users, samples/orders/results × GET/POST/PUT/DELETE). Behaviour-preserving, independently reviewed.

📋 Governance & Ops

  • SECURITY.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md, issue/PR templates.
  • docs/SECRET_ROTATION.md — JWT secret-rotation runbook (with the audit-HMAC-key caveat).

✅ Tests

  • 235 unit tests, including new API-layer regression coverage for the ISO 15189 compliance branches (immutability 409, invalid status-transition 409, ADMIN-only VALIDATE 403, delete guards).

Notes

  • Default credentials admin/admin are for development only — change in production.
  • Configure TLS (--tls-cert/--tls-key/--force-https) and set OPENSYLAB_JWT_SECRET + OPENSYLAB_AUDIT_HMAC_KEY (≥32 chars) for production.

Full changelog: CHANGELOG.md

v0.9.0 — Architecture Modernization + Security Hardening

Choose a tag to compare

@AurevionSec AurevionSec released this 25 May 11:15

v0.9.0 — Architecture Modernization + Security Hardening

Architecture

  • nlohmann/json v3.11.3 via FetchContent — replaced hand-rolled JSON parser throughout the API layer
  • spdlog v1.14.1 structured logging — LOG_* macros, JSON output, rotating file sink
  • IDatabase interface — pure virtual interface decouples API layer from SQLite implementation
  • PostgreSQLDatabase stub — implements IDatabase; production support in v1.1
  • Database migration frameworkschema_migrations table, 3 versioned migrations, runs automatically on startup
  • OpenAPI 3.0 specificationdocs/openapi.yaml (23 paths), served unauthenticated at GET /api/v1/openapi.yaml
  • Configuration fileopensylab.conf INI format with 11 settings, search order: --config → env var → cwd → /etc/opensylab/

Security

  • HMAC-SHA256 audit hash chain — mandatory OPENSYLAB_AUDIT_HMAC_KEY (≥32 chars, hard-fail at startup); tamper-evident chain across all audit entries
  • GET /api/v1/audit/verify — ADMIN-only endpoint returns first broken chain entry on integrity failure
  • TOTP Base32 enrollmentPOST /auth/mfa/enroll, POST /auth/mfa/verify-enrollment, DELETE /auth/mfa

Bug Fixes (Waves 33–36, 28 confirmed bugs)

  • iat < pwChangedAt (was <=) — tokens issued before password change are now correctly invalidated
  • LOGIN_FAILED audit action type — failed logins were incorrectly logged as UPDATE
  • Logout persists to DB first — eliminates crash-window token replay
  • TOTP time-step int64_t — prevents Y2038 integer overflow
  • verifyUserMfa now uses verifyAndConsumeMfaCode — TOTP anti-replay was not enforced in CLI path
  • HL7/FHIR import endpoints were unreachable — fell into JSON parse block and returned 400/404
  • Content-Type: application/json enforced on all POST/PUT (HTTP 415 if absent)
  • Negative Content-Length bypass closed (TLS and plain HTTP paths)
  • Body size capped at 10 MB when Content-Length header is absent
  • VALIDATED order status now requires ADMIN role (OPERATOR could previously set it)
  • Future registration_date rejected in API handlers, updateSample, and CSV import
  • createSamplesBatch uses INSERT OR IGNORE — duplicates no longer abort the whole batch; each rejected duplicate gets an ISO 15189 audit entry
  • VALIDATED/REJECTED TestResult terminal state enforced in CLI edit and validate flows
  • HL7/FHIR result count capped at 10 000 per import
  • CSV sample_id/patient_id length enforced (64 chars); result fields enforced (255 chars)
  • CSV validateHeader accepts extra trailing columns
  • Logout DB expiry uses token exp claim instead of now + expirationMinutes
  • Audit chain anchor preserved after retention purge; verifyAuditChain uses BEGIN DEFERRED for snapshot isolation

Frontend

  • Vitest v2.1.9 + React Testing Library — 46 unit tests (AuthContext, API client, utilities, Login component)
  • ErrorBoundary component

Test Coverage

228/228 backend unit tests passing. Build: 0 errors, 0 warnings (GCC + Clang).

v0.8.2 — Test-Regression-Fix & Docs

Choose a tag to compare

@AurevionSec AurevionSec released this 14 May 22:14

Fehlerbehebungen (Tests & Validierung)

  • isValidStatusString / isValidPriorityString: Neue Validierungsmethoden für Sample und Order — entkoppeln Input-Validierung von DB-Deserialisierungs-Fallback-Logik
  • ApiServer.cpp: Query-Parameter-Validierung (?status=, ?priority=) nutzt jetzt isValidStatusString/isValidPriorityString statt try/catch — verhindert Regression durch Safe-Fallback (bughunt-43)
  • CsvImport.cpp: Status-Validierung beim CSV-Import prüft via isValidStatusString — korrumpierter Status erzeugt wieder Fehlermeldung
  • test_api.cpp: SerializeResultJson-Assertion an String-Format von order_id angepasst
  • Alle 181 Tests grün (vorher: 177/181)

Dokumentation

  • frontend/README.md: Veraltete v0.6.0/v0.6+-Annotationen entfernt, Version auf 0.8.2 aktualisiert
  • README.md: Badges auf v0.8.2 / 181 passing aktualisiert
  • TODO.md: Aktuelle Version auf v0.8.2, Nächste Version v0.9.0

v0.8.1 — Bug-Hunt & Security Hardening

Choose a tag to compare

@AurevionSec AurevionSec released this 14 May 19:13

OpenSylab v0.8.1

Bug-Hunt & Security Hardening — 30+ Fixes, 12 Review-Iterationen, 3 aufeinanderfolgende saubere Passes.

Sicherheit

  • isApiKeyValid thread-safe refactoriert (optional<string> statt Shared-State)
  • Rate-Limiter Bypass geschlossen: Query-Strings (?foo) umgingen /auth/login-Limit
  • RBAC-Reihenfolge korrigiert: Auth-Check vor JSON-Parse auf User-Routen
  • verifyPassword gehärtet: Exception-Handling für stoi, Iterations-Schranke, Salt-Guard
  • base64Encode: Integer-Overflow durch implizite Promotion behoben

Backend-Fixes

  • bindAndListen(): FD-Leak auf Fehlerpfaden geschlossen
  • ~ApiServer: Destruktor ergänzt, running_=false vor Socket-Close
  • createSample: updated_at=0 Bug behoben — wird jetzt via std::time() gebunden
  • evaluateFlag(): Floating-Point-Gleichheitsvergleich entfernt
  • stringToStatus/Flag/Priority: Throws durch sichere Fallback-Werte ersetzt
  • Audit-Export: Tmp-File-Leak + Kollisionsschutz via PID + Sequenz-Zähler

Frontend-Fixes

  • Sidebar-Logout navigiert sofort zu /login
  • AuditLog: cancelRef Race-Condition behoben
  • Import: csvError-State (TypeScript-Compilefehler), 5-MB-Guard + reader.onerror für alle 3 Import-Typen
  • ResultCreateModal: Auto-Flag überschreibt manuelle Auswahl nicht mehr

Tests & Build

  • Doppelte Makrodefinitionen in test_runner.cpp entfernt
  • HL7/FHIR-Tests nutzen uniqueDbPath() statt hardcodierten Namen
  • CMakeLists.txt: version.h ins Build-Tree, nicht Source-Tree

Dokumentation

  • README.md vollständig neu geschrieben: 10 Screenshot-Platzhalter mit Aufnahme-Anweisungen, aktualisierte Feature-Tabellen, API-Übersicht
  • CHANGELOG.md: v0.8.1-Eintrag ergänzt

Checksums & Build:

  • 75 Unit-Tests passing
  • TypeScript strict: 0 Errors
  • C++17, CMake 3.15+, OpenSSL, SQLite3

OpenSylab v0.8.0 — Production-Ready Security & Infrastructure

Choose a tag to compare

@AurevionSec AurevionSec released this 12 May 00:07

OpenSylab v0.8.0

22 of 28 v0.8 TODO items completed — focused on production-readiness.

Security (P0) — All 5 items completed

  • Health endpoint GET /api/v1/health (unauthenticated)
  • Rate limiting on /api/v1/auth/login (10 req/60s per IP, HTTP 429)
  • Forced password change on first login with admin/admin
  • --force-https + --tls-cert / --tls-key flags
  • API key RBAC hardened (role column, no more hardcoded OPERATOR)

Core Features (P1) — 4 of 8 items

  • HL7 v2.5.1 HTTP endpoints: POST /api/v1/hl7/import, GET /api/v1/hl7/export/{id}
  • FHIR R4 HTTP endpoints: POST /api/v1/fhir/import, GET /api/v1/fhir/export/{id}
  • Audit-Log CSV export button in UI
  • Status transition validation enforced in backend (422 on invalid transitions)

UI/UX (P2) — 9 of 10 items

  • Import page: tabbed layout for CSV / HL7 v2.5.1 / FHIR R4
  • Dashboard stats: priority distribution and critical count from server (not client-side limit:100)
  • Results list: order_id shows string format (e.g. O-2024-001) not numeric FK
  • Sample responses include updated_at timestamp
  • Breadcrumb bug fixed (/audit-log now shows "Audit Log")
  • Search prefix fixed (O- prefix for orders)
  • canWrite guard on Results create button
  • Password strength indicator on Profile page
  • Sidebar dead code removed (hardcoded badge '24')

Infrastructure (P3) — 3 of 5 items

  • CI/CD: .github/workflows/ci.yml (backend cmake+tests, frontend tsc+build)
  • Docker healthcheck enabled (backend uses /api/v1/health)
  • CORS origin deduplication (read once at construction)

Quality

  • 181/181 unit tests passing
  • TypeScript strict: 0 errors
  • All changes build cleanly

Remaining for v0.9: opensylab.conf, frontend unit tests (Vitest), OpenAPI/Swagger, DB migration system, single-threaded server improvement

v0.7.0 — Security, RBAC & Production Hardening

Choose a tag to compare

@AurevionSec AurevionSec released this 11 May 22:42

OpenSylab v0.7.0

Release Date: 2026-05-11
181 Unit-Tests passing · 0 TypeScript errors · 0 npm vulnerabilities


🔐 Sicherheit

  • JWT-Authentifizierung mit HMAC-SHA256 (ersetzt API-Key-Only-Modus vollständig)
  • PBKDF2-HMAC-SHA256 Passwort-Hashing, 210.000 Iterationen (OWASP 2023)
  • RBAC auf allen Schreib-Endpoints: ADMIN / OPERATOR / VIEWER / CUSTOM
  • MFA (TOTP RFC 6238) — vollständiger Zwei-Schritt-Login, ±1 Zeitfenster
  • LDAP-Authentifizierung mit lokalem Shadow-Account
  • Letzter-Admin-Schutz in updateUser, deleteUser, assignUserRole — transaktional, TOCTOU-frei
  • Fehler-Sanitisierung: keine SQLite-Internals in HTTP-Antworten

🧪 Labordaten

  • Auto-Flag: NORMAL / LOW / HIGH / CRITICAL (margin-basiert: 50 % des Referenzintervalls)
  • Soft-Delete für Proben (ARCHIVED), Aufträge (CANCELLED), Ergebnisse (REJECTED)
  • Batch-CSV-Import für Proben und Ergebnisse mit Fehler-Tracking pro Zeile
  • HL7 v2.5.1 ORU^R01 Import/Export mit vollständigem Feld-Escaping
  • FHIR R4 Bundle Import/Export
  • Server-seitige Paginierung auf allen Listen-Endpoints
  • Globale Suche im Header navigiert per ?q= zu Samples/Orders

🖥️ Frontend

  • TypeScript strict mode — keine any-Typen
  • RBAC-Guards auf allen Create/Edit/Delete-Buttons und Sidebar-Einträgen
  • Responsive Tabellen (Tablet-optimiert)
  • Vollständiger MFA-Login-Flow im UI
  • Single Source of Truth für Versionsnummer: CMakeLists.txtinclude/version.h

🐛 Bugfixes

56 Bughunt-Iterationen, 60+ Bugs behoben — darunter:

  • DELETE /api/v1/users/:id war durch Routing-Block unerreichbar
  • sqlite3_errmsg() nach ROLLBACK lieferte leere Fehlermeldung (43 Stellen)
  • ResultEditModal nutzte numerische PK statt result_id für PUT-Requests
  • Alle Export-Funktionen entfernen Teildateien auf jedem Fehlerpfad
  • MFA-403-Interceptor blockierte Login-Flow im Frontend
  • TOCTOU-Race in updateUser/deleteUser/assignUserRole

Upgrade von v0.6

git pull origin main
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel $(nproc)
cd frontend && npm install && npm run build

Wichtig: OPENSYLAB_JWT_SECRET Umgebungsvariable setzen — der Dev-Secret löst jetzt eine Warnung aus.


Full Changelog: CHANGELOG.md