diff --git a/server/helfer-kachel-echtfarbe.mjs b/server/helfer-kachel-echtfarbe.mjs index 7e7c9f58..cad39a4e 100644 --- a/server/helfer-kachel-echtfarbe.mjs +++ b/server/helfer-kachel-echtfarbe.mjs @@ -37,6 +37,7 @@ import { DatabaseSync } from "node:sqlite"; import { scryptSync, randomBytes } from "node:crypto"; import { createServer } from "node:https"; import { request as httpAnfrage } from "node:http"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); const CREW = "crew.dogfather-universe.com"; @@ -127,12 +128,21 @@ export async function pruefeEchteFarben({ port = 4369, breite = 1500 } = {}) { /* Chromium zwingt crew.… per eingebauter HSTS-Liste auf https -- deshalb derselbe selbst unterschriebene Vorbau wie überall. */ const zKey = join(ordner, "k.pem"), zCrt = join(ordner, "z.pem"); + /* HIER BLEIBT DAS try/catch -- anders als an den 28 anderen + Stellen. Diese Datei hat einen dritten Ausgang: Sie sagt + „moeglich: false" samt Grund, statt den ganzen Lauf + abzubrechen. Ein fehlender https-Vorbau ist hier kein Befund + ueber die Farben, sondern „konnte nicht nachsehen". + + Seit dem 29.09.2026 sucht `zertifikatBauen` openssl auch + ausserhalb des PATH -- der Fall sollte damit nicht mehr + eintreten. Der Ausgang bleibt trotzdem stehen: Eine Sicherung + abzuschaffen, weil ihr Anlass gerade behoben ist, ist der + Anfang des naechsten stillen Fehlschlags. */ try { - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", zKey, "-out", zCrt, "-days", "2", "-subj", `/CN=${CREW}`, - "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); - } catch { - return { moeglich: false, grund: "openssl ist nicht da (fuer den https-Vorbau)" }; + zertifikatBauen(zKey, zCrt, CREW); + } catch (f) { + return { moeglich: false, grund: `openssl: ${f.message.split("\n")[0]}` }; } const HTTPS_PORT = port + 1; diff --git a/server/helfer-openssl.mjs b/server/helfer-openssl.mjs new file mode 100644 index 00000000..c426c0d7 --- /dev/null +++ b/server/helfer-openssl.mjs @@ -0,0 +1,112 @@ +/* ===================================================================== + helfer-openssl.mjs — wo liegt openssl? + + WAS HIER SCHIEFGING (29.09.2026 gemessen): + Im nächtlichen Lauf standen dreizehn Prüfungen mit derselben Zeile + rot: + + [uncaughtException] Error: spawnSync openssl ENOENT + + Kein Programmfehler. Die Prüfungen brauchen einen https-Vorbau + (der Sitzungskeks des Hauses ist `secure`, über http kommt er nicht + an), und dafür erzeugen sie ein Wegwerf-Zertifikat mit `openssl`. + + AUF DIESEM RECHNER LIEGT ES IN Git Bash: + C:\Program Files\Git\mingw64\bin\openssl.exe + C:\Program Files\Git\usr\bin\openssl.exe + + Im PATH des Systems steht aber nur `C:\Program Files\Git\cmd` — + dort liegt `git.exe` und sonst nichts. Wer aus Git Bash heraus + startet, erbt die mingw-Pfade und merkt nie etwas. Die + Aufgabenplanung startet `node.exe` direkt, ohne Shell — und + bekommt sie nicht. + + Das ist die unangenehmste Sorte Fehler: Bei mir grün, nachts rot, + und der Grund steht nicht im Code. Dreizehn dauerhaft rote Zeilen + in einer Notiz, die Filipe morgens liest, gewöhnen einem das + Hinsehen ab — und decken dabei die echten Befunde zu. + + WAS DIESE DATEI TUT: Sie sucht `openssl` zuerst dort, wo es + ohnehin gefunden würde (PATH), und danach an den Orten, an denen + es auf einem Windows-Rechner mit Git tatsächlich liegt. Damit + läuft dieselbe Prüfung in beiden Umgebungen. + + WARUM KEIN EINTRAG IN DEN SYSTEM-PATH: `mingw64\bin` enthält rund + hundert Programme mit Unix-Namen (`find`, `sort`, `link` …), die + gleichnamige Windows-Befehle verdecken. Das für eine einzige + Prüfung zu ändern, würde an ganz anderen Stellen Fehler + verursachen, die niemand mehr hierher zurückverfolgt. + ===================================================================== */ + +import { existsSync } from "node:fs"; +import { execFileSync } from "node:child_process"; +import { delimiter, join } from "node:path"; + +/* Die Orte, an denen Git für Windows sein openssl ablegt. Beide + kommen vor: `mingw64` bei der 64-Bit-Fassung, `usr` bei der + mitgelieferten Unix-Umgebung. */ +const BEKANNTE_ORTE = [ + "C:/Program Files/Git/mingw64/bin/openssl.exe", + "C:/Program Files/Git/usr/bin/openssl.exe", + "C:/Program Files (x86)/Git/mingw64/bin/openssl.exe", + "C:/Program Files (x86)/Git/usr/bin/openssl.exe", + "C:/Program Files/OpenSSL-Win64/bin/openssl.exe", +]; + +let gemerkt = null; + +/* IM PATH SUCHEN, OHNE `where` ODER `which` ZU BRAUCHEN. Beide sind + selbst Programme und können genauso fehlen; und `which` gibt es + unter Windows außerhalb von Git Bash gar nicht. */ +const imPfad = () => { + const pfade = (process.env.PATH || "").split(delimiter).filter(Boolean); + const namen = process.platform === "win32" + ? ["openssl.exe", "openssl.com", "openssl"] + : ["openssl"]; + for (const p of pfade) { + for (const n of namen) { + const voll = join(p, n); + if (existsSync(voll)) return voll; + } + } + return null; +}; + +/* Der Pfad zu openssl — oder ein Abbruch mit Anleitung. + * + * DRITTER AUSGANG: Wird nichts gefunden, ist das weder „in Ordnung" + * noch „das Programm ist kaputt", sondern „konnte nicht nachsehen". + * Der Fehler sagt deshalb, WAS fehlt und WO man es herbekommt — + * `spawnSync openssl ENOENT` sagt nur, dass etwas nicht da war. */ +export function opensslPfad() { + if (gemerkt) return gemerkt; + const gefunden = imPfad() || BEKANNTE_ORTE.find((o) => existsSync(o)); + if (!gefunden) { + throw new Error( + "openssl ist nicht auffindbar. Es wird fuer den https-Vorbau gebraucht " + + "(der Sitzungskeks ist `secure` und kommt ueber http nicht an).\n" + + " Gesucht im PATH und an diesen Orten:\n" + + BEKANNTE_ORTE.map((o) => " " + o).join("\n") + + "\n Unter Windows bringt Git fuer Windows es mit; sonst " + + "https://slproweb.com/products/Win32OpenSSL.html"); + } + gemerkt = gefunden; + return gefunden; +} + +/* Ein Wegwerf-Zertifikat für einen Hostnamen. + * + * WARUM HIER UND NICHT IN JEDER DATEI: Die Zeile stand + * neunundzwanzigmal fast gleich im Haus. Zwei Tage bevor ich das + * hier schrieb, war eine davon um ein `-addext` ärmer als die + * anderen — gemerkt hat es niemand, weil der Browser den fehlenden + * Alternativnamen erst bei einer Weiterleitung anmahnt. Eine Stelle + * kann nicht von sich selbst abweichen. */ +export function zertifikatBauen(schluessel, zertifikat, host, tage = 2) { + execFileSync(opensslPfad(), [ + "req", "-x509", "-newkey", "rsa:2048", "-nodes", + "-keyout", schluessel, "-out", zertifikat, + "-days", String(tage), "-subj", `/CN=${host}`, + "-addext", `subjectAltName=DNS:${host}`, + ], { stdio: "ignore" }); +} diff --git a/server/mess-alle-einzelsicht.mjs b/server/mess-alle-einzelsicht.mjs index e4ee57ab..9ca35eb8 100644 --- a/server/mess-alle-einzelsicht.mjs +++ b/server/mess-alle-einzelsicht.mjs @@ -50,6 +50,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-alle-einzelsicht"); await new Promise((r) => setTimeout(r, 900)); @@ -146,9 +147,7 @@ console.log("Stand:", JSON.stringify(stand), `\n (${idLinke}=Kessi/linke, ${idM1}=Diene, ${idM2}=Marina, ${idM3}=Ghost)`); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-aushang.mjs b/server/mess-aushang.mjs index 6fa6d645..e200a794 100644 --- a/server/mess-aushang.mjs +++ b/server/mess-aushang.mjs @@ -39,6 +39,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-aushang"); await new Promise((r) => setTimeout(r, 900)); @@ -105,9 +106,7 @@ await roh(kDogi, `/workspace/api/chat/nachrichten/${nid}/anheften`, "PUT", { an: console.log(`Aushang #${nid} in Raum #${raumId}`); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-buehne.mjs b/server/mess-buehne.mjs index 12b24289..fa044be8 100644 --- a/server/mess-buehne.mjs +++ b/server/mess-buehne.mjs @@ -36,6 +36,7 @@ import { fileURLToPath } from "node:url"; import { request } from "node:http"; import { execFileSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); const ordner = mkdtempSync(join(tmpdir(), "mess-buehne-")); @@ -159,9 +160,7 @@ const REDEN = [ /* ---------- Der Vorbau -------------------------------------------------- */ const schluesselDatei = join(ordner, "p.key"); const zertDatei = join(ordner, "p.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluesselDatei, "-out", zertDatei, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); +zertifikatBauen(schluesselDatei, zertDatei, CREW); const vorbau = httpsServer({ key: readFileSync(schluesselDatei), cert: readFileSync(zertDatei), diff --git a/server/mess-chat-neu-stelle.mjs b/server/mess-chat-neu-stelle.mjs index 6fd48254..3725b579 100644 --- a/server/mess-chat-neu-stelle.mjs +++ b/server/mess-chat-neu-stelle.mjs @@ -41,6 +41,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(300_000, "mess-chat-neu-stelle"); await new Promise((r) => setTimeout(r, 900)); @@ -129,9 +130,7 @@ console.log(`gelesen_bis beim Oeffnen: ${stand.json().gelesen_bis}` + `, Nachrichten: ${(stand.json().nachrichten || []).length}`); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-chat-optik.mjs b/server/mess-chat-optik.mjs index b9953234..86346905 100644 --- a/server/mess-chat-optik.mjs +++ b/server/mess-chat-optik.mjs @@ -40,6 +40,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(260_000, "mess-chat-optik"); await new Promise((r) => setTimeout(r, 900)); @@ -134,9 +135,7 @@ if (an.code !== 200) { console.log(`ABBRUCH: Anmeldung ${an.code}`); process.exi const keks = (an.kopf["set-cookie"] || []).map((x) => x.split(";")[0]).join("; "); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-dialog-ausgang.mjs b/server/mess-dialog-ausgang.mjs index 9308dcda..a38cb6ae 100644 --- a/server/mess-dialog-ausgang.mjs +++ b/server/mess-dialog-ausgang.mjs @@ -53,6 +53,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-dialog-ausgang"); await new Promise((r) => setTimeout(r, 900)); @@ -108,9 +109,7 @@ if (an.code !== 200) { console.log(`ABBRUCH: Anmeldung ${an.code}`); process.exi const keks = (an.kopf["set-cookie"] || []).map((x) => x.split(";")[0]).join("; "); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-eingang-optik.mjs b/server/mess-eingang-optik.mjs index 296dc60d..acd323c1 100644 --- a/server/mess-eingang-optik.mjs +++ b/server/mess-eingang-optik.mjs @@ -38,6 +38,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-eingang-optik"); await new Promise((r) => setTimeout(r, 900)); @@ -116,9 +117,7 @@ if (an.code !== 200) { console.log(`ABBRUCH: Anmeldung ${an.code}`); process.exi const keks = (an.kopf["set-cookie"] || []).map((x) => x.split(";")[0]).join("; "); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-gifs-handy.mjs b/server/mess-gifs-handy.mjs index e75eafce..45cb5840 100644 --- a/server/mess-gifs-handy.mjs +++ b/server/mess-gifs-handy.mjs @@ -47,6 +47,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(300_000, "mess-gifs-handy"); await new Promise((r) => setTimeout(r, 900)); @@ -140,9 +141,7 @@ const raumId = JSON.parse(raum.text || "{}").raum_id; console.log(`Gespraech: HTTP ${raum.code}, Raum ${raumId}`); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-hand-personen.mjs b/server/mess-hand-personen.mjs index 60338070..a3294b9d 100644 --- a/server/mess-hand-personen.mjs +++ b/server/mess-hand-personen.mjs @@ -48,6 +48,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-hand-personen"); await new Promise((r) => setTimeout(r, 900)); @@ -144,9 +145,7 @@ for (const [wer, keks] of Object.entries(kekse)) { } const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-kachelreihen.mjs b/server/mess-kachelreihen.mjs index 9c53119f..d4ebb018 100644 --- a/server/mess-kachelreihen.mjs +++ b/server/mess-kachelreihen.mjs @@ -59,6 +59,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-kachelreihen"); await new Promise((r) => setTimeout(r, 900)); @@ -126,9 +127,7 @@ for (const [, rolle, code] of ROLLEN) { } const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/mess-notizblock.mjs b/server/mess-notizblock.mjs index 0e28d996..bbea436f 100644 --- a/server/mess-notizblock.mjs +++ b/server/mess-notizblock.mjs @@ -54,6 +54,7 @@ const ordner = mkdtempSync(join(tmpdir(), "ws-notiz-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; /* Eine feste Nummer -- `eigenerPort` leitet seine aus der Stelle im Alphabet der PRUEFdateien ab, und dieses Werkzeug ist keine. @@ -183,9 +184,7 @@ const { createServer: httpsServer } = await import("node:https"); const { request: httpAnfrage } = await import("node:http"); const schluesselDatei = join(ordner, "m.key"); const zertDatei = join(ordner, "m.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluesselDatei, "-out", zertDatei, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); +zertifikatBauen(schluesselDatei, zertDatei, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ key: readFileSync(schluesselDatei), cert: readFileSync(zertDatei) }, (von, nach) => { diff --git a/server/mess-quer.mjs b/server/mess-quer.mjs index be2f7c98..6c3a420c 100644 --- a/server/mess-quer.mjs +++ b/server/mess-quer.mjs @@ -23,6 +23,7 @@ import { fileURLToPath } from "node:url"; import { request } from "node:http"; import { execFileSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); const ordner = mkdtempSync(join(tmpdir(), "mess-reakt-")); @@ -146,9 +147,7 @@ const REDEN = [ /* ---------- Der Vorbau -------------------------------------------------- */ const schluesselDatei = join(ordner, "p.key"); const zertDatei = join(ordner, "p.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluesselDatei, "-out", zertDatei, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); +zertifikatBauen(schluesselDatei, zertDatei, CREW); const vorbau = httpsServer({ key: readFileSync(schluesselDatei), cert: readFileSync(zertDatei), diff --git a/server/mess-reaktion.mjs b/server/mess-reaktion.mjs index 50967082..05c5f344 100644 --- a/server/mess-reaktion.mjs +++ b/server/mess-reaktion.mjs @@ -23,6 +23,7 @@ import { fileURLToPath } from "node:url"; import { request } from "node:http"; import { execFileSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); const ordner = mkdtempSync(join(tmpdir(), "mess-reakt-")); @@ -162,9 +163,7 @@ const REDEN = [ /* ---------- Der Vorbau -------------------------------------------------- */ const schluesselDatei = join(ordner, "p.key"); const zertDatei = join(ordner, "p.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluesselDatei, "-out", zertDatei, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); +zertifikatBauen(schluesselDatei, zertDatei, CREW); const vorbau = httpsServer({ key: readFileSync(schluesselDatei), cert: readFileSync(zertDatei), diff --git a/server/mess-support-runde.mjs b/server/mess-support-runde.mjs index 79d80477..b1f84a98 100644 --- a/server/mess-support-runde.mjs +++ b/server/mess-support-runde.mjs @@ -53,6 +53,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "mess-support-runde"); await new Promise((r) => setTimeout(r, 900)); @@ -129,9 +130,7 @@ await anfrage(`/workspace/api/support/${dran}`, "PATCH", + "er war hinter der Kopfleiste verschwunden." }, kHand); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/pruef-bewerbung-aufgaben.mjs b/server/pruef-bewerbung-aufgaben.mjs index 8278da92..8602c20a 100644 --- a/server/pruef-bewerbung-aufgaben.mjs +++ b/server/pruef-bewerbung-aufgaben.mjs @@ -45,6 +45,7 @@ import { join } from "node:path"; import { request as httpAnfrage } from "node:http"; import { eigenerPort } from "./helfer-port.mjs"; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const PORT = await eigenerPort(import.meta, "pruef-bewerbung-aufgaben"); const ordner = mkdtempSync(join(tmpdir(), "ws-bew-")); @@ -460,10 +461,7 @@ melde("=== 6. Am echten Bildschirm ==="); const schluessel = join(ordner, "pruef.key"); const zertifikat = join(ordner, "pruef.crt"); - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluessel, "-out", zertifikat, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], - { stdio: "ignore" }); + zertifikatBauen(schluessel, zertifikat, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ diff --git a/server/pruef-chat-neu-stelle.mjs b/server/pruef-chat-neu-stelle.mjs index 67095a2d..f58945e9 100644 --- a/server/pruef-chat-neu-stelle.mjs +++ b/server/pruef-chat-neu-stelle.mjs @@ -58,6 +58,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(300_000, "pruef-chat-neu-stelle"); await new Promise((r) => setTimeout(r, 1000)); @@ -153,9 +154,7 @@ const LEUTE = [ /* ---- Zertifikat und Vorbau (eine Adresse je Haus) ------------------- */ const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, - "-addext", `subjectAltName=DNS:${CREW},DNS:${AGENTUR}`], { stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ diff --git a/server/pruef-chat-neu.mjs b/server/pruef-chat-neu.mjs index 6760388c..c3755054 100644 --- a/server/pruef-chat-neu.mjs +++ b/server/pruef-chat-neu.mjs @@ -57,6 +57,7 @@ import { execFileSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; import { eigenerPort } from "./helfer-port.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const PORT = await eigenerPort(import.meta, "pruef-chat-neu"); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-drei-")); @@ -100,9 +101,7 @@ const idB = mach("Nele", "modi", "CODE-MODI-0002"); d.close(); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], - { stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const HP = PORT + 1; const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ host: "127.0.0.1", port: PORT, path: von.url, method: von.method, diff --git a/server/pruef-community-sicht.mjs b/server/pruef-community-sicht.mjs index c6fc8f32..518c68f9 100644 --- a/server/pruef-community-sicht.mjs +++ b/server/pruef-community-sicht.mjs @@ -102,6 +102,17 @@ const COMMUNITY_SEITEN = [ "chat.html", // der Treff "hilfe.html", // Regeln & Hilfe "material.html", // Dogi-Media + /* DIE REACTION kam am 28.09.2026 dazu und steht im + Community-Bereich als eigene Kachel hinter Dogi-Media. Wer + zusieht, braucht die Seite -- sonst gaebe es niemanden im Saal. + + WARUM DIESE LISTE TROTZDEM VON HAND GEPFLEGT WIRD: Sie ist eine + ABSICHT, keine Ableitung. Wuerde sie aus `rechte.js` gelesen, + verglichen zwei Kopien derselben Quelle miteinander -- dann + waere sie immer gruen und wuerde nichts beweisen. Der Preis ist + dieser Eintrag hier; die Pruefung sagt beim Anschlagen selbst, + welche Seite fehlt oder zu viel ist. */ + "reaktion.html", // zusammen schauen (seit 28.09.2026) "start.html", // die Wand "steckbrief.html", // der eigene Steckbrief "support.html", // etwas ist kaputt (seit 24.09. fuer alle) diff --git a/server/pruef-handy-teamdogi.mjs b/server/pruef-handy-teamdogi.mjs index 39e5b3b3..7aef5354 100644 --- a/server/pruef-handy-teamdogi.mjs +++ b/server/pruef-handy-teamdogi.mjs @@ -104,6 +104,7 @@ import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { notbremse } from "./helfer-notbremse.mjs"; import { eigenerPort } from "./helfer-port.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const REPO = join(dirname(fileURLToPath(import.meta.url)), ".."); const ordner = mkdtempSync(join(tmpdir(), "ws-handy-")); @@ -250,10 +251,7 @@ const { request: httpAnfrage } = await import("node:http"); const schluessel = join(ordner, "pruef.key"); const zertifikat = join(ordner, "pruef.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluessel, "-out", zertifikat, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], - { stdio: "ignore" }); +zertifikatBauen(schluessel, zertifikat, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ diff --git a/server/pruef-kopfleiste-farbe.mjs b/server/pruef-kopfleiste-farbe.mjs index 882af0be..996df7dc 100644 --- a/server/pruef-kopfleiste-farbe.mjs +++ b/server/pruef-kopfleiste-farbe.mjs @@ -42,6 +42,7 @@ import { execFileSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; import { notbremse } from "./helfer-notbremse.mjs"; import { eigenerPort } from "./helfer-port.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const CREW = "crew.dogfather-universe.com"; const PORT = await eigenerPort(import.meta, "pruef-kopfleiste-farbe"); @@ -83,9 +84,7 @@ d.close(); /* ---------- Der Vorbau ------------------------------------------------- */ const schl = join(ordner, "p.key"), zert = join(ordner, "p.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const HP = PORT + 1; const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ host: "127.0.0.1", port: PORT, path: von.url, method: von.method, diff --git a/server/pruef-material.mjs b/server/pruef-material.mjs index cf3aedb0..dd46b1e0 100644 --- a/server/pruef-material.mjs +++ b/server/pruef-material.mjs @@ -55,6 +55,7 @@ import { join } from "node:path"; import { request as httpAnfrage } from "node:http"; import { eigenerPort } from "./helfer-port.mjs"; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const PORT = await eigenerPort(import.meta, "pruef-material"); @@ -783,10 +784,7 @@ melde("=== 13. Am echten Bildschirm ==="); const schluessel = join(ordner, "pruef.key"); const zertifikat = join(ordner, "pruef.crt"); - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluessel, "-out", zertifikat, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], - { stdio: "ignore" }); + zertifikatBauen(schluessel, zertifikat, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ diff --git a/server/pruef-notizen.mjs b/server/pruef-notizen.mjs index 8afc3439..2b52360b 100644 --- a/server/pruef-notizen.mjs +++ b/server/pruef-notizen.mjs @@ -50,6 +50,7 @@ const ordner = mkdtempSync(join(tmpdir(), "ws-notiz-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const { eigenerPort } = await import("./helfer-port.mjs"); const PORT = await eigenerPort(import.meta, "die Notizblockpruefung"); @@ -421,10 +422,7 @@ const { request: httpAnfrage } = await import("node:http"); const schluesselDatei = join(ordner, "pruef.key"); const zertDatei = join(ordner, "pruef.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluesselDatei, "-out", zertDatei, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], - { stdio: "ignore" }); +zertifikatBauen(schluesselDatei, zertDatei, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ diff --git a/server/pruef-personen-formular.mjs b/server/pruef-personen-formular.mjs index f880e7bc..af0cfc27 100644 --- a/server/pruef-personen-formular.mjs +++ b/server/pruef-personen-formular.mjs @@ -41,6 +41,7 @@ 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"; import { eigenerPort } from "./helfer-port.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); /* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort zwei Auffangnetze ein, die einen Absturz nur protokollieren -- @@ -480,9 +481,7 @@ console.log("\n— Die rechte Hand legt jemanden an —"); const { readFileSync: lesen } = await import("node:fs"); const HOST = "crew.dogfather-universe.com"; const sk = join(ordner, "pf.key"), zt = join(ordner, "pf.crt"); - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", sk, "-out", zt, "-days", "2", "-subj", `/CN=${HOST}`, - "-addext", `subjectAltName=DNS:${HOST}`], { stdio: "ignore" }); + zertifikatBauen(sk, zt, HOST); const HP = PORT + 1; const vorbau = httpsServer({ key: lesen(sk), cert: lesen(zt) }, (von, nach) => { const w = httpAnfrage({ host: "127.0.0.1", port: PORT, path: von.url, diff --git a/server/pruef-struktur.mjs b/server/pruef-struktur.mjs index 8c60a203..c0b90efd 100644 --- a/server/pruef-struktur.mjs +++ b/server/pruef-struktur.mjs @@ -902,5 +902,68 @@ ok(routeGibtEs("/workspace/api/aufgaben"), ok(!existsSync(join(WS, "gibtesnicht.html")), "erfundene Seite wird als fehlend erkannt"); +/* ===================================================================== + RUFT JEMAND `openssl` WIEDER DIREKT AUF? + + WAS HIER SCHIEFGING (29.09.2026 gemessen): Im naechtlichen Lauf + standen DREIZEHN Pruefungen mit derselben Zeile rot -- + + [uncaughtException] Error: spawnSync openssl ENOENT + + Kein Programmfehler. Die Pruefungen brauchen einen https-Vorbau + (der Sitzungskeks ist `secure`), und dafuer erzeugen sie ein + Wegwerf-Zertifikat. Auf diesem Rechner liegt openssl in + `Git\\mingw64\\bin`; im System-PATH steht aber nur `Git\\cmd`. Wer + aus Git Bash startet, erbt die mingw-Pfade und merkt nie etwas -- + die Aufgabenplanung startet `node.exe` direkt und bekommt sie + nicht. + + Bei mir gruen, nachts rot, und der Grund steht nicht im Code. Die + dreizehn roten Zeilen haben dabei monatelang die echten Befunde + zugedeckt. + + `helfer-openssl.mjs` sucht das Programm jetzt auch ausserhalb des + PATH. Diese Wache sorgt dafuer, dass der direkte Aufruf nicht + zurueckkommt -- der naechste, der ihn schreibt, merkt es hier und + nicht erst in einem Nachtlauf, den niemand liest. */ +console.log(`\n=== Ruft noch jemand openssl direkt auf? ===`); +{ + const direkt = []; + let ueberHelfer = 0; + for (const datei of readdirSync(SERVER).filter((n) => /\.(mjs|js)$/.test(n))) { + if (datei === "helfer-openssl.mjs") continue; + const text = readFileSync(join(SERVER, datei), "utf8"); + for (const m of text.matchAll(/exec(?:File)?Sync\(\s*["'`]openssl/g)) { + direkt.push(`${datei}:${text.slice(0, m.index).split("\n").length}`); + } + if (/zertifikatBauen\(/.test(text)) ueberHelfer++; + } + ok(ueberHelfer > 20, + `${ueberHelfer} Dateien bauen ihr Zertifikat ueber den Helfer`); + ok(direkt.length === 0, + direkt.length + ? `DIREKT: ${direkt.slice(0, 6).join(" | ")} -- bitte zertifikatBauen() aus ` + + "helfer-openssl.mjs nehmen, sonst faellt es im Nachtlauf um" + : "keine Datei ruft openssl mehr am PATH vorbei"); + + /* GEGENPROBE IN BEIDE RICHTUNGEN. Eine Wache, die nur „nichts + gefunden" sagen kann, hat nichts bewiesen. + + DIE PROBETEXTE WERDEN ZUSAMMENGESETZT und stehen nicht am Stueck + da. Beim ersten Anlauf schlug diese Wache auf ihre EIGENEN + Gegenproben an: Sie liest den Quelltext aller Serverdateien, + und dazu gehoert diese hier. Dasselbe ist mir heute schon + zweimal passiert -- eine Pruefung, die ihre eigene Begruendung + als Fund meldet, ist der haeufigste Selbsttreffer im Haus. */ + const findet = (t) => [...t.matchAll(/exec(?:File)?Sync\(\s*["'`]openssl/g)].length; + const O = "openssl"; + ok(findet(`execFileSync("${O}", ["version"]);`) === 1, + "Gegenprobe: ein direkter Aufruf wird erkannt"); + ok(findet(`execSync(\`${O} version\`);`) === 1, + "auch mit Schraegstrich-Anfuehrung"); + ok(findet("zertifikatBauen(k, z, CREW);") === 0, + "und der Weg ueber den Helfer gilt nicht als Fund"); +} + console.log(`\n${fehler === 0 ? "ALLES IN ORDNUNG" : `${fehler} FEHLER`}`); process.exit(fehler ? 1 : 0); diff --git a/server/pruef-teamlage-karten.mjs b/server/pruef-teamlage-karten.mjs index aebd3593..4e8bd1cd 100644 --- a/server/pruef-teamlage-karten.mjs +++ b/server/pruef-teamlage-karten.mjs @@ -49,6 +49,7 @@ import { execFileSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; import { notbremse } from "./helfer-notbremse.mjs"; import { eigenerPort } from "./helfer-port.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const CREW = "crew.dogfather-universe.com"; const PORT = await eigenerPort(import.meta, "pruef-teamlage-karten"); @@ -123,9 +124,7 @@ d.close(); https. Ein selbstsigniertes Zertifikat plus MAP-Regel ist der Weg, den auch die anderen Browserpruefungen dieses Hauses gehen. */ const schl = join(ordner, "p.key"), zert = join(ordner, "p.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schl, "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, - "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const HP = PORT + 1; const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { diff --git a/server/pruef-unterstuetzung.mjs b/server/pruef-unterstuetzung.mjs index eeb635d5..960dfdff 100644 --- a/server/pruef-unterstuetzung.mjs +++ b/server/pruef-unterstuetzung.mjs @@ -75,6 +75,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(240_000, "pruef-unterstuetzung"); await new Promise((r) => setTimeout(r, 800)); @@ -344,9 +345,7 @@ ok(WEG_SPALTEN.includes("geaendert_von"), melde(""); melde("=== 6. Im Browser ==="); const schl = join(ordner, "b.key"), zert = join(ordner, "b.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", schl, - "-out", zert, "-days", "2", "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], -{ stdio: "ignore" }); +zertifikatBauen(schl, zert, CREW); const vorbau = httpsServer({ key: readFileSync(schl), cert: readFileSync(zert) }, (von, nach) => { const w = httpAnfrage({ host: "127.0.0.1", port: PORT, path: von.url, method: von.method, diff --git a/server/pruef-werdegang.mjs b/server/pruef-werdegang.mjs index 66298b32..494e0ea4 100644 --- a/server/pruef-werdegang.mjs +++ b/server/pruef-werdegang.mjs @@ -47,6 +47,7 @@ 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"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; await import("./index.js"); notbremse(180_000, "pruef-werdegang"); await new Promise((r) => setTimeout(r, 700)); @@ -627,9 +628,7 @@ melde("=== 11. Im Browser ==="); const zOrdner = tempOrdner(pfad(tempWurzel(), "wg-zeugnis-")); const zKey = pfad(zOrdner, "k.pem"), zCrt = pfad(zOrdner, "z.pem"); - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", zKey, "-out", zCrt, "-days", "2", "-subj", `/CN=${CREW}`, - "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); + zertifikatBauen(zKey, zCrt, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer( diff --git a/server/pruef-willkommen.mjs b/server/pruef-willkommen.mjs index fa08d6ac..7ac993c3 100644 --- a/server/pruef-willkommen.mjs +++ b/server/pruef-willkommen.mjs @@ -45,6 +45,7 @@ const ordner = mkdtempSync(join(tmpdir(), "ws-willk-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const { eigenerPort } = await import("./helfer-port.mjs"); const PORT = await eigenerPort(import.meta, "die Willkommenspruefung"); @@ -351,10 +352,7 @@ melde("\n=== Am echten Bildschirm ==="); const schluessel = join(ordner, "pruef.key"); const zertifikat = join(ordner, "pruef.crt"); - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluessel, "-out", zertifikat, "-days", "2", - "-subj", `/CN=${HOST}`, "-addext", `subjectAltName=DNS:${HOST}`], - { stdio: "ignore" }); + zertifikatBauen(schluessel, zertifikat, HOST); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ diff --git a/server/pruef-zuteilung.mjs b/server/pruef-zuteilung.mjs index 85293699..9fdfa9ff 100644 --- a/server/pruef-zuteilung.mjs +++ b/server/pruef-zuteilung.mjs @@ -41,6 +41,7 @@ const ordner = mkdtempSync(join(tmpdir(), "ws-zuteil-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); import { notbremse } from "./helfer-notbremse.mjs"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const { eigenerPort } = await import("./helfer-port.mjs"); const PORT = await eigenerPort(import.meta, "die Zuteilungspruefung"); @@ -511,10 +512,7 @@ melde("\n=== Am echten Bildschirm ==="); const schluessel = join(ordner, "pruef.key"); const zertifikat = join(ordner, "pruef.crt"); - execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", schluessel, "-out", zertifikat, "-days", "2", - "-subj", `/CN=${HOST}`, "-addext", `subjectAltName=DNS:${HOST}`], - { stdio: "ignore" }); + zertifikatBauen(schluessel, zertifikat, HOST); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ diff --git a/server/tiktok-videos.mjs b/server/tiktok-videos.mjs index b83be982..52e5eb1c 100644 --- a/server/tiktok-videos.mjs +++ b/server/tiktok-videos.mjs @@ -81,6 +81,7 @@ import { request as httpAnfrage } from "node:http"; import { execFileSync, spawnSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; import { createServer as netServer } from "node:net"; +import { zertifikatBauen } from "./helfer-openssl.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); const WURZEL = join(HIER, ".."); @@ -493,9 +494,7 @@ console.log(`Chat: ${treffRaum ? `${imChat} von ${CHAT.length} Nachrichten` : "R /* ---------- Der Vorbau mit dem Zertifikat ------------------------------- */ const key = join(ordner, "v.key"), crt = join(ordner, "v.crt"); -execFileSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", - "-keyout", key, "-out", crt, "-days", "2", - "-subj", `/CN=${CREW}`, "-addext", `subjectAltName=DNS:${CREW}`], { stdio: "ignore" }); +zertifikatBauen(key, crt, CREW); const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ key: readFileSync(key), cert: readFileSync(crt) }, (von, nach) => { const weiter = httpAnfrage({