Documentation
¶
Index ¶
- Constants
- func DefaultConfigPath() string
- func Save(path string, cfg *Config) error
- func SlugifyID(s string) string
- func SlugifyProfileID(firstName, lastName string, existing []NamedProfile) string
- type Config
- type Email
- type EmailConfig
- type InboxConfig
- type NamedProfile
- type Options
- type Pipeline
- type Profile
- type SMTPConfig
Constants ¶
const DefaultProfileID = "default"
DefaultProfileID is the synthetic ID used for the legacy single Profile block when no profiles: list is configured, and is what pre-multi-profile history rows are attributed to after the profile_id migration.
Variables ¶
This section is empty.
Functions ¶
func DefaultConfigPath ¶
func DefaultConfigPath() string
func SlugifyID ¶
SlugifyID converts arbitrary text into a lowercase-hyphenated identifier safe to use as a NamedProfile.ID - stripping everything outside [a-z0-9]. Both the CLI (`eraser profile add`) and the web UI's "add profile" form must funnel a user-typed or name-derived ID through this same function: Go's net/http cookie writer silently drops (rather than quotes) any byte outside 0x20-0x7e when writing a Set-Cookie header, including any non-ASCII UTF-8 byte such as diacritics in a name - an ID that carries one round-trips incorrectly through the web UI's profile-switcher cookie, silently falling back to the first configured profile.
func SlugifyProfileID ¶
func SlugifyProfileID(firstName, lastName string, existing []NamedProfile) string
SlugifyProfileID derives a profile ID from a first/last name pair (see SlugifyID for the charset rule), appending -2, -3, ... if the base is already taken by an existing profile - so the web UI's "add profile" form never needs to ask the user to pick an ID themselves.
Types ¶
type Config ¶
type Config struct {
// Profile is the legacy single-profile block. Still fully supported -
// GetProfiles() wraps it as a single "default" profile whenever Profiles
// is empty, so an existing single-person config.yaml keeps working
// unchanged. Ignored once Profiles is non-empty (see GetProfiles).
Profile Profile `yaml:"profile"`
// Profiles lets one eraser install send and track removal requests for
// more than one person (e.g. yourself and a family member) against the
// same broker database, email account, and options - each profile's
// send history, pipeline state, and pending tasks are tracked
// separately (see history.Store's profile_id column). Takes precedence
// over Profile when non-empty; Profile is otherwise ignored.
Profiles []NamedProfile `yaml:"profiles,omitempty"`
Email EmailConfig `yaml:"email"`
Options Options `yaml:"options"`
Inbox InboxConfig `yaml:"inbox,omitempty"`
Pipeline Pipeline `yaml:"pipeline,omitempty"`
}
func (*Config) GetProfile ¶
func (c *Config) GetProfile(id string) (NamedProfile, error)
GetProfile resolves the active profile by ID. An empty id resolves to the sole configured profile when there's exactly one; with several configured, an empty id is ambiguous and returns an error listing the available IDs (the caller - CLI flag, web session - must disambiguate).
func (*Config) GetProfiles ¶
func (c *Config) GetProfiles() []NamedProfile
GetProfiles returns every configured profile. A config with no explicit profiles: list returns a single synthetic profile (ID "default") wrapping the legacy top-level profile: block, so existing single-profile configs keep working unchanged without needing to be rewritten.
func (*Config) IsManualSend ¶
IsManualSend reports whether the user opted out of automated sending - Eraser renders the emails but never transmits them.
func (*Config) ValidateInbox ¶
ValidateInbox validates inbox configuration (only called when inbox monitoring is used)
type Email ¶
type Email = EmailConfig
type EmailConfig ¶
type EmailConfig struct {
Provider string `yaml:"provider"`
From string `yaml:"from"`
SMTP SMTPConfig `yaml:"smtp,omitempty"`
}
type InboxConfig ¶
type InboxConfig struct {
Enabled bool `yaml:"enabled"`
Provider string `yaml:"provider"` // "gmail", "outlook", "imap"
Server string `yaml:"server"` // e.g., "imap.gmail.com"
Port int `yaml:"port"` // e.g., 993
Email string `yaml:"email"` // Email address to monitor
Password string `yaml:"password"` // App password (not main password)
Folder string `yaml:"folder"` // Folder to monitor (default: "INBOX")
AutoArchive bool `yaml:"auto_archive"` // Automatically move processed emails to archive folder
ArchiveFolder string `yaml:"archive_folder"` // Folder to archive emails to (default: "Eraser")
}
InboxConfig holds IMAP settings for monitoring broker responses
type NamedProfile ¶
type NamedProfile struct {
// ID should be short, lowercase, and hyphenated (like a broker ID) -
// e.g. "maris" or "spouse". Stored verbatim in history.db so changing it
// later orphans that profile's existing history from the CLI/web UI
// (the rows are still in the database, just no longer reachable by the
// new ID).
ID string `yaml:"id"`
Profile `yaml:",inline"`
}
NamedProfile is one entry in a multi-profile config: a person identity (name, address, contact info - everything Profile already carries) plus a stable ID used to select it via --profile on the CLI, to scope history records to it, and to switch between profiles in the web UI.
type Options ¶
type Options struct {
Template string `yaml:"template"`
// SendMode selects how removal emails leave the machine:
// "" / "smtp" - Eraser sends them itself over the configured SMTP account.
// "manual" - Eraser never sends. It renders the emails for you to send
// by hand from your own mail client, and you record each one
// with `eraser mark-sent` / the web UI's "Mark sent" button.
// No `email:` block is required in this mode.
// For users who won't give any tool their mailbox credentials.
SendMode string `yaml:"send_mode,omitempty"`
DryRun bool `yaml:"dry_run"`
RateLimitMs int `yaml:"rate_limit_ms"`
// DailySendLimit caps how many emails `send` will dispatch per rolling
// 24h window, so a large broker list can't blow past your provider's
// daily sending cap (Gmail's is ~500/day) or read as bulk-spam behavior.
// 0 uses the default (450). Overridden per-run with --ignore-daily-limit.
DailySendLimit int `yaml:"daily_send_limit,omitempty"`
// BrokerList picks which built-in list the send-family commands use:
// "" / "full" - the full ~750-entry list (default)
// "verified" - the smaller registry-sourced list (data/brokers-verified.yaml)
// Overridden per-run with `send --list`. Ignored when BrokerFile or
// --brokers points at an explicit file.
BrokerList string `yaml:"broker_list,omitempty"`
// BrokerFile points the send-family commands at your own broker list,
// the config equivalent of the global --brokers flag (which still wins).
// Takes precedence over BrokerList.
BrokerFile string `yaml:"broker_file,omitempty"`
Regions []string `yaml:"regions"`
ExcludedBrokers []string `yaml:"excluded_brokers,omitempty"`
// ExcludedCategories skips every broker whose category (case-insensitive)
// matches one of these - e.g. "requires-id" to skip brokers that ask for
// a government-issued ID document or similar heavyweight identity
// verification before they'll act on a request, which this tool won't
// supply on your behalf.
ExcludedCategories []string `yaml:"excluded_categories,omitempty"`
}
type Pipeline ¶
type Pipeline struct {
AutoConfirm bool `yaml:"auto_confirm"` // Auto-click confirmation links
AutoFillForms bool `yaml:"auto_fill_forms"` // Enable browser automation for forms
// BrowserHeadless defaults to true (headless) when unset. A plain bool
// can't tell "explicitly set to false" apart from "never set" - both
// unmarshal as the zero value - so this used to get silently forced
// back to true on every load, discarding a `browser_headless: false`
// someone set to watch the browser solve a CAPTCHA. A pointer fixes
// that; use Headless() to read it with the default applied.
BrowserHeadless *bool `yaml:"browser_headless,omitempty"`
BrowserTimeoutSec int `yaml:"browser_timeout_sec"` // Browser operation timeout
}
Pipeline holds settings for the automation pipeline
type Profile ¶
type Profile struct {
FirstName string `yaml:"first_name"`
// MiddleName is optional - most brokers only match on first/last name,
// but some (especially background-check and financial-b2b brokers)
// index records by full legal name, so including it helps them find
// (and thus actually delete) the right record.
MiddleName string `yaml:"middle_name,omitempty"`
LastName string `yaml:"last_name"`
Email string `yaml:"email"`
// AdditionalEmails are other addresses you've used over the years (old
// personal accounts, work emails, etc). Brokers often indexed your record
// under one of these rather than your current address, so listing them
// all in the removal request helps them actually locate and delete it.
AdditionalEmails []string `yaml:"additional_emails,omitempty"`
// NameVariants covers other spellings brokers may have indexed you under -
// e.g. a diacritic-free version of your name ("Maris" for "Māris"), a
// maiden name, or a nickname you've used to sign up for things.
NameVariants []string `yaml:"name_variants,omitempty"`
// PreviousAddresses are other places you've lived recently enough that a
// broker might still have the record - a partial address (missing an
// apartment number, say) is still worth including, since most broker
// matching keys off street/city/postal code rather than the exact unit.
PreviousAddresses []string `yaml:"previous_addresses,omitempty"`
Address string `yaml:"address,omitempty"`
City string `yaml:"city,omitempty"`
State string `yaml:"state,omitempty"`
ZipCode string `yaml:"zip_code,omitempty"`
Country string `yaml:"country,omitempty"`
Phone string `yaml:"phone,omitempty"`
// AdditionalPhones covers other numbers you've used to sign up for
// things (an old number, a work line) that a broker might have on file
// instead of your current one.
AdditionalPhones []string `yaml:"additional_phones,omitempty"`
DateOfBirth string `yaml:"date_of_birth,omitempty"`
}