s3db.js 13.6.1 → 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.
Files changed (189) hide show
  1. package/README.md +56 -15
  2. package/dist/s3db.cjs +72446 -39022
  3. package/dist/s3db.cjs.map +1 -1
  4. package/dist/s3db.es.js +72172 -38790
  5. package/dist/s3db.es.js.map +1 -1
  6. package/mcp/lib/base-handler.js +157 -0
  7. package/mcp/lib/handlers/connection-handler.js +280 -0
  8. package/mcp/lib/handlers/query-handler.js +533 -0
  9. package/mcp/lib/handlers/resource-handler.js +428 -0
  10. package/mcp/lib/tool-registry.js +336 -0
  11. package/mcp/lib/tools/connection-tools.js +161 -0
  12. package/mcp/lib/tools/query-tools.js +267 -0
  13. package/mcp/lib/tools/resource-tools.js +404 -0
  14. package/package.json +85 -50
  15. package/src/clients/memory-client.class.js +346 -191
  16. package/src/clients/memory-storage.class.js +300 -84
  17. package/src/clients/s3-client.class.js +7 -6
  18. package/src/concerns/geo-encoding.js +19 -2
  19. package/src/concerns/ip.js +59 -9
  20. package/src/concerns/money.js +8 -1
  21. package/src/concerns/password-hashing.js +49 -8
  22. package/src/concerns/plugin-storage.js +186 -18
  23. package/src/concerns/storage-drivers/filesystem-driver.js +284 -0
  24. package/src/database.class.js +139 -29
  25. package/src/errors.js +332 -42
  26. package/src/plugins/api/auth/oidc-auth.js +66 -17
  27. package/src/plugins/api/auth/strategies/base-strategy.class.js +74 -0
  28. package/src/plugins/api/auth/strategies/factory.class.js +63 -0
  29. package/src/plugins/api/auth/strategies/global-strategy.class.js +44 -0
  30. package/src/plugins/api/auth/strategies/path-based-strategy.class.js +83 -0
  31. package/src/plugins/api/auth/strategies/path-rules-strategy.class.js +118 -0
  32. package/src/plugins/api/concerns/failban-manager.js +106 -57
  33. package/src/plugins/api/concerns/route-context.js +601 -0
  34. package/src/plugins/api/index.js +168 -40
  35. package/src/plugins/api/routes/auth-routes.js +198 -30
  36. package/src/plugins/api/routes/resource-routes.js +19 -4
  37. package/src/plugins/api/server/health-manager.class.js +163 -0
  38. package/src/plugins/api/server/middleware-chain.class.js +310 -0
  39. package/src/plugins/api/server/router.class.js +472 -0
  40. package/src/plugins/api/server.js +280 -1303
  41. package/src/plugins/api/utils/custom-routes.js +17 -5
  42. package/src/plugins/api/utils/guards.js +76 -17
  43. package/src/plugins/api/utils/openapi-generator-cached.class.js +133 -0
  44. package/src/plugins/api/utils/openapi-generator.js +7 -6
  45. package/src/plugins/audit.plugin.js +30 -8
  46. package/src/plugins/backup.plugin.js +110 -14
  47. package/src/plugins/cache/cache.class.js +22 -5
  48. package/src/plugins/cache/filesystem-cache.class.js +116 -19
  49. package/src/plugins/cache/memory-cache.class.js +211 -57
  50. package/src/plugins/cache/multi-tier-cache.class.js +371 -0
  51. package/src/plugins/cache/partition-aware-filesystem-cache.class.js +168 -47
  52. package/src/plugins/cache/redis-cache.class.js +552 -0
  53. package/src/plugins/cache/s3-cache.class.js +17 -8
  54. package/src/plugins/cache.plugin.js +176 -61
  55. package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +8 -1
  56. package/src/plugins/cloud-inventory/drivers/aws-driver.js +60 -29
  57. package/src/plugins/cloud-inventory/drivers/azure-driver.js +8 -1
  58. package/src/plugins/cloud-inventory/drivers/base-driver.js +16 -2
  59. package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +8 -1
  60. package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +8 -1
  61. package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +8 -1
  62. package/src/plugins/cloud-inventory/drivers/linode-driver.js +8 -1
  63. package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +8 -1
  64. package/src/plugins/cloud-inventory/drivers/vultr-driver.js +8 -1
  65. package/src/plugins/cloud-inventory/index.js +29 -8
  66. package/src/plugins/cloud-inventory/registry.js +64 -42
  67. package/src/plugins/cloud-inventory.plugin.js +240 -138
  68. package/src/plugins/concerns/plugin-dependencies.js +54 -0
  69. package/src/plugins/concerns/resource-names.js +100 -0
  70. package/src/plugins/consumers/index.js +10 -2
  71. package/src/plugins/consumers/sqs-consumer.js +12 -2
  72. package/src/plugins/cookie-farm-suite.plugin.js +278 -0
  73. package/src/plugins/cookie-farm.errors.js +73 -0
  74. package/src/plugins/cookie-farm.plugin.js +869 -0
  75. package/src/plugins/costs.plugin.js +7 -1
  76. package/src/plugins/eventual-consistency/analytics.js +94 -19
  77. package/src/plugins/eventual-consistency/config.js +15 -7
  78. package/src/plugins/eventual-consistency/consolidation.js +29 -11
  79. package/src/plugins/eventual-consistency/garbage-collection.js +3 -1
  80. package/src/plugins/eventual-consistency/helpers.js +39 -14
  81. package/src/plugins/eventual-consistency/install.js +21 -2
  82. package/src/plugins/eventual-consistency/utils.js +32 -10
  83. package/src/plugins/fulltext.plugin.js +38 -11
  84. package/src/plugins/geo.plugin.js +61 -9
  85. package/src/plugins/identity/concerns/config.js +61 -0
  86. package/src/plugins/identity/concerns/mfa-manager.js +15 -2
  87. package/src/plugins/identity/concerns/rate-limit.js +124 -0
  88. package/src/plugins/identity/concerns/resource-schemas.js +9 -1
  89. package/src/plugins/identity/concerns/token-generator.js +29 -4
  90. package/src/plugins/identity/drivers/auth-driver.interface.js +76 -0
  91. package/src/plugins/identity/drivers/client-credentials-driver.js +127 -0
  92. package/src/plugins/identity/drivers/index.js +18 -0
  93. package/src/plugins/identity/drivers/password-driver.js +122 -0
  94. package/src/plugins/identity/email-service.js +17 -2
  95. package/src/plugins/identity/index.js +413 -69
  96. package/src/plugins/identity/oauth2-server.js +413 -30
  97. package/src/plugins/identity/oidc-discovery.js +16 -8
  98. package/src/plugins/identity/rsa-keys.js +115 -35
  99. package/src/plugins/identity/server.js +166 -45
  100. package/src/plugins/identity/session-manager.js +53 -7
  101. package/src/plugins/identity/ui/pages/mfa-verification.js +17 -15
  102. package/src/plugins/identity/ui/routes.js +363 -255
  103. package/src/plugins/importer/index.js +153 -20
  104. package/src/plugins/index.js +9 -2
  105. package/src/plugins/kubernetes-inventory/index.js +6 -0
  106. package/src/plugins/kubernetes-inventory/k8s-driver.js +867 -0
  107. package/src/plugins/kubernetes-inventory/resource-types.js +274 -0
  108. package/src/plugins/kubernetes-inventory.plugin.js +980 -0
  109. package/src/plugins/metrics.plugin.js +64 -16
  110. package/src/plugins/ml/base-model.class.js +25 -15
  111. package/src/plugins/ml/regression-model.class.js +1 -1
  112. package/src/plugins/ml.errors.js +57 -25
  113. package/src/plugins/ml.plugin.js +28 -4
  114. package/src/plugins/namespace.js +210 -0
  115. package/src/plugins/plugin.class.js +180 -8
  116. package/src/plugins/puppeteer/console-monitor.js +729 -0
  117. package/src/plugins/puppeteer/cookie-manager.js +492 -0
  118. package/src/plugins/puppeteer/network-monitor.js +816 -0
  119. package/src/plugins/puppeteer/performance-manager.js +746 -0
  120. package/src/plugins/puppeteer/proxy-manager.js +478 -0
  121. package/src/plugins/puppeteer/stealth-manager.js +556 -0
  122. package/src/plugins/puppeteer.errors.js +81 -0
  123. package/src/plugins/puppeteer.plugin.js +1327 -0
  124. package/src/plugins/queue-consumer.plugin.js +69 -14
  125. package/src/plugins/recon/behaviors/uptime-behavior.js +691 -0
  126. package/src/plugins/recon/concerns/command-runner.js +148 -0
  127. package/src/plugins/recon/concerns/diff-detector.js +372 -0
  128. package/src/plugins/recon/concerns/fingerprint-builder.js +307 -0
  129. package/src/plugins/recon/concerns/process-manager.js +338 -0
  130. package/src/plugins/recon/concerns/report-generator.js +478 -0
  131. package/src/plugins/recon/concerns/security-analyzer.js +571 -0
  132. package/src/plugins/recon/concerns/target-normalizer.js +68 -0
  133. package/src/plugins/recon/config/defaults.js +321 -0
  134. package/src/plugins/recon/config/resources.js +370 -0
  135. package/src/plugins/recon/index.js +778 -0
  136. package/src/plugins/recon/managers/dependency-manager.js +174 -0
  137. package/src/plugins/recon/managers/scheduler-manager.js +179 -0
  138. package/src/plugins/recon/managers/storage-manager.js +745 -0
  139. package/src/plugins/recon/managers/target-manager.js +274 -0
  140. package/src/plugins/recon/stages/asn-stage.js +314 -0
  141. package/src/plugins/recon/stages/certificate-stage.js +84 -0
  142. package/src/plugins/recon/stages/dns-stage.js +107 -0
  143. package/src/plugins/recon/stages/dnsdumpster-stage.js +362 -0
  144. package/src/plugins/recon/stages/fingerprint-stage.js +71 -0
  145. package/src/plugins/recon/stages/google-dorks-stage.js +440 -0
  146. package/src/plugins/recon/stages/http-stage.js +89 -0
  147. package/src/plugins/recon/stages/latency-stage.js +148 -0
  148. package/src/plugins/recon/stages/massdns-stage.js +302 -0
  149. package/src/plugins/recon/stages/osint-stage.js +1373 -0
  150. package/src/plugins/recon/stages/ports-stage.js +169 -0
  151. package/src/plugins/recon/stages/screenshot-stage.js +94 -0
  152. package/src/plugins/recon/stages/secrets-stage.js +514 -0
  153. package/src/plugins/recon/stages/subdomains-stage.js +295 -0
  154. package/src/plugins/recon/stages/tls-audit-stage.js +78 -0
  155. package/src/plugins/recon/stages/vulnerability-stage.js +78 -0
  156. package/src/plugins/recon/stages/web-discovery-stage.js +113 -0
  157. package/src/plugins/recon/stages/whois-stage.js +349 -0
  158. package/src/plugins/recon.plugin.js +75 -0
  159. package/src/plugins/recon.plugin.js.backup +2635 -0
  160. package/src/plugins/relation.errors.js +87 -14
  161. package/src/plugins/replicator.plugin.js +514 -137
  162. package/src/plugins/replicators/base-replicator.class.js +89 -1
  163. package/src/plugins/replicators/bigquery-replicator.class.js +66 -22
  164. package/src/plugins/replicators/dynamodb-replicator.class.js +22 -15
  165. package/src/plugins/replicators/mongodb-replicator.class.js +22 -15
  166. package/src/plugins/replicators/mysql-replicator.class.js +52 -17
  167. package/src/plugins/replicators/planetscale-replicator.class.js +30 -4
  168. package/src/plugins/replicators/postgres-replicator.class.js +62 -27
  169. package/src/plugins/replicators/s3db-replicator.class.js +25 -18
  170. package/src/plugins/replicators/schema-sync.helper.js +3 -3
  171. package/src/plugins/replicators/sqs-replicator.class.js +8 -2
  172. package/src/plugins/replicators/turso-replicator.class.js +23 -3
  173. package/src/plugins/replicators/webhook-replicator.class.js +42 -4
  174. package/src/plugins/s3-queue.plugin.js +464 -65
  175. package/src/plugins/scheduler.plugin.js +20 -6
  176. package/src/plugins/state-machine.plugin.js +40 -9
  177. package/src/plugins/tfstate/base-driver.js +28 -4
  178. package/src/plugins/tfstate/errors.js +65 -10
  179. package/src/plugins/tfstate/filesystem-driver.js +52 -8
  180. package/src/plugins/tfstate/index.js +163 -90
  181. package/src/plugins/tfstate/s3-driver.js +64 -6
  182. package/src/plugins/ttl.plugin.js +72 -17
  183. package/src/plugins/vector/distances.js +18 -12
  184. package/src/plugins/vector/kmeans.js +26 -4
  185. package/src/resource.class.js +115 -19
  186. package/src/testing/factory.class.js +20 -3
  187. package/src/testing/seeder.class.js +7 -1
  188. package/src/clients/memory-client.md +0 -917
  189. 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)