subaddressing support, closes #61

This commit is contained in:
Aine
2023-09-25 23:20:17 +03:00
parent 18f1113d33
commit 6be4891165
14 changed files with 519 additions and 16 deletions

View File

@@ -1,14 +1,56 @@
package utils
import "strings"
import (
"strings"
"github.com/mcnijman/go-emailaddress"
)
// Mailbox returns mailbox part from email address
func Mailbox(email string) string {
index := strings.LastIndex(email, "@")
if index == -1 {
return email
mailbox, _, _ := EmailParts(email)
return mailbox
}
// Subaddress returns sub address part form email address
func Subaddress(email string) string {
_, sub, _ := EmailParts(email)
return sub
}
// Hostname returns hostname part from email address
func Hostname(email string) string {
_, _, hostname := EmailParts(email)
return hostname
}
// EmailParts parses email address into mailbox, subaddress, and hostname
func EmailParts(email string) (string, string, string) {
var mailbox, hostname string
address, err := emailaddress.Parse(email)
if err == nil {
mailbox = address.LocalPart
hostname = address.Domain
} else {
mailbox = email
hostname = email
mIdx := strings.Index(email, "@")
hIdx := strings.LastIndex(email, "@")
if mIdx != -1 {
mailbox = email[:mIdx]
}
if hIdx != -1 {
hostname = email[hIdx+1:]
}
}
return email[:index]
var sub string
idx := strings.Index(mailbox, "+")
if idx != -1 {
sub = strings.ReplaceAll(mailbox[idx:], "+", "")
mailbox = strings.ReplaceAll(mailbox[:idx], "+", "")
}
return mailbox, sub, hostname
}
// EmailsList returns human-readable list of mailbox's emails for all available domains
@@ -34,8 +76,3 @@ func EmailsList(mailbox string, domain string) string {
return msg.String()
}
// Hostname returns hostname part from email address
func Hostname(email string) string {
return email[strings.LastIndex(email, "@")+1:]
}

70
utils/mail_test.go Normal file
View File

@@ -0,0 +1,70 @@
package utils
import "testing"
func TestMailbox(t *testing.T) {
tests := map[string]string{
"mailbox@example.com": "mailbox",
"mail-box@example.com": "mail-box",
"mailbox": "mailbox",
"mail@box@example.com": "mail",
"mailbox+@example.com": "mailbox",
"mailbox+sub@example.com": "mailbox",
"mailbox+++sub@example.com": "mailbox",
}
for in, expected := range tests {
t.Run(in, func(t *testing.T) {
output := Mailbox(in)
if output != expected {
t.Error(expected, "!=", output)
}
})
}
}
func TestSubaddress(t *testing.T) {
tests := map[string]string{
"mailbox@example@example.com": "",
"mail-box@example.com": "",
"mailbox+": "",
"mailbox+sub@example.com": "sub",
"mailbox+++sub@example.com": "sub",
}
for in, expected := range tests {
t.Run(in, func(t *testing.T) {
output := Subaddress(in)
if output != expected {
t.Error(expected, "!=", output)
}
})
}
}
func TestHostname(t *testing.T) {
tests := map[string]string{
"mailbox@example.com": "example.com",
"mailbox": "mailbox",
"mail@box@example.com": "example.com",
}
for in, expected := range tests {
t.Run(in, func(t *testing.T) {
output := Hostname(in)
if output != expected {
t.Error(expected, "!=", output)
}
})
}
}
func TestEmailList(t *testing.T) {
domains = []string{"example.com", "example.org"}
expected := "test@example.org, test@example.com"
actual := EmailsList("test", "example.org")
if actual != expected {
t.Error(expected, "!=", actual)
}
}