Files
EpicNext-Cms/src/app/(site)/register/page.tsx
T
openhands 9cf1eb615c
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
feat(auth): make password length configurable via env (min 5–30, max 30–128)
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.
2026-10-18 19:20:38 +02:00

61 lines
1.6 KiB
TypeScript

import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { getTranslations } from "next-intl/server";
import {
AuthLandingView,
loadAuthLanding,
} 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");
const title = t("title");
const description = t("subtitle");
return {
title,
description,
openGraph: { title, description, type: "website" },
};
}
export default async function RegisterPage() {
const t = await getTranslations("pages.register");
// An account already exists in this browser — there is nothing to sign up.
const session = await auth();
if (session?.user?.id) redirect("/me");
const data = await loadAuthLanding();
return (
<AuthLandingView
data={data}
copy={{
title: t("title"),
subtitle: t("subtitle"),
promoTitle: (
<>
{t("title")} —{" "}
<span className="gradient-text">{data.hotelName}</span>
</>
),
promoSubtitle: t("subtitle"),
usersOnlineLabel: t("usersOnline", { count: data.online }),
whoIsOnlineLabel: t("whoIsOnline"),
newestCitizensLabel: t("newestCitizens"),
}}
form={
<RegisterForm
hotelName={data.hotelName}
captcha={data.captcha}
nonce={data.nonce}
passwordMinLength={passwordPolicy.minLength}
passwordMaxLength={passwordPolicy.maxLength}
/>
}
/>
);
}