import { redirect } from "next/navigation"; import { PasswortAendernFormular } from "@/components/auth/PasswortAendernFormular"; import { CARD_CLASS } from "@/components/ui/Card"; import { currentUserId } from "@/lib/auth/session"; import { sql, withUser } from "@/lib/db"; // Diese Seite liegt **ausserhalb** der Gruppe (app), und das ist der Punkt. // // app/(app)/layout.tsx lässt nur durch, wer aktive HR-Person ist — und genau // das ist man nicht, solange ein Passwortwechsel aussteht: is_hr_user() liefert // dann false (Migration 20260908120000). Läge diese Seite unter (app), wäre sie // für die einzigen Menschen gesperrt, die sie brauchen. // // Angemeldet sein muss man trotzdem: darum kümmert sich proxy.ts, der jede // Adresse ausser /login und /api/auth hinter eine Sitzung stellt. Die Prüfung // unten ist die zweite Linie für den Fall, dass jemand den Matcher ändert. export const metadata = { title: "Passwort ändern" }; export default async function PasswortAendernPage() { const userId = await currentUserId(); if (!userId) redirect("/login"); // Erzwungen oder freiwillig — davon hängt nur die Beschriftung ab und ob es // einen Weg zurück gibt. // // Ob dieses Konto überhaupt ein Passwort hat, wird hier *nicht* gefragt: // app_passwoerter ist für die Anwendungsrolle unerreichbar (Policy // `using (false)`), und eine Auskunftsfunktion nur für diese Anzeige wäre // eine Funktion zu viel. Wer kein Passwort hat, bekommt beim Absenden die // Meldung aus app_passwort_aendern(). const erzwungen = await withUser(userId, async (tx) => { const ergebnis = await sql<{ wechseln: boolean }>`select app_muss_passwort_wechseln() as wechseln`.execute(tx); return ergebnis.rows[0]?.wechseln === true; }); return (

Passwort ändern

{erzwungen ? (

Ihr Zugang wurde mit einem gemeinsamen Startpasswort eingerichtet. Solange es gilt, bleiben alle Personaldaten verschlossen — bitte vergeben Sie jetzt ein eigenes.

) : (

Sie können hier jederzeit ein neues Passwort vergeben.

)}
); }