s3db.js 13.6.0 → 14.0.2
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/README.md +139 -43
- package/dist/s3db.cjs +72425 -38970
- package/dist/s3db.cjs.map +1 -1
- package/dist/s3db.es.js +72177 -38764
- package/dist/s3db.es.js.map +1 -1
- package/mcp/lib/base-handler.js +157 -0
- package/mcp/lib/handlers/connection-handler.js +280 -0
- package/mcp/lib/handlers/query-handler.js +533 -0
- package/mcp/lib/handlers/resource-handler.js +428 -0
- package/mcp/lib/tool-registry.js +336 -0
- package/mcp/lib/tools/connection-tools.js +161 -0
- package/mcp/lib/tools/query-tools.js +267 -0
- package/mcp/lib/tools/resource-tools.js +404 -0
- package/package.json +94 -49
- package/src/clients/memory-client.class.js +346 -191
- package/src/clients/memory-storage.class.js +300 -84
- package/src/clients/s3-client.class.js +7 -6
- package/src/concerns/geo-encoding.js +19 -2
- package/src/concerns/ip.js +59 -9
- package/src/concerns/money.js +8 -1
- package/src/concerns/password-hashing.js +49 -8
- package/src/concerns/plugin-storage.js +186 -18
- package/src/concerns/storage-drivers/filesystem-driver.js +284 -0
- package/src/database.class.js +139 -29
- package/src/errors.js +332 -42
- package/src/plugins/api/auth/oidc-auth.js +66 -17
- package/src/plugins/api/auth/strategies/base-strategy.class.js +74 -0
- package/src/plugins/api/auth/strategies/factory.class.js +63 -0
- package/src/plugins/api/auth/strategies/global-strategy.class.js +44 -0
- package/src/plugins/api/auth/strategies/path-based-strategy.class.js +83 -0
- package/src/plugins/api/auth/strategies/path-rules-strategy.class.js +118 -0
- package/src/plugins/api/concerns/failban-manager.js +106 -57
- package/src/plugins/api/concerns/opengraph-helper.js +116 -0
- package/src/plugins/api/concerns/route-context.js +601 -0
- package/src/plugins/api/concerns/state-machine.js +288 -0
- package/src/plugins/api/index.js +180 -41
- package/src/plugins/api/routes/auth-routes.js +198 -30
- package/src/plugins/api/routes/resource-routes.js +19 -4
- package/src/plugins/api/server/health-manager.class.js +163 -0
- package/src/plugins/api/server/middleware-chain.class.js +310 -0
- package/src/plugins/api/server/router.class.js +472 -0
- package/src/plugins/api/server.js +280 -1303
- package/src/plugins/api/utils/custom-routes.js +17 -5
- package/src/plugins/api/utils/guards.js +76 -17
- package/src/plugins/api/utils/openapi-generator-cached.class.js +133 -0
- package/src/plugins/api/utils/openapi-generator.js +7 -6
- package/src/plugins/api/utils/template-engine.js +77 -3
- package/src/plugins/audit.plugin.js +30 -8
- package/src/plugins/backup.plugin.js +110 -14
- package/src/plugins/cache/cache.class.js +22 -5
- package/src/plugins/cache/filesystem-cache.class.js +116 -19
- package/src/plugins/cache/memory-cache.class.js +211 -57
- package/src/plugins/cache/multi-tier-cache.class.js +371 -0
- package/src/plugins/cache/partition-aware-filesystem-cache.class.js +168 -47
- package/src/plugins/cache/redis-cache.class.js +552 -0
- package/src/plugins/cache/s3-cache.class.js +17 -8
- package/src/plugins/cache.plugin.js +176 -61
- package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/aws-driver.js +60 -29
- package/src/plugins/cloud-inventory/drivers/azure-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/base-driver.js +16 -2
- package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/linode-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/vultr-driver.js +8 -1
- package/src/plugins/cloud-inventory/index.js +29 -8
- package/src/plugins/cloud-inventory/registry.js +64 -42
- package/src/plugins/cloud-inventory.plugin.js +240 -138
- package/src/plugins/concerns/plugin-dependencies.js +54 -0
- package/src/plugins/concerns/resource-names.js +100 -0
- package/src/plugins/consumers/index.js +10 -2
- package/src/plugins/consumers/sqs-consumer.js +12 -2
- package/src/plugins/cookie-farm-suite.plugin.js +278 -0
- package/src/plugins/cookie-farm.errors.js +73 -0
- package/src/plugins/cookie-farm.plugin.js +869 -0
- package/src/plugins/costs.plugin.js +7 -1
- package/src/plugins/eventual-consistency/analytics.js +94 -19
- package/src/plugins/eventual-consistency/config.js +15 -7
- package/src/plugins/eventual-consistency/consolidation.js +29 -11
- package/src/plugins/eventual-consistency/garbage-collection.js +3 -1
- package/src/plugins/eventual-consistency/helpers.js +39 -14
- package/src/plugins/eventual-consistency/install.js +21 -2
- package/src/plugins/eventual-consistency/utils.js +32 -10
- package/src/plugins/fulltext.plugin.js +38 -11
- package/src/plugins/geo.plugin.js +61 -9
- package/src/plugins/identity/concerns/config.js +61 -0
- package/src/plugins/identity/concerns/mfa-manager.js +15 -2
- package/src/plugins/identity/concerns/rate-limit.js +124 -0
- package/src/plugins/identity/concerns/resource-schemas.js +9 -1
- package/src/plugins/identity/concerns/token-generator.js +29 -4
- package/src/plugins/identity/drivers/auth-driver.interface.js +76 -0
- package/src/plugins/identity/drivers/client-credentials-driver.js +127 -0
- package/src/plugins/identity/drivers/index.js +18 -0
- package/src/plugins/identity/drivers/password-driver.js +122 -0
- package/src/plugins/identity/email-service.js +17 -2
- package/src/plugins/identity/index.js +413 -69
- package/src/plugins/identity/oauth2-server.js +413 -30
- package/src/plugins/identity/oidc-discovery.js +16 -8
- package/src/plugins/identity/rsa-keys.js +115 -35
- package/src/plugins/identity/server.js +166 -45
- package/src/plugins/identity/session-manager.js +53 -7
- package/src/plugins/identity/ui/pages/mfa-verification.js +17 -15
- package/src/plugins/identity/ui/routes.js +363 -255
- package/src/plugins/importer/index.js +153 -20
- package/src/plugins/index.js +9 -2
- package/src/plugins/kubernetes-inventory/index.js +6 -0
- package/src/plugins/kubernetes-inventory/k8s-driver.js +867 -0
- package/src/plugins/kubernetes-inventory/resource-types.js +274 -0
- package/src/plugins/kubernetes-inventory.plugin.js +980 -0
- package/src/plugins/metrics.plugin.js +64 -16
- package/src/plugins/ml/base-model.class.js +25 -15
- package/src/plugins/ml/regression-model.class.js +1 -1
- package/src/plugins/ml.errors.js +57 -25
- package/src/plugins/ml.plugin.js +28 -4
- package/src/plugins/namespace.js +210 -0
- package/src/plugins/plugin.class.js +180 -8
- package/src/plugins/puppeteer/console-monitor.js +729 -0
- package/src/plugins/puppeteer/cookie-manager.js +492 -0
- package/src/plugins/puppeteer/network-monitor.js +816 -0
- package/src/plugins/puppeteer/performance-manager.js +746 -0
- package/src/plugins/puppeteer/proxy-manager.js +478 -0
- package/src/plugins/puppeteer/stealth-manager.js +556 -0
- package/src/plugins/puppeteer.errors.js +81 -0
- package/src/plugins/puppeteer.plugin.js +1327 -0
- package/src/plugins/queue-consumer.plugin.js +69 -14
- package/src/plugins/recon/behaviors/uptime-behavior.js +691 -0
- package/src/plugins/recon/concerns/command-runner.js +148 -0
- package/src/plugins/recon/concerns/diff-detector.js +372 -0
- package/src/plugins/recon/concerns/fingerprint-builder.js +307 -0
- package/src/plugins/recon/concerns/process-manager.js +338 -0
- package/src/plugins/recon/concerns/report-generator.js +478 -0
- package/src/plugins/recon/concerns/security-analyzer.js +571 -0
- package/src/plugins/recon/concerns/target-normalizer.js +68 -0
- package/src/plugins/recon/config/defaults.js +321 -0
- package/src/plugins/recon/config/resources.js +370 -0
- package/src/plugins/recon/index.js +778 -0
- package/src/plugins/recon/managers/dependency-manager.js +174 -0
- package/src/plugins/recon/managers/scheduler-manager.js +179 -0
- package/src/plugins/recon/managers/storage-manager.js +745 -0
- package/src/plugins/recon/managers/target-manager.js +274 -0
- package/src/plugins/recon/stages/asn-stage.js +314 -0
- package/src/plugins/recon/stages/certificate-stage.js +84 -0
- package/src/plugins/recon/stages/dns-stage.js +107 -0
- package/src/plugins/recon/stages/dnsdumpster-stage.js +362 -0
- package/src/plugins/recon/stages/fingerprint-stage.js +71 -0
- package/src/plugins/recon/stages/google-dorks-stage.js +440 -0
- package/src/plugins/recon/stages/http-stage.js +89 -0
- package/src/plugins/recon/stages/latency-stage.js +148 -0
- package/src/plugins/recon/stages/massdns-stage.js +302 -0
- package/src/plugins/recon/stages/osint-stage.js +1373 -0
- package/src/plugins/recon/stages/ports-stage.js +169 -0
- package/src/plugins/recon/stages/screenshot-stage.js +94 -0
- package/src/plugins/recon/stages/secrets-stage.js +514 -0
- package/src/plugins/recon/stages/subdomains-stage.js +295 -0
- package/src/plugins/recon/stages/tls-audit-stage.js +78 -0
- package/src/plugins/recon/stages/vulnerability-stage.js +78 -0
- package/src/plugins/recon/stages/web-discovery-stage.js +113 -0
- package/src/plugins/recon/stages/whois-stage.js +349 -0
- package/src/plugins/recon.plugin.js +75 -0
- package/src/plugins/recon.plugin.js.backup +2635 -0
- package/src/plugins/relation.errors.js +87 -14
- package/src/plugins/replicator.plugin.js +514 -137
- package/src/plugins/replicators/base-replicator.class.js +89 -1
- package/src/plugins/replicators/bigquery-replicator.class.js +66 -22
- package/src/plugins/replicators/dynamodb-replicator.class.js +22 -15
- package/src/plugins/replicators/mongodb-replicator.class.js +22 -15
- package/src/plugins/replicators/mysql-replicator.class.js +52 -17
- package/src/plugins/replicators/planetscale-replicator.class.js +30 -4
- package/src/plugins/replicators/postgres-replicator.class.js +62 -27
- package/src/plugins/replicators/s3db-replicator.class.js +25 -18
- package/src/plugins/replicators/schema-sync.helper.js +3 -3
- package/src/plugins/replicators/sqs-replicator.class.js +8 -2
- package/src/plugins/replicators/turso-replicator.class.js +23 -3
- package/src/plugins/replicators/webhook-replicator.class.js +42 -4
- package/src/plugins/s3-queue.plugin.js +464 -65
- package/src/plugins/scheduler.plugin.js +20 -6
- package/src/plugins/state-machine.plugin.js +40 -9
- package/src/plugins/tfstate/README.md +126 -126
- package/src/plugins/tfstate/base-driver.js +28 -4
- package/src/plugins/tfstate/errors.js +65 -10
- package/src/plugins/tfstate/filesystem-driver.js +52 -8
- package/src/plugins/tfstate/index.js +163 -90
- package/src/plugins/tfstate/s3-driver.js +64 -6
- package/src/plugins/ttl.plugin.js +72 -17
- package/src/plugins/vector/distances.js +18 -12
- package/src/plugins/vector/kmeans.js +26 -4
- package/src/resource.class.js +115 -19
- package/src/testing/factory.class.js +20 -3
- package/src/testing/seeder.class.js +7 -1
- package/src/clients/memory-client.md +0 -917
- package/src/plugins/cloud-inventory/drivers/mock-drivers.js +0 -449
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhoisStage
|
|
3
|
+
*
|
|
4
|
+
* WHOIS lookup stage for domain registration information:
|
|
5
|
+
* - Registrar details
|
|
6
|
+
* - Registration/expiration dates
|
|
7
|
+
* - Name servers
|
|
8
|
+
* - Registrant information (when available)
|
|
9
|
+
* - Domain status
|
|
10
|
+
* - DNSSEC status
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { exec } from 'child_process';
|
|
14
|
+
import { promisify } from 'util';
|
|
15
|
+
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
|
|
18
|
+
export class WhoisStage {
|
|
19
|
+
constructor(plugin) {
|
|
20
|
+
this.plugin = plugin;
|
|
21
|
+
this.timeout = 15000; // 15 second timeout for WHOIS queries
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Execute WHOIS lookup for target domain
|
|
26
|
+
* @param {Object} target - Target object with host property
|
|
27
|
+
* @returns {Object} WHOIS information
|
|
28
|
+
*/
|
|
29
|
+
async execute(target) {
|
|
30
|
+
const result = {
|
|
31
|
+
status: 'ok',
|
|
32
|
+
domain: null,
|
|
33
|
+
registrar: null,
|
|
34
|
+
registrant: {},
|
|
35
|
+
dates: {},
|
|
36
|
+
nameservers: [],
|
|
37
|
+
dnssec: null,
|
|
38
|
+
domainStatus: [],
|
|
39
|
+
raw: null,
|
|
40
|
+
errors: {}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
// Extract base domain from hostname (remove subdomains)
|
|
45
|
+
const domain = this.extractBaseDomain(target.host);
|
|
46
|
+
result.domain = domain;
|
|
47
|
+
|
|
48
|
+
// Check if whois command is available
|
|
49
|
+
const hasWhois = await this.checkWhoisAvailable();
|
|
50
|
+
if (!hasWhois) {
|
|
51
|
+
result.status = 'unavailable';
|
|
52
|
+
result.message = 'whois command not found. Install with: apt install whois';
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Execute whois command
|
|
57
|
+
const whoisData = await this.executeWhois(domain);
|
|
58
|
+
result.raw = whoisData;
|
|
59
|
+
|
|
60
|
+
// Parse WHOIS data
|
|
61
|
+
const parsed = this.parseWhoisData(whoisData);
|
|
62
|
+
|
|
63
|
+
result.registrar = parsed.registrar;
|
|
64
|
+
result.registrant = parsed.registrant;
|
|
65
|
+
result.dates = parsed.dates;
|
|
66
|
+
result.nameservers = parsed.nameservers;
|
|
67
|
+
result.dnssec = parsed.dnssec;
|
|
68
|
+
result.domainStatus = parsed.domainStatus;
|
|
69
|
+
|
|
70
|
+
// Calculate days until expiration
|
|
71
|
+
if (parsed.dates.expiration) {
|
|
72
|
+
const expirationDate = new Date(parsed.dates.expiration);
|
|
73
|
+
const now = new Date();
|
|
74
|
+
const daysUntilExpiration = Math.ceil((expirationDate - now) / (1000 * 60 * 60 * 24));
|
|
75
|
+
result.dates.daysUntilExpiration = daysUntilExpiration;
|
|
76
|
+
|
|
77
|
+
if (daysUntilExpiration < 0) {
|
|
78
|
+
result.status = 'expired';
|
|
79
|
+
} else if (daysUntilExpiration < 30) {
|
|
80
|
+
result.status = 'expiring-soon';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
} catch (error) {
|
|
85
|
+
result.status = 'error';
|
|
86
|
+
result.message = error?.message || 'WHOIS lookup failed';
|
|
87
|
+
result.errors.whois = error?.message;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check if whois command is available
|
|
95
|
+
* @returns {Promise<boolean>}
|
|
96
|
+
*/
|
|
97
|
+
async checkWhoisAvailable() {
|
|
98
|
+
try {
|
|
99
|
+
await execAsync('which whois', { timeout: 2000 });
|
|
100
|
+
return true;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Execute whois command
|
|
108
|
+
* @param {string} domain - Domain to lookup
|
|
109
|
+
* @returns {Promise<string>} Raw WHOIS data
|
|
110
|
+
*/
|
|
111
|
+
async executeWhois(domain) {
|
|
112
|
+
try {
|
|
113
|
+
const { stdout, stderr } = await execAsync(`whois ${domain}`, {
|
|
114
|
+
timeout: this.timeout,
|
|
115
|
+
maxBuffer: 1024 * 1024 // 1MB buffer
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
if (stderr && !stdout) {
|
|
119
|
+
throw new Error(`WHOIS query failed: ${stderr}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return stdout;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (error.killed) {
|
|
125
|
+
throw new Error(`WHOIS query timed out after ${this.timeout}ms`);
|
|
126
|
+
}
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Extract base domain from hostname (remove subdomains)
|
|
133
|
+
* @param {string} host - Full hostname
|
|
134
|
+
* @returns {string} Base domain
|
|
135
|
+
*/
|
|
136
|
+
extractBaseDomain(host) {
|
|
137
|
+
// Remove protocol if present
|
|
138
|
+
let domain = host.replace(/^https?:\/\//, '');
|
|
139
|
+
|
|
140
|
+
// Remove port if present
|
|
141
|
+
domain = domain.split(':')[0];
|
|
142
|
+
|
|
143
|
+
// Remove path if present
|
|
144
|
+
domain = domain.split('/')[0];
|
|
145
|
+
|
|
146
|
+
// Extract base domain (last 2 parts for most TLDs, 3 for special cases)
|
|
147
|
+
const parts = domain.split('.');
|
|
148
|
+
|
|
149
|
+
// Handle special TLDs like .co.uk, .com.br, etc.
|
|
150
|
+
const specialTlds = ['co.uk', 'com.br', 'com.au', 'co.jp', 'co.za', 'com.mx', 'com.ar'];
|
|
151
|
+
const lastTwoParts = parts.slice(-2).join('.');
|
|
152
|
+
|
|
153
|
+
if (specialTlds.includes(lastTwoParts)) {
|
|
154
|
+
return parts.slice(-3).join('.');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Default: return last 2 parts (domain.tld)
|
|
158
|
+
return parts.slice(-2).join('.');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Parse raw WHOIS data into structured format
|
|
163
|
+
* @param {string} raw - Raw WHOIS response
|
|
164
|
+
* @returns {Object} Parsed WHOIS data
|
|
165
|
+
*/
|
|
166
|
+
parseWhoisData(raw) {
|
|
167
|
+
const lines = raw.split('\n');
|
|
168
|
+
const parsed = {
|
|
169
|
+
registrar: null,
|
|
170
|
+
registrant: {
|
|
171
|
+
name: null,
|
|
172
|
+
organization: null,
|
|
173
|
+
email: null,
|
|
174
|
+
country: null
|
|
175
|
+
},
|
|
176
|
+
dates: {
|
|
177
|
+
created: null,
|
|
178
|
+
updated: null,
|
|
179
|
+
expiration: null
|
|
180
|
+
},
|
|
181
|
+
nameservers: [],
|
|
182
|
+
dnssec: null,
|
|
183
|
+
domainStatus: []
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const registrarPatterns = [
|
|
187
|
+
/Registrar:\s*(.+)/i,
|
|
188
|
+
/Sponsoring Registrar:\s*(.+)/i,
|
|
189
|
+
/Registrar Name:\s*(.+)/i
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
const createdPatterns = [
|
|
193
|
+
/Creation Date:\s*(.+)/i,
|
|
194
|
+
/Created:\s*(.+)/i,
|
|
195
|
+
/Registration Date:\s*(.+)/i,
|
|
196
|
+
/Domain Registration Date:\s*(.+)/i
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
const expirationPatterns = [
|
|
200
|
+
/Registry Expiry Date:\s*(.+)/i,
|
|
201
|
+
/Expiration Date:\s*(.+)/i,
|
|
202
|
+
/Expires:\s*(.+)/i,
|
|
203
|
+
/Expiry Date:\s*(.+)/i,
|
|
204
|
+
/Domain Expiration Date:\s*(.+)/i
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
const updatedPatterns = [
|
|
208
|
+
/Updated Date:\s*(.+)/i,
|
|
209
|
+
/Last Updated:\s*(.+)/i,
|
|
210
|
+
/Modified:\s*(.+)/i
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
const nameserverPatterns = [
|
|
214
|
+
/Name Server:\s*(.+)/i,
|
|
215
|
+
/Nameserver:\s*(.+)/i,
|
|
216
|
+
/nserver:\s*(.+)/i
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
const dnssecPatterns = [
|
|
220
|
+
/DNSSEC:\s*(.+)/i,
|
|
221
|
+
/dnssec:\s*(.+)/i
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
const statusPatterns = [
|
|
225
|
+
/Domain Status:\s*(.+)/i,
|
|
226
|
+
/Status:\s*(.+)/i
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
for (const line of lines) {
|
|
230
|
+
const trimmed = line.trim();
|
|
231
|
+
if (!trimmed || trimmed.startsWith('%') || trimmed.startsWith('#')) {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Parse registrar
|
|
236
|
+
for (const pattern of registrarPatterns) {
|
|
237
|
+
const match = trimmed.match(pattern);
|
|
238
|
+
if (match && !parsed.registrar) {
|
|
239
|
+
parsed.registrar = match[1].trim();
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Parse creation date
|
|
245
|
+
for (const pattern of createdPatterns) {
|
|
246
|
+
const match = trimmed.match(pattern);
|
|
247
|
+
if (match && !parsed.dates.created) {
|
|
248
|
+
parsed.dates.created = this.parseDate(match[1].trim());
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Parse expiration date
|
|
254
|
+
for (const pattern of expirationPatterns) {
|
|
255
|
+
const match = trimmed.match(pattern);
|
|
256
|
+
if (match && !parsed.dates.expiration) {
|
|
257
|
+
parsed.dates.expiration = this.parseDate(match[1].trim());
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Parse updated date
|
|
263
|
+
for (const pattern of updatedPatterns) {
|
|
264
|
+
const match = trimmed.match(pattern);
|
|
265
|
+
if (match && !parsed.dates.updated) {
|
|
266
|
+
parsed.dates.updated = this.parseDate(match[1].trim());
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Parse nameservers
|
|
272
|
+
for (const pattern of nameserverPatterns) {
|
|
273
|
+
const match = trimmed.match(pattern);
|
|
274
|
+
if (match) {
|
|
275
|
+
const ns = match[1].trim().toLowerCase();
|
|
276
|
+
if (ns && !parsed.nameservers.includes(ns)) {
|
|
277
|
+
parsed.nameservers.push(ns);
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Parse DNSSEC
|
|
284
|
+
for (const pattern of dnssecPatterns) {
|
|
285
|
+
const match = trimmed.match(pattern);
|
|
286
|
+
if (match && !parsed.dnssec) {
|
|
287
|
+
parsed.dnssec = match[1].trim().toLowerCase();
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Parse domain status
|
|
293
|
+
for (const pattern of statusPatterns) {
|
|
294
|
+
const match = trimmed.match(pattern);
|
|
295
|
+
if (match) {
|
|
296
|
+
const status = match[1].trim();
|
|
297
|
+
if (status && !parsed.domainStatus.includes(status)) {
|
|
298
|
+
parsed.domainStatus.push(status);
|
|
299
|
+
}
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Parse registrant information
|
|
305
|
+
if (/Registrant Name:\s*(.+)/i.test(trimmed)) {
|
|
306
|
+
parsed.registrant.name = trimmed.match(/Registrant Name:\s*(.+)/i)[1].trim();
|
|
307
|
+
}
|
|
308
|
+
if (/Registrant Organization:\s*(.+)/i.test(trimmed)) {
|
|
309
|
+
parsed.registrant.organization = trimmed.match(/Registrant Organization:\s*(.+)/i)[1].trim();
|
|
310
|
+
}
|
|
311
|
+
if (/Registrant Email:\s*(.+)/i.test(trimmed)) {
|
|
312
|
+
parsed.registrant.email = trimmed.match(/Registrant Email:\s*(.+)/i)[1].trim();
|
|
313
|
+
}
|
|
314
|
+
if (/Registrant Country:\s*(.+)/i.test(trimmed)) {
|
|
315
|
+
parsed.registrant.country = trimmed.match(/Registrant Country:\s*(.+)/i)[1].trim();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return parsed;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Parse date string to ISO format
|
|
324
|
+
* @param {string} dateStr - Date string from WHOIS
|
|
325
|
+
* @returns {string|null} ISO date string or null
|
|
326
|
+
*/
|
|
327
|
+
parseDate(dateStr) {
|
|
328
|
+
if (!dateStr) return null;
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
// Remove timezone abbreviations and extra text
|
|
332
|
+
let cleaned = dateStr
|
|
333
|
+
.replace(/\s*\([^)]+\)/g, '') // Remove parentheses content
|
|
334
|
+
.replace(/\s+[A-Z]{3,4}$/, '') // Remove timezone abbreviations at end
|
|
335
|
+
.trim();
|
|
336
|
+
|
|
337
|
+
// Try to parse
|
|
338
|
+
const date = new Date(cleaned);
|
|
339
|
+
|
|
340
|
+
if (!isNaN(date.getTime())) {
|
|
341
|
+
return date.toISOString();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return null;
|
|
345
|
+
} catch (error) {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReconPlugin - Backward Compatibility Wrapper
|
|
3
|
+
*
|
|
4
|
+
* This file maintains backward compatibility with the original monolithic ReconPlugin.
|
|
5
|
+
* It re-exports the modular refactored version from src/plugins/recon/index.js
|
|
6
|
+
*
|
|
7
|
+
* Migration Path:
|
|
8
|
+
* 1. Original: import { ReconPlugin } from 's3db.js/plugins/recon.plugin.js'
|
|
9
|
+
* 2. Modular: import { ReconPlugin } from 's3db.js/plugins/recon/index.js'
|
|
10
|
+
*
|
|
11
|
+
* Both imports work identically - this wrapper ensures existing code continues to function.
|
|
12
|
+
*
|
|
13
|
+
* The original 2709-line monolithic implementation has been backed up to:
|
|
14
|
+
* src/plugins/recon.plugin.js.backup
|
|
15
|
+
*
|
|
16
|
+
* New Modular Structure:
|
|
17
|
+
* ├── recon/
|
|
18
|
+
* │ ├── index.js # Main plugin orchestrator
|
|
19
|
+
* │ ├── config/
|
|
20
|
+
* │ │ ├── defaults.js # Default configuration
|
|
21
|
+
* │ │ └── resources.js # Database resource schemas
|
|
22
|
+
* │ ├── managers/
|
|
23
|
+
* │ │ ├── storage-manager.js # Report persistence & resource updates
|
|
24
|
+
* │ │ ├── target-manager.js # Dynamic target management
|
|
25
|
+
* │ │ ├── scheduler-manager.js # Scheduled scanning
|
|
26
|
+
* │ │ └── dependency-manager.js # Tool availability checking
|
|
27
|
+
* │ ├── stages/
|
|
28
|
+
* │ │ ├── dns-stage.js # DNS enumeration
|
|
29
|
+
* │ │ ├── certificate-stage.js # TLS certificate inspection
|
|
30
|
+
* │ │ ├── latency-stage.js # Network latency measurement
|
|
31
|
+
* │ │ ├── http-stage.js # HTTP header analysis
|
|
32
|
+
* │ │ ├── ports-stage.js # Port scanning
|
|
33
|
+
* │ │ ├── subdomains-stage.js # Subdomain discovery
|
|
34
|
+
* │ │ ├── web-discovery-stage.js # Directory/endpoint fuzzing
|
|
35
|
+
* │ │ ├── vulnerability-stage.js # Vulnerability scanning
|
|
36
|
+
* │ │ ├── tls-audit-stage.js # TLS/SSL security auditing
|
|
37
|
+
* │ │ ├── fingerprint-stage.js # Technology fingerprinting
|
|
38
|
+
* │ │ ├── screenshot-stage.js # Visual reconnaissance
|
|
39
|
+
* │ │ └── osint-stage.js # OSINT data gathering
|
|
40
|
+
* │ └── concerns/
|
|
41
|
+
* │ ├── command-runner.js # CLI command execution
|
|
42
|
+
* │ ├── target-normalizer.js # URL/domain parsing
|
|
43
|
+
* │ ├── fingerprint-builder.js # Fingerprint aggregation
|
|
44
|
+
* │ ├── report-generator.js # Report generation (MD/JSON/HTML)
|
|
45
|
+
* │ └── diff-detector.js # Change detection
|
|
46
|
+
*
|
|
47
|
+
* Benefits of Modular Structure:
|
|
48
|
+
* - Testability: Each stage/manager/concern can be tested independently
|
|
49
|
+
* - Maintainability: Easy to locate and modify specific functionality
|
|
50
|
+
* - Extensibility: Simple to add new stages or tools
|
|
51
|
+
* - Performance: Stages can run in parallel
|
|
52
|
+
* - Clarity: Clear separation of concerns
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
// Re-export the modular ReconPlugin
|
|
56
|
+
export { ReconPlugin } from './recon/index.js';
|
|
57
|
+
|
|
58
|
+
// Default export for CommonJS compatibility
|
|
59
|
+
export { ReconPlugin as default } from './recon/index.js';
|
|
60
|
+
|
|
61
|
+
// Note: All public APIs remain unchanged. Existing code using ReconPlugin
|
|
62
|
+
// will continue to work without modifications:
|
|
63
|
+
//
|
|
64
|
+
// await plugin.scan(target, options)
|
|
65
|
+
// await plugin.batchScan(targets, options)
|
|
66
|
+
// await plugin.getReport(reportId)
|
|
67
|
+
// await plugin.listReports(options)
|
|
68
|
+
// await plugin.compareReports(id1, id2)
|
|
69
|
+
// await plugin.addTarget(target, schedule)
|
|
70
|
+
// await plugin.removeTarget(targetId)
|
|
71
|
+
// await plugin.listTargets()
|
|
72
|
+
// plugin.generateMarkdownReport(report)
|
|
73
|
+
// plugin.generateJSONReport(report)
|
|
74
|
+
// plugin.generateHTMLReport(report)
|
|
75
|
+
// plugin.generateExecutiveSummary(report)
|