email

package
v0.60.0 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: AGPL-3.0 Imports: 32 Imported by: 0

Documentation

Index

Constants

View Source
const InputSchemaJSON = `` /* 4453-byte string literal not displayed */
View Source
const ToolName = "email"

Variables

View Source
var ErrMessageNotFound = errors.New("message not found")

Functions

func DialPublicTCP added in v0.43.0

func DialPublicTCP(ctx context.Context, kind, host string, port int) (net.Conn, error)

func Dispatch added in v0.60.0

func Dispatch(ctx context.Context, h Handler, action string, args map[string]any) (any, error)

func Folders

func Folders(acct EmailAccount) ([]string, error)

Folders returns a sorted list of mailbox names available on the server.

func FormatDryRun

func FormatDryRun(acct EmailAccount, opts SendOptions) string

FormatDryRun returns a human-readable representation of the email that would be sent, for use with --dry-run.

func InputSchema added in v0.60.0

func InputSchema() map[string]any

func MarkSeen added in v0.26.0

func MarkSeen(acct EmailAccount, folder string, uid uint32, seen bool) error

MarkSeen adds or removes the \Seen flag on a message identified by UID. seen=true marks the message as read; seen=false marks it as unread.

func ResolvePublicHost added in v0.43.0

func ResolvePublicHost(kind, host string) ([]netip.Addr, error)

ResolvePublicHost resolves host and rejects any result that is not safe for server-side email egress. Callers must connect to the returned IPs, not resolve the original hostname again, or DNS rebinding reopens the SSRF hole.

func SaveAttachments

func SaveAttachments(acct EmailAccount, folder string, uid uint32, dir string) ([]string, error)

SaveAttachments downloads and saves all attachments of a message to dir. It returns the list of file paths written.

func Send

func Send(acct EmailAccount, opts SendOptions) error

Send composes and sends an email via SMTP using the provided account configuration.

func ValidateAccountEgress added in v0.43.0

func ValidateAccountEgress(acct EmailAccount) error

ValidateAccountEgress rejects email server hosts that would make stellad connect to local or private infrastructure on behalf of an authenticated user.

func ValidateAccountName

func ValidateAccountName(name string) error

Types

type Access added in v0.60.0

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

