Die Modi-App bekommt ihre eigene Adresse: crew.dogfather-universe.com

Filipe: "ich will dass es eine eigene app wird" -- und dann "subdomain
machen jetzt sofort". Name von ihm gewaehlt: crew. (unauffaellig).

Auf einem Ursprung laesst sich genau EINE App installieren (w3c/manifest
Nr. 1180). Derselbe Grund, aus dem der Workspace am 06.09. umgezogen ist.
Getrennt wird ueber den HOSTNAMEN: ein Dienst, eine Datenbank, ein
Verzeichnis wie bisher.

DIE REGEL STEHT AN EINER STELLE
crew-adresse.js beantwortet: Darf diese Rolle auf dieser Adresse
angemeldet sein? Eingehaengt in sitzungLesen() -- durch die Funktion geht
jedes der 26 Fachmodule und jede Seitenschranke. Eine Middleware daneben
kann man in einem neuen Modul vergessen, und ein vergessener Rechteschutz
faellt nicht auf, weil dann alles geht.

  crew.      nur Modis; jeder andere bekommt 401 wie bei einem Tippfehler
  workspace. keine Modis mehr; sie bekommen den Weg zur neuen Adresse
  localhost  UNVERAENDERT

Die dritte Zeile ist der Kern: Die Regel ist eine AUFZAEHLUNG der drei
echten Adressen, nicht "alles ausser crew". Sonst wuerden sieben andere
Pruefdateien ab sofort messen, dass ein Modi nirgends hereinkommt -- gruen,
weil sie nichts mehr finden.

ZWEI APPS, ZWEI NAMEN
Beide Adressen liefern dieselben HTML-Dateien. Auf crew. wird
/workspace/app.webmanifest serverseitig auf crew.webmanifest umgebogen --
so braucht keine der 30 Seiten eine zweite Zeile, die man bei der 31.
vergisst. "Team Dogi" statt "Creator Workspace", eigenes Zeichen:
derselbe Husky, aber ohne Chili (die gehoert zu Spicy Media, nicht zu
ihnen) und im Modi-Ton #5f8a9f.

tools/crew-symbol.mjs erzeugt die sechs Symbole und bricht ab, wenn sie
sich zu weniger als 10 % vom Workspace-Symbol unterscheiden. Gemessen:
43 bis 53 %.

GEMESSEN
pruef-crew-adresse    74 Pruefungen, 0 Fehler -- mit Gegenprobe: der Modi
                      bekommt in der Datenbank die Rolle 'manager', danach
                      MUSS dieselbe Sitzung auf crew. ins Leere laufen
pruef-rollen          245, unveraendert (die Regel ist lokal wirkungslos)
pruef-workspace-umzug 31 Faelle
pruef-zwischenspeicher 21 -- ein Stempel im Haus, jetzt ueber 23 Dateien

