Files
alpenwerk-hr/actions/passwort.ts
Andrei Laas c6cff9656e
Some checks failed
CI / Lint, Typen, Tests, Build (push) Failing after 5m27s
CI / Migrationen auf leerer Datenbank (push) Successful in 10m3s
Passwort-Anmeldung: Provider, Formulare, drei Zustaende der Shell
2026-09-08 16:51:14 +02:00

62 lines
2.3 KiB
TypeScript

"use server";
import { redirect } from "next/navigation";
import { currentUserId } from "@/lib/auth/session";
import { runMutation } from "@/lib/db/rpc";
// Das eigene Passwort wechseln.
//
// Getrennt von actions/auth.ts, weil es etwas anderes ist: dort geht es um das
// Herstellen einer Sitzung, hier um eine Änderung an den eigenen Daten. Und
// getrennt von actions/benutzer.ts (Benutzerverwaltung), weil diese Aktion die
// einzige ist, die **ohne** HR-Rechte funktionieren muss.
export type WechselZustand = { fehler: string | null };
/**
* Wechselt das Passwort der angemeldeten Person.
*
* Kein `revalidatePath`: der Weg danach ist eine Weiterleitung durch die
* Komponente, und es gibt keine zwischengespeicherte Seite, die den alten Stand
* zeigen könnte.
*
* Die Meldungen kommen aus app_passwort_aendern() und sind für die Oberfläche
* geschrieben („Das bisherige Passwort stimmt nicht.") — sie werden
* durchgereicht wie bei jeder anderen Mutation.
*/
export async function passwortAendern(
_zustand: WechselZustand,
formular: FormData
): Promise<WechselZustand> {
const altes = String(formular.get("altes_passwort") ?? "");
const neues = String(formular.get("neues_passwort") ?? "");
const wiederholung = String(formular.get("wiederholung") ?? "");
if (!altes || !neues) {
return { fehler: "Bitte das bisherige und das neue Passwort eingeben." };
}
// Diese eine Prüfung gehört hierher und nicht in die Datenbank: die
// Wiederholung ist ein Bedienelement gegen Vertippen, kein Datum. Die
// Datenbank sieht sie nie und soll sie auch nicht sehen.
if (neues !== wiederholung) {
return { fehler: "Die beiden neuen Passwörter stimmen nicht überein." };
}
const ergebnis = await runMutation(await currentUserId(), "app_passwort_aendern", {
altes_passwort: altes,
neues_passwort: neues,
});
if (!ergebnis.success) {
return { fehler: ergebnis.error ?? "Unbekannter Fehler." };
}
// Ab hier ist der Wechsel erledigt, is_hr_user() liefert wieder true und die
// Anwendung ist offen. Die Weiterleitung steht in der Aktion und nicht in der
// Komponente: `redirect()` wirft, die Aktion kehrt also nicht zurück, und es
// gibt keinen Zwischenzustand, in dem das Formular noch einmal abgeschickt
// werden könnte.
redirect("/");
}