added IMAP, LetsEncrypt, update layout
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package mailstore
|
||||
|
||||
import "strings"
|
||||
|
||||
// FilterAction is the outcome of evaluating a mailbox's filter rules against one
|
||||
// incoming message.
|
||||
type FilterAction struct {
|
||||
Folder string // non-empty: store here instead of INBOX
|
||||
MarkRead bool
|
||||
Drop bool // don't store at all
|
||||
}
|
||||
|
||||
// ApplyRules evaluates a mailbox's filter rules in priority order and returns the
|
||||
// first match's action (zero value if none match, meaning "store in INBOX, unread").
|
||||
// headers should have "from"/"to"/"subject" keys — rules run at delivery time, before
|
||||
// the message is encrypted and stored, so real header values are available, not just
|
||||
// the plaintext cache columns used for fast IMAP listing.
|
||||
func (s *Store) ApplyRules(mailboxID int64, headers map[string]string) (FilterAction, error) {
|
||||
rules, err := s.DB.ListRulesForMailbox(mailboxID)
|
||||
if err != nil {
|
||||
return FilterAction{}, err
|
||||
}
|
||||
for _, r := range rules {
|
||||
if !r.IsActive {
|
||||
continue
|
||||
}
|
||||
if !matchCondition(r.ConditionOp, headers[r.ConditionField], r.ConditionValue) {
|
||||
continue
|
||||
}
|
||||
switch r.Action {
|
||||
case "move_to_folder":
|
||||
return FilterAction{Folder: r.ActionValue}, nil
|
||||
case "delete":
|
||||
return FilterAction{Drop: true}, nil
|
||||
case "mark_read":
|
||||
return FilterAction{MarkRead: true}, nil
|
||||
}
|
||||
}
|
||||
return FilterAction{}, nil
|
||||
}
|
||||
|
||||
func matchCondition(op, value, target string) bool {
|
||||
value = strings.ToLower(value)
|
||||
target = strings.ToLower(target)
|
||||
switch op {
|
||||
case "contains":
|
||||
return strings.Contains(value, target)
|
||||
case "equals":
|
||||
return value == target
|
||||
case "starts_with":
|
||||
return strings.HasPrefix(value, target)
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user