diff --git a/.codeclimate.yml b/.codeclimate.yml
index 1fd0569..0b9e04c 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -1,15 +1,15 @@
engines:
eslint:
enabled: true
- channel: "eslint-8"
+ channel: 'eslint-8'
config:
- config: ".eslintrc.yaml"
+ config: '.eslintrc.yaml'
ratings:
- paths:
- - "**.js"
+ paths:
+ - '**.js'
checks:
method-complexity:
config:
- threshold: 10
\ No newline at end of file
+ threshold: 10
diff --git a/.eslintrc.yaml b/.eslintrc.yaml
index fe947ea..9fe535c 100644
--- a/.eslintrc.yaml
+++ b/.eslintrc.yaml
@@ -2,24 +2,10 @@ env:
node: true
es6: true
mocha: true
- es2020: true
-
-plugins:
- - haraka
+ es2022: true
extends:
- - eslint:recommended
- - plugin:haraka/recommended
+ - '@haraka'
rules:
- indent: [2, 2, {"SwitchCase": 1}]
-
-root: true
-
-globals:
- OK: true
- CONT: true
- DENY: true
- DENYSOFT: true
- DENYDISCONNECT: true
- DENYSOFTDISCONNECT: true
+ no-unused-vars: 1
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3c40dcc..7924e85 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,6 +2,7 @@ name: CI
on:
push:
+ pull_request:
env:
CI: true
@@ -14,23 +15,10 @@ jobs:
# uses: haraka/.github/.github/workflows/coverage.yml@master
# secrets: inherit
- test:
- needs: lint
- runs-on: ${{ matrix.os }}
- strategy:
- matrix:
- os: [ ubuntu-latest, windows-latest ]
- node-version: [ 14, 16, 18 ]
- fail-fast: false
+ ubuntu:
+ needs: [lint]
+ uses: haraka/.github/.github/workflows/ubuntu.yml@master
- steps:
- - uses: actions/checkout@v3
-
- - uses: actions/setup-node@v3
- name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
- with:
- node-version: ${{ matrix.node-version }}
-
- - run: npm install
-
- - run: npm test
+ windows:
+ needs: [lint]
+ uses: haraka/.github/.github/workflows/windows.yml@master
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 3627451..8314a66 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -2,10 +2,10 @@ name: CodeQL
on:
push:
- branches: [ master ]
+ branches: [master]
pull_request:
# The branches below must be a subset of the branches above
- branches: [ master ]
+ branches: [master]
schedule:
- cron: '18 7 * * 4'
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index d489fbd..e81c15f 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -13,4 +13,4 @@ env:
jobs:
publish:
uses: haraka/.github/.github/workflows/publish.yml@master
- secrets: inherit
\ No newline at end of file
+ secrets: inherit
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..8ded5e0
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,2 @@
+singleQuote: true
+semi: false
diff --git a/.release b/.release
index 0890e94..afb1db8 160000
--- a/.release
+++ b/.release
@@ -1 +1 @@
-Subproject commit 0890e945e4e061c96c7b2ab45017525904c17728
+Subproject commit afb1db801607dda5e859f39b600f0dd0111e4651
diff --git a/Changes.md b/CHANGELOG.md
similarity index 61%
rename from Changes.md
rename to CHANGELOG.md
index 22e6776..1b95b3e 100644
--- a/Changes.md
+++ b/CHANGELOG.md
@@ -1,18 +1,28 @@
+# Changelog
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/).
+
### Unreleased
+### [2.0.3] - 2023-12-13
+
+- ci: use shared ci workflows
+- confirm maxmind db has loaded before registering hook #23
+- populate [files] in package.json
+- dep: eslint-plugin-haraka -> @haraka/eslint-config
+- lint: remove duplicate / stale rules from .eslintrc
+- doc: renamed Changes.md -> CHANGELOG.md
### 2.0.2 - 2023-02-07
- fix: catching DNS timeout exception
-
### 2.0.1 - 2022-05-27
- fix: when adding headers, assure ASN is string
- fix: when adding header, look in correct location for asn.org
- when create conn note, only assign properties with values
-
### 2.0.0 - 2022-05-23
- style: replace most callbacks with async/await
@@ -20,7 +30,6 @@
- asn.ini: switch default dns provider to rspamd
- dep: remove async
-
### 1.0.9 - 2022-05-22
- ci: add GitHub Actions CI, #17
@@ -30,7 +39,6 @@
- style: more es6/7
- dep(async): bump version to 3.2
-
### 1.0.8 - 2018-01-22
- parse maxmind ASN w/o Org data
@@ -39,18 +47,15 @@
- added parse_rspamd test
- emit rspamd DNS provider results (when enabled)
-
### 1.0.7 - 2017-02-06
- updated eslint to use eslint-plugin-haraka
- aggregate results before emitting
-
### 1.0.6 - 2016-10-20
-* when protocols[setting]=false, don't enable that protocol
- * ie, do what the config implies
-
+- when protocols[setting]=false, don't enable that protocol
+ - ie, do what the config implies
### 1.0.5 - 2016-10-08
@@ -62,5 +67,8 @@
### 1.0.0 - 2016-07-21
-
-[2.0.2]: https://github.com/haraka/haraka-plugin-asn/releases/tag/2.0.2
+[1.0.9]: https://github.com/haraka/haraka-plugin-asn/releases/tag/v1.0.9
+[2.0.0]: https://github.com/haraka/haraka-plugin-asn/releases/tag/v2.0.0
+[2.0.1]: https://github.com/haraka/haraka-plugin-asn/releases/tag/2.0.1
+[2.0.2]: https://github.com/haraka/haraka-plugin-asn/releases/tag/v2.0.2
+[2.0.3]: https://github.com/haraka/haraka-plugin-asn/releases/tag/2.0.3
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
new file mode 100644
index 0000000..028df07
--- /dev/null
+++ b/CONTRIBUTORS.md
@@ -0,0 +1,8 @@
+# Contributors
+
+This handcrafted artisinal software is brought to you by:
+
+|
msimerson (26) |
analogic (1) |
lnedry (1) |
+| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+
+this file is maintained by [.release](https://github.com/msimerson/.release)
diff --git a/README.md b/README.md
index a3cc681..cfd26db 100644
--- a/README.md
+++ b/README.md
@@ -6,21 +6,18 @@
look up ASN from local GeoIP databases and/or DNS based providers.
-
### DNS providers
-* origin.asn.cymru.com
-* asn.routeviews.org
-* asn.rspamd.com
-
+- origin.asn.cymru.com
+- asn.routeviews.org
+- asn.rspamd.com
### Databases
-* MaxMind ASN database
+- MaxMind ASN database
PS: Run something like [maxmind-geolite-mirror](https://www.npmjs.com/package/maxmind-geolite-mirror) weekly to keep your database files up-to-date.
-
[ci-img]: https://github.com/haraka/haraka-plugin-asn/actions/workflows/ci.yml/badge.svg
[ci-url]: https://github.com/haraka/haraka-plugin-asn/actions/workflows/ci.yml
[clim-img]: https://codeclimate.com/github/haraka/haraka-plugin-asn/badges/gpa.svg
diff --git a/index.js b/index.js
index e25f317..44e5344 100644
--- a/index.js
+++ b/index.js
@@ -1,232 +1,237 @@
// determine the ASN of the connecting IP
-// node built-ins
-const dns = require('dns').promises;
-const fs = require('fs/promises');
-const path = require('path')
-
-let test_ip = '66.128.51.163';
-const providers = [];
-let conf_providers = [ 'origin.asn.cymru.com', 'asn.routeviews.org', 'asn.rspamd.com' ];
+const dns = require('node:dns').promises
+const fs = require('node:fs/promises')
+const path = require('node:path')
+
+let test_ip = '66.128.51.163'
+const providers = []
+let conf_providers = [
+ 'origin.asn.cymru.com',
+ 'asn.routeviews.org',
+ 'asn.rspamd.com',
+]
exports.register = async function () {
- this.registered = false;
+ this.registered = false
- this.load_asn_ini();
+ this.load_asn_ini()
- await this.test_and_register_dns_providers();
- await this.test_and_register_geoip();
+ await this.test_and_register_dns_providers()
+ await this.test_and_register_geoip()
if (this.cfg.header.asn) {
- this.register_hook('data_post', 'add_header_asn');
+ this.register_hook('data_post', 'add_header_asn')
}
if (this.cfg.header.provider) {
- this.register_hook('data_post', 'add_header_provider');
+ this.register_hook('data_post', 'add_header_provider')
}
}
exports.test_and_register_dns_providers = async function () {
- if (!this.cfg.protocols.dns) return; // disabled in config
+ if (!this.cfg.protocols.dns) return // disabled in config
for (const zone of conf_providers) {
try {
const res = await this.get_dns_results(zone, test_ip)
if (!res) {
- this.logerror(this, `${zone} failed`);
- continue;
+ this.logerror(this, `${zone} failed`)
+ continue
}
- this.logdebug(this, `${zone} succeeded`);
+ this.logdebug(this, `${zone} succeeded`)
- if (!providers.includes(zone)) providers.push(zone);
- if (this.registered) continue;
- this.registered = true;
- this.register_hook('lookup_rdns', 'lookup_via_dns');
- }
- catch (err) {
- this.logerror(this, `zone ${zone} encountered ${err.message}`);
+ if (!providers.includes(zone)) providers.push(zone)
+ if (this.registered) continue
+ this.registered = true
+ this.register_hook('lookup_rdns', 'lookup_via_dns')
+ } catch (err) {
+ this.logerror(this, `zone ${zone} encountered ${err.message}`)
}
}
return providers
}
exports.load_asn_ini = function () {
- const plugin = this;
- plugin.cfg = plugin.config.get('asn.ini', {
- booleans: [
- '+header.asn',
- '-header.provider',
- '+protocols.dns',
- '+protocols.geoip',
- ]
- },
- function () {
- plugin.load_asn_ini();
- });
-
- const c = plugin.cfg;
+ const plugin = this
+ plugin.cfg = plugin.config.get(
+ 'asn.ini',
+ {
+ booleans: [
+ '+header.asn',
+ '-header.provider',
+ '+protocols.dns',
+ '+protocols.geoip',
+ ],
+ },
+ function () {
+ plugin.load_asn_ini()
+ },
+ )
+
+ const c = plugin.cfg
if (c.main.providers !== undefined) {
if (c.main.providers === '') {
- conf_providers = [];
- }
- else {
- conf_providers = c.main.providers.split(/[\s,;]+/);
+ conf_providers = []
+ } else {
+ conf_providers = c.main.providers.split(/[\s,;]+/)
}
}
- if (c.main.test_ip) test_ip = c.main.test_ip;
-
- // backwards compat with old config settings (Sunset 3.0)
- if (c.main.asn_header !== undefined) c.header.asn = c.main.asn_header;
- if (c.main.provider_header !== undefined) c.header.provider = c.main.provider_header;
+ if (c.main.test_ip) test_ip = c.main.test_ip
}
exports.get_dns_results = async function (zone, ip) {
- const query = `${ip.split('.').reverse().join('.')}.${zone}`;
+ const query = `${ip.split('.').reverse().join('.')}.${zone}`
const timeout = (prom, time, exception) => {
- let timer;
+ let timer
return Promise.race([
prom,
- new Promise((_r, rej) => timer = setTimeout(rej, time, exception))
- ]).finally(() => clearTimeout(timer));
+ new Promise((_r, rej) => (timer = setTimeout(rej, time, exception))),
+ ]).finally(() => clearTimeout(timer))
}
try {
const addrs = await timeout(
dns.resolveTxt(query),
(this.cfg.main.timeout || 4) * 1000,
- new Error(`${zone} timeout`)
- );
+ new Error(`${zone} timeout`),
+ )
if (!addrs || !addrs[0]) {
- this.logerror(this, `no results for ${query}`);
+ this.logerror(this, `no results for ${query}`)
return
}
- const first = addrs[0];
+ const first = addrs[0]
- this.logdebug(this, `${zone} answers: ${first}`);
+ this.logdebug(this, `${zone} answers: ${first}`)
- return this.get_result(zone, first);
- }
- catch (err) {
- this.logerror(this, `error: ${err} running: ${query}`);
+ return this.get_result(zone, first)
+ } catch (err) {
+ this.logerror(this, `error: ${err} running: ${query}`)
}
-
}
exports.get_result = function (zone, first) {
-
switch (zone) {
- case 'origin.asn.cymru.com' : return this.parse_cymru(first.join(''));
- case 'asn.routeviews.org' : return this.parse_routeviews(first);
- case 'asn.rspamd.com' : return this.parse_rspamd(first.join(''));
- case 'origin.asn.spameatingmonkey.net': return this.parse_monkey(first.join(''));
+ case 'origin.asn.cymru.com':
+ return this.parse_cymru(first.join(''))
+ case 'asn.routeviews.org':
+ return this.parse_routeviews(first)
+ case 'asn.rspamd.com':
+ return this.parse_rspamd(first.join(''))
+ case 'origin.asn.spameatingmonkey.net':
+ return this.parse_monkey(first.join(''))
}
- this.logerror(this, `unrecognized ASN provider: ${zone}`);
- return;
+ this.logerror(this, `unrecognized ASN provider: ${zone}`)
+ return
}
exports.lookup_via_dns = function (next, connection) {
- const plugin = this;
- if (connection.remote.is_private) return next();
+ if (connection.remote.is_private) return next()
const promises = []
for (const zone of providers) {
- promises.push(new Promise(resolve => {
- // connection.logdebug(plugin, `zone: ${zone}`);
-
- try {
-
- plugin.get_dns_results(zone, connection.remote.ip).then(r => {
- if (!r) return resolve();
-
- const results = { emit: true };
-
- // store asn & net from any source
- if (r.asn) results.asn = r.asn;
- if (r.net) results.net = r.net;
-
- // store provider specific results
- switch (zone) {
- case 'origin.asn.cymru.com':
- results.cymru = r;
- break;
- case 'asn.routeviews.org':
- results.routeviews = r;
- break;
- case 'origin.asn.spameatingmonkey.net':
- results.monkey = r;
- break;
- case 'asn.rspamd.com':
- results.rspamd = r;
- break;
- }
-
- connection.results.add(plugin, results);
- resolve(results);
- })
- }
- catch (err) {
- connection.results.add(plugin, { err })
- resolve();
- }
- }))
+ promises.push(
+ new Promise((resolve) => {
+ // connection.logdebug(plugin, `zone: ${zone}`);
+
+ try {
+ this.get_dns_results(zone, connection.remote.ip).then((r) => {
+ if (!r) return resolve()
+
+ const results = { emit: true }
+
+ // store asn & net from any source
+ if (r.asn) results.asn = r.asn
+ if (r.net) results.net = r.net
+
+ // store provider specific results
+ switch (zone) {
+ case 'origin.asn.cymru.com':
+ results.cymru = r
+ break
+ case 'asn.routeviews.org':
+ results.routeviews = r
+ break
+ case 'origin.asn.spameatingmonkey.net':
+ results.monkey = r
+ break
+ case 'asn.rspamd.com':
+ results.rspamd = r
+ break
+ }
+
+ connection.results.add(this, results)
+ resolve(results)
+ })
+ } catch (err) {
+ connection.results.add(this, { err })
+ resolve()
+ }
+ }),
+ )
}
Promise.all(promises).then(next)
}
exports.parse_routeviews = function (thing) {
- let labels;
+ let labels
if (typeof thing === 'string' && /,/.test(thing)) {
- labels = thing.split(',');
- return { asn: labels[0], net: `${labels[1]}/${labels[2]}` };
+ labels = thing.split(',')
+ return { asn: labels[0], net: `${labels[1]}/${labels[2]}` }
}
// this is a correct result (node >= 0.10.26)
// 99.177.75.208.asn.routeviews.org. IN TXT "40431" "208.75.176.0" "21"
if (Array.isArray(thing)) {
- labels = thing;
- }
- else {
+ labels = thing
+ } else {
// this is what node (< 0.10.26) returns
// 99.177.75.208.asn.routeviews.org. IN TXT "40431208.75.176.021"
- labels = thing.split(/ /);
+ labels = thing.split(/ /)
}
if (labels.length !== 3) {
- this.logerror(this, `result length not 3: ${labels.length} string="${thing}"`);
- return;
+ this.logerror(
+ this,
+ `result length not 3: ${labels.length} string="${thing}"`,
+ )
+ return
}
- return { asn: labels[0], net: `${labels[1]}/${labels[2]}` };
+ return { asn: labels[0], net: `${labels[1]}/${labels[2]}` }
}
exports.parse_cymru = function (str) {
- const r = str.split(/\s+\|\s*/);
+ const r = str.split(/\s+\|\s*/)
// 99.177.75.208.origin.asn.cymru.com. 14350 IN TXT
// "40431 | 208.75.176.0/21 | US | arin | 2007-03-02"
// "10290 | 12.129.48.0/24 | US | arin |"
if (r.length < 4) {
- this.logerror(this, `cymru: bad result length ${r.length} string="${str}"`);
- return;
+ this.logerror(this, `cymru: bad result length ${r.length} string="${str}"`)
+ return
}
- return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] };
+ return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] }
}
exports.parse_monkey = function (str) {
- const plugin = this;
- const r = str.split(/\s+\|\s+/);
+ const plugin = this
+ const r = str.split(/\s+\|\s+/)
// "74.125.44.0/23 | AS15169 | Google Inc. | 2000-03-30"
// "74.125.0.0/16 | AS15169 | Google Inc. | 2000-03-30 | US"
if (r.length < 3) {
- plugin.logerror(plugin, `monkey: bad result length ${r.length} string="${str}"`);
- return;
+ plugin.logerror(
+ plugin,
+ `monkey: bad result length ${r.length} string="${str}"`,
+ )
+ return
}
return {
asn: r[1].substring(2),
@@ -234,81 +239,81 @@ exports.parse_monkey = function (str) {
org: r[2],
date: r[3],
country: r[4],
- };
+ }
}
exports.parse_rspamd = function (str) {
- const plugin = this;
- const r = str.split(/\s*\|\s*/);
+ const plugin = this
+ const r = str.split(/\s*\|\s*/)
// 8.8.8.8.asn.rspamd.com. 14350 IN TXT
// "15169|8.8.8.0/24|US|arin|"
if (r.length < 4) {
- plugin.logerror(plugin, `rspamd: bad result length ${r.length} string="${str}"`);
- return;
+ plugin.logerror(
+ plugin,
+ `rspamd: bad result length ${r.length} string="${str}"`,
+ )
+ return
}
- return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] };
+ return { asn: r[0], net: r[1], country: r[2], assignor: r[3], date: r[4] }
}
exports.add_header_asn = function (next, connection) {
-
- const asn = connection.results.get('asn');
- if (!asn?.asn) return next();
- if (!connection.transaction) return next();
+ const asn = connection.results.get('asn')
+ if (!asn?.asn) return next()
+ if (!connection.transaction) return next()
if (asn.net) {
- connection.transaction.add_header('X-Haraka-ASN', `${asn.asn} ${asn.net}`);
- }
- else {
- connection.transaction.add_header('X-Haraka-ASN', `${asn.asn}`);
+ connection.transaction.add_header('X-Haraka-ASN', `${asn.asn} ${asn.net}`)
+ } else {
+ connection.transaction.add_header('X-Haraka-ASN', `${asn.asn}`)
}
if (asn.org) {
- connection.transaction.add_header('X-Haraka-ASN-Org', `${asn.org}`);
+ connection.transaction.add_header('X-Haraka-ASN-Org', `${asn.org}`)
}
- next();
+ next()
}
exports.add_header_provider = function (next, connection) {
-
- const asn = connection.results.get('asn');
- if (!asn?.asn) return next();
+ const asn = connection.results.get('asn')
+ if (!asn?.asn) return next()
for (const p in asn) {
- if (!asn[p].asn) continue; // ignore non-object results
+ if (!asn[p].asn) continue // ignore non-object results
- const name = `X-Haraka-ASN-${p.toUpperCase()}`;
- const values = [];
+ const name = `X-Haraka-ASN-${p.toUpperCase()}`
+ const values = []
for (const k in asn[p]) {
- values.push(`${k}=${asn[p][k]}`);
+ values.push(`${k}=${asn[p][k]}`)
}
- if (values.length === 0) continue;
- connection.transaction.add_header(name, values.join(' '));
+ if (values.length === 0) continue
+ connection.transaction.add_header(name, values.join(' '))
}
- next();
+ next()
}
exports.test_and_register_geoip = async function () {
- if (!this.cfg.protocols.geoip) return; // disabled in config
+ if (!this.cfg.protocols.geoip) return // disabled in config
try {
- this.maxmind = require('maxmind');
+ this.maxmind = require('maxmind')
if (await this.load_dbs()) {
- this.register_hook('connect', 'lookup_via_maxmind');
+ this.register_hook('connect', 'lookup_via_maxmind')
}
- }
- catch (e) {
- this.logerror(e);
- this.logerror("unable to load maxmind, try\n\n\t'npm install -g maxmind@0.6'\n\n");
+ } catch (e) {
+ this.logerror(e)
+ this.logerror(
+ "unable to load maxmind, try\n\n\t'npm install -g maxmind@0.6'\n\n",
+ )
}
}
exports.load_dbs = async function () {
-
- this.dbsLoaded = 0;
- const dbdir = this.cfg.main.dbdir || '/usr/local/share/GeoIP/';
- const dbPath = path.join(dbdir, `GeoLite2-ASN.mmdb`);
+ this.dbsLoaded = 0
+ const dbdir = this.cfg.main.dbdir || '/usr/local/share/GeoIP/'
+ const dbPath = path.join(dbdir, `GeoLite2-ASN.mmdb`)
try {
await fs.access(dbPath)
@@ -318,14 +323,13 @@ exports.load_dbs = async function () {
watchForUpdates: true,
cache: {
max: 1000, // max items in cache
- maxAge: 1000 * 60 * 60 // life time in milliseconds
- }
+ maxAge: 1000 * 60 * 60, // life time in milliseconds
+ },
})
- this.loginfo(`loaded maxmind db ${dbPath}`);
- this.dbsLoaded++;
- }
- catch (e) {
+ this.loginfo(`loaded maxmind db ${dbPath}`)
+ this.dbsLoaded++
+ } catch (e) {
console.error(e)
this.loginfo(`missing [access to] DB ${dbPath}`)
}
@@ -334,15 +338,19 @@ exports.load_dbs = async function () {
}
exports.lookup_via_maxmind = function (next, connection) {
- if (!this.maxmind || !this.dbsLoaded) return next();
+ if (!this.maxmind || !this.dbsLoaded) return next()
const asn = this.lookup.get(connection.remote.ip)
if (asn?.autonomous_system_number || asn?.autonomous_system_organization) {
connection.results.add(this, {
- ...(asn.autonomous_system_number ? { asn: asn.autonomous_system_number } : {}),
- ...(asn.autonomous_system_organization ? { org: asn.autonomous_system_organization } : {}),
- });
+ ...(asn.autonomous_system_number
+ ? { asn: asn.autonomous_system_number }
+ : {}),
+ ...(asn.autonomous_system_organization
+ ? { org: asn.autonomous_system_organization }
+ : {}),
+ })
}
- next();
+ next()
}
diff --git a/package.json b/package.json
index 425d9cd..49e297a 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,21 @@
{
"name": "haraka-plugin-asn",
- "version": "2.0.2",
+ "version": "2.0.3",
"description": "look up ASN of remote MTA",
"main": "index.js",
+ "files": [
+ "CHANGELOG.md",
+ "config"
+ ],
"scripts": {
- "test": "npx mocha --exit",
- "lint": "npx eslint *.js test",
- "lintfix": "npx eslint --fix *.js test",
- "versions": "npx dependency-version-checker check"
+ "format": "npm run prettier:fix && npm run lint:fix",
+ "lint": "npx eslint@^8 *.js test",
+ "lint:fix": "npx eslint@^8 *.js test --fix",
+ "prettier": "npx prettier . --check",
+ "prettier:fix": "npx prettier . --write --log-level=warn",
+ "test": "npx mocha@^10 --exit",
+ "versions": "npx dependency-version-checker check",
+ "versions:fix": "npx dependency-version-checker update"
},
"repository": {
"type": "git",
@@ -26,12 +34,10 @@
},
"homepage": "https://github.com/haraka/haraka-plugin-asn#readme",
"dependencies": {
- "maxmind": "^4.3.6"
+ "maxmind": "^4.3.19"
},
"devDependencies": {
- "eslint": ">=8",
- "eslint-plugin-haraka": ">=1.0.14",
- "haraka-test-fixtures": ">=1.0.34",
- "mocha": ">=9"
+ "@haraka/eslint-config": "^1.1.5",
+ "haraka-test-fixtures": "^1.3.7"
}
}
diff --git a/test/asn.js b/test/asn.js
index 28f7f83..874209b 100644
--- a/test/asn.js
+++ b/test/asn.js
@@ -1,191 +1,194 @@
-'use strict';
+'use strict'
-// node build-in modules
-const assert = require('assert');
+const assert = require('node:assert')
// npm installed modules
-const fixtures = require('haraka-test-fixtures');
+const fixtures = require('haraka-test-fixtures')
describe('parse_monkey', function () {
-
- const asn = new fixtures.plugin('asn');
+ const asn = new fixtures.plugin('asn')
it('parses AS 15169/23', function () {
assert.deepEqual(
asn.parse_monkey('74.125.44.0/23 | AS15169 | Google Inc. | 2000-03-30'),
- { net: '74.125.44.0/23', asn: '15169', org: 'Google Inc.',
- date: '2000-03-30', country: undefined,
- }
+ {
+ net: '74.125.44.0/23',
+ asn: '15169',
+ org: 'Google Inc.',
+ date: '2000-03-30',
+ country: undefined,
+ },
)
})
it('parses AS 15169/16', function () {
assert.deepEqual(
- asn.parse_monkey('74.125.0.0/16 | AS15169 | Google Inc. | 2000-03-30 | US'),
- { net: '74.125.0.0/16', asn: '15169', org: 'Google Inc.',
- date: '2000-03-30', country: 'US',
- }
+ asn.parse_monkey(
+ '74.125.0.0/16 | AS15169 | Google Inc. | 2000-03-30 | US',
+ ),
+ {
+ net: '74.125.0.0/16',
+ asn: '15169',
+ org: 'Google Inc.',
+ date: '2000-03-30',
+ country: 'US',
+ },
)
})
})
describe('parse_routeviews', function () {
-
- const asn = new fixtures.plugin('asn');
+ const asn = new fixtures.plugin('asn')
it('40431 string, asn-only', function () {
- assert.deepEqual(
- asn.parse_routeviews('40431'),
- undefined
- )
+ assert.deepEqual(asn.parse_routeviews('40431'), undefined)
})
it('40431 string', function () {
- assert.deepEqual(
- asn.parse_routeviews('40431 208.75.176.0 21'),
- {
- asn: '40431', net: '208.75.176.0/21',
- }
- );
- });
+ assert.deepEqual(asn.parse_routeviews('40431 208.75.176.0 21'), {
+ asn: '40431',
+ net: '208.75.176.0/21',
+ })
+ })
it('15169 CSV string', function () {
- assert.deepEqual(
- asn.parse_routeviews('15169,8.8.8.0,24'), { asn: '15169', net: '8.8.8.0/24' }
- )
+ assert.deepEqual(asn.parse_routeviews('15169,8.8.8.0,24'), {
+ asn: '15169',
+ net: '8.8.8.0/24',
+ })
})
it('40431 array', function () {
- assert.deepEqual(
- asn.parse_routeviews(['40431','208.75.176.0','21']),
- { asn: '40431', net: '208.75.176.0/21' }
- )
+ assert.deepEqual(asn.parse_routeviews(['40431', '208.75.176.0', '21']), {
+ asn: '40431',
+ net: '208.75.176.0/21',
+ })
})
})
describe('parse_cymru', function () {
-
- const asn = new fixtures.plugin('asn');
+ const asn = new fixtures.plugin('asn')
it('40431', function () {
assert.deepEqual(
asn.parse_cymru('40431 | 208.75.176.0/21 | US | arin | 2007-03-02'),
- { asn: '40431', net: '208.75.176.0/21', country: 'US',
- assignor: 'arin', date: '2007-03-02',
- }
- );
- });
+ {
+ asn: '40431',
+ net: '208.75.176.0/21',
+ country: 'US',
+ assignor: 'arin',
+ date: '2007-03-02',
+ },
+ )
+ })
it('10290', function () {
- assert.deepEqual(
- asn.parse_cymru('10290 | 12.129.48.0/24 | US | arin |'),
- { asn: '10290', net: '12.129.48.0/24', country: 'US',
- assignor: 'arin', date: '',
- }
- )
+ assert.deepEqual(asn.parse_cymru('10290 | 12.129.48.0/24 | US | arin |'), {
+ asn: '10290',
+ net: '12.129.48.0/24',
+ country: 'US',
+ assignor: 'arin',
+ date: '',
+ })
})
})
describe('parse_rspamd', function () {
-
- const asn = new fixtures.plugin('asn');
+ const asn = new fixtures.plugin('asn')
it('40431', function () {
- assert.deepEqual(
- asn.parse_rspamd('15169|8.8.8.0/24|US|arin|'),
- {
- asn: '15169', net: '8.8.8.0/24', country: 'US',
- assignor: 'arin', date: '',
- }
- )
+ assert.deepEqual(asn.parse_rspamd('15169|8.8.8.0/24|US|arin|'), {
+ asn: '15169',
+ net: '8.8.8.0/24',
+ country: 'US',
+ assignor: 'arin',
+ date: '',
+ })
})
})
describe('get_dns_results', function () {
-
- const asn = new fixtures.plugin('asn');
- asn.cfg = { main: { }, protocols: { dns: true } };
- asn.connection = fixtures.connection.createConnection();
+ const asn = new fixtures.plugin('asn')
+ asn.cfg = { main: {}, protocols: { dns: true } }
+ asn.connection = fixtures.connection.createConnection()
it('origin.asn.cymru.com', function (done) {
- this.timeout(4000)
- asn.get_dns_results('origin.asn.cymru.com', '8.8.8.8').then(obj => {
+ this.timeout(5000)
+ asn.get_dns_results('origin.asn.cymru.com', '8.8.8.8').then((obj) => {
if (obj) {
- assert.equal('15169', obj.asn);
- assert.equal('8.8.8.0/24', obj.net);
- }
- else {
- assert.equal('something', obj);
+ assert.equal('15169', obj.asn)
+ assert.equal('8.8.8.0/24', obj.net)
+ } else {
+ assert.equal('something', obj)
}
- done();
+ done()
})
})
it('asn.routeviews.org', function (done) {
- asn.get_dns_results('asn.routeviews.org', '8.8.8.8').then(obj => {
+ this.timeout(5000)
+ asn.get_dns_results('asn.routeviews.org', '8.8.8.8').then((obj) => {
if (obj) {
if (obj.asn && obj.asn === '15169') {
- assert.equal('15169', obj.asn);
+ assert.equal('15169', obj.asn)
}
+ } else {
+ assert.ok('Node DNS (c-ares) bug')
}
- else {
- assert.ok("Node DNS (c-ares) bug");
- }
- done();
- });
- });
+ done()
+ })
+ })
it('asn.rspamd.com', function (done) {
- this.timeout(3000);
+ this.timeout(5000)
asn.get_dns_results('asn.rspamd.com', '8.8.8.8').then((obj, zone) => {
if (obj) {
- assert.equal('15169', obj.asn);
- assert.equal('8.8.8.0/24', obj.net);
+ assert.equal('15169', obj.asn)
+ assert.equal('8.8.8.0/24', obj.net)
+ } else {
+ assert.equal('something', obj)
}
- else {
- assert.equal('something', obj);
- }
- done();
+ done()
})
})
it('origin.asn.spameatingmonkey.net', (done) => {
- this.timeout(3000);
- asn.get_dns_results('origin.asn.spameatingmonkey.net', '8.8.8.8').then((obj, zone) => {
- if (obj) {
- assert.equal('15169', obj.asn);
- assert.equal('8.8.8.0/24', obj.net);
- }
- else {
- assert.equal('something', obj);
- }
- done();
- })
+ this.timeout(5000)
+ asn
+ .get_dns_results('origin.asn.spameatingmonkey.net', '8.8.8.8')
+ .then((obj, zone) => {
+ if (obj) {
+ assert.equal('15169', obj.asn)
+ assert.equal('8.8.8.0/24', obj.net)
+ } else {
+ assert.equal('something', obj)
+ }
+ done()
+ })
})
})
describe('lookup_via_dns', function () {
it('returns results from active providers', function (done) {
- const asn = new fixtures.plugin('asn');
- asn.cfg = { main: { }, protocols: { dns: true } };
- const connection = fixtures.connection.createConnection();
- connection.remote.ip='66.128.51.163';
+ this.timeout(5000)
+ const asn = new fixtures.plugin('asn')
+ asn.cfg = { main: {}, protocols: { dns: true } }
+ const connection = fixtures.connection.createConnection()
+ connection.remote.ip = '66.128.51.163'
asn.test_and_register_dns_providers().then((providers) => {
asn.lookup_via_dns((r) => {
assert.ok(r.length)
done()
- },
- connection)
+ }, connection)
})
})
})
describe('maxmind geoip db', () => {
-
it('test_and_register_geoip', (done) => {
- const asn = new fixtures.plugin('asn');
- asn.cfg = { main: { }, protocols: { geoip: true } };
+ const asn = new fixtures.plugin('asn')
+ asn.cfg = { main: {}, protocols: { geoip: true } }
asn.test_and_register_geoip().then((r) => {
// console.log(r)
assert.ok(asn.maxmind)
@@ -194,44 +197,40 @@ describe('maxmind geoip db', () => {
})
it('lookup_via_maxmind, IPv4', (done) => {
- const asn = new fixtures.plugin('asn');
- asn.cfg = { main: { }, protocols: { geoip: true } };
- asn.connection = fixtures.connection.createConnection();
- asn.connection.remote.ip='8.8.8.8';
+ const asn = new fixtures.plugin('asn')
+ asn.cfg = { main: {}, protocols: { geoip: true } }
+ asn.connection = fixtures.connection.createConnection()
+ asn.connection.remote.ip = '8.8.8.8'
asn.test_and_register_geoip().then(() => {
asn.lookup_via_maxmind(() => {
if (asn.dbsLoaded) {
- const res = asn.connection.results.get('asn');
- assert.equal(res.asn, 15169);
- assert.equal(res.org, 'GOOGLE');
- }
- else {
- console.error('no DBs found');
+ const res = asn.connection.results.get('asn')
+ assert.equal(res.asn, 15169)
+ assert.equal(res.org, 'GOOGLE')
+ } else {
+ console.error('no DBs found')
}
- done();
- },
- asn.connection);
+ done()
+ }, asn.connection)
})
})
it('maxmind AS with org', (done) => {
- const asn = new fixtures.plugin('asn');
- asn.cfg = { main: { }, protocols: { geoip: true } };
- asn.connection = fixtures.connection.createConnection();
- asn.connection.remote.ip='1.1.1.1';
+ const asn = new fixtures.plugin('asn')
+ asn.cfg = { main: {}, protocols: { geoip: true } }
+ asn.connection = fixtures.connection.createConnection()
+ asn.connection.remote.ip = '1.1.1.1'
asn.test_and_register_geoip().then(() => {
try {
asn.lookup_via_maxmind(() => {
if (asn.dbsLoaded) {
- const res = asn.connection.results.get('asn');
- assert.equal(res?.asn, 13335);
- assert.equal(res?.org, 'CLOUDFLARENET');
+ const res = asn.connection.results.get('asn')
+ assert.equal(res?.asn, 13335)
+ assert.equal(res?.org, 'CLOUDFLARENET')
}
done()
- },
- asn.connection);
- }
- catch (e) {
+ }, asn.connection)
+ } catch (e) {
console.error(e)
done()
}