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.
Files changed (193) hide show
  1. package/README.md +139 -43
  2. package/dist/s3db.cjs +72425 -38970
  3. package/dist/s3db.cjs.map +1 -1
  4. package/dist/s3db.es.js +72177 -38764
  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 +94 -49
  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/opengraph-helper.js +116 -0
  34. package/src/plugins/api/concerns/route-context.js +601 -0
  35. package/src/plugins/api/concerns/state-machine.js +288 -0
  36. package/src/plugins/api/index.js +180 -41
  37. package/src/plugins/api/routes/auth-routes.js +198 -30
  38. package/src/plugins/api/routes/resource-routes.js +19 -4
  39. package/src/plugins/api/server/health-manager.class.js +163 -0
  40. package/src/plugins/api/server/middleware-chain.class.js +310 -0
  41. package/src/plugins/api/server/router.class.js +472 -0
  42. package/src/plugins/api/server.js +280 -1303
  43. package/src/plugins/api/utils/custom-routes.js +17 -5
  44. package/src/plugins/api/utils/guards.js +76 -17
  45. package/src/plugins/api/utils/openapi-generator-cached.class.js +133 -0
  46. package/src/plugins/api/utils/openapi-generator.js +7 -6
  47. package/src/plugins/api/utils/template-engine.js +77 -3
  48. package/src/plugins/audit.plugin.js +30 -8
  49. package/src/plugins/backup.plugin.js +110 -14
  50. package/src/plugins/cache/cache.class.js +22 -5
  51. package/src/plugins/cache/filesystem-cache.class.js +116 -19
  52. package/src/plugins/cache/memory-cache.class.js +211 -57
  53. package/src/plugins/cache/multi-tier-cache.class.js +371 -0
  54. package/src/plugins/cache/partition-aware-filesystem-cache.class.js +168 -47
  55. package/src/plugins/cache/redis-cache.class.js +552 -0
  56. package/src/plugins/cache/s3-cache.class.js +17 -8
  57. package/src/plugins/cache.plugin.js +176 -61
  58. package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +8 -1
  59. package/src/plugins/cloud-inventory/drivers/aws-driver.js +60 -29
  60. package/src/plugins/cloud-inventory/drivers/azure-driver.js +8 -1
  61. package/src/plugins/cloud-inventory/drivers/base-driver.js +16 -2
  62. package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +8 -1
  63. package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +8 -1
  64. package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +8 -1
  65. package/src/plugins/cloud-inventory/drivers/linode-driver.js +8 -1
  66. package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +8 -1
  67. package/src/plugins/cloud-inventory/drivers/vultr-driver.js +8 -1
  68. package/src/plugins/cloud-inventory/index.js +29 -8
  69. package/src/plugins/cloud-inventory/registry.js +64 -42
  70. package/src/plugins/cloud-inventory.plugin.js +240 -138
  71. package/src/plugins/concerns/plugin-dependencies.js +54 -0
  72. package/src/plugins/concerns/resource-names.js +100 -0
  73. package/src/plugins/consumers/index.js +10 -2
  74. package/src/plugins/consumers/sqs-consumer.js +12 -2
  75. package/src/plugins/cookie-farm-suite.plugin.js +278 -0
  76. package/src/plugins/cookie-farm.errors.js +73 -0
  77. package/src/plugins/cookie-farm.plugin.js +869 -0
  78. package/src/plugins/costs.plugin.js +7 -1
  79. package/src/plugins/eventual-consistency/analytics.js +94 -19
  80. package/src/plugins/eventual-consistency/config.js +15 -7
  81. package/src/plugins/eventual-consistency/consolidation.js +29 -11
  82. package/src/plugins/eventual-consistency/garbage-collection.js +3 -1
  83. package/src/plugins/eventual-consistency/helpers.js +39 -14
  84. package/src/plugins/eventual-consistency/install.js +21 -2
  85. package/src/plugins/eventual-consistency/utils.js +32 -10
  86. package/src/plugins/fulltext.plugin.js +38 -11
  87. package/src/plugins/geo.plugin.js +61 -9
  88. package/src/plugins/identity/concerns/config.js +61 -0
  89. package/src/plugins/identity/concerns/mfa-manager.js +15 -2
  90. package/src/plugins/identity/concerns/rate-limit.js +124 -0
  91. package/src/plugins/identity/concerns/resource-schemas.js +9 -1
  92. package/src/plugins/identity/concerns/token-generator.js +29 -4
  93. package/src/plugins/identity/drivers/auth-driver.interface.js +76 -0
  94. package/src/plugins/identity/drivers/client-credentials-driver.js +127 -0
  95. package/src/plugins/identity/drivers/index.js +18 -0
  96. package/src/plugins/identity/drivers/password-driver.js +122 -0
  97. package/src/plugins/identity/email-service.js +17 -2
  98. package/src/plugins/identity/index.js +413 -69
  99. package/src/plugins/identity/oauth2-server.js +413 -30
  100. package/src/plugins/identity/oidc-discovery.js +16 -8
  101. package/src/plugins/identity/rsa-keys.js +115 -35
  102. package/src/plugins/identity/server.js +166 -45
  103. package/src/plugins/identity/session-manager.js +53 -7
  104. package/src/plugins/identity/ui/pages/mfa-verification.js +17 -15
  105. package/src/plugins/identity/ui/routes.js +363 -255
  106. package/src/plugins/importer/index.js +153 -20
  107. package/src/plugins/index.js +9 -2
  108. package/src/plugins/kubernetes-inventory/index.js +6 -0
  109. package/src/plugins/kubernetes-inventory/k8s-driver.js +867 -0
  110. package/src/plugins/kubernetes-inventory/resource-types.js +274 -0
  111. package/src/plugins/kubernetes-inventory.plugin.js +980 -0
  112. package/src/plugins/metrics.plugin.js +64 -16
  113. package/src/plugins/ml/base-model.class.js +25 -15
  114. package/src/plugins/ml/regression-model.class.js +1 -1
  115. package/src/plugins/ml.errors.js +57 -25
  116. package/src/plugins/ml.plugin.js +28 -4
  117. package/src/plugins/namespace.js +210 -0
  118. package/src/plugins/plugin.class.js +180 -8
  119. package/src/plugins/puppeteer/console-monitor.js +729 -0
  120. package/src/plugins/puppeteer/cookie-manager.js +492 -0
  121. package/src/plugins/puppeteer/network-monitor.js +816 -0
  122. package/src/plugins/puppeteer/performance-manager.js +746 -0
  123. package/src/plugins/puppeteer/proxy-manager.js +478 -0
  124. package/src/plugins/puppeteer/stealth-manager.js +556 -0
  125. package/src/plugins/puppeteer.errors.js +81 -0
  126. package/src/plugins/puppeteer.plugin.js +1327 -0
  127. package/src/plugins/queue-consumer.plugin.js +69 -14
  128. package/src/plugins/recon/behaviors/uptime-behavior.js +691 -0
  129. package/src/plugins/recon/concerns/command-runner.js +148 -0
  130. package/src/plugins/recon/concerns/diff-detector.js +372 -0
  131. package/src/plugins/recon/concerns/fingerprint-builder.js +307 -0
  132. package/src/plugins/recon/concerns/process-manager.js +338 -0
  133. package/src/plugins/recon/concerns/report-generator.js +478 -0
  134. package/src/plugins/recon/concerns/security-analyzer.js +571 -0
  135. package/src/plugins/recon/concerns/target-normalizer.js +68 -0
  136. package/src/plugins/recon/config/defaults.js +321 -0
  137. package/src/plugins/recon/config/resources.js +370 -0
  138. package/src/plugins/recon/index.js +778 -0
  139. package/src/plugins/recon/managers/dependency-manager.js +174 -0
  140. package/src/plugins/recon/managers/scheduler-manager.js +179 -0
  141. package/src/plugins/recon/managers/storage-manager.js +745 -0
  142. package/src/plugins/recon/managers/target-manager.js +274 -0
  143. package/src/plugins/recon/stages/asn-stage.js +314 -0
  144. package/src/plugins/recon/stages/certificate-stage.js +84 -0
  145. package/src/plugins/recon/stages/dns-stage.js +107 -0
  146. package/src/plugins/recon/stages/dnsdumpster-stage.js +362 -0
  147. package/src/plugins/recon/stages/fingerprint-stage.js +71 -0
  148. package/src/plugins/recon/stages/google-dorks-stage.js +440 -0
  149. package/src/plugins/recon/stages/http-stage.js +89 -0
  150. package/src/plugins/recon/stages/latency-stage.js +148 -0
  151. package/src/plugins/recon/stages/massdns-stage.js +302 -0
  152. package/src/plugins/recon/stages/osint-stage.js +1373 -0
  153. package/src/plugins/recon/stages/ports-stage.js +169 -0
  154. package/src/plugins/recon/stages/screenshot-stage.js +94 -0
  155. package/src/plugins/recon/stages/secrets-stage.js +514 -0
  156. package/src/plugins/recon/stages/subdomains-stage.js +295 -0
  157. package/src/plugins/recon/stages/tls-audit-stage.js +78 -0
  158. package/src/plugins/recon/stages/vulnerability-stage.js +78 -0
  159. package/src/plugins/recon/stages/web-discovery-stage.js +113 -0
  160. package/src/plugins/recon/stages/whois-stage.js +349 -0
  161. package/src/plugins/recon.plugin.js +75 -0
  162. package/src/plugins/recon.plugin.js.backup +2635 -0
  163. package/src/plugins/relation.errors.js +87 -14
  164. package/src/plugins/replicator.plugin.js +514 -137
  165. package/src/plugins/replicators/base-replicator.class.js +89 -1
  166. package/src/plugins/replicators/bigquery-replicator.class.js +66 -22
  167. package/src/plugins/replicators/dynamodb-replicator.class.js +22 -15
  168. package/src/plugins/replicators/mongodb-replicator.class.js +22 -15
  169. package/src/plugins/replicators/mysql-replicator.class.js +52 -17
  170. package/src/plugins/replicators/planetscale-replicator.class.js +30 -4
  171. package/src/plugins/replicators/postgres-replicator.class.js +62 -27
  172. package/src/plugins/replicators/s3db-replicator.class.js +25 -18
  173. package/src/plugins/replicators/schema-sync.helper.js +3 -3
  174. package/src/plugins/replicators/sqs-replicator.class.js +8 -2
  175. package/src/plugins/replicators/turso-replicator.class.js +23 -3
  176. package/src/plugins/replicators/webhook-replicator.class.js +42 -4
  177. package/src/plugins/s3-queue.plugin.js +464 -65
  178. package/src/plugins/scheduler.plugin.js +20 -6
  179. package/src/plugins/state-machine.plugin.js +40 -9
  180. package/src/plugins/tfstate/README.md +126 -126
  181. package/src/plugins/tfstate/base-driver.js +28 -4
  182. package/src/plugins/tfstate/errors.js +65 -10
  183. package/src/plugins/tfstate/filesystem-driver.js +52 -8
  184. package/src/plugins/tfstate/index.js +163 -90
  185. package/src/plugins/tfstate/s3-driver.js +64 -6
  186. package/src/plugins/ttl.plugin.js +72 -17
  187. package/src/plugins/vector/distances.js +18 -12
  188. package/src/plugins/vector/kmeans.js +26 -4
  189. package/src/resource.class.js +115 -19
  190. package/src/testing/factory.class.js +20 -3
  191. package/src/testing/seeder.class.js +7 -1
  192. package/src/clients/memory-client.md +0 -917
  193. package/src/plugins/cloud-inventory/drivers/mock-drivers.js +0 -449
