/* MESSUNG, KEINE PRUEFUNG (17.09.2026) Filipe: "die community und alle anderen sollen die neuen sachen in allen kategorien auch sehen bitte. in allen die sie sehen soll auch jede aenderung mit gehen, immer nur in denen die ihnen erlaubt ist zu sehen." Die Frage: Was sieht eigentlich wer? Nicht geraten -- gemessen. ZWEI DINGE, DIE ICH BEIM ERSTEN VERSUCH FALSCH HATTE und die jede Zahl wertlos gemacht haben: 1. Die Community lebt auf crew., nicht auf der Agenturadresse. Ohne den richtigen Host-Kopf kam der Gast mit 401 "ungueltig" heraus -- und das sah aus wie ein Befund, war aber meine eigene falsche Adresse. 2. Ein Gast bestaetigt beim Anmelden sein Alter (`alter_ok`). Aufrufen mit: node server/mess-sichtbarkeit.mjs */ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { request as httpAnfrage } from "node:http"; import { eigenerPort } from "./helfer-port.mjs"; const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-mess-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; const express = (await import("express")).default; const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; await import("./index.js"); notbremse(180_000, "mess-sichtbarkeit"); await new Promise((r) => setTimeout(r, 700)); const CREW = "crew.dogfather-universe.com"; const AGENTUR = "workspace.dogfather-universe.com"; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes, createHmac } = await import("node:crypto"); const { TREFF_BRETTER } = await import("./workspace.js"); const { TREFF_FREIGABE_BRETTER } = await import("./workspace-treff.js"); const { BEREICHE } = await import("./workspace-bereiche.js"); const ALLE_BEREICHE = Object.keys(BEREICHE); const d = new DatabaseSync(process.env.WORKSPACE_DB); const jetzt = new Date().toISOString(); const sch = randomBytes(32).toString("hex"); d.prepare("INSERT INTO einstellungen (schluessel, wert, geaendert, von)" + " VALUES (?,?,?,NULL) ON CONFLICT(schluessel) DO NOTHING") .run("code_kennung_schluessel", sch, jetzt); const ROLLEN = ["admin", "hand", "modi", "gast"]; const codes = {}; for (const r of ROLLEN) { const code = `CODE-${r.toUpperCase()}-0001`; const salt = randomBytes(16).toString("hex"); const hash = scryptSync(code, salt, 64, { N: 32768, r: 8, p: 1, maxmem: 96 * 1024 * 1024 }).toString("hex"); d.prepare("INSERT INTO personen" + " (name, rolle, code_hash, code_salt, code_n, code_kennung, aktiv, erstellt)" + " VALUES (?,?,?,?,?,?,1,?)") .run(r, r, hash, salt, 32768, createHmac("sha256", sch).update(code).digest("hex"), jetzt); codes[r] = code; } d.close(); function roh(pfad, host, kopf = {}, koerper = null, methode = null) { return new Promise((fertig, schief) => { const a = httpAnfrage({ host: "127.0.0.1", port: PORT, path: pfad, method: methode || (koerper ? "POST" : "GET"), headers: { Host: host, ...(koerper ? { "Content-Type": "application/json" } : {}), ...kopf }, }, (antwort) => { let text = ""; antwort.on("data", (s) => { text += s; }); antwort.on("end", () => fertig({ code: antwort.statusCode, text, kopf: antwort.headers })); }); a.on("error", schief); if (koerper) a.write(JSON.stringify(koerper)); a.end(); }); } async function anmelden(rolle, host) { const r = await roh("/workspace/api/anmelden", host, {}, rolle === "gast" ? { rolle, code: codes[rolle], alter_ok: true } : { rolle, code: codes[rolle] }); const kekse = [].concat(r.kopf?.["set-cookie"] || []); return { keks: kekse.map((c) => c.split(";")[0]).join("; "), code: r.code }; } /* Jede Rolle auf der Wand, auf der sie hingehoert. */ const WAND = { admin: CREW, hand: CREW, modi: CREW, gast: CREW }; const kekse = {}; console.log("\n=== Anmeldung ==="); for (const r of ROLLEN) { const a = await anmelden(r, WAND[r]); kekse[r] = a.keks; console.log(` ${r.padEnd(8)} auf ${WAND[r]} -> ${a.code}`); } /* ---- DogFather uebernimmt ueberall den Startkatalog ------------------ */ console.log("\n=== DogFather uebernimmt die Vorschlaege ==="); for (const b of ALLE_BEREICHE) { const a = await roh(`/workspace/api/bereich/${b}/start`, CREW, { cookie: kekse.admin, origin: `https://${CREW}` }, {}); const j = JSON.parse(a.text || "{}"); console.log(` ${b.padEnd(12)} ${a.code} angelegt: ${j?.angelegt ?? "-"}`); } /* ---- Und jetzt: wer sieht wie viel? --------------------------------- */ console.log("\n=== Was jede Rolle danach sieht ==="); console.log(" Brett " + ROLLEN.map((r) => r.padEnd(8)).join("") + "Freigabe?"); for (const b of TREFF_BRETTER) { const zahlen = []; for (const r of ROLLEN) { const a = await roh(`/workspace/api/bereich/${b}`, WAND[r], { cookie: kekse[r] }); let j = null; try { j = JSON.parse(a.text); } catch { /* keine JSON-Antwort */ } zahlen.push(a.code === 200 ? String((j?.eintraege || []).length) : `(${a.code})`); } const frei = TREFF_FREIGABE_BRETTER.includes(b) ? "JA" : "-"; console.log(` ${b.padEnd(14)}` + zahlen.map((z) => z.padEnd(8)).join("") + frei); } console.log("\n=== Wer bekommt den Vorschlagskasten? ==="); for (const b of TREFF_BRETTER) { const zeile = []; for (const r of ROLLEN) { const a = await roh(`/workspace/api/bereich/${b}/start`, WAND[r], { cookie: kekse[r] }); let j = null; try { j = JSON.parse(a.text); } catch { /* keine JSON-Antwort */ } zeile.push(a.code === 200 ? `${(j?.vorschlaege || []).length}` : `(${a.code})`); } console.log(` ${b.padEnd(14)}` + zeile.map((z) => z.padEnd(8)).join("")); } console.log("\n=== Und die uebrigen Kategorien (ausserhalb des Rudels) ==="); const andere = Object.keys(BEREICHE).filter((b) => !TREFF_BRETTER.includes(b)); console.log(" Bereich " + ROLLEN.map((r) => r.padEnd(8)).join("")); for (const b of andere) { const zeile = []; for (const r of ROLLEN) { const a = await roh(`/workspace/api/bereich/${b}`, WAND[r], { cookie: kekse[r] }); let j = null; try { j = JSON.parse(a.text); } catch { /* keine JSON-Antwort */ } zeile.push(a.code === 200 ? String((j?.eintraege || []).length) : `(${a.code})`); } console.log(` ${b.padEnd(14)}` + zeile.map((z) => z.padEnd(8)).join("")); } try { rmSync(ordner, { recursive: true, force: true }); } catch { /* Aufraeumrest */ } process.exit(0);