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.
61 lines
1.6 KiB
TypeScript
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}
|
|
/>
|
|
}
|
|
/>
|
|
);
|
|
}
|