"use server"; import { verschluesseln } from "@/lib/geheimnisse"; import { BENUTZERNAME_MUSTER } from "@/lib/shell"; import { z } from "@/lib/validierung"; import { RechteFehler, rechtErforderlich } from "@/server/auth/sitzungspflicht"; import { protokollieren } from "@/server/services/protokoll"; import { vorgangEinreihen } from "@/server/vorgaenge/vorgaenge"; /** * Bootstrap starten (#010). Das Passwort verlaesst diese Funktion nur verschluesselt im Job * und steht nie in `Vorgang.eingabe`, im Protokoll oder in einem Log. */ export type BootstrapAntwort = { readonly vorgangId?: string; readonly fehler?: string }; const passwortSchema = z.object({ hostId: z.string().min(1).max(64), benutzer: z.string().regex(BENUTZERNAME_MUSTER, "Ungültiger Benutzername."), passwort: z.string().min(1).max(1024), }); export async function bootstrapPerPasswortAktion( eingabe: z.input, ): Promise { try { const { benutzer } = await rechtErforderlich("hostsVerwalten"); const daten = passwortSchema.safeParse(eingabe); if (!daten.success) return { fehler: daten.error.issues[0]?.message ?? "Eingaben unvollständig." }; const vorgangId = await vorgangEinreihen({ art: "BOOTSTRAP", angefordertVonId: benutzer.id, hostId: daten.data.hostId, eingabe: { modus: "passwort", benutzer: daten.data.benutzer }, geheim: verschluesseln(daten.data.passwort), }); await protokollieren({ akteur: { id: benutzer.id, name: benutzer.name }, aktion: "host.bootstrap.angefordert", ergebnis: "ERFOLG", details: { hostId: daten.data.hostId, anmeldung: daten.data.benutzer, art: "passwort" }, }); return { vorgangId }; } catch (fehler) { if (fehler instanceof RechteFehler) return { fehler: fehler.message }; throw fehler; } } export async function bootstrapPruefenAktion(hostId: string): Promise { try { const { benutzer } = await rechtErforderlich("hostsVerwalten"); const id = z.string().min(1).max(64).parse(hostId); return { vorgangId: await vorgangEinreihen({ art: "BOOTSTRAP", angefordertVonId: benutzer.id, hostId: id, eingabe: { modus: "pruefen" }, }), }; } catch (fehler) { if (fehler instanceof RechteFehler) return { fehler: fehler.message }; throw fehler; } }