2025-11-23 22:49:46 +07:00

85 lines
2.0 KiB
Go

// internal/utils/validator.go
package utils
import (
"regexp"
"strings"
"github.com/go-playground/validator/v10"
)
var validate *validator.Validate
// InitValidator initializes the validator
func InitValidator() {
validate = validator.New()
// Register custom validators
validate.RegisterValidation("phone", validatePhone)
validate.RegisterValidation("nrp", validateNRP)
}
// ValidateStruct validates a struct
func ValidateStruct(s interface{}) error {
if validate == nil {
InitValidator()
}
return validate.Struct(s)
}
// validatePhone validates Indonesian phone numbers
func validatePhone(fl validator.FieldLevel) bool {
phone := fl.Field().String()
if phone == "" {
return true // Allow empty (use required tag separately)
}
// Remove spaces and dashes
phone = strings.ReplaceAll(phone, " ", "")
phone = strings.ReplaceAll(phone, "-", "")
// Check if starts with 0 or +62 or 62
pattern := `^(0|\+?62)[0-9]{8,12}$`
matched, _ := regexp.MatchString(pattern, phone)
return matched
}
// validateNRP validates NRP (Nomor Registrasi Pokok)
func validateNRP(fl validator.FieldLevel) bool {
nrp := fl.Field().String()
if nrp == "" {
return true // Allow empty (use required tag separately)
}
// NRP format: 10 digits
pattern := `^[0-9]{10}$`
matched, _ := regexp.MatchString(pattern, nrp)
return matched
}
// IsValidEmail checks if email is valid
func IsValidEmail(email string) bool {
pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
matched, _ := regexp.MatchString(pattern, email)
return matched
}
// IsValidURL checks if URL is valid
func IsValidURL(url string) bool {
pattern := `^https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$`
matched, _ := regexp.MatchString(pattern, url)
return matched
}
// SanitizeString removes potentially dangerous characters
func SanitizeString(s string) string {
// Remove control characters
s = strings.Map(func(r rune) rune {
if r < 32 && r != '\n' && r != '\r' && r != '\t' {
return -1
}
return r
}, s)
return strings.TrimSpace(s)
}