All files / Scripts/row Antispam.ts

100% Statements 55/55
90.9% Branches 20/22
100% Functions 12/12
100% Lines 51/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 1035x 5x   5x 5x   5x 98x 98x 98x 98x 98x 98x             162x     73x 702x 7x       66x       75x 631x 57x 57x 57x       18x         14x 14x 1x         13x       13x       13x   13x 13x 13x 13x 49x 49x 49x 18x           13x 13x     8x   22x 2x 2x     20x     73x   8x 6x   6x 4x 4x 16x   4x      
import { mhaStrings } from "../mhaStrings";
import { Strings } from "../Strings";
import { Header } from "./Header";
import { Row } from "./Row";
import { SummaryTable } from "../table/SummaryTable";
 
export class AntiSpamReport extends SummaryTable {
    public readonly tableName: string = "antiSpamReport";
    public readonly displayName: string = mhaStrings.mhaAntiSpamReport;
    public readonly tag: string = "AS";
    private sourceInternal = "";
    private unparsedInternal = "";
    private antiSpamRows: Row[] = [
        new Row("BCL", mhaStrings.mhaBcl, "X-Microsoft-Antispam"),
        new Row("PCL", mhaStrings.mhaPcl, "X-Microsoft-Antispam"),
        new Row("source", mhaStrings.mhaSource, "X-Microsoft-Antispam"),
        new Row("unparsed", mhaStrings.mhaUnparsed, "X-Microsoft-Antispam")
    ];
 
    public get rows(): Row[] { return this.antiSpamRows; }
 
    public existsInternal(rows: Row[]): boolean {
        for (const row of rows) {
            if (row.value) {
                return true;
            }
        }
 
        return false;
    }
 
    private setRowValue(rows: Row[], key: string, value: string): boolean {
        for (const row of rows) {
            if (row.header.toUpperCase() === key.toUpperCase()) {
                row.value = value;
                row.onGetUrl = (headerName: string, value: string) => { return Strings.mapHeaderToURL(headerName, value); };
                return true;
            }
        }
 
        return false;
    }
 
    // https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers
    public parse(report: string): void {
        this.sourceInternal = report;
        if (!report) {
            return;
        }
 
        // Sometimes we see extraneous (null) in the report. They look like this: UIP:(null);(null);(null)SFV:SKI
        // First pass: Remove the (null).
        report = report.replace(/\(null\)/g, "");
 
        // Occasionally, we find the final ; is missing.
        // Second pass: Add one. If it is extraneous, the next pass will remove it.
        report = report + ";";
 
        // Removing the (null) can leave consecutive ; which confound later parsing.
        // Third pass: Collapse them.
        report = report.replace(/;+/g, ";");
 
        const lines = report.match(/(.*?):(.*?);/g);
        this.unparsedInternal = "";
        Eif (lines) {
            for (let iLine = 0; iLine < lines.length; iLine++) {
                const line = lines[iLine]?.match(/(.*?):(.*?);/m);
                Eif (line && line[1]) {
                    if (line[2] === undefined || !this.setRowValue(this.rows, line[1], line[2])) {
                        this.unparsedInternal += line[1] + ":" + line[2] + ";";
                    }
                }
            }
        }
 
        this.setRowValue(this.rows, "source", this.sourceInternal);
        this.setRowValue(this.rows, "unparsed", this.unparsedInternal);
    }
 
    public addInternal(report: string): void { this.parse(report); }
    public add(header: Header): boolean {
        if (header.header.toUpperCase() === "X-Microsoft-Antispam".toUpperCase()) {
            this.parse(header.value);
            return true;
        }
 
        return false;
    }
 
    public override exists(): boolean { return this.existsInternal(this.rows); }
 
    public get source(): string { return this.sourceInternal; }
    public get unparsed(): string { return this.unparsedInternal; }
    public override toString(): string {
        if (!this.exists()) return "";
        const ret = ["AntiSpamReport"];
        this.rows.forEach(function (row) {
            if (row.value) { ret.push(row.toString()); }
        });
        return ret.join("\n");
    }
}