150 lines
7.6 KiB
TypeScript
150 lines
7.6 KiB
TypeScript
/**
|
||
* Lesbare Beschriftung der technischen Protokoll-Aktionen (#027).
|
||
*
|
||
* Das Protokoll speichert stabile Schluessel wie `authorized_keys.geschrieben`, damit sich
|
||
* Auswertungen (CSV, Syslog, SIEM) nicht an Oberflaechentexten aufhaengen. Die Ansicht
|
||
* uebersetzt sie hier. `tests/protokoll-aktionen.test.ts` sucht jede `aktion: "…"` im
|
||
* Quellcode und verlangt einen Eintrag – eine neue Aktion ohne Text faellt so sofort auf.
|
||
*
|
||
* `aendert`: Die Aktion veraendert etwas (Datei geschrieben, Schluessel erzeugt …) und wird bei
|
||
* Erfolg in --ok gezeigt. Lesende oder rein informative Aktionen (Anmeldung, Abruf, Export)
|
||
* bleiben neutral, damit das Grün die Stellen markiert, an denen sich etwas getan hat.
|
||
*/
|
||
|
||
export const AKTIONSGRUPPEN = {
|
||
anmeldung: "Anmeldung",
|
||
hostkey: "Host-Key",
|
||
ausrollen: "Ausrollen",
|
||
schluessel: "Schlüssel",
|
||
widerruf: "Widerruf/Rotation",
|
||
zielkonto: "Zielkonto",
|
||
abgleich: "Abgleich",
|
||
hosts: "Hosts",
|
||
stammdaten: "Personen und Vorlagen",
|
||
protokoll: "Protokoll",
|
||
benachrichtigung: "Benachrichtigung",
|
||
} as const;
|
||
|
||
export type Aktionsgruppe = keyof typeof AKTIONSGRUPPEN;
|
||
|
||
type Beschreibung = { readonly text: string; readonly gruppe: Aktionsgruppe; readonly aendert: boolean };
|
||
|
||
const a = (text: string, gruppe: Aktionsgruppe, aendert = true): Beschreibung => ({ text, gruppe, aendert });
|
||
|
||
export const AKTIONEN: Readonly<Record<string, Beschreibung>> = {
|
||
// Benachrichtigungen (#028)
|
||
"benachrichtigung.gesendet": a("Benachrichtigung gesendet", "benachrichtigung", false),
|
||
"benachrichtigung.fehlgeschlagen": a("Benachrichtigung fehlgeschlagen", "benachrichtigung", false),
|
||
"einstellungen.benachrichtigungen.geaendert": a("Benachrichtigungen geändert", "benachrichtigung"),
|
||
// Ereignisname im Webhook (#028); taucht als Text auf, wenn ein Host-Key-Alarm protokolliert wird.
|
||
"hostkey.geaendert": a("Host-Key geändert (Alarm)", "hostkey", false),
|
||
|
||
// Anmeldung und Bestaetigung (#004)
|
||
"anmeldung.oidc": a("Anmeldung (OIDC)", "anmeldung", false),
|
||
"anmeldung.oidc.erstmals": a("Erste Anmeldung (OIDC)", "anmeldung"),
|
||
"anmeldung.verweigert": a("Anmeldung verweigert", "anmeldung", false),
|
||
"anmeldung.notfall": a("Anmeldung Notfall-Admin", "anmeldung", false),
|
||
"anmeldung.notfall.fehlgeschlagen": a("Notfall-Anmeldung fehlgeschlagen", "anmeldung", false),
|
||
"anmeldung.notfall.gesperrt": a("Notfall-Anmeldung gesperrt", "anmeldung", false),
|
||
"anmeldung.notfall.totp_falsch": a("Notfall-Anmeldung: TOTP falsch", "anmeldung", false),
|
||
"bestaetigung.oidc": a("Anmeldung bestätigt (Re-Auth)", "anmeldung", false),
|
||
"notfall.totp_eingerichtet": a("TOTP für Notfall-Admin eingerichtet", "anmeldung"),
|
||
|
||
// Host-Keys (#009)
|
||
"hostkey.abgerufen": a("Host-Key abgerufen", "hostkey", false),
|
||
"hostkey.bestaetigt": a("Host-Key bestätigt", "hostkey"),
|
||
"hostkey.ersetzt": a("Host-Key ersetzt", "hostkey"),
|
||
"hostkey.abgelehnt": a("Host-Key abgelehnt", "hostkey"),
|
||
"hostkey.abweichung": a("Host-Key weicht ab – Verbindung abgebrochen", "hostkey", false),
|
||
|
||
// Ausrollen (#016, #017)
|
||
"authorized_keys.geschrieben": a("authorized_keys geschrieben", "ausrollen"),
|
||
"privatekey.ausgerollt": a("Private Key ausgerollt", "ausrollen"),
|
||
"verwendung.public.angelegt": a("Public Key zugewiesen", "ausrollen"),
|
||
"verwendung.public.entfernen": a("Public-Key-Zuweisung zum Entfernen vorgemerkt", "ausrollen"),
|
||
"verwendung.private.angelegt": a("Private Key zugewiesen", "ausrollen"),
|
||
"verwendung.private.entfernen": a("Private-Key-Zuweisung zum Entfernen vorgemerkt", "ausrollen"),
|
||
|
||
// Schluessel (#012, #013, #014)
|
||
"schluessel.erzeugt": a("Schlüssel erzeugt", "schluessel"),
|
||
"schluessel.importiert": a("Schlüssel importiert", "schluessel"),
|
||
"schluessel.uebernommen": a("Schlüssel vom Host übernommen", "schluessel"),
|
||
"schluessel.selbst_hinterlegt": a("Eigenen Public Key hinterlegt", "schluessel"),
|
||
"schluessel.selbst_entfernt": a("Eigenen Public Key entfernt", "schluessel"),
|
||
"schluessel.geaendert": a("Schlüssel geändert", "schluessel"),
|
||
"privatekey.angefordert": a("Private Key angefordert", "schluessel", false),
|
||
"privatekey.angezeigt": a("Private Key angezeigt", "schluessel", false),
|
||
"privatekey.heruntergeladen": a("Private Key heruntergeladen", "schluessel", false),
|
||
"privatekey.geloescht": a("Private Key gelöscht", "schluessel"),
|
||
"deploymentkey.erzeugt": a("Deployment-Key erzeugt", "schluessel"),
|
||
"deploymentkey.geprueft": a("Neuer Deployment-Key geprüft", "widerruf", false),
|
||
"deploymentkey.umgestellt": a("Deployment-Key umgestellt", "widerruf"),
|
||
"deploymentkey.abgeschlossen": a("Rotation des Deployment-Keys abgeschlossen", "widerruf"),
|
||
|
||
// Widerruf und Rotation (#023, #024)
|
||
"schluessel.widerruf.eingeleitet": a("Widerruf eingeleitet", "widerruf"),
|
||
"schluessel.widerrufen": a("Schlüssel widerrufen", "widerruf"),
|
||
"schluessel.rotiert": a("Schlüssel rotiert", "widerruf"),
|
||
"schluessel.rotation.uebernommen": a("Rotation: Zuweisungen übernommen", "widerruf"),
|
||
"schluessel.rotation.abgebrochen": a("Rotation abgebrochen", "widerruf"),
|
||
|
||
// Zielkonten (#018)
|
||
"zielkonto.angelegt": a("Zielkonto angelegt", "zielkonto"),
|
||
"zielkonto.geaendert": a("Zielkonto geändert", "zielkonto"),
|
||
"zielkonto.entfernt": a("Zielkonto entfernt", "zielkonto"),
|
||
|
||
// Abgleich und Uebernahme (#021, #022)
|
||
abgleich: a("Abgleich durchgeführt", "abgleich", false),
|
||
"uebernahme.verwalten": a("Fremden Key übernommen und verwaltet", "abgleich"),
|
||
"uebernahme.bekannt": a("Fremden Key als bekannt aufgenommen", "abgleich"),
|
||
|
||
// Hosts, Gruppen, Kunden (#008, #010)
|
||
"host.angelegt": a("Host angelegt", "hosts"),
|
||
"host.geaendert": a("Host geändert", "hosts"),
|
||
"host.archiviert": a("Host archiviert", "hosts"),
|
||
"host.bootstrap.angefordert": a("Einrichtung angefordert", "hosts", false),
|
||
"host.bootstrap": a("Host eingerichtet (Bootstrap)", "hosts"),
|
||
"host.bootstrap.geprueft": a("Einrichtung geprüft", "hosts"),
|
||
"hostgruppe.angelegt": a("Hostgruppe angelegt", "hosts"),
|
||
"hostgruppe.geaendert": a("Hostgruppe geändert", "hosts"),
|
||
"kunde.angelegt": a("Kunde angelegt", "hosts"),
|
||
verbindungstest: a("Verbindung geprüft", "hosts", false),
|
||
|
||
// Personen und Vorlagen (#013, #019)
|
||
"person.angelegt": a("Person angelegt", "stammdaten"),
|
||
"person.geaendert": a("Person geändert", "stammdaten"),
|
||
"person.archiviert": a("Person archiviert", "stammdaten"),
|
||
"person.verknuepft": a("Person mit Konto verknüpft", "stammdaten"),
|
||
"vorlage.angelegt": a("Vorlage angelegt", "stammdaten"),
|
||
"vorlage.geaendert": a("Vorlage geändert", "stammdaten"),
|
||
"vorlage.archiviert": a("Vorlage archiviert", "stammdaten"),
|
||
|
||
// Protokoll selbst (#027)
|
||
"protokoll.exportiert": a("Protokoll exportiert (CSV)", "protokoll", false),
|
||
"protokoll.kette_beschaedigt": a("Hash-Kette beschädigt gefunden", "protokoll", false),
|
||
};
|
||
|
||
/** Text zur Aktion; unbekannte (etwa aus aelteren Versionen) bleiben technisch lesbar. */
|
||
export function aktionText(aktion: string): string {
|
||
return AKTIONEN[aktion]?.text ?? aktion;
|
||
}
|
||
|
||
/** Alle bekannten Aktionen einer Gruppe – Grundlage fuer den Filter `aktion IN (…)`. */
|
||
export function aktionenDerGruppe(gruppe: Aktionsgruppe): string[] {
|
||
return Object.entries(AKTIONEN)
|
||
.filter(([, b]) => b.gruppe === gruppe)
|
||
.map(([aktion]) => aktion);
|
||
}
|
||
|
||
export type AktionsTon = "ok" | "gefahr" | "neutral";
|
||
|
||
/** Farbe in der Liste: Fehlschlag und Verweigerung immer --danger, Aenderungen --ok. */
|
||
export function aktionTon(aktion: string, ergebnis: "ERFOLG" | "FEHLER" | "VERWEIGERT"): AktionsTon {
|
||
if (ergebnis !== "ERFOLG") return "gefahr";
|
||
return AKTIONEN[aktion]?.aendert ? "ok" : "neutral";
|
||
}
|
||
|
||
export function istAktionsgruppe(wert: string): wert is Aktionsgruppe {
|
||
return Object.hasOwn(AKTIONSGRUPPEN, wert);
|
||
}
|