Zugang: die gewaehlte Kachel ist bindend

Filipe, 01.10.2026: „mach das. es soll fest sein."

VanVan hatte gemeldet: „Man kann sich mit seinem Zugangscode immer
noch über jeden Button der Startseite anmelden, egal welche Rolle man
hat."

ICH HATTE ZUERST ABGERATEN -- und lag falsch, weil ich eine alte Lage
beschrieben habe.

Am 09.09.2026 hatte Filipe entschieden, dass die Modis KEINE eigene
Eingangskachel bekommen: „damit die von der workspace auch nicht mal
sehen dass die modis von mir einen eigenen zugang haben." Wer keine
Kachel hat, muss irgendeine nehmen koennen -- daher der stille Zugang.

SEIT DER HAUSTRENNUNG AM 24.09.2026 STIMMT DAS NICHT MEHR. Auf
`crew.` steht laengst ein eigener Kachelsatz mit ALLEN fuenf Rollen:
DogFather, rechte Hand, linke Hand, Modi, Community (CREW_KACHEL, und
crew-index.html zeigt sie). Das Verbergen leistet seither die ADRESSE
-- wer sie nicht kennt, findet die Wand nicht; wer sie kennt, liest
die Rollennamen ohnehin offen darauf.

Der stille Zugang war damit ein Rest. Er hat niemanden mehr
geschuetzt und nur dafuer gesorgt, dass die Kachelwahl folgenlos
blieb. Nachgesehen habe ich das erst, NACHDEM Filipe widersprochen
hat; die Kachelsaetze standen die ganze Zeit im Quelltext.

WAS SICH NICHT AENDERT: Auf der Agenturwand war der stille Zugang nie
aktiv. Ein Team-Dogi-Code verhaelt sich dort weiterhin wie ein
erfundener -- gleiche Antwort, gleicher Weg, gleiche Dauer. Das ist
jetzt ausdruecklich gemessen.

EINE PRUEFADRESSE IST KEINE WAND. `127.0.0.1` ist weder crew. noch
Agentur. Ohne den stillen Zugang gaelte dort der Agentursatz -- und
kein Modi kaeme mehr herein. Fuenfzig Pruefdateien melden Team-Rollen
ueber diese Adresse an. Auf einer Adresse ohne Wand gibt es deshalb
ALLE Kacheln; welche auf welcher ECHTEN Wand steht, misst
pruef-modi-verborgen mit ausdruecklichem Host-Kopf.

GEPRUEFT -- pruef-modi-verborgen 87/0 (war 85; die fuenf Zeilen „jede
Kachel geht" sind durch sieben ersetzt, die die neue Regel und ihre
Gegenproben messen). Die Anzahl ist Zeile fuer Zeile verglichen.

  Modi-Kachel + Modi-Code      -> herein
  admin/hand/linke/gast        -> abgewiesen
  rechte Hand auf ihrer Kachel -> herein
  Agenturwand + Modi-Code      -> wie ein erfundener

pruef-crew-adresse 169/0 (unveraenderte Anzahl, zwei Zeilen
umgedreht).

SECHZEHN PRUEFDATEIEN MELDETEN SICH UEBER FREMDE KACHELN AN -- ein
Rest derselben Zeit. Systematisch gesucht statt einzeln entdeckt:
Waere ich dem roten Lauf hinterhergelaufen, haette ich beim zwoelften
aufgehoert.

