package email import ( "io" "mime" "net/mail" "strings" "testing" ) func TestBuildMessageIsRFC5322(t *testing.T) { raw := buildMessage("panel@example.com", "3x-ui", []string{"a@example.com", "b@example.com"}, "Тест", "hi") msg, err := mail.ReadMessage(strings.NewReader(string(raw))) if err != nil { t.Fatalf("message does not parse as RFC 5322: %v", err) } from, err := mail.ParseAddress(msg.Header.Get("From")) if err != nil { t.Fatalf("From header does not parse: %v", err) } if from.Name != "3x-ui" || from.Address != "panel@example.com" { t.Errorf("From = %q <%q>, want name %q addr %q", from.Name, from.Address, "3x-ui", "panel@example.com") } if _, err := msg.Header.Date(); err != nil { t.Errorf("Date header missing or unparseable: %v", err) } id := msg.Header.Get("Message-ID") if !strings.HasPrefix(id, "<") || !strings.HasSuffix(id, "@example.com>") { t.Errorf("Message-ID = %q, want ", id) } subject, err := (&mime.WordDecoder{}).DecodeHeader(msg.Header.Get("Subject")) if err != nil { t.Fatalf("Subject does not decode: %v", err) } if subject != "Тест" { t.Errorf("Subject = %q, want %q", subject, "Тест") } body, _ := io.ReadAll(msg.Body) if string(body) != "hi" { t.Errorf("body = %q, want %q", body, "hi") } } func TestBuildMessageFromWithoutName(t *testing.T) { raw := buildMessage("panel@example.com", "", []string{"a@example.com"}, "s", "b") msg, err := mail.ReadMessage(strings.NewReader(string(raw))) if err != nil { t.Fatalf("parse: %v", err) } from, err := mail.ParseAddress(msg.Header.Get("From")) if err != nil { t.Fatalf("From header does not parse: %v", err) } if from.Name != "" || from.Address != "panel@example.com" { t.Errorf("From = %q <%q>, want bare addr", from.Name, from.Address) } } func TestBuildMessageStripsHeaderInjection(t *testing.T) { raw := buildMessage( "panel@example.com\r\nBcc: evil@example.com", "Name\r\nX-Evil: 1", []string{"a@example.com"}, "s", "b", ) msg, err := mail.ReadMessage(strings.NewReader(string(raw))) if err != nil { t.Fatalf("parse: %v", err) } if got := msg.Header.Get("Bcc"); got != "" { t.Errorf("injected Bcc header leaked: %q", got) } if got := msg.Header.Get("X-Evil"); got != "" { t.Errorf("injected X-Evil header leaked: %q", got) } }