@feardread/fear 1.0.1

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 (99) hide show
  1. package/FEAR.js +459 -0
  2. package/FEARServer.js +280 -0
  3. package/controllers/agent.js +438 -0
  4. package/controllers/auth/index.js +345 -0
  5. package/controllers/auth/token.js +50 -0
  6. package/controllers/blog.js +105 -0
  7. package/controllers/brand.js +10 -0
  8. package/controllers/cart.js +425 -0
  9. package/controllers/category.js +9 -0
  10. package/controllers/coupon.js +63 -0
  11. package/controllers/crud/crud.js +508 -0
  12. package/controllers/crud/index.js +36 -0
  13. package/controllers/email.js +34 -0
  14. package/controllers/enquiry.js +65 -0
  15. package/controllers/events.js +9 -0
  16. package/controllers/order.js +125 -0
  17. package/controllers/payment.js +31 -0
  18. package/controllers/product.js +147 -0
  19. package/controllers/review.js +247 -0
  20. package/controllers/tag.js +10 -0
  21. package/controllers/task.js +10 -0
  22. package/controllers/upload.js +41 -0
  23. package/controllers/user.js +401 -0
  24. package/index.js +7 -0
  25. package/libs/agent/index.js +561 -0
  26. package/libs/agent/modules/ai/ai.js +285 -0
  27. package/libs/agent/modules/ai/chat.js +518 -0
  28. package/libs/agent/modules/ai/config.js +688 -0
  29. package/libs/agent/modules/ai/operations.js +787 -0
  30. package/libs/agent/modules/analyze/api.js +546 -0
  31. package/libs/agent/modules/analyze/dorks.js +395 -0
  32. package/libs/agent/modules/ccard/README.md +454 -0
  33. package/libs/agent/modules/ccard/audit.js +479 -0
  34. package/libs/agent/modules/ccard/checker.js +674 -0
  35. package/libs/agent/modules/ccard/payment-processors.json +16 -0
  36. package/libs/agent/modules/ccard/validator.js +629 -0
  37. package/libs/agent/modules/code/analyzer.js +303 -0
  38. package/libs/agent/modules/code/jquery.js +1093 -0
  39. package/libs/agent/modules/code/react.js +1536 -0
  40. package/libs/agent/modules/code/refactor.js +499 -0
  41. package/libs/agent/modules/crypto/exchange.js +564 -0
  42. package/libs/agent/modules/net/proxy.js +409 -0
  43. package/libs/agent/modules/security/cve.js +442 -0
  44. package/libs/agent/modules/security/monitor.js +360 -0
  45. package/libs/agent/modules/security/scanner.js +300 -0
  46. package/libs/agent/modules/security/vulnerability.js +506 -0
  47. package/libs/agent/modules/security/web.js +465 -0
  48. package/libs/agent/modules/utils/browser.js +492 -0
  49. package/libs/agent/modules/utils/colorizer.js +285 -0
  50. package/libs/agent/modules/utils/manager.js +478 -0
  51. package/libs/cloud/index.js +228 -0
  52. package/libs/config/db.js +21 -0
  53. package/libs/config/validator.js +82 -0
  54. package/libs/db/index.js +318 -0
  55. package/libs/emailer/imap.js +126 -0
  56. package/libs/emailer/info.js +41 -0
  57. package/libs/emailer/smtp.js +77 -0
  58. package/libs/handler/async.js +3 -0
  59. package/libs/handler/error.js +66 -0
  60. package/libs/handler/index.js +161 -0
  61. package/libs/logger/index.js +49 -0
  62. package/libs/logger/morgan.js +24 -0
  63. package/libs/passport/passport.js +109 -0
  64. package/libs/search/api.js +384 -0
  65. package/libs/search/features.js +219 -0
  66. package/libs/search/service.js +64 -0
  67. package/libs/swagger/config.js +18 -0
  68. package/libs/swagger/index.js +35 -0
  69. package/libs/validator/index.js +254 -0
  70. package/models/blog.js +31 -0
  71. package/models/brand.js +12 -0
  72. package/models/cart.js +14 -0
  73. package/models/category.js +11 -0
  74. package/models/coupon.js +9 -0
  75. package/models/customer.js +0 -0
  76. package/models/enquiry.js +29 -0
  77. package/models/events.js +13 -0
  78. package/models/order.js +94 -0
  79. package/models/product.js +32 -0
  80. package/models/review.js +14 -0
  81. package/models/tag.js +10 -0
  82. package/models/task.js +11 -0
  83. package/models/user.js +68 -0
  84. package/package.json +12 -0
  85. package/routes/agent.js +615 -0
  86. package/routes/auth.js +13 -0
  87. package/routes/blog.js +19 -0
  88. package/routes/brand.js +15 -0
  89. package/routes/cart.js +105 -0
  90. package/routes/category.js +16 -0
  91. package/routes/coupon.js +15 -0
  92. package/routes/enquiry.js +14 -0
  93. package/routes/events.js +16 -0
  94. package/routes/mail.js +170 -0
  95. package/routes/order.js +19 -0
  96. package/routes/product.js +22 -0
  97. package/routes/review.js +11 -0
  98. package/routes/task.js +12 -0
  99. package/routes/user.js +17 -0