UND DABEI EIN EIGENER FEHLER: Mein erster Durchlauf las die Rolle am
CODENAMEN ab (CODE-MODI- -> modi). Das ging gut, bis „Nane" kam: ein
Modi mit dem Code CODE-NANE-0001. Zwei Pruefungen wurden rot, und
zwar an einer Stelle („die Stimmen stimmen"), die mit Anmeldung
nichts zu tun hat. Ein Codename ist eine Beschriftung, keine
Tatsache -- die Rolle steht in `anlegen()`. Danach abgeleitet blieben
genau zwei Abweichungen uebrig, und beide sind absichtliche
Gegenproben.

Drei Browserpruefungen tippten die Creator-Kachel mit einem
Modi-Code. Die Modi-Kachel gibt es nur auf der Crew-Wand, und ein
Browser auf 127.0.0.1 bekommt die Agenturwand; sie melden sich jetzt
ueber die Schnittstelle an und bekommen den Keks. Gemessen werden
soll dort, was ein Modi SIEHT -- nicht, wie er hereinkommt.

Grün: pruef-modi-verborgen, pruef-crew-adresse, pruef-treff 85/0,
pruef-galerie, pruef-kanaele, pruef-modi-katalog 150/0,
pruef-modi-ideen, pruef-modi-kategorien, pruef-modi-checkliste 75/0,
pruef-modi-livecheck, pruef-kachelraster, pruef-team-ampel 32/0,
pruef-team-stufen 47/0, pruef-wunschliste, pruef-bremse,
pruef-gespraech, pruef-personen-formular 43/0, pruef-start-ansicht,
pruef-community-sicht, pruef-reaktion 421/0, pruef-abzeichen,
pruef-chat, pruef-chat-kanaele 81/0, pruef-entwicklung 79/0,
pruef-bewerbung-aufgaben 154/0, pruef-struktur,
pruef-zwischenspeicher 34/0.

`code_kennung` wird weiter geschrieben, aber nicht mehr gelesen --
sie war der Suchschluessel des stillen Weges. Stehen gelassen: Eine
Spalte zu entfernen ist eine Schemaaenderung mit Sicherung, und sie
kostet nichts.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-01 00:22:55 +02:00
co-authored by Claude Opus 5
parent 4503b1a475
commit 718b267de0
63 changed files with 1017 additions and 863 deletions
+52 -109
View File
@@ -6714,34 +6714,6 @@ workspaceRouter.use((req, res, next) => {
return next();
});
/**
* Gehoert dieser Code zu einem verborgenen Zugang?
*
* Gibt die Person zurueck oder null. `null` heisst hier ausdruecklich
* "nein oder nicht feststellbar" -- ohne Suchschluessel (etwa weil die
* Einstellung fehlt) gibt codeKennung() null zurueck, und dann wird
* niemand angemeldet. Das ist die richtige Richtung: Im Zweifel kommt
* niemand herein, statt dass im Zweifel jemand hereinkommt.
*/
function stillerZugang(code) {
try {
const kennung = codeKennung(code);
if (!kennung) return null;
const k = db().prepare(
"SELECT id, name, rolle, code_hash, code_salt, code_n FROM personen "
+ `WHERE code_kennung = ? AND rolle IN (${
[...TEAM_DOGI_ROLLEN].map((r) => `'${r}'`).join(", ")}) AND aktiv = 1`).get(kennung);
if (!k) return null;
/* Trotz Treffer wird geprueft. Der Suchschluessel ist ein
Wegweiser, kein Ausweis -- und ein Wegweiser, dem man blind
folgt, ist eine Hintertuer. */
return gleich(hashe(code, k.code_salt, k.code_n), k.code_hash) ? k : null;
} catch (fehler) {
console.error("[workspace] Stiller Zugang nicht pruefbar:", fehler?.message);
return null;
}
}
/* DIE TAFEL LIEGT SEIT DEM 11.09.2026 IN workspace-rechte.js.
Hier stand ein nur LESENDER Weg. Filipe: "so dass ich die da auch
@@ -6763,95 +6735,49 @@ workspaceRouter.post("/workspace/api/anmelden", (req, res) => {
const codeBrauchbar = code.length >= 4 && code.length <= 200;
/* =================================================================
DER STILLE ZUGANG (09.09.2026)
DIE KACHEL IST BINDEND (01.10.2026)
Wunsch Filipe: *"dass die keine neue eingangs kachel bekommen wie
spicy dogfather und so sondern einfach einen code. damit die von
der workspace auch nicht mal sehen dass die modis von mir einen
eigenen zugang haben."*
Filipe: „mach das. es soll fest sein."
Ein Modi oeffnet dieselbe Seite, tippt auf IRGENDEINE vorhandene
Kachel und gibt seinen Code ein. Welche Kachel, ist gleichgueltig
-- der Code allein entscheidet. Von aussen sieht das aus wie jede
andere Anmeldung: dieselbe Seite, dieselbe Anfrage, dieselben
Felder.
VanVan hatte gemeldet: „Man kann sich mit seinem Zugangscode
immer noch über jeden Button der Startseite anmelden, egal
welche Rolle man hat."
ZWEI NAHELIEGENDE WEGE, DIE ABSICHTLICH NICHT GEWAEHLT WURDEN:
---------------------------------------------------------------
HIER STAND DER STILLE ZUGANG (09.09. bis 01.10.2026)
* Ein Merkmal im Code ("M-..."): waere ein sichtbares Kennzeichen
auf dem Zettel des Modis. Wer den Code sieht, sieht die Sorte.
* Eine eigene Adresse (/modi.html): waere eine Seite, die man
finden kann -- und die Seitenpruefung zaehlt Seiten.
Er liess einen Team-Dogi-Code auf JEDER Kachel durch. Das war
kein Versehen, sondern Filipes Entscheidung vom 09.09.2026:
„dass die keine neue eingangs kachel bekommen wie spicy
dogfather und so sondern einfach einen code. damit die von der
workspace auch nicht mal sehen dass die modis von mir einen
eigenen zugang haben."
WARUM DAS VOR DEM GEWOHNTEN WEG STEHT UND NICHT DAHINTER: Ein
Rueckfall NACH einem Fehlversuch haette den gewohnten Weg
verlaengert -- und zwar nur dann, wenn er scheitert. Genau daran
waere es zu erkennen gewesen: Fehlversuche dauern ploetzlich
laenger als frueher. Der Suchschluessel kostet Mikrosekunden und
trifft in aller Regel nichts; fuer alle anderen bleibt der Ablauf
unveraendert, auch in der Zeit.
Wer keine Kachel hat, muss irgendeine nehmen koennen.
DER SUCHSCHLUESSEL ALLEIN LAESST NIEMANDEN HEREIN. Er sagt nur,
WEN man pruefen soll -- danach entscheidet scrypt wie ueberall. */
/* AUF DEN ALTEN ADRESSEN WIRD DER VERBORGENE ZUGANG GAR NICHT ERST
GEFRAGT (Entscheidung Filipe, 10.09.2026).
WARUM ER JETZT WEG KANN -- und das ist der ganze Punkt: Seit
der Haustrennung am 24.09.2026 gibt es ZWEI Waende. Auf `crew.`
steht ein eigener Kachelsatz (CREW_KACHEL): DogFather, rechte
Hand, linke Hand, Modi, Community. Alle fuenf Rollen haben dort
ihre Kachel.
Vorher stand hier eine Weiterleitung: Wer seinen Code noch auf
workspace.dogfather-universe.com eintippte, bekam keine Sitzung,
aber den Weg zur neuen Adresse. Filipes Entscheidung dagegen:
"gar nichts -- Code stimmt nicht". Die alte Wand soll sich
verhalten, als waere der Code erfunden.
Das Verbergen leistet seither die ADRESSE. Wer sie nicht kennt,
findet die Wand nicht; wer sie kennt, sieht die Rollennamen
ohnehin offen darauf stehen. Der Trick mit der beliebigen
Kachel hat niemanden mehr geschuetzt und nur noch dafuer
gesorgt, dass die Wahl folgenlos blieb.
WARUM DAS NICHT NUR EINE ANDERE ANTWORT IST, SONDERN EIN ANDERER
WEG: Haette ich hier bloss `return 401` gesetzt, waere der Ablauf
trotzdem ein anderer geblieben -- ein Suchschluessel-Treffer und
EIN scrypt-Durchlauf statt der Kandidatenschleife der gewaehlten
Kachel. Das ist messbar, und Zeitunterschiede sind genau die
Spur, die dieser ganze Zugang vermeiden soll.
WAS SICH NICHT AENDERT: Auf der Agenturwand war der stille
Zugang nie aktiv. Ein Team-Dogi-Code verhaelt sich dort
weiterhin wie ein erfundener -- gleiche Antwort, gleicher Weg,
gleiche Dauer. Dafuer sorgt der Kachelsatz unten, nicht eine
eigene Bedingung.
Deshalb wird `stillerZugang` auf diesen drei Adressen ueberhaupt
nicht aufgerufen. Der Code faellt danach durch den gewohnten Weg
wie jeder unbekannte: dieselbe Schleife, derselbe Eintrag in
`versuche`, dieselbe Antwort, dieselbe Dauer. Die alte Wand
verhaelt sich damit exakt so wie vor dem Tag, an dem es diese
Rollen gab.
DER PREIS, und er gehoert genannt: Ein Modi, der die alte
Verknuepfung auf dem Handy hat, sammelt dort Fehlversuche wie
jeder andere auch. Acht in zehn Minuten sperren seine IP -- und
zwar auch fuer die neue Adresse, denn die Sperre haengt an der
IP, nicht am Hostnamen. Das ist der Preis der Stille; er faellt
nur an, wenn jemand die alte Adresse mehrfach probiert. */
/* UND AUCH NICHT AUF DER WAND DES TREFFS (11.09.2026).
Hier stand `!istOhneModiAdresse(...)` -- also "ueberall ausser auf
den alten Adressen". Als dritte Wand dazukam, hiess das
stillschweigend auch: dort. Ein Modi kam damit ueber den
verborgenen Weg in den Treff herein, obwohl die Kachelliste dort
nur `gast` kennt und die Adressregel ihn abweist.
Gefunden hat das nicht das Lesen, sondern eine Zeile in
pruef-treff, die das GEGENTEIL behauptete und rot wurde:
"auf treff. kommt sonst niemand herein -- auch DogFather nicht
(401/200)". DogFather wurde abgewiesen, der Modi nicht.
Die Lehre ist dieselbe wie bei `null` in der Rechtetafel: Eine
Bedingung, die durch AUSSCHLIESSEN formuliert ist, nimmt jede
neue Moeglichkeit automatisch mit auf. Jetzt steht dort, WO der
Weg gilt, statt wo er nicht gilt. */
const stilleWand = istCrewAdresse(req.get("host")) || istPruefAdresse(req.get("host"));
const still = codeBrauchbar && stilleWand ? stillerZugang(code) : null;
if (still) {
db().prepare("DELETE FROM versuche WHERE ip = ?").run(ip);
db().prepare("UPDATE personen SET letzter_login = ? WHERE id = ?").run(jetzt(), still.id);
sitzungSetzen(res, still, req);
protokolliere("anmeldung", {
personId: still.id, rolle: still.rolle, ip, detail: still.name,
});
return res.json({
weiter: "/workspace/start.html", name: still.name, rolle: still.rolle,
});
}
`code_kennung` in `personen` wird weiter GESCHRIEBEN, aber
nicht mehr gelesen. Sie war der Suchschluessel dieses Weges.
Stehen gelassen und nicht geloescht: Eine Spalte zu entfernen
ist eine Schemaaenderung mit Sicherung, und sie kostet nichts.
Wer sie wieder braucht, findet hier, wofuer sie da war. */
/* Ab hier der gewohnte Weg -- unveraendert. 'modi' ist keine
Kachel-Rolle und faellt deshalb in dieselbe Antwort wie eine
@@ -6885,7 +6811,24 @@ workspaceRouter.post("/workspace/api/anmelden", (req, res) => {
Wand gerade dran ist. Ein Manager, der crew. erraet und seinen
Code eintippt, faellt dadurch in genau dieselbe Antwort wie
jemand mit einer erfundenen Rolle. */
const kachelSatz = istCrewAdresse(req.get("host")) ? CREW_KACHEL : ROLLEN_KACHEL;
/* ==== EINE PRUEFADRESSE IST KEINE WAND (01.10.2026) ==========
`127.0.0.1` ist weder crew. noch die Agentur. Bis heute fiel
das nicht auf: Der stille Zugang liess Team-Dogi-Codes dort
ohnehin durch, egal welcher Kachelsatz galt. Mit seinem
Wegfall gaelte dort der AGENTUR-Satz -- und damit kaeme kein
einziger Modi mehr herein. Fuenfzig Pruefdateien melden
Team-Rollen ueber diese Adresse an; sie waeren alle rot, und
zwar wegen der Messumgebung, nicht wegen des Programms.
Auf einer Adresse ohne Wand gibt es deshalb ALLE Kacheln. Das
versteckt nichts: Welche Kachel auf welcher ECHTEN Wand steht,
entscheiden weiterhin die zwei Mengen darunter, und genau das
misst pruef-modi-verborgen -- mit ausdruecklichem Host-Kopf,
nicht ueber 127.0.0.1. */
const kachelSatz = istPruefAdresse(req.get("host"))
? new Set([...ROLLEN_KACHEL, ...CREW_KACHEL])
: (istCrewAdresse(req.get("host")) ? CREW_KACHEL : ROLLEN_KACHEL);
if (!kachelSatz.has(rolle) || !codeBrauchbar) {
db().prepare("INSERT INTO versuche (ip, zeitpunkt) VALUES (?,?)").run(ip, jetzt());