Files
postmoogle/vendor/gitlab.com/etke.cc/go/validator/domains.go
2022-11-16 12:08:51 +02:00

73 lines
1.9 KiB
Go

package validator
import (
"regexp"
"strings"
"golang.org/x/net/publicsuffix"
)
// based on W3C email regex, ref: https://www.w3.org/TR/2016/REC-html51-20161101/sec-forms.html#email-state-typeemail
var domainRegex = regexp.MustCompile(`^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$`)
var privateSuffix = []string{".etke.host"}
// Domain checks if domain is valid
func (v *V) Domain(domain string) bool {
if domain == "" {
return !v.enforce.Domain
}
if !v.DomainString(domain) {
return false
}
return true
}
// DomainString checks if domain string / value is valid using string checks like length and regexp
func (v *V) DomainString(domain string) bool {
if len(domain) < 4 || len(domain) > 77 {
v.log.Info("domain %s invalid, reason: length", domain)
return false
}
if !domainRegex.MatchString(domain) {
v.log.Info("domain %s invalid, reason: regexp", domain)
return false
}
return true
}
// GetBase returns base domain/host of the provided domain
func (v *V) GetBase(domain string) string {
// domain without subdomain "example.com" has parts: example com
minSize := 2
if v.hasSuffix(domain) {
// domain with a certain TLDs contains 3 parts: example.co.uk -> example co uk
minSize = 3
}
parts := strings.Split(domain, ".")
size := len(parts)
// If domain contains only 2 parts (or less) - consider it without subdomains
if size <= minSize {
return domain
}
// return domain without subdomain (sub.example.com -> example.com; sub.example.co.uk -> example.co.uk)
return strings.Join(parts[size-minSize:], ".")
}
// hasSuffix checks if domain has a suffix from public suffix list or from predefined suffix list
func (v *V) hasSuffix(domain string) bool {
for _, suffix := range privateSuffix {
if strings.HasSuffix(domain, suffix) {
return true
}
}
eTLD, _ := publicsuffix.PublicSuffix(domain)
return strings.IndexByte(eTLD, '.') >= 0
}