UNPKG

dmarc-solution

Version:

One stop solution for all DMARC Problems. This package includes fetching of dmarc record, parsing the provided/fetched record, validation of DMARC record, generating a new DMARC record

175 lines (174 loc) 9.05 kB
"use strict"; exports.__esModule = true; exports.validators = void 0; var email_validator_1 = require("email-validator"); exports.validators = { v: { required: true, description: "The v tag is required and represents the protocol version. An example is v=DMARC1", validate: function (term, value) { if (value !== "DMARC1") { throw new Error("Invalid DMARC version: '".concat(value, "'")); } } }, fo: { description: "The FO tag pertains to how forensic reports are created and presented to DMARC users.", validate: function (term, originalValue) { var value = originalValue.split(":"); if (value.length <= 4) { if (!/^([01ds])$/i.test(value[0])) { throw new Error("Invalid value for '".concat(term, "': '").concat(originalValue, "', must be colon seprated with: 0, 1, d, s")); } if (value.length > 1 && !/^([01ds])$/i.test(value[1])) { throw new Error("Invalid value for '".concat(term, "': '").concat(originalValue, "', must be colon seprated with: 0, 1, d, s")); } if (value.length > 2 && !/^([01ds])$/i.test(value[2])) { throw new Error("Invalid value for '".concat(term, "': '").concat(originalValue, "', must be colon seprated with: 0, 1, d, s")); } if (value.length > 3 && !/^([01ds])$/i.test(value[3])) { throw new Error("Invalid value for '".concat(term, "': '").concat(originalValue, "', must be colon seprated with: 0, 1, d, s")); } } }, generate: function (value) { if (value && value.length) return value.join(":"); throw new Error("Invalid for 'fo' tag"); } }, p: { description: "The required p tag demonstrates the policy for domain (or requested handling policy). It directs the receiver to report, quarantine, or reject emails that fail authentication checks. Policy options are: 1) None 2) Quarantine or 3) Reject.", validate: function (term, value) { if (!/^(none|quarantine|reject)$/i.test(value)) { throw new Error("Invalid value for '".concat(term, "': '").concat(value, "', must be one of: none, quarantine, reject")); } } }, pct: { description: "This DMARC tag specifies the percentage of email messages subjected to filtering. For example, pct=25 means a quarter of your company\u2019s emails will be filtered by the recipient.", validate: function (term, value) { if (!/^\d+$/.test(value)) { throw new Error("Invalid value for '".concat(term, "': ").concat(value, ", must be a positive integer")); } else if (parseInt(value, 10) > 100 || parseInt(value, 10) < 0) { throw new Error("Invalid value for '".concat(term, "': ").concat(value, ", must be an integer between 0 and 100")); } } }, rf: { description: "Format to be used for message-specific failure reports (colon-separated plain-text list of values)", validate: function (term, value) { // The RFC says the values are colon-separated but a lot of examples/docs around the net show commas... so we'll do both var values = value.split(/,|:/).map(function (x) { return x.trim(); }); for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { var val = values_1[_i]; if (!/^(afrf|iodef)$/i.test(val)) { throw new Error("Invalid value for '".concat(term, "': '").concat(value, "', must be one or more of these values: afrf, iodef. Multiple values must be separated by a comma or colon")); } } } }, ri: { description: "The ri tag corresponds to the aggregate reporting interval and provides DMARC feedback for the outlined criteria.", validate: function (term, value) { if (!/^\d+$/.test(value)) { throw new Error("Invalid value for '".concat(term, "': ").concat(value, ", must be an unsigned integer")); } } }, rua: { description: "This optional tag is designed for reporting URI(s) for aggregate data. An rua example is rua=mailto:CUSTOMER@for.example.com.", validate: function (term, value) { var values = value.split(/,/).map(function (x) { return x.trim(); }); for (var _i = 0, values_2 = values; _i < values_2.length; _i++) { var val = values_2[_i]; var matches = val.match(/^mailto:(.+)$/i); if (!matches) { throw new Error("Invalid value for '".concat(term, "': ").concat(value, ", must be a list of DMARC URIs such as 'mailto:some.email@somedomain.com'")); } var email = matches[1]; if (!(0, email_validator_1.validate)(email)) { throw new Error("Invalid email address in '".concat(term, "': '").concat(email, "'")); } } }, generate: function (value) { var mailtoList = []; if (value && value.length) { for (var i = 0; i < value.length; i++) { if (typeof value[i] === "string") { if (!value[i].startsWith("mailto:")) value[i] = "mailto:" + value[i]; if (mailtoList.indexOf(value[i]) == -1) mailtoList.push(value[i]); } else throw new Error("Invalid Email: '" + value[i] + "' for 'rua' tag"); } return mailtoList.join(","); } else throw new Error("Invalid value for 'rua' tag"); } }, ruf: { description: "Like the rua tag, the ruf designation is an optional tag. It directs addresses to which message-specific forensic information is to be reported (i.e., comma-separated plain-text list of URIs). An ruf example is ruf=mailto:CUSTOMER@for.example.com.", validate: function (term, value) { var values = value.split(/,/).map(function (x) { return x.trim(); }); for (var _i = 0, values_3 = values; _i < values_3.length; _i++) { var val = values_3[_i]; var matches = val.match(/^mailto:(.+)$/i); if (!matches) { throw new Error("Invalid value for '".concat(term, "': ").concat(value, ", must be a list of DMARC URIs such as 'mailto:some.email@somedomain.com'")); } var email = matches[1]; if (!(0, email_validator_1.validate)(email)) { throw new Error("Invalid email address in '".concat(term, "': '").concat(email, "'")); } } }, generate: function (value) { var mailtoList = []; if (value && value.length) { for (var i = 0; i < value.length; i++) { if (typeof value[i] === "string") { if (!value[i].startsWith("mailto:")) value[i] = "mailto:" + value[i]; if (mailtoList.indexOf(value[i]) == -1) mailtoList.push(value[i]); } else throw new Error("Invalid Email: '" + value[i] + "' for 'ruf' tag"); } return mailtoList.join(","); } else throw new Error("Invalid value for 'ruf' tag"); } }, sp: { description: 'Requested Mail Receiver policy for all subdomains. Can be "none", "quarantine", or "reject".', validate: function (term, value) { if (!/^(none|quarantine|reject)$/i.test(value)) { throw new Error("Invalid value for '".concat(term, "': '").concat(value, "', must be one of: none, quarantine, reject")); } } }, aspf: { description: "The aspf tag represents alignment mode for SPF. An optional tag, aspf=r is a common example of its configuration.", validate: function (term, value) { if (!/^(s|r)$/i.test(value)) { throw new Error("Invalid value for '".concat(term, "': '").concat(value, "', must be one of \"r\" or \"s\"")); } } }, adkim: { description: "Similar to aspf, the optional adkim tag is the alignment mode for the DKIM protocol. A sample tag is adkim=r.", validate: function (term, value) { if (!/^(s|r)$/i.test(value)) { throw new Error("Invalid value for '".concat(term, "': '").concat(value, "', must be one of \"r\" or \"s\"")); } } } };