Das 0.1.0-Paket enthielt keinen update-agent. "Jetzt installieren" sucht ihn
ueber UpdateClient.ResolveAgentPath() neben der Anwendung - ohne ihn konnte
sich keine Installation selbst aktualisieren.
- BundleUpdateAgent (App-csproj): legt den Agenten beim Publish fuer eine
Laufzeitkennung neben die Anwendung; fuer ein Release ein Abbruch, wenn er fehlt
- scripts/release.ps1: unveraenderte Vorlage des Deploymentcenters
- scripts/publish-release.ps1: holt den Agenten mit Pruefsumme aus installer.json
und legt die Packager-Konfiguration neben pack-and-deploy
- Version 0.2.0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Umsetzung von #567.
Entscheidung Richard, 13.09.2026: Geheimnisse verwalten wir ausschliesslich im
Desktop, und selbst dort erst nach zusaetzlicher Passwortabfrage.
Bisher sah und aenderte jeder, der die Desktop-Oberflaeche offen vor sich
hatte:
- Polymarket-Konten mit ApiKey, ApiSecret, ApiPassphrase und PrivateKey
- Master-Key, OpenRouter-Key, Watchdog-Token und Lizenzschluessel
- Mullvad-Account und Polygon-RPC-URL mit Alchemy-Key, offen im Editor
- das WebUI-Token, per "Anzeigen" lesbar
Jetzt gesperrt, bis entsperrt:
- Tab "Polymarket Accounts": Gesperrt stehen die Konten gar nicht im
visuellen Baum. Das Raster bleibt leer, der Editor mit den Private Keys
ebenfalls; nichts ist nur verdeckt.
- Master-Key erzeugen, OpenRouter-, Watchdog- und Lizenzschluessel setzen.
- Mullvad-Account und Polygon-RPC-URL: mit [SensitiveSetting] markiert und im
Editor ausgeblendet.
- WebUI-Zugang: Gesperrt steht das Token nicht einmal maskiert im Feld.
Speichern ist mitgesperrt, weil es den Feldinhalt als Token schreibt;
gesperrt und leer haette es das Token geloescht.
- Frei bleiben Lizenzpruefung und Test-Heartbeat, weil sie keinen Schluessel
zeigen.
Kern im Core (PolyTrader.Core.Security), weil nur dort testbar:
- SettingsPasswordStore: PBKDF2-HMAC-SHA256, 600 000 Iterationen, Salt, eigene
Datei settings-password.json neben master.key, atomar geschrieben und nur fuer
den Besitzer lesbar. Nicht in server_settings.xml, die seit #561 das WebUI
mitschreibt. Ein vorhandenes Passwort wird nie ueberschrieben.
- SettingsLock:
- erstes Festlegen mit Wiederholung und mindestens 10 Zeichen
- zwei freie Fehlversuche, danach 5 s bis 5 min Wartezeit, in der auch das
richtige Passwort nicht geprueft wird
- Sperre nach 5 Minuten ohne geschuetzte Aktion und beim Verlassen der
Einstellungen
- eine unlesbare Passwortdatei entsperrt nie und gilt auch nicht still als
"kein Passwort"
- Protokoll ohne eingegebene Werte
Oberflaeche: PasswordDialog deklarativ in .axaml, Sperr-Leiste ueber den Tabs.
Die PBKDF2-Pruefung dauert etwa eine halbe Sekunde und laeuft nicht im
UI-Thread.
Grenzen:
- Die Sperre schuetzt gegen jemanden an einer entsperrten Desktop-Sitzung. Wer
Dateizugriff hat, liest master.key selbst. Deshalb gibt es kein "Passwort
vergessen": Wer settings-password.json loeschen kann, braucht keins.
- Die Wartezeit nach Fehlversuchen beginnt nach einem Neustart von vorn.
- "Datenbankeinstellungen": Eine Ansicht dafuer gibt es im Desktop nicht; die
Verbindungszeichenfolge steht nur in appsettings.Local.json. Entsteht eine,
gehoert sie hinter dieselbe Sperre.
Tests: 20 fuer Passwortdatei und Sperre (Festlegen, Fehlversuche, Wartezeit,
Leerlauf, unlesbare Datei, Aendern, Iterationszahl aus der Datei, Dateirechte)
und 5 fuer die Markierung der Geheimnisfelder. Die Oberflaeche selbst wird auf
der VM abgenommen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mit dem vorigen Commit sind versehentlich vier .idea/-Dateien mitgegangen
(git add -A). Sie enthalten maschinenspezifische Pfade und Index-Layouts und
blockierten den git pull auf der Linux-Testmaschine, wo Rider dieselben Dateien
lokal angelegt hat.
Die Projektkonvention ignoriert IDE-Dateien ohnehin (.vs/, *.user) - .idea/
fehlte dort nur, weil bisher niemand mit Rider gearbeitet hat.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Repo enthaelt ab jetzt ausschliesslich plattformneutralen Code. Build gruen
(0 Fehler), 476 Tests gruen, Linux-Publish der Avalonia-App verifiziert.
Rueckfallebene ist der Tag winforms-final, der jetzt auch auf dem Server liegt.
WinForms endgueltig ausgebaut (P11/L5):
- PolyTrader.App.csproj aus PolyTraderSharp.sln genommen und geloescht
- Ui/, Models/, Licensing/, services/, Properties/, Resources/icons/,
Program.cs, favicon.ico entfernt - rund 4.500 LOC generierter Designer-Code
- Root-appsettings.json entfernt: exaktes Duplikat der Avalonia-Kopie, die die
App tatsaechlich liest. Zwei Dateien mit gleichem Inhalt laufen frueher oder
spaeter auseinander.
- Kein net10.0-windows mehr im Repo; Build-Warnungen von 23 auf 15 gesunken
(die CS0169 aus den Designer-Resten sind weg)
PNG-Symbole gerettet statt geloescht:
Die Avalonia-App band sie per ..\..\Resources\*.png aus dem Repo-Root ein und
haette sie mitverloren. Sie liegen jetzt in src/PolyTrader.App.Avalonia/Assets/,
wo sie hingehoeren. Der avares-Pfad "Assets/<datei>.png" bleibt unveraendert -
in der gebauten Assembly nachgeprueft.
LicenseLabrador abgeloest (D-6):
- LicenseLabrador.Client aus lib/nuget entfernt, Quellen-Mapping in
NuGet.Config auf Deploymentcenter.* reduziert, lib/nuget/README.md neu
- Bewusste Abweichung vom Plan: die Watchdog*-Felder in ServerSettings bleiben.
D-1 hat sie auf die Deploymentcenter-API umgewidmet statt sie zu ersetzen;
sie werden aktiv benutzt. Die Planzeile stammte aus der Zeit davor.
Weitere Altlasten:
- agentspace/ (30 Dateien: WinForms-Designer-Patcher, fix_mongo.py nach der
MySQL-Migration, tmp/test/scratch-Skripte) entfernt
- Ideen-fuer-Mittwoch.txt entfernt - Inhalt ist laengst umgesetzt
- tote .gitignore-Regel fuer agentspace/antigravity/ entfernt
- lokal entfernt (nicht versioniert): MongoDB/-Exporte, data.db, .bak-Datei
Dokumentation nachgezogen:
- ANALYSE-Linux-Portierung.md auf Revision 6, P11/L5 als erledigt
- LEITFADEN: Abschnitt B vollstaendig aufgeloest, A5 prueft ab jetzt gegen
einen Worktree des Tags statt gegen den Arbeitsbaum
- UMSETZUNGSPLAN-Watchdog-LicenseLabrador-Integration.md als ABGELOEST
gekennzeichnet, D-6 im Deploymentcenter-Plan auf den Iststand gezogen
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sicherungscommit vor dem Aufraeumen des Repos, damit nachvollziehbar bleibt,
welcher Stand vor der Bereinigung galt. Build gruen, 476 Tests gruen.
Zwei Straenge, die sich ueber .csproj, Program.cs und appsettings.json
ueberschneiden und darum gemeinsam abgelegt werden:
Deploymentcenter-Integration (P3c, Plan D-0 bis D-5 code-seitig fertig):
- Deploymentcenter.Client 2.5.0 als lokales Paket, Source-Mapping erweitert
- DeploymentcenterOptions, DeploymentcenterErrorReporter, LicenseGate/LicenseCli
- WatchdogHeartbeatService auf die Deploymentcenter-API umgestellt
(version, os, checks, metrics, status stopped)
- Security: MasterKeyResolver, SecretRedactor, FilePermissions
- Directory.Build.props mit zentraler Version 0.1.0 (Packager-Versionsdisziplin)
- deploy/: Packager-Vorlage und systemd-Unit; echte Zugangsdaten bleiben
ueber .gitignore aussen vor
- setup.json fuer die Erstinstallation
- UMSETZUNGSPLAN-Deploymentcenter-Integration.md; ANALYSE-Linux-Portierung.md
verweist auf den neuen Plan
Einfenster-Shell (UI-Redesign):
- ShellWindow + ShellNavModel als Seitenleisten-Shell
- WindowMenuBar und WindowMenuModel entfallen
- Modul- und Kernfenster auf die Shell-Einbettung angepasst
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Behebt den kritischsten Befund (Klartext-Private-Keys in remote-gehosteter MySQL):
- SecretProtection (Core/Security): AES-256-GCM, authenticated. Master-Key AUSSERHALB der DB
(env POLYTRADER_MASTER_KEY, sonst gitignorierte master.key). Format enc:v1:base64(nonce|tag|ct).
Alt-Klartext (ohne Praefix) wird gelesen und beim Speichern verschluesselt (selbstheilend).
Ohne Master-Key: Passthrough + deutliche Startwarnung (kein stiller Sicherheitsverlust).
- EncryptedStringConverter (EF ValueConverter) auf core_accounts.PrivateKey/ApiSecret/ApiPassphrase;
Spalten 256->512 verbreitert (Migration EncryptAccountSecretsWidenColumns, offline generiert).
- Program.cs: Master-Key vor der Hydration laden; nach Start einmalige/idempotente Re-Encryption
vorhandener Klartext-Credentials. Auch in --smoke-ui verdrahtet.
- CoreDbContextFactory nutzt jetzt fixe Server-Version (offline-Migrationsgenerierung, kein DB-Zugriff).
13 neue Krypto-Tests (Round-Trip, Nonce-Frische, Manipulations-/Falscher-Key-Erkennung, Passthrough,
Key-Formate). Build 0 Fehler, 324 Tests gruen, --smoke-ui ok (Warnung ohne Key wie erwartet).
AKTIVIERUNG (im Zielland): POLYTRADER_MASTER_KEY setzen (zufaelliger 32-Byte-Base64-Key, SEPARAT sichern!)
+ Migration anwenden (dotnet ef database update --context CoreDbContext). Danach Alchemy-/Mullvad-Secrets
aus F3 rotieren. WICHTIG: Master-Key-Verlust = Kein Zugriff auf die Keys mehr.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Erster Commit des bestehenden monolithischen WinForms-Copytraders,
inklusive der Alt-Backups (*.bak), damit diese dauerhaft in der
Historie rekonstruierbar bleiben. Threema-Lib unter libs/ wurde
vendored (nested .git entfernt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>