email

package
v0.8.2 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package email holds what backd knows about the emails it asks a realm's delivery function to send: the kinds, the templates (loaded from <realm>/email/ into memory at startup and rendered per message), and the shape of the message handed to the function. backd never sends mail itself.

Index

Constants

View Source
const (
	VerifyEmail     = "verify-email"
	ResetPassword   = "reset-password"
	AccountExists   = "account-exists"
	PasswordChanged = "password-changed"
	Welcome         = "welcome"
	ChangeEmail     = "change-email"
	EmailChanged    = "email-changed"
	Invitation      = "invitation"
	// SecurityNotice tells the user a change to their sign-in security (a
	// second factor on or off, a password set or removed, a key created); the
	// template reads {{.Data.event}}. MFAFailed warns of wrong second-factor codes
	// after a right password.
	SecurityNotice = "security-notice"
	MFAFailed      = "mfa-failed"
	// ReauthCode carries the 6-digit code that proves a user with no password and no
	// second factor is there before a sensitive action ({{.Data.code}}, {{.ExpiresAt}}).
	ReauthCode = "reauth-code"
	// MFAReset tells a user that an administrator removed their second factor.
	MFAReset = "mfa-reset"
	// MagicLink carries the link and the 6-digit code that sign a user in
	// ({{.Link}}, {{.Data.code}}, {{.ExpiresAt}}); NoAccount tells the owner of an address with
	// no account that someone asked to sign in with it.
	MagicLink = "magic-link"
	NoAccount = "no-account"
	// ConsentUpdated asks people to review the new version of a consent
	// ({{.Data.event}} is the consent's name); it is only sent by `backd consents notify`.
	ConsentUpdated = "consent-updated"
)

The kinds of email backd sends on its own.

View Source
const (
	PageVerifyEmail        = "verify-email"
	PageResetPassword      = "reset-password"
	PageConfirmEmailChange = "confirm-email-change"
	PageRevertEmailChange  = "revert-email-change"
	PageAcceptInvitation   = "accept-invitation"
	PageResult             = "result"
	PageInvalidToken       = "invalid-token"
	// PageOAuthError is shown when a provider sends the user back with a sign-in
	// attempt backd can't trace to an app. A realm may write its own
	// (<realm>/pages/oauth-error/<locale>.html); without one the built-in English
	// page is shown. It is not among PageKinds: a realm that only sends email
	// doesn't need it.
	PageOAuthError = "oauth-error"
	// PageMagicLink is what a magic link opens: a button that signs in (Kind "confirm"), or,
	// when the request has nowhere to send the browser, the instruction to type the code in the
	// app (Kind "type-code"). Optional like PageOAuthError: the built-in English page is
	// used when a realm has none.
	PageMagicLink = "magic-link"
)

The hosted pages. The first five are the forms a link opens; Result is shown after an action succeeds, InvalidToken for any link that doesn't work.

View Source
const DirName = "email"

DirName is the folder of a realm that holds its email templates.

View Source
const PagesDirName = "pages"

PagesDirName is the folder of a realm that holds its hosted pages: the pages the links in emails open (<realm>/pages/<kind>/<locale>.html).

Variables

BuiltInKinds are system kinds a realm does not have to ship: when its email folder has none, the built-in English text is used for every listed locale, so a realm that existed before them keeps working. A folder of the kind replaces the built-in text.

View Source
var OptionalPageKinds = []string{PageOAuthError, PageMagicLink}

OptionalPageKinds are pages a realm may have in addition to PageKinds.

PageKinds are the pages every realm that sends email has, in every language it lists.

RequiredKinds must have a template in every realm that configures email.

SystemKinds are the kinds backd knows; `backd template realm` writes an English template for each.

Functions

func DefaultFiles

func DefaultFiles(kind string) (map[string][]byte, error)

DefaultFiles returns the English template files of a system kind, by file name (en.subject.txt, en.txt, en.html).

func DefaultPage

func DefaultPage(kind string) ([]byte, error)

