feat(auth): Anmeldung per OIDC und Notfall-Admin mit TOTP (#004)
Sitzung, OIDC-Fluss und Rueckruf aus Laufzettel uebernommen und auf sshkv angepasst. Abweichungen mit Absicht: - Ohne passende sshkv-Gruppe gibt es keinen Zugang, auch keinen Lesezugriff: schon die Hostliste verraet, wer wohin darf. - Notfall-Admin nur mit TOTP (Freigabe Frage 5). Ein richtiges Passwort fuehrt beim ersten Mal nur zur Einrichtung. Jeder Code gilt einmal, fuenf Fehlversuche sperren 15 Minuten. - Kritische Rechte verlangen eine Bestaetigung, die hoechstens fuenf Minuten alt ist. Bei OIDC mit prompt=login, max_age=0 und Pruefung von auth_time, sonst zaehlte eine laufende SSO-Sitzung als Beweis. - Sitzungen laufen acht statt zwoelf Stunden. Die Seiten folgen, sobald das Design-System (#002) steht. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import type { Prisma } from "@/generated/prisma/client";
|
||||
import type { ProtokollErgebnis } from "@/generated/prisma/enums";
|
||||
import { prisma } from "@/lib/db";
|
||||
|
||||
/**
|
||||
* Schreibt einen Eintrag ins revisionssichere Protokoll (#005).
|
||||
*
|
||||
* Hash und Verkettung berechnet die Datenbank (Trigger), hier wird nur eingefuegt.
|
||||
* `details` laeuft vor dem Schreiben durch `schwaerzen()` (#006), damit kein Private Key
|
||||
* und kein Passwort hineingeraet – auch nicht aus Versehen ueber ein Fehlerobjekt.
|
||||
*/
|
||||
export type ProtokollEintrag = {
|
||||
readonly akteur: { readonly id: string; readonly name: string } | "System";
|
||||
readonly aktion: string;
|
||||
readonly ergebnis: ProtokollErgebnis;
|
||||
readonly hostName?: string | null;
|
||||
readonly zielbenutzer?: string | null;
|
||||
readonly fingerprint?: string | null;
|
||||
readonly diff?: string | null;
|
||||
readonly details?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export async function protokollieren(
|
||||
eintrag: ProtokollEintrag,
|
||||
client: Prisma.TransactionClient = prisma,
|
||||
): Promise<void> {
|
||||
const akteur = eintrag.akteur === "System" ? { id: null, name: "System" } : eintrag.akteur;
|
||||
await client.protokoll.create({
|
||||
data: {
|
||||
akteurId: akteur.id,
|
||||
akteurName: akteur.name,
|
||||
aktion: eintrag.aktion,
|
||||
ergebnis: eintrag.ergebnis,
|
||||
hostName: eintrag.hostName ?? null,
|
||||
zielbenutzer: eintrag.zielbenutzer ?? null,
|
||||
fingerprint: eintrag.fingerprint ?? null,
|
||||
diff: eintrag.diff ?? null,
|
||||
details: (eintrag.details as Prisma.InputJsonValue | undefined) ?? undefined,
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user