diff --git a/features/auth/schemas/auth-schema.ts b/features/auth/schemas/auth-schema.ts new file mode 100644 index 0000000..00f1842 --- /dev/null +++ b/features/auth/schemas/auth-schema.ts @@ -0,0 +1,94 @@ +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;