37c2930af0a53bbd9ad5b1b38af4258c5e94d717
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
51c3d4402b |
Audit des Creator Workspace, App-Symbole fuer alle Apps der Domain
AUDIT (Auftrag: vollstaendiger Durchgang, Fehler direkt beheben)
Ausgangslage waren 40 Pruefungen mit 1616 Einzelpunkten, alle gruen.
Acht neue Pruefungen kamen dazu; sie haben gefunden, was die alten nicht
sehen konnten.
Der schwerste Fund: Die Zugangsschranke verglich req.path EXAKT gegen
eine Liste. Express raeumt Punkt-Segmente selbst weg, mehrfache
Schraegstriche aber nicht. Damit kam //workspace/start.html OHNE
Anmeldung mit HTTP 200, und ein Creator bekam ueber
/workspace//personen.html die Verwaltungsseite. Die DATEN waren nie
betroffen (nachgemessen: 404 bzw. 401). Behoben durch Normalisierung
UND eine Umkehr der Logik -- jetzt ist jede .html geschuetzt ausser der
Anmeldeseite, statt nur die in der Liste. Eine vergessene neue Seite
steht damit nicht mehr versehentlich offen.
Weiter behoben:
* Kaputter/abgebrochener Rumpf ergab 500 in HTML statt 400 in JSON --
die Oberflaeche ruft ueberall a.json() und lief in einen zweiten
Fehler; der Knopf hing ohne Meldung.
* POST /zustand/sichern war der einzige von 60 schreibenden Wegen
ohne Herkunftspruefung.
* workspace-sicherung.js gab interne Pfade in Fehlermeldungen nach
aussen; alle 23 anderen Module antworten neutral.
* admin_notiz war als einziges von 14 Feldern ohne <label>.
* Der aktive Filter hatte keinen sichtbaren Fokus (CSS-Spezifitaet
0,3,0 schlug 0,2,0) -- genau der Knopf, auf dem man steht.
* h1 -> h3 ohne Zwischenstufe auf zwei Seiten.
* HSTS ging auch ueber http mit (RFC 6797, 7.2 verbietet das).
* upgrade-insecure-requests galt auch auf 127.0.0.1 -- dadurch war
WebKit/Safari ueberhaupt nicht pruefbar, also der Browser, den
jedes iPhone benutzt.
* pruef-grosscheck las readdirSync(".") und pruefte aus server/
gestartet NULL oeffentliche Seiten -- meldete aber "ok".
Neue Pruefungen: struktur, schranke, haerte, alle-wege,
barrierefrei-workspace, breiten, tempo-workspace, browser.
Jede mit Gegenprobe und mit der geprueften Anzahl in der Bedingung.
Vier davon sind beim Bauen durch die eigene Gegenprobe aufgeflogen und
haetten sonst dauerhaft gruen gemeldet, ohne etwas zu messen.
APP-SYMBOLE (Wunsch: alle Apps der Domain, jede anders, ausser
safeaddress)
Zehn Apps, zehn Stile, zehn in OKLCH gerechnete Farben. Zusammen haelt
sie dasselbe Logo, dieselbe Eckenrundung und eine gemeinsame gedeckte
Farbreihe. Beim Bauen wird gemessen, ob sich das Logo vom Grund abhebt
(19 bis 58 Helligkeitsstufen).
Dabei aufgefallen: Das Kundenportal hatte kein eigenes Manifest und
trug Namen und Symbol der Webdesign-Seite. Der Workspace hatte gar
keins und war als App nicht installierbar. Beide haben jetzt eins.
Geaendert wurde AUSSCHLIESSLICH das Symbol. Ein Zwischenstand hatte
auch die Themenfarben gesetzt; das war mehr als bestellt und wurde
zurueckgenommen.
Werkzeuge: tools/logo-freistellen.mjs, tools/app-symbole.mjs,
tools/app-symbole-einbinden.mjs -- alles im Browser gerechnet, kein
Bildprogramm, keine neue Abhaengigkeit.
Gitea und Nextcloud sind bereits live und nachgeprueft.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
80639d0bab |
Abnahme vor der Vorstellung: eine tote Kachel gefunden und geschlossen
Morgen wird die Seite als Produkt vorgestellt. Deshalb eine Pruefung,
die es bisher nicht gab: server/pruef-live-abnahme.mjs geht gegen die
ECHTE Domain statt gegen einen Server auf diesem Rechner.
Der Unterschied ist nicht theoretisch. Zwischen "laeuft bei mir" und
"laeuft im Netz" liegen Caddy, Cloudflare, der Cache-Stempel, das
Zertifikat und der Dienst-Neustart -- genau dort ist am 18.08. und am
22.08.2026 schon zweimal etwas haengengeblieben, das lokal tadellos war.
Sie geht 26 Seiten in DREI Gestalten durch:
RECHNER 1440 px
HANDY 390 px, mit Fingerbedienung
INSTALLIERT als App vom Startbildschirm -- ohne Adresszeile und ohne
Zurueck-Knopf des Browsers. Dort faellt auf, was man mit
Browserleiste nie merkt.
Gemessen je Seite: Konsolenfehler, fehlgeschlagene Anfragen, seitlicher
Ueberlauf, tote Verweise, fehlende Bilder, ueberhaupt Inhalt, Titel.
Dazu die App selbst: Manifest, Name, Start ohne Browserleiste, alle vier
Startbildschirm-Symbole einzeln abgefragt, Hintergrunddienst angemeldet
und aktiv.
DER EINE ECHTE FUND: Auf links.html war die Kachel "Merchandise / Shop"
ein <a href="#"> -- sie sah aus wie ein Verweis, liess sich anklicken
und tat nichts. Auf der Kachel steht "Folgt in Kuerze"; genau dann darf
sie nicht klickbar sein. Ein Knopf, der nichts tut, ist schlimmer als
gar keiner: Man drueckt ihn zweimal und haelt die Seite fuer kaputt.
Jetzt ein <div> mit denselben Klassen -- gleiches Aussehen, kein
Versprechen mehr, das die Seite nicht halten kann.
ZWEI FEHLALARME, beide in MEINER Pruefung, beide aufgeschrieben:
* Sie meldete "fehlende Bilder" auf zwei Seiten. Es waren versteckte
Platzhalter (<img hidden> ohne src), die JavaScript erst fuellt --
der Normalzustand. Jetzt zaehlen nur sichtbare Bilder mit Quelle.
* Sie meldete "manifest.json nicht ladbar", waehrend curl gleichzeitig
200 lieferte. Die Probe stand noch auf about:blank und holte von
dort -- fremde Herkunft, der Browser lehnt ab. Sie hat also nicht
die Seite geprueft, sondern sich selbst. Erst navigieren, dann
messen.
Die beiden anderen href="#" auf der Seite (index.html, streamplan.html)
bleiben: Sie sind versteckt und werden von JavaScript gefuellt, sobald
es etwas zu verlinken gibt. Geprueft wird nur, was man auch sieht.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
0404f8c0c1 |
Dreizehn Lecks: eine Managerin sah die Creator aller anderen
Wunsch: "jeder manager soll auch immer nur seine und die seiner scouts
zugeteilten creator und creator daten sehen. und nicht die der anderen."
DIE KETTE WAR GEBAUT -- SIE WURDE NUR NICHT BENUTZT
Manager -> seine Scouts -> deren Creator steht seit dem 01.09.2026 an
genau einer Stelle (betreuteIds). Die Frage war eine andere: Benutzt sie
auch JEDER Weg, der Creator-Daten herausgibt? Ueber zwanzig Stellen
prueften die ROLLE statt der ZUTEILUNG -- "ist Leitung? dann alles".
NICHT GELESEN, SONDERN GEMESSEN
server/pruef-manager-sicht.mjs baut zwei Managerinnen mit vollstaendig
getrennten Creators. Bei der fremden heisst ALLES "GEHEIM..." -- Aufgabe,
Termin, Bereichseintrag, Datei, Steckbrief, Content-Saeule. Danach wird
jede der 31 Leseschnittstellen abgefragt und die ganze Antwort danach
durchsucht. Ein Leck faellt damit auf, egal wo es sitzt und egal, ob ich
es beim Lesen uebersehen haette.
GEFUNDEN: DREIZEHN. Alle geschlossen:
Kalender fremde Fristen -- besonders unangenehm, weil es
nicht wie ein Leck aussieht: eine kleine orange
Marke mit einem Titel, in dem fremde Vorhaben stehen
Personenauswahl alle Namen im Zuweisungsfeld
Dateien alle Namen in der Freigabe-Auswahl
Uebersicht Gesamtuebersicht ueber ALLE Creator
Report Auswahl UND Auswertung ueber den ganzen Bestand
Start-Check alle Creator zur Auswahl
Steckbriefe Bild, Kanaele, "ueber mich" von allen
Profile alle Profile, samt interner Notiz
Schulung Schulungsstand aller Creator
Suche Creator-Profile aller -- die unauffaelligste Stelle:
Man sucht etwas anderes und bekommt fremde Namen
Content-Balance Themensaeulen fremder Kanaele (die Abfrage daneben
war korrekt eingeschraenkt, DIESE hatte eine eigene
Bedingung)
darfCreator eine einzige Zeile -- sie hing an Profil,
Start-Check und Uebersicht gleichzeitig. Es reichte,
eine Nummer in die Adresse zu schreiben.
Die Antwort steht jetzt an EINER Stelle: sichtbareCreatorIds und
sichtbarePersonenIds in workspace.js. Rueckgabe null heisst "alle" und
gilt allein DogFather -- bewusst kein leeres Feld: Eine leere Liste
bedeutet "niemand", und die Verwechslung der beiden macht aus einer
Sperre eine Freigabe.
ZWEI DINGE, DIE ICH MIR SELBST NACHTRAGEN MUSS
1. Beim Stopfen fehlte einmal ein Import. Der Weg warf einen Fehler,
antwortete 503 -- und weil in einer Fehlermeldung kein "GEHEIM" steht,
meldete die Pruefung "kein Leck". Sie war gruen, weil der Weg KAPUTT
war. Die Pruefung zaehlt jetzt beides: nichts durchsickern UND
antworten.
2. Ein Fehlalarm: Die Suche gibt den SUCHBEGRIFF in ihrer Antwort
zurueck. Wer nach "GEHEIM" sucht, findet das Wort zwangslaeufig --
auch bei null Treffern. Ich haette um ein Haar ein Leck "repariert",
das es nie gab. Das Echo wird jetzt entfernt, bevor gemessen wird.
FOLGEN, bewusst in Kauf genommen:
* Ein Manager ohne Zuteilung sieht keinen Creator. Die Uebersicht sagt
ihm das jetzt in einem Satz, statt leer zu bleiben.
* Er kann nur noch IN SEINEN Creator-Bereichen schreiben (darfCreator).
ZWEI PRUEFUNGEN UMGEDREHT statt geloescht -- eine geloeschte Pruefung
hinterlaesst keine Spur davon, dass hier einmal etwas anderes galt:
pruef-uebersicht ("Manager sieht dasselbe" -> "nur seine zugeteilten",
mit beiden Faellen) und pruef-scout-zuteilung ("sieht die ganze
Personenliste" -> "landet auf der Startseite").
GEPRUEFT: 43 neue Pruefungen, dazu 23 bestehende Laeufe gruen --
Startansicht 133, Rollen 97, Kalender 84, Serien 67, Steckbrief 65,
Handy 50, Sicht 48, Ampel 47, Content 45, Aufgabenbrett 44, Schulung 41,
Bereiche 37, Scout-Zuteilung 36, Uebersicht 35, Personenliste 33,
Freie Namen 32, Team 30, Protokoll-Loeschen 20, Personenformular 20,
Formulare 19, Betreuung 18, Code 17, Grosscheck 15.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d8720debc1 |
Personen & Automationen gehoeren DogFather allein -- und das Formular laeuft nicht mehr ueber
ZWEI MELDUNGEN.
1. "DAS SIEHT JA MAL RICHTIG SCHEISSE AUS"
Die Rollenauswahl im Formular "Neue Person" lief unten aus dem
Formular heraus und legte sich ueber die Personenliste darunter.
Die Ursache war keine schlampige Gestaltung, sondern eine Regel, die
fuer etwas anderes gemacht ist: `.neu__raster > *` (aufgaben.css) gibt
JEDEM direkten Kind ein Raster mit fester Zeilenhoehe von 44 px, damit
Beschriftung und Eingabefeld in allen Spalten auf einer Linie sitzen.
Fuer ein einzeiliges Feld ist das genau richtig. Die Rollenauswahl ist
aber kein Feld, sondern ein Block aus vier hohen Karten -- die passten
nicht in 44 px, und was nicht hineinpasst, steht eben daneben.
Das Formular ist jetzt aus dem Spaltenraster geloest und liest sich
von oben nach unten: NAME (schmal, ein Name braucht keine 1200 px),
ROLLE (volle Breite, vier gleich breite Karten), Knoepfe. Das ist
nicht nur reparierter Ueberlauf, sondern auch die Reihenfolge, in der
man die Sache tatsaechlich entscheidet.
Dazu zwei Kleinigkeiten, die den Unterschied machen: Das Namensfeld
war ohne Rasterzeile 60 px hoch geworden (`height: 100%` einer Zeile,
die es nicht mehr gibt) -- hoeher als die Knoepfe daneben, was nach
Versehen aussieht, weil es eins war. Und die gewaehlte Rolle traegt
jetzt ein HAEKCHEN, nicht nur einen etwas helleren Rahmen: Genau die
Art Unterschied, die im Kontrastmodus verschwindet und fuer
farbunsichere Augen nie existiert hat.
2. "DIE MANAGER SOLLEN DIESE KATEGORIEN GARNICHT SEHEN"
"Personen & Zugaenge" und "Automationen" gehoeren ab sofort allein
DogFather.
Bei den Personen war es ohnehin ein Widerspruch im eigenen Haus: In
der Rollenauswahl steht seit jeher "Manager -- dieselben Rechte wie
DogFather, AUSSER der Personenverwaltung". Die Kachel stand trotzdem
bei ihm, und die Schranke liess ihn hinein: Codes erneuern, sperren,
Zuteilungen aendern. Eine Beschreibung, die etwas anderes sagt als die
Software, ist schlimmer als beides einzeln -- man weiss danach nicht
mehr, welcher von beiden man glauben soll.
Umgesetzt auf DREI Ebenen, weil Wegnehmen was man SIEHT kein
Rechteentzug ist:
1. die Kachel erscheint nicht mehr
2. die Seite leitet zur Startseite zurueck (GESCHUETZT)
3. die Schnittstellen antworten mit 404 -- Personenverwaltung,
Systemzustand, KI-Schalter
FOLGE, die bewusst in Kauf genommen wird: Die Betreuungs-Zuteilung
liegt auf der Personenseite. Ab jetzt kann also NUR DogFather
festlegen, wer welchen Creator betreut.
GEPRUEFT: server/pruef-personen-formular.mjs, 20 Pruefungen. Das Aussehen
wird gemessen, nicht angesehen: Endet die Rollenauswahl innerhalb des
Formulars? Ragt eine Karte seitlich hinaus? Liegt etwas ueber der Liste?
Sind alle vier Karten gleich breit (272-272 px)? Traegt die gewaehlte ein
Haekchen? Dazu zwei Gegenproben: DogFather kommt weiterhin an beide
Bereiche (sonst waere jede Sperr-Zeile auch bei einem fuer ALLE kaputten
Bereich gruen), und die Managerin arbeitet ansonsten unveraendert weiter.
Bestehende Laeufe gruen: Rollen 97, Handy 50, Sicherung 41, Personenliste
33, Team 30, Formulare 19, Code 17, Grosscheck 15.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
e7b277b7fc |
Die Startseite log nicht -- sie war nur alt. Und Protokolle lassen sich loeschen
Drei Meldungen aus einer Nachricht.
1. "WIRD IMMER NOCH ANGEZEIGT"
Ein Protokoll war geschrieben, die Startseite meldete trotzdem weiter
"1 Gespraech hat noch kein Protokoll".
NACHGESTELLT statt vermutet: Der Server lag die ganze Zeit richtig.
Der Hinweis erscheint, sobald ein vergangenes Gespraech kein Protokoll
hat, und verschwindet in dem Moment, in dem eines geschrieben ist --
nachgemessen, beides.
Falsch war der BILDSCHIRM. Browser legen eine verlassene Seite
vollstaendig beiseite (bfcache) und holen sie beim Zurueckgehen
unveraendert hervor, mitsamt allen Zahlen vom ersten Laden. Kein
Skript laeuft dabei erneut. Wer ein Protokoll schreibt und dann auf
"Zurueck" tippt, sieht zwangslaeufig den Stand von vorher.
Das ist kein Schoenheitsfehler: Eine Zahl, die etwas Falsches
behauptet, ist schlimmer als gar keine -- man glaubt ihr ja. Und sie
kostet danach Vertrauen in ALLE Zahlen.
kopf.js laedt eine zurueckgeholte Seite jetzt neu. Nur dann
(`event.persisted`), nicht bei jedem Anzeigen -- sonst waere es eine
Endlosschleife. Gilt fuer jede Workspace-Seite, nicht nur die
Startseite.
2. PROTOKOLLE LOESCHEN -- NUR DOGFATHER
Bewusst istDogFather und nicht istLeitung: Ein Manager hat sonst
ueberall dieselben Rechte, hier ausdruecklich nicht. Wer ein Protokoll
entfernen darf, kann nachtraeglich bestimmen, was besprochen wurde.
Geloescht wird NUR das Protokoll. Das Gespraech bleibt im Kalender und
rutscht wieder zu "Protokoll fehlt" -- die Handlung ist damit
umkehrbar: neu schreiben, fertig. Die daraus entstandenen AUFGABEN
bleiben ebenfalls stehen; sie sind echte Arbeit, die jemand uebernommen
hat, und mit einem Klick auf ein Protokoll zu verschwinden waere ein
stiller Datenverlust an ganz anderer Stelle.
Der Knopf steht nur bei DogFather. Ein Knopf, der bei anderen
erscheint und dann abgewiesen wird, ist eine Einladung zum Aergernis.
3. IMMER NUR EINS OFFEN
Vorher liessen sich beliebig viele Protokolle gleichzeitig aufklappen
-- die Seite wurde so lang, dass die Liste darunter aus dem Blick
geriet. Ein neu geoeffnetes Gespraech schliesst jetzt das vorherige.
Beim Laden ist alles zu.
GEPRUEFT: server/pruef-protokoll-loeschen.mjs, 20 Pruefungen. Die
Zurueck-Pruefung misst an EINZAHL gegen MEHRZAHL ("1 Gespraech HAT" gegen
"2 Gespraeche HABEN") -- die Zahl selbst steht in einem eigenen Feld und
taucht im Fliesstext nicht auf. Drei Gegenproben: dass der Hinweis nach
dem Reparieren ueberhaupt noch anschlaegt (sonst waere "verschwunden"
auch bei kaputtem Hinweis gruen), dass eine Managerin 403 bekommt und das
Protokoll danach unveraendert dasteht, und dass der Loeschknopf bei ihr
gar nicht erst gezeichnet wird. Bestehende Laeufe gruen: Startansicht 133,
Rollen 97, Kalender 84, Serien 67, Protokoll-Klappe 52, Handy 50, Ampel
47, Freie Namen 32, Code 17.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
fc26597083 |
Wer sich einen neuen Code gibt, sperrt sich nicht mehr selbst aus
Gemeldet: "ich hab einen neuen code fuer mich gemacht aber ich wurde raus
gekickt bevor ich den neuen code kopieren konnte jetzt komm ich nicht mehr
rein."
DER FEHLER
Ein neuer Code beendete ALLE Sitzungen der Person -- auch die, in der der
Code gerade auf dem Bildschirm stand. Der naechste Aufruf der Seite lief in
ein "nicht angemeldet", die Umleitung zur Anmeldung nahm den Kasten samt
Code mit, und der Code ist nirgends noch einmal abrufbar (in der Datenbank
steht nur seine Pruefsumme). Ergebnis: ausgesperrt, Rueckweg nur ueber
einen Eingriff auf dem Server.
Bitter daran: Die Rueckfrage sagte das sogar an ("Deine aktuelle Sitzung
wird sofort beendet") -- als Warnung formuliert, nicht als Fehler erkannt.
Ein Ablauf, den man nur mit gutem Timing ueberlebt, ist keiner.
DREI RIEGEL, NICHT EINER
1. DIE EIGENE SITZUNG BLEIBT. codeNeu() beendet weiterhin alle Sitzungen
der Person -- ausser der einen, aus der heraus der Code gerade erneuert
wird. Sicherheitlich kostet das nichts: Wer den Code tauscht, hat sich
mit genau dieser Sitzung soeben ausgewiesen und haelt sie in Haenden.
Alle ANDEREN Geraete fliegen weiterhin hinaus -- das ist der Sinn der
Uebung und wird eigens geprueft.
2. DER KASTEN BLEIBT STEHEN. Solange ein frischer Code angezeigt wird,
springt die Personenseite nicht mehr von selbst zur Anmeldung. Selbst
wenn eine Sitzung aus einem anderen Grund endet (Zeitablauf, Neustart),
bleibt der Code lesbar, bis er weggeklickt ist -- mit einem Hinweis,
ihn jetzt abzuschreiben. Ein Code, den man nicht mehr lesen kann, ist
schlimmer als gar keiner.
3. EINE TUER VON AUSSEN: tools/notfall-code.sh. Setzt auf dem Server einen
neuen Code, zeigt ihn an und loescht die Sperre nach acht Fehlversuchen
gleich mit. Weigert sich, als root zu laufen (sonst gehoerten die
Hilfsdateien der Datenbank danach root und der Dienst koennte nicht
mehr schreiben). Dokumentiert als "Fall 0" in WIEDERHERSTELLUNG.md --
dem ersten Fall, den man aufschlaegt, wenn nichts kaputt ist ausser
dem Zugang.
KEIN fest hinterlegter Notfall-Code in der Anwendung: Der waere eine
Hintertuer, die dauerhaft offensteht, fuer jeden der sie findet, ohne
dass es auffiele. Dieser Weg verlangt Zugang zum Server, hinterlaesst
einen Protokolleintrag, und es gibt nichts zu erraten.
Die Rueckfrage sagt jetzt, was wirklich passiert, statt vor etwas zu
warnen, das nicht mehr eintritt.
GEPRUEFT: server/pruef-code.mjs, 17 Pruefungen -- darunter die Gegenprobe,
dass das ZWEITE Geraet derselben Person sehr wohl abgemeldet wird (ohne sie
waere die Reparatur auf dem Weg, einen neuen Code zur Formalie zu machen),
dass der alte Code nicht mehr gilt, dass beim Erneuern eines FREMDEN Codes
weiterhin alles hinausfliegt, und dass die Seite nach dem Erzeugen nicht
zur Anmeldung springt. Das Notfall-Skript ist mit beiden Wegen getestet
(Treffer und unbekannter Name). Bestehende Laeufe gruen: Rollen 97,
Personen-Liste 33, Sicht 48.
Co-Authored-By: Claude Opus 5 <[email protected]>
|