Access is one email use case bound to one trusted Authority. Email is a user-owned capability: the account config lives in the acting user's vault, so ownership is simply the captured userID — every operation loads that user's config and nothing else. A delegated AgentActor acts as its delegating user (an agent shares its user's mail), so it reaches the same accounts. There is no policy evaluation: transports and the agent tool pass a trusted authz.Authority and never a bare identity, and the per-user vault namespace is the boundary.

func (*Access) Accounts added in v0.60.0

func (a *Access) Accounts(ctx context.Context) (AccountList, error)

func (*Access) Folders added in v0.60.0

func (a *Access) Folders(ctx context.Context, account string) ([]string, error)

func (*Access) List added in v0.60.0

func (a *Access) List(ctx context.Context, account string, opts ListOptions) ([]Envelope, error)

func (*Access) MarkSeen added in v0.60.0

func (a *Access) MarkSeen(ctx context.Context, account, folder string, uid uint32, seen bool) error

func (*Access) Read added in v0.60.0

func (a *Access) Read(ctx context.Context, account, folder string, uid uint32) (*Message, error)

func (*Access) Send added in v0.60.0

func (a *Access) Send(ctx context.Context, account string, opts SendOptions, idempotencyKey string) (SendResult, error)

type AccountList added in v0.60.0

type AccountList struct {
	Accounts []string
	Default  string
}

type AccountsInput added in v0.60.0

type AccountsInput struct {
}

type AttachmentInfo

type AttachmentInfo struct {
	Filename string `json:"filename"`
	Size     int64  `json:"size"`
	MIMEType string `json:"mime_type"`
}

AttachmentInfo holds metadata about a message attachment (no content).

type Config

type Config struct {
	Default  string                  `json:"default"`
	Accounts map[string]EmailAccount `json:"accounts"`
}

func LoadFromEnv

func LoadFromEnv() (*Config, error)

func (*Config) AccountNames

func (c *Config) AccountNames() []string

func (*Config) Remove

func (c *Config) Remove(name string) error

func (*Config) Resolve

func (c *Config) Resolve(name string) (EmailAccount, error)

func (*Config) SetDefault

func (c *Config) SetDefault(name string) error

func (*Config) Upsert

func (c *Config) Upsert(name string, partial EmailAccount)

func (*Config) Validate added in v0.41.4

func (c *Config) Validate() error

type EmailAccount

type EmailAccount struct {
	IMAPHost string `json:"imap_host,omitempty"`
	IMAPPort int    `json:"imap_port,omitempty"`
	IMAPTLS  string `json:"imap_tls,omitempty"`
	SMTPHost string `json:"smtp_host,omitempty"`
	SMTPPort int    `json:"smtp_port,omitempty"`
	SMTPTLS  string `json:"smtp_tls,omitempty"`
	Username string `json:"username,omitempty"`
	Password string `json:"password,omitempty"`
	From     string `json:"from,omitempty"`
}

type Envelope

type Envelope struct {
	UID            uint32    `json:"uid"`
	MessageID      string    `json:"message_id,omitempty"`
	From           string    `json:"from"`
	FromName       string    `json:"from_name,omitempty"`
	FromAddr       string    `json:"from_addr,omitempty"`
	To             []string  `json:"to"`
	Subject        string    `json:"subject"`
	Date           time.Time `json:"date"`
	Flags          []string  `json:"flags"`
	HasAttachments bool      `json:"has_attachments"`
	Size           int64     `json:"size"`
}

Envelope holds metadata about an email message.

func List

func List(acct EmailAccount, opts ListOptions) ([]Envelope, error)

List returns envelope metadata for messages in the given folder, filtered by opts.

type Handler added in v0.60.0

type Handler interface {
	Accounts(context.Context, AccountsInput) (any, error)
	List(context.Context, ListInput) (any, error)
	Read(context.Context, ReadInput) (any, error)
	Send(context.Context, SendInput) (any, error)
}

type ListInput added in v0.60.0

type ListInput struct {
	Account string `json:"account,omitempty"`
	Before  string `json:"before,omitempty"`
	Folder  string `json:"folder,omitempty"`
	From    string `json:"from,omitempty"`
	Limit   int    `json:"limit,omitempty"`
	Since   string `json:"since,omitempty"`
	Subject string `json:"subject,omitempty"`
	Unread  *bool  `json:"unread,omitempty"`
}

type ListOptions

type ListOptions struct {
	Folder  string
	Limit   int
	Unread  bool
	From    string
	Subject string
	Since   *time.Time
	Before  *time.Time
}

ListOptions controls which messages are returned by List.

type Message

type Message struct {
	Envelope
	TextBody    string           `json:"text_body,omitempty"`
	HTMLBody    string           `json:"html_body,omitempty"`
	Attachments []AttachmentInfo `json:"attachments,omitempty"`
}

Message is a fully-fetched email message including body and attachment metadata.

func Read

func Read(acct EmailAccount, folder string, uid uint32) (*Message, error)

Read fetches and parses a single message by UID.

type Queries added in v0.60.0

type Queries interface {
	DeleteExpiredEmailSendDedup(context.Context) error
	CreateEmailSendDedup(context.Context, sqlc.CreateEmailSendDedupParams) (sqlc.EmailSendDedup, error)
	GetEmailSendDedup(context.Context, sqlc.GetEmailSendDedupParams) (sqlc.EmailSendDedup, error)
	DeleteEmailSendDedup(context.Context, sqlc.DeleteEmailSendDedupParams) error
}

type ReadInput added in v0.60.0

type ReadInput struct {
	Account string `json:"account,omitempty"`
	Folder  string `json:"folder,omitempty"`
	Uid     int    `json:"uid,omitempty"`
}

type SendInput added in v0.60.0

type SendInput struct {
	Account        string `json:"account,omitempty"`
	Bcc            []any  `json:"bcc,omitempty"`
	Body           string `json:"body,omitempty"`
	Cc             []any  `json:"cc,omitempty"`
	From           string `json:"from,omitempty"`
	Html           *bool  `json:"html,omitempty"`
	IdempotencyKey string `json:"idempotency_key,omitempty"`
	InReplyTo      string `json:"in_reply_to,omitempty"`
	ReplyTo        string `json:"reply_to,omitempty"`
	Subject        string `json:"subject,omitempty"`
	To             []any  `json:"to,omitempty"`
}

type SendOptions

type SendOptions struct {
	To          []string
	Cc          []string
	Bcc         []string
	Subject     string
	Body        string
	HTML        bool
	Attachments []string // file paths
	From        string   // override sender
	ReplyTo     string
	InReplyTo   string // Message-ID of the message being replied to
}

SendOptions holds the parameters for composing and sending an email.

type SendResult added in v0.60.0

type SendResult struct {
	Status    string
	Duplicate bool
}

type Service added in v0.60.0

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

func NewService added in v0.60.0

func NewService(vaultSvc *vault.Service, q Queries) *Service

func NewServiceForPool added in v0.60.0

func NewServiceForPool(vaultSvc *vault.Service, pool *pgxpool.Pool) *Service

NewServiceForPool creates an email service that owns the sqlc query set for the email tables, so callers pass only the pgx pool.

func (*Service) Access added in v0.60.0

func (s *Service) Access(authority authz.Authority) (*Access, error)

Access binds one email use case to a trusted Authority. It rejects an invalid Authority (403) and one carrying no user (401) up front, so every method can assume a non-empty acting user.

func (*Service) SetSendFunc added in v0.60.0

func (s *Service) SetSendFunc(fn func(EmailAccount, SendOptions) error)

type Tool added in v0.60.0

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

func NewTool added in v0.60.0

func NewTool(svc *Service) *Tool

func (*Tool) Definition added in v0.60.0

func (t *Tool) Definition() tools.Definition

func (*Tool) Execute added in v0.60.0

func (t *Tool) Execute(ctx context.Context, args map[string]any) (string, error)

Jump to

Keyboard shortcuts

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