157 lines
3.6 KiB
Go
157 lines
3.6 KiB
Go
package validation
|
|
|
|
import (
|
|
"net/mail"
|
|
"regexp"
|
|
"strings"
|
|
"unicode"
|
|
|
|
"git.techease.ru/Smart-search/smart-search-back/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
MinPasswordLength = 8
|
|
MaxPasswordLength = 128
|
|
MaxEmailLength = 254
|
|
MaxNameLength = 100
|
|
MaxPhoneLength = 20
|
|
MaxRequestTxtLen = 50000
|
|
MaxFileSizeBytes = 10 * 1024 * 1024
|
|
)
|
|
|
|
var (
|
|
phoneRegex = regexp.MustCompile(`^\+?[1-9]\d{6,14}$`)
|
|
)
|
|
|
|
func ValidateEmail(email string) error {
|
|
if email == "" {
|
|
return errors.NewBusinessError(errors.ValidationInvalidEmail, "email is required")
|
|
}
|
|
|
|
if len(email) > MaxEmailLength {
|
|
return errors.NewBusinessError(errors.ValidationInvalidEmail, "email is too long")
|
|
}
|
|
|
|
_, err := mail.ParseAddress(email)
|
|
if err != nil {
|
|
return errors.NewBusinessError(errors.ValidationInvalidEmail, "invalid email format")
|
|
}
|
|
|
|
parts := strings.Split(email, "@")
|
|
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
|
return errors.NewBusinessError(errors.ValidationInvalidEmail, "invalid email format")
|
|
}
|
|
|
|
if strings.Contains(parts[1], "..") {
|
|
return errors.NewBusinessError(errors.ValidationInvalidEmail, "invalid email format")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ValidatePassword(password string) error {
|
|
if password == "" {
|
|
return errors.NewBusinessError(errors.ValidationInvalidPassword, "password is required")
|
|
}
|
|
|
|
if len(password) < MinPasswordLength {
|
|
return errors.NewBusinessError(errors.ValidationInvalidPassword, "password must be at least 8 characters")
|
|
}
|
|
|
|
if len(password) > MaxPasswordLength {
|
|
return errors.NewBusinessError(errors.ValidationInvalidPassword, "password is too long")
|
|
}
|
|
|
|
var hasUpper, hasLower, hasDigit bool
|
|
for _, c := range password {
|
|
switch {
|
|
case unicode.IsUpper(c):
|
|
hasUpper = true
|
|
case unicode.IsLower(c):
|
|
hasLower = true
|
|
case unicode.IsDigit(c):
|
|
hasDigit = true
|
|
}
|
|
}
|
|
|
|
if !hasUpper || !hasLower || !hasDigit {
|
|
return errors.NewBusinessError(errors.ValidationInvalidPassword, "password must contain uppercase, lowercase and digit")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ValidatePhone(phone string) error {
|
|
if phone == "" {
|
|
return nil
|
|
}
|
|
|
|
if len(phone) > MaxPhoneLength {
|
|
return errors.NewBusinessError(errors.ValidationInvalidPhone, "phone is too long")
|
|
}
|
|
|
|
cleaned := strings.ReplaceAll(phone, " ", "")
|
|
cleaned = strings.ReplaceAll(cleaned, "-", "")
|
|
cleaned = strings.ReplaceAll(cleaned, "(", "")
|
|
cleaned = strings.ReplaceAll(cleaned, ")", "")
|
|
|
|
if !phoneRegex.MatchString(cleaned) {
|
|
return errors.NewBusinessError(errors.ValidationInvalidPhone, "invalid phone format")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ValidateName(name string) error {
|
|
if name == "" {
|
|
return errors.NewBusinessError(errors.ValidationInvalidName, "name is required")
|
|
}
|
|
|
|
if len(name) > MaxNameLength {
|
|
return errors.NewBusinessError(errors.ValidationInvalidName, "name is too long")
|
|
}
|
|
|
|
trimmed := strings.TrimSpace(name)
|
|
if trimmed == "" {
|
|
return errors.NewBusinessError(errors.ValidationInvalidName, "name cannot be only whitespace")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ValidateRequestTxt(txt string) error {
|
|
if len(txt) > MaxRequestTxtLen {
|
|
return errors.NewBusinessError(errors.ValidationRequestTooLong, "request text exceeds 50000 characters limit")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ValidateFileSize(size int) error {
|
|
if size > MaxFileSizeBytes {
|
|
return errors.NewBusinessError(errors.ValidationFileTooLarge, "file size exceeds 10MB limit")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ValidateRegistration(email, password, name, phone string) error {
|
|
if err := ValidateEmail(email); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ValidatePassword(password); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ValidateName(name); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ValidatePhone(phone); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|