import * as fs from 'fs';
|
import * as path from 'path';
|
import type { Einstellungen } from 'bibliothek-types';
|
import { anwendungsDatenOrdner } from './pfade';
|
|
/**
|
* Einstellungen liegen in `konfiguration.json` neben der Anwendung. Die Datei wird
|
* beim ersten Start mit Standardwerten angelegt und kann über die Oberfläche
|
* (nur lokal am Server) oder von Hand gepflegt werden.
|
*
|
* Umgebungsvariablen haben Vorrang — praktisch für abweichende Testläufe.
|
*/
|
|
const STANDARD_EINSTELLUNGEN: Einstellungen = {
|
datenOrdner: '', // leer = Unterordner „data" im Anwendungsdaten-Ordner
|
port: 3000,
|
gitBenutzer: '', // leer = SSH-Konfiguration des Dienstbenutzers entscheidet
|
gitSchluessel: '',
|
};
|
|
const konfigurationsPfad = path.join(anwendungsDatenOrdner(), 'konfiguration.json');
|
|
/** Liest die Konfigurationsdatei (und legt sie beim ersten Start an). */
|
function leseOderErzeuge(): Einstellungen {
|
try {
|
if (fs.existsSync(konfigurationsPfad)) {
|
return normalisiere(JSON.parse(fs.readFileSync(konfigurationsPfad, 'utf8')) as Partial<Einstellungen>);
|
}
|
const standard = { ...STANDARD_EINSTELLUNGEN };
|
schreibeDatei(standard);
|
return standard;
|
} catch (fehler) {
|
console.warn(`konfiguration.json konnte nicht gelesen werden, Standardwerte greifen: ${String(fehler)}`);
|
return { ...STANDARD_EINSTELLUNGEN };
|
}
|
}
|
|
// Beim Laden des Moduls einlesen, damit auch die Datenbank-Schicht schon den
|
// konfigurierten Ordner sieht (sie wird beim Start direkt initialisiert).
|
let gelesene: Einstellungen = leseOderErzeuge();
|
|
/** Speichert geänderte Einstellungen. Der Datenordner wirkt erst nach einem Neustart. */
|
export function speichereEinstellungen(neue: Partial<Einstellungen>): Einstellungen {
|
gelesene = normalisiere({ ...gelesene, ...neue });
|
schreibeDatei(gelesene);
|
return gelesene;
|
}
|
|
export function aktuelleEinstellungen(): Einstellungen {
|
return gelesene;
|
}
|
|
export function konfigurationsDatei(): string {
|
return konfigurationsPfad;
|
}
|
|
/** Tatsächlich genutzter Datenordner — Umgebungsvariable vor Einstellung vor Standard. */
|
export function effektiverDatenOrdner(): string {
|
const ausUmgebung = process.env.DATEN_ORDNER?.trim();
|
if (ausUmgebung) {
|
return path.resolve(ausUmgebung);
|
}
|
if (gelesene.datenOrdner.trim()) {
|
return path.resolve(gelesene.datenOrdner.trim());
|
}
|
return path.join(anwendungsDatenOrdner(), 'data');
|
}
|
|
/** Tatsächlich genutzter Port — Umgebungsvariable vor Einstellung vor Standard. */
|
export function effektiverPort(): number {
|
const ausUmgebung = Number(process.env.PORT);
|
if (Number.isInteger(ausUmgebung) && ausUmgebung > 0) {
|
return ausUmgebung;
|
}
|
return gelesene.port;
|
}
|
|
function normalisiere(eingabe: Partial<Einstellungen>): Einstellungen {
|
const port = Number(eingabe.port);
|
return {
|
datenOrdner: typeof eingabe.datenOrdner === 'string' ? eingabe.datenOrdner.trim() : '',
|
port: Number.isInteger(port) && port > 0 && port < 65536 ? port : STANDARD_EINSTELLUNGEN.port,
|
// Nur was als SSH-Benutzername taugt — schützt zugleich vor Einschleusen in die Befehlszeile.
|
gitBenutzer: /^[A-Za-z0-9._-]*$/.test(String(eingabe.gitBenutzer ?? '').trim()) ? String(eingabe.gitBenutzer ?? '').trim() : '',
|
gitSchluessel: String(eingabe.gitSchluessel ?? '').trim(),
|
};
|
}
|
|
/**
|
* Baut den SSH-Aufruf für Git aus den Einstellungen. Leer, wenn nichts gepflegt ist —
|
* dann greift die SSH-Konfiguration des Dienstbenutzers wie bisher.
|
*/
|
export function gitSshBefehl(): string {
|
const teile = ['ssh'];
|
if (gelesene.gitBenutzer) {
|
teile.push('-o', `User=${gelesene.gitBenutzer}`);
|
}
|
if (gelesene.gitSchluessel) {
|
teile.push('-i', `"${gelesene.gitSchluessel.replace(/\\/g, '/')}"`);
|
}
|
return teile.length > 1 ? teile.join(' ') : '';
|
}
|
|
function schreibeDatei(einstellungen: Einstellungen): void {
|
fs.mkdirSync(path.dirname(konfigurationsPfad), { recursive: true });
|
fs.writeFileSync(konfigurationsPfad, `${JSON.stringify(einstellungen, null, 2)}\n`);
|
}
|