config

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package config is the typed view of the instance settings kept in the database. There is no config file: `lfr setup` writes the first values and `lfr config set` changes them, so the running server and the CLI never disagree about where configuration lives.

Index

Constants

This section is empty.

Variables

View Source
var Keys = []Key{
	{Name: "hostname", Help: "Mail host name: MX target, HELO name and PTR of the server (e.g. mail.example.com).", Check: isHost},
	{Name: "ipv4", Check: isIP(4), Help: "Public IPv4 address of the server, used in DNS records."},
	{Name: "ipv6", Check: isIP(6), Help: "Public IPv6 address of the server, used in DNS records when set."},
	{Name: "acme.email", Help: "Contact address for Let's Encrypt (expiry notices)."},
	{Name: "acme.directory", Default: "https://acme-v02.api.letsencrypt.org/directory", Help: "ACME directory URL."},
	{Name: "mta_sts.mode", Default: "testing", Check: oneOf("testing", "enforce"), Help: "MTA-STS mode published for every domain: testing only asks senders for TLS reports; enforce makes them refuse to deliver without valid TLS. Switch once lfr reports shows clean TLS reports for a few weeks."},
	{Name: "relay.url", Help: "Outbound relay, e.g. smtps://user@email-smtp.eu-central-1.amazonaws.com:2465 or smtp://user@mail.smtp2go.com:2525 (STARTTLS). Empty: deliver directly to recipients' MX on port 25."},
	{Name: "relay.password", Secret: true, Help: "Password for the relay user."},
	{Name: "relay.spf", Help: "SPF mechanism of the relay, e.g. include:amazonses.com; added to every domain's SPF record."},
	{Name: "relay.sns_topic", Help: "Amazon SNS topic whose notifications the ses webhook accepts; set by the first confirmed subscription. Clear it to subscribe a new topic."},
	{Name: "relay.rate", Default: "10", Check: isInt(1, 1000), Help: "Maximum messages per second handed to the relay or sent directly."},
	{Name: "relay.connections", Default: "2", Check: isInt(1, 16), Help: "Parallel outbound connections."},
	{Name: "smtp.max_size", Default: "20971520", Check: isInt(1<<20, 1<<30), Help: "Largest accepted inbound message in bytes."},
	{Name: "smtp.max_conns", Default: "50", Check: isInt(1, 10000), Help: "Concurrent inbound SMTP connections."},
	{Name: "smtp.max_conns_per_ip", Default: "5", Check: isInt(1, 1000), Help: "Concurrent inbound SMTP connections per IP address."},
	{Name: "smtp.rate_per_ip", Default: "30", Check: isInt(1, 100000), Help: "Inbound SMTP connections per IP address per hour."},
	{Name: "smtp.early_talker", Default: "true", Check: isBool, Help: "Drop clients that talk before the greeting (a strong spambot signal); delays each connection by 0.5 s."},
	{Name: "spam.dnsbl", Default: "zen.spamhaus.org,bl.spamcop.net,psbl.surriel.com", Help: "DNS blocklists for connecting IPs, comma separated. Spamhaus needs a DQS key when your resolver is a large public one (use <key>.zen.dq.spamhaus.net)."},
	{Name: "spam.junk", Default: "0.6", Check: isFraction, Help: "Spam probability from which mail goes to junk."},
	{Name: "spam.reject", Default: "0.98", Check: isFraction, Help: "Spam probability from which mail is refused during SMTP."},
	{Name: "web.signup_per_ip", Default: "10", Check: isInt(1, 100000), Help: "Signups accepted per IP address per hour."},
	{Name: "web.confirm_per_list", Default: "200", Check: isInt(1, 1000000), Help: "Confirmation mails per list per hour; protects against list bombing."},
	{Name: "retention.trash_days", Default: "30", Check: isInt(1, 3650), Help: "Days before trash is purged."},
	{Name: "retention.junk_days", Default: "30", Check: isInt(1, 3650), Help: "Days before junk is purged."},
	{Name: "retention.unsubscribed_days", Default: "1095", Check: isInt(30, 36500), Help: "Days after unsubscribe before member IP addresses and browser details are cleared; suppression and consent records stay."},
	{Name: "retention.events_days", Default: "400", Check: isInt(30, 36500), Help: "Days opens, clicks and delivery events are kept."},
}

Keys are every operator-facing setting, in display order.

Functions

func Names

func Names() []string

Names lists every key name, sorted.

Types

type Config

type Config struct{ DB *store.DB }

Config reads and writes settings.

func (Config) All

func (c Config) All(ctx context.Context) ([]Entry, error)

All returns every setting, secrets masked.

func (Config) Bool

func (c Config) Bool(ctx context.Context, name string) bool

Bool reads a boolean setting.

func (Config) Float

func (c Config) Float(ctx context.Context, name string) float64

Float reads a decimal setting, falling back to its default.

func (Config) Get

func (c Config) Get(ctx context.Context, name string) (string, error)

Get returns a setting or its default.

func (Config) Initialized

func (c Config) Initialized(ctx context.Context) time.Time

Initialized reports when `lfr setup` completed, zero if never.

func (Config) Int

func (c Config) Int(ctx context.Context, name string) int

Int reads a numeric setting, falling back to its default when unreadable.

func (Config) List

func (c Config) List(ctx context.Context, name string) []string

List reads a comma separated setting.

func (Config) Secret

func (c Config) Secret(ctx context.Context) ([]byte, error)

Secret returns the instance's token secret, creating it on first use.

func (Config) Set

func (c Config) Set(ctx context.Context, name, value string) error

Set validates and stores a setting; an empty value restores the default.

type Entry

type Entry struct {
	Name    string `json:"name"`
	Value   string `json:"value"`
	Default bool   `json:"default"`
	Help    string `json:"help"`
}

Entry is one setting as shown to the operator.

type Key

type Key struct {
	Name, Default, Help string
	Secret              bool                // never printed back
	Check               func(string) error  // validates a new value
	Normalize           func(string) string // optional canonical form
}

Key describes one setting an operator may change.

func Lookup

func Lookup(name string) (Key, bool)

Lookup finds a key by name.

Jump to

Keyboard shortcuts

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