Help us shape the future of Go! Take the 2026 Go Developer Survey

smtp

package
v1.149.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package smtp is the admin-configured mail server layer of the notification substrate: the stored connection settings, the admin API's write/read shapes with their validation, and the store that persists them with the password encrypted at rest.

It knows nothing about queues, preferences, or rendering. The send path (internal/notification/notifysend) takes a Settings value per call, so an admin change applies to the next send without a restart.

Index

Constants

View Source
const (
	// TLSModeStartTLS negotiates STARTTLS on a plaintext connection (port 587).
	TLSModeStartTLS = "starttls"
	// TLSModeImplicit opens a TLS connection directly (port 465).
	TLSModeImplicit = "implicit"
	// TLSModeNone sends in plaintext. Only for closed-network relays.
	TLSModeNone = "none"
)

SMTP TLS modes.

View Source
const PlaintextAuthWarning = "TLS is disabled (tls_mode: none) while SMTP credentials are configured; " +
	"the username and password are sent in cleartext. Use starttls or implicit unless the relay is on a closed network."

PlaintextAuthWarning is reported when SMTP credentials are configured alongside TLSModeNone: go-mail then authenticates over an unencrypted connection, putting the username and password on the wire in the clear.

View Source
const SettingsSection = "smtp"

SettingsSection is the platform_settings section key for SMTP.

Variables

View Source
var (
	// ErrNotFound is returned by the store when SMTP has never been configured.
	ErrNotFound = errors.New("notification: smtp settings not found")
	// ErrNotConfigured is returned by delivery actions when SMTP is absent,
	// disabled, or missing a host; the caller should surface it as a
	// configuration conflict, not a delivery failure.
	ErrNotConfigured = errors.New("notification: smtp is disabled or not configured")
)

Sentinel errors returned by this package.

Functions

This section is empty.

Types

type PostgresStore

type PostgresStore struct {
	// contains filtered or unexported fields
}

PostgresStore implements SettingsStore backed by the platform_settings table. Secrets inside a section value are encrypted with the injected StringEncryptor before they reach the database.

func NewPostgresStore

func NewPostgresStore(db *sql.DB, enc StringEncryptor) *PostgresStore

NewPostgresStore creates a PostgreSQL-backed settings store. The encryptor may be nil-safe (encryption disabled) but must not be nil.

func (*PostgresStore) Get

func (s *PostgresStore) Get(ctx context.Context) (*Settings, error)

Get returns the stored SMTP settings with the password decrypted.

func (*PostgresStore) Set

func (s *PostgresStore) Set(ctx context.Context, in Settings, author string) error

Set upserts the SMTP settings. An empty incoming password keeps the previously stored (still encrypted) one so the admin UI never round-trips the secret.

type Settings

type Settings struct {
	Enabled  bool   `json:"enabled"`
	Host     string `json:"host"`
	Port     int    `json:"port"`
	Username string `json:"username"`
	Password string `json:"password,omitempty"`
	// From is the sender address, e.g. "platform@example.com".
	From string `json:"from"`
	// FromName is the optional display name for the From address.
	FromName string `json:"from_name"`
	// TLSMode is one of the TLSMode* constants.
	TLSMode string `json:"tls_mode"`
	// UpdatedBy and UpdatedAt describe the last admin write.
	UpdatedBy string    `json:"updated_by,omitempty"`
	UpdatedAt time.Time `json:"updated_at"`
}

Settings is the admin-configured mail server connection. The password is encrypted at rest and never returned by the admin API.

func (*Settings) View

func (s *Settings) View() SettingsView

View maps stored settings to the password-free read shape.

type SettingsInput

type SettingsInput struct {
	Enabled  bool   `json:"enabled" example:"true"`
	Host     string `json:"host" example:"smtp.example.com"`
	Port     int    `json:"port" example:"587"`
	Username string `json:"username,omitempty" example:"mailer@example.com"`
	Password string `json:"password,omitempty" example:"app-password"`
	From     string `json:"from" example:"platform@example.com"`
	FromName string `json:"from_name,omitempty" example:"Data Platform"`
	TLSMode  string `json:"tls_mode,omitempty" example:"starttls"`
}

SettingsInput is the write shape for the admin SMTP configuration. An empty password keeps the currently stored one.

func (*SettingsInput) Settings

func (in *SettingsInput) Settings() Settings

Settings maps the validated input to store settings.

func (*SettingsInput) Validate

func (in *SettingsInput) Validate() string

Validate normalizes defaults in place and returns a non-empty message when the input is invalid. Omitted fields take defaults (port 587, STARTTLS) so a minimal `{"enabled": false}` disable call works.

type SettingsStore

type SettingsStore interface {
	// Get returns the stored SMTP settings with the password decrypted,
	// or ErrNotFound when SMTP has never been configured.
	Get(ctx context.Context) (*Settings, error)
	// Set upserts the SMTP settings, encrypting the password at rest.
	// An empty incoming password preserves the previously stored one so the
	// admin UI can stay write-only without re-sending the secret.
	Set(ctx context.Context, s Settings, author string) error
}

SettingsStore persists the admin's SMTP configuration. It is the SMTP section of the platform_settings table; another global setting would add its own contract over the same table rather than widen this one.

type SettingsView

type SettingsView struct {
	Enabled     bool      `json:"enabled" example:"true"`
	Host        string    `json:"host" example:"smtp.example.com"`
	Port        int       `json:"port" example:"587"`
	Username    string    `json:"username" example:"mailer@example.com"`
	PasswordSet bool      `json:"password_set" example:"true"`
	From        string    `json:"from" example:"platform@example.com"`
	FromName    string    `json:"from_name" example:"Data Platform"`
	TLSMode     string    `json:"tls_mode" example:"starttls"`
	UpdatedBy   string    `json:"updated_by,omitempty" example:"admin@example.com"`
	UpdatedAt   time.Time `json:"updated_at"`
	// Warnings describes accepted-but-hazardous combinations in the stored
	// configuration. They never block a save; they exist so the operator sees
	// the hazard at the surface where the setting was chosen.
	Warnings []string `json:"warnings,omitempty"`
}

SettingsView is the read shape for the admin SMTP configuration. The password is write-only: the view reports only whether one is stored.

func UnconfiguredView

func UnconfiguredView() SettingsView

UnconfiguredView is the read shape served before SMTP has ever been configured: disabled, with the transport defaults prefilled.

type StringEncryptor

type StringEncryptor interface {
	Encrypt(plaintext string) (string, error)
	Decrypt(ciphertext string) (string, error)
}

StringEncryptor encrypts and decrypts a single string secret. Satisfied by fieldcrypt.RestFieldEncryptor; a nil-safe passthrough is acceptable when encryption is disabled.

type TestEmailRequest

type TestEmailRequest struct {
	To string `json:"to" example:"admin@example.com"`
}

TestEmailRequest is the body for the admin send-test-email action.

func (*TestEmailRequest) Validate

func (r *TestEmailRequest) Validate() string

Validate returns a non-empty message when the recipient is invalid.

Jump to

Keyboard shortcuts

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