Seitenbreite wirkt, vier Menueplaetze, Seiten ohne Kopfbereich
Drei Fragen, drei unterschiedliche Antworten. Die globale Seitenbreite war einstellbar und wirkte nur in eine Richtung: site.css schrieb width:min(1180px,...), also schluckte die 1180 jeden groesseren Wert aus dem Designbereich. Schmaler ging, breiter nicht, ohne jede Meldung. Die Zahl kommt jetzt aus dem Theme. Das ist der dritte Fehler dieser Art an einem Tag - nach der Rahmenstaerke und der Bildrundung -, und alle drei hatten dieselbe Ursache: CSS, das nie gegen eine Erwartung geprueft wurde. Menueplaetze und Menueart waren vermischt. Wo ein Menue steht, bestimmt der Block und war immer frei. Welche Eintraege es zeigt, bestimmt der Platz - davon gab es zwei, jetzt vier (Haupt, zweite, Fusszeile, Rechtliches). Wie es aussieht, war gar nicht einstellbar: jetzt waagerecht, untereinander oder aufklappbar als Burger. Der Burger ist ein details-Element, denn ein Menue, das ein Skript zum Oeffnen braucht, geht auf einer Seite ohne Skript nicht auf. "Seiten ohne Menue" war nicht moeglich - der Kopfbereich war ein Dokument fuer alle Seiten. Jetzt waehlt jede Seite: Standard, ein anderer Bereich, oder keiner. Dafuer musste die Regel "es gibt genau einen Kopf- und Fussbereich" fallen; sie war richtig, solange niemand waehlen konnte, und wurde falsch, sobald man waehlen kann. Ein bestehender Test, der diese Regel zusicherte, ist deshalb umgeschrieben und prueft jetzt die neue. Gespeichert wird die Wahl, nicht das Ergebnis: leer heisst Standard, none heisst keiner, sonst die Adresse. Ein Verweis auf einen geloeschten Bereich faellt auf den Standard zurueck, statt die Seite stillschweigend ohne Navigation auszuliefern. Neu im Ausbauplan: ein einzelnes install.php, das das Releasearchiv herunterlaedt und entpackt, damit niemand tausende Dateien per FTP hochladen muss. Mit den Regeln, die darueber entscheiden, ob das eine Hilfe oder eine Einladung ist: Adresse und SHA-256 stehen in der Datei und nicht im Formular, HTTPS mit Zertifikatspruefung, Schutz gegen ZIP-Slip, Selbstloeschung danach. 336 PHP-Tests / 1354 Assertions, 17 JS-Modelltests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
67b85751cf
commit
af3589c95c
22 files changed
+357
-26
No files matched your search
+13
-1
@@ -201,12 +201,24 @@ Umut: „Einen Installer brauche ich noch wie wordpress schritt für schritt all
|
||||
|
||||
**Ablauf, wie bei WordPress, aber ohne dessen Nachlässigkeiten:** eine Seite unter `/install`, die nur antwortet, solange keine Installation existiert, und danach dauerhaft 404 liefert. Schritte: (1) Systemprüfung – PHP-Version, benötigte Erweiterungen, Schreibrechte auf `var/` und den Medienordner, ob `public/` wirklich der Dokumentenstamm ist; jede Prüfung mit dem Satz, was zu tun ist, wenn sie fehlschlägt. (2) Datenbank – SQLite-Datei oder MySQL-Zugangsdaten, Verbindung sofort geprüft statt erst beim Speichern. (3) Migration ausführen, mit Ausgabe der angewandten Versionen. (4) Erstes Administratorkonto – Name und Passwort, dieselben Regeln wie in der Benutzerverwaltung. (5) Website – Name, Adresse, Sprache; dazu Kopf- und Fußbereich, Startseite sowie Datenschutz- und Impressumsgerüst anlegen. (6) Fertig: Anmeldung, und eine Liste dessen, was noch auszufüllen ist.
|
||||
|
||||
**Davor steht ein einzelner Dateidownload** (Nutzerauftrag vom 12.09.2026: „einen installer das eine php ist und alle dateien herunterladet dann muss man nicht alles hochladen. Am besten zip herunterladen dann entpacken“). Eine Datei `install.php` per FTP hochladen, im Browser aufrufen, fertig – statt tausende Dateien einzeln zu übertragen. Das ist der Teil, der über Sicherheit entscheidet, deshalb die Regeln vorweg:
|
||||
|
||||
- **Die Adresse steht in der Datei, nicht im Formular.** Ein Installer, der eine URL abfragt und den Inhalt entpackt, ist eine Einladung, fremden Code auf den Server zu legen. Geladen wird von einer festen Adresse des Releasearchivs.
|
||||
- **Die Prüfsumme steht ebenfalls in der Datei.** SHA-256 des Archivs, in `install.php` eingebacken und vor dem Entpacken verglichen. Stimmt sie nicht, wird abgebrochen – ohne Prüfsumme kein Entpacken, auch nicht mit Häkchen.
|
||||
- **HTTPS mit Zertifikatsprüfung**, kein `verify_peer => false`, kein Rückfall auf HTTP.
|
||||
- **Schutz gegen ZIP-Slip:** jeder Eintrag wird gegen das Zielverzeichnis geprüft, bevor er geschrieben wird. Ein Archiveintrag `../../.env` darf nichts außerhalb des Ziels anfassen.
|
||||
- **Nach dem Entpacken löscht sich die Datei selbst** und verweigert jeden weiteren Aufruf, sobald eine Installation existiert.
|
||||
- **Vorprüfung zuerst:** Schreibrechte, `ZipArchive` oder `PharData`, genug Platz, PHP-Version, und ob der Download überhaupt möglich ist (`allow_url_fopen` oder curl). Fehlt etwas, sagt die Seite welche Zeile in welcher Datei zu ändern ist – statt auf halbem Weg zu scheitern.
|
||||
- **`vendor/` ist im Archiv.** Damit ist die offene Frage aus Arbeitspaket J für diesen Weg entschieden: das Releasearchiv wird auf einem Build-Rechner erzeugt und bringt die Abhängigkeiten mit, weil geteiltes Hosting kein Composer hat.
|
||||
|
||||
Danach übernimmt der eigentliche Installer unten: Systemprüfung, Datenbank, Migration, erstes Konto, Website.
|
||||
|
||||
**Die drei Punkte, an denen WordPress-Installer regelmäßig zum Problem werden, und was hier anders läuft:**
|
||||
- **Der Installer schreibt `.env`,** braucht dafür Schreibrechte im Projektstamm und sagt es, statt die Datei stillschweigend nicht zu schreiben. `APP_SECRET` wird erzeugt, nicht abgefragt.
|
||||
- **Er ist nach dem ersten Durchlauf tot.** Gesperrt wird über den Zustand der Datenbank (existiert ein Konto?), nicht über eine Datei, die jemand löschen kann.
|
||||
- **Er legt keine Zugangsdaten in ein Protokoll und zeigt kein Passwort erneut an.**
|
||||
|
||||
Abnahme: eine leere Installation ist im Browser in sechs Schritten betriebsbereit, ohne Konsole. Ein zweiter Aufruf von `/install` liefert 404. Die Systemprüfung schlägt bei fehlenden Schreibrechten fehl und sagt, welcher Pfad fehlt. Getestet gegen ein leeres Verzeichnis und eine leere Datenbank, nicht gegen die Entwicklungsinstallation.
|
||||
Abnahme: **eine einzelne hochgeladene PHP-Datei genügt**, um von einem leeren Webspace zu einer betriebsbereiten Installation zu kommen; eine leere Installation ist im Browser in sechs Schritten betriebsbereit, ohne Konsole. Ein manipuliertes Archiv (falsche Prüfsumme) wird abgelehnt, und ein Archiveintrag mit `..` im Pfad landet nirgends. Ein zweiter Aufruf von `/install` liefert 404. Die Systemprüfung schlägt bei fehlenden Schreibrechten fehl und sagt, welcher Pfad fehlt. Getestet gegen ein leeres Verzeichnis und eine leere Datenbank, nicht gegen die Entwicklungsinstallation.
|
||||
|
||||
### O – Sicherung und Wiederherstellung als Funktion (Nutzerauftrag vom 12.09.2026)
|
||||
|
||||
|
||||
Reference in new issue
Block a user