Die Zeichen-Whitelist /^[A-Za-z0-9._-]+$/ liess Namen wie ".." durch, weil
Punkt und Bindestrich erlaubte Zeichen sind -- path.join(desktopDistDir, '..')
loest aber in den Elternordner auf und unterlaeuft genau die Verteidigung in
der Tiefe (T-18-02), die diese Zeile laut Kommentar herstellen soll. Jetzt
werden "." und ".." explizit abgelehnt UND der aufgeloeste Pfad zusaetzlich
gegen desktopDistDir geprueft (haelt auch kuenftige Varianten ab, falls die
Whitelist anderswo wiederverwendet wird). Neue Testfaelle fuer manifest-Eintraege
namens "..", "." und "../manifest.json".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ein kaputter Plattform-Eintrag (z. B. fehlendes name-Feld oder ungueltiger
sha256) fiel bisher erst spaeter unbemerkt durch -- entry.name === undefined
wurde zu "undefined" gecoerct und als Dateiname gesucht. getManifest()
prueft jetzt jeden vorhandenen Plattform-Eintrag (name: string, size: number,
sha256: 64-stelliger Hex-String) und behandelt ein kaputtes Manifest wie ein
fehlendes (404 + Warn-Log), statt die kaputte Form durchzureichen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die duenne Strecke Skript -> Abbild -> API beweisen (D-08, D-10):
- desktop-collect.sh sammelt AppImage/exe ein, schreibt manifest.json
(Version, Kanal, Commit, Groesse, SHA-256) ohne Secrets
- apps/api/src/desktop/: neues Modul mit GET /desktop/latest und
GET /desktop/download/:platform, beide @Public(); Plattform-Whitelist
vor jedem Dateisystemzugriff, Dateiname ausschliesslich aus dem
Manifest (T-18-01, T-18-02)
- packages/shared: DesktopPlatform/-Manifest(File)/-Latest(Response)
Typen
- Dockerfile kopiert desktop-dist/ in die runner-Stufe; desktop-dist/
per .gitkeep + .gitignore versioniert (leeres Verzeichnis, Pakete
bleiben ungetrackt)
- HTTP-Durchstich-Spec (8 Tests) via NestFactory, kein fs-Mock; echtes
Temp-Verzeichnis + unabhaengig berechneter SHA-256
Abweichung: DesktopController braucht @Inject(DesktopService) explizit
— Vitest transpiliert ueber esbuild, das emitDecoratorMetadata nicht
abbildet, sonst bleibt desktopService bei einem echten NestFactory-Bau
undefined (Rule 3, Blocker).
Lokal bewiesen: neu gebautes API-Abbild liefert /desktop/latest (200)
und /desktop/download/linux (200, attachment) aus, auch ueber
/api-proxy/ des Web-Containers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>