mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
119 lines
3.4 KiB
Go
119 lines
3.4 KiB
Go
package dispatch
|
|
|
|
import (
|
|
"html"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/coderd/notifications/render"
|
|
"github.com/coder/coder/v2/coderd/notifications/types"
|
|
)
|
|
|
|
func TestSMTPHTMLTemplateEscapesAppearanceHelpers(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const (
|
|
appName = `Coder"><script>alert(1)</script>`
|
|
logoURL = `https://example.com/logo.png"><img src=x onerror=alert(1)>`
|
|
)
|
|
|
|
payload := types.MessagePayload{
|
|
NotificationTemplateID: "00000000-0000-0000-0000-000000000000",
|
|
UserName: "Test User",
|
|
Labels: map[string]string{
|
|
"_subject": "Test notification",
|
|
"_body": "<p>Test body</p>",
|
|
},
|
|
}
|
|
helpers := map[string]any{
|
|
"base_url": func() string { return "https://coder.example.com" },
|
|
"current_year": func() string { return "2026" },
|
|
"logo_url": func() string { return logoURL },
|
|
"app_name": func() string { return appName },
|
|
}
|
|
|
|
got, err := render.GoTemplate(htmlTemplate, payload, helpers)
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, strings.Contains(got, html.EscapeString(appName)), "application name must be HTML escaped")
|
|
require.True(t, strings.Contains(got, html.EscapeString(logoURL)), "logo URL must be HTML escaped")
|
|
require.False(t, strings.Contains(got, appName), "raw application name must not be rendered")
|
|
require.False(t, strings.Contains(got, logoURL), "raw logo URL must not be rendered")
|
|
}
|
|
|
|
func TestValidateFromAddr(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expectedEnvelope string
|
|
expectedHeader string
|
|
expectedErrContain string
|
|
}{
|
|
{
|
|
name: "bare email address",
|
|
input: "system@coder.com",
|
|
expectedEnvelope: "system@coder.com",
|
|
expectedHeader: "system@coder.com",
|
|
},
|
|
{
|
|
name: "email with display name",
|
|
input: "Coder System <system@coder.com>",
|
|
expectedEnvelope: "system@coder.com",
|
|
expectedHeader: "Coder System <system@coder.com>",
|
|
},
|
|
{
|
|
name: "email with quoted display name",
|
|
input: `"Coder Notifications" <notifications@coder.com>`,
|
|
expectedEnvelope: "notifications@coder.com",
|
|
expectedHeader: `"Coder Notifications" <notifications@coder.com>`,
|
|
},
|
|
{
|
|
name: "email with special characters in display name",
|
|
input: `"O'Brien, John" <john@example.com>`,
|
|
expectedEnvelope: "john@example.com",
|
|
expectedHeader: `"O'Brien, John" <john@example.com>`,
|
|
},
|
|
{
|
|
name: "invalid email address",
|
|
input: "not-an-email",
|
|
expectedErrContain: "parse 'from' address",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
input: "",
|
|
expectedErrContain: "parse 'from' address",
|
|
},
|
|
{
|
|
name: "multiple addresses",
|
|
input: "a@example.com, b@example.com",
|
|
expectedErrContain: "'from' address not defined",
|
|
},
|
|
}
|
|
|
|
handler := &SMTPHandler{}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
envelope, header, err := handler.validateFromAddr(tc.input)
|
|
|
|
if tc.expectedErrContain != "" {
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, tc.expectedErrContain)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, tc.expectedEnvelope, envelope,
|
|
"envelope address should be the bare email")
|
|
require.Equal(t, tc.expectedHeader, header,
|
|
"header address should preserve the original input")
|
|
})
|
|
}
|
|
}
|