This commit is contained in:
2025-12-19 22:41:13 -05:00
parent 3e606d2354
commit ee9db9f674
14 changed files with 136 additions and 443 deletions

View File

@@ -1,153 +0,0 @@
import { z } from "zod";
/**
* Validation Schemas for tRPC Procedures
*
* These schemas are the source of truth for server-side validation.
* Client-side validation (src/lib/validation.ts) is optional for UX only.
*/
// ============================================================================
// Base Schemas
// ============================================================================
/**
* Email validation schema
* - Must be valid email format
* - Min 3 chars, max 255 chars
* - Trimmed and lowercased automatically
*/
export const emailSchema = z
.string()
.trim()
.toLowerCase()
.email("Invalid email address")
.min(3, "Email too short")
.max(255, "Email too long");
/**
* Password validation schema
* - Minimum 8 characters
* - Maximum 128 characters
* - Can add additional complexity requirements if needed
*/
export const passwordSchema = z
.string()
.min(8, "Password must be at least 8 characters")
.max(128, "Password too long");
/**
* Display name validation schema
* - Minimum 1 character (after trim)
* - Maximum 50 characters
*/
export const displayNameSchema = z
.string()
.trim()
.min(1, "Display name is required")
.max(50, "Display name too long");
/**
* Comment body validation schema
* - Minimum 1 character (after trim)
* - Maximum 10,000 characters
*/
export const commentBodySchema = z
.string()
.trim()
.min(1, "Comment cannot be empty")
.max(10000, "Comment too long (max 10,000 characters)");
// ============================================================================
// Composed Schemas
// ============================================================================
/**
* Email/password login schema
*/
export const loginSchema = z.object({
email: emailSchema,
password: passwordSchema,
rememberMe: z.boolean().optional()
});
/**
* Email/password registration schema with password confirmation
*/
export const registrationSchema = z
.object({
email: emailSchema,
password: passwordSchema,
passwordConfirmation: passwordSchema,
displayName: displayNameSchema.optional()
})
.refine((data) => data.password === data.passwordConfirmation, {
message: "Passwords do not match",
path: ["passwordConfirmation"]
});
/**
* Password change schema (requires old password)
*/
export const passwordChangeSchema = z
.object({
oldPassword: passwordSchema,
newPassword: passwordSchema,
newPasswordConfirmation: passwordSchema
})
.refine((data) => data.newPassword === data.newPasswordConfirmation, {
message: "New passwords do not match",
path: ["newPasswordConfirmation"]
})
.refine((data) => data.oldPassword !== data.newPassword, {
message: "New password must be different from old password",
path: ["newPassword"]
});
/**
* Password reset schema (no old password required)
*/
export const passwordResetSchema = z
.object({
token: z.string(),
newPassword: passwordSchema,
newPasswordConfirmation: passwordSchema
})
.refine((data) => data.newPassword === data.newPasswordConfirmation, {
message: "Passwords do not match",
path: ["newPasswordConfirmation"]
});
/**
* Password set schema (for OAuth users setting password first time)
*/
export const passwordSetSchema = z
.object({
password: passwordSchema,
passwordConfirmation: passwordSchema
})
.refine((data) => data.password === data.passwordConfirmation, {
message: "Passwords do not match",
path: ["passwordConfirmation"]
});
/**
* Update email schema
*/
export const updateEmailSchema = z.object({
email: emailSchema
});
/**
* Update display name schema
*/
export const updateDisplayNameSchema = z.object({
displayName: displayNameSchema
});
/**
* Account deletion schema
*/
export const deleteAccountSchema = z.object({
password: passwordSchema
});