import { z } from "zod"; import { PASSWORD_RULES } from "@/features/auth/constants"; /** * [비밀번호 검증 스키마] * * 비밀번호 강도 요구사항: * - 최소 8자 이상 * - 대문자 1개 이상 * - 소문자 1개 이상 * - 숫자 1개 이상 * - 특수문자 1개 이상 */ const passwordSchema = z .string() .min(PASSWORD_RULES.MIN_LENGTH, { message: `비밀번호는 최소 ${PASSWORD_RULES.MIN_LENGTH}자 이상이어야 합니다.`, }) .regex(/[A-Z]/, { message: "비밀번호에 대문자가 최소 1개 이상 포함되어야 합니다.", }) .regex(/[a-z]/, { message: "비밀번호에 소문자가 최소 1개 이상 포함되어야 합니다.", }) .regex(/[0-9]/, { message: "비밀번호에 숫자가 최소 1개 이상 포함되어야 합니다.", }) .regex(/[!@#$%^&*(),.?":{}|<>]/, { message: "비밀번호에 특수문자가 최소 1개 이상 포함되어야 합니다.", }); /** * [회원가입 폼 스키마] * * 회원가입 시 필요한 필드 검증 */ export const signupSchema = z .object({ email: z .string() .min(1, { message: "이메일을 입력해주세요." }) .email({ message: "올바른 이메일 형식이 아닙니다." }), password: passwordSchema, confirmPassword: z .string() .min(1, { message: "비밀번호 확인을 입력해주세요." }), }) .refine((data) => data.password === data.confirmPassword, { message: "비밀번호가 일치하지 않습니다.", path: ["confirmPassword"], }); /** * [비밀번호 재설정 폼 스키마] */ export const resetPasswordSchema = z .object({ password: passwordSchema, confirmPassword: z .string() .min(1, { message: "비밀번호 확인을 입력해주세요." }), }) .refine((data) => data.password === data.confirmPassword, { message: "비밀번호가 일치하지 않습니다.", path: ["confirmPassword"], }); /** * [로그인 폼 스키마] */ export const loginSchema = z.object({ email: z .string() .min(1, { message: "이메일을 입력해주세요." }) .email({ message: "올바른 이메일 형식이 아닙니다." }), password: z.string().min(1, { message: "비밀번호를 입력해주세요." }), rememberMe: z.boolean().optional(), }); /** * [비밀번호 찾기 폼 스키마] */ export const forgotPasswordSchema = z.object({ email: z .string() .min(1, { message: "이메일을 입력해주세요." }) .email({ message: "올바른 이메일 형식이 아닙니다." }), }); // TypeScript 타입 추론 export type SignupFormData = z.infer; export type ResetPasswordFormData = z.infer; export type LoginFormData = z.infer; export type ForgotPasswordFormData = z.infer;