bootstrap-admin.mjs: Zugangsdaten nicht mehr verlieren, wenn ZUGANGSDATEN.md nicht beschreibbar ist

Der Admin-Benutzer wird immer in der Datenbank angelegt, bevor
versucht wird, die generierten Zugangsdaten in ZUGANGSDATEN.md zu
schreiben. Schlug dieser Schreibvorgang fehl (z. B. EACCES, weil die
per Bind-Mount eingebundene Host-Datei root gehört und der
App-Container als nicht-root läuft), flog bisher eine ungefangene
Exception – das Skript brach ab, BEVOR das Passwort irgendwo
protokolliert wurde. Der Admin existierte dann in der DB, aber niemand
kannte sein Passwort mehr.

appendFileSync() läuft jetzt in einem try/catch; schlägt der
Dateizugriff fehl, werden E-Mail und Passwort stattdessen direkt ins
Log geschrieben, und das Skript beendet sich weiterhin mit Exitcode 0
(die eigentlich kritische Operation – der DB-Insert – ist ja bereits
erfolgreich). Lokal verifiziert: Skript bricht bei einer nicht
beschreibbaren ZUGANGSDATEN.md nicht mehr ab, Zugangsdaten landen im
Log, zweiter Lauf bleibt idempotent.

DEPLOYMENT.md: Schritt 2 ergänzt um "chmod 666 ZUGANGSDATEN.md" (der
eigentliche Auslöser), neue Fehlerbehebung-Einträge für
ECONNREFUSED-Startreihenfolge und diesen EACCES-Fall inkl.
Recovery-Anleitung für einen bereits verwaisten Admin-Account.
This commit is contained in:
2026-07-18 14:44:38 +02:00
parent 0d9d26b885
commit 94a2c98252
2 changed files with 60 additions and 5 deletions
+21 -4
View File
@@ -58,19 +58,36 @@ async function main() {
[email, passwordHash]
);
// Der Admin-Datensatz steht ab hier in der Datenbank – das darf durch
// ein Problem beim Ablegen der Zugangsdaten nicht mehr verloren gehen
// (sonst gibt es einen Benutzer, dessen Passwort niemand kennt).
// appendFileSync() also bewusst nicht mehr ungefangen werfen lassen,
// sondern im Fehlerfall die Zugangsdaten direkt ins Log schreiben.
const zugangsdatenPath = join(
dirname(dirname(fileURLToPath(import.meta.url))),
"ZUGANGSDATEN.md"
);
const entry = `\n## Admin-Zugang (automatisch angelegt, ${new Date().toISOString().slice(0, 10)})\n\n- E-Mail: \`${email}\`\n- Passwort: \`${password}\`\n\nBitte nach dem ersten Login ändern.\n`;
if (existsSync(zugangsdatenPath)) {
appendFileSync(zugangsdatenPath, entry);
let wroteFile = false;
try {
if (existsSync(zugangsdatenPath)) {
appendFileSync(zugangsdatenPath, entry);
wroteFile = true;
}
} catch (err) {
console.warn(`bootstrap-admin – Konnte ${zugangsdatenPath} nicht beschreiben: ${err.message}`);
}
if (wroteFile) {
console.log(`bootstrap-admin – Admin angelegt: ${email} (Passwort siehe ZUGANGSDATEN.md)`);
} else {
console.warn(
`bootstrap-admin – ${zugangsdatenPath} existiert nicht, Zugangsdaten werden nur geloggt:`
`bootstrap-admin – ${zugangsdatenPath} existiert nicht oder ist nicht beschreibbar. ` +
`Zugangsdaten NUR HIER im Log, bitte sofort notieren:`
);
console.log(`bootstrap-admin – Admin-E-Mail: ${email}`);
console.log(`bootstrap-admin – Admin-Passwort: ${password}`);
}
console.log(`bootstrap-admin – Admin angelegt: ${email} (Passwort siehe ZUGANGSDATEN.md)`);
} finally {
await client.end();
}