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
JavaScript
;
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\""));
}
}
}
};