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

email

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 10, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package email is the transactional-email layer for the auth surface.

Concrete implementations:

  • Stdout — writes a human-readable dump of every email to a writer. Used in tests and as the dev default when no SMTP is configured.
  • MailHog (any plain SMTP server) — used by `make dev-email` for local end-to-end testing.
  • Postmark — the prod implementation. Skeleton lives in postmark.go; full credentials wired by S35 deploy work.

Templates live alongside the auth handlers under templates/email/ and have HTML + plaintext variants. Senders MUST send both.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Branding

type Branding struct {
	SiteName string // e.g. "shithub"
	BaseURL  string // e.g. "https://shithub.example" — no trailing slash
	From     string // e.g. "shithub <noreply@shithub.example>"
}

Branding is the per-instance customization for outgoing emails.

type Message

type Message struct {
	From    string
	To      string
	Subject string
	HTML    string
	Text    string
}

Message is the unit a Sender ships. Both HTML and Text are required — every transactional email shithub sends must work in plain-text clients.

func NoticeMessage

func NoticeMessage(b Branding, to, username, kind string) (Message, error)

NoticeMessage builds a 2FA / security state-change notice for kind. The kind names match audit-log Action values where applicable.

func ResetMessage

func ResetMessage(b Branding, to, token string) (Message, error)

ResetMessage builds the password-reset message.

func SSHKeyAddedMessage

func SSHKeyAddedMessage(b Branding, to, username, title, fingerprint, ip string) (Message, error)

SSHKeyAddedMessage builds the new-key notification email. Sent on successful key add — title/fingerprint/IP help the user spot a compromise quickly.

func TokenCreatedMessage

func TokenCreatedMessage(b Branding, to, username, name, prefix, ip string) (Message, error)

TokenCreatedMessage notifies the user that a new PAT was minted on their account. Helps detect compromise — a token they didn't make is a big red flag.

func VerifyMessage

func VerifyMessage(b Branding, to, username, token string) (Message, error)

VerifyMessage builds the email-verification message.

type PostmarkSender

type PostmarkSender struct {
	ServerToken string // X-Postmark-Server-Token
	From        string // verified sender address
	HTTP        *http.Client
}

PostmarkSender posts messages to the Postmark transactional API. The integration is intentionally thin: one HTTP POST per message, no templates, no batching. Postmark's templating story stays out-of-band.

func (*PostmarkSender) Send

func (p *PostmarkSender) Send(ctx context.Context, m Message) error

Send implements Sender.

type SMTPSender

type SMTPSender struct {
	Addr     string // host:port
	From     string // default From when Message.From is empty
	Username string // optional
	Password string // optional
	UseTLS   bool   // STARTTLS upgrade after EHLO
}

SMTPSender ships messages through a plain SMTP server. Used for MailHog locally. SMTP credentials are optional (MailHog accepts none).

func (*SMTPSender) Send

func (s *SMTPSender) Send(_ context.Context, m Message) error

Send implements Sender. Builds a multipart/alternative body so MUAs can pick the variant they prefer.

The SMTP envelope sender is the bare address — `MAIL FROM:<...>` per RFC 5321 forbids nested angle brackets, so a configured `From` like `shithub <noreply@shithub.local>` only goes in the message header. The displayed-name form lives unchanged in the `From:` header inside the body.

type Sender

type Sender interface {
	Send(ctx context.Context, msg Message) error
}

Sender is the abstract interface every backend implements. Implementations MUST be safe for concurrent use.

type StdoutSender

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

StdoutSender writes a dump of every send to w. Convenient for tests (capture w to assert) and as the dev default when no real backend is configured. Implements Sender.

func NewStdoutSender

func NewStdoutSender(w io.Writer) *StdoutSender

NewStdoutSender returns a sender that writes to w. Pass os.Stdout in dev.

func (*StdoutSender) Send

func (s *StdoutSender) Send(_ context.Context, m Message) error

Send implements Sender.

Jump to

Keyboard shortcuts

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