- Add comprehensive root README with badges, architecture diagram, and setup guide - Update backend README with security middlewares and endpoint documentation - Update frontend README with design system and page structure - Update seeder-api README with generated data and credentials - Add internal module READMEs (middleware, handlers, components) - Document Clean Architecture layers and request flow - Add environment variables reference table
89 lines
2.3 KiB
Go
89 lines
2.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"html"
|
|
"regexp"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// Sanitizer provides input sanitization utilities
|
|
type Sanitizer struct {
|
|
// Max lengths for common fields
|
|
MaxNameLength int
|
|
MaxDescriptionLength int
|
|
MaxEmailLength int
|
|
}
|
|
|
|
// DefaultSanitizer returns a sanitizer with default settings
|
|
func DefaultSanitizer() *Sanitizer {
|
|
return &Sanitizer{
|
|
MaxNameLength: 255,
|
|
MaxDescriptionLength: 10000,
|
|
MaxEmailLength: 320,
|
|
}
|
|
}
|
|
|
|
// SanitizeString escapes HTML and trims whitespace
|
|
func (s *Sanitizer) SanitizeString(input string) string {
|
|
if input == "" {
|
|
return ""
|
|
}
|
|
// Trim whitespace
|
|
result := strings.TrimSpace(input)
|
|
// Escape HTML entities to prevent XSS
|
|
result = html.EscapeString(result)
|
|
return result
|
|
}
|
|
|
|
// SanitizeName sanitizes a name field
|
|
func (s *Sanitizer) SanitizeName(input string) string {
|
|
sanitized := s.SanitizeString(input)
|
|
if utf8.RuneCountInString(sanitized) > s.MaxNameLength {
|
|
runes := []rune(sanitized)
|
|
sanitized = string(runes[:s.MaxNameLength])
|
|
}
|
|
return sanitized
|
|
}
|
|
|
|
// SanitizeEmail sanitizes and validates email format
|
|
func (s *Sanitizer) SanitizeEmail(input string) string {
|
|
sanitized := strings.TrimSpace(strings.ToLower(input))
|
|
if utf8.RuneCountInString(sanitized) > s.MaxEmailLength {
|
|
return ""
|
|
}
|
|
return sanitized
|
|
}
|
|
|
|
// SanitizeDescription sanitizes long text fields
|
|
func (s *Sanitizer) SanitizeDescription(input string) string {
|
|
sanitized := s.SanitizeString(input)
|
|
if utf8.RuneCountInString(sanitized) > s.MaxDescriptionLength {
|
|
runes := []rune(sanitized)
|
|
sanitized = string(runes[:s.MaxDescriptionLength])
|
|
}
|
|
return sanitized
|
|
}
|
|
|
|
// SanitizeSlug creates a URL-safe slug
|
|
func (s *Sanitizer) SanitizeSlug(input string) string {
|
|
// Convert to lowercase
|
|
result := strings.ToLower(strings.TrimSpace(input))
|
|
// Replace spaces with hyphens
|
|
result = strings.ReplaceAll(result, " ", "-")
|
|
// Remove non-alphanumeric characters except hyphens
|
|
reg := regexp.MustCompile(`[^a-z0-9-]`)
|
|
result = reg.ReplaceAllString(result, "")
|
|
// Remove multiple consecutive hyphens
|
|
reg = regexp.MustCompile(`-+`)
|
|
result = reg.ReplaceAllString(result, "-")
|
|
// Trim hyphens from ends
|
|
result = strings.Trim(result, "-")
|
|
return result
|
|
}
|
|
|
|
// StripHTML removes all HTML tags from input
|
|
func StripHTML(input string) string {
|
|
reg := regexp.MustCompile(`<[^>]*>`)
|
|
return reg.ReplaceAllString(input, "")
|
|
}
|