Files
DogFatherGitandClaude Opus 5 74091590b8 Verwaltung: nur noch EINMAL den Code eingeben
Rueckmeldung 22.08.2026: "ich hab auf der verwaltungs seite 2 mal dass ich
den zugangscode eingeben muss und vanvan auch, ich will es nur einmal
eingeben muessen." Berechtigt.

Die Zugangswand hat serverseitig laengst geprueft, WER da ist -- Dogfather
oder VanVan, laut Masterplan S.4 beide gleichberechtigte
Volladministratoren. Ein zweites Passwort danach bringt keinen
zusaetzlichen Schutz, es kostet nur jedes Mal Zeit.

Warum es nicht einfach "Cookie mitschicken" ist: Die Verwaltungsdaten
liegen hinter postfach.dogfather-universe.com, einem ANDEREN Rechnernamen.
Das Sitzungs-Cookie gilt dort nicht -- so sind Cookies gebaut, und das ist
gut so.

Loesung: Die Zugangswand stellt unter /webdesign/api-ausweis einen
kurzlebigen, signierten Ausweis aus, den die interne API anerkennt.
  - 15 Minuten gueltig, die Seite holt bei Bedarf still einen neuen
  - traegt bereich="wd-admin", damit ein Sitzungs-Token der Zugangswand
    hier NICHT durchgeht und umgekehrt
  - nur mit gueltiger Zugangssitzung zu bekommen
  - gilt AUSSCHLIESSLICH fuer die /webdesign-Endpunkte. Postfach,
    Bewerbungen, Supporter und Teamverwaltung bleiben unberuehrt

Fehlt WEBDESIGN_API_SECRET auf einer der beiden Seiten, gilt kein Ausweis
und die Verwaltung fragt wie bisher nach dem Team-Code. Ein fehlender
Konfigurationswert darf niemals eine Tuer oeffnen -- nur eine schliessen.
Genau das prueft der letzte Testfall.

Bei einem 401 wird EINMAL still ein neuer Ausweis geholt und die Anfrage
wiederholt, statt jemanden mitten im Arbeiten rauszuwerfen.

10/10 Tests, darunter: gefaelschte Signatur, fremdes Geheimnis,
abgelaufen, falscher Bereich, erfundene Rolle.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:36:11 +02:00

49 lines
2.7 KiB
JavaScript

/* =====================================================================
test-webdesign-ausweis.mjs — Ausweis der Zugangswand
Der Ausweis erlaubt Dogfather und VanVan, die Webdesign-Verwaltung ohne
zweite Anmeldung zu benutzen (Rückmeldung 22.08.2026: "ich will es nur
einmal eingeben müssen"). Genau deshalb muss hier besonders sauber
geprüft werden, was NICHT durchgeht.
Aufruf: node test-webdesign-ausweis.mjs
===================================================================== */
import { createHmac } from "node:crypto";
process.env.WEBDESIGN_API_SECRET = "test-geheimnis";
const { ausweisPruefen } = await import("./lib/webdesign-ausweis.js");
const b64 = (b) => Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
function bau(inhalt, geheim = "test-geheimnis") {
const n = b64(Buffer.from(JSON.stringify(inhalt), "utf8"));
return n + "." + b64(createHmac("sha256", geheim).update(n).digest());
}
const req = (t) => ({ headers: t ? { authorization: "Bearer " + t } : {} });
let ok = 0, bad = 0;
const p = (n, b, z = "") => { if (b) { ok++; console.log(" ok " + n); } else { bad++; console.log(" FEHLT " + n + " " + z); } };
console.log("\n=== Ausweis der Zugangswand ===\n");
const gut = bau({ bereich: "wd-admin", rolle: "dogfather", exp: Date.now() + 900000 });
p("gueltiger Ausweis wird anerkannt", ausweisPruefen(req(gut))?.rolle === "dogfather");
p("VanVan ebenso", ausweisPruefen(req(bau({ bereich: "wd-admin", rolle: "vanvan", exp: Date.now() + 900000 })))?.rolle === "vanvan");
p("ohne Ausweis -> null", ausweisPruefen(req(null)) === null);
p("Unsinn -> null", ausweisPruefen(req("kein.ausweis")) === null);
p("mit fremdem Geheimnis signiert -> null",
ausweisPruefen(req(bau({ bereich: "wd-admin", rolle: "dogfather", exp: Date.now() + 900000 }, "anderes"))) === null);
p("abgelaufen -> null",
ausweisPruefen(req(bau({ bereich: "wd-admin", rolle: "dogfather", exp: Date.now() - 1000 }))) === null);
p("Sitzungs-Token der Zugangswand gilt hier NICHT",
ausweisPruefen(req(bau({ bereich: "webdesign", rolle: "dogfather", exp: Date.now() + 900000 }))) === null,
"-> anderer Zweck, anderer Bereich");
p("erfundene Rolle -> null",
ausweisPruefen(req(bau({ bereich: "wd-admin", rolle: "hacker", exp: Date.now() + 900000 }))) === null);
p("verfaelschte Signatur -> null", ausweisPruefen(req(gut.split(".")[0] + ".AAAA")) === null);
delete process.env.WEBDESIGN_API_SECRET;
const { ausweisPruefen: ohne } = await import("./lib/webdesign-ausweis.js?neu=1");
p("ohne eingerichtetes Geheimnis gilt KEIN Ausweis", ohne(req(gut)) === null,
"-> ein fehlender Wert schliesst, er oeffnet nicht");
console.log(`\n=== ${ok} bestanden, ${bad} gescheitert ===\n`);
process.exit(bad === 0 ? 0 : 1);