mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
This patch adds a missing docstrings for exported identifiers, and adjust some of the existing ones to match the standard style. In some cases, the identifiers were un-exported after noticing they had no external users. Besides improving documentation, it also reduces the linter noise significantly.
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
// Package normalize contains functions to normalize usernames, domains and
|
|
// addresses.
|
|
package normalize
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"blitiri.com.ar/go/chasquid/internal/envelope"
|
|
"golang.org/x/net/idna"
|
|
"golang.org/x/text/secure/precis"
|
|
"golang.org/x/text/unicode/norm"
|
|
)
|
|
|
|
// User normalizes an username using PRECIS.
|
|
// On error, it will also return the original username to simplify callers.
|
|
func User(user string) (string, error) {
|
|
norm, err := precis.UsernameCaseMapped.String(user)
|
|
if err != nil {
|
|
return user, err
|
|
}
|
|
|
|
return norm, nil
|
|
}
|
|
|
|
// Domain normalizes a DNS domain into a cleaned UTF-8 form.
|
|
// On error, it will also return the original domain to simplify callers.
|
|
func Domain(domain string) (string, error) {
|
|
// For now, we just convert them to lower case and make sure it's in NFC
|
|
// form for consistency.
|
|
// There are other possible transformations (like nameprep) but for our
|
|
// purposes these should be enough.
|
|
// https://tools.ietf.org/html/rfc5891#section-5.2
|
|
// https://blog.golang.org/normalization
|
|
d, err := idna.ToUnicode(domain)
|
|
if err != nil {
|
|
return domain, err
|
|
}
|
|
|
|
d = norm.NFC.String(d)
|
|
d = strings.ToLower(d)
|
|
return d, nil
|
|
}
|
|
|
|
// Addr normalizes an email address, applying User and Domain to its
|
|
// respective components.
|
|
// On error, it will also return the original address to simplify callers.
|
|
func Addr(addr string) (string, error) {
|
|
user, domain := envelope.Split(addr)
|
|
|
|
user, err := User(user)
|
|
if err != nil {
|
|
return addr, err
|
|
}
|
|
|
|
domain, err = Domain(domain)
|
|
if err != nil {
|
|
return addr, err
|
|
}
|
|
|
|
return user + "@" + domain, nil
|
|
}
|
|
|
|
// DomainToUnicode takes an address with an ASCII domain, and convert it to
|
|
// Unicode as per IDNA, including basic normalization.
|
|
// The user part is unchanged.
|
|
func DomainToUnicode(addr string) (string, error) {
|
|
if addr == "<>" {
|
|
return addr, nil
|
|
}
|
|
user, domain := envelope.Split(addr)
|
|
|
|
domain, err := Domain(domain)
|
|
return user + "@" + domain, err
|
|
}
|