Files
sshkeyvault/prisma/seed.ts
T
florian.wildeandClaude Opus 5.5 03c7c45576 feat(datenbank): Datenmodell mit Datenbankregeln und Seed (#003)
Alle Modelle fuer die fuenf Phasen in einer Migration, damit spaetere
Phasen keine Umbauten an Kerntabellen brauchen. Was auch an der
Service-Schicht vorbei gelten muss, steht als CHECK, partieller Index
oder Trigger in der Datenbank: Personen-Keys ohne Private Key, genau
ein Instanz-Deployment-Key, ein vertrauter Host-Key je Algorithmus,
shell-sichere Zielbenutzer und Pfade.

Das Protokoll ist append-only und per Hash-Kette verbunden; den Hash
berechnet ein Trigger, damit keine Zeile ohne Verkettung entstehen
kann (#005 baut darauf auf).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:12:06 +02:00

54 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";
import { PrismaClient } from "../src/generated/prisma/client";
import { PASSWORT_MINDESTLAENGE, passwortHashen } from "../src/lib/passwort-hash";
import { EINGEBAUTE_VORLAGEN } from "./vorlagen";
/**
* Grundausstattung (#003): Notfall-Admin und eingebaute Vorlagen.
*
* Laeuft bei jedem Start des migrate-Dienstes und ist deshalb idempotent. Ein bestehender
* Notfall-Admin wird nie angefasst – sonst setzte jeder Neustart ein in der Oberflaeche
* geaendertes Passwort zurueck.
*/
const prisma = new PrismaClient({ adapter: new PrismaPg({ connectionString: process.env["DATABASE_URL"] }) });
async function notfallAdmin(): Promise<void> {
const anmeldename = process.env["SSHKV_BREAKGLASS_USER"]?.trim() || "notfall";
const passwort = process.env["SSHKV_BREAKGLASS_PASSWORD"] ?? "";
if (await prisma.benutzer.findFirst({ where: { istNotfall: true } })) {
console.log("Notfall-Admin vorhanden – unverändert.");
return;
}
if (passwort.length < PASSWORT_MINDESTLAENGE) {
console.warn(
`Kein Notfall-Admin angelegt: SSHKV_BREAKGLASS_PASSWORD fehlt oder ist kürzer als ${PASSWORT_MINDESTLAENGE} Zeichen.`,
);
return;
}
await prisma.benutzer.create({
data: {
anmeldename,
name: "Notfall-Admin",
rolle: "ADMIN",
istNotfall: true,
passwortHash: await passwortHashen(passwort),
},
});
console.log(`Notfall-Admin „${anmeldename}“ angelegt. TOTP wird bei der ersten Anmeldung eingerichtet.`);
}
async function vorlagen(): Promise<void> {
for (const vorlage of EINGEBAUTE_VORLAGEN) {
await prisma.vorlage.upsert({ where: { name: vorlage.name }, create: vorlage, update: {} });
}
console.log(`${EINGEBAUTE_VORLAGEN.length} eingebaute Vorlagen geprüft.`);
}
try {
await notfallAdmin();
await vorlagen();
} finally {
await prisma.$disconnect();
}