@mainwp/control 1.0.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 (204) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +583 -0
  3. package/bin/_exit.js +12 -0
  4. package/bin/dev.js +7 -0
  5. package/bin/run.js +7 -0
  6. package/dist/chat/chat-engine.d.ts +213 -0
  7. package/dist/chat/chat-engine.d.ts.map +1 -0
  8. package/dist/chat/chat-engine.js +636 -0
  9. package/dist/chat/chat-engine.js.map +1 -0
  10. package/dist/chat/index.d.ts +10 -0
  11. package/dist/chat/index.d.ts.map +1 -0
  12. package/dist/chat/index.js +14 -0
  13. package/dist/chat/index.js.map +1 -0
  14. package/dist/chat/providers/anthropic.d.ts +52 -0
  15. package/dist/chat/providers/anthropic.d.ts.map +1 -0
  16. package/dist/chat/providers/anthropic.js +292 -0
  17. package/dist/chat/providers/anthropic.js.map +1 -0
  18. package/dist/chat/providers/gemini.d.ts +52 -0
  19. package/dist/chat/providers/gemini.d.ts.map +1 -0
  20. package/dist/chat/providers/gemini.js +284 -0
  21. package/dist/chat/providers/gemini.js.map +1 -0
  22. package/dist/chat/providers/index.d.ts +19 -0
  23. package/dist/chat/providers/index.d.ts.map +1 -0
  24. package/dist/chat/providers/index.js +23 -0
  25. package/dist/chat/providers/index.js.map +1 -0
  26. package/dist/chat/providers/local.d.ts +37 -0
  27. package/dist/chat/providers/local.d.ts.map +1 -0
  28. package/dist/chat/providers/local.js +130 -0
  29. package/dist/chat/providers/local.js.map +1 -0
  30. package/dist/chat/providers/openai-compatible.d.ts +155 -0
  31. package/dist/chat/providers/openai-compatible.d.ts.map +1 -0
  32. package/dist/chat/providers/openai-compatible.js +264 -0
  33. package/dist/chat/providers/openai-compatible.js.map +1 -0
  34. package/dist/chat/providers/openai.d.ts +24 -0
  35. package/dist/chat/providers/openai.d.ts.map +1 -0
  36. package/dist/chat/providers/openai.js +62 -0
  37. package/dist/chat/providers/openai.js.map +1 -0
  38. package/dist/chat/providers/openrouter.d.ts +26 -0
  39. package/dist/chat/providers/openrouter.d.ts.map +1 -0
  40. package/dist/chat/providers/openrouter.js +65 -0
  41. package/dist/chat/providers/openrouter.js.map +1 -0
  42. package/dist/chat/providers/provider-fetch.d.ts +15 -0
  43. package/dist/chat/providers/provider-fetch.d.ts.map +1 -0
  44. package/dist/chat/providers/provider-fetch.js +35 -0
  45. package/dist/chat/providers/provider-fetch.js.map +1 -0
  46. package/dist/chat/providers/provider.d.ts +214 -0
  47. package/dist/chat/providers/provider.d.ts.map +1 -0
  48. package/dist/chat/providers/provider.js +166 -0
  49. package/dist/chat/providers/provider.js.map +1 -0
  50. package/dist/chat/providers/sse-reader.d.ts +21 -0
  51. package/dist/chat/providers/sse-reader.d.ts.map +1 -0
  52. package/dist/chat/providers/sse-reader.js +48 -0
  53. package/dist/chat/providers/sse-reader.js.map +1 -0
  54. package/dist/chat/system-prompt.d.ts +33 -0
  55. package/dist/chat/system-prompt.d.ts.map +1 -0
  56. package/dist/chat/system-prompt.js +166 -0
  57. package/dist/chat/system-prompt.js.map +1 -0
  58. package/dist/chat/tool-envelope.d.ts +72 -0
  59. package/dist/chat/tool-envelope.d.ts.map +1 -0
  60. package/dist/chat/tool-envelope.js +263 -0
  61. package/dist/chat/tool-envelope.js.map +1 -0
  62. package/dist/commands/abilities/info.d.ts +21 -0
  63. package/dist/commands/abilities/info.d.ts.map +1 -0
  64. package/dist/commands/abilities/info.js +80 -0
  65. package/dist/commands/abilities/info.js.map +1 -0
  66. package/dist/commands/abilities/list.d.ts +19 -0
  67. package/dist/commands/abilities/list.d.ts.map +1 -0
  68. package/dist/commands/abilities/list.js +98 -0
  69. package/dist/commands/abilities/list.js.map +1 -0
  70. package/dist/commands/abilities/run.d.ts +75 -0
  71. package/dist/commands/abilities/run.d.ts.map +1 -0
  72. package/dist/commands/abilities/run.js +468 -0
  73. package/dist/commands/abilities/run.js.map +1 -0
  74. package/dist/commands/chat.d.ts +54 -0
  75. package/dist/commands/chat.d.ts.map +1 -0
  76. package/dist/commands/chat.js +384 -0
  77. package/dist/commands/chat.js.map +1 -0
  78. package/dist/commands/config/show.d.ts +54 -0
  79. package/dist/commands/config/show.d.ts.map +1 -0
  80. package/dist/commands/config/show.js +324 -0
  81. package/dist/commands/config/show.js.map +1 -0
  82. package/dist/commands/doctor.d.ts +77 -0
  83. package/dist/commands/doctor.d.ts.map +1 -0
  84. package/dist/commands/doctor.js +412 -0
  85. package/dist/commands/doctor.js.map +1 -0
  86. package/dist/commands/jobs/watch.d.ts +50 -0
  87. package/dist/commands/jobs/watch.d.ts.map +1 -0
  88. package/dist/commands/jobs/watch.js +269 -0
  89. package/dist/commands/jobs/watch.js.map +1 -0
  90. package/dist/commands/login.d.ts +25 -0
  91. package/dist/commands/login.d.ts.map +1 -0
  92. package/dist/commands/login.js +165 -0
  93. package/dist/commands/login.js.map +1 -0
  94. package/dist/commands/profile/delete.d.ts +22 -0
  95. package/dist/commands/profile/delete.d.ts.map +1 -0
  96. package/dist/commands/profile/delete.js +57 -0
  97. package/dist/commands/profile/delete.js.map +1 -0
  98. package/dist/commands/profile/list.d.ts +19 -0
  99. package/dist/commands/profile/list.d.ts.map +1 -0
  100. package/dist/commands/profile/list.js +53 -0
  101. package/dist/commands/profile/list.js.map +1 -0
  102. package/dist/commands/profile/use.d.ts +22 -0
  103. package/dist/commands/profile/use.d.ts.map +1 -0
  104. package/dist/commands/profile/use.js +46 -0
  105. package/dist/commands/profile/use.js.map +1 -0
  106. package/dist/config/fs-utils.d.ts +14 -0
  107. package/dist/config/fs-utils.d.ts.map +1 -0
  108. package/dist/config/fs-utils.js +31 -0
  109. package/dist/config/fs-utils.js.map +1 -0
  110. package/dist/config/keychain.d.ts +53 -0
  111. package/dist/config/keychain.d.ts.map +1 -0
  112. package/dist/config/keychain.js +175 -0
  113. package/dist/config/keychain.js.map +1 -0
  114. package/dist/config/profile-store.d.ts +85 -0
  115. package/dist/config/profile-store.d.ts.map +1 -0
  116. package/dist/config/profile-store.js +228 -0
  117. package/dist/config/profile-store.js.map +1 -0
  118. package/dist/config/settings.d.ts +71 -0
  119. package/dist/config/settings.d.ts.map +1 -0
  120. package/dist/config/settings.js +151 -0
  121. package/dist/config/settings.js.map +1 -0
  122. package/dist/core/abilities-executor.d.ts +126 -0
  123. package/dist/core/abilities-executor.d.ts.map +1 -0
  124. package/dist/core/abilities-executor.js +264 -0
  125. package/dist/core/abilities-executor.js.map +1 -0
  126. package/dist/core/batch-manager.d.ts +113 -0
  127. package/dist/core/batch-manager.d.ts.map +1 -0
  128. package/dist/core/batch-manager.js +244 -0
  129. package/dist/core/batch-manager.js.map +1 -0
  130. package/dist/core/http-client.d.ts +111 -0
  131. package/dist/core/http-client.d.ts.map +1 -0
  132. package/dist/core/http-client.js +329 -0
  133. package/dist/core/http-client.js.map +1 -0
  134. package/dist/core/safety-controller.d.ts +114 -0
  135. package/dist/core/safety-controller.d.ts.map +1 -0
  136. package/dist/core/safety-controller.js +229 -0
  137. package/dist/core/safety-controller.js.map +1 -0
  138. package/dist/hooks/command-not-found.d.ts +12 -0
  139. package/dist/hooks/command-not-found.d.ts.map +1 -0
  140. package/dist/hooks/command-not-found.js +58 -0
  141. package/dist/hooks/command-not-found.js.map +1 -0
  142. package/dist/index.d.ts +7 -0
  143. package/dist/index.d.ts.map +1 -0
  144. package/dist/index.js +7 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/lib/base-command.d.ts +123 -0
  147. package/dist/lib/base-command.d.ts.map +1 -0
  148. package/dist/lib/base-command.js +285 -0
  149. package/dist/lib/base-command.js.map +1 -0
  150. package/dist/output/formatter.d.ts +48 -0
  151. package/dist/output/formatter.d.ts.map +1 -0
  152. package/dist/output/formatter.js +138 -0
  153. package/dist/output/formatter.js.map +1 -0
  154. package/dist/output/json-envelope.d.ts +43 -0
  155. package/dist/output/json-envelope.d.ts.map +1 -0
  156. package/dist/output/json-envelope.js +73 -0
  157. package/dist/output/json-envelope.js.map +1 -0
  158. package/dist/utils/audit-logger.d.ts +97 -0
  159. package/dist/utils/audit-logger.d.ts.map +1 -0
  160. package/dist/utils/audit-logger.js +169 -0
  161. package/dist/utils/audit-logger.js.map +1 -0
  162. package/dist/utils/colors.d.ts +29 -0
  163. package/dist/utils/colors.d.ts.map +1 -0
  164. package/dist/utils/colors.js +36 -0
  165. package/dist/utils/colors.js.map +1 -0
  166. package/dist/utils/errors.d.ts +107 -0
  167. package/dist/utils/errors.d.ts.map +1 -0
  168. package/dist/utils/errors.js +149 -0
  169. package/dist/utils/errors.js.map +1 -0
  170. package/dist/utils/exit-codes.d.ts +21 -0
  171. package/dist/utils/exit-codes.d.ts.map +1 -0
  172. package/dist/utils/exit-codes.js +20 -0
  173. package/dist/utils/exit-codes.js.map +1 -0
  174. package/dist/utils/format.d.ts +64 -0
  175. package/dist/utils/format.d.ts.map +1 -0
  176. package/dist/utils/format.js +69 -0
  177. package/dist/utils/format.js.map +1 -0
  178. package/dist/utils/prompt.d.ts +34 -0
  179. package/dist/utils/prompt.d.ts.map +1 -0
  180. package/dist/utils/prompt.js +132 -0
  181. package/dist/utils/prompt.js.map +1 -0
  182. package/dist/utils/retry.d.ts +59 -0
  183. package/dist/utils/retry.d.ts.map +1 -0
  184. package/dist/utils/retry.js +96 -0
  185. package/dist/utils/retry.js.map +1 -0
  186. package/dist/utils/terminal-sanitizer.d.ts +60 -0
  187. package/dist/utils/terminal-sanitizer.d.ts.map +1 -0
  188. package/dist/utils/terminal-sanitizer.js +166 -0
  189. package/dist/utils/terminal-sanitizer.js.map +1 -0
  190. package/dist/validation/input-sanitizer.d.ts +76 -0
  191. package/dist/validation/input-sanitizer.d.ts.map +1 -0
  192. package/dist/validation/input-sanitizer.js +199 -0
  193. package/dist/validation/input-sanitizer.js.map +1 -0
  194. package/dist/validation/schema-validator.d.ts +75 -0
  195. package/dist/validation/schema-validator.d.ts.map +1 -0
  196. package/dist/validation/schema-validator.js +147 -0
  197. package/dist/validation/schema-validator.js.map +1 -0
  198. package/oclif.manifest.json +857 -0
  199. package/package.json +101 -0
  200. package/scripts/completions/README.md +221 -0
  201. package/scripts/completions/mainwpcontrol.bash +193 -0
  202. package/scripts/completions/mainwpcontrol.zsh +267 -0
  203. package/scripts/completions/profile-completer.sh +35 -0
  204. package/scripts/completions/regenerate.sh +78 -0
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Terminal Output Sanitizer for mainwpcontrol
3
+ *
4
+ * Security utility to strip ANSI escape sequences and control characters
5
+ * from untrusted data before rendering to terminal output.
6
+ *
7
+ * Prevents:
8
+ * - Terminal escape sequence injection
9
+ * - Fake prompt attacks
10
+ * - Screen manipulation/overwriting
11
+ * - OSC command execution
12
+ */
13
+ /**
14
+ * Regular expressions for matching escape sequences
15
+ */
16
+ const ESCAPE_PATTERNS = {
17
+ // ANSI escape sequences: ESC [ ... (CSI sequences)
18
+ // Matches: colors, cursor movement, screen clearing, etc.
19
+ csi: /\x1b\[[0-9;]*[A-Za-z]/g,
20
+ // Operating System Command sequences: ESC ] ... ST
21
+ // Used for setting window titles, clipboard, etc.
22
+ osc: /\x1b\][\s\S]*?(?:\x07|\x1b\\)/g,
23
+ // Single-character escape sequences: ESC followed by single char
24
+ singleEsc: /\x1b[^[\]]/g,
25
+ // C1 control characters (0x80-0x9F)
26
+ c1: /[\x80-\x9f]/g,
27
+ // Device Control Strings: ESC P ... ST
28
+ dcs: /\x1bP[\s\S]*?(?:\x1b\\)/g,
29
+ // Application Program Command: ESC _ ... ST
30
+ apc: /\x1b_[\s\S]*?(?:\x1b\\)/g,
31
+ // Privacy Message: ESC ^ ... ST
32
+ pm: /\x1b\^[\s\S]*?(?:\x1b\\)/g,
33
+ // Start of String: ESC X ... ST
34
+ sos: /\x1bX[\s\S]*?(?:\x1b\\)/g,
35
+ };
36
+ /**
37
+ * C0 control characters to remove (0x00-0x1F)
38
+ * Preserves: \t (0x09), \n (0x0A), \r (0x0D)
39
+ */
40
+ const C0_UNSAFE = /[\x00-\x08\x0b\x0c\x0e-\x1f]/g;
41
+ /**
42
+ * Strip all ANSI escape sequences and control characters from a string.
43
+ *
44
+ * This is the core sanitization function that removes:
45
+ * - ANSI CSI sequences (colors, cursor movement, screen control)
46
+ * - OSC sequences (window titles, clipboard commands)
47
+ * - Other escape sequences (DCS, APC, PM, SOS)
48
+ * - C0 control characters (except tab, newline, carriage return)
49
+ * - C1 control characters
50
+ *
51
+ * @param str - The string to sanitize
52
+ * @returns The sanitized string with all escape sequences removed
53
+ */
54
+ export function stripControlChars(str) {
55
+ if (typeof str !== 'string') {
56
+ return '';
57
+ }
58
+ let result = str;
59
+ // Remove all escape sequence types
60
+ result = result.replace(ESCAPE_PATTERNS.osc, '');
61
+ result = result.replace(ESCAPE_PATTERNS.dcs, '');
62
+ result = result.replace(ESCAPE_PATTERNS.apc, '');
63
+ result = result.replace(ESCAPE_PATTERNS.pm, '');
64
+ result = result.replace(ESCAPE_PATTERNS.sos, '');
65
+ result = result.replace(ESCAPE_PATTERNS.csi, '');
66
+ result = result.replace(ESCAPE_PATTERNS.singleEsc, '');
67
+ // Remove control characters
68
+ result = result.replace(ESCAPE_PATTERNS.c1, '');
69
+ result = result.replace(C0_UNSAFE, '');
70
+ // Remove any remaining bare ESC characters
71
+ result = result.replace(/\x1b/g, '');
72
+ return result;
73
+ }
74
+ /**
75
+ * Recursively sanitize a value for safe terminal output.
76
+ *
77
+ * Handles:
78
+ * - Strings: strips control characters
79
+ * - Arrays: recursively sanitizes each element
80
+ * - Objects: recursively sanitizes each value
81
+ * - Other types: converted to string and sanitized
82
+ *
83
+ * @param value - The value to sanitize
84
+ * @returns A sanitized copy of the value (original is not modified)
85
+ */
86
+ export function sanitizeForTerminal(value) {
87
+ if (value === null || value === undefined) {
88
+ return value;
89
+ }
90
+ if (typeof value === 'string') {
91
+ return stripControlChars(value);
92
+ }
93
+ if (typeof value === 'number' || typeof value === 'boolean') {
94
+ return value;
95
+ }
96
+ if (Array.isArray(value)) {
97
+ return value.map((item) => sanitizeForTerminal(item));
98
+ }
99
+ if (typeof value === 'object') {
100
+ const sanitized = {};
101
+ for (const [key, val] of Object.entries(value)) {
102
+ // Sanitize both keys and values
103
+ const sanitizedKey = stripControlChars(key);
104
+ sanitized[sanitizedKey] = sanitizeForTerminal(val);
105
+ }
106
+ return sanitized;
107
+ }
108
+ // For other types (functions, symbols, etc.), convert to string and sanitize
109
+ return stripControlChars(String(value));
110
+ }
111
+ /**
112
+ * Sanitize a string for safe display, preserving safe content.
113
+ *
114
+ * This is a convenience wrapper that handles non-string inputs
115
+ * by converting them to JSON first.
116
+ *
117
+ * @param value - The value to sanitize for display
118
+ * @returns A safe string suitable for terminal output
119
+ */
120
+ export function safeString(value) {
121
+ if (value === null) {
122
+ return 'null';
123
+ }
124
+ if (value === undefined) {
125
+ return 'undefined';
126
+ }
127
+ if (typeof value === 'string') {
128
+ return stripControlChars(value);
129
+ }
130
+ if (typeof value === 'number' || typeof value === 'boolean') {
131
+ return String(value);
132
+ }
133
+ // For objects and arrays, sanitize then stringify
134
+ const sanitized = sanitizeForTerminal(value);
135
+ return JSON.stringify(sanitized);
136
+ }
137
+ /**
138
+ * Check if a string contains potentially dangerous escape sequences.
139
+ *
140
+ * Useful for logging or debugging when you want to detect
141
+ * but not necessarily remove escape sequences.
142
+ *
143
+ * @param str - The string to check
144
+ * @returns True if the string contains escape sequences
145
+ */
146
+ export function containsEscapeSequences(str) {
147
+ if (typeof str !== 'string') {
148
+ return false;
149
+ }
150
+ // Reset lastIndex on global regexes before test() to avoid
151
+ // alternating true/false results from stateful .test() calls
152
+ ESCAPE_PATTERNS.csi.lastIndex = 0;
153
+ ESCAPE_PATTERNS.osc.lastIndex = 0;
154
+ ESCAPE_PATTERNS.singleEsc.lastIndex = 0;
155
+ ESCAPE_PATTERNS.c1.lastIndex = 0;
156
+ ESCAPE_PATTERNS.dcs.lastIndex = 0;
157
+ C0_UNSAFE.lastIndex = 0;
158
+ return (ESCAPE_PATTERNS.csi.test(str) ||
159
+ ESCAPE_PATTERNS.osc.test(str) ||
160
+ ESCAPE_PATTERNS.singleEsc.test(str) ||
161
+ ESCAPE_PATTERNS.c1.test(str) ||
162
+ ESCAPE_PATTERNS.dcs.test(str) ||
163
+ C0_UNSAFE.test(str) ||
164
+ str.includes('\x1b'));
165
+ }
166
+ //# sourceMappingURL=terminal-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-sanitizer.js","sourceRoot":"","sources":["../../src/utils/terminal-sanitizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Input Sanitizer for mainwpcontrol
3
+ *
4
+ * Security sanitization for inputs:
5
+ * - Input limits (string length, array elements, object depth)
6
+ * - Error sanitization (path redaction, credential stripping)
7
+ */
8
+ /**
9
+ * Default limits for input sanitization
10
+ */
11
+ export declare const DEFAULT_LIMITS: {
12
+ /** Maximum string length */
13
+ readonly maxStringLength: 65536;
14
+ /** Maximum array elements */
15
+ readonly maxArrayElements: 1000;
16
+ /** Maximum object depth */
17
+ readonly maxObjectDepth: 10;
18
+ /** Maximum object keys */
19
+ readonly maxObjectKeys: 100;
20
+ /** Maximum total input size (approximate) */
21
+ readonly maxInputSize: 1048576;
22
+ };
23
+ /**
24
+ * Sanitization options
25
+ */
26
+ export interface SanitizeOptions {
27
+ maxStringLength?: number;
28
+ maxArrayElements?: number;
29
+ maxObjectDepth?: number;
30
+ maxObjectKeys?: number;
31
+ maxInputSize?: number;
32
+ }
33
+ /**
34
+ * Input Sanitizer class
35
+ */
36
+ export declare class InputSanitizer {
37
+ private readonly limits;
38
+ constructor(options?: SanitizeOptions);
39
+ /**
40
+ * Sanitize and validate input
41
+ *
42
+ * @param input - Input data to sanitize
43
+ * @throws InputError if input exceeds limits
44
+ * @returns Sanitized input (same object if valid)
45
+ */
46
+ sanitize(input: Record<string, unknown>): Record<string, unknown>;
47
+ /**
48
+ * Recursively validate a value
49
+ */
50
+ private validateValue;
51
+ /**
52
+ * Check if a key name appears to contain sensitive data
53
+ */
54
+ isSensitiveKey(key: string): boolean;
55
+ /**
56
+ * Redact sensitive values in an object (for logging/errors)
57
+ */
58
+ redactSensitive(data: Record<string, unknown>): Record<string, unknown>;
59
+ /**
60
+ * Recursively redact sensitive values
61
+ */
62
+ private redactValue;
63
+ /**
64
+ * Sanitize error message to remove sensitive paths and data
65
+ */
66
+ sanitizeErrorMessage(message: string): string;
67
+ /**
68
+ * Sanitize an error object for safe logging
69
+ */
70
+ sanitizeError(error: Error): Error;
71
+ }
72
+ /**
73
+ * Get the input sanitizer singleton
74
+ */
75
+ export declare function getInputSanitizer(): InputSanitizer;
76
+ //# sourceMappingURL=input-sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-sanitizer.d.ts","sourceRoot":"","sources":["../../src/validation/input-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,eAAO,MAAM,cAAc;IACzB,4BAA4B;;IAE5B,6BAA6B;;IAE7B,2BAA2B;;IAE3B,0BAA0B;;IAE1B,6CAA6C;;CAErC,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8BD;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;gBAEvC,OAAO,CAAC,EAAE,eAAe;IAUrC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAiBjE;;OAEG;IACH,OAAO,CAAC,aAAa;IAsDrB;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIpC;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIvE;;OAEG;IACH,OAAO,CAAC,WAAW;IAwBnB;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IA6B7C;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK;CAenC;AAOD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Input Sanitizer for mainwpcontrol
3
+ *
4
+ * Security sanitization for inputs:
5
+ * - Input limits (string length, array elements, object depth)
6
+ * - Error sanitization (path redaction, credential stripping)
7
+ */
8
+ import { InputError } from '../utils/errors.js';
9
+ /**
10
+ * Default limits for input sanitization
11
+ */
12
+ export const DEFAULT_LIMITS = {
13
+ /** Maximum string length */
14
+ maxStringLength: 65536, // 64KB
15
+ /** Maximum array elements */
16
+ maxArrayElements: 1000,
17
+ /** Maximum object depth */
18
+ maxObjectDepth: 10,
19
+ /** Maximum object keys */
20
+ maxObjectKeys: 100,
21
+ /** Maximum total input size (approximate) */
22
+ maxInputSize: 1048576, // 1MB
23
+ };
24
+ /**
25
+ * Patterns that indicate sensitive data
26
+ */
27
+ const SENSITIVE_PATTERNS = [
28
+ /password/i,
29
+ /secret/i,
30
+ /token/i,
31
+ /api[_-]?key/i,
32
+ /auth/i,
33
+ /credential/i,
34
+ /private[_-]?key/i,
35
+ /bearer/i,
36
+ /signing[_-]?key/i,
37
+ /encryption[_-]?key/i,
38
+ ];
39
+ /**
40
+ * Patterns for redacting file paths
41
+ */
42
+ const PATH_PATTERNS = [
43
+ // Absolute paths
44
+ /\/Users\/[^/\s]+/g,
45
+ /\/home\/[^/\s]+/g,
46
+ /C:\\Users\\[^\\]+/gi,
47
+ // Config directories
48
+ /\.config\/mainwpcontrol/g,
49
+ ];
50
+ /**
51
+ * Input Sanitizer class
52
+ */
53
+ export class InputSanitizer {
54
+ limits;
55
+ constructor(options) {
56
+ this.limits = {
57
+ maxStringLength: options?.maxStringLength ?? DEFAULT_LIMITS.maxStringLength,
58
+ maxArrayElements: options?.maxArrayElements ?? DEFAULT_LIMITS.maxArrayElements,
59
+ maxObjectDepth: options?.maxObjectDepth ?? DEFAULT_LIMITS.maxObjectDepth,
60
+ maxObjectKeys: options?.maxObjectKeys ?? DEFAULT_LIMITS.maxObjectKeys,
61
+ maxInputSize: options?.maxInputSize ?? DEFAULT_LIMITS.maxInputSize,
62
+ };
63
+ }
64
+ /**
65
+ * Sanitize and validate input
66
+ *
67
+ * @param input - Input data to sanitize
68
+ * @throws InputError if input exceeds limits
69
+ * @returns Sanitized input (same object if valid)
70
+ */
71
+ sanitize(input) {
72
+ // Check total size
73
+ const serialized = JSON.stringify(input);
74
+ if (serialized.length > this.limits.maxInputSize) {
75
+ throw new InputError(`Input size exceeds limit: ${serialized.length} bytes (max: ${this.limits.maxInputSize})`, { size: serialized.length, limit: this.limits.maxInputSize }, 'Reduce the size of your input or split into multiple requests');
76
+ }
77
+ // Validate structure
78
+ this.validateValue(input, 0, 'input');
79
+ return input;
80
+ }
81
+ /**
82
+ * Recursively validate a value
83
+ */
84
+ validateValue(value, depth, path) {
85
+ // Check depth
86
+ if (depth > this.limits.maxObjectDepth) {
87
+ throw new InputError(`Input exceeds maximum depth at "${path}"`, { path, depth, limit: this.limits.maxObjectDepth }, 'Simplify your input structure or reduce nesting depth');
88
+ }
89
+ if (value === null || value === undefined) {
90
+ return;
91
+ }
92
+ if (typeof value === 'string') {
93
+ if (value.length > this.limits.maxStringLength) {
94
+ throw new InputError(`String exceeds maximum length at "${path}"`, { path, length: value.length, limit: this.limits.maxStringLength }, 'Use shorter strings or split into multiple requests');
95
+ }
96
+ return;
97
+ }
98
+ if (Array.isArray(value)) {
99
+ if (value.length > this.limits.maxArrayElements) {
100
+ throw new InputError(`Array exceeds maximum elements at "${path}"`, { path, length: value.length, limit: this.limits.maxArrayElements }, 'Reduce the number of array elements or split into multiple requests');
101
+ }
102
+ value.forEach((item, index) => {
103
+ this.validateValue(item, depth + 1, `${path}[${index}]`);
104
+ });
105
+ return;
106
+ }
107
+ if (typeof value === 'object') {
108
+ const keys = Object.keys(value);
109
+ if (keys.length > this.limits.maxObjectKeys) {
110
+ throw new InputError(`Object exceeds maximum keys at "${path}"`, { path, count: keys.length, limit: this.limits.maxObjectKeys }, 'Reduce the number of object properties or split into multiple requests');
111
+ }
112
+ for (const key of keys) {
113
+ this.validateValue(value[key], depth + 1, `${path}.${key}`);
114
+ }
115
+ }
116
+ }
117
+ /**
118
+ * Check if a key name appears to contain sensitive data
119
+ */
120
+ isSensitiveKey(key) {
121
+ return SENSITIVE_PATTERNS.some((pattern) => pattern.test(key));
122
+ }
123
+ /**
124
+ * Redact sensitive values in an object (for logging/errors)
125
+ */
126
+ redactSensitive(data) {
127
+ return this.redactValue(data);
128
+ }
129
+ /**
130
+ * Recursively redact sensitive values
131
+ */
132
+ redactValue(value) {
133
+ if (value === null || value === undefined) {
134
+ return value;
135
+ }
136
+ if (Array.isArray(value)) {
137
+ return value.map((item) => this.redactValue(item));
138
+ }
139
+ if (typeof value === 'object') {
140
+ const result = {};
141
+ for (const [key, val] of Object.entries(value)) {
142
+ if (this.isSensitiveKey(key)) {
143
+ result[key] = '[REDACTED]';
144
+ }
145
+ else {
146
+ result[key] = this.redactValue(val);
147
+ }
148
+ }
149
+ return result;
150
+ }
151
+ return value;
152
+ }
153
+ /**
154
+ * Sanitize error message to remove sensitive paths and data
155
+ */
156
+ sanitizeErrorMessage(message) {
157
+ let sanitized = message;
158
+ // Redact file paths
159
+ for (const pattern of PATH_PATTERNS) {
160
+ sanitized = sanitized.replace(pattern, '[PATH]');
161
+ }
162
+ // Redact URLs with credentials
163
+ sanitized = sanitized.replace(/https?:\/\/[^:]+:[^@]+@[^\s]+/g, '[URL_WITH_CREDENTIALS]');
164
+ // Redact base64 that might be auth headers
165
+ sanitized = sanitized.replace(/Basic\s+[A-Za-z0-9+/]+=*/gi, 'Basic [REDACTED]');
166
+ // Redact bearer tokens
167
+ sanitized = sanitized.replace(/Bearer\s+[A-Za-z0-9._-]+/gi, 'Bearer [REDACTED]');
168
+ return sanitized;
169
+ }
170
+ /**
171
+ * Sanitize an error object for safe logging
172
+ */
173
+ sanitizeError(error) {
174
+ const sanitizedMessage = this.sanitizeErrorMessage(error.message);
175
+ if (sanitizedMessage === error.message) {
176
+ return error;
177
+ }
178
+ const sanitizedError = new Error(sanitizedMessage);
179
+ sanitizedError.name = error.name;
180
+ if (error.stack) {
181
+ sanitizedError.stack = this.sanitizeErrorMessage(error.stack);
182
+ }
183
+ return sanitizedError;
184
+ }
185
+ }
186
+ /**
187
+ * Singleton instance
188
+ */
189
+ let instance = null;
190
+ /**
191
+ * Get the input sanitizer singleton
192
+ */
193
+ export function getInputSanitizer() {
194
+ if (!instance) {
195
+ instance = new InputSanitizer();
196
+ }
197
+ return instance;
198
+ }
199
+ //# sourceMappingURL=input-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-sanitizer.js","sourceRoot":"","sources":["../../src/validation/input-sanitizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Schema Validator for mainwpcontrol
3
+ *
4
+ * AJV-based input validation against ability JSON schemas.
5
+ * Caches compiled schemas for performance.
6
+ */
7
+ /**
8
+ * Validation result
9
+ */
10
+ export interface ValidationResult {
11
+ valid: boolean;
12
+ errors?: ValidationError[];
13
+ /** Coerced copy of input after AJV applies type coercion and defaults */
14
+ coerced?: Record<string, unknown>;
15
+ }
16
+ /**
17
+ * Structured validation error
18
+ */
19
+ export interface ValidationError {
20
+ path: string;
21
+ message: string;
22
+ keyword: string;
23
+ params: Record<string, unknown>;
24
+ }
25
+ /**
26
+ * Schema Validator class
27
+ */
28
+ export declare class SchemaValidator {
29
+ private readonly ajv;
30
+ private readonly schemaCache;
31
+ constructor();
32
+ /**
33
+ * Validate input against a JSON schema
34
+ *
35
+ * @param input - The input data to validate
36
+ * @param schema - The JSON schema to validate against
37
+ * @param schemaId - Optional ID for caching compiled schema
38
+ * @returns Validation result with any errors
39
+ */
40
+ validate(input: Record<string, unknown>, schema: Record<string, unknown>, schemaId?: string): ValidationResult;
41
+ /**
42
+ * Validate input and throw if invalid
43
+ *
44
+ * @param input - The input data to validate
45
+ * @param schema - The JSON schema to validate against
46
+ * @param abilityName - Name of the ability (for error message)
47
+ * @throws SchemaValidationError if validation fails
48
+ */
49
+ validateOrThrow(input: Record<string, unknown>, schema: Record<string, unknown>, abilityName: string): ValidationResult;
50
+ /**
51
+ * Check if input would be valid (without detailed errors)
52
+ */
53
+ isValid(input: Record<string, unknown>, schema: Record<string, unknown>, schemaId?: string): boolean;
54
+ /**
55
+ * Get or compile schema
56
+ */
57
+ private getCompiledSchema;
58
+ /**
59
+ * Format AJV errors into structured errors
60
+ */
61
+ private formatErrors;
62
+ /**
63
+ * Format a single error into a human-readable message
64
+ */
65
+ private formatErrorMessage;
66
+ /**
67
+ * Clear the schema cache
68
+ */
69
+ clearCache(): void;
70
+ }
71
+ /**
72
+ * Get the schema validator singleton
73
+ */
74
+ export declare function getSchemaValidator(): SchemaValidator;
75
+ //# sourceMappingURL=schema-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-validator.d.ts","sourceRoot":"","sources":["../../src/validation/schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAKD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4C;;IAYxE;;;;;;;OAOG;IACH,QAAQ,CACN,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB;IAcnB;;;;;;;OAOG;IACH,eAAe,CACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,WAAW,EAAE,MAAM,GAClB,gBAAgB;IAenB;;OAEG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO;IAKV;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqC1B;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB;AAOD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD"}