|
|
@@ -0,0 +1,70 @@
|
|
|
+import {
|
|
|
+ PASSWORD_POLICY,
|
|
|
+ PASSWORD_POLICY_REASON,
|
|
|
+} from "@/lib/auth/passwordPolicy";
|
|
|
+
|
|
|
+const ORDERED_REASONS = [
|
|
|
+ PASSWORD_POLICY_REASON.MIN_LENGTH,
|
|
|
+ PASSWORD_POLICY_REASON.MISSING_LETTER,
|
|
|
+ PASSWORD_POLICY_REASON.MISSING_NUMBER,
|
|
|
+ PASSWORD_POLICY_REASON.SAME_AS_CURRENT,
|
|
|
+];
|
|
|
+
|
|
|
+function uniqueStrings(arr) {
|
|
|
+ const list = Array.isArray(arr) ? arr.map(String) : [];
|
|
|
+ return Array.from(new Set(list));
|
|
|
+}
|
|
|
+
|
|
|
+function labelForReasonDe(reason, { minLength } = {}) {
|
|
|
+ const min =
|
|
|
+ Number.isInteger(minLength) && minLength > 0
|
|
|
+ ? minLength
|
|
|
+ : PASSWORD_POLICY.minLength;
|
|
|
+
|
|
|
+ if (reason === PASSWORD_POLICY_REASON.MIN_LENGTH) {
|
|
|
+ return `Mindestens ${min} Zeichen`;
|
|
|
+ }
|
|
|
+ if (reason === PASSWORD_POLICY_REASON.MISSING_LETTER) {
|
|
|
+ return "Mindestens 1 Buchstabe (A–Z)";
|
|
|
+ }
|
|
|
+ if (reason === PASSWORD_POLICY_REASON.MISSING_NUMBER) {
|
|
|
+ return "Mindestens 1 Zahl (0–9)";
|
|
|
+ }
|
|
|
+ if (reason === PASSWORD_POLICY_REASON.SAME_AS_CURRENT) {
|
|
|
+ return "Neues Passwort darf nicht identisch sein";
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+export function getPasswordPolicyHintLinesDe(policy = PASSWORD_POLICY) {
|
|
|
+ const min =
|
|
|
+ Number.isInteger(policy?.minLength) && policy.minLength > 0
|
|
|
+ ? policy.minLength
|
|
|
+ : PASSWORD_POLICY.minLength;
|
|
|
+
|
|
|
+ const lines = [`Mindestens ${min} Zeichen`];
|
|
|
+
|
|
|
+ if (policy?.requireLetter) lines.push("Mindestens 1 Buchstabe (A–Z)");
|
|
|
+ if (policy?.requireNumber) lines.push("Mindestens 1 Zahl (0–9)");
|
|
|
+ if (policy?.disallowSameAsCurrent)
|
|
|
+ lines.push("Darf nicht identisch zum aktuellen Passwort sein");
|
|
|
+
|
|
|
+ return lines;
|
|
|
+}
|
|
|
+
|
|
|
+export function reasonsToHintLinesDe({ reasons, minLength } = {}) {
|
|
|
+ const set = new Set(uniqueStrings(reasons));
|
|
|
+ const ordered = ORDERED_REASONS.filter((r) => set.has(r));
|
|
|
+
|
|
|
+ const lines = ordered
|
|
|
+ .map((r) => labelForReasonDe(r, { minLength }))
|
|
|
+ .filter(Boolean);
|
|
|
+
|
|
|
+ return lines;
|
|
|
+}
|
|
|
+
|
|
|
+export function buildWeakPasswordMessageDe({ reasons, minLength } = {}) {
|
|
|
+ const lines = reasonsToHintLinesDe({ reasons, minLength });
|
|
|
+ if (lines.length === 0) return "Bitte wählen Sie ein stärkeres Passwort.";
|
|
|
+ return lines.join(" • ");
|
|
|
+}
|