Vier Bereiche unter Einstellungen -> System: Adresse und Agent, Kaufmaennisches, Sicherheit sowie Firma und Darstellung. Alles liegt als eine JSON-Zeile in der Tabelle Einstellung; fehlende Felder bekommen ihren Vorgabewert, eine kaputte Zeile legt den Betrieb nicht lahm. Die Werte wirken auch wirklich: Die Dashboard-Adresse und der Melderhythmus landen im ausgelieferten Einzeiler und im systemd-Timer (live geprueft), der Steuersatz in neuen Rechnungspositionen, die Sitzungsdauer im Token, die Firmenangaben im Kopf der PDF-Dateien. Nebenbei geschlossen: die OIDC-Luecke aus #024. Erlaubte Domaenen und ein Schalter gegen automatisch angelegte Konten. Dazu raeumt der Worker nachts nach den eingestellten Fristen auf - der juengste Report je Host bleibt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
43 lines
1.7 KiB
TypeScript
43 lines
1.7 KiB
TypeScript
import { readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { einstellungen, onCalendar } from "@/server/einstellungen";
|
|
import { AGENT_VERSION } from "./http";
|
|
|
|
/**
|
|
* Liefert die Agent-Skripte aus dem Verzeichnis `agent/` aus und setzt dabei Dashboard-Adresse,
|
|
* Agent-Version und die Vorgaben aus *Einstellungen → System* ein (Melderhythmus, Streuung,
|
|
* Selbstaktualisierung).
|
|
*/
|
|
export async function skriptLaden(datei: "install.sh" | "proxledger-agent.sh", basisUrl: string) {
|
|
const pfad = path.join(process.cwd(), "agent", datei);
|
|
const [inhalt, werte] = await Promise.all([readFile(pfad, "utf8"), einstellungen()]);
|
|
|
|
return inhalt
|
|
.replaceAll("@@DASHBOARD_URL@@", basisUrl.replace(/\/$/, ""))
|
|
.replaceAll("@@AGENT_VERSION@@", AGENT_VERSION)
|
|
.replaceAll("@@TIMER_ONCALENDAR@@", onCalendar(werte.agentRhythmus))
|
|
.replaceAll("@@TIMER_STREUUNG@@", `${werte.agentStreuungStunden}h`)
|
|
.replaceAll("@@AUTO_UPDATE@@", werte.agentAutoUpdate ? "yes" : "no");
|
|
}
|
|
|
|
/**
|
|
* Bevorzugt die im Dashboard eingetragene Adresse, dann `APP_URL`, sonst die Herkunft der Anfrage.
|
|
* Die Reihenfolge ist wichtig: Hinter einem Reverse Proxy stimmt die Herkunft oft nicht.
|
|
*/
|
|
export async function basisUrl(request: Request): Promise<string> {
|
|
const werte = await einstellungen();
|
|
if (werte.dashboardUrl) return werte.dashboardUrl;
|
|
if (process.env.APP_URL) return process.env.APP_URL;
|
|
return new URL(request.url).origin;
|
|
}
|
|
|
|
export function skriptAntwort(inhalt: string, dateiname: string) {
|
|
return new Response(inhalt, {
|
|
headers: {
|
|
"Content-Type": "text/x-shellscript; charset=utf-8",
|
|
"Content-Disposition": `inline; filename="${dateiname}"`,
|
|
"Cache-Control": "no-store",
|
|
},
|
|
});
|
|
}
|