mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 11:51:12 -05:00
Refactor: Improve validation schemas
This commit is contained in:
@@ -32,8 +32,14 @@ export const usernameSchema = z
|
||||
.string()
|
||||
.min(3, 'Username must be at least 3 characters')
|
||||
.max(30, 'Username must be less than 30 characters')
|
||||
.regex(/^[a-zA-Z0-9_-]+$/, 'Username can only contain letters, numbers, underscores, and hyphens')
|
||||
.regex(/^[a-zA-Z0-9]/, 'Username must start with a letter or number')
|
||||
.regex(
|
||||
/^[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/,
|
||||
'Username must start and end with letters/numbers, and can only contain letters, numbers, hyphens, and underscores'
|
||||
)
|
||||
.refine(
|
||||
(val) => !/[-_]{2,}/.test(val),
|
||||
'Username cannot contain consecutive hyphens or underscores'
|
||||
)
|
||||
.transform(val => val.toLowerCase())
|
||||
.refine(val => !FORBIDDEN_USERNAMES.has(val), 'This username is not allowed');
|
||||
|
||||
@@ -50,10 +56,46 @@ export const displayNameSchema = z
|
||||
}, 'Display name contains inappropriate content')
|
||||
.optional();
|
||||
|
||||
// Password validation schema with complexity requirements
|
||||
export const passwordSchema = z.object({
|
||||
currentPassword: z.string().min(1, 'Current password is required'),
|
||||
newPassword: z.string()
|
||||
.min(8, 'Password must be at least 8 characters')
|
||||
.max(128, 'Password must be less than 128 characters')
|
||||
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
|
||||
.regex(/[a-z]/, 'Password must contain at least one lowercase letter')
|
||||
.regex(/[0-9]/, 'Password must contain at least one number')
|
||||
.regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character'),
|
||||
confirmPassword: z.string()
|
||||
}).refine(data => data.newPassword === data.confirmPassword, {
|
||||
message: "Passwords don't match",
|
||||
path: ["confirmPassword"]
|
||||
});
|
||||
|
||||
// Bio field validation with sanitization
|
||||
export const bioSchema = z.string()
|
||||
.max(500, 'Bio must be less than 500 characters')
|
||||
.transform(val => val?.trim())
|
||||
.refine(
|
||||
val => !val || !/[<>]/.test(val),
|
||||
'Bio cannot contain HTML tags'
|
||||
)
|
||||
.optional();
|
||||
|
||||
// Personal location field validation with sanitization
|
||||
export const personalLocationSchema = z.string()
|
||||
.max(100, 'Location must be less than 100 characters')
|
||||
.transform(val => val?.trim())
|
||||
.refine(
|
||||
val => !val || !/[<>{}]/.test(val),
|
||||
'Location cannot contain special characters'
|
||||
)
|
||||
.optional();
|
||||
|
||||
export const profileEditSchema = z.object({
|
||||
username: usernameSchema,
|
||||
display_name: displayNameSchema,
|
||||
bio: z.string().max(500, 'Bio must be less than 500 characters').optional(),
|
||||
bio: bioSchema,
|
||||
});
|
||||
|
||||
export type ProfileEditForm = z.infer<typeof profileEditSchema>;
|
||||
Reference in New Issue
Block a user