using FluentValidation; namespace FamilyNido.Api.Features.Auth; /// /// Centralized password complexity requirements. Plain enough to remember, /// strict enough to keep the obvious "1234" / "password" attacks out. /// Reused by both and the invitation /// "accept-local" path. /// internal static class PasswordPolicy { /// Minimum number of characters. public const int MinLength = 8; /// Maximum length we ever accept (defends the hash function from absurd inputs). public const int MaxLength = 256; /// /// Rule helper used by FluentValidation builders. /// Requires length, at least one letter, and at least one digit. /// public static IRuleBuilderOptions Password(this IRuleBuilder rule) { return rule .NotEmpty() .MinimumLength(MinLength).WithMessage($"Password must be at least {MinLength} characters.") .MaximumLength(MaxLength) .Must(s => s.Any(char.IsLetter)).WithMessage("Password must contain at least one letter.") .Must(s => s.Any(char.IsDigit)).WithMessage("Password must contain at least one digit."); } }