dmarc-solution
Advanced tools
| { | ||
| "printWidth": 150, | ||
| "semi": true, | ||
| "useTabs": true, | ||
| "tabWidth": 4 | ||
| } |
+22
-26
@@ -1,28 +0,24 @@ | ||
| var dns = require('dns'); | ||
| var dns = require("dns").promises; | ||
| var fetch = function (domainName) { | ||
| return new Promise((resolve, reject) => { | ||
| dns.resolveTxt('_dmarc.' + domainName, (err, records) => { | ||
| if (err) { | ||
| if (err.message && typeof err.message == 'string' && err.message.startsWith('queryTxt ENOTFOUND')) | ||
| return reject(new Error('DMARC Record not available')); | ||
| return reject(err.message); | ||
| var fetch = async function (domainName) { | ||
| let records = await dns.resolveTxt("_dmarc." + domainName).catch(console.error); | ||
| if (!records) { | ||
| if (err.message && typeof err.message == "string" && err.message.startsWith("queryTxt ENOTFOUND")) | ||
| throw new Error("DMARC Record not available"); | ||
| throw new Error(err.message); | ||
| } | ||
| var record = null; | ||
| for (var i = 0; i < records.length; i++) { | ||
| for (var j = 0; j < records[i].length; j++) { | ||
| if (records[i][j].startsWith("v=DMARC")) { | ||
| record = records[i][j]; | ||
| break; | ||
| } | ||
| var record = null; | ||
| for (var i = 0; i < records.length; i++) { | ||
| for (var j = 0; j < records[i].length; j++) { | ||
| if (records[i][j].startsWith('v=DMARC')) { | ||
| record = records[i][j]; | ||
| break; | ||
| } | ||
| } | ||
| if (record && records[i].length > 0) record = records[i].join("") | ||
| if (record != null) | ||
| break; | ||
| } | ||
| if (record == null) return reject(new Error('DMARC Record not available')); | ||
| return resolve(record); | ||
| }); | ||
| }) | ||
| } | ||
| module.exports = fetch; | ||
| } | ||
| if (record && records[i].length > 0) record = records[i].join(""); | ||
| if (record != null) break; | ||
| } | ||
| if (record == null) return reject(new Error("DMARC Record not available")); | ||
| return record; | ||
| }; | ||
| module.exports = fetch; |
+8
-8
@@ -1,2 +0,2 @@ | ||
| var validators = require('./validator'); | ||
| var validators = require("./validator"); | ||
@@ -6,9 +6,9 @@ var generate = function (values) { | ||
| if (values.v == undefined) { | ||
| throw new Error('DMARC Version is required tag'); | ||
| throw new Error("DMARC Version is required tag"); | ||
| } | ||
| validators.v.validate.call(validators.v, 'v', values.v); | ||
| record.push('v=' + values.v); | ||
| validators.v.validate.call(validators.v, "v", values.v); | ||
| record.push("v=" + values.v); | ||
| for (var i = 0; i < Object.keys(values).length; i++) { | ||
| var term = Object.keys(values)[i]; | ||
| if (term === 'v') continue; | ||
| if (term === "v") continue; | ||
| if (validators[term]) { | ||
@@ -24,5 +24,5 @@ let settings = validators[term]; | ||
| } | ||
| return record.join('; '); | ||
| } | ||
| return record.join("; "); | ||
| }; | ||
| module.exports = generate; | ||
| module.exports = generate; |
+12
-15
@@ -1,3 +0,3 @@ | ||
| 'use strict'; | ||
| var validators = require('./validator'); | ||
| "use strict"; | ||
| var validators = require("./validator"); | ||
@@ -9,14 +9,12 @@ function parse(policy) { | ||
| let terms = policy.split(/;/) | ||
| .map(t => t.trim()) // Trim surrounding whitespace | ||
| .filter(x => x !== ''); // Ignore empty tags | ||
| let terms = policy | ||
| .split(/;/) | ||
| .map((t) => t.trim()) // Trim surrounding whitespace | ||
| .filter((x) => x !== ""); // Ignore empty tags | ||
| let rules = terms.map( | ||
| x => x.split(/[=]/) | ||
| .map(p => p.trim()) | ||
| ); | ||
| let rules = terms.map((x) => x.split(/[=]/).map((p) => p.trim())); | ||
| let retval = { | ||
| tags: {}, | ||
| messages: [] | ||
| messages: [], | ||
| }; | ||
@@ -41,3 +39,3 @@ | ||
| debugger; | ||
| let termRegex = new RegExp(`^${validatorTerm}$`, 'i'); | ||
| let termRegex = new RegExp(`^${validatorTerm}$`, "i"); | ||
| if (termRegex.test(term)) { | ||
@@ -48,3 +46,3 @@ found = true; | ||
| // tag: term, | ||
| description: settings.description | ||
| description: settings.description, | ||
| }; | ||
@@ -57,4 +55,3 @@ | ||
| retval.tags[term] = tag; | ||
| } | ||
| catch (err) { | ||
| } catch (err) { | ||
| retval.messages.push(err.message); | ||
@@ -81,2 +78,2 @@ } | ||
| module.exports = parse; | ||
| module.exports = parse; |
+45
-45
@@ -1,2 +0,2 @@ | ||
| const validator = require('email-validator'); | ||
| const validator = require("email-validator"); | ||
@@ -6,13 +6,13 @@ const validators = { | ||
| required: true, | ||
| description: 'The v tag is required and represents the protocol version. An example is v=DMARC1', | ||
| description: "The v tag is required and represents the protocol version. An example is v=DMARC1", | ||
| validate(term, value) { | ||
| if (value !== 'DMARC1') { | ||
| if (value !== "DMARC1") { | ||
| throw new Error(`Invalid DMARC version: '${value}'`); | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
| fo: { | ||
| description: 'The FO tag pertains to how forensic reports are created and presented to DMARC users.', | ||
| description: "The FO tag pertains to how forensic reports are created and presented to DMARC users.", | ||
| validate(term, originalValue) { | ||
| var value = originalValue.split(':'); | ||
| var value = originalValue.split(":"); | ||
| if (value.length <= 4) { | ||
@@ -34,9 +34,9 @@ if (!/^([01ds])$/i.test(value[0])) { | ||
| generate(value) { | ||
| if (value && value.length) | ||
| return value.join(':'); | ||
| throw new Error("Invalid for 'fo' tag") | ||
| } | ||
| 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.', | ||
| 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(term, value) { | ||
@@ -46,3 +46,3 @@ if (!/^(none|quarantine|reject)$/i.test(value)) { | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
@@ -54,7 +54,6 @@ pct: { | ||
| throw new Error(`Invalid value for '${term}': ${value}, must be a positive integer`); | ||
| } | ||
| else if (parseInt(value, 10) > 100 || parseInt(value, 10) < 0) { | ||
| } else if (parseInt(value, 10) > 100 || parseInt(value, 10) < 0) { | ||
| throw new Error(`Invalid value for '${term}': ${value}, must be an integer between 0 and 100`); | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
@@ -65,13 +64,15 @@ rf: { | ||
| // The RFC says the values are colon-separated but a lot of examples/docs around the net show commas... so we'll do both | ||
| let values = value.split(/,|:/).map(x => x.trim()); | ||
| let values = value.split(/,|:/).map((x) => x.trim()); | ||
| for (let val of values) { | ||
| if (!/^(afrf|iodef)$/i.test(val)) { | ||
| throw new Error(`Invalid value for '${term}': '${value}', must be one or more of these values: afrf, iodef. Multiple values must be separated by a comma or colon`); | ||
| throw new Error( | ||
| `Invalid value for '${term}': '${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.', | ||
| description: "The ri tag corresponds to the aggregate reporting interval and provides DMARC feedback for the outlined criteria.", | ||
| validate(term, value) { | ||
@@ -81,8 +82,8 @@ if (!/^\d+$/.test(value)) { | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
| rua: { | ||
| description: 'This optional tag is designed for reporting URI(s) for aggregate data. An rua example is rua=mailto:CUSTOMER@for.example.com.', | ||
| description: "This optional tag is designed for reporting URI(s) for aggregate data. An rua example is rua=mailto:CUSTOMER@for.example.com.", | ||
| validate(term, value) { | ||
| let values = value.split(/,/).map(x => x.trim()); | ||
| let values = value.split(/,/).map((x) => x.trim()); | ||
@@ -104,16 +105,16 @@ for (let val of values) { | ||
| 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]) | ||
| 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`) | ||
| } | ||
| 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.', | ||
| 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(term, value) { | ||
| let values = value.split(/,/).map(x => x.trim()); | ||
| let values = value.split(/,/).map((x) => x.trim()); | ||
@@ -135,11 +136,10 @@ for (let val of values) { | ||
| 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]) | ||
| 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`) | ||
| } | ||
| return mailtoList.join(","); | ||
| } else throw new Error(`Invalid value for 'ruf' tag`); | ||
| }, | ||
| }, | ||
@@ -152,6 +152,6 @@ sp: { | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
| aspf: { | ||
| description: 'The aspf tag represents alignment mode for SPF. An optional tag, aspf=r is a common example of its configuration.', | ||
| description: "The aspf tag represents alignment mode for SPF. An optional tag, aspf=r is a common example of its configuration.", | ||
| validate(term, value) { | ||
@@ -161,6 +161,6 @@ if (!/^(s|r)$/i.test(value)) { | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
| adkim: { | ||
| description: 'Similar to aspf, the optional adkim tag is the alignment mode for the DKIM protocol. A sample tag is adkim=r.', | ||
| description: "Similar to aspf, the optional adkim tag is the alignment mode for the DKIM protocol. A sample tag is adkim=r.", | ||
| validate(term, value) { | ||
@@ -170,6 +170,6 @@ if (!/^(s|r)$/i.test(value)) { | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| }, | ||
| }; | ||
| module.exports = validators; | ||
| module.exports = validators; |
+18
-35
@@ -1,40 +0,23 @@ | ||
| var parser = require('./bin/parser'); | ||
| var fetcher = require('./bin/fetcher'); | ||
| var generator = require('./bin/generator'); | ||
| var parser = require("./bin/parser"); | ||
| var fetcher = require("./bin/fetcher"); | ||
| var generator = require("./bin/generator"); | ||
| var recordParser = function (dmarcRecord) { | ||
| return new Promise((resolve, reject) => { | ||
| var result = parser(dmarcRecord); | ||
| if (result.messages && result.messages.length) return reject(result.messages); | ||
| resolve(result.tags); | ||
| }); | ||
| } | ||
| var recordParser = async function (dmarcRecord) { | ||
| var result = parser(dmarcRecord); | ||
| if (result.messages && result.messages.length) throw new Error(result.messages); | ||
| return result.tags; | ||
| }; | ||
| var recordFetcher = function (domainName) { | ||
| return new Promise((resolve, reject) => { | ||
| return fetcher(domainName) | ||
| .then(record => { | ||
| return recordParser(record).then(r => [r, record]); | ||
| }) | ||
| .then(([data, record]) => { | ||
| resolve({ record: record, tags: data }); | ||
| }) | ||
| .catch(err => { | ||
| reject(err); | ||
| }) | ||
| }) | ||
| } | ||
| var recordFetcher = async function (domainName) { | ||
| let record = await fetcher(domainName); | ||
| let data = await recordParser(record); | ||
| return { record: record, tags: data }; | ||
| }; | ||
| var recordGenerator = async function (values) { | ||
| return generator(values); | ||
| }; | ||
| var recordGenerator = function (values) { | ||
| return new Promise((resolve, reject) => { | ||
| try { | ||
| resolve(generator(values)) | ||
| } catch (err) { | ||
| reject(err.message) | ||
| } | ||
| }) | ||
| } | ||
| exports.parse = recordParser; | ||
| exports.fetch = recordFetcher; | ||
| exports.generate = recordGenerator; | ||
| exports.generate = recordGenerator; |
+1
-1
| { | ||
| "name": "dmarc-solution", | ||
| "version": "1.0.4", | ||
| "version": "1.0.5", | ||
| "description": "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", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
9
12.5%14375
-1.71%283
-6.29%