feat(headers): add parsing for Stalwart spam headers
Example of headers created by Stalwart below X-Spam-Result: TRUSTED_DOMAIN (-7.00), PROB_HAM_LOW (-2.00), RBL_SENDERSCORE_REPUT_9 (-1.00), DMARC_POLICY_ALLOW (-0.50), RCVD_DKIM_ARC_DNSWL_MED (-0.50) X-Spam-Score: ham, score=-5.60, avg_confidence=0.26 X-Spam-Status: No Only need to add small tweak by detecting spam|ham as well as Yes|No The most useful header is X-Spam-Score, so we make sure to parse that before X-Spam-Status
This commit is contained in:
@@ -118,7 +118,8 @@ export function parseAuthenticationResults(header: string): AuthenticationResult
|
||||
*/
|
||||
export function parseSpamScore(header: string): { score: number; status: string } | null {
|
||||
// Try X-Spam-Status format: "No, score=-0.25"
|
||||
const statusMatch = header.match(/^(Yes|No),?\s+score=([-\d.]+)/i);
|
||||
// And try X-Spam-Score format (Stalwart): "ham, score=-0.25"
|
||||
const statusMatch = header.match(/^(Yes|No|spam|ham),?\s+score=([-\d.]+)/i);
|
||||
if (statusMatch) {
|
||||
return {
|
||||
status: statusMatch[1].toLowerCase(),
|
||||
|
||||
+2
-2
@@ -1243,10 +1243,10 @@ export class JMAPClient implements IJMAPClient {
|
||||
email.authenticationResults = parseAuthenticationResults(value);
|
||||
}
|
||||
|
||||
for (const headerName of ['X-Spam-Status', 'X-Spam-Result', 'X-Rspamd-Score']) {
|
||||
for (const headerName of ['X-Spam-Score', 'X-Spam-Status', 'X-Spam-Result', 'X-Rspamd-Score']) {
|
||||
if (!headersRecord[headerName]) continue;
|
||||
const value = Array.isArray(headersRecord[headerName]) ? headersRecord[headerName][0] : headersRecord[headerName];
|
||||
const spamResult = parseSpamScore(value as string);
|
||||
const spamResult = parseSpamScore((value as string).trim());
|
||||
if (spamResult) {
|
||||
email.spamScore = spamResult.score;
|
||||
email.spamStatus = spamResult.status;
|
||||
|
||||
Reference in New Issue
Block a user