email

package
v0.2.0-beta.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

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

View Source
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 Backend

type Backend string

Backend names which transport a Config uses to actually send.

const (
	BackendSMTP Backend = "smtp"
	BackendSES  Backend = "ses"
)

The two backends NewSender supports.

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

type ConfigLoader func(ctx context.Context) (Config, error)

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.

type SESConfig

type SESConfig struct {
	Region          string
	AccessKeyID     string
	SecretAccessKey string
	From            string
}

SESConfig is an AWS SES v2 sender's connection details.

type SMTPConfig

type SMTPConfig struct {
	// Addr is host:port, e.g. "smtp.example.com:587".
	Addr     string
	Host     string // just the host part of Addr, for PlainAuth's identity check
	Username string
	Password string
	From     string
}

SMTPConfig is an SMTP server's connection details.

type Sender

type Sender interface {
	Send(ctx context.Context, to, subject, body string) error
}

Sender sends one plain-text email.

func NewSender

func NewSender(cfg Config) (Sender, error)

NewSender builds the Sender cfg.Backend names, or ErrNotConfigured for an empty or unrecognized Backend.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL