using FluentValidation; namespace Features.Auth.Commands.RegisterUser; /// /// Validates the field-level constraints on : username format and /// length, name lengths, email format, minimum age of 19, and password complexity. /// public class RegisterUserValidator : AbstractValidator { public RegisterUserValidator() { RuleFor(x => x.Username) .NotEmpty() .WithMessage("Username is required") .Length(3, 64) .WithMessage("Username must be between 3 and 64 characters") .Matches("^[a-zA-Z0-9._-]+$") .WithMessage( "Username can only contain letters, numbers, dots, underscores, and hyphens" ); RuleFor(x => x.FirstName) .NotEmpty() .WithMessage("First name is required") .MaximumLength(128) .WithMessage("First name cannot exceed 128 characters"); RuleFor(x => x.LastName) .NotEmpty() .WithMessage("Last name is required") .MaximumLength(128) .WithMessage("Last name cannot exceed 128 characters"); RuleFor(x => x.Email) .NotEmpty() .WithMessage("Email is required") .EmailAddress() .WithMessage("Invalid email format") .MaximumLength(128) .WithMessage("Email cannot exceed 128 characters"); RuleFor(x => x.DateOfBirth) .NotEmpty() .WithMessage("Date of birth is required") .LessThan(DateTime.Today.AddYears(-19)) .WithMessage("You must be at least 19 years old to register"); RuleFor(x => x.Password) .NotEmpty() .WithMessage("Password is required") .MinimumLength(8) .WithMessage("Password must be at least 8 characters") .Matches("[A-Z]") .WithMessage("Password must contain at least one uppercase letter") .Matches("[a-z]") .WithMessage("Password must contain at least one lowercase letter") .Matches("[0-9]") .WithMessage("Password must contain at least one number") .Matches("[^a-zA-Z0-9]") .WithMessage("Password must contain at least one special character"); } }