import { z } from 'zod'; // Reserved usernames for security and system purposes const FORBIDDEN_USERNAMES = new Set([ // System/Admin accounts 'admin', 'administrator', 'moderator', 'mod', 'owner', 'root', 'system', 'support', 'staff', 'team', 'official', 'verified', 'bot', 'api', 'service', // Company/Brand protection 'thrillwiki', 'lovable', 'supabase', 'cloudflare', // Common system routes/pages 'www', 'mail', 'email', 'ftp', 'blog', 'forum', 'shop', 'store', 'app', 'mobile', 'help', 'support', 'contact', 'about', 'terms', 'privacy', 'security', 'legal', 'login', 'signup', 'register', 'signin', 'signout', 'logout', 'auth', 'oauth', 'profile', 'profiles', 'user', 'users', 'account', 'accounts', 'settings', 'dashboard', 'console', 'panel', 'manage', 'management', // Technical terms 'null', 'undefined', 'true', 'false', 'delete', 'remove', 'test', 'demo', 'localhost', 'example', 'temp', 'temporary', 'guest', 'anonymous', 'anon', // Offensive prevention (basic) 'fuck', 'shit', 'damn', 'hell', 'ass', 'bitch', 'bastard', 'crap', 'nazi', 'hitler', 'stalin', 'terrorist', 'kill', 'death', 'murder', // Impersonation prevention 'ceo', 'president', 'manager', 'director', 'executive', 'founder' ]); 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') .transform(val => val.toLowerCase()) .refine(val => !FORBIDDEN_USERNAMES.has(val), 'This username is not allowed'); // Display name validation with content filtering export const displayNameSchema = z .string() .max(100, 'Display name must be less than 100 characters') .refine(val => { if (!val) return true; const lowerVal = val.toLowerCase(); // Check for basic offensive content in display names const offensiveTerms = ['nazi', 'hitler', 'terrorist', 'kill', 'murder', 'fuck', 'shit']; return !offensiveTerms.some(term => lowerVal.includes(term)); }, 'Display name contains inappropriate content') .optional(); export const profileEditSchema = z.object({ username: usernameSchema, display_name: displayNameSchema, bio: z.string().max(500, 'Bio must be less than 500 characters').optional(), }); export type ProfileEditForm = z.infer;