Skip to content

Commit 515b467

Browse files
authored
fix: fix filter handler overrides and filter precedence (#1147)
1 parent a7ba203 commit 515b467

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

lib/filter-handler.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,17 @@ class FilterHandler {
654654
});
655655
}
656656

657-
if (typeof userData.spamLevel === 'number' && userData.spamLevel >= 0) {
657+
const hasMailboxFilterAction = !!filterActions.get('mailbox');
658+
659+
if (hasMailboxFilterAction && filterActions.get('spam') > 0) {
660+
// An explicit filter destination takes precedence over moving the message to Junk.
661+
filterActions.delete('spam');
662+
spamActionSource = false;
663+
spamActionDomainaccess = false;
664+
spamActionFilter = false;
665+
}
666+
667+
if (!hasMailboxFilterAction && typeof userData.spamLevel === 'number' && userData.spamLevel >= 0) {
658668
let isSpam;
659669

660670
if (userData.spamLevel === 0) {
@@ -700,7 +710,7 @@ class FilterHandler {
700710
}
701711

702712
const overrideFlags = Array.isArray(meta?.overrides?.flags) ? meta.overrides.flags : false;
703-
if (overrideFlags && spamActionSource !== 'filter') {
713+
if (overrideFlags && !hasMailboxFilterAction && spamActionSource !== 'filter') {
704714
// Recipient-level overrides may only replace domainaccess and user spamLevel decisions.
705715
originalSpam = filterActions.get('spam') === true;
706716
if (overrideFlags.includes('ham')) {

test/filter-handler-overrides-test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,57 @@ describe('FilterHandler recipient spam overrides', () => {
390390
expect(getSpamResult(result)).to.not.exist;
391391
});
392392

393+
it('should not let a spam override replace a filter mailbox destination', async () => {
394+
const mailbox = new ObjectId();
395+
const { addOptions, result } = await runCase({
396+
overrideFlags: ['spam'],
397+
filters: [
398+
{
399+
_id: new ObjectId(),
400+
query: {
401+
headers: {
402+
from: 'alice@example.com'
403+
}
404+
},
405+
action: {
406+
mailbox
407+
}
408+
}
409+
]
410+
});
411+
412+
expect(addOptions.mailbox).to.equal(mailbox);
413+
expect(addOptions.path).to.not.exist;
414+
expect(addOptions.specialUse).to.not.exist;
415+
expect(getSpamResult(result)).to.not.exist;
416+
});
417+
418+
it('should prefer a filter mailbox destination over a spam action', async () => {
419+
const mailbox = new ObjectId();
420+
const { addOptions, result } = await runCase({
421+
filters: [
422+
{
423+
_id: new ObjectId(),
424+
query: {
425+
headers: {
426+
from: 'alice@example.com'
427+
}
428+
},
429+
action: {
430+
mailbox,
431+
spam: true
432+
}
433+
}
434+
]
435+
});
436+
437+
expect(addOptions.mailbox).to.equal(mailbox);
438+
expect(addOptions.path).to.not.exist;
439+
expect(addOptions.specialUse).to.not.exist;
440+
expect(getSpamResult(result)).to.not.exist;
441+
expect(addOptions.prepared.mimeTree.header.some(header => /^WD-Mail-Classification:/i.test(header))).to.equal(false);
442+
});
443+
393444
it('should prefer ham when mixed with spam-like override flags', async () => {
394445
const { addOptions } = await runCase({
395446
overrideFlags: ['blacklist', 'ham']

0 commit comments

Comments
 (0)