Files
crimson-vault/internal/api/validator.go
T

71 lines
1.8 KiB
Go

package api
import (
"fmt"
"net/http"
"regexp"
"github.com/go-playground/validator/v10"
"github.com/hazemKrimi/crimson-vault/internal/types"
)
type CustomValidator struct {
validator *validator.Validate
}
func (v *CustomValidator) Validate(i any) error {
if err := v.validator.Struct(i); err != nil {
if validationErrors, ok := err.(validator.ValidationErrors); ok {
errors := make([]string, 0, 10)
for _, ve := range validationErrors {
field := ve.Field()
tag := ve.Tag()
var msg string
switch tag {
case "required":
msg = fmt.Sprintf("%s is required!", field)
case "email":
msg = fmt.Sprintf("%s must be a valid email!", field)
case "alpha":
msg = fmt.Sprintf("%s must only contain alphabetic characters!", field)
case "e164":
msg = fmt.Sprintf("%s must be a valid phone number in e164 format!", field)
case "password":
msg = fmt.Sprintf("%s must have at lease one uppercase, one lowercase, one number and one special character!", field)
case "eqcsfield":
msg = fmt.Sprintf("%s must be the same as %s!", field, ve.Param())
default:
msg = fmt.Sprintf("%s is not valid!", field)
}
errors = append(errors, msg)
}
return types.Error{Code: http.StatusBadRequest, Messages: errors}
}
}
return nil
}
func PasswordValidator(fieldLevel validator.FieldLevel) bool {
password := fieldLevel.Field().String()
var (
upper = regexp.MustCompile(`[A-Z]`)
lower = regexp.MustCompile(`[a-z]`)
number = regexp.MustCompile(`[0-9]`)
special = regexp.MustCompile(`[!@#~$%^&*()+|_{}:<>?,./;'\[\]\\-]`)
minChars = 8
)
return len(password) >= minChars &&
upper.MatchString(password) &&
lower.MatchString(password) &&
number.MatchString(password) &&
special.MatchString(password)
}