mirror of
https://github.com/Dvorinka/Trackeep.git
synced 2026-06-03 20:12:58 +00:00
137 lines
3.4 KiB
Go
137 lines
3.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// Validator provides common validation functions
|
|
type Validator struct {
|
|
errors map[string]string
|
|
}
|
|
|
|
// NewValidator creates a new validator instance
|
|
func NewValidator() *Validator {
|
|
return &Validator{
|
|
errors: make(map[string]string),
|
|
}
|
|
}
|
|
|
|
// Required checks if a field is not empty
|
|
func (v *Validator) Required(field, value string) *Validator {
|
|
if strings.TrimSpace(value) == "" {
|
|
v.errors[field] = fmt.Sprintf("%s is required", field)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// MinLength checks if a field meets minimum length
|
|
func (v *Validator) MinLength(field, value string, min int) *Validator {
|
|
if utf8.RuneCountInString(value) < min {
|
|
v.errors[field] = fmt.Sprintf("%s must be at least %d characters", field, min)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// MaxLength checks if a field exceeds maximum length
|
|
func (v *Validator) MaxLength(field, value string, max int) *Validator {
|
|
if utf8.RuneCountInString(value) > max {
|
|
v.errors[field] = fmt.Sprintf("%s must be at most %d characters", field, max)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// Email checks if a field is a valid email
|
|
func (v *Validator) Email(field, value string) *Validator {
|
|
emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
|
|
if !emailRegex.MatchString(value) {
|
|
v.errors[field] = fmt.Sprintf("%s must be a valid email address", field)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// URL checks if a field is a valid URL
|
|
func (v *Validator) URL(field, value string) *Validator {
|
|
urlRegex := regexp.MustCompile(`^https?://[^\s/$.?#].[^\s]*$`)
|
|
if !urlRegex.MatchString(value) {
|
|
v.errors[field] = fmt.Sprintf("%s must be a valid URL", field)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// Match checks if a field matches a regex pattern
|
|
func (v *Validator) Match(field, value, pattern, message string) *Validator {
|
|
regex := regexp.MustCompile(pattern)
|
|
if !regex.MatchString(value) {
|
|
v.errors[field] = message
|
|
}
|
|
return v
|
|
}
|
|
|
|
// In checks if a field value is in the allowed values
|
|
func (v *Validator) In(field, value string, allowed []string) *Validator {
|
|
for _, allowedValue := range allowed {
|
|
if value == allowedValue {
|
|
return v
|
|
}
|
|
}
|
|
v.errors[field] = fmt.Sprintf("%s must be one of: %s", field, strings.Join(allowed, ", "))
|
|
return v
|
|
}
|
|
|
|
// HasErrors returns true if there are validation errors
|
|
func (v *Validator) HasErrors() bool {
|
|
return len(v.errors) > 0
|
|
}
|
|
|
|
// GetErrors returns all validation errors
|
|
func (v *Validator) GetErrors() map[string]string {
|
|
return v.errors
|
|
}
|
|
|
|
// GetError returns a specific field error
|
|
func (v *Validator) GetError(field string) string {
|
|
return v.errors[field]
|
|
}
|
|
|
|
// Clear clears all validation errors
|
|
func (v *Validator) Clear() *Validator {
|
|
v.errors = make(map[string]string)
|
|
return v
|
|
}
|
|
|
|
// ValidatePassword checks password strength
|
|
func (v *Validator) ValidatePassword(field, password string) *Validator {
|
|
if len(password) < 8 {
|
|
v.errors[field] = "Password must be at least 8 characters long"
|
|
return v
|
|
}
|
|
|
|
hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
|
|
hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
|
|
hasNumber := regexp.MustCompile(`[0-9]`).MatchString(password)
|
|
hasSpecial := regexp.MustCompile(`[!@#$%^&*(),.?":{}|<>]`).MatchString(password)
|
|
|
|
errorCount := 0
|
|
if !hasUpper {
|
|
errorCount++
|
|
}
|
|
if !hasLower {
|
|
errorCount++
|
|
}
|
|
if !hasNumber {
|
|
errorCount++
|
|
}
|
|
if !hasSpecial {
|
|
errorCount++
|
|
}
|
|
|
|
if errorCount > 1 {
|
|
v.errors[field] = "Password must contain at least 3 of: uppercase, lowercase, number, special character"
|
|
}
|
|
|
|
return v
|
|
}
|