Bisher ließ sich der Instanz-Key nur von Hand auf jedem Host tauschen. Die Rotation läuft jetzt in fünf Schritten: Nachfolger erzeugen, per Dry-Run neben den alten verteilen, Anmeldung je Host prüfen, umstellen, alten Key aus allen Blöcken entfernen und seinen Private Key verwerfen. Der Nachfolger steht während der Rotation in Block und Pflichtliste, damit kein Host ohne funktionierenden Key dasteht. Umgestellt wird nur nach erfolgreicher Prüfung oder bewusstem Übergehen eines Hosts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { z } from "@/lib/validierung";
|
|
import { akteurVon } from "@/server/actions/formular";
|
|
import type { VorgangsAntwort } from "@/server/actions/verwendungen";
|
|
import { BestaetigungFehler, RechteFehler, rechtErforderlich } from "@/server/auth/sitzungspflicht";
|
|
import { DeploymentKeyFehler, rotationsSchrittAnfordern, umstellen } from "@/server/services/deploymentkey";
|
|
|
|
/** Rotation des Deployment-Keys (#031). Nur Admins mit frischer Bestaetigung. */
|
|
|
|
function alsAntwort(fehler: unknown): { fehler: string } {
|
|
if (
|
|
fehler instanceof DeploymentKeyFehler ||
|
|
fehler instanceof RechteFehler ||
|
|
fehler instanceof BestaetigungFehler
|
|
) {
|
|
return { fehler: fehler.message };
|
|
}
|
|
throw fehler;
|
|
}
|
|
|
|
export async function rotationsSchrittAktion(
|
|
schritt: "erzeugen" | "pruefen" | "abschliessen",
|
|
): Promise<VorgangsAntwort> {
|
|
try {
|
|
const { benutzer } = await rechtErforderlich("deploymentKeyVerwalten");
|
|
const geprueft = z.enum(["erzeugen", "pruefen", "abschliessen"]).parse(schritt);
|
|
return { vorgangId: await rotationsSchrittAnfordern(geprueft, akteurVon(benutzer)) };
|
|
} catch (fehler) {
|
|
return alsAntwort(fehler);
|
|
}
|
|
}
|
|
|
|
export async function umstellenAktion(uebergehen: readonly string[]): Promise<{ fehler?: string }> {
|
|
try {
|
|
const { benutzer } = await rechtErforderlich("deploymentKeyVerwalten");
|
|
await umstellen(akteurVon(benutzer), z.array(z.string().min(1).max(64)).max(500).parse(uebergehen));
|
|
revalidatePath("/deployment-key");
|
|
return {};
|
|
} catch (fehler) {
|
|
return alsAntwort(fehler);
|
|
}
|
|
}
|