Documentation
¶
Overview ¶
Package web serves everything lfr shows to readers: each list's small site (latest issues, archive, feed, signup form), the confirm and unsubscribe pages, click and open tracking, MTA-STS policies and relay webhooks. There is no admin interface; operators use the CLI.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrLimited = errors.New("too many signups")
ErrLimited is returned by Signup when a list sends too many confirmations.
var Pages = []string{"home", "archive", "issue", "message"}
Pages a site renders; each is its own template set.
Functions ¶
func FromCloudflare ¶
FromCloudflare reports whether a remote address ("ip:port") is a Cloudflare edge.
Types ¶
type Server ¶
type Server struct {
DB *store.DB
Lists *lists.Service
Issues *issues.Service
Renderer *issues.Renderer
Tokens *token.Signer
Events *events.Bus
Config config.Config
Sites *Sites
Now func() time.Time
Log *slog.Logger
MailHost func(ctx context.Context) string
MTASTS func(ctx context.Context, domain string) (string, bool) // policy text when lfr serves domain
Signup func(ctx context.Context, l *lists.List, email string, s lists.Signup) error
Feedback func(ctx context.Context, evs []feedback.Event)
SNSClient *http.Client // fetches SNS certificates and confirms subscriptions
// SNSTopic accepts the topic of a verified SNS message: the first one
// confirmed is remembered, later ones must match it.
SNSTopic func(ctx context.Context, arn string, confirm bool) bool
// contains filtered or unexported fields
}
Server is the HTTP handler.
type Sites ¶
type Sites struct {
Dir string
// contains filtered or unexported fields
}
Sites loads the templates of each list: the embedded defaults, with any file of the same name in <dir>/<list-slug>/ taking its place. custom.html there is added to every page (to redefine "style", for example), and email.html replaces the email layout. Edits are picked up within seconds.
func (*Sites) Asset ¶
Asset resolves a file under a list's assets directory, refusing paths that escape it.