@@ -0,0 +1,174 @@
1
+ /**
2
+ * DependencyManager
3
+ *
4
+ * Validates tool availability and emits warnings:
5
+ * - Checks if reconnaissance tools are installed
6
+ * - Provides installation guidance
7
+ * - Emits detailed warnings for missing tools
8
+ */
9
+
10
+ export class DependencyManager {
11
+ constructor(plugin) {
12
+ this.plugin = plugin;
13
+ }
14
+
15
+ /**
16
+ * Check all dependencies based on enabled features
17
+ */
18
+ async checkAll() {
19
+ const features = this.plugin.config.features;
20
+ const warnings = [];
21
+ const available = {};
22
+ const missing = {};
23
+
24
+ const toolMap = {
25
+ 'whois': 'whois',
26
+ 'secrets.gitleaks': 'gitleaks',
27
+ 'latency.ping': 'ping',
28
+ 'latency.traceroute': ['mtr', 'traceroute'],
29
+ 'http.curl': 'curl',
30
+ 'ports.nmap': 'nmap',
31
+ 'ports.masscan': 'masscan',
32
+ 'subdomains.amass': 'amass',
33
+ 'subdomains.subfinder': 'subfinder',
34
+ 'subdomains.assetfinder': 'assetfinder',
35
+ 'web.ffuf': 'ffuf',
36
+ 'web.feroxbuster': 'feroxbuster',
37
+ 'web.gobuster': 'gobuster',
38
+ 'vulnerability.nikto': 'nikto',
39
+ 'vulnerability.wpscan': 'wpscan',
40
+ 'vulnerability.droopescan': 'droopescan',
41
+ 'tlsAudit.openssl': 'openssl',
42
+ 'tlsAudit.sslyze': 'sslyze',
43
+ 'tlsAudit.testssl': 'testssl.sh',
44
+ 'tlsAudit.sslscan': 'sslscan',
45
+ 'fingerprint.whatweb': 'whatweb',
46
+ 'screenshots.aquatone': 'aquatone',
47
+ 'screenshots.eyewitness': 'EyeWitness',
48
+ 'osint.theHarvester': 'theHarvester',
49
+ 'osint.sherlock': 'sherlock',
50
+ 'osint.maigret': 'maigret',
51
+ 'asn': 'dig',
52
+ 'massdns': 'massdns'
53
+ };
54
+
55
+ for (const [featurePath, commands] of Object.entries(toolMap)) {
56
+ const isEnabled = this._isFeatureEnabled(features, featurePath);
57
+ if (!isEnabled) {
58
+ continue;
59
+ }
60
+
61
+ const commandList = Array.isArray(commands) ? commands : [commands];
62
+ let foundAny = false;
63
+
64
+ for (const cmd of commandList) {
65
+ const isAvailable = await this._checkTool(cmd);
66
+ if (isAvailable) {
67
+ foundAny = true;
68
+ available[cmd] = true;
69
+ break;
70
+ }
71
+ }
72
+
73
+ if (!foundAny) {
74
+ const toolNames = commandList.join(' ou ');
75
+ warnings.push({
76
+ feature: featurePath,
77
+ tools: commandList,
78
+ message: `Ferramenta "${toolNames}" não encontrada no PATH`,
79
+ installGuide: this._getInstallGuide(commandList[0])
80
+ });
81
+
82
+ for (const cmd of commandList) {
83
+ missing[cmd] = true;
84
+ }
85
+
86
+ this.plugin.emit('recon:dependency-missing', {
87
+ feature: featurePath,
88
+ tools: commandList,
89
+ message: `Ferramenta "${toolNames}" não encontrada no PATH`,
90
+ installGuide: this._getInstallGuide(commandList[0])
91
+ });
92
+ }
93
+ }
94
+
95
+ const availableTools = Object.keys(available);
96
+ const missingTools = Object.keys(missing);
97
+
98
+ this.plugin.emit('recon:dependencies-checked', {
99
+ available: availableTools.length,
100
+ missing: missingTools.length,
101
+ availableTools,
102
+ missingTools,
103
+ warnings
104
+ });
105
+
106
+ return warnings;
107
+ }
108
+
109
+ /**
110
+ * Check if a specific tool is available
111
+ */
112
+ async checkTool(toolName) {
113
+ return await this._checkTool(toolName);
114
+ }
115
+
116
+ // ========================================
117
+ // Private Helper Methods
118
+ // ========================================
119
+
120
+ async _checkTool(command) {
121
+ const runner = this.plugin.commandRunner;
122
+ return await runner.isAvailable(command);
123
+ }
124
+
125
+ _isFeatureEnabled(features, path) {
126
+ const parts = path.split('.');
127
+ let current = features;
128
+
129
+ for (const part of parts) {
130
+ if (current == null || typeof current !== 'object') {
131
+ return false;
132
+ }
133
+ current = current[part];
134
+ }
135
+
136
+ return current === true || (typeof current === 'object' && current !== null);
137
+ }
138
+
139
+ _getInstallGuide(toolName) {
140
+ const guides = {
141
+ whois: 'Ubuntu: apt-get install whois | macOS: brew install whois',
142
+ gitleaks: 'https://github.com/gitleaks/gitleaks | go install github.com/gitleaks/gitleaks/v8@latest | brew install gitleaks',
143
+ ping: 'Geralmente pré-instalado. No Ubuntu: apt-get install iputils-ping',
144
+ mtr: 'Ubuntu: apt-get install mtr-tiny | macOS: brew install mtr',
145
+ traceroute: 'Ubuntu: apt-get install traceroute | macOS: Pré-instalado',
146
+ curl: 'Ubuntu: apt-get install curl | macOS: Pré-instalado',
147
+ nmap: 'Ubuntu: apt-get install nmap | macOS: brew install nmap',
148
+ masscan: 'Ubuntu: apt-get install masscan | macOS: brew install masscan',
149
+ amass: 'https://github.com/owasp-amass/amass | Ubuntu: apt install amass | macOS: brew install amass',
150
+ subfinder: 'https://github.com/projectdiscovery/subfinder | go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest',
151
+ assetfinder: 'https://github.com/tomnomnom/assetfinder | go install github.com/tomnomnom/assetfinder@latest',
152
+ ffuf: 'https://github.com/ffuf/ffuf | go install github.com/ffuf/ffuf/v2@latest',
153
+ feroxbuster: 'https://github.com/epi052/feroxbuster | Ubuntu: apt install feroxbuster | macOS: brew install feroxbuster',
154
+ gobuster: 'https://github.com/OJ/gobuster | go install github.com/OJ/gobuster/v3@latest',
155
+ nikto: 'Ubuntu: apt-get install nikto | macOS: brew install nikto',
156
+ wpscan: 'https://github.com/wpscanteam/wpscan | gem install wpscan',
157
+ droopescan: 'https://github.com/SamJoan/droopescan | pip install droopescan',
158
+ openssl: 'Ubuntu: apt-get install openssl | macOS: Pré-instalado',
159
+ sslyze: 'https://github.com/nabla-c0d3/sslyze | pip install sslyze',
160
+ 'testssl.sh': 'https://github.com/drwetter/testssl.sh | git clone --depth 1 https://github.com/drwetter/testssl.sh.git',
161
+ sslscan: 'https://github.com/rbsec/sslscan | Ubuntu: apt-get install sslscan | macOS: brew install sslscan',
162
+ whatweb: 'https://github.com/urbanadventurer/WhatWeb | Ubuntu: apt-get install whatweb | macOS: brew install whatweb',
163
+ aquatone: 'https://github.com/michenriksen/aquatone | Download binário do GitHub Releases',
164
+ EyeWitness: 'https://github.com/FortyNorthSecurity/EyeWitness | git clone e seguir instruções',
165
+ theHarvester: 'https://github.com/laramies/theHarvester | pip install theHarvester',
166
+ sherlock: 'https://github.com/sherlock-project/sherlock | pip install sherlock-project',
167
+ maigret: 'https://github.com/soxoj/maigret | pip install maigret',
168
+ dig: 'Ubuntu: apt-get install dnsutils | macOS: Pré-instalado',
169
+ massdns: 'https://github.com/blechschmidt/massdns | git clone && make && sudo make install'
170
+ };
171
+
172
+ return guides[toolName] || `Consulte a documentação oficial da ferramenta "${toolName}" para instruções de instalação.`;
173
+ }
174
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * SchedulerManager
3
+ *
4
+ * Handles cron-based scheduled sweeps:
5
+ * - Manages cron job registration
6
+ * - Triggers scheduled target sweeps
7
+ * - Iterates over enabled targets
8
+ */
9
+
10
+ import { PromisePool } from '@supercharge/promise-pool';
11
+
12
+ export class SchedulerManager {
13
+ constructor(plugin) {
14
+ this.plugin = plugin;
15
+ this.cronJobId = null;
16
+ }
17
+
18
+ /**
19
+ * Start the scheduler (register cron job)
20
+ */
21
+ async start() {
22
+ if (!this.plugin.config.schedule.enabled) {
23
+ return;
24
+ }
25
+
26
+ const cronExpression = this.plugin.config.schedule.cron;
27
+ if (!cronExpression) {
28
+ this.plugin.emit('recon:scheduler-warning', {
29
+ message: 'Schedule enabled but no cron expression provided'
30
+ });
31
+ return;
32
+ }
33
+
34
+ // Register cron job with SchedulerPlugin (if available)
35
+ if (this.plugin.database?.plugins?.scheduler) {
36
+ const scheduler = this.plugin.database.plugins.scheduler;
37
+ this.cronJobId = await scheduler.registerJob({
38
+ name: `recon-sweep-${this.plugin.namespace || 'default'}`,
39
+ cron: cronExpression,
40
+ handler: async () => {
41
+ await this.triggerSweep('scheduled');
42
+ },
43
+ enabled: true,
44
+ metadata: {
45
+ plugin: 'recon',
46
+ namespace: this.plugin.namespace
47
+ }
48
+ });
49
+
50
+ this.plugin.emit('recon:scheduler-started', {
51
+ cronJobId: this.cronJobId,
52
+ cron: cronExpression
53
+ });
54
+ } else {
55
+ // Fallback: use setInterval (less accurate, no persistence)
56
+ this._startFallbackScheduler(cronExpression);
57
+ }
58
+
59
+ // Run on start if configured
60
+ if (this.plugin.config.schedule.runOnStart) {
61
+ await this.triggerSweep('startup');
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Stop the scheduler (unregister cron job)
67
+ */
68
+ async stop() {
69
+ if (this.cronJobId && this.plugin.database?.plugins?.scheduler) {
70
+ const scheduler = this.plugin.database.plugins.scheduler;
71
+ await scheduler.unregisterJob(this.cronJobId);
72
+ this.cronJobId = null;
73
+
74
+ this.plugin.emit('recon:scheduler-stopped', {});
75
+ }
76
+
77
+ if (this._fallbackIntervalId) {
78
+ clearInterval(this._fallbackIntervalId);
79
+ this._fallbackIntervalId = null;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Trigger a sweep of all enabled targets
85
+ */
86
+ async triggerSweep(reason = 'manual') {
87
+ const targetManager = this.plugin._targetManager;
88
+ const activeTargets = await targetManager.list({ includeDisabled: false });
89
+
90
+ if (!activeTargets.length) {
91
+ this.plugin.emit('recon:no-active-targets', {
92
+ reason,
93
+ message: 'No active targets configured for sweep'
94
+ });
95
+ return;
96
+ }
97
+
98
+ this.plugin.emit('recon:sweep-started', {
99
+ reason,
100
+ targetCount: activeTargets.length,
101
+ targets: activeTargets.map(t => t.id)
102
+ });
103
+
104
+ await PromisePool.withConcurrency(this.plugin.config.concurrency || 1)
105
+ .for(activeTargets)
106
+ .process(async (targetEntry) => {
107
+ try {
108
+ const report = await this.plugin.runDiagnostics(targetEntry.target, {
109
+ behavior: targetEntry.behavior,
110
+ features: targetEntry.features,
111
+ tools: targetEntry.tools,
112
+ persist: targetEntry.persist ?? true
113
+ });
114
+
115
+ this.plugin.emit('recon:completed', {
116
+ reason,
117
+ target: report.target.host,
118
+ status: report.status,
119
+ scanCount: (targetEntry.scanCount || 0) + 1,
120
+ endedAt: report.endedAt
121
+ });
122
+
123
+ // Update target metadata
124
+ await targetManager.updateScanMetadata(targetEntry.id, report);
125
+ } catch (error) {
126
+ this.plugin.emit('recon:target-error', {
127
+ reason,
128
+ target: targetEntry.target,
129
+ message: error?.message || 'Recon execution failed',
130
+ error
131
+ });
132
+ }
133
+ });
134
+
135
+ this.plugin.emit('recon:sweep-completed', {
136
+ reason,
137
+ targetCount: activeTargets.length
138
+ });
139
+ }
140
+
141
+ // ========================================
142
+ // Private Helper Methods
143
+ // ========================================
144
+
145
+ _startFallbackScheduler(cronExpression) {
146
+ // Simple fallback: parse cron and use setInterval
147
+ // NOTE: This is NOT production-ready - use SchedulerPlugin instead
148
+ const intervalMs = this._parseCronToInterval(cronExpression);
149
+
150
+ this._fallbackIntervalId = setInterval(async () => {
151
+ await this.triggerSweep('scheduled-fallback');
152
+ }, intervalMs);
153
+
154
+ this.plugin.emit('recon:scheduler-started', {
155
+ cronJobId: 'fallback',
156
+ cron: cronExpression,
157
+ warning: 'Using fallback scheduler - install SchedulerPlugin for accurate cron execution'
158
+ });
159
+ }
160
+
161
+ _parseCronToInterval(cronExpression) {
162
+ // Very basic cron parsing for fallback mode
163
+ // Format: minute hour day month weekday
164
+ const parts = cronExpression.split(' ');
165
+
166
+ if (parts[0].startsWith('*/')) {
167
+ const minutes = parseInt(parts[0].substring(2));
168
+ return minutes * 60 * 1000;
169
+ }
170
+
171
+ if (parts[1].startsWith('*/')) {
172
+ const hours = parseInt(parts[1].substring(2));
173
+ return hours * 60 * 60 * 1000;
174
+ }
175
+
176
+ // Default: every hour
177
+ return 60 * 60 * 1000;
178
+ }
179
+ }