mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
webui, rest: Render UTF-8 addresses correctly, fixes #117
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
Date: %DATE%
|
||||
To: %TO_ADDRESS%
|
||||
From: %FROM_ADDRESS%
|
||||
To: %TO_ADDRESS%,
|
||||
=?utf-8?B?VGVzdCBvZiDIh8myyqLIr8ihyarJtMqb?= <recipient@inbucket.org>
|
||||
From: =?utf-8?q?X-=C3=A4=C3=A9=C3=9F_Y-=C3=A4=C3=A9=C3=9F?=
|
||||
<fromuser@inbucket.org>
|
||||
Subject: =?utf-8?B?VGVzdCBvZiDIh8myyqLIr8ihyarJtMqb?=
|
||||
Thread-Topic: =?utf-8?B?VGVzdCBvZiDIh8myyqLIr8ihyarJtMqb?=
|
||||
Thread-Index: Ac6+4nH7mOymA+1JRQyk2LQPe1bEcw==
|
||||
|
||||
@@ -33,7 +33,7 @@ func MailboxListV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (
|
||||
jmessages[i] = &model.JSONMessageHeaderV1{
|
||||
Mailbox: name,
|
||||
ID: msg.ID,
|
||||
From: msg.From.String(),
|
||||
From: stringutil.StringAddress(msg.From),
|
||||
To: stringutil.StringAddressList(msg.To),
|
||||
Subject: msg.Subject,
|
||||
Date: msg.Date,
|
||||
@@ -79,7 +79,7 @@ func MailboxShowV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (
|
||||
&model.JSONMessageV1{
|
||||
Mailbox: name,
|
||||
ID: msg.ID,
|
||||
From: msg.From.String(),
|
||||
From: stringutil.StringAddress(msg.From),
|
||||
To: stringutil.StringAddressList(msg.To),
|
||||
Subject: msg.Subject,
|
||||
Date: msg.Date,
|
||||
|
||||
@@ -8,11 +8,13 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jhillyerd/inbucket/pkg/stringutil"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// TemplateFuncs declares functions made available to all templates (including partials)
|
||||
var TemplateFuncs = template.FuncMap{
|
||||
"address": stringutil.StringAddress,
|
||||
"friendlyTime": FriendlyTime,
|
||||
"reverse": Reverse,
|
||||
"stringsJoin": strings.Join,
|
||||
|
||||
@@ -19,13 +19,28 @@ func HashMailboxName(mailbox string) string {
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
// StringAddressList converts a list of addresses to a list of strings
|
||||
// StringAddress converts an Address to a UTF-8 string.
|
||||
func StringAddress(a *mail.Address) string {
|
||||
b := &strings.Builder{}
|
||||
if a != nil {
|
||||
if a.Name != "" {
|
||||
b.WriteString(a.Name)
|
||||
b.WriteRune(' ')
|
||||
}
|
||||
if a.Address != "" {
|
||||
b.WriteRune('<')
|
||||
b.WriteString(a.Address)
|
||||
b.WriteRune('>')
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// StringAddressList converts a list of addresses to a list of UTF-8 strings.
|
||||
func StringAddressList(addrs []*mail.Address) []string {
|
||||
s := make([]string, len(addrs))
|
||||
for i, a := range addrs {
|
||||
if a != nil {
|
||||
s[i] = a.String()
|
||||
}
|
||||
s[i] = StringAddress(a)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -17,10 +17,14 @@ func TestHashMailboxName(t *testing.T) {
|
||||
|
||||
func TestStringAddressList(t *testing.T) {
|
||||
input := []*mail.Address{
|
||||
{Name: "Fred B. Fish", Address: "fred@fish.org"},
|
||||
{Name: "Fred ß. Fish", Address: "fred@fish.org"},
|
||||
{Name: "User", Address: "user@domain.org"},
|
||||
{Address: "a@b.com"},
|
||||
}
|
||||
want := []string{`"Fred B. Fish" <fred@fish.org>`, `"User" <user@domain.org>`}
|
||||
want := []string{
|
||||
`Fred ß. Fish <fred@fish.org>`,
|
||||
`User <user@domain.org>`,
|
||||
`<a@b.com>`}
|
||||
output := stringutil.StringAddressList(input)
|
||||
if len(output) != len(want) {
|
||||
t.Fatalf("Got %v strings, want: %v", len(output), len(want))
|
||||
|
||||
@@ -44,6 +44,7 @@ func TestSuite(t *testing.T) {
|
||||
}{
|
||||
{"basic", testBasic},
|
||||
{"fullname", testFullname},
|
||||
{"encodedHeader", testEncodedHeader},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, tc.test)
|
||||
@@ -59,13 +60,13 @@ func testBasic(t *testing.T) {
|
||||
to := []string{"recipient@inbucket.org"}
|
||||
input := readTestData("basic.txt")
|
||||
|
||||
// Send mail
|
||||
// Send mail.
|
||||
err = smtpclient.SendMail(smtpHost, nil, from, to, input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Confirm receipt
|
||||
// Confirm receipt.
|
||||
msg, err := client.GetMessage("recipient", "latest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -88,13 +89,13 @@ func testFullname(t *testing.T) {
|
||||
to := []string{"recipient@inbucket.org"}
|
||||
input := readTestData("fullname.txt")
|
||||
|
||||
// Send mail
|
||||
// Send mail.
|
||||
err = smtpclient.SendMail(smtpHost, nil, from, to, input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Confirm receipt
|
||||
// Confirm receipt.
|
||||
msg, err := client.GetMessage("recipient", "latest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -108,6 +109,35 @@ func testFullname(t *testing.T) {
|
||||
goldiff.File(t, got, "testdata", "fullname.golden")
|
||||
}
|
||||
|
||||
func testEncodedHeader(t *testing.T) {
|
||||
client, err := client.New(restBaseURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
from := "fromuser@inbucket.org"
|
||||
to := []string{"recipient@inbucket.org"}
|
||||
input := readTestData("encodedheader.txt")
|
||||
|
||||
// Send mail.
|
||||
err = smtpclient.SendMail(smtpHost, nil, from, to, input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Confirm receipt.
|
||||
msg, err := client.GetMessage("recipient", "latest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if msg == nil {
|
||||
t.Errorf("Got nil message, wanted non-nil message.")
|
||||
}
|
||||
|
||||
// Compare to golden.
|
||||
got := formatMessage(msg)
|
||||
goldiff.File(t, got, "testdata", "encodedheader.golden")
|
||||
}
|
||||
|
||||
func formatMessage(m *client.Message) []byte {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "Mailbox: %v\n", m.Mailbox)
|
||||
|
||||
12
pkg/test/testdata/encodedheader.golden
vendored
Normal file
12
pkg/test/testdata/encodedheader.golden
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Mailbox: recipient
|
||||
From: X-äéß Y-äéß <fromuser@inbucket.org>
|
||||
To: [Test of ȇɲʢȯȡɪɴʛ <recipient@inbucket.org>]
|
||||
Subject: Test of ȇɲʢȯȡɪɴʛ
|
||||
Size: 351
|
||||
|
||||
BODY TEXT:
|
||||
Basic message.
|
||||
|
||||
|
||||
BODY HTML:
|
||||
|
||||
5
pkg/test/testdata/encodedheader.txt
vendored
Normal file
5
pkg/test/testdata/encodedheader.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
From: =?utf-8?q?X-=C3=A4=C3=A9=C3=9F_Y-=C3=A4=C3=A9=C3=9F?= <fromuser@inbucket.org>
|
||||
To: =?utf-8?B?VGVzdCBvZiDIh8myyqLIr8ihyarJtMqb?= <recipient@inbucket.org>
|
||||
Subject: =?utf-8?b?VGVzdCBvZiDIh8myyqLIr8ihyarJtMqb?=
|
||||
|
||||
Basic message.
|
||||
4
pkg/test/testdata/fullname.golden
vendored
4
pkg/test/testdata/fullname.golden
vendored
@@ -1,6 +1,6 @@
|
||||
Mailbox: recipient
|
||||
From: "From User" <fromuser@inbucket.org>
|
||||
To: ["Rec I. Pient" <recipient@inbucket.org>]
|
||||
From: From User <fromuser@inbucket.org>
|
||||
To: [Rec I. Pient <recipient@inbucket.org>]
|
||||
Subject: basic subject
|
||||
Size: 246
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>From:</dt>
|
||||
<dd>{{.message.From}}</dd>
|
||||
<dd>{{.message.From | address}}</dd>
|
||||
<dt>To:</dt>
|
||||
<dd>
|
||||
{{range $i, $addr := .message.To}}
|
||||
{{- if $i}},{{end}}
|
||||
{{$addr -}}
|
||||
{{$addr | address -}}
|
||||
{{end}}
|
||||
</dd>
|
||||
<dt>Date:</dt>
|
||||
|
||||
Reference in New Issue
Block a user