Documentation
¶
Overview ¶
Package email is the platform's one email-sending capability: a narrow Sender interface plus SMTP and SES implementations, shared by internal/alerting and internal/api so neither imports the other.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotConfigured = errors.New("email: not configured")
ErrNotConfigured is returned by NewSender when a Config names no backend: no settings row and no env-var fallback.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
Backend Backend
SMTP *SMTPConfig
SES *SESConfig
}
Config names which backend to use plus that backend's own settings.
type ConfigLoader ¶
ConfigLoader resolves the current Config on every call, never cached: settings can change at runtime.
type DynamicSender ¶
type DynamicSender struct {
// contains filtered or unexported fields
}
DynamicSender adapts a ConfigLoader into a Sender, so a settings change takes effect on the very next send with no restart required.
func NewDynamicSender ¶
func NewDynamicSender(load ConfigLoader) *DynamicSender
NewDynamicSender builds a DynamicSender. load must not be nil.
func (*DynamicSender) Send ¶
func (d *DynamicSender) Send(ctx context.Context, to, subject, body string) error
Send implements Sender. Every caller (invite emails, password resets, deploy/alert notifications) ultimately funnels through here regardless of backend, so this is the one place that rejects a CR or LF in to or subject: smtpSender.Send builds a raw "To: %s\r\nSubject: %s\r\n..." header block via fmt.Sprintf, and neither to (an operator-entered invite/user email, internal/api/invites.go and users.go do no format validation) nor subject is otherwise guaranteed free of \r\n, which would otherwise inject arbitrary extra headers (a Bcc:, for example) into the outgoing message.