feat(cli): configurable send-as From address (flags, TUI, validation)
- tui.ValidFromAddress: exported validator; blank passes, malformed rejects - Fields.FromAddress: new field, round-trips through ToAccount/FieldsFromAccount - Fields.Validate: calls ValidFromAddress before returning nil - TUI form: from_address fieldDef between username and password - send.go: From set via acc.SendFrom() instead of acc.Username - admin.go account add: --from flag with pre-parse validation - admin.go account edit: --from flag; validate before Visit, apply in Visit - USER-MANUAL.md: --from flag added to account add flags table Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,7 @@ func runAccount(args []string, role store.Role, out, errOut io.Writer) int {
|
||||
smtpSec := fs.String("smtp-security", "tls", "tls|starttls")
|
||||
user := fs.String("username", "", "login username")
|
||||
pass := fs.String("password", "", "login password")
|
||||
from := fs.String("from", "", "send-as address (blank = use username)")
|
||||
subj := fs.String("subject-regex", "", "inbound subject filter")
|
||||
wlIn := fs.Bool("whitelist-in", false, "enable inbound whitelist")
|
||||
wlOut := fs.Bool("whitelist-out", false, "enable outbound whitelist")
|
||||
@@ -56,9 +57,14 @@ func runAccount(args []string, role store.Role, out, errOut io.Writer) int {
|
||||
fmt.Fprintln(errOut, "name, imap-host, and username are required")
|
||||
return 2
|
||||
}
|
||||
if err := tui.ValidFromAddress(*from); err != nil {
|
||||
fmt.Fprintln(errOut, err)
|
||||
return 2
|
||||
}
|
||||
acc := store.Account{
|
||||
Name: *name, Mode: *mode, IMAPHost: *host, IMAPPort: *port, IMAPSecurity: *sec,
|
||||
AuthType: "password", Username: *user, Password: *pass,
|
||||
FromAddress: *from,
|
||||
SubjectRegex: *subj, WhitelistInEnabled: *wlIn, WhitelistOutEnabled: *wlOut,
|
||||
ProcessBacklog: *backlog,
|
||||
}
|
||||
@@ -85,6 +91,7 @@ func runAccount(args []string, role store.Role, out, errOut io.Writer) int {
|
||||
smtpSec := fs.String("smtp-security", "", "tls|starttls")
|
||||
user := fs.String("username", "", "login username")
|
||||
pass := fs.String("password", "", "login password (blank keeps existing)")
|
||||
from := fs.String("from", "", "send-as address (blank keeps existing)")
|
||||
subj := fs.String("subject-regex", "", "inbound subject filter")
|
||||
if err := fs.Parse(rest); err != nil {
|
||||
return 2
|
||||
@@ -96,6 +103,10 @@ func runAccount(args []string, role store.Role, out, errOut io.Writer) int {
|
||||
if fs.NFlag() == 1 { // only --name → interactive TUI form, prefilled
|
||||
return editInteractive(st, *name, out, errOut)
|
||||
}
|
||||
if err := tui.ValidFromAddress(*from); err != nil {
|
||||
fmt.Fprintln(errOut, err)
|
||||
return 2
|
||||
}
|
||||
acc, err := st.GetAccount(*name)
|
||||
if err != nil {
|
||||
fmt.Fprintf(errOut, "edit: %v\n", err)
|
||||
@@ -122,6 +133,8 @@ func runAccount(args []string, role store.Role, out, errOut io.Writer) int {
|
||||
acc.Username = *user
|
||||
case "password":
|
||||
acc.Password = *pass
|
||||
case "from":
|
||||
acc.FromAddress = *from
|
||||
case "subject-regex":
|
||||
acc.SubjectRegex = *subj
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user