mcp-wordpress 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +503 -0
  2. package/dist/client/api.d.ts +90 -0
  3. package/dist/client/api.d.ts.map +1 -1
  4. package/dist/client/api.js +90 -0
  5. package/dist/client/api.js.map +1 -1
  6. package/dist/security/AISecurityScanner.d.ts +175 -0
  7. package/dist/security/AISecurityScanner.d.ts.map +1 -0
  8. package/dist/security/AISecurityScanner.js +645 -0
  9. package/dist/security/AISecurityScanner.js.map +1 -0
  10. package/dist/security/AutomatedRemediation.d.ts +145 -0
  11. package/dist/security/AutomatedRemediation.d.ts.map +1 -0
  12. package/dist/security/AutomatedRemediation.js +535 -0
  13. package/dist/security/AutomatedRemediation.js.map +1 -0
  14. package/dist/security/SecurityCIPipeline.d.ts +213 -0
  15. package/dist/security/SecurityCIPipeline.d.ts.map +1 -0
  16. package/dist/security/SecurityCIPipeline.js +684 -0
  17. package/dist/security/SecurityCIPipeline.js.map +1 -0
  18. package/dist/security/SecurityConfigManager.d.ts +294 -0
  19. package/dist/security/SecurityConfigManager.d.ts.map +1 -0
  20. package/dist/security/SecurityConfigManager.js +553 -0
  21. package/dist/security/SecurityConfigManager.js.map +1 -0
  22. package/dist/security/SecurityMonitoring.d.ts +245 -0
  23. package/dist/security/SecurityMonitoring.d.ts.map +1 -0
  24. package/dist/security/SecurityMonitoring.js +596 -0
  25. package/dist/security/SecurityMonitoring.js.map +1 -0
  26. package/dist/security/SecurityReviewer.d.ts +168 -0
  27. package/dist/security/SecurityReviewer.d.ts.map +1 -0
  28. package/dist/security/SecurityReviewer.js +683 -0
  29. package/dist/security/SecurityReviewer.js.map +1 -0
  30. package/dist/security/index.d.ts +182 -0
  31. package/dist/security/index.d.ts.map +1 -0
  32. package/dist/security/index.js +189 -0
  33. package/dist/security/index.js.map +1 -0
  34. package/dist/tools/media.d.ts +43 -4
  35. package/dist/tools/media.d.ts.map +1 -1
  36. package/dist/tools/media.js +43 -4
  37. package/dist/tools/media.js.map +1 -1
  38. package/dist/tools/posts.d.ts +225 -4
  39. package/dist/tools/posts.d.ts.map +1 -1
  40. package/dist/tools/posts.js +225 -4
  41. package/dist/tools/posts.js.map +1 -1
  42. package/docs/DOCKER_PUBLISHING_TROUBLESHOOTING.md +233 -0
  43. package/docs/PUBLISHING-TROUBLESHOOTING.md +227 -0
  44. package/docs/api/README.md +53 -11
  45. package/docs/api/openapi.json +10 -10
  46. package/docs/api/summary.json +1 -1
  47. package/docs/api/tools/wp_create_post.md +9 -3
  48. package/docs/api/tools/wp_delete_post.md +2 -3
  49. package/docs/api/tools/wp_get_current_user.md +7 -1
  50. package/docs/api/tools/wp_get_post.md +2 -3
  51. package/docs/api/tools/wp_get_post_revisions.md +1 -1
  52. package/docs/api/tools/wp_list_posts.md +10 -3
  53. package/docs/api/tools/wp_list_users.md +8 -1
  54. package/docs/api/tools/wp_search_site.md +8 -1
  55. package/docs/api/tools/wp_test_auth.md +8 -1
  56. package/docs/api/tools/wp_update_post.md +2 -3
  57. package/docs/examples/docker-production.md +801 -0
  58. package/docs/examples/multi-site-setup.md +575 -0
  59. package/docs/examples/single-site-setup.md +390 -0
  60. package/docs/examples/use-case-workflows.md +469 -0
  61. package/package.json +11 -3
  62. package/src/client/api.ts +90 -0
  63. package/src/security/AISecurityScanner.ts +780 -0
  64. package/src/security/AutomatedRemediation.ts +665 -0
  65. package/src/security/SecurityCIPipeline.ts +969 -0
  66. package/src/security/SecurityConfigManager.ts +829 -0
  67. package/src/security/SecurityMonitoring.ts +841 -0
  68. package/src/security/SecurityReviewer.ts +855 -0
  69. package/src/security/index.ts +249 -0
  70. package/src/tools/media.ts +43 -4
  71. package/src/tools/posts.ts +225 -4
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Automated Security Remediation System
3
+ * Provides intelligent automated fixes for detected vulnerabilities
4
+ */
5
+ import { SecurityVulnerability, SecurityScanResult } from "./AISecurityScanner";
6
+ interface RemediationAction {
7
+ id: string;
8
+ type: "replace" | "insert" | "delete" | "config" | "file";
9
+ target: {
10
+ file?: string | undefined;
11
+ line?: number | undefined;
12
+ pattern?: RegExp | undefined;
13
+ value?: string | undefined;
14
+ };
15
+ replacement: {
16
+ content?: string;
17
+ config?: Record<string, any>;
18
+ action?: string;
19
+ };
20
+ backup: {
21
+ enabled: boolean;
22
+ path?: string;
23
+ };
24
+ validation: {
25
+ test?: string;
26
+ expected?: any;
27
+ };
28
+ }
29
+ export interface RemediationResult {
30
+ vulnerabilityId: string;
31
+ success: boolean;
32
+ action: string;
33
+ details: string;
34
+ timestamp: Date;
35
+ backupPath?: string | undefined;
36
+ validationResult?: boolean | undefined;
37
+ }
38
+ interface RemediationPlan {
39
+ planId: string;
40
+ vulnerabilities: SecurityVulnerability[];
41
+ actions: RemediationAction[];
42
+ estimatedDuration: number;
43
+ riskLevel: "low" | "medium" | "high";
44
+ requiresApproval: boolean;
45
+ }
46
+ /**
47
+ * Automated Security Remediation Engine
48
+ */
49
+ export declare class AutomatedRemediation {
50
+ private remediationHistory;
51
+ private backupDirectory;
52
+ /**
53
+ * Create remediation plan for scan results
54
+ */
55
+ createRemediationPlan(scanResult: SecurityScanResult): Promise<RemediationPlan>;
56
+ /**
57
+ * Create remediation action for a specific vulnerability
58
+ */
59
+ private createRemediationAction;
60
+ /**
61
+ * Create SQL injection remediation
62
+ */
63
+ private createSQLInjectionRemediation;
64
+ /**
65
+ * Create XSS remediation
66
+ */
67
+ private createXSSRemediation;
68
+ /**
69
+ * Create path traversal remediation
70
+ */
71
+ private createPathTraversalRemediation;
72
+ /**
73
+ * Create credential exposure remediation
74
+ */
75
+ private createCredentialExposureRemediation;
76
+ /**
77
+ * Create configuration remediation
78
+ */
79
+ private createConfigRemediation;
80
+ /**
81
+ * Create information disclosure remediation
82
+ */
83
+ private createInfoDisclosureRemediation;
84
+ /**
85
+ * Execute remediation plan
86
+ */
87
+ executeRemediationPlan(plan: RemediationPlan, options?: {
88
+ dryRun?: boolean;
89
+ requireConfirmation?: boolean;
90
+ }): Promise<RemediationResult[]>;
91
+ /**
92
+ * Execute a single remediation action
93
+ */
94
+ private executeRemediationAction;
95
+ /**
96
+ * Execute replace action
97
+ */
98
+ private executeReplaceAction;
99
+ /**
100
+ * Execute insert action
101
+ */
102
+ private executeInsertAction;
103
+ /**
104
+ * Execute delete action
105
+ */
106
+ private executeDeleteAction;
107
+ /**
108
+ * Execute config action
109
+ */
110
+ private executeConfigAction;
111
+ /**
112
+ * Execute file action
113
+ */
114
+ private executeFileAction;
115
+ /**
116
+ * Create backup of file
117
+ */
118
+ private createBackup;
119
+ /**
120
+ * Ensure backup directory exists
121
+ */
122
+ private ensureBackupDirectory;
123
+ /**
124
+ * Validate remediation
125
+ */
126
+ private validateRemediation;
127
+ /**
128
+ * Simulate remediation actions for dry run
129
+ */
130
+ private simulateRemediationActions;
131
+ /**
132
+ * Get remediation history
133
+ */
134
+ getRemediationHistory(): RemediationResult[];
135
+ /**
136
+ * Rollback remediation using backup
137
+ */
138
+ rollbackRemediation(backupPath: string, targetFile: string): Promise<void>;
139
+ /**
140
+ * Clean up old backups
141
+ */
142
+ cleanupBackups(maxAge?: number): Promise<void>;
143
+ }
144
+ export {};
145
+ //# sourceMappingURL=AutomatedRemediation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomatedRemediation.d.ts","sourceRoot":"","sources":["../../src/security/AutomatedRemediation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,535 @@
1
+ /**
2
+ * Automated Security Remediation System
3
+ * Provides intelligent automated fixes for detected vulnerabilities
4
+ */
5
+ import * as fs from "fs/promises";
6
+ import * as path from "path";
7
+ import { SecurityUtils } from "./SecurityConfig";
8
+ import { SecurityValidationError } from "./InputValidator";
9
+ /**
10
+ * Automated remediation patterns for common vulnerabilities
11
+ */
12
+ const REMEDIATION_PATTERNS = {
13
+ sqlInjection: {
14
+ pattern: /(SELECT|INSERT|UPDATE|DELETE).*?[\'\"].*?[\'\"].*?(WHERE|FROM|INTO)/gi,
15
+ replacement: "// TODO: Replace with parameterized query",
16
+ confidence: 0.7,
17
+ },
18
+ xssSimple: {
19
+ pattern: /innerHTML\s*=\s*[^;]+;?/gi,
20
+ replacement: "textContent = $1; // XSS remediation",
21
+ confidence: 0.8,
22
+ },
23
+ pathTraversal: {
24
+ pattern: /\.\.[\/\\]/g,
25
+ replacement: "",
26
+ confidence: 0.9,
27
+ },
28
+ credentialExposure: {
29
+ pattern: /(password|secret|key|token)\s*[:=]\s*['"][^'"]+['"]/gi,
30
+ replacement: "$1 = process.env.$1?.toUpperCase() || '[REQUIRED]'",
31
+ confidence: 0.85,
32
+ },
33
+ httpToHttps: {
34
+ pattern: /http:\/\//gi,
35
+ replacement: "https://",
36
+ confidence: 0.95,
37
+ },
38
+ insecureConfig: {
39
+ pattern: /(ssl|secure|verify)\s*[:=]\s*false/gi,
40
+ replacement: "$1: true",
41
+ confidence: 0.9,
42
+ },
43
+ };
44
+ /**
45
+ * Automated Security Remediation Engine
46
+ */
47
+ export class AutomatedRemediation {
48
+ remediationHistory = [];
49
+ backupDirectory = "security-backups";
50
+ /**
51
+ * Create remediation plan for scan results
52
+ */
53
+ async createRemediationPlan(scanResult) {
54
+ const planId = SecurityUtils.generateSecureToken(16);
55
+ const remediableVulns = scanResult.vulnerabilities.filter((v) => v.remediation.automated);
56
+ console.log(`[Remediation] Creating plan for ${remediableVulns.length} remediable vulnerabilities`);
57
+ const actions = [];
58
+ let estimatedDuration = 0;
59
+ let maxRiskLevel = "low";
60
+ for (const vulnerability of remediableVulns) {
61
+ const action = await this.createRemediationAction(vulnerability);
62
+ if (action) {
63
+ actions.push(action);
64
+ estimatedDuration += 30; // 30 seconds per action estimate
65
+ // Update risk level
66
+ if (vulnerability.severity === "critical" || vulnerability.severity === "high") {
67
+ maxRiskLevel = "high";
68
+ }
69
+ else if (vulnerability.severity === "medium" && maxRiskLevel === "low") {
70
+ maxRiskLevel = "medium";
71
+ }
72
+ }
73
+ }
74
+ const requiresApproval = maxRiskLevel === "high" || actions.length > 10;
75
+ return {
76
+ planId,
77
+ vulnerabilities: remediableVulns,
78
+ actions,
79
+ estimatedDuration,
80
+ riskLevel: maxRiskLevel,
81
+ requiresApproval,
82
+ };
83
+ }
84
+ /**
85
+ * Create remediation action for a specific vulnerability
86
+ */
87
+ async createRemediationAction(vulnerability) {
88
+ const actionId = SecurityUtils.generateSecureToken(12);
89
+ switch (vulnerability.type) {
90
+ case "SQL Injection":
91
+ return this.createSQLInjectionRemediation(actionId, vulnerability);
92
+ case "Cross-Site Scripting (XSS)":
93
+ return this.createXSSRemediation(actionId, vulnerability);
94
+ case "Path Traversal":
95
+ return this.createPathTraversalRemediation(actionId, vulnerability);
96
+ case "Credential Exposure":
97
+ return this.createCredentialExposureRemediation(actionId, vulnerability);
98
+ case "Insecure Configuration":
99
+ return this.createConfigRemediation(actionId, vulnerability);
100
+ case "Information Disclosure":
101
+ return this.createInfoDisclosureRemediation(actionId, vulnerability);
102
+ default:
103
+ return null;
104
+ }
105
+ }
106
+ /**
107
+ * Create SQL injection remediation
108
+ */
109
+ createSQLInjectionRemediation(actionId, vulnerability) {
110
+ return {
111
+ id: actionId,
112
+ type: "replace",
113
+ target: {
114
+ file: vulnerability.location.file,
115
+ line: vulnerability.location.line,
116
+ pattern: REMEDIATION_PATTERNS.sqlInjection.pattern,
117
+ },
118
+ replacement: {
119
+ content: "// SECURITY FIX: Replace with parameterized query to prevent SQL injection\n" +
120
+ "// Example: db.query('SELECT * FROM users WHERE id = ?', [userId])",
121
+ },
122
+ backup: {
123
+ enabled: true,
124
+ },
125
+ validation: {
126
+ test: 'grep -n "SELECT.*WHERE" $file | wc -l',
127
+ expected: 0,
128
+ },
129
+ };
130
+ }
131
+ /**
132
+ * Create XSS remediation
133
+ */
134
+ createXSSRemediation(actionId, vulnerability) {
135
+ return {
136
+ id: actionId,
137
+ type: "replace",
138
+ target: {
139
+ file: vulnerability.location.file,
140
+ line: vulnerability.location.line,
141
+ pattern: /innerHTML\s*=\s*([^;]+);?/gi,
142
+ },
143
+ replacement: {
144
+ content: "textContent = $1; // XSS remediation: use textContent instead of innerHTML",
145
+ },
146
+ backup: {
147
+ enabled: true,
148
+ },
149
+ validation: {
150
+ test: 'grep -n "innerHTML" $file | wc -l',
151
+ expected: 0,
152
+ },
153
+ };
154
+ }
155
+ /**
156
+ * Create path traversal remediation
157
+ */
158
+ createPathTraversalRemediation(actionId, vulnerability) {
159
+ return {
160
+ id: actionId,
161
+ type: "replace",
162
+ target: {
163
+ file: vulnerability.location.file,
164
+ line: vulnerability.location.line,
165
+ pattern: /\.\.[\/\\]/g,
166
+ },
167
+ replacement: {
168
+ content: "", // Remove path traversal sequences
169
+ },
170
+ backup: {
171
+ enabled: true,
172
+ },
173
+ validation: {
174
+ test: 'grep -n "\\.\\./" $file | wc -l',
175
+ expected: 0,
176
+ },
177
+ };
178
+ }
179
+ /**
180
+ * Create credential exposure remediation
181
+ */
182
+ createCredentialExposureRemediation(actionId, vulnerability) {
183
+ return {
184
+ id: actionId,
185
+ type: "replace",
186
+ target: {
187
+ file: vulnerability.location.file,
188
+ line: vulnerability.location.line,
189
+ pattern: /(password|secret|key|token)\s*[:=]\s*['"][^'"]+['"]/gi,
190
+ },
191
+ replacement: {
192
+ content: "// SECURITY FIX: Credential moved to environment variable\n" +
193
+ "// Add to .env: $1=your_actual_value\n" +
194
+ "$1: process.env.$1 || (() => { throw new Error('$1 environment variable required'); })()",
195
+ },
196
+ backup: {
197
+ enabled: true,
198
+ },
199
+ validation: {
200
+ test: 'grep -n "password.*=.*[\'\\"]" $file | wc -l',
201
+ expected: 0,
202
+ },
203
+ };
204
+ }
205
+ /**
206
+ * Create configuration remediation
207
+ */
208
+ createConfigRemediation(actionId, vulnerability) {
209
+ return {
210
+ id: actionId,
211
+ type: "replace",
212
+ target: {
213
+ file: vulnerability.location.file,
214
+ line: vulnerability.location.line,
215
+ pattern: /(ssl|secure|verify)\s*[:=]\s*false/gi,
216
+ },
217
+ replacement: {
218
+ content: "$1: true // Security fix: enabled secure configuration",
219
+ },
220
+ backup: {
221
+ enabled: true,
222
+ },
223
+ validation: {
224
+ test: 'grep -n "ssl.*false" $file | wc -l',
225
+ expected: 0,
226
+ },
227
+ };
228
+ }
229
+ /**
230
+ * Create information disclosure remediation
231
+ */
232
+ createInfoDisclosureRemediation(actionId, vulnerability) {
233
+ return {
234
+ id: actionId,
235
+ type: "replace",
236
+ target: {
237
+ file: vulnerability.location.file,
238
+ line: vulnerability.location.line,
239
+ pattern: /(debug|trace|error)\s*[:=]\s*true/gi,
240
+ },
241
+ replacement: {
242
+ content: "$1: process.env.NODE_ENV !== 'production' // Security fix: disable in production",
243
+ },
244
+ backup: {
245
+ enabled: true,
246
+ },
247
+ validation: {
248
+ test: 'grep -n "debug.*true" $file | wc -l',
249
+ expected: 0,
250
+ },
251
+ };
252
+ }
253
+ /**
254
+ * Execute remediation plan
255
+ */
256
+ async executeRemediationPlan(plan, options = {}) {
257
+ console.log(`[Remediation] Executing plan ${plan.planId} with ${plan.actions.length} actions`);
258
+ if (options.dryRun) {
259
+ console.log("[Remediation] DRY RUN MODE - No changes will be made");
260
+ return this.simulateRemediationActions(plan.actions);
261
+ }
262
+ const results = [];
263
+ // Ensure backup directory exists
264
+ await this.ensureBackupDirectory();
265
+ for (const action of plan.actions) {
266
+ try {
267
+ console.log(`[Remediation] Executing action ${action.id} of type ${action.type}`);
268
+ const result = await this.executeRemediationAction(action);
269
+ results.push(result);
270
+ if (!result.success) {
271
+ console.error(`[Remediation] Action ${action.id} failed: ${result.details}`);
272
+ }
273
+ }
274
+ catch (error) {
275
+ console.error(`[Remediation] Action ${action.id} threw error:`, error);
276
+ results.push({
277
+ vulnerabilityId: action.id,
278
+ success: false,
279
+ action: action.type,
280
+ details: `Error: ${error instanceof Error ? error.message : String(error)}`,
281
+ timestamp: new Date(),
282
+ });
283
+ }
284
+ }
285
+ this.remediationHistory.push(...results);
286
+ const successCount = results.filter((r) => r.success).length;
287
+ console.log(`[Remediation] Plan completed: ${successCount}/${results.length} actions successful`);
288
+ return results;
289
+ }
290
+ /**
291
+ * Execute a single remediation action
292
+ */
293
+ async executeRemediationAction(action) {
294
+ const startTime = Date.now();
295
+ try {
296
+ let backupPath;
297
+ // Create backup if enabled
298
+ if (action.backup.enabled && action.target.file) {
299
+ backupPath = await this.createBackup(action.target.file);
300
+ }
301
+ // Execute the action based on type
302
+ switch (action.type) {
303
+ case "replace":
304
+ await this.executeReplaceAction(action);
305
+ break;
306
+ case "insert":
307
+ await this.executeInsertAction(action);
308
+ break;
309
+ case "delete":
310
+ await this.executeDeleteAction(action);
311
+ break;
312
+ case "config":
313
+ await this.executeConfigAction(action);
314
+ break;
315
+ case "file":
316
+ await this.executeFileAction(action);
317
+ break;
318
+ default:
319
+ throw new Error(`Unknown action type: ${action.type}`);
320
+ }
321
+ // Validate the fix if validation is provided
322
+ let validationResult;
323
+ if (action.validation && action.target.file) {
324
+ validationResult = await this.validateRemediation(action);
325
+ }
326
+ return {
327
+ vulnerabilityId: action.id,
328
+ success: true,
329
+ action: action.type,
330
+ details: `Remediation completed successfully in ${Date.now() - startTime}ms`,
331
+ timestamp: new Date(),
332
+ backupPath,
333
+ validationResult,
334
+ };
335
+ }
336
+ catch (error) {
337
+ return {
338
+ vulnerabilityId: action.id,
339
+ success: false,
340
+ action: action.type,
341
+ details: `Remediation failed: ${error instanceof Error ? error.message : String(error)}`,
342
+ timestamp: new Date(),
343
+ };
344
+ }
345
+ }
346
+ /**
347
+ * Execute replace action
348
+ */
349
+ async executeReplaceAction(action) {
350
+ if (!action.target.file || !action.target.pattern || !action.replacement.content) {
351
+ throw new Error("Replace action missing required fields");
352
+ }
353
+ const content = await fs.readFile(action.target.file, "utf-8");
354
+ const updatedContent = content.replace(action.target.pattern, action.replacement.content);
355
+ if (content === updatedContent) {
356
+ throw new Error("No changes made - pattern not found");
357
+ }
358
+ await fs.writeFile(action.target.file, updatedContent, "utf-8");
359
+ }
360
+ /**
361
+ * Execute insert action
362
+ */
363
+ async executeInsertAction(action) {
364
+ if (!action.target.file || !action.replacement.content) {
365
+ throw new Error("Insert action missing required fields");
366
+ }
367
+ const content = await fs.readFile(action.target.file, "utf-8");
368
+ const lines = content.split("\n");
369
+ const insertIndex = action.target.line ? Math.max(0, action.target.line - 1) : lines.length;
370
+ lines.splice(insertIndex, 0, action.replacement.content);
371
+ await fs.writeFile(action.target.file, lines.join("\n"), "utf-8");
372
+ }
373
+ /**
374
+ * Execute delete action
375
+ */
376
+ async executeDeleteAction(action) {
377
+ if (!action.target.file) {
378
+ throw new Error("Delete action missing file");
379
+ }
380
+ if (action.target.line) {
381
+ // Delete specific line
382
+ const content = await fs.readFile(action.target.file, "utf-8");
383
+ const lines = content.split("\n");
384
+ if (action.target.line > 0 && action.target.line <= lines.length) {
385
+ lines.splice(action.target.line - 1, 1);
386
+ await fs.writeFile(action.target.file, lines.join("\n"), "utf-8");
387
+ }
388
+ }
389
+ else if (action.target.pattern) {
390
+ // Delete pattern matches
391
+ const content = await fs.readFile(action.target.file, "utf-8");
392
+ const updatedContent = content.replace(action.target.pattern, "");
393
+ await fs.writeFile(action.target.file, updatedContent, "utf-8");
394
+ }
395
+ else {
396
+ throw new Error("Delete action missing target specification");
397
+ }
398
+ }
399
+ /**
400
+ * Execute config action
401
+ */
402
+ async executeConfigAction(action) {
403
+ if (!action.target.file || !action.replacement.config) {
404
+ throw new Error("Config action missing required fields");
405
+ }
406
+ const content = await fs.readFile(action.target.file, "utf-8");
407
+ const config = JSON.parse(content);
408
+ // Merge configuration changes
409
+ Object.assign(config, action.replacement.config);
410
+ await fs.writeFile(action.target.file, JSON.stringify(config, null, 2), "utf-8");
411
+ }
412
+ /**
413
+ * Execute file action
414
+ */
415
+ async executeFileAction(action) {
416
+ if (!action.replacement.action) {
417
+ throw new Error("File action missing action specification");
418
+ }
419
+ switch (action.replacement.action) {
420
+ case "delete":
421
+ if (action.target.file) {
422
+ await fs.unlink(action.target.file);
423
+ }
424
+ break;
425
+ case "create":
426
+ if (action.target.file && action.replacement.content) {
427
+ await fs.writeFile(action.target.file, action.replacement.content, "utf-8");
428
+ }
429
+ break;
430
+ default:
431
+ throw new Error(`Unknown file action: ${action.replacement.action}`);
432
+ }
433
+ }
434
+ /**
435
+ * Create backup of file
436
+ */
437
+ async createBackup(filePath) {
438
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
439
+ const backupPath = path.join(this.backupDirectory, `${path.basename(filePath)}.${timestamp}.backup`);
440
+ const content = await fs.readFile(filePath, "utf-8");
441
+ await fs.writeFile(backupPath, content, "utf-8");
442
+ console.log(`[Remediation] Created backup: ${backupPath}`);
443
+ return backupPath;
444
+ }
445
+ /**
446
+ * Ensure backup directory exists
447
+ */
448
+ async ensureBackupDirectory() {
449
+ try {
450
+ await fs.access(this.backupDirectory);
451
+ }
452
+ catch {
453
+ await fs.mkdir(this.backupDirectory, { recursive: true });
454
+ console.log(`[Remediation] Created backup directory: ${this.backupDirectory}`);
455
+ }
456
+ }
457
+ /**
458
+ * Validate remediation
459
+ */
460
+ async validateRemediation(action) {
461
+ if (!action.validation?.test || !action.target.file) {
462
+ return true; // No validation specified
463
+ }
464
+ try {
465
+ // This is a simplified validation - in practice you'd run the test command
466
+ const content = await fs.readFile(action.target.file, "utf-8");
467
+ // Simple pattern-based validation
468
+ if (action.target.pattern) {
469
+ const matches = content.match(action.target.pattern);
470
+ return (matches?.length || 0) === (action.validation.expected || 0);
471
+ }
472
+ return true;
473
+ }
474
+ catch (error) {
475
+ console.warn(`[Remediation] Validation failed for action ${action.id}:`, error);
476
+ return false;
477
+ }
478
+ }
479
+ /**
480
+ * Simulate remediation actions for dry run
481
+ */
482
+ async simulateRemediationActions(actions) {
483
+ const results = [];
484
+ for (const action of actions) {
485
+ results.push({
486
+ vulnerabilityId: action.id,
487
+ success: true,
488
+ action: `${action.type} (simulated)`,
489
+ details: `Would ${action.type} in ${action.target.file || "configuration"}`,
490
+ timestamp: new Date(),
491
+ });
492
+ }
493
+ return results;
494
+ }
495
+ /**
496
+ * Get remediation history
497
+ */
498
+ getRemediationHistory() {
499
+ return [...this.remediationHistory];
500
+ }
501
+ /**
502
+ * Rollback remediation using backup
503
+ */
504
+ async rollbackRemediation(backupPath, targetFile) {
505
+ try {
506
+ const backupContent = await fs.readFile(backupPath, "utf-8");
507
+ await fs.writeFile(targetFile, backupContent, "utf-8");
508
+ console.log(`[Remediation] Rolled back ${targetFile} from ${backupPath}`);
509
+ }
510
+ catch (error) {
511
+ throw new SecurityValidationError(`Rollback failed: ${error instanceof Error ? error.message : String(error)}`);
512
+ }
513
+ }
514
+ /**
515
+ * Clean up old backups
516
+ */
517
+ async cleanupBackups(maxAge = 7 * 24 * 60 * 60 * 1000) {
518
+ try {
519
+ const files = await fs.readdir(this.backupDirectory);
520
+ const now = Date.now();
521
+ for (const file of files) {
522
+ const filePath = path.join(this.backupDirectory, file);
523
+ const stats = await fs.stat(filePath);
524
+ if (now - stats.mtime.getTime() > maxAge) {
525
+ await fs.unlink(filePath);
526
+ console.log(`[Remediation] Cleaned up old backup: ${file}`);
527
+ }
528
+ }
529
+ }
530
+ catch (error) {
531
+ console.warn("[Remediation] Backup cleanup failed:", error);
532
+ }
533
+ }
534
+ }
535
+ //# sourceMappingURL=AutomatedRemediation.js.map