"use client"; import { useActionState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { changePasswordSelf, redeemInvitation, redeemPasswordReset, requestEmailChange, requestPasswordReset, type EmailChangeState, type RedeemResetState, type RequestResetState, type SelfChangeState, } from "@/server/actions/auth-recovery"; /** * SEC2 — Formulare des Passwort-Self-Service. * * Alle Rückmeldungen sind bewusst generisch gehalten (Enumeration-Schutz): das * Formular zeigt genau den Text, den die Server-Action liefert, und ergänzt ihn * nicht um Hinweise auf die Existenz eines Kontos. */ const OK = "mt-4 rounded-lg bg-[rgba(57,192,127,0.14)] px-3 py-2 text-sm text-[var(--ok)]"; const ERR = "mt-4 rounded-lg bg-[rgba(255,107,107,0.16)] px-3 py-2 text-sm text-[var(--risk)]"; export function ForgotPasswordForm({ domain }: { domain: "tenant" | "platform" }) { const [state, action, pending] = useActionState( requestPasswordReset, { status: "idle" }, ); if (state.status === "done") { return (

{state.message}

); } return (
{state.status === "error" && (

{state.message}

)}
); } export function ResetPasswordForm({ token, domain, policyHint, loginPath, variant = "reset", }: { token: string; domain: "tenant" | "platform"; policyHint: string; loginPath: string; /** "invite" nutzt den Einladungs-Flow (Option C, WS3) statt des Reset-Flows. */ variant?: "reset" | "invite"; }) { const [state, action, pending] = useActionState( variant === "invite" ? redeemInvitation : redeemPasswordReset, { status: "idle" }, ); if (state.status === "done") { return (

{variant === "invite" ? "Ihr Konto ist eingerichtet. Sie können sich jetzt anmelden." : "Ihr Passwort wurde gesetzt. Alle bisherigen Sitzungen sind abgemeldet."}

{/* Bewusst kein Auto-Login: der Nutzer meldet sich neu an (SEC2 §6). */}
); } return (

{policyHint}

{state.status === "error" && (

{state.message}

)}
); } export function ChangePasswordSelfForm({ domain, policyHint, }: { domain: "tenant" | "platform"; policyHint: string; }) { const [state, action, pending] = useActionState(changePasswordSelf, { status: "idle", }); return (

{policyHint}

{state.status !== "idle" && (

{state.message}

)}
); } export function ChangeEmailForm({ domain, currentEmail, }: { domain: "tenant" | "platform"; currentEmail: string; }) { const [state, action, pending] = useActionState(requestEmailChange, { status: "idle", }); return (

Die Änderung wird erst wirksam, wenn Sie den Link in der neuen Adresse bestätigen.

{state.status !== "idle" && (

{state.message}

)}
); }