Spaces:
Build error
Build error
File size: 3,953 Bytes
ef73937 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | import { z } from 'zod';
import { config } from '@config/index.js';
export const registerSchema = z.object({
username: z.string()
.min(3, 'Username must be at least 3 characters')
.max(16, 'Username must not exceed 16 characters')
.regex(/^[a-zA-Z0-9_-]+$/, 'Username can only contain letters, numbers, underscore and hyphen')
.toLowerCase(),
password: z.string()
.min(8, 'Password must be at least 8 characters')
.max(16, 'Password must not exceed 16 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(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/, 'Password must contain at least one special character'),
captchaToken: z.string().min(1, 'Captcha verification required'),
acceptTerms: z.boolean().refine(v => v === true, 'You must accept the terms of service'),
});
export const loginSchema = z.object({
username: z.string().min(1, 'Username is required').toLowerCase(),
password: z.string().min(1, 'Password is required'),
captchaToken: z.string().min(1, 'Captcha verification required'),
});
export const channelAddSchema = z.object({
inviteLink: z.string().url('Invalid URL format').regex(config.whatsappChannelRegex, 'Must be a valid WhatsApp channel link'),
});
export const channelTagsSchema = z.object({
tags: z.array(z.string().min(1).max(30).toLowerCase()).max(10, 'Maximum 10 tags allowed'),
});
export const profileUpdateSchema = z.object({
email: z.string().email('Invalid email format').optional().or(z.literal('')),
currentPassword: z.string().optional(),
newPassword: z.string()
.min(8, 'Password must be at least 8 characters')
.max(16, 'Password must not exceed 16 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(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/, 'Password must contain at least one special character')
.optional(),
}).refine(data => data.currentPassword || !data.newPassword, {
message: 'Current password required to change password',
path: ['currentPassword'],
});
export const searchSchema = z.object({
q: z.string().max(100).optional(),
tag: z.string().max(50).optional(),
sort: z.enum(['trending', 'followers', 'votes', 'newest', 'oldest', 'alpha', 'updated']).default('newest'),
page: z.coerce.number().min(1).default(1),
limit: z.coerce.number().min(1).max(100).default(20),
});
export const voteSchema = z.object({
channelId: z.string().min(1, 'Channel ID required'),
});
export const adminUserSearchSchema = z.object({
q: z.string().max(100).optional(),
isAdmin: z.coerce.boolean().optional(),
isBanned: z.coerce.boolean().optional(),
page: z.coerce.number().min(1).default(1),
limit: z.coerce.number().min(1).max(100).default(20),
});
export const adminChannelSearchSchema = z.object({
q: z.string().max(100).optional(),
status: z.enum(['pending', 'scraping', 'validating', 'published', 'rejected', 'banned']).optional(),
isBanned: z.coerce.boolean().optional(),
page: z.coerce.number().min(1).default(1),
limit: z.coerce.number().min(1).max(100).default(20),
});
export const banSchema = z.object({
type: z.enum(['user', 'channel', 'ip']),
targetId: z.string().min(1),
targetValue: z.string().min(1),
reason: z.string().min(1, 'Reason required').max(500),
expiresAt: z.string().datetime().optional(),
});
export function validateInput<T>(schema: z.ZodSchema<T>, data: unknown): { success: true; data: T } | { success: false; errors: z.ZodIssue[] } {
const result = schema.safeParse(data);
if (result.success) {
return { success: true, data: result.data };
}
return { success: false, errors: result.error.issues };
} |