Add support for wildcards in the email domain blocklist.
Eg: *.example.com, *.mail.example.com etc. Closes #1275. Closes #1276.
This commit is contained in:
parent
98729f63df
commit
3baf18ea45
1 changed files with 41 additions and 9 deletions
|
@ -24,7 +24,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
"github.com/knadh/koanf/maps"
|
|
||||||
"github.com/knadh/listmonk/internal/i18n"
|
"github.com/knadh/listmonk/internal/i18n"
|
||||||
"github.com/knadh/listmonk/models"
|
"github.com/knadh/listmonk/models"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
@ -52,10 +51,11 @@ const (
|
||||||
|
|
||||||
// Importer represents the bulk CSV subscriber import system.
|
// Importer represents the bulk CSV subscriber import system.
|
||||||
type Importer struct {
|
type Importer struct {
|
||||||
opt Options
|
opt Options
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
i18n *i18n.I18n
|
i18n *i18n.I18n
|
||||||
domainBlocklist map[string]bool
|
domainBlocklist map[string]bool
|
||||||
|
hasBlocklistWildcards bool
|
||||||
|
|
||||||
stop chan bool
|
stop chan bool
|
||||||
status Status
|
status Status
|
||||||
|
@ -135,10 +135,24 @@ func New(opt Options, db *sql.DB, i *i18n.I18n) *Importer {
|
||||||
opt: opt,
|
opt: opt,
|
||||||
db: db,
|
db: db,
|
||||||
i18n: i,
|
i18n: i,
|
||||||
domainBlocklist: maps.StringSliceToLookupMap(opt.DomainBlocklist),
|
domainBlocklist: make(map[string]bool, len(opt.DomainBlocklist)),
|
||||||
status: Status{Status: StatusNone, logBuf: bytes.NewBuffer(nil)},
|
status: Status{Status: StatusNone, logBuf: bytes.NewBuffer(nil)},
|
||||||
stop: make(chan bool, 1),
|
stop: make(chan bool, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Domain blocklist.
|
||||||
|
for _, d := range opt.DomainBlocklist {
|
||||||
|
im.domainBlocklist[d] = true
|
||||||
|
|
||||||
|
// Domains with *. as the subdomain prefix, strip that
|
||||||
|
// and add the full domain to the blocklist as welll.
|
||||||
|
// eg: *.example.com => example.com
|
||||||
|
if strings.Contains(d, "*.") {
|
||||||
|
im.hasBlocklistWildcards = true
|
||||||
|
im.domainBlocklist[strings.TrimPrefix(d, "*.")] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &im
|
return &im
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,13 +601,31 @@ func (im *Importer) SanitizeEmail(email string) (string, error) {
|
||||||
return "", errors.New(im.i18n.T("subscribers.invalidEmail"))
|
return "", errors.New(im.i18n.T("subscribers.invalidEmail"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the e-mail's domain is blocklisted.
|
// Check if the e-mail's domain is blocklisted. The e-mail domain and blocklist config
|
||||||
|
// are always lowercase.
|
||||||
d := strings.Split(em.Address, "@")
|
d := strings.Split(em.Address, "@")
|
||||||
if len(d) == 2 {
|
if len(d) == 2 {
|
||||||
_, ok := im.domainBlocklist[d[1]]
|
domain := d[1]
|
||||||
if ok {
|
|
||||||
|
// Check the domain as-is.
|
||||||
|
if _, ok := im.domainBlocklist[domain]; ok {
|
||||||
return "", errors.New(im.i18n.T("subscribers.domainBlocklisted"))
|
return "", errors.New(im.i18n.T("subscribers.domainBlocklisted"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are wildcards in the blocklist and the email domain has a subdomain, check that.
|
||||||
|
if im.hasBlocklistWildcards && strings.Count(domain, ".") > 1 {
|
||||||
|
parts := strings.Split(domain, ".")
|
||||||
|
|
||||||
|
// Replace the first part of the subdomain with * and check if that exists in the blocklist.
|
||||||
|
// Eg: test.mail.example.com => *.mail.example.com
|
||||||
|
parts[0] = "*"
|
||||||
|
domain = strings.Join(parts, ".")
|
||||||
|
|
||||||
|
if _, ok := im.domainBlocklist[domain]; ok {
|
||||||
|
return "", errors.New(im.i18n.T("subscribers.domainBlocklisted"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return em.Address, nil
|
return em.Address, nil
|
||||||
|
|
Loading…
Reference in a new issue