Files
frontend/src/features/auth/model/validation.ts
T

55 lines
1.4 KiB
TypeScript

import { z } from "zod";
import { validationMessage } from "@/shared/i18n";
const ASCII_SPACE = 32;
const ASCII_DELETE = 127;
const MAX_EMAIL_LENGTH = 254;
const MIN_PASSWORD_BYTES = 12;
const MAX_PASSWORD_BYTES = 72;
function isEmailCharacterInvalid(character: string): boolean {
return (
/\s/.test(character) ||
character.charCodeAt(0) < ASCII_SPACE ||
character.charCodeAt(0) === ASCII_DELETE
);
}
const email = z
.string()
.trim()
.toLowerCase()
.max(MAX_EMAIL_LENGTH)
.refine(
(value) =>
value.split("@").length === 2 &&
value.split("@").every(Boolean) &&
!value.split("").some(isEmailCharacterInvalid),
validationMessage("auth.validation.invalidEmail"),
);
const password = z
.string()
.refine(
(value) =>
new TextEncoder().encode(value).length >= MIN_PASSWORD_BYTES &&
new TextEncoder().encode(value).length <= MAX_PASSWORD_BYTES,
validationMessage("auth.validation.invalidPasswordLength"),
);
const loginSchema = z.object({
email,
password,
passwordConfirmation: z.string().optional(),
});
const registerSchema = loginSchema.refine(
(value) => value.password === value.passwordConfirmation,
(value) => ({
path: ["passwordConfirmation"],
...validationMessage("auth.validation.passwordsDoNotMatch")(value),
}),
);
type AuthFormValues = z.input<typeof loginSchema>;
export { type AuthFormValues, loginSchema, registerSchema };