diff --git a/rest/apiv1_controller.go b/rest/apiv1_controller.go index 4e1e125..5e5d543 100644 --- a/rest/apiv1_controller.go +++ b/rest/apiv1_controller.go @@ -17,7 +17,7 @@ type JSONMessageHeaderV1 struct { Mailbox string `json:"mailbox"` ID string `json:"id"` From string `json:"from"` - To string `json:"to"` + To []string `json:"to"` Subject string `json:"subject"` Date time.Time `json:"date"` Size int64 `json:"size"` @@ -28,7 +28,7 @@ type JSONMessageV1 struct { Mailbox string `json:"mailbox"` ID string `json:"id"` From string `json:"from"` - To string `json:"to"` + To []string `json:"to"` Subject string `json:"subject"` Date time.Time `json:"date"` Size int64 `json:"size"` @@ -112,7 +112,7 @@ func MailboxShowV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) Mailbox: name, ID: msg.ID(), From: msg.From(), - To: msg.To(), + To: msg.To(), Subject: msg.Subject(), Date: msg.Date(), Size: msg.Size(), diff --git a/rest/apiv1_controller_test.go b/rest/apiv1_controller_test.go index d7117ea..9297f88 100644 --- a/rest/apiv1_controller_test.go +++ b/rest/apiv1_controller_test.go @@ -95,7 +95,7 @@ func TestRestMailboxList(t *testing.T) { Mailbox: "good", ID: "0001", From: "from1", - To: "to1", + To: []string{"to1"}, Subject: "subject 1", Date: time.Date(2012, 2, 1, 10, 11, 12, 253, time.FixedZone("PST", -800)), } @@ -103,7 +103,7 @@ func TestRestMailboxList(t *testing.T) { Mailbox: "good", ID: "0002", From: "from2", - To: "to1", + To: []string{"to1"}, Subject: "subject 2", Date: time.Date(2012, 7, 1, 10, 11, 12, 253, time.FixedZone("PDT", -700)), } diff --git a/rest/testmocks_test.go b/rest/testmocks_test.go index a4ce88d..30a46bf 100644 --- a/rest/testmocks_test.go +++ b/rest/testmocks_test.go @@ -70,9 +70,9 @@ func (m *MockMessage) From() string { return args.String(0) } -func (m *MockMessage) To() string { +func (m *MockMessage) To() []string { args := m.Called() - return args.String(0) + return args.Get(0).([]string) } func (m *MockMessage) Date() time.Time { diff --git a/rest/testutils_test.go b/rest/testutils_test.go index b4bd701..3d4f86d 100644 --- a/rest/testutils_test.go +++ b/rest/testutils_test.go @@ -17,7 +17,7 @@ import ( type InputMessageData struct { Mailbox, ID, From, Subject string - To string + To []string Date time.Time Size int Header mail.Header @@ -81,8 +81,10 @@ func (d *InputMessageData) CompareToJSONHeaderMap(json interface{}) (errors []st if msg, ok := isJSONStringEqual(fromKey, d.From, m[fromKey]); !ok { errors = append(errors, msg) } - if msg, ok := isJSONStringEqual(toKey, d.To, m[toKey]); !ok { - errors = append(errors, msg) + for i, inputTo := range d.To { + if msg, ok := isJSONStringEqual(toKey, inputTo, m[toKey].([]interface{})[i]); !ok { + errors = append(errors, msg) + } } if msg, ok := isJSONStringEqual(subjectKey, d.Subject, m[subjectKey]); !ok { errors = append(errors, msg) diff --git a/smtpd/datastore.go b/smtpd/datastore.go index a483852..746be78 100644 --- a/smtpd/datastore.go +++ b/smtpd/datastore.go @@ -36,7 +36,7 @@ type Mailbox interface { type Message interface { ID() string From() string - To() string + To() []string Date() time.Time Subject() string RawReader() (reader io.ReadCloser, err error) diff --git a/smtpd/filestore.go b/smtpd/filestore.go index 81e3385..b40869f 100644 --- a/smtpd/filestore.go +++ b/smtpd/filestore.go @@ -295,7 +295,7 @@ type FileMessage struct { Fid string Fdate time.Time Ffrom string - Fto string + Fto []string Fsubject string Fsize int64 // These are for creating new messages only @@ -345,7 +345,7 @@ func (m *FileMessage) From() string { } // From returns the value of the Message To header -func (m *FileMessage) To() string { +func (m *FileMessage) To() []string { return m.Fto } @@ -490,11 +490,24 @@ func (m *FileMessage) Close() error { return err } - // Only public fields are stored in gob - m.Ffrom = body.GetHeader("From") - m.Fto = body.GetHeader("To") + // Only public fields are stored in gob, hence starting with capital F + // Parse From address + if address, err := mail.ParseAddress(body.GetHeader("From")); err == nil { + m.Ffrom = address.String() + } else { + m.Ffrom = body.GetHeader("From") + } m.Fsubject = body.GetHeader("Subject") + // Turn the To header into a slice + if addresses, err := body.AddressList("To"); err == nil { + for _, a := range addresses { + m.Fto = append(m.Fto, a.String()) + } + } else { + m.Fto = []string{body.GetHeader("To")} + } + // Refresh the index before adding our message err = m.mailbox.readIndex() if err != nil { diff --git a/smtpd/retention_test.go b/smtpd/retention_test.go index b7eeb16..1344498 100644 --- a/smtpd/retention_test.go +++ b/smtpd/retention_test.go @@ -126,9 +126,9 @@ func (m *MockMessage) From() string { return args.String(0) } -func (m *MockMessage) To() string { +func (m *MockMessage) To() []string { args := m.Called() - return args.String(0) + return args.Get(0).([]string) } func (m *MockMessage) Date() time.Time { diff --git a/swaks-tests/run-tests.sh b/swaks-tests/run-tests.sh index e747dde..f7c3564 100755 --- a/swaks-tests/run-tests.sh +++ b/swaks-tests/run-tests.sh @@ -31,7 +31,7 @@ export SWAKS_OPT_to="$to@inbucket.local" swaks $* --h-Subject: "Swaks Plain Text" --body text.txt # Multi-recipient test -swaks $* --to="$to@inbucket.local,alternate@inbucket.local" --h-Subject: "Swaks Multi-Recipient" \ +swaks $* --to="$to@inbucket.local,Alt User " --h-Subject: "Swaks Multi-Recipient" \ --body text.txt # HTML test diff --git a/themes/bootstrap/templates/mailbox/_show.html b/themes/bootstrap/templates/mailbox/_show.html index ada6fd8..474e0cf 100644 --- a/themes/bootstrap/templates/mailbox/_show.html +++ b/themes/bootstrap/templates/mailbox/_show.html @@ -53,7 +53,12 @@
From:
{{.message.From}}
To:
-
{{.message.To}}
+
+ {{range $i, $addr := .message.To}} + {{- if $i}},{{end}} + {{$addr -}} + {{end}} +
Date:
{{.message.Date}}
Subject:
diff --git a/themes/bootstrap/templates/mailbox/index.html b/themes/bootstrap/templates/mailbox/index.html index 6644fd4..2059562 100644 --- a/themes/bootstrap/templates/mailbox/index.html +++ b/themes/bootstrap/templates/mailbox/index.html @@ -15,9 +15,9 @@ $(document).ready(function() {