Der Server kennt die Adresse damit. DNS und Caddy bleiben Filipes Schritt.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-10 13:07:12 +02:00
co-authored by Claude Opus 5
parent 05f262eb61
commit 3cda64568d
35 changed files with 1012 additions and 263 deletions
+65 -1
View File
@@ -27,6 +27,8 @@ import { dirname, join } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { mkdirSync } from "node:fs";
import { createRequire } from "node:module";
import { sitzungPasstZurAdresse, CREW_ADRESSE, istOhneModiAdresse, istCrewAdresse }
from "./crew-adresse.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -2397,6 +2399,24 @@ export function sitzungLesen(req) {
db().prepare("DELETE FROM sitzungen WHERE token_hash = ?").run(tokenHash(token));
return null;
}
/* DIE ADRESSE ENTSCHEIDET MIT (10.09.2026).
Seit die Modi-App unter crew.dogfather-universe.com laeuft, gehoert
jede Sitzung zu genau EINER Adresse: Modis dorthin, alle anderen auf
den Workspace. Die Regel steht in crew-adresse.js und ist dort ohne
laufenden Server pruefbar.
WARUM HIER UND NICHT IN DEN MODULEN: Durch diese Funktion geht jedes
der 26 Fachmodule und jede Seitenschranke. Eine Middleware daneben
koennte man in einem neuen Modul vergessen -- und ein vergessener
Rechteschutz faellt nicht auf, weil dann alles geht.
`null` heisst hier dasselbe wie bei einer abgelaufenen Sitzung:
nicht angemeldet. Die Seitenschranke schickt zur Zugangswand, die
Schnittstellen antworten mit 401. Beides ist genau richtig -- auf
dieser Adresse ist diese Person schlicht niemand. */
if (!sitzungPasstZurAdresse(reihe.rolle, req.get?.("host"))) return null;
return { id: reihe.id, name: reihe.name, rolle: reihe.rolle };
} catch { return null; }
}
@@ -2697,6 +2717,33 @@ workspaceRouter.post("/workspace/api/anmelden", (req, res) => {
WEN man pruefen soll -- danach entscheidet scrypt wie ueberall. */
const still = codeBrauchbar ? stillerZugang(code) : null;
if (still) {
/* AUF DER ALTEN ADRESSE GIBT ES KEINE SITZUNG MEHR (10.09.2026).
Die Modi-App hat seit heute eine eigene Adresse. Wer seinen Code
noch auf workspace.dogfather-universe.com eintippt, bekommt hier
den Weg dorthin -- und ausdruecklich KEINE Anmeldung: zwei
Sitzungen auf zwei Adressen waeren zwei Apps auf dem
Startbildschirm und eine zweite Spur genau dort, wo alle anderen
arbeiten.
DASS DIE ANTWORT DIE NEUE ADRESSE NENNT, IST KEIN LECK. Sie
kommt nur nach Eingabe eines gueltigen Modi-Codes; wer den hat,
ist Modi. Fuer jeden anderen -- auch fuer einen Manager mit
gueltigem eigenen Code -- veraendert sich hier gar nichts.
Kein Eintrag in `versuche`: Der Code war richtig. Ein Modi, der
die alte Verknuepfung auf dem Handy hat, wuerde sich sonst mit
jedem Versuch selbst aussperren. */
if (istOhneModiAdresse(req.get("host"))) {
protokolliere("anmeldung_alte_adresse", {
personId: still.id, rolle: still.rolle, ip, detail: still.name,
});
return res.json({
weiter: `${CREW_ADRESSE}/workspace/start.html`,
name: still.name, rolle: still.rolle, umgezogen: true,
});
}
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);
@@ -2711,7 +2758,24 @@ workspaceRouter.post("/workspace/api/anmelden", (req, res) => {
/* Ab hier der gewohnte Weg -- unveraendert. 'modi' ist keine
Kachel-Rolle und faellt deshalb in dieselbe Antwort wie eine
erfundene. */
if (!ROLLEN_KACHEL.has(rolle) || !codeBrauchbar) {
/* AUF DER MODI-ADRESSE ENDET DER GEWOHNTE WEG HIER (10.09.2026).
crew.dogfather-universe.com ist nicht die zweite Tuer in den
Workspace. Wer sie errät und seinen eigenen Code eintippt, soll
genau das erleben, was er bei einem Tippfehler erlebt: Die
Zugangswand sieht aus wie immer, der Code stimmt nicht. Wuerde er
stattdessen hereinkommen, wuesste er im selben Moment, dass es
hier noch etwas gibt.
BEWUSST IN DIESELBE BEDINGUNG GESCHRIEBEN und nicht als eigener
Block davor: So ist es nicht nur dieselbe ANTWORT, sondern
derselbe Weg -- ein Eintrag in `versuche`, kein scrypt-Durchlauf,
401 "ungueltig". Ein eigener Block waere messbar schneller oder
langsamer gewesen als der Weg daneben, und genau daran erkennt
man eine Sonderbehandlung. */
const fremdAufCrew = istCrewAdresse(req.get("host"));
if (!ROLLEN_KACHEL.has(rolle) || !codeBrauchbar || fremdAufCrew) {
db().prepare("INSERT INTO versuche (ip, zeitpunkt) VALUES (?,?)").run(ip, jetzt());
return res.status(401).json({ fehler: "ungueltig" });
}