@@ -0,0 +1,465 @@
1
+ // modules/web-scraper.js - Web Scraping & Content Extraction
2
+ const https = require('https');
3
+ const http = require('http');
4
+ const { URL } = require('url');
5
+ const fs = require('fs').promises;
6
+ const colorizer = require('../utils/colorizer');
7
+
8
+ const WebScraper = function() {
9
+ this.userAgent = 'Security-AI-Agent/2.2 (Web Scraper)';
10
+ this.timeout = 10000;
11
+ this.maxRedirects = 5;
12
+ }
13
+
14
+ WebScraper.prototype = {
15
+
16
+ scrape(args) {
17
+ const url = args[0];
18
+
19
+ if (!url) {
20
+ console.log(colorizer.error('Usage: scrape <url>'));
21
+ console.log(colorizer.info('Examples:'));
22
+ console.log(colorizer.dim(' scrape https://example.com'));
23
+ console.log(colorizer.dim(' scrape https://news.ycombinator.com\n'));
24
+ return Promise.resolve();
25
+ }
26
+
27
+ console.log(colorizer.header('Web Scraper'));
28
+ console.log(colorizer.separator());
29
+ console.log(colorizer.cyan('URL: ') + colorizer.bright(url));
30
+ console.log(colorizer.cyan('Fetching content...\n'));
31
+
32
+ return this.fetchURL(url)
33
+ .then(data => {
34
+ console.log(colorizer.success('Content fetched successfully\n'));
35
+
36
+ const extracted = this.extractContent(data.body, url);
37
+ this.displayResults(extracted, data);
38
+
39
+ return extracted;
40
+ })
41
+ .catch(err => {
42
+ console.log(colorizer.error('Scraping failed: ' + err.message + '\n'));
43
+ });
44
+ },
45
+
46
+ fetchURL(url, redirectCount = 0) {
47
+ return new Promise((resolve, reject) => {
48
+ if (redirectCount >= this.maxRedirects) {
49
+ return reject(new Error('Too many redirects'));
50
+ }
51
+
52
+ const parsedUrl = new URL(url);
53
+ const lib = parsedUrl.protocol === 'https:' ? https : http;
54
+
55
+ const options = {
56
+ hostname: parsedUrl.hostname,
57
+ port: parsedUrl.port,
58
+ path: parsedUrl.pathname + parsedUrl.search,
59
+ method: 'GET',
60
+ headers: {
61
+ 'User-Agent': this.userAgent,
62
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
63
+ 'Accept-Language': 'en-US,en;q=0.5',
64
+ 'Accept-Encoding': 'identity',
65
+ 'Connection': 'close'
66
+ },
67
+ timeout: this.timeout,
68
+ rejectUnauthorized: false
69
+ };
70
+
71
+ const req = lib.request(options, res => {
72
+ // Handle redirects
73
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
74
+ const redirectUrl = new URL(res.headers.location, url).href;
75
+ console.log(colorizer.dim(' Redirecting to: ' + redirectUrl));
76
+ return this.fetchURL(redirectUrl, redirectCount + 1)
77
+ .then(resolve)
78
+ .catch(reject);
79
+ }
80
+
81
+ let data = '';
82
+
83
+ res.on('data', chunk => {
84
+ data += chunk.toString();
85
+ });
86
+
87
+ res.on('end', () => {
88
+ resolve({
89
+ statusCode: res.statusCode,
90
+ headers: res.headers,
91
+ body: data,
92
+ url: url
93
+ });
94
+ });
95
+ });
96
+
97
+ req.on('error', err => {
98
+ reject(err);
99
+ });
100
+
101
+ req.on('timeout', () => {
102
+ req.destroy();
103
+ reject(new Error('Request timeout'));
104
+ });
105
+
106
+ req.end();
107
+ });
108
+ },
109
+
110
+ extractContent(html, url) {
111
+ const extracted = {
112
+ title: this.extractTitle(html),
113
+ description: this.extractDescription(html),
114
+ links: this.extractLinks(html, url),
115
+ images: this.extractImages(html, url),
116
+ headings: this.extractHeadings(html),
117
+ text: this.extractText(html),
118
+ meta: this.extractMeta(html),
119
+ scripts: this.extractScripts(html),
120
+ forms: this.extractForms(html)
121
+ };
122
+
123
+ return extracted;
124
+ },
125
+
126
+ extractTitle(html) {
127
+ const match = html.match(/<title[^>]*>([^<]+)<\/title>/i);
128
+ return match ? match[1].trim() : 'No title found';
129
+ },
130
+
131
+ extractDescription(html) {
132
+ const match = html.match(/<meta\s+name=["']description["']\s+content=["']([^"']+)["']/i);
133
+ return match ? match[1].trim() : 'No description found';
134
+ },
135
+
136
+ extractLinks(html, baseUrl) {
137
+ const linkRegex = /<a[^>]+href=["']([^"']+)["'][^>]*>([^<]*)<\/a>/gi;
138
+ const links = [];
139
+ let match;
140
+
141
+ while ((match = linkRegex.exec(html)) !== null) {
142
+ try {
143
+ const href = match[1];
144
+ const text = match[2].trim() || '(no text)';
145
+ const absoluteUrl = new URL(href, baseUrl).href;
146
+ links.push({ url: absoluteUrl, text: text });
147
+ } catch (err) {
148
+ // Invalid URL, skip
149
+ }
150
+ }
151
+
152
+ return links;
153
+ },
154
+
155
+ extractImages(html, baseUrl) {
156
+ const imgRegex = /<img[^>]+src=["']([^"']+)["'][^>]*(?:alt=["']([^"']*)["'])?[^>]*>/gi;
157
+ const images = [];
158
+ let match;
159
+
160
+ while ((match = imgRegex.exec(html)) !== null) {
161
+ try {
162
+ const src = match[1];
163
+ const alt = match[2] || '(no alt text)';
164
+ const absoluteUrl = new URL(src, baseUrl).href;
165
+ images.push({ url: absoluteUrl, alt: alt });
166
+ } catch (err) {
167
+ // Invalid URL, skip
168
+ }
169
+ }
170
+
171
+ return images;
172
+ },
173
+
174
+ extractHeadings(html) {
175
+ const headings = [];
176
+
177
+ for (let i = 1; i <= 6; i++) {
178
+ const regex = new RegExp(`<h${i}[^>]*>([^<]+)</h${i}>`, 'gi');
179
+ let match;
180
+
181
+ while ((match = regex.exec(html)) !== null) {
182
+ headings.push({
183
+ level: i,
184
+ text: match[1].trim()
185
+ });
186
+ }
187
+ }
188
+
189
+ return headings;
190
+ },
191
+
192
+ extractText(html) {
193
+ // Remove scripts and styles
194
+ let text = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
195
+ text = text.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
196
+
197
+ // Remove HTML tags
198
+ text = text.replace(/<[^>]+>/g, ' ');
199
+
200
+ // Clean up whitespace
201
+ text = text.replace(/\s+/g, ' ').trim();
202
+
203
+ return text.substring(0, 500) + (text.length > 500 ? '...' : '');
204
+ },
205
+
206
+ extractMeta(html) {
207
+ const metaRegex = /<meta\s+([^>]+)>/gi;
208
+ const meta = [];
209
+ let match;
210
+
211
+ while ((match = metaRegex.exec(html)) !== null) {
212
+ const attrs = match[1];
213
+ const nameMatch = attrs.match(/name=["']([^"']+)["']/i);
214
+ const contentMatch = attrs.match(/content=["']([^"']+)["']/i);
215
+
216
+ if (nameMatch && contentMatch) {
217
+ meta.push({
218
+ name: nameMatch[1],
219
+ content: contentMatch[1]
220
+ });
221
+ }
222
+ }
223
+
224
+ return meta;
225
+ },
226
+
227
+ extractScripts(html) {
228
+ const scriptRegex = /<script[^>]*(?:src=["']([^"']+)["'])?[^>]*>/gi;
229
+ const scripts = [];
230
+ let match;
231
+
232
+ while ((match = scriptRegex.exec(html)) !== null) {
233
+ if (match[1]) {
234
+ scripts.push(match[1]);
235
+ }
236
+ }
237
+
238
+ return scripts;
239
+ },
240
+
241
+ extractForms(html) {
242
+ const formRegex = /<form[^>]*action=["']([^"']+)["'][^>]*method=["']([^"']+)["'][^>]*>/gi;
243
+ const forms = [];
244
+ let match;
245
+
246
+ while ((match = formRegex.exec(html)) !== null) {
247
+ forms.push({
248
+ action: match[1],
249
+ method: match[2].toUpperCase()
250
+ });
251
+ }
252
+
253
+ return forms;
254
+ },
255
+
256
+ displayResults(extracted, data) {
257
+ console.log(colorizer.section('Page Information'));
258
+ console.log(colorizer.cyan('Title: ') + colorizer.bright(extracted.title));
259
+ console.log(colorizer.cyan('Description: ') + extracted.description);
260
+ console.log(colorizer.cyan('Status: ') + (data.statusCode === 200 ? colorizer.green(data.statusCode) : colorizer.red(data.statusCode)));
261
+
262
+ if (data.headers['content-type']) {
263
+ console.log(colorizer.cyan('Content-Type: ') + data.headers['content-type']);
264
+ }
265
+
266
+ if (extracted.headings.length > 0) {
267
+ console.log(colorizer.section('Headings (' + extracted.headings.length + ')'));
268
+ extracted.headings.slice(0, 10).forEach(h => {
269
+ const indent = ' '.repeat(h.level - 1);
270
+ console.log(colorizer.dim(indent + 'H' + h.level + ':') + ' ' + h.text);
271
+ });
272
+ if (extracted.headings.length > 10) {
273
+ console.log(colorizer.dim(' ... and ' + (extracted.headings.length - 10) + ' more'));
274
+ }
275
+ }
276
+
277
+ if (extracted.links.length > 0) {
278
+ console.log(colorizer.section('Links (' + extracted.links.length + ')'));
279
+ extracted.links.slice(0, 10).forEach(link => {
280
+ console.log(colorizer.bullet(link.text));
281
+ console.log(colorizer.dim(' ' + link.url));
282
+ });
283
+ if (extracted.links.length > 10) {
284
+ console.log(colorizer.dim(' ... and ' + (extracted.links.length - 10) + ' more'));
285
+ }
286
+ }
287
+
288
+ if (extracted.images.length > 0) {
289
+ console.log(colorizer.section('Images (' + extracted.images.length + ')'));
290
+ extracted.images.slice(0, 5).forEach(img => {
291
+ console.log(colorizer.bullet(img.alt));
292
+ console.log(colorizer.dim(' ' + img.url));
293
+ });
294
+ if (extracted.images.length > 5) {
295
+ console.log(colorizer.dim(' ... and ' + (extracted.images.length - 5) + ' more'));
296
+ }
297
+ }
298
+
299
+ if (extracted.forms.length > 0) {
300
+ console.log(colorizer.section('Forms (' + extracted.forms.length + ')'));
301
+ extracted.forms.forEach(form => {
302
+ console.log(colorizer.bullet(colorizer.yellow(form.method) + ' -> ' + form.action));
303
+ });
304
+ }
305
+
306
+ if (extracted.scripts.length > 0) {
307
+ console.log(colorizer.section('External Scripts (' + extracted.scripts.length + ')'));
308
+ extracted.scripts.slice(0, 5).forEach(script => {
309
+ console.log(colorizer.bullet(script));
310
+ });
311
+ if (extracted.scripts.length > 5) {
312
+ console.log(colorizer.dim(' ... and ' + (extracted.scripts.length - 5) + ' more'));
313
+ }
314
+ }
315
+
316
+ console.log(colorizer.section('Text Preview'));
317
+ console.log(colorizer.dim(extracted.text));
318
+ console.log();
319
+ },
320
+
321
+ scrapeLinks(args) {
322
+ const url = args[0];
323
+
324
+ if (!url) {
325
+ console.log(colorizer.error('Usage: scrape-links <url>\n'));
326
+ return Promise.resolve();
327
+ }
328
+
329
+ console.log(colorizer.header('Link Extractor'));
330
+ console.log(colorizer.separator());
331
+ console.log(colorizer.cyan('URL: ') + colorizer.bright(url) + '\n');
332
+
333
+ return this.fetchURL(url)
334
+ .then(data => {
335
+ const links = this.extractLinks(data.body, url);
336
+
337
+ console.log(colorizer.success('Found ' + links.length + ' links\n'));
338
+
339
+ links.forEach((link, i) => {
340
+ console.log(colorizer.numbered(i + 1, link.text));
341
+ console.log(colorizer.dim(' ' + link.url));
342
+ });
343
+ console.log();
344
+
345
+ return links;
346
+ })
347
+ .catch(err => {
348
+ console.log(colorizer.error('Failed to extract links: ' + err.message + '\n'));
349
+ });
350
+ },
351
+
352
+ scrapeImages(args) {
353
+ const url = args[0];
354
+
355
+ if (!url) {
356
+ console.log(colorizer.error('Usage: scrape-images <url>\n'));
357
+ return Promise.resolve();
358
+ }
359
+
360
+ console.log(colorizer.header('Image Extractor'));
361
+ console.log(colorizer.separator());
362
+ console.log(colorizer.cyan('URL: ') + colorizer.bright(url) + '\n');
363
+
364
+ return this.fetchURL(url)
365
+ .then(data => {
366
+ const images = this.extractImages(data.body, url);
367
+
368
+ console.log(colorizer.success('Found ' + images.length + ' images\n'));
369
+
370
+ images.forEach((img, i) => {
371
+ console.log(colorizer.numbered(i + 1, img.alt));
372
+ console.log(colorizer.dim(' ' + img.url));
373
+ });
374
+ console.log();
375
+
376
+ return images;
377
+ })
378
+ .catch(err => {
379
+ console.log(colorizer.error('Failed to extract images: ' + err.message + '\n'));
380
+ });
381
+ },
382
+
383
+ exportScrape(args) {
384
+ const url = args[0];
385
+ const filename = args[1] || 'scrape-' + Date.now() + '.json';
386
+
387
+ if (!url) {
388
+ console.log(colorizer.error('Usage: export-scrape <url> [filename]\n'));
389
+ return Promise.resolve();
390
+ }
391
+
392
+ return this.fetchURL(url)
393
+ .then(data => {
394
+ const extracted = this.extractContent(data.body, url);
395
+
396
+ const report = {
397
+ url: url,
398
+ timestamp: new Date().toISOString(),
399
+ statusCode: data.statusCode,
400
+ headers: data.headers,
401
+ content: extracted
402
+ };
403
+
404
+ return fs.writeFile(filename, JSON.stringify(report, null, 2));
405
+ })
406
+ .then(() => {
407
+ console.log(colorizer.success('Scrape data exported to: ' + filename + '\n'));
408
+ })
409
+ .catch(err => {
410
+ console.log(colorizer.error('Export failed: ' + err.message + '\n'));
411
+ });
412
+ },
413
+
414
+ analyzeSecurityHeaders(args) {
415
+ const url = args[0];
416
+
417
+ if (!url) {
418
+ console.log(colorizer.error('Usage: analyze-headers <url>\n'));
419
+ return Promise.resolve();
420
+ }
421
+
422
+ console.log(colorizer.header('Security Headers Analysis'));
423
+ console.log(colorizer.separator());
424
+ console.log(colorizer.cyan('URL: ') + colorizer.bright(url) + '\n');
425
+
426
+ return this.fetchURL(url)
427
+ .then(data => {
428
+ const headers = data.headers;
429
+
430
+ const securityHeaders = {
431
+ 'strict-transport-security': { present: !!headers['strict-transport-security'], severity: 'HIGH' },
432
+ 'content-security-policy': { present: !!headers['content-security-policy'], severity: 'HIGH' },
433
+ 'x-frame-options': { present: !!headers['x-frame-options'], severity: 'MEDIUM' },
434
+ 'x-content-type-options': { present: !!headers['x-content-type-options'], severity: 'MEDIUM' },
435
+ 'x-xss-protection': { present: !!headers['x-xss-protection'], severity: 'LOW' },
436
+ 'referrer-policy': { present: !!headers['referrer-policy'], severity: 'LOW' }
437
+ };
438
+
439
+ console.log(colorizer.section('Security Headers Status'));
440
+
441
+ Object.entries(securityHeaders).forEach(([header, info]) => {
442
+ const status = info.present ? colorizer.green('PRESENT') : colorizer.red('MISSING');
443
+ const severity = info.severity;
444
+ console.log(colorizer.bullet(header + ': ' + status + ' (' + severity + ')'));
445
+ if (info.present && headers[header]) {
446
+ console.log(colorizer.dim(' Value: ' + headers[header]));
447
+ }
448
+ });
449
+
450
+ const missingCount = Object.values(securityHeaders).filter(h => !h.present).length;
451
+ const score = Math.floor(((6 - missingCount) / 6) * 100);
452
+
453
+ console.log(colorizer.section('Security Score: ' +
454
+ (score >= 80 ? colorizer.green(score) :
455
+ score >= 50 ? colorizer.yellow(score) :
456
+ colorizer.red(score)) + '/100'));
457
+ console.log();
458
+ })
459
+ .catch(err => {
460
+ console.log(colorizer.error('Analysis failed: ' + err.message + '\n'));
461
+ });
462
+ }
463
+ };
464
+
465
+ module.exports = WebScraper;