Der Rollenname steht in keiner ausgelieferten Datei mehr
pruef-modi-wortleck war rot und meldete 17 Fundstellen -- seit Wochen,
bei jedem Lauf. Eine Warnung, die immer kommt, wird ueberlesen, und
dann auch die echte.
ERST GEMESSEN, OB DIE REGEL UEBERHAUPT NOCH GILT. Seit dem 11.09. gibt
es die eigene Adresse crew. mit einem offenen Modi-Knopf an der Wand --
es waere gut moeglich gewesen, dass die Pruefung etwas bewacht, das es
nicht mehr gibt. Sie gilt: pruef-modi-verborgen setzt mit 80 Pruefungen
durch, dass ein Manager keinen Modi sieht.
UND DABEI KAM ETWAS SCHLIMMERES HERAUS. Auf der echten Seite gemessen:
/workspace/start.html 302 (Anmeldung noetig)
/workspace/assets/js/talente.js 200 25 KB Quelltext
/workspace/assets/js/chat.js 200 85 KB
/workspace/assets/css/entwicklung.css 200 34 KB
Jede Datei unter workspace/ ist OHNE JEDE ANMELDUNG aus dem offenen
Netz abrufbar. Der verborgene Zugang stand also nicht in einer Datei,
die "jeder herunterlaedt, der angemeldet ist" -- sondern in einer, die
man einfach abrufen kann.
Die Rollentabelle in workspace.js sagt seit dem 11.09. genau das
Richtige dazu: "Der Name steht hier und NICHT in einer Datei, die jeder
herunterlaedt -- ausgeliefert wird er nur an den, der ihn selbst
traegt, und an die, die ihn sehen duerfen." Danach ist jetzt gebaut,
ueberall:
- talente.js hatte `rolle: 'modi'` fest im Text, dazu den Namen im
Codekasten und im Rechtevergleich. Die Seite FRAGT ihn jetzt ab;
/talente/lage liefert ihn, und die Route geht nur an DogFather und
die rechte Hand.
- Der Regeltext des Treffs nennt den Namen weiterhin -- Filipe hat am
11.09. ausdruecklich gewaehlt, dass die Community ihn sieht. Er
kommt jetzt als DATEN mit der Antwort, nicht als fester Text.
- Das Feld hiess selbst `modi_frist_tage`. Das Muster \bmodi\b trifft
das nicht, weil danach ein Unterstrich folgt -- ein Leck durch eine
Luecke im Muster, nicht durch eine Entscheidung. Heisst jetzt
`pause_frist_tage`.
- Die uebrigen elf Fundstellen waren Kommentare. Umformuliert, ohne
dass sie weniger erklaeren.
Ergebnis: 17 -> 0. Ohne Ausnahmeliste, ohne die Pruefung zu entschaerfen.
ZWEI LOECHER, DIE ICH DABEI SELBST GERISSEN HAETTE:
darfAnlegen wurde aus `lage` gerechnet -- aber ichHolen() laeuft VOR
laden(), also war `lage` noch null. Der Wert waere dauerhaft falsch
gewesen und der Knopf nie erschienen. Jetzt ist es eine Frage statt
eines Wertes, beantwortet beim Zeichnen. Gefunden beim Nachsehen der
Reihenfolge, nicht im Testlauf -- deshalb steht die Frage ab jetzt in
pruef-uebergang.
Und im HTML des Treffs steht als Ersatzfassung "jemandem aus dem
Team". Kommt der Name nicht an, bleibt sie stehen, die Seite sieht
vollkommen richtig aus, und niemand merkt es. Ein Platzhalter "…"
waere aufgefallen; eine richtige Ersatzfassung faellt nicht auf.
pruef-neue-seiten prueft jetzt, dass wirklich der Name dasteht.
pruef-modi-wortleck 0 Fehler (vorher 17 Fundstellen)
pruef-uebergang 65 (vorher 61), pruef-neue-seiten 97 (vorher 93)
pruef-modi-verborgen 80, pruef-nachwuchs 123, pruef-treff 66,
pruef-treff-werkzeuge 70, pruef-css-klassen -- alle 0 Fehler
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -533,6 +533,29 @@ melde("=== Stand das Neue auch wirklich da? ===");
|
||||
ok(t.split("Ins Team holen").length - 1 === 1,
|
||||
`der Zugangsknopf ebenso (${t.split("Ins Team holen").length - 1})`);
|
||||
|
||||
/* ===== DER ROLLENNAME KOMMT ALS DATEN, NICHT AUS DEM SKRIPT ========
|
||||
|
||||
Seit dem 16.09.2026 steht der Name im Regeltext des Treffs nicht
|
||||
mehr fest im Browser -- er kommt mit der Antwort des Servers. Der
|
||||
Grund: Jede Datei unter workspace/ ist ohne Anmeldung abrufbar
|
||||
(nachgemessen: `talente.js` liefert 200 und 25 KB Quelltext).
|
||||
|
||||
DAS BRAUCHT EINE PRUEFUNG, und zwar genau hier. Im HTML steht als
|
||||
Ersatzfassung „jemandem aus dem Team" -- ein Satz, der auch ohne
|
||||
Skript stimmt. Kommt der Name NICHT an, bleibt diese Fassung
|
||||
stehen, die Seite sieht vollkommen richtig aus, und niemand merkt
|
||||
es. Ein Platzhalter „…" waere aufgefallen; eine richtige Ersatz-
|
||||
fassung faellt nicht auf. Deshalb wird nachgesehen, ob wirklich
|
||||
der Name dasteht. */
|
||||
const regeln = gesehen.regeln || "";
|
||||
ok(regeln.length > 400, `Regeln: die Seite ist gefüllt (${regeln.length} Zeichen)`);
|
||||
ok(/sag es einem \S+/.test(regeln),
|
||||
"Regeln: der Rollenname ist im Kontaktsatz angekommen");
|
||||
ok(!/jemandem aus dem Team/.test(regeln),
|
||||
"die Ersatzfassung steht NICHT mehr da — sie wurde wirklich ersetzt");
|
||||
ok(/Pause von bis zu \d+ Tagen/.test(regeln),
|
||||
"und die Frist steht als Zahl darin, nicht als Platzhalter");
|
||||
|
||||
const hand = gesehen["entwicklung-hand"] || "";
|
||||
const dogi = gesehen.entwicklung || "";
|
||||
/* WENN ES SCHIEFGEHT, SOLL DIE MELDUNG SAGEN, WAS STATTDESSEN DA WAR.
|
||||
|
||||
@@ -410,6 +410,51 @@ melde("=== 8. Im Browser ===");
|
||||
jemanden bestimmt, ohne ihn gefragt zu haben. */
|
||||
ok(frage.vorbelegt === "", "und keiner ist vorausgewählt — hier muss jemand wirklich wählen");
|
||||
|
||||
/* ===== DER ROLLENNAME STEHT NICHT MEHR IM SKRIPT (16.09.2026) =====
|
||||
|
||||
`talente.js` hatte `rolle: 'modi'` als festen Text -- und der Server
|
||||
liefert jede Datei unter workspace/ an jeden aus, der die Adresse
|
||||
kennt. Nachgemessen am 16.09. auf der echten Seite: ohne jede
|
||||
Anmeldung 200 und 25 KB Quelltext.
|
||||
|
||||
Jetzt fragt die Seite den Namen ab. Das ist eine Codeänderung an
|
||||
der Stelle, an der aus einem Talent ein Mensch mit Zugang wird --
|
||||
der letzte Schritt des Trichters, und der einzige, den man nicht
|
||||
zurücknehmen kann. Also wird er gemessen, nicht angenommen. */
|
||||
const wissen = await seite.evaluate(async () => {
|
||||
const a = await fetch("/workspace/api/talente/lage", { credentials: "same-origin" });
|
||||
const l = await a.json();
|
||||
const quelle = await (await fetch("/workspace/assets/js/talente.js")).text();
|
||||
return {
|
||||
rolle: l?.zugang?.rolle || "",
|
||||
name: l?.zugang?.name || "",
|
||||
imSkript: /rolle:\s*'modi'/.test(quelle),
|
||||
};
|
||||
});
|
||||
ok(!!wissen.rolle && !!wissen.name,
|
||||
`der Server sagt der Seite, welcher Zugang entsteht (${wissen.rolle} / ${wissen.name})`);
|
||||
ok(wissen.imSkript === false,
|
||||
"und im ausgelieferten Skript steht der Name nicht mehr");
|
||||
|
||||
/* UND DER KNOPF MUSS TROTZDEM DA SEIN. Der Wert wird jetzt erst beim
|
||||
Zeichnen gerechnet -- mein erster Entwurf rechnete ihn zu früh,
|
||||
und dann wäre er dauerhaft falsch gewesen und der Knopf nie
|
||||
erschienen. Gefunden hat das die Reihenfolge im Quelltext, nicht
|
||||
der Testlauf; deshalb steht die Frage ab jetzt hier. */
|
||||
await seite.goto(`http://127.0.0.1:${PORT}/workspace/talente.html`, { waitUntil: "networkidle" });
|
||||
await seite.waitForTimeout(900);
|
||||
const knopf = await seite.evaluate(() => {
|
||||
const k = [...document.querySelectorAll(".t-karte")]
|
||||
.find((x) => x.dataset.stufe === "probe");
|
||||
return {
|
||||
karte: !!k,
|
||||
text: k?.querySelector(".t-schritt__knopf")?.textContent.trim() || "",
|
||||
};
|
||||
});
|
||||
ok(knopf.karte, "eine Karte auf der Probe steht auf der Seite");
|
||||
ok(/Zugang anlegen/.test(knopf.text),
|
||||
`und DogFather sieht den Knopf dafür („${knopf.text}“)`);
|
||||
|
||||
ok(konsole.length === 0,
|
||||
konsole.length ? "Fehler im Browser: " + konsole[0].slice(0, 90) : "keine Fehler im Browser");
|
||||
await browser.close();
|
||||
|
||||
@@ -102,6 +102,27 @@ const KARTEN_ROLLEN = ["hand", "modi"];
|
||||
* begleiten, die er selbst nicht macht. */
|
||||
const BUDDY_ROLLEN = ["admin", "hand", "modi"];
|
||||
|
||||
/** Welchen Zugang der letzte Schritt des Trichters anlegt.
|
||||
*
|
||||
* ER STEHT HIER UND NICHT IM BROWSER (16.09.2026). Die Talente-Seite
|
||||
* hatte `rolle: 'modi'` als festen Text im Skript -- und jede Datei
|
||||
* unter `workspace/` liefert der Server an JEDEN aus, der die Adresse
|
||||
* kennt. Nachgemessen am 16.09.: `talente.js` kommt ohne jede
|
||||
* Anmeldung mit 200 aus dem offenen Netz, 25 KB Quelltext, der
|
||||
* Rollenname mittendrin.
|
||||
*
|
||||
* Damit stand der verborgene Zugang in einer Datei, die man nicht
|
||||
* einmal geschenkt bekommen muss -- man kann sie abrufen. Die
|
||||
* Rollentabelle nebenan sagt seit dem 11.09. genau das Richtige dazu:
|
||||
* „Der Name steht hier und NICHT in einer Datei, die jeder
|
||||
* herunterlaedt -- ausgeliefert wird er nur an den, der ihn selbst
|
||||
* traegt, und an die, die ihn sehen duerfen."
|
||||
*
|
||||
* Die Seite fragt ihn deshalb ab, statt ihn zu kennen. Die Antwort
|
||||
* geht ueber `nurLeitung` -- also nur an DogFather und die rechte
|
||||
* Hand. */
|
||||
const ZUGANG_ROLLE = "modi";
|
||||
|
||||
/* =====================================================================
|
||||
DIE TABELLEN
|
||||
===================================================================== */
|
||||
@@ -898,6 +919,10 @@ entwicklungRouter.get("/workspace/api/talente/lage", (req, res) => {
|
||||
ORDER BY ${ROLLEN_SORTIERUNG}, name COLLATE NOCASE`).all(...BUDDY_ROLLEN),
|
||||
erster_tag: ERSTER_TAG,
|
||||
schicht_weit_tage: SCHICHT_WEIT_TAGE,
|
||||
/* WELCHEN ZUGANG DER LETZTE SCHRITT ANLEGT -- Schluessel und
|
||||
Wort. Beides kommt von hier, damit im Browser kein fester Text
|
||||
dazu steht; siehe ZUGANG_ROLLE oben. */
|
||||
zugang: { rolle: ZUGANG_ROLLE, name: ROLLEN_NAME[ZUGANG_ROLLE] ?? ZUGANG_ROLLE },
|
||||
kandidaten: karten,
|
||||
/* Wie viele auf jeder Stufe liegen -- der Trichter als Zahlen.
|
||||
Abgeleitet, damit er nicht danebenliegen kann. */
|
||||
|
||||
@@ -439,7 +439,25 @@ treffRouter.get("/workspace/api/treff/regeln", (req, res) => {
|
||||
stamm_beitraege: STAMM_BEITRAEGE,
|
||||
anschlag_max: ANSCHLAG_MAX,
|
||||
grund_min: GRUND_MIN,
|
||||
modi_frist_tage: MODI_FRIST_TAGE,
|
||||
/* DER NAME KOMMT ALS DATEN MIT (16.09.2026).
|
||||
|
||||
Filipe hat am 11.09. ausdruecklich gewaehlt, dass im Treff der
|
||||
volle Rollenname neben einem Beitrag steht. Die Regel dazu steht
|
||||
an ROLLEN_NAME in workspace.js: Der Name wird AUSGELIEFERT, aber
|
||||
er steht nicht als fester Text in einer Datei, die jeder abrufen
|
||||
kann -- und abrufen kann sie wirklich jeder, nachgemessen am
|
||||
16.09.: `talente.js` kommt ohne Anmeldung mit 200 aus dem Netz.
|
||||
|
||||
Im Regeltext des Treffs stand er trotzdem dreimal fest im
|
||||
Skript. Jetzt kommt er von hier.
|
||||
|
||||
UND DER SCHLUESSEL HIESS SELBST SO: `modi_frist_tage`. Das
|
||||
Wortleck-Muster ist `modi` und trifft das nicht, weil danach
|
||||
ein Unterstrich folgt -- ein Leck durch eine Luecke im Muster,
|
||||
nicht durch eine Entscheidung. Deshalb heisst das Feld jetzt
|
||||
nach dem, was es bedeutet. */
|
||||
rolle_name: ROLLEN_NAME.modi,
|
||||
pause_frist_tage: MODI_FRIST_TAGE,
|
||||
stufen: STUFEN.map((s) => ({ schluessel: s, name: STUFEN_NAME[s] })),
|
||||
/* Welche Bretter erst nach Freigabe erscheinen — auch das gehoert
|
||||
in den Regeltext, und auch das soll nicht abschreibbar sein. */
|
||||
|
||||
Reference in New Issue
Block a user