DefaultPage returns the English template of a hosted page.

func RenderBuiltin added in v0.8.2

func RenderBuiltin(kind string, d PageData) (string, error)

RenderBuiltin renders the built-in English page of a kind.

func ValidLocale

func ValidLocale(v string) bool

ValidLocale reports whether v looks like a BCP 47 language tag (es, es-MX).

Types

type Data

type Data struct {
	Realm     string
	User      User
	Link      string
	ExpiresAt time.Time
	Data      map[string]any
}

Data is what a template can use: {{.Realm}}, {{.User.Email}}, {{.User.Locale}}, {{.Link}}, {{.ExpiresAt}} and {{.Data}}. Templates never receive text written by whoever caused the email, so backd can't be used to send someone else's words.

type Message

type Message struct {
	Subject string
	Text    string
	HTML    string
}

Message is a rendered email.

type PageData

type PageData struct {
	Realm  string
	Locale string
	Action string
	Token  string
	Error  string
	// ErrorCode names the problem in Error (password_mismatch, password_policy)
	// so a template can write it in its own words.
	ErrorCode string
	Kind      string
	// Email is the address the link is about: the new one for a change, the
	// previous one for an undo, the invited one for an invitation.
	Email string
	// Redirect and BackURL are checked against the realm's allowed_redirects
	// before they get here, so they may use an app's own scheme (acme://),
	// which html/template would otherwise refuse in a link.
	Redirect     htmltemplate.URL
	DelaySeconds int
	BackURL      htmltemplate.URL
}

PageData is what a page template can use: {{.Realm}}, {{.Locale}}, {{.Action}} (where its form posts), {{.Token}} (the hidden field), {{.Error}} and {{.ErrorCode}} (what to show on the form again), {{.Kind}} (which flow a result is for), {{.Email}} (the address the link is about), {{.Redirect}} and {{.DelaySeconds}} (where the result sends the user and when), {{.BackURL}} (a way back to the app on the error page).

type Pages

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

Pages are a realm's parsed hosted pages, held in memory.

func LoadPages

func LoadPages(dir string, locales []string) (*Pages, []error)

LoadPages reads <realm>/pages/ (dir): <kind>/<locale>.html for every kind of PageKinds and every one of locales. It parses and test-renders each page, and reports every problem together, naming the files.

func (*Pages) Has

func (p *Pages) Has(kind, locale string) bool

Has reports whether the page exists in locale.

func (*Pages) Render

func (p *Pages) Render(kind, locale string, d PageData) (string, error)

Render renders a page in locale.

type Purpose

type Purpose string

Purpose is what a token created for an email can be redeemed for.

func TokenPurpose

func TokenPurpose(kind string) Purpose

TokenPurpose returns the token an email of this kind carries, or "" when the kind has no link with a token.

func (Purpose) DefaultLifetime

func (p Purpose) DefaultLifetime() time.Duration

DefaultLifetime is how long a token of this purpose can be redeemed.

func (Purpose) LinkPath

func (p Purpose) LinkPath() string

LinkPath is the route of backd that a link of this purpose opens, under /v1/<realm>/_auth/.

type Templates

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

Templates are a realm's parsed templates, held in memory.

func Load

func Load(dir string, locales []string) (*Templates, []error)

Load reads <realm>/email/ (dir): one folder per kind, with <locale>.subject.txt, <locale>.txt and <locale>.html per locale. It parses and test-renders every template, requires the RequiredKinds, and requires every kind found to be complete in every one of locales. Problems are reported together, naming the files.

func (*Templates) Has

func (t *Templates) Has(kind, locale string) bool

Has reports whether kind has a template in locale.

func (*Templates) Kinds

func (t *Templates) Kinds() []string

Kinds lists the kinds that have templates, sorted.

func (*Templates) Render

func (t *Templates) Render(kind, locale string, d Data) (Message, error)

Render renders kind in locale.

type User

type User struct {
	Email  string
	Locale string
}

User is who a message is for.

Jump to

Keyboard shortcuts

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