Fix email local part validation per RFC 5321

- Remove dots from character class (handled separately)
- Check username doesn't start/end with dot
- Check for no consecutive dots (..)
- Valid chars: a-zA-Z0-9!#$%&'*+-/=?^_`{|}~-
This commit is contained in:
Christoph Haas 2026-03-23 00:16:15 +01:00
parent f9ddfa869e
commit 16b6d9df60

View file

@ -263,7 +263,7 @@ func (h *UserHandler) ListAll(c *gin.Context) {
Success(c, users)
}
var emailLocalPartRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\-/=?^_`{|}~-]+$")
var emailLocalPartRegex = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~-]+$")
func validateEmailLocalPart(email string) error {
parts := strings.Split(email, "@")
@ -276,8 +276,19 @@ func validateEmailLocalPart(email string) error {
return &ValidationError{Message: "username must be between 1 and 64 characters"}
}
// RFC 5321: local-part cannot start or end with a dot
if strings.HasPrefix(localPart, ".") || strings.HasSuffix(localPart, ".") {
return &ValidationError{Message: "username cannot start or end with a dot"}
}
// RFC 5321: local-part cannot contain consecutive dots
if strings.Contains(localPart, "..") {
return &ValidationError{Message: "username cannot contain consecutive dots"}
}
// Check valid characters (RFC 5321: letters, digits, and special chars !#$%&'*+/=?^_`{|}~-)
if !emailLocalPartRegex.MatchString(localPart) {
return &ValidationError{Message: "username can only contain letters, numbers, and common special characters"}
return &ValidationError{Message: "username contains invalid characters"}
}
return nil