@@ -8,12 +8,13 @@ import type { ThemeContextType } from "../../context/ThemeContext";
88
99const backendUrl = import . meta. env . VITE_BACKEND_URL ;
1010
11- // Must mirror the Zod rule in backend/validators/authValidator.js exactly.
12- // Requires: lowercase, uppercase, digit, and one special character from @$!%*?&
13- // Minimum 8 characters, maximum enforced by the backend (100).
14- const PASSWORD_REGEX = / ^ (? = .* [ a - z ] ) (? = .* [ A - Z ] ) (? = .* \d ) (? = .* [ @ $ ! % * ? & ] ) [ A - Z a - z \d @ $ ! % * ? & ] { 8 , } $ / ;
15- const PASSWORD_ERROR =
16- "Password must be at least 8 characters and include uppercase, lowercase, a number, and a special character (@$!%*?&)" ;
11+ // Username rules -- must mirror backend/validators/authValidator.js exactly.
12+ // Accepted characters: letters (a-z, A-Z), digits (0-9), and underscores.
13+ // Length: minimum 3, maximum 30 characters.
14+ const USERNAME_REGEX = / ^ [ a - z A - Z 0 - 9 _ ] + $ / ;
15+ const USERNAME_MIN = 3 ;
16+ const USERNAME_MAX = 30 ;
17+ const USERNAME_ERROR = "Username can only contain letters, numbers, and underscores" ;
1718
1819interface SignUpFormData {
1920 username : string ;
@@ -46,8 +47,12 @@ const SignUp: React.FC = () => {
4647 if ( name === "username" ) {
4748 if ( ! value . trim ( ) ) {
4849 errorMessage = "Username is required" ;
49- } else if ( ! / ^ [ A - Z a - z \s ] + $ / . test ( value ) ) {
50- errorMessage = "Only letters are allowed" ;
50+ } else if ( value . trim ( ) . length < USERNAME_MIN ) {
51+ errorMessage = `Username must be at least ${ USERNAME_MIN } characters long` ;
52+ } else if ( value . trim ( ) . length > USERNAME_MAX ) {
53+ errorMessage = `Username must be at most ${ USERNAME_MAX } characters long` ;
54+ } else if ( ! USERNAME_REGEX . test ( value . trim ( ) ) ) {
55+ errorMessage = USERNAME_ERROR ;
5156 }
5257 }
5358 if ( name === "email" ) {
@@ -69,10 +74,15 @@ const SignUp: React.FC = () => {
6974
7075 const handleSubmit = async ( e : React . FormEvent ) => {
7176 e . preventDefault ( ) ;
72- const usernameError = ! formData . username . trim ( )
77+ const trimmedUsername = formData . username . trim ( ) ;
78+ const usernameError = ! trimmedUsername
7379 ? "Username is required"
74- : ! / ^ [ A - Z a - z \s ] + $ / . test ( formData . username )
75- ? "Only letters are allowed"
80+ : trimmedUsername . length < USERNAME_MIN
81+ ? `Username must be at least ${ USERNAME_MIN } characters long`
82+ : trimmedUsername . length > USERNAME_MAX
83+ ? `Username must be at most ${ USERNAME_MAX } characters long`
84+ : ! USERNAME_REGEX . test ( trimmedUsername )
85+ ? USERNAME_ERROR
7686 : "" ;
7787 const emailError = ! formData . email . trim ( )
7888 ? "Email is required"
0 commit comments