fix(cli): reuse folder uidvalidity from setup in AckCmd

Thread uidv through setup's return value (new uint32 before the cleanup
func) so AckCmd no longer makes a redundant SelectFolder round-trip that
silently returned 0 on failure and recorded acks under the wrong
UID-validity epoch. All four callers updated; read-only callers ignore
the value with _.
This commit is contained in:
2026-06-22 00:06:26 +01:00
parent ccf6fa0542
commit e1d86dc587
+11 -12
View File
@@ -36,16 +36,16 @@ func (d Deps) audit(account, action, target, result, reason string) {
// setup loads the account, builds the inbound rule, dials IMAP, and selects the
// folder (establishing the baseline). Returns a cleanup func.
func (d Deps) setup(account, folder string) (store.Account, policy.InboundRule, Mailer, func(), *Envelope) {
func (d Deps) setup(account, folder string) (store.Account, policy.InboundRule, Mailer, uint32, func(), *Envelope) {
acc, err := d.Store.GetAccount(account)
if err != nil {
e := Failure(CodeNotFound, "account not found: "+account)
return acc, policy.InboundRule{}, nil, nil, &e
return acc, policy.InboundRule{}, nil, 0, nil, &e
}
re, err := policy.CompileSubject(acc.SubjectRegex)
if err != nil {
e := Failure(CodeConfig, "invalid subject_regex: "+err.Error())
return acc, policy.InboundRule{}, nil, nil, &e
return acc, policy.InboundRule{}, nil, 0, nil, &e
}
wlIn, _ := d.Store.ListWhitelist(account, store.DirIn)
rule := policy.InboundRule{
@@ -56,20 +56,20 @@ func (d Deps) setup(account, folder string) (store.Account, policy.InboundRule,
m, err := d.Dial(acc)
if err != nil {
e := Failure(CodeNetwork, "imap connect failed: "+err.Error())
return acc, rule, nil, nil, &e
return acc, rule, nil, 0, nil, &e
}
uidv, maxUID, err := m.SelectFolder(folder)
if err != nil {
m.Logout()
e := Failure(CodeNetwork, "select folder failed: "+err.Error())
return acc, rule, nil, nil, &e
return acc, rule, nil, 0, nil, &e
}
if err := d.Store.EnsureFolderBaseline(account, folder, uidv, maxUID); err != nil {
m.Logout()
e := Failure(CodeDB, err.Error())
return acc, rule, nil, nil, &e
return acc, rule, nil, 0, nil, &e
}
return acc, rule, m, func() { m.Logout() }, nil
return acc, rule, m, uidv, func() { m.Logout() }, nil
}
func headerMap(h mail.Header) map[string]any {
@@ -80,7 +80,7 @@ func headerMap(h mail.Header) map[string]any {
}
func ListCmd(d Deps, account, folder string, onlyNew bool, beforeUID, sinceUID uint32, limit int) error {
_, rule, m, done, fail := d.setup(account, folder)
_, rule, m, _, done, fail := d.setup(account, folder)
if fail != nil {
return d.emit(*fail)
}
@@ -134,7 +134,7 @@ func (d Deps) visible(m Mailer, rule policy.InboundRule, folder string, uid uint
}
func GetCmd(d Deps, account, folder string, uid uint32) error {
_, rule, m, done, fail := d.setup(account, folder)
_, rule, m, _, done, fail := d.setup(account, folder)
if fail != nil {
return d.emit(*fail)
}
@@ -169,7 +169,7 @@ func GetCmd(d Deps, account, folder string, uid uint32) error {
}
func SearchCmd(d Deps, account, folder string, sc mail.SearchCriteria, limit int) error {
_, rule, m, done, fail := d.setup(account, folder)
_, rule, m, _, done, fail := d.setup(account, folder)
if fail != nil {
return d.emit(*fail)
}
@@ -193,12 +193,11 @@ func SearchCmd(d Deps, account, folder string, sc mail.SearchCriteria, limit int
}
func AckCmd(d Deps, account, folder string, uids []uint32) error {
_, rule, m, done, fail := d.setup(account, folder)
_, rule, m, uidv, done, fail := d.setup(account, folder)
if fail != nil {
return d.emit(*fail)
}
defer done()
uidv, _, _ := m.SelectFolder(folder)
for _, uid := range uids {
ok, err := d.visible(m, rule, folder, uid)
if err != nil {