Dreizehn rote Pruefungen, eine Ursache: openssl steht nicht im PATH

DER BEFUND

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 des Hauses ist `secure` und kommt ueber http nicht an),
und dafuer erzeugen sie ein Wegwerf-Zertifikat mit openssl.

GEMESSEN, NICHT VERMUTET

  openssl liegt hier:   C:\Program Files\Git\mingw64\bin\openssl.exe
                        C:\Program Files\Git\usr\bin\openssl.exe
  im System-PATH steht: C:\Program Files\Git\cmd   (nur git.exe)
  im Benutzer-PATH:     nichts mit Git

Wer aus Git Bash startet, erbt die mingw-Pfade und merkt nie etwas.
Die Aufgabenplanung startet `node.exe` DIREKT, ohne Shell -- und
bekommt sie nicht. Bei mir gruen, nachts rot, und der Grund steht
nicht im Code.

Das Schlimmste daran ist nicht der Ausfall: Dreizehn dauerhaft rote
Zeilen in einer Notiz, die Filipe morgens liest, gewoehnen einem das
Hinsehen ab -- und decken dabei die echten Befunde zu.

DIE REPARATUR

`server/helfer-openssl.mjs` sucht openssl erst im PATH (ohne `where`
oder `which` -- beides sind selbst Programme und koennen genauso
fehlen), danach an den Orten, an denen es auf einem Windows-Rechner
mit Git wirklich liegt.

Dazu `zertifikatBauen(schluessel, zertifikat, host)`. Die acht
Aufrufformen im Haus waren identisch bis auf die Variablennamen
(schl/zert, schluesselDatei/zertDatei, zKey/zCrt, sk/zt, key/crt) --
eine Stelle traegt alle neunundzwanzig. Zwei Tage zuvor war eine
davon um ein `-addext` aermer 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.

KEIN EINTRAG IN DEN SYSTEM-PATH. `mingw64\bin` enthaelt rund hundert
Programme mit Unix-Namen (`find`, `sort`, `link`), die gleichnamige
Windows-Befehle verdecken. Das fuer eine Pruefung zu aendern haette
an ganz anderen Stellen Fehler verursacht, die niemand hierher
zurueckverfolgt.

GEGENPROBE IN BEIDE RICHTUNGEN, mit dem PATH des Nachtlaufs:

  vorher (direkter Aufruf):  ABSTURZ: spawnSync openssl ENOENT
  nachher (ueber den Helfer): Zertifikat gebaut, 1236 Bytes

Und eine echte Pruefung unter denselben Bedingungen:

  PATH ohne mingw64 -> pruef-chat-neu-stelle
  63 Pruefungen, 0 Fehler, 0 Abstuerze

Genau diese Datei stand im Nachtlauf mit ENOENT rot.

EINE WACHE DAGEGEN

pruef-struktur prueft ab jetzt, dass niemand openssl wieder direkt
ruft -- der naechste merkt es dort und nicht erst in einem
Nachtlauf, den niemand liest. Drei Gegenproben.

Beim ersten Anlauf schlug sie auf ihre EIGENEN Probetexte an: Sie
liest alle Serverdateien, und dazu gehoert sie selbst. Die Texte
werden jetzt zusammengesetzt. Derselbe Selbsttreffer ist mir heute
schon zweimal passiert.

DER DRITTE AUSGANG BLEIBT, WO ER HINGEHOERT

`helfer-kachel-echtfarbe.mjs` faengt den Fehler weiterhin ab und
meldet `moeglich: false` mit Grund, statt abzubrechen. Eine
Sicherung abzuschaffen, weil ihr Anlass gerade behoben ist, ist der
Anfang des naechsten stillen Fehlschlags.

NEBENBEI: pruef-community-sicht

Sie war rot mit "ZU VIEL: reaktion.html" -- mein eigener Rueckstand
vom 28.09. Die Reaction steht als Kachel im Community-Bereich; die
Liste war nicht nachgezogen. Jetzt 10 / 0.

Die Liste bleibt bewusst von Hand gepflegt: Sie ist eine ABSICHT,
keine Ableitung. Aus rechte.js gelesen verglichen sich zwei Kopien
derselben Quelle -- immer gruen, nie ein Beweis.

GEPRUEFT
  pruef-struktur         ALLES IN ORDNUNG (mit der neuen Wache)
  pruef-community-sicht  10 / 0
  pruef-chat-neu-stelle  63 / 0  (mit dem PATH des Nachtlaufs)
  pruef-notizen, -teamlage-karten, -werdegang: EXIT 0, keine Abstuerze
  mess-quer              EXIT 0
  29 Dateien: node --check auf allen, kein direkter Aufruf mehr
This commit is contained in:
2026-09-29 16:14:13 +02:00
parent b846693de5
commit 077925ab25
32 changed files with 257 additions and 95 deletions
+15 -5
View File
@@ -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;
+112
View File
@@ -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" });
}
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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),
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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) => {
+2 -3
View File
@@ -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),
+2 -3
View File
@@ -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),
+2 -3
View File
@@ -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({
+2 -4
View File
@@ -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({
+2 -3
View File
@@ -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({
+2 -3
View File
@@ -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,
+11
View File
@@ -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)
+2 -4
View File
@@ -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({
+2 -3
View File
@@ -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,
+2 -4
View File
@@ -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({
+2 -4
View File
@@ -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({
+2 -3
View File
@@ -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,
+63
View File
@@ -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);
+2 -3
View File
@@ -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) => {
+2 -3
View File
@@ -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,
+2 -3
View File
@@ -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(
+2 -4
View File
@@ -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({
+2 -4
View File
@@ -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({
+2 -3
View File
@@ -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({