feat(auth): make password length configurable via env (min 5–30, max 30–128)
CI / check (push) Successful in 29s
CI / tests-imaging-browsers (push) Successful in 1m46s
CI / tests-integration (push) Successful in 1m47s
CI / tests-unit (push) Successful in 1m49s
CI / tests-quality (push) Successful in 44s
CI / tests-ui (push) Successful in 4m38s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 3m38s

Add PASSWORD_MIN_LENGTH / PASSWORD_MAX_LENGTH (validated in src/env.ts) and a
shared passwordPolicy helper. The policy drives the zod schemas in register,
password reset and the admin create-user dialog, plus the live requirement
checks and strength meter in the register form.

Locale messages now interpolate the configured minimum via {min} instead of
hard-coding 12.
This commit is contained in:
openhands committed 2026-10-18 19:20:38 +02:00
1 parent aef0939ee9
commit 9cf1eb615c
36 files changed
+227 -143

No files matched your search

+3
View File
@@ -7,6 +7,7 @@ import {
} from "@/components/auth/auth-landing";
import { RegisterForm } from "@/components/auth/register-form";
import { auth } from "@/lib/auth";
import { passwordPolicy } from "@/lib/auth/password-policy";
export async function generateMetadata(): Promise<Metadata> {
const t = await getTranslations("pages.register");
@@ -50,6 +51,8 @@ export default async function RegisterPage() {
hotelName={data.hotelName}
captcha={data.captcha}
nonce={data.nonce}
passwordMinLength={passwordPolicy.minLength}
passwordMaxLength={passwordPolicy.maxLength}
/>
}
/>
+7 -2
View File
@@ -3,6 +3,7 @@ import { getTranslations } from "next-intl/server";
import { resetPassword } from "@/actions/password-reset";
import Link from "@/components/link";
import { ContentCard } from "@/components/public/ui";
import { passwordPolicy } from "@/lib/auth/password-policy";
export async function generateMetadata(): Promise<Metadata> {
const t = await getTranslations("pages.reset");
@@ -41,8 +42,12 @@ export default async function ResetPage({
<input
name="password"
type="password"
placeholder={t("passwordPlaceholder")}
placeholder={t("passwordPlaceholder", {
min: passwordPolicy.minLength,
})}
autoComplete="new-password"
minLength={passwordPolicy.minLength}
maxLength={passwordPolicy.maxLength}
required
/>
<button type="submit" className="btn btn-primary">
@@ -58,7 +63,7 @@ export default async function ResetPage({
marginBottom: 0,
}}
>
{t(errorKey)}
{t(errorKey, { min: passwordPolicy.minLength })}
</p>
) : null}
<p