refactor: replace strong password hook with mild password implementation and update related components
This commit is contained in:
parent
e0353bb6f9
commit
d9fdfabf00
11 changed files with 243 additions and 158 deletions
|
|
@ -12,7 +12,7 @@ import {
|
|||
} from "~/components/custom_ui/form";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import Input from "~/components/ui/input";
|
||||
import { useStrongPassword } from "~/hooks/useStrongPassword";
|
||||
import { useMildPassword } from "~/hooks/usePassword";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
|
|
@ -25,8 +25,9 @@ export const ChangePasswordForm = () => {
|
|||
passwordRefine,
|
||||
getStrengthTxt,
|
||||
strengthScore,
|
||||
maxStrength,
|
||||
toggleVisibility,
|
||||
} = useStrongPassword();
|
||||
} = useMildPassword();
|
||||
const router = useRouter();
|
||||
|
||||
const ChangePasswordFormSchema = z
|
||||
|
|
@ -161,7 +162,7 @@ export const ChangePasswordForm = () => {
|
|||
</button>
|
||||
<div
|
||||
aria-label="Password strength"
|
||||
aria-valuemax={4}
|
||||
aria-valuemax={maxStrength}
|
||||
aria-valuemin={0}
|
||||
aria-valuenow={strengthScore}
|
||||
className="mt-3 mb-4 h-1 w-full overflow-hidden rounded-full bg-border"
|
||||
|
|
@ -172,7 +173,7 @@ export const ChangePasswordForm = () => {
|
|||
"h-full transition-all duration-500 ease-out",
|
||||
getStrengthColor(strengthScore),
|
||||
)}
|
||||
style={{ width: `${(strengthScore / 4) * 100}%` }}
|
||||
style={{ width: `${(strengthScore / maxStrength) * 100}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
import { Button } from "~/components/ui/button";
|
||||
import Input from "~/components/ui/input";
|
||||
import { PhoneInput } from "~/components/ui/phone-input";
|
||||
import { useStrongPassword } from "~/hooks/useStrongPassword";
|
||||
import { useMildPassword } from "~/hooks/usePassword";
|
||||
import { generatePassword } from "~/lib/basicPwGenerator";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
|
|
@ -31,7 +31,8 @@ export const FormNewUser = ({
|
|||
getStrengthTxt,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
} = useStrongPassword();
|
||||
maxStrength,
|
||||
} = useMildPassword();
|
||||
|
||||
const NewUserSchema = z
|
||||
.object({
|
||||
|
|
@ -206,7 +207,7 @@ export const FormNewUser = ({
|
|||
</button>
|
||||
<div
|
||||
aria-label="Password strength"
|
||||
aria-valuemax={4}
|
||||
aria-valuemax={maxStrength}
|
||||
aria-valuemin={0}
|
||||
aria-valuenow={strengthScore}
|
||||
className="mt-3 mb-4 h-1 w-full overflow-hidden rounded-full bg-border"
|
||||
|
|
@ -217,7 +218,9 @@ export const FormNewUser = ({
|
|||
"h-full transition-all duration-500 ease-out",
|
||||
getStrengthColor(strengthScore),
|
||||
)}
|
||||
style={{ width: `${(strengthScore / 4) * 100}%` }}
|
||||
style={{
|
||||
width: `${(strengthScore / maxStrength) * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
import Input from "~/components/ui/input";
|
||||
import { Label } from "~/components/ui/label";
|
||||
import { Separator } from "~/components/ui/separator";
|
||||
import { useStrongPassword } from "~/hooks/useStrongPassword";
|
||||
import { useMildPassword } from "~/hooks/usePassword";
|
||||
import { generatePassword } from "~/lib/basicPwGenerator";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
|
|
@ -38,7 +38,8 @@ export const OverridePasswordForm = ({ id }: { id: UsersId }) => {
|
|||
getStrengthTxt,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
} = useStrongPassword();
|
||||
maxStrength,
|
||||
} = useMildPassword();
|
||||
|
||||
const OverridePasswordFormSchema = z
|
||||
.object({
|
||||
|
|
@ -203,7 +204,7 @@ export const OverridePasswordForm = ({ id }: { id: UsersId }) => {
|
|||
</button>
|
||||
<div
|
||||
aria-label="Password strength"
|
||||
aria-valuemax={4}
|
||||
aria-valuemax={maxStrength}
|
||||
aria-valuemin={0}
|
||||
aria-valuenow={strengthScore}
|
||||
className="mt-3 mb-4 h-1 w-full overflow-hidden rounded-full bg-border"
|
||||
|
|
@ -214,7 +215,9 @@ export const OverridePasswordForm = ({ id }: { id: UsersId }) => {
|
|||
"h-full transition-all duration-500 ease-out",
|
||||
getStrengthColor(strengthScore),
|
||||
)}
|
||||
style={{ width: `${(strengthScore / 4) * 100}%` }}
|
||||
style={{
|
||||
width: `${(strengthScore / maxStrength) * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { Eye, EyeOff } from "lucide-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { z } from "zod/v4";
|
||||
import {
|
||||
|
|
@ -12,6 +11,7 @@ import {
|
|||
FormMessage,
|
||||
} from "~/components/custom_ui/form";
|
||||
import Input from "~/components/ui/input";
|
||||
import { useMildPassword } from "~/hooks/usePassword";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
|
|
@ -20,38 +20,16 @@ import { api } from "~/utils/api";
|
|||
export const FormRstPwFromToken = (props: { token: string }) => {
|
||||
const { locale, t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [strengthScore, setStrengthScore] = useState(0);
|
||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||
const toggleVisibility = () => setIsVisible((prevState) => !prevState);
|
||||
|
||||
const checkStrength = (pass: string) => {
|
||||
const requirements = [
|
||||
{ regex: /.{8,}/, text: t.auth.signup.pw.lenght },
|
||||
{ regex: /[0-9]/, text: t.auth.signup.pw.number },
|
||||
{ regex: /[a-z]/, text: t.auth.signup.pw.lowercase },
|
||||
{ regex: /[A-Z]/, text: t.auth.signup.pw.uppercase },
|
||||
];
|
||||
|
||||
return requirements.map((req) => ({
|
||||
met: req.regex.test(pass),
|
||||
text: req.text,
|
||||
}));
|
||||
};
|
||||
|
||||
const getStrengthColor = (score: number) => {
|
||||
if (score === 0) return "bg-border";
|
||||
if (score <= 1) return "bg-red-500";
|
||||
if (score <= 2) return "bg-orange-500";
|
||||
if (score === 3) return "bg-amber-500";
|
||||
return "bg-emerald-500";
|
||||
};
|
||||
const getStrengthTxt = (score: number) => {
|
||||
if (score === 0) return "text-border";
|
||||
if (score <= 1) return "text-red-500";
|
||||
if (score <= 2) return "text-orange-500";
|
||||
if (score === 3) return "text-amber-500";
|
||||
return "text-emerald-500";
|
||||
};
|
||||
const {
|
||||
isVisible,
|
||||
getStrengthColor,
|
||||
passwordRefine,
|
||||
getStrengthTxt,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
maxStrength,
|
||||
} = useMildPassword();
|
||||
|
||||
const ResetFormSchema = z
|
||||
.object({
|
||||
|
|
@ -59,21 +37,11 @@ export const FormRstPwFromToken = (props: { token: string }) => {
|
|||
repeat_password: z.string(),
|
||||
})
|
||||
.superRefine(({ password, repeat_password }, refinementContext) => {
|
||||
const complexity = checkStrength(password);
|
||||
|
||||
if (complexity.filter((req) => req.met).length !== complexity.length) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: complexity
|
||||
.filter((req) => !req.met)
|
||||
.map((req) => req.text)
|
||||
.join("\n"),
|
||||
path: ["password"],
|
||||
});
|
||||
}
|
||||
setStrengthScore(complexity.filter((req) => req.met).length);
|
||||
|
||||
passwordRefine({
|
||||
password,
|
||||
path: "password",
|
||||
refinementContext,
|
||||
});
|
||||
if (password !== repeat_password) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
|
|
@ -164,7 +132,7 @@ export const FormRstPwFromToken = (props: { token: string }) => {
|
|||
</button>
|
||||
<div
|
||||
aria-label="Password strength"
|
||||
aria-valuemax={4}
|
||||
aria-valuemax={maxStrength}
|
||||
aria-valuemin={0}
|
||||
aria-valuenow={strengthScore}
|
||||
className="mt-3 mb-4 h-1 w-full overflow-hidden rounded-full bg-border"
|
||||
|
|
@ -175,7 +143,9 @@ export const FormRstPwFromToken = (props: { token: string }) => {
|
|||
"h-full transition-all duration-500 ease-out",
|
||||
getStrengthColor(strengthScore),
|
||||
)}
|
||||
style={{ width: `${(strengthScore / 4) * 100}%` }}
|
||||
style={{
|
||||
width: `${(strengthScore / maxStrength) * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
190
apps/infoalloggi/src/hooks/usePassword.ts
Normal file
190
apps/infoalloggi/src/hooks/usePassword.ts
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
import { useState } from "react";
|
||||
import { type RefinementCtx, z } from "zod/v4";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
|
||||
export const zStrongPassword = z.string().superRefine((password, ctx) => {
|
||||
const test = [/.{8,}/, /[0-9]/, /[a-z]/, /[A-Z]/].every((regex) =>
|
||||
regex.test(password),
|
||||
);
|
||||
if (!test) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message:
|
||||
"La password deve contenere almeno 8 caratteri, un numero, una lettera minuscola e una maiuscola.",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
type PasswordManager = {
|
||||
getStrengthColor: (score: number) => string;
|
||||
getStrengthTxt: (score: number) => string;
|
||||
isVisible: boolean;
|
||||
passwordRefine: ({
|
||||
password,
|
||||
refinementContext,
|
||||
path,
|
||||
}: {
|
||||
password: string;
|
||||
refinementContext: RefinementCtx;
|
||||
path: string;
|
||||
}) => void;
|
||||
strengthScore: number;
|
||||
toggleVisibility: () => void;
|
||||
maxStrength: number;
|
||||
};
|
||||
|
||||
export const useStrongPassword = (): PasswordManager => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||
const [strengthScore, setStrengthScore] = useState(0);
|
||||
|
||||
const checkStrength = (pass: string) => {
|
||||
const requirements = [
|
||||
{ regex: /.{8,}/, text: t.auth.signup.pw.lenght8 },
|
||||
{ regex: /[0-9]/, text: t.auth.signup.pw.number },
|
||||
{ regex: /[a-z]/, text: t.auth.signup.pw.lowercase },
|
||||
{ regex: /[A-Z]/, text: t.auth.signup.pw.uppercase },
|
||||
];
|
||||
|
||||
return requirements.map((req) => ({
|
||||
met: req.regex.test(pass),
|
||||
text: req.text,
|
||||
}));
|
||||
};
|
||||
|
||||
const getStrengthColor = (score: number) => {
|
||||
if (score === 0) return "bg-border";
|
||||
if (score <= 1) return "bg-red-500";
|
||||
if (score <= 2) return "bg-orange-500";
|
||||
if (score === 3) return "bg-amber-500";
|
||||
return "bg-emerald-500";
|
||||
};
|
||||
const getStrengthTxt = (score: number) => {
|
||||
if (score === 0) return "text-border";
|
||||
if (score <= 1) return "text-red-500";
|
||||
if (score <= 2) return "text-orange-500";
|
||||
if (score === 3) return "text-amber-500";
|
||||
return "text-emerald-500";
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible((prevState) => !prevState);
|
||||
|
||||
const passwordRefine = ({
|
||||
password,
|
||||
refinementContext,
|
||||
path,
|
||||
}: {
|
||||
password: string;
|
||||
refinementContext: RefinementCtx;
|
||||
path: string;
|
||||
}) => {
|
||||
const complexity = checkStrength(password);
|
||||
|
||||
if (complexity.filter((req) => req.met).length !== complexity.length) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: complexity
|
||||
.filter((req) => !req.met)
|
||||
.map((req) => req.text)
|
||||
.join("\n"),
|
||||
path: [path],
|
||||
});
|
||||
}
|
||||
setStrengthScore(complexity.filter((req) => req.met).length);
|
||||
};
|
||||
|
||||
return {
|
||||
getStrengthColor,
|
||||
getStrengthTxt,
|
||||
isVisible,
|
||||
passwordRefine,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
maxStrength: 4,
|
||||
};
|
||||
};
|
||||
|
||||
export const zMildPassword = z.string().superRefine((password, ctx) => {
|
||||
const test = [/.{6,}/, /[a-z]/, /[A-Z]/].every((regex) =>
|
||||
regex.test(password),
|
||||
);
|
||||
if (!test) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message:
|
||||
"La password deve contenere almeno 6 caratteri, una lettera minuscola e una maiuscola.",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const useMildPassword = (): PasswordManager => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||
const [strengthScore, setStrengthScore] = useState(0);
|
||||
|
||||
const checkStrength = (pass: string) => {
|
||||
const requirements = [
|
||||
{ regex: /.{6,}/, text: t.auth.signup.pw.lenght6 },
|
||||
{ regex: /[a-z]/, text: t.auth.signup.pw.lowercase },
|
||||
{ regex: /[A-Z]/, text: t.auth.signup.pw.uppercase },
|
||||
];
|
||||
|
||||
return requirements.map((req) => ({
|
||||
met: req.regex.test(pass),
|
||||
text: req.text,
|
||||
}));
|
||||
};
|
||||
|
||||
const getStrengthColor = (score: number) => {
|
||||
if (score === 0) return "bg-border";
|
||||
if (score <= 1) return "bg-red-500";
|
||||
if (score === 2) return "bg-amber-500";
|
||||
return "bg-emerald-500";
|
||||
};
|
||||
const getStrengthTxt = (score: number) => {
|
||||
if (score === 0) return "text-border";
|
||||
if (score <= 1) return "text-red-500";
|
||||
if (score === 2) return "text-amber-500";
|
||||
return "text-emerald-500";
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible((prevState) => !prevState);
|
||||
|
||||
const passwordRefine = ({
|
||||
password,
|
||||
refinementContext,
|
||||
path,
|
||||
}: {
|
||||
password: string;
|
||||
refinementContext: RefinementCtx;
|
||||
path: string;
|
||||
}) => {
|
||||
const complexity = checkStrength(password);
|
||||
|
||||
if (complexity.filter((req) => req.met).length !== complexity.length) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: complexity
|
||||
.filter((req) => !req.met)
|
||||
.map((req) => req.text)
|
||||
.join("\n"),
|
||||
path: [path],
|
||||
});
|
||||
}
|
||||
setStrengthScore(complexity.filter((req) => req.met).length);
|
||||
};
|
||||
|
||||
return {
|
||||
getStrengthColor,
|
||||
getStrengthTxt,
|
||||
isVisible,
|
||||
passwordRefine,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
maxStrength: 3,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
import { useState } from "react";
|
||||
import { type RefinementCtx, z } from "zod/v4";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
|
||||
export const zStrongPassword = z.string().superRefine((password, ctx) => {
|
||||
const test = [/.{8,}/, /[0-9]/, /[a-z]/, /[A-Z]/].every((regex) =>
|
||||
regex.test(password),
|
||||
);
|
||||
if (!test) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message:
|
||||
"La password deve contenere almeno 8 caratteri, un numero, una lettera minuscola e una maiuscola.",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const useStrongPassword = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||
const [strengthScore, setStrengthScore] = useState(0);
|
||||
|
||||
const checkStrength = (pass: string) => {
|
||||
const requirements = [
|
||||
{ regex: /.{8,}/, text: t.auth.signup.pw.lenght },
|
||||
{ regex: /[0-9]/, text: t.auth.signup.pw.number },
|
||||
{ regex: /[a-z]/, text: t.auth.signup.pw.lowercase },
|
||||
{ regex: /[A-Z]/, text: t.auth.signup.pw.uppercase },
|
||||
];
|
||||
|
||||
return requirements.map((req) => ({
|
||||
met: req.regex.test(pass),
|
||||
text: req.text,
|
||||
}));
|
||||
};
|
||||
|
||||
const getStrengthColor = (score: number) => {
|
||||
if (score === 0) return "bg-border";
|
||||
if (score <= 1) return "bg-red-500";
|
||||
if (score <= 2) return "bg-orange-500";
|
||||
if (score === 3) return "bg-amber-500";
|
||||
return "bg-emerald-500";
|
||||
};
|
||||
const getStrengthTxt = (score: number) => {
|
||||
if (score === 0) return "text-border";
|
||||
if (score <= 1) return "text-red-500";
|
||||
if (score <= 2) return "text-orange-500";
|
||||
if (score === 3) return "text-amber-500";
|
||||
return "text-emerald-500";
|
||||
};
|
||||
|
||||
const toggleVisibility = () => setIsVisible((prevState) => !prevState);
|
||||
|
||||
const passwordRefine = ({
|
||||
password,
|
||||
refinementContext,
|
||||
path,
|
||||
}: {
|
||||
password: string;
|
||||
refinementContext: RefinementCtx;
|
||||
path: string;
|
||||
}) => {
|
||||
const complexity = checkStrength(password);
|
||||
|
||||
if (complexity.filter((req) => req.met).length !== complexity.length) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: complexity
|
||||
.filter((req) => !req.met)
|
||||
.map((req) => req.text)
|
||||
.join("\n"),
|
||||
path: [path],
|
||||
});
|
||||
}
|
||||
setStrengthScore(complexity.filter((req) => req.met).length);
|
||||
};
|
||||
|
||||
return {
|
||||
getStrengthColor,
|
||||
getStrengthTxt,
|
||||
isVisible,
|
||||
passwordRefine,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
};
|
||||
};
|
||||
|
|
@ -369,7 +369,8 @@ export const en: LangDict = {
|
|||
nome: "Name",
|
||||
password: "Password",
|
||||
pw: {
|
||||
lenght: "At least 8 characters",
|
||||
lenght8: "At least 8 characters",
|
||||
lenght6: "At least 6 characters",
|
||||
lowercase: "At least 1 lowercase letter",
|
||||
number: "At least 1 number",
|
||||
uppercase: "At least 1 uppercase letter",
|
||||
|
|
|
|||
|
|
@ -374,7 +374,8 @@ export const it: LangDict = {
|
|||
nome: "Nome",
|
||||
password: "Password",
|
||||
pw: {
|
||||
lenght: "Almeno 8 caratteri",
|
||||
lenght8: "Almeno 8 caratteri",
|
||||
lenght6: "Almeno 6 caratteri",
|
||||
lowercase: "Almeno 1 lettera minuscola",
|
||||
number: "Almeno 1 numero",
|
||||
uppercase: "Almeno 1 lettera maiuscola",
|
||||
|
|
|
|||
|
|
@ -550,7 +550,8 @@ export type LangDict = {
|
|||
success: string;
|
||||
fail: string;
|
||||
pw: {
|
||||
lenght: string;
|
||||
lenght6: string;
|
||||
lenght8: string;
|
||||
number: string;
|
||||
lowercase: string;
|
||||
uppercase: string;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import {
|
|||
} from "~/components/ui/alert-dialog";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import Input from "~/components/ui/input";
|
||||
import { useStrongPassword } from "~/hooks/useStrongPassword";
|
||||
import { useMildPassword } from "~/hooks/usePassword";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
import type { NextPageWithLayout } from "~/pages/_app";
|
||||
|
|
@ -64,7 +64,8 @@ const AcceptInvitePage: NextPageWithLayout<InviteTokenProps> = ({
|
|||
getStrengthTxt,
|
||||
strengthScore,
|
||||
toggleVisibility,
|
||||
} = useStrongPassword();
|
||||
maxStrength,
|
||||
} = useMildPassword();
|
||||
const router = useRouter();
|
||||
|
||||
const schema = z
|
||||
|
|
@ -189,7 +190,7 @@ const AcceptInvitePage: NextPageWithLayout<InviteTokenProps> = ({
|
|||
</button>
|
||||
<div
|
||||
aria-label="Password strength"
|
||||
aria-valuemax={4}
|
||||
aria-valuemax={maxStrength}
|
||||
aria-valuemin={0}
|
||||
aria-valuenow={strengthScore}
|
||||
className="mt-3 mb-4 h-1 w-full overflow-hidden rounded-full bg-border"
|
||||
|
|
@ -200,7 +201,9 @@ const AcceptInvitePage: NextPageWithLayout<InviteTokenProps> = ({
|
|||
"h-full transition-all duration-500 ease-out",
|
||||
getStrengthColor(strengthScore),
|
||||
)}
|
||||
style={{ width: `${(strengthScore / 4) * 100}%` }}
|
||||
style={{
|
||||
width: `${(strengthScore / maxStrength) * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { z } from "zod/v4";
|
||||
import { zStrongPassword } from "~/hooks/useStrongPassword";
|
||||
import { zMildPassword } from "~/hooks/usePassword";
|
||||
import {
|
||||
adminProcedure,
|
||||
createTRPCRouter,
|
||||
|
|
@ -38,7 +38,7 @@ export const authRouter = createTRPCRouter({
|
|||
cognome: z.string().nonempty("Inserisci un cognome valido"),
|
||||
email: z.email(),
|
||||
nome: z.string().nonempty("Inserisci un nome valido"),
|
||||
password: zStrongPassword,
|
||||
password: zMildPassword,
|
||||
telefono: z.string().nonempty("Inserisci un numero di telefono"),
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue