1
7
8import { z } from "zod";
9
10import { LIMITS } from "../constants.js";
11
12
16export const passwordSchema = z
17 .string()
18 .min(LIMITS.MIN_PASSWORD, "Password must be at least 10 characters")
19 .max(LIMITS.MAX_PASSWORD, "Password must be at most 72 characters")
20 .regex(/[A-Za-z]/, "Password must contain at least one letter")
21 .regex(/[0-9]/, "Password must contain at least one number");
22export type PasswordInput = z.infer<typeof passwordSchema>;
23
24export const emailSchema = z
25 .string()
26 .min(1, "Email is required")
27 .max(254)
28 .email("Invalid email address")
29 .transform((v) => v.toLowerCase());
30export type EmailInput = z.infer<typeof emailSchema>;
31
32export const registerInputSchema = z
33 .object({
34 name: z.string().min(1, "Name is required").max(100),
35 email: emailSchema,
36 password: passwordSchema,
37 })
38 .strict();
39export type RegisterInput = z.infer<typeof registerInputSchema>;
40
41export const loginInputSchema = z
42 .object({
43 email: emailSchema,
44 password: z.string().min(1, "Password is required"),
45 })
46 .strict();
47export type LoginInput = z.infer<typeof loginInputSchema>;
48
49export const refreshInputSchema = z
50 .object({
51
52 refreshToken: z.string().min(1, "Refresh token is required"),
53 })
54 .strict();
55export type RefreshInput = z.infer<typeof refreshInputSchema>;
56
57export const passwordResetRequestSchema = z
58 .object({
59 email: emailSchema,
60 })
61 .strict();
62export type PasswordResetRequest = z.infer<typeof passwordResetRequestSchema>;
63
64export const passwordResetConfirmSchema = z
65 .object({
66
67 token: z.string().min(1, "Token is required"),
68 password: passwordSchema,
69 })
70 .strict();
71export type PasswordResetConfirm = z.infer<typeof passwordResetConfirmSchema>;
72
73export const updateProfileInputSchema = z
74 .object({
75 name: z.string().min(1).max(100).optional(),
76 displayName: z.string().min(1).max(100).optional(),
77 avatarUrl: z.string().url().optional().nullable(),
78 locale: z
79 .string()
80 .regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,4})?$/)
81 .optional(),
82 timezone: z.string().min(1).max(64).optional(),
83 theme: z.enum(["light", "dark", "system"]).optional(),
84 })
85 .strict()
86 .refine((v) => Object.keys(v).length > 0, { message: "No fields to update" });
87export type UpdateProfileInput = z.infer<typeof updateProfileInputSchema>;
88