add service
All checks were successful
Deploy Smart Search Backend / deploy (push) Successful in 1m47s
All checks were successful
Deploy Smart Search Backend / deploy (push) Successful in 1m47s
This commit is contained in:
156
pkg/validation/validation.go
Normal file
156
pkg/validation/validation.go
Normal file
@@ -0,0 +1,156 @@
|
||||
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 errors.NewBusinessError(errors.ValidationInvalidPhone, "phone is required")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user