From 64c29348ce9cef83028c8759f0de3a11e1054f91 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 28 Sep 2025 17:57:48 +0000 Subject: [PATCH] Add disallowed usernames --- src/lib/validation.ts | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/lib/validation.ts b/src/lib/validation.ts index 0fb16bc3..a5ff02d5 100644 --- a/src/lib/validation.ts +++ b/src/lib/validation.ts @@ -1,16 +1,58 @@ 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()); + .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: z.string().max(100, 'Display name must be less than 100 characters').optional(), + display_name: displayNameSchema, bio: z.string().max(500, 'Bio must be less than 500 characters').optional(), });