diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 6a842c5..0000000 --- a/TODO.md +++ /dev/null @@ -1,217 +0,0 @@ -# U-Navigator – TODO - -Stand: 2026-07-14 - -Ziel dieser Liste ist eine sichere, testbare und veröffentlichungsfähige Version des Plugins. Schreibzugriff sollte erst empfohlen werden, wenn alle Punkte unter P0 abgeschlossen und auf einer echten Unraid-Installation geprüft sind. - -## P0 – Sicherheitsblocker - -### Geschützte Root-Pfade - -- [ ] Eine zentrale Funktion `unav_assert_mutable_path()` einführen. -- [ ] Löschen eines konfigurierten Root-Pfads verbieten. -- [ ] Verschieben und Umbenennen eines konfigurierten Root-Pfads verbieten. -- [ ] Rekursive Rechte- oder Besitzeränderungen direkt am Root-Pfad verbieten. -- [ ] Quelle und Ziel auch im Worker unmittelbar vor der Operation erneut prüfen. -- [ ] API-Tests für Delete, Move und Permissions auf `/mnt/user` beziehungsweise einem Test-Root ergänzen. - -Abnahmekriterium: Kein mutierender API-Aufruf kann den erlaubten Root selbst verändern oder entfernen. - -### Sichere Symlink-Behandlung - -- [ ] Eingabepfad und kanonischen Sicherheitspfad getrennt speichern. -- [ ] Für Dateioperationen `lstat()` statt ausschließlich `realpath()` verwenden. -- [ ] Beim Löschen eines Symlinks ausschließlich den Link entfernen, niemals dessen Ziel. -- [ ] Copy und Move von Symlinks entweder kontrolliert implementieren oder ausdrücklich ablehnen. -- [ ] Symlinks auf Ziele außerhalb erlaubter Roots für Listing, Vorschau und Download weiterhin blockieren. -- [ ] Rekursive Operationen dürfen Symlinks nicht verfolgen. -- [ ] Tests für interne Symlinks, externe Symlinks, kaputte Symlinks und Symlink-Schleifen ergänzen. - -Abnahmekriterium: Eine Aktion auf einem Symlink wirkt niemals unerwartet auf dessen Ziel. - -### Upload-Pfade härten - -- [ ] Relative Pfade vollständig validieren; `..` nicht still entfernen, sondern als Fehler ablehnen. -- [ ] Absolute Pfade, Nullbytes und leere Pfadsegmente ablehnen. -- [ ] Jeden Parent-Pfad prüfen, bevor ein Verzeichnis angelegt wird. -- [ ] Beim Anlegen von Upload-Ordnern keine vorhandenen Symlinks durchlaufen. -- [ ] Zielpfad unmittelbar vor Schreiben beziehungsweise Rename erneut validieren. -- [ ] Temporäre Upload-Dateien in einem privaten Verzeichnis ablegen und zufällige IDs verwenden. -- [ ] Abgebrochene und veraltete Upload-Fragmente automatisch entfernen. -- [ ] Tests für Symlink-Parents und konkurrierende Pfadänderungen ergänzen. - -Abnahmekriterium: Ein Upload kann außerhalb der erlaubten Roots weder Dateien noch Verzeichnisse erzeugen. - -### CSRF und Request-Schutz - -- [ ] Auf einer aktuellen Unraid-7.x-Installation prüfen, ob die WebGUI-Schicht Plugin-PHP-Endpunkte automatisch gegen CSRF schützt. -- [ ] Direkte POST-Requests ohne, mit falschem und mit gültigem `csrf_token` testen. -- [ ] Falls nötig, CSRF-Prüfung zentral in `common.php` implementieren. -- [ ] Mutierende Endpunkte ausschließlich per POST erlauben. -- [ ] Für nicht erlaubte Methoden `405 Method Not Allowed` und einen `Allow`-Header liefern. -- [ ] Für JSON- und Formular-Requests dieselben Schutzregeln anwenden. -- [ ] Authentifizierungsverhalten bei direktem Aufruf aller API-Endpunkte prüfen und dokumentieren. - -Abnahmekriterium: Kein mutierender Aufruf funktioniert ohne gültige Unraid-Sitzung und gültigen CSRF-Schutz. - -### Ressourcenlimits - -- [ ] Maximale Upload-Dateigröße konfigurierbar machen. -- [ ] Maximale Gesamtgröße und Dateianzahl pro Upload begrenzen. -- [ ] Raw-Uploads streamen, statt den gesamten Request in den PHP-Speicher zu laden. -- [ ] Maximale Dateianzahl und Gesamtgröße für ZIP-Downloads festlegen. -- [ ] Vor ZIP-Erstellung freien temporären Speicher prüfen. -- [ ] ZIP-Erstellung als Hintergrundjob ausführen. -- [ ] Laufzeit- und Rekursionstiefenlimits für Size, Copy, Delete und Permissions einführen. -- [ ] Große Verzeichnisse im Listing paginieren oder begrenzen. - -Abnahmekriterium: Einzelne Requests können weder PHP-Speicher noch temporären Speicher unkontrolliert erschöpfen. - -## P1 – Datenintegrität und Jobs - -### Robuste Copy-/Move-Operationen - -- [ ] Kopien zunächst unter einem temporären Zielnamen erstellen. -- [ ] Ziel erst nach erfolgreicher vollständiger Kopie atomar sichtbar machen. -- [ ] Unvollständige Ziele bei Fehlern zuverlässig entfernen. -- [ ] Quelle bei einem Cross-Filesystem-Move erst nach verifizierter Kopie löschen. -- [ ] Dateigröße und optional Prüfsumme vor dem Löschen der Quelle vergleichen. -- [ ] Rechte, Owner, Gruppe und Zeitstempel erhalten. -- [ ] Verhalten für Sparse Files, Hardlinks und Special Files definieren. -- [ ] Zielkonflikte auch unmittelbar vor dem finalen Rename prüfen. -- [ ] Tests für Fehler mitten in einer Verzeichniskopie ergänzen. - -### Job-System - -- [ ] Job-Verzeichnis mit `0700` statt `0777` erstellen. -- [ ] Jobdateien atomar über temporäre Datei plus Rename schreiben. -- [ ] Beim Lesen passende Locks beziehungsweise atomare Snapshots verwenden. -- [ ] Kryptografisch zufällige Job-IDs verwenden. -- [ ] Prüfen, ob der Worker wirklich gestartet ist; nicht nur den Shell-Exitcode auswerten. -- [ ] Hängende Jobs nach Timeout als fehlgeschlagen markieren. -- [ ] Abbruch-Endpunkt für laufende Jobs implementieren. -- [ ] Abbruchstatus in rekursiven Operationen regelmäßig prüfen. -- [ ] Abbruchschaltfläche im Transfer-Panel ergänzen. -- [ ] Alte abgeschlossene Jobs automatisch löschen. -- [ ] Gleichzeitige, kollidierende Jobs auf denselben Pfaden erkennen und serialisieren oder ablehnen. -- [ ] Jobfehler mit verständlicher Meldung und technischem Logeintrag trennen. - -### Löschschutz - -- [ ] Optionalen Papierkorb pro Root implementieren. -- [ ] Direktes permanentes Löschen als gesonderte Aktion behandeln. -- [ ] Anzahl und geschätzte Größe vor rekursivem Löschen anzeigen. -- [ ] Mehrfachauswahl vor dem Start vollständig validieren. -- [ ] Optional eine zweite Bestätigung für sehr große Löschvorgänge verlangen. - -## P1 – Tests - -### PHP-Backend testen - -- [ ] Eigenständige Tests für die tatsächlich ausgelieferten PHP-Endpunkte aufbauen. -- [ ] Die Tests in einer Unraid-kompatiblen PHP-Version ausführen. -- [ ] Listing innerhalb und außerhalb erlaubter Roots testen. -- [ ] Upload, Download, Preview, Copy, Move, Delete, Size und Permissions testen. -- [ ] Read-only-Modus für jede mutierende Aktion testen. -- [ ] Zielkonflikte und ungültige Request-Methoden testen. -- [ ] Sonderzeichen, Unicode, sehr lange Namen und versteckte Dateien testen. -- [ ] Mehrere konfigurierte Roots testen. -- [ ] Regressionstests für alle P0-Sicherheitsfälle ergänzen. - -### CI und statische Prüfung - -- [ ] `php -l` für alle PHP-Dateien in CI ausführen. -- [ ] JavaScript-Syntaxprüfung ausführen. -- [ ] ShellCheck für `build-plugin.sh` aktivieren. -- [ ] XML beziehungsweise PLG-Manifest validieren. -- [ ] Paket bauen und mit den Quellen vergleichen. -- [ ] Manifest-Prüfsumme automatisch verifizieren. -- [ ] Tests bei jedem Push und Pull Request ausführen. - -### Test auf echter Unraid-Instanz - -- [ ] Installation auf unterstützten Unraid-Versionen testen. -- [ ] Upgrade von einer vorherigen Plugin-Version testen. -- [ ] Deinstallation und Neuinstallation testen. -- [ ] Verhalten bei gestopptem und gestartetem Array prüfen. -- [ ] User Shares, Pools und Disk Shares getrennt prüfen. -- [ ] Große Ordner und große Dateien testen. -- [ ] WebGUI-Neustart und Server-Neustart während laufender Jobs testen. -- [ ] Alle offiziellen Themes und mobile Darstellung prüfen. - -## P2 – Konfiguration und Bedienung - -### Root-Konfiguration - -- [ ] Erlaubte Roots in `settings.json` speichern. -- [ ] Einstellungsoberfläche zum Hinzufügen und Entfernen von Roots bauen. -- [ ] Nur existierende absolute Verzeichnisse akzeptieren. -- [ ] Gefährliche Systempfade wie `/`, `/boot`, `/etc`, `/usr`, `/var` und `/root` standardmäßig verbieten. -- [ ] Pro Root einen Anzeigenamen und Read-only-Status erlauben. -- [ ] Änderungen an Roots erst nach erneuter serverseitiger Validierung übernehmen. -- [ ] Root-Auswahl im Explorer anbieten. - -### Dateimanager-Funktionen - -- [ ] Neuen Ordner anlegen. -- [ ] Leere Datei anlegen. -- [ ] Umbenennen mit serverseitiger Namensvalidierung verbessern. -- [ ] Suche nach Dateiname im aktuellen Ordner implementieren. -- [ ] Optionale rekursive Suche mit Ergebnislimit ergänzen. -- [ ] Sortierung nach Name, Typ, Größe und Änderungsdatum anbieten. -- [ ] Versteckte Dateien ein- und ausblendbar machen. -- [ ] Breadcrumb-Navigation ergänzen. -- [ ] Dateibaum beziehungsweise Share-Navigation ergänzen. -- [ ] Tastaturbedienung für Auswahl, Öffnen, Kopieren, Verschieben und Löschen verbessern. - -### Transfer-Oberfläche - -- [ ] Reale Fortschrittswerte nach Bytes statt nur nach Top-Level-Einträgen berechnen. -- [ ] Quelle, Ziel, Geschwindigkeit und Restzeit anzeigen. -- [ ] Fehlgeschlagene Jobs wiederholbar machen. -- [ ] Abgeschlossene Einträge einzeln oder gesammelt entfernen. -- [ ] Uploads pausieren und abbrechen können. - -### Vorschau und Download - -- [ ] MIME-Typ anhand des Dateiinhalts prüfen, nicht nur anhand der Erweiterung. -- [ ] SVG-Vorschau sicher behandeln oder deaktivieren. -- [ ] Medien- und PDF-Vorschau mit geeigneten Sandbox-Headern testen. -- [ ] HTTP-Range-Requests für große Audio- und Videodateien unterstützen. -- [ ] RFC-konforme UTF-8-Dateinamen im `Content-Disposition`-Header verwenden. -- [ ] Einzeldateien streamen, ohne unnötige Pufferung. - -## P2 – Protokollierung und Betrieb - -- [ ] Audit-Log für Upload, Copy, Move, Delete und Permissions einführen. -- [ ] Zeitpunkt, Aktion, Quelle, Ziel, Ergebnis und Fehler protokollieren. -- [ ] Keine CSRF-Tokens oder sensiblen Inhalte ins Debug-Log schreiben. -- [ ] Logrotation und maximale Loggröße definieren. -- [ ] Diagnoseexport für Supportfälle anbieten. -- [ ] Gesundheitsstatus für Job-Worker und temporären Speicher anzeigen. - -## P3 – Paketierung und Veröffentlichung - -- [ ] Version nur an einer Stelle pflegen und beim Build überall einsetzen. -- [ ] `package.json`-Version mit der Plugin-Version synchronisieren. -- [ ] Reproduzierbare TGZ-Pakete mit stabiler Sortierung und Zeitstempeln erzeugen. -- [ ] Nach Möglichkeit SHA-256 zusätzlich zur MD5-Prüfung veröffentlichen. -- [ ] Minimale und getestete Unraid-Version im Plugin-Manifest angeben. -- [ ] Changelog pro Version vollständig pflegen. -- [ ] Release-Build in einer sauberen Working Copy erzeugen. -- [ ] Community-Applications-Metadaten validieren. -- [ ] Installations-, Update- und Rollback-Anleitung ergänzen. -- [ ] Sicherheitsmodell und bekannte Einschränkungen dokumentieren. -- [ ] Read-only als empfohlenen Standard deutlich in README und Oberfläche anzeigen. - -## Definition of Done für die erste produktive Version - -- [ ] Alle P0-Punkte sind abgeschlossen. -- [ ] PHP-Integrationstests decken alle mutierenden Operationen ab. -- [ ] Keine Root- oder Symlink-Regression ist offen. -- [ ] CSRF und Authentifizierung sind auf echter Unraid-Hardware bestätigt. -- [ ] Große Uploads, Downloads und Verzeichnisse besitzen getestete Limits. -- [ ] Fehlgeschlagene Copy-/Move-Jobs hinterlassen keine unbemerkten Teildaten. -- [ ] Installation, Upgrade, Neustart und Deinstallation wurden getestet. -- [ ] Paketinhalt und Manifest-Prüfsumme stimmen überein. -- [ ] Dokumentation und Changelog entsprechen dem ausgelieferten Funktionsumfang. diff --git a/build-plugin.sh b/build-plugin.sh index ba7c4d3..f4bfe08 100755 --- a/build-plugin.sh +++ b/build-plugin.sh @@ -2,7 +2,7 @@ set -eu PLUGIN="u-navigator" -VERSION="2026.07.14.r008" +VERSION="2026.07.04.r007" PKG_DIR="packages" WORK_DIR=".plugin-build" PKG_NAME="${PLUGIN}-${VERSION}.tgz" diff --git a/packages/u-navigator-2026.07.14.r008.tgz b/packages/u-navigator-2026.07.14.r008.tgz deleted file mode 100644 index 4d5e7d8..0000000 Binary files a/packages/u-navigator-2026.07.14.r008.tgz and /dev/null differ diff --git a/plugin-root/usr/local/emhttp/plugins/u-navigator/U-Navigator.page b/plugin-root/usr/local/emhttp/plugins/u-navigator/U-Navigator.page index 24f2bba..08ac58d 100644 --- a/plugin-root/usr/local/emhttp/plugins/u-navigator/U-Navigator.page +++ b/plugin-root/usr/local/emhttp/plugins/u-navigator/U-Navigator.page @@ -11,7 +11,26 @@ $plugin = "u-navigator"; $version = "__VERSION__"; ?> -
+Initialisiere...
+