47 lines
2.3 KiB
TypeScript
47 lines
2.3 KiB
TypeScript
// Die Passwortregeln — noch einmal, für die Oberfläche.
|
|
//
|
|
// Verbindlich ist app_passwort_regeln() in der Datenbank
|
|
// (20260908120000). Hier stehen dieselben Regeln ein zweites Mal, damit die
|
|
// Maske sie beim Tippen anzeigen kann statt erst nach dem Absenden. Dieselbe
|
|
// Doppelung wie in lib/history.ts, aus demselben Grund und mit derselben
|
|
// Rangfolge: läuft eine Seite der anderen davon, gewinnt die Datenbank — sie
|
|
// weist ab, und die Meldung von dort wird angezeigt.
|
|
|
|
/** Was in der Maske als Hinweis steht. Reihenfolge wie in der SQL-Funktion. */
|
|
export const PASSWORT_REGELN = [
|
|
"mindestens 12 Zeichen",
|
|
"mindestens ein Grossbuchstabe",
|
|
"mindestens ein Kleinbuchstabe",
|
|
"mindestens eine Ziffer",
|
|
] as const;
|
|
|
|
/**
|
|
* Liefert die Beanstandung im Klartext oder null.
|
|
*
|
|
* Wortgleich mit app_passwort_regeln(). Ein Unterschied bleibt und ist
|
|
* unvermeidbar: `length()` in PostgreSQL zählt Zeichen, `String.length` in
|
|
* JavaScript zählt UTF-16-Einheiten. Bei einem Emoji im Passwort weichen die
|
|
* beiden um eins ab. Das betrifft nur die Vorabanzeige — abgewiesen oder
|
|
* angenommen wird in der Datenbank.
|
|
*/
|
|
export function passwortBeanstandung(passwort: string): string | null {
|
|
if (passwort.length < 12) return "Das Passwort muss mindestens 12 Zeichen lang sein.";
|
|
if (passwort.length > 72) return "Das Passwort darf höchstens 72 Zeichen lang sein.";
|
|
if (!/\p{Lu}/u.test(passwort)) return "Das Passwort muss mindestens einen Grossbuchstaben enthalten.";
|
|
if (!/\p{Ll}/u.test(passwort)) return "Das Passwort muss mindestens einen Kleinbuchstaben enthalten.";
|
|
if (!/\p{Nd}/u.test(passwort)) return "Das Passwort muss mindestens eine Ziffer enthalten.";
|
|
return null;
|
|
}
|
|
|
|
// Das gemeinsame Initialpasswort steht **nicht** in dieser Datei.
|
|
//
|
|
// Sie wird von den Anmelde- und Wechselformularen eingebunden, und die laufen
|
|
// im Browser. Jede Konstante hier landete damit im ausgelieferten Bündel — und
|
|
// das Initialpasswort wäre für jede Besucherin der offenen Anmeldeseite
|
|
// lesbar, ohne dass sie auch nur eine E-Mail-Adresse kennen müsste. Heute
|
|
// braucht ein Fremder beides.
|
|
//
|
|
// Es liegt deshalb in actions/benutzer.ts, also in einem Modul mit
|
|
// "use server", das nie in den Browser gelangt. Dort wird es auch nur
|
|
// gebraucht: beim Anlegen und beim Zurücksetzen.
|