@profullstack/nichedb 0.37.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +62 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { homedir, tmpdir } from 'node:os';
|
|
|
15
15
|
import { join } from 'node:path';
|
|
16
16
|
import { createInterface } from 'node:readline';
|
|
17
17
|
|
|
18
|
-
export const VERSION = '0.
|
|
18
|
+
export const VERSION = '0.40.0';
|
|
19
19
|
const GEO_FLAGS = ['lat', 'long', 'radius', 'unit', 'bbox', 'sort', 'offset'];
|
|
20
20
|
const DEFAULT_API = process.env.NICHEDB_API ?? 'https://nichedb.dev';
|
|
21
21
|
const CONFIG_DIR = join(process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config'), 'nichedb');
|
|
@@ -236,6 +236,20 @@ export const COMMANDS = [
|
|
|
236
236
|
'--json',
|
|
237
237
|
],
|
|
238
238
|
},
|
|
239
|
+
{
|
|
240
|
+
name: 'reputation',
|
|
241
|
+
usage: 'reputation <ip-or-domain>',
|
|
242
|
+
summary:
|
|
243
|
+
'Is an IP or a domain on a blocklist? nichedb /traffic (human-reviewed bans), abuse.ch malware feeds, SURBL and live DNS blocklists (Spamhaus ZEN/DBL, SpamCop, PSBL, Mailspike, URIBL) in one answer; a domain is also checked on each address it resolves to. Exits 1 when listed.',
|
|
244
|
+
options: ['--json'],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: 'traffic',
|
|
248
|
+
usage: 'traffic [<ip>] [--days <n>] [--category <c>] [--txt]',
|
|
249
|
+
summary:
|
|
250
|
+
'The human-reviewed /traffic IP blocklist: newest approvals, one address, or --txt for a fail2ban/nftables-ready list. Exits 1 when an address is listed.',
|
|
251
|
+
options: ['--days <n>', '--category <c>', '--limit <n>', '--offset <n>', '--txt', '--json'],
|
|
252
|
+
},
|
|
239
253
|
{
|
|
240
254
|
name: 'profiles',
|
|
241
255
|
usage:
|
|
@@ -1048,6 +1062,53 @@ export async function run(
|
|
|
1048
1062
|
for (const l of r.lookUpYourself) out(`${pad(l.name, 44)} ${l.url}`);
|
|
1049
1063
|
return 0;
|
|
1050
1064
|
}
|
|
1065
|
+
case 'reputation': {
|
|
1066
|
+
const indicator = rest[0];
|
|
1067
|
+
if (!indicator) throw new Error('reputation <ip-or-domain>');
|
|
1068
|
+
const r = await client.get(`/api/v1/reputation/${encodeURIComponent(indicator)}`);
|
|
1069
|
+
if (json) {
|
|
1070
|
+
out(JSON.stringify(r, null, 2));
|
|
1071
|
+
return 0;
|
|
1072
|
+
}
|
|
1073
|
+
out(`${r.query}: ${r.listed ? `LISTED, score ${r.score}/100` : 'not listed'}`);
|
|
1074
|
+
for (const reason of r.reasons) out(` ${reason}`);
|
|
1075
|
+
for (const a of r.addresses ?? [])
|
|
1076
|
+
out(` resolves to ${a.ip}: ${a.listed ? 'LISTED' : 'not listed'}`);
|
|
1077
|
+
if (r.unknown?.length) out(` could not ask: ${r.unknown.join(', ')}`);
|
|
1078
|
+
if (r.note) out(` ${r.note}`);
|
|
1079
|
+
out(` checked: ${r.checked.map((c) => c.name).join('; ')}`);
|
|
1080
|
+
out(` deeper: ${r.deeper.url}`);
|
|
1081
|
+
return r.listed ? 1 : 0;
|
|
1082
|
+
}
|
|
1083
|
+
case 'traffic': {
|
|
1084
|
+
const qs = new URLSearchParams();
|
|
1085
|
+
for (const k of ['days', 'category', 'limit', 'offset'])
|
|
1086
|
+
if (flags[k] && flags[k] !== true) qs.set(k, String(flags[k]));
|
|
1087
|
+
if (rest[0]) {
|
|
1088
|
+
const r = await client.get(`/api/v1/traffic/ip/${encodeURIComponent(rest[0])}`);
|
|
1089
|
+
if (json) out(JSON.stringify(r, null, 2));
|
|
1090
|
+
else if (!r.listed) out(`${r.ip}: not on /traffic`);
|
|
1091
|
+
else
|
|
1092
|
+
out(
|
|
1093
|
+
`${r.ip}: listed (${r.category}), ${r.servers} servers, ${r.blocks} bans, last seen ${String(r.last_seen).slice(0, 10)}`,
|
|
1094
|
+
);
|
|
1095
|
+
return r.listed ? 1 : 0;
|
|
1096
|
+
}
|
|
1097
|
+
if (flags.txt) {
|
|
1098
|
+
out(await client.text(`/traffic/blocklist.txt${qs.size ? `?${qs}` : ''}`));
|
|
1099
|
+
return 0;
|
|
1100
|
+
}
|
|
1101
|
+
const r = await client.get(`/api/v1/traffic${qs.size ? `?${qs}` : ''}`);
|
|
1102
|
+
if (json) {
|
|
1103
|
+
out(JSON.stringify(r, null, 2));
|
|
1104
|
+
return 0;
|
|
1105
|
+
}
|
|
1106
|
+
for (const x of r.addresses ?? r.rows ?? [])
|
|
1107
|
+
out(
|
|
1108
|
+
`${pad(x.ip, 40)} ${pad(x.category ?? 'other', 12)} ${String(x.last_seen ?? '').slice(0, 10)}`,
|
|
1109
|
+
);
|
|
1110
|
+
return 0;
|
|
1111
|
+
}
|
|
1051
1112
|
case 'profiles': {
|
|
1052
1113
|
const term = rest.join(' ');
|
|
1053
1114
|
const qs = new URLSearchParams();
|