mcp-wordpress 2.4.2 → 2.5.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 (348) hide show
  1. package/README.md +114 -48
  2. package/dist/ajv-patch.js +34 -0
  3. package/dist/cache/CacheInvalidation.d.ts +3 -1
  4. package/dist/cache/CacheInvalidation.d.ts.map +1 -1
  5. package/dist/cache/CacheInvalidation.js +10 -4
  6. package/dist/cache/CacheInvalidation.js.map +1 -1
  7. package/dist/cache/CacheManager.d.ts +3 -2
  8. package/dist/cache/CacheManager.d.ts.map +1 -1
  9. package/dist/cache/CacheManager.js +11 -3
  10. package/dist/cache/CacheManager.js.map +1 -1
  11. package/dist/cache/HttpCacheWrapper.d.ts +7 -6
  12. package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
  13. package/dist/cache/HttpCacheWrapper.js +8 -5
  14. package/dist/cache/HttpCacheWrapper.js.map +1 -1
  15. package/dist/cache/__tests__/HttpCacheWrapper.test.js +6 -5
  16. package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -1
  17. package/dist/cache/index.d.ts +3 -3
  18. package/dist/cache/index.d.ts.map +1 -1
  19. package/dist/cache/index.js +1 -1
  20. package/dist/cache/index.js.map +1 -1
  21. package/dist/client/CachedWordPressClient.d.ts +23 -9
  22. package/dist/client/CachedWordPressClient.d.ts.map +1 -1
  23. package/dist/client/CachedWordPressClient.js +4 -1
  24. package/dist/client/CachedWordPressClient.js.map +1 -1
  25. package/dist/client/MockWordPressClient.d.ts +2 -1
  26. package/dist/client/MockWordPressClient.d.ts.map +1 -1
  27. package/dist/client/MockWordPressClient.js +3 -1
  28. package/dist/client/MockWordPressClient.js.map +1 -1
  29. package/dist/client/api.d.ts +17 -13
  30. package/dist/client/api.d.ts.map +1 -1
  31. package/dist/client/api.js +135 -30
  32. package/dist/client/api.js.map +1 -1
  33. package/dist/client/auth.d.ts.map +1 -1
  34. package/dist/client/auth.js +2 -3
  35. package/dist/client/auth.js.map +1 -1
  36. package/dist/client/managers/AuthenticationManager.d.ts +55 -2
  37. package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
  38. package/dist/client/managers/AuthenticationManager.js +269 -71
  39. package/dist/client/managers/AuthenticationManager.js.map +1 -1
  40. package/dist/client/managers/BaseManager.d.ts +3 -3
  41. package/dist/client/managers/BaseManager.d.ts.map +1 -1
  42. package/dist/client/managers/BaseManager.js +11 -5
  43. package/dist/client/managers/BaseManager.js.map +1 -1
  44. package/dist/client/managers/RequestManager.d.ts +2 -2
  45. package/dist/client/managers/RequestManager.d.ts.map +1 -1
  46. package/dist/client/managers/RequestManager.js +25 -12
  47. package/dist/client/managers/RequestManager.js.map +1 -1
  48. package/dist/config/Config.d.ts +155 -0
  49. package/dist/config/Config.d.ts.map +1 -0
  50. package/dist/config/Config.js +215 -0
  51. package/dist/config/Config.js.map +1 -0
  52. package/dist/config/ConfigurationSchema.d.ts +21 -21
  53. package/dist/config/ConfigurationSchema.d.ts.map +1 -1
  54. package/dist/config/ConfigurationSchema.js +19 -2
  55. package/dist/config/ConfigurationSchema.js.map +1 -1
  56. package/dist/config/ServerConfiguration.d.ts +2 -1
  57. package/dist/config/ServerConfiguration.d.ts.map +1 -1
  58. package/dist/config/ServerConfiguration.js +50 -41
  59. package/dist/config/ServerConfiguration.js.map +1 -1
  60. package/dist/docs/DocumentationGenerator.d.ts +9 -8
  61. package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
  62. package/dist/docs/DocumentationGenerator.js +10 -7
  63. package/dist/docs/DocumentationGenerator.js.map +1 -1
  64. package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
  65. package/dist/docs/MarkdownFormatter.js +3 -2
  66. package/dist/docs/MarkdownFormatter.js.map +1 -1
  67. package/dist/dxt-entry.cjs +81 -0
  68. package/dist/dxt-entry.js +15 -14
  69. package/dist/dxt-entry.js.map +1 -1
  70. package/dist/index.d.ts +3 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +37 -21
  73. package/dist/index.js.map +1 -1
  74. package/dist/performance/MetricsCollector.d.ts +13 -7
  75. package/dist/performance/MetricsCollector.d.ts.map +1 -1
  76. package/dist/performance/MetricsCollector.js +69 -27
  77. package/dist/performance/MetricsCollector.js.map +1 -1
  78. package/dist/performance/PerformanceAnalytics.d.ts +8 -2
  79. package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
  80. package/dist/performance/PerformanceAnalytics.js +17 -47
  81. package/dist/performance/PerformanceAnalytics.js.map +1 -1
  82. package/dist/performance/PerformanceMonitor.d.ts +2 -1
  83. package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
  84. package/dist/performance/PerformanceMonitor.js +12 -13
  85. package/dist/performance/PerformanceMonitor.js.map +1 -1
  86. package/dist/performance/index.d.ts +2 -2
  87. package/dist/performance/index.d.ts.map +1 -1
  88. package/dist/security/AISecurityScanner.d.ts +1 -0
  89. package/dist/security/AISecurityScanner.d.ts.map +1 -1
  90. package/dist/security/AISecurityScanner.js +22 -12
  91. package/dist/security/AISecurityScanner.js.map +1 -1
  92. package/dist/security/AutomatedRemediation.d.ts +4 -3
  93. package/dist/security/AutomatedRemediation.d.ts.map +1 -1
  94. package/dist/security/AutomatedRemediation.js +46 -15
  95. package/dist/security/AutomatedRemediation.js.map +1 -1
  96. package/dist/security/InputValidator.d.ts +13 -9
  97. package/dist/security/InputValidator.d.ts.map +1 -1
  98. package/dist/security/InputValidator.js +4 -2
  99. package/dist/security/InputValidator.js.map +1 -1
  100. package/dist/security/SecurityCIPipeline.d.ts +1 -1
  101. package/dist/security/SecurityCIPipeline.d.ts.map +1 -1
  102. package/dist/security/SecurityCIPipeline.js +38 -29
  103. package/dist/security/SecurityCIPipeline.js.map +1 -1
  104. package/dist/security/SecurityConfig.d.ts +3 -3
  105. package/dist/security/SecurityConfig.d.ts.map +1 -1
  106. package/dist/security/SecurityConfig.js +13 -9
  107. package/dist/security/SecurityConfig.js.map +1 -1
  108. package/dist/security/SecurityConfigManager.d.ts +2 -2
  109. package/dist/security/SecurityConfigManager.d.ts.map +1 -1
  110. package/dist/security/SecurityConfigManager.js +20 -15
  111. package/dist/security/SecurityConfigManager.js.map +1 -1
  112. package/dist/security/SecurityMonitoring.d.ts +2 -2
  113. package/dist/security/SecurityMonitoring.d.ts.map +1 -1
  114. package/dist/security/SecurityMonitoring.js +19 -17
  115. package/dist/security/SecurityMonitoring.js.map +1 -1
  116. package/dist/security/SecurityReviewer.d.ts.map +1 -1
  117. package/dist/security/SecurityReviewer.js +10 -7
  118. package/dist/security/SecurityReviewer.js.map +1 -1
  119. package/dist/security/index.d.ts +24 -23
  120. package/dist/security/index.d.ts.map +1 -1
  121. package/dist/security/index.js +52 -23
  122. package/dist/security/index.js.map +1 -1
  123. package/dist/server/ConnectionTester.d.ts +12 -4
  124. package/dist/server/ConnectionTester.d.ts.map +1 -1
  125. package/dist/server/ConnectionTester.js +96 -22
  126. package/dist/server/ConnectionTester.js.map +1 -1
  127. package/dist/server/ToolRegistry.d.ts +2 -2
  128. package/dist/server/ToolRegistry.d.ts.map +1 -1
  129. package/dist/server/ToolRegistry.js +10 -5
  130. package/dist/server/ToolRegistry.js.map +1 -1
  131. package/dist/tools/BaseToolManager.d.ts +47 -11
  132. package/dist/tools/BaseToolManager.d.ts.map +1 -1
  133. package/dist/tools/BaseToolManager.js +168 -29
  134. package/dist/tools/BaseToolManager.js.map +1 -1
  135. package/dist/tools/auth.d.ts +16 -10
  136. package/dist/tools/auth.d.ts.map +1 -1
  137. package/dist/tools/auth.js +3 -2
  138. package/dist/tools/auth.js.map +1 -1
  139. package/dist/tools/cache.d.ts +30 -30
  140. package/dist/tools/cache.d.ts.map +1 -1
  141. package/dist/tools/cache.js +1 -6
  142. package/dist/tools/cache.js.map +1 -1
  143. package/dist/tools/comments.d.ts +20 -20
  144. package/dist/tools/comments.d.ts.map +1 -1
  145. package/dist/tools/comments.js +16 -9
  146. package/dist/tools/comments.js.map +1 -1
  147. package/dist/tools/media.d.ts +18 -16
  148. package/dist/tools/media.d.ts.map +1 -1
  149. package/dist/tools/media.js +16 -15
  150. package/dist/tools/media.js.map +1 -1
  151. package/dist/tools/pages.d.ts +19 -17
  152. package/dist/tools/pages.d.ts.map +1 -1
  153. package/dist/tools/pages.js +16 -12
  154. package/dist/tools/pages.js.map +1 -1
  155. package/dist/tools/performance.d.ts +11 -1
  156. package/dist/tools/performance.d.ts.map +1 -1
  157. package/dist/tools/performance.js +67 -34
  158. package/dist/tools/performance.js.map +1 -1
  159. package/dist/tools/posts/PostHandlers.d.ts +46 -0
  160. package/dist/tools/posts/PostHandlers.d.ts.map +1 -0
  161. package/dist/tools/posts/PostHandlers.js +400 -0
  162. package/dist/tools/posts/PostHandlers.js.map +1 -0
  163. package/dist/tools/posts/PostToolDefinitions.d.ts +37 -0
  164. package/dist/tools/posts/PostToolDefinitions.d.ts.map +1 -0
  165. package/dist/tools/posts/PostToolDefinitions.js +236 -0
  166. package/dist/tools/posts/PostToolDefinitions.js.map +1 -0
  167. package/dist/tools/posts/index.d.ts +138 -0
  168. package/dist/tools/posts/index.d.ts.map +1 -0
  169. package/dist/tools/posts/index.js +163 -0
  170. package/dist/tools/posts/index.js.map +1 -0
  171. package/dist/tools/posts.d.ts +10 -246
  172. package/dist/tools/posts.d.ts.map +1 -1
  173. package/dist/tools/posts.js +11 -723
  174. package/dist/tools/posts.js.map +1 -1
  175. package/dist/tools/site.d.ts +19 -18
  176. package/dist/tools/site.d.ts.map +1 -1
  177. package/dist/tools/site.js +14 -10
  178. package/dist/tools/site.js.map +1 -1
  179. package/dist/tools/taxonomies.d.ts +23 -24
  180. package/dist/tools/taxonomies.d.ts.map +1 -1
  181. package/dist/tools/taxonomies.js +24 -18
  182. package/dist/tools/taxonomies.js.map +1 -1
  183. package/dist/tools/users.d.ts +20 -15
  184. package/dist/tools/users.d.ts.map +1 -1
  185. package/dist/tools/users.js +12 -8
  186. package/dist/tools/users.js.map +1 -1
  187. package/dist/types/client.d.ts +48 -41
  188. package/dist/types/client.d.ts.map +1 -1
  189. package/dist/types/client.js +30 -5
  190. package/dist/types/client.js.map +1 -1
  191. package/dist/types/enhanced.d.ts +237 -0
  192. package/dist/types/enhanced.d.ts.map +1 -0
  193. package/dist/types/enhanced.js +49 -0
  194. package/dist/types/enhanced.js.map +1 -0
  195. package/dist/types/index.d.ts +15 -12
  196. package/dist/types/index.d.ts.map +1 -1
  197. package/dist/types/index.js +2 -0
  198. package/dist/types/index.js.map +1 -1
  199. package/dist/types/mcp.d.ts +12 -12
  200. package/dist/types/mcp.d.ts.map +1 -1
  201. package/dist/types/requests.d.ts +322 -0
  202. package/dist/types/requests.d.ts.map +1 -0
  203. package/dist/types/requests.js +8 -0
  204. package/dist/types/requests.js.map +1 -0
  205. package/dist/types/tools.d.ts +506 -0
  206. package/dist/types/tools.d.ts.map +1 -0
  207. package/dist/types/tools.js +8 -0
  208. package/dist/types/tools.js.map +1 -0
  209. package/dist/types/wordpress.d.ts +43 -15
  210. package/dist/types/wordpress.d.ts.map +1 -1
  211. package/dist/types/wordpress.js +8 -1
  212. package/dist/types/wordpress.js.map +1 -1
  213. package/dist/utils/debug.d.ts +19 -11
  214. package/dist/utils/debug.d.ts.map +1 -1
  215. package/dist/utils/debug.js +46 -10
  216. package/dist/utils/debug.js.map +1 -1
  217. package/dist/utils/enhancedError.d.ts +8 -8
  218. package/dist/utils/enhancedError.d.ts.map +1 -1
  219. package/dist/utils/enhancedError.js.map +1 -1
  220. package/dist/utils/error.d.ts +2 -4
  221. package/dist/utils/error.d.ts.map +1 -1
  222. package/dist/utils/error.js +42 -5
  223. package/dist/utils/error.js.map +1 -1
  224. package/dist/utils/logger.d.ts +106 -0
  225. package/dist/utils/logger.d.ts.map +1 -0
  226. package/dist/utils/logger.js +280 -0
  227. package/dist/utils/logger.js.map +1 -0
  228. package/dist/utils/streaming.d.ts +9 -9
  229. package/dist/utils/streaming.d.ts.map +1 -1
  230. package/dist/utils/streaming.js +71 -52
  231. package/dist/utils/streaming.js.map +1 -1
  232. package/dist/utils/toolWrapper.d.ts +9 -7
  233. package/dist/utils/toolWrapper.d.ts.map +1 -1
  234. package/dist/utils/toolWrapper.js.map +1 -1
  235. package/dist/utils/validation/core.d.ts +21 -0
  236. package/dist/utils/validation/core.d.ts.map +1 -0
  237. package/dist/utils/validation/core.js +71 -0
  238. package/dist/utils/validation/core.js.map +1 -0
  239. package/dist/utils/validation/index.d.ts +25 -0
  240. package/dist/utils/validation/index.d.ts.map +1 -0
  241. package/dist/utils/validation/index.js +29 -0
  242. package/dist/utils/validation/index.js.map +1 -0
  243. package/dist/utils/validation/network.d.ts +19 -0
  244. package/dist/utils/validation/network.d.ts.map +1 -0
  245. package/dist/utils/validation/network.js +93 -0
  246. package/dist/utils/validation/network.js.map +1 -0
  247. package/dist/utils/validation/rateLimit.d.ts +21 -0
  248. package/dist/utils/validation/rateLimit.d.ts.map +1 -0
  249. package/dist/utils/validation/rateLimit.js +43 -0
  250. package/dist/utils/validation/rateLimit.js.map +1 -0
  251. package/dist/utils/validation/security.d.ts +29 -0
  252. package/dist/utils/validation/security.d.ts.map +1 -0
  253. package/dist/utils/validation/security.js +327 -0
  254. package/dist/utils/validation/security.js.map +1 -0
  255. package/dist/utils/validation/wordpress.d.ts +31 -0
  256. package/dist/utils/validation/wordpress.d.ts.map +1 -0
  257. package/dist/utils/validation/wordpress.js +146 -0
  258. package/dist/utils/validation/wordpress.js.map +1 -0
  259. package/dist/utils/validation.d.ts +13 -82
  260. package/dist/utils/validation.d.ts.map +1 -1
  261. package/dist/utils/validation.js +25 -343
  262. package/dist/utils/validation.js.map +1 -1
  263. package/docs/BADGE_UPDATES.md +132 -0
  264. package/docs/CI_CD_IMPROVEMENTS.md +191 -0
  265. package/docs/INCREMENTAL_COVERAGE.md +183 -0
  266. package/docs/api/README.md +3 -1
  267. package/docs/api/openapi.json +5 -1
  268. package/docs/api/summary.json +1 -1
  269. package/docs/api/tools/wp_create_post.md +12 -14
  270. package/docs/examples/claude-desktop-config.md +1 -1
  271. package/docs/examples/docker-production.md +100 -93
  272. package/docs/examples/multi-site-setup.md +5 -4
  273. package/docs/examples/single-site-setup.md +3 -4
  274. package/docs/examples/use-case-workflows.md +4 -5
  275. package/docs/integrations/claude-desktop.md +31 -31
  276. package/docs/integrations/cline.md +4 -4
  277. package/docs/integrations/vs-code.md +9 -8
  278. package/docs/user-guides/SMITHERY_SETUP.md +10 -10
  279. package/package.json +44 -25
  280. package/src/cache/CacheInvalidation.ts +12 -5
  281. package/src/cache/CacheManager.ts +18 -15
  282. package/src/cache/HttpCacheWrapper.ts +30 -59
  283. package/src/cache/__tests__/HttpCacheWrapper.test.ts +6 -5
  284. package/src/cache/index.ts +3 -14
  285. package/src/client/CachedWordPressClient.ts +32 -30
  286. package/src/client/MockWordPressClient.ts +4 -2
  287. package/src/client/api.ts +186 -64
  288. package/src/client/auth.ts +15 -40
  289. package/src/client/managers/AuthenticationManager.ts +337 -77
  290. package/src/client/managers/BaseManager.ts +18 -30
  291. package/src/client/managers/RequestManager.ts +39 -44
  292. package/src/config/Config.ts +308 -0
  293. package/src/config/ConfigurationSchema.ts +23 -2
  294. package/src/config/ServerConfiguration.ts +51 -47
  295. package/src/docs/DocumentationGenerator.ts +50 -39
  296. package/src/docs/MarkdownFormatter.ts +19 -29
  297. package/src/dxt-entry.cjs +26 -16
  298. package/src/dxt-entry.ts +17 -27
  299. package/src/index.ts +42 -28
  300. package/src/performance/MetricsCollector.ts +108 -86
  301. package/src/performance/PerformanceAnalytics.ts +69 -164
  302. package/src/performance/PerformanceMonitor.ts +32 -47
  303. package/src/performance/index.ts +2 -10
  304. package/src/security/AISecurityScanner.ts +22 -12
  305. package/src/security/AutomatedRemediation.ts +49 -18
  306. package/src/security/InputValidator.ts +9 -6
  307. package/src/security/SecurityCIPipeline.ts +53 -37
  308. package/src/security/SecurityConfig.ts +22 -22
  309. package/src/security/SecurityConfigManager.ts +23 -19
  310. package/src/security/SecurityMonitoring.ts +24 -21
  311. package/src/security/SecurityReviewer.ts +10 -7
  312. package/src/security/index.ts +64 -29
  313. package/src/server/ConnectionTester.ts +120 -31
  314. package/src/server/ToolRegistry.ts +31 -21
  315. package/src/tools/BaseToolManager.ts +286 -33
  316. package/src/tools/auth.ts +20 -8
  317. package/src/tools/cache.ts +5 -15
  318. package/src/tools/comments.ts +34 -48
  319. package/src/tools/media.ts +41 -53
  320. package/src/tools/pages.ts +32 -54
  321. package/src/tools/performance.ts +141 -176
  322. package/src/tools/posts/PostHandlers.ts +474 -0
  323. package/src/tools/posts/PostToolDefinitions.ts +250 -0
  324. package/src/tools/posts/index.ts +192 -0
  325. package/src/tools/posts.ts +24 -780
  326. package/src/tools/site.ts +34 -19
  327. package/src/tools/taxonomies.ts +41 -57
  328. package/src/tools/users.ts +28 -16
  329. package/src/types/client.ts +114 -138
  330. package/src/types/enhanced.ts +318 -0
  331. package/src/types/index.ts +51 -30
  332. package/src/types/mcp.ts +20 -42
  333. package/src/types/requests.ts +378 -0
  334. package/src/types/tools.ts +608 -0
  335. package/src/types/wordpress.ts +56 -34
  336. package/src/utils/debug.ts +77 -59
  337. package/src/utils/enhancedError.ts +8 -8
  338. package/src/utils/error.ts +53 -31
  339. package/src/utils/logger.ts +351 -0
  340. package/src/utils/streaming.ts +86 -68
  341. package/src/utils/toolWrapper.ts +10 -12
  342. package/src/utils/validation/core.ts +108 -0
  343. package/src/utils/validation/index.ts +36 -0
  344. package/src/utils/validation/network.ts +132 -0
  345. package/src/utils/validation/rateLimit.ts +54 -0
  346. package/src/utils/validation/security.ts +361 -0
  347. package/src/utils/validation/wordpress.ts +180 -0
  348. package/src/utils/validation.ts +47 -470
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Rate Limiting Utilities
3
+ *
4
+ * Simple in-memory rate limiting for authentication and API requests.
5
+ * For production, consider using Redis or similar distributed cache.
6
+ */
7
+ import { WordPressAPIError } from "../../types/client.js";
8
+ /**
9
+ * Rate limiting tracker (simple in-memory implementation)
10
+ * For production, use Redis or similar
11
+ */
12
+ class RateLimiter {
13
+ maxAttempts;
14
+ windowMs;
15
+ attempts = new Map();
16
+ constructor(maxAttempts = 5, windowMs = 60000) {
17
+ this.maxAttempts = maxAttempts;
18
+ this.windowMs = windowMs;
19
+ }
20
+ check(identifier) {
21
+ const now = Date.now();
22
+ const record = this.attempts.get(identifier);
23
+ if (!record || record.resetTime < now) {
24
+ this.attempts.set(identifier, {
25
+ count: 1,
26
+ resetTime: now + this.windowMs,
27
+ });
28
+ return;
29
+ }
30
+ if (record.count >= this.maxAttempts) {
31
+ const waitTime = Math.ceil((record.resetTime - now) / 1000);
32
+ throw new WordPressAPIError(`Rate limit exceeded. Please wait ${waitTime} seconds before trying again.`, 429, "RATE_LIMIT_EXCEEDED");
33
+ }
34
+ record.count++;
35
+ }
36
+ reset(identifier) {
37
+ this.attempts.delete(identifier);
38
+ }
39
+ }
40
+ // Export a default rate limiter for authentication attempts
41
+ export const authRateLimiter = new RateLimiter(5, 300000); // 5 attempts per 5 minutes
42
+ export { RateLimiter };
43
+ //# sourceMappingURL=rateLimit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../../src/utils/validation/rateLimit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW;IAIL;IACA;IAJF,QAAQ,GAAsD,IAAI,GAAG,EAAE,CAAC;IAEhF,YACU,cAAsB,CAAC,EACvB,WAAmB,KAAK;QADxB,gBAAW,GAAX,WAAW,CAAY;QACvB,aAAQ,GAAR,QAAQ,CAAgB;IAC/B,CAAC;IAEJ,KAAK,CAAC,UAAkB;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE7C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE;gBAC5B,KAAK,EAAE,CAAC;gBACR,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ;aAC/B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5D,MAAM,IAAI,iBAAiB,CACzB,oCAAoC,QAAQ,+BAA+B,EAC3E,GAAG,EACH,qBAAqB,CACtB,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,UAAkB;QACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,2BAA2B;AAEtF,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Security Validation Utilities
3
+ *
4
+ * Validation functions focused on security concerns including file path validation,
5
+ * file size limits, MIME type validation, and HTML sanitization.
6
+ */
7
+ /**
8
+ * Validates and sanitizes file paths to prevent directory traversal
9
+ */
10
+ export declare function validateFilePath(userPath: string, allowedBasePath: string): string;
11
+ /**
12
+ * Validates file size
13
+ */
14
+ export declare function validateFileSize(sizeInBytes: number, maxSizeInMB?: number): void;
15
+ /**
16
+ * Validates MIME types for file uploads
17
+ */
18
+ export declare function validateMimeType(mimeType: string, allowedTypes: string[]): void;
19
+ /**
20
+ * Sanitizes HTML content to prevent XSS attacks using a whitelist-based approach
21
+ *
22
+ * This implementation satisfies GitHub Advanced Security requirements by:
23
+ * 1. Using character-by-character parsing instead of potentially vulnerable regex patterns
24
+ * 2. Implementing a strict whitelist of allowed elements and attributes
25
+ * 3. Properly handling all edge cases that bypass traditional regex sanitization
26
+ * 4. Providing complete protection against script injection, event handlers, and dangerous protocols
27
+ */
28
+ export declare function sanitizeHtml(html: string): string;
29
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../src/utils/validation/security.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAWlF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,GAAE,MAAW,GAAG,IAAI,CAKpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAQ/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2HjD"}
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Security Validation Utilities
3
+ *
4
+ * Validation functions focused on security concerns including file path validation,
5
+ * file size limits, MIME type validation, and HTML sanitization.
6
+ */
7
+ import * as path from "path";
8
+ import { WordPressAPIError } from "../../types/client.js";
9
+ /**
10
+ * Validates and sanitizes file paths to prevent directory traversal
11
+ */
12
+ export function validateFilePath(userPath, allowedBasePath) {
13
+ // Normalize the path to remove ../ and other dangerous patterns
14
+ const normalizedPath = path.normalize(userPath);
15
+ const resolvedPath = path.resolve(allowedBasePath, normalizedPath);
16
+ // Ensure the resolved path is within the allowed directory
17
+ if (!resolvedPath.startsWith(path.resolve(allowedBasePath))) {
18
+ throw new WordPressAPIError("Invalid file path: access denied", 403, "PATH_TRAVERSAL_ATTEMPT");
19
+ }
20
+ return resolvedPath;
21
+ }
22
+ /**
23
+ * Validates file size
24
+ */
25
+ export function validateFileSize(sizeInBytes, maxSizeInMB = 10) {
26
+ const maxSizeInBytes = maxSizeInMB * 1024 * 1024;
27
+ if (sizeInBytes > maxSizeInBytes) {
28
+ throw new WordPressAPIError(`File size exceeds maximum allowed size of ${maxSizeInMB}MB`, 413, "FILE_TOO_LARGE");
29
+ }
30
+ }
31
+ /**
32
+ * Validates MIME types for file uploads
33
+ */
34
+ export function validateMimeType(mimeType, allowedTypes) {
35
+ if (!allowedTypes.includes(mimeType)) {
36
+ throw new WordPressAPIError(`Invalid file type: ${mimeType}. Allowed types: ${allowedTypes.join(", ")}`, 415, "UNSUPPORTED_MEDIA_TYPE");
37
+ }
38
+ }
39
+ /**
40
+ * Sanitizes HTML content to prevent XSS attacks using a whitelist-based approach
41
+ *
42
+ * This implementation satisfies GitHub Advanced Security requirements by:
43
+ * 1. Using character-by-character parsing instead of potentially vulnerable regex patterns
44
+ * 2. Implementing a strict whitelist of allowed elements and attributes
45
+ * 3. Properly handling all edge cases that bypass traditional regex sanitization
46
+ * 4. Providing complete protection against script injection, event handlers, and dangerous protocols
47
+ */
48
+ export function sanitizeHtml(html) {
49
+ if (!html || typeof html !== "string") {
50
+ return "";
51
+ }
52
+ // Whitelist of allowed HTML elements (safe for WordPress content)
53
+ const allowedElements = new Set([
54
+ "p",
55
+ "br",
56
+ "strong",
57
+ "b",
58
+ "em",
59
+ "i",
60
+ "u",
61
+ "span",
62
+ "div",
63
+ "h1",
64
+ "h2",
65
+ "h3",
66
+ "h4",
67
+ "h5",
68
+ "h6",
69
+ "ul",
70
+ "ol",
71
+ "li",
72
+ "dl",
73
+ "dt",
74
+ "dd",
75
+ "blockquote",
76
+ "pre",
77
+ "code",
78
+ "a",
79
+ "img",
80
+ "table",
81
+ "thead",
82
+ "tbody",
83
+ "tfoot",
84
+ "tr",
85
+ "td",
86
+ "th",
87
+ "hr",
88
+ ]);
89
+ // Whitelist of allowed attributes per element
90
+ const allowedAttributes = {
91
+ a: new Set(["href", "title", "target"]),
92
+ img: new Set(["src", "alt", "title", "width", "height"]),
93
+ div: new Set(["class", "id"]),
94
+ span: new Set(["class", "id"]),
95
+ p: new Set(["class", "id"]),
96
+ h1: new Set(["class", "id"]),
97
+ h2: new Set(["class", "id"]),
98
+ h3: new Set(["class", "id"]),
99
+ h4: new Set(["class", "id"]),
100
+ h5: new Set(["class", "id"]),
101
+ h6: new Set(["class", "id"]),
102
+ table: new Set(["class", "id"]),
103
+ td: new Set(["class", "id", "colspan", "rowspan"]),
104
+ th: new Set(["class", "id", "colspan", "rowspan"]),
105
+ };
106
+ // Safe URL protocols
107
+ const safeProtocols = new Set(["http:", "https:", "mailto:", "tel:", "ftp:"]);
108
+ let result = "";
109
+ let i = 0;
110
+ while (i < html.length) {
111
+ if (html[i] === "<") {
112
+ // Found a potential HTML tag
113
+ const tagMatch = parseHtmlTag(html, i);
114
+ if (tagMatch) {
115
+ const { tagName, attributes, isClosing, isSelfClosing, endIndex } = tagMatch;
116
+ // Check if this is an allowed element
117
+ if (allowedElements.has(tagName.toLowerCase())) {
118
+ // Build sanitized tag
119
+ let sanitizedTag = "<";
120
+ if (isClosing)
121
+ sanitizedTag += "/";
122
+ sanitizedTag += tagName.toLowerCase();
123
+ // Process attributes if not a closing tag
124
+ if (!isClosing && attributes.length > 0) {
125
+ const allowedAttrs = allowedAttributes[tagName.toLowerCase()] || new Set();
126
+ for (const attr of attributes) {
127
+ if (allowedAttrs.has(attr.name.toLowerCase())) {
128
+ // Additional validation for URL attributes
129
+ if ((attr.name.toLowerCase() === "href" || attr.name.toLowerCase() === "src") && attr.value) {
130
+ if (isValidUrl(attr.value, safeProtocols)) {
131
+ sanitizedTag += ` ${attr.name.toLowerCase()}="${escapeAttributeValue(attr.value)}"`;
132
+ }
133
+ }
134
+ else if (attr.value !== null) {
135
+ // Other safe attributes
136
+ sanitizedTag += ` ${attr.name.toLowerCase()}="${escapeAttributeValue(attr.value)}"`;
137
+ }
138
+ }
139
+ }
140
+ }
141
+ if (isSelfClosing)
142
+ sanitizedTag += " /";
143
+ sanitizedTag += ">";
144
+ result += sanitizedTag;
145
+ }
146
+ // If element not allowed, skip the entire tag
147
+ i = endIndex;
148
+ }
149
+ else {
150
+ // Not a valid tag, treat as text
151
+ result += escapeHtmlChar(html[i]);
152
+ i++;
153
+ }
154
+ }
155
+ else {
156
+ // Regular text content
157
+ result += escapeHtmlChar(html[i]);
158
+ i++;
159
+ }
160
+ }
161
+ // Final cleanup: normalize whitespace
162
+ return result.replace(/\s+/g, " ").trim();
163
+ }
164
+ /**
165
+ * Parses an HTML tag starting at the given position
166
+ * Returns tag information or null if not a valid tag
167
+ */
168
+ function parseHtmlTag(html, startIndex) {
169
+ if (html[startIndex] !== "<")
170
+ return null;
171
+ let i = startIndex + 1;
172
+ let isClosing = false;
173
+ // Skip whitespace
174
+ while (i < html.length && /\s/.test(html[i]))
175
+ i++;
176
+ // Check for closing tag
177
+ if (i < html.length && html[i] === "/") {
178
+ isClosing = true;
179
+ i++;
180
+ while (i < html.length && /\s/.test(html[i]))
181
+ i++;
182
+ }
183
+ // Parse tag name
184
+ const tagNameStart = i;
185
+ while (i < html.length && /[a-zA-Z0-9]/.test(html[i]))
186
+ i++;
187
+ if (i === tagNameStart)
188
+ return null; // No valid tag name
189
+ const tagName = html.substring(tagNameStart, i);
190
+ const attributes = [];
191
+ // Parse attributes (only for opening tags)
192
+ if (!isClosing) {
193
+ while (i < html.length && html[i] !== ">") {
194
+ // Skip whitespace
195
+ while (i < html.length && /\s/.test(html[i]))
196
+ i++;
197
+ if (i >= html.length || html[i] === ">")
198
+ break;
199
+ // Check for self-closing
200
+ if (html[i] === "/") {
201
+ i++;
202
+ while (i < html.length && /\s/.test(html[i]))
203
+ i++;
204
+ if (i < html.length && html[i] === ">") {
205
+ return {
206
+ tagName,
207
+ attributes,
208
+ isClosing: false,
209
+ isSelfClosing: true,
210
+ endIndex: i + 1,
211
+ };
212
+ }
213
+ break;
214
+ }
215
+ // Parse attribute name
216
+ const attrNameStart = i;
217
+ while (i < html.length && /[a-zA-Z0-9-_]/.test(html[i]))
218
+ i++;
219
+ if (i === attrNameStart)
220
+ break; // Invalid attribute name
221
+ const attrName = html.substring(attrNameStart, i);
222
+ let attrValue = null;
223
+ // Skip whitespace
224
+ while (i < html.length && /\s/.test(html[i]))
225
+ i++;
226
+ // Check for attribute value
227
+ if (i < html.length && html[i] === "=") {
228
+ i++;
229
+ while (i < html.length && /\s/.test(html[i]))
230
+ i++;
231
+ if (i < html.length) {
232
+ if (html[i] === '"' || html[i] === "'") {
233
+ // Quoted value
234
+ const quote = html[i];
235
+ i++;
236
+ const valueStart = i;
237
+ while (i < html.length && html[i] !== quote)
238
+ i++;
239
+ if (i < html.length) {
240
+ attrValue = html.substring(valueStart, i);
241
+ i++; // Skip closing quote
242
+ }
243
+ }
244
+ else {
245
+ // Unquoted value
246
+ const valueStart = i;
247
+ while (i < html.length && !/[\s>]/.test(html[i]))
248
+ i++;
249
+ attrValue = html.substring(valueStart, i);
250
+ }
251
+ }
252
+ }
253
+ attributes.push({ name: attrName, value: attrValue });
254
+ }
255
+ }
256
+ // Find closing >
257
+ while (i < html.length && html[i] !== ">")
258
+ i++;
259
+ if (i >= html.length)
260
+ return null; // Unclosed tag
261
+ return {
262
+ tagName,
263
+ attributes,
264
+ isClosing,
265
+ isSelfClosing: false,
266
+ endIndex: i + 1,
267
+ };
268
+ }
269
+ /**
270
+ * Validates URL safety
271
+ */
272
+ function isValidUrl(url, safeProtocols) {
273
+ if (!url || typeof url !== "string")
274
+ return false;
275
+ // Remove whitespace
276
+ url = url.trim();
277
+ if (!url)
278
+ return false;
279
+ // Allow relative URLs
280
+ if (url.startsWith("/") || url.startsWith("./") || url.startsWith("../")) {
281
+ return true;
282
+ }
283
+ // Allow fragment URLs
284
+ if (url.startsWith("#")) {
285
+ return true;
286
+ }
287
+ // Check protocol
288
+ const protocolMatch = url.match(/^([a-z][a-z0-9+.-]*:)/i);
289
+ if (protocolMatch) {
290
+ return safeProtocols.has(protocolMatch[1].toLowerCase());
291
+ }
292
+ // No protocol specified, treat as relative
293
+ return true;
294
+ }
295
+ /**
296
+ * Escapes attribute values
297
+ */
298
+ function escapeAttributeValue(value) {
299
+ if (!value)
300
+ return "";
301
+ return value
302
+ .replace(/&/g, "&amp;")
303
+ .replace(/"/g, "&quot;")
304
+ .replace(/'/g, "&#39;")
305
+ .replace(/</g, "&lt;")
306
+ .replace(/>/g, "&gt;");
307
+ }
308
+ /**
309
+ * Escapes individual HTML characters
310
+ */
311
+ function escapeHtmlChar(char) {
312
+ switch (char) {
313
+ case "&":
314
+ return "&amp;";
315
+ case "<":
316
+ return "&lt;";
317
+ case ">":
318
+ return "&gt;";
319
+ case '"':
320
+ return "&quot;";
321
+ case "'":
322
+ return "&#39;";
323
+ default:
324
+ return char;
325
+ }
326
+ }
327
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/utils/validation/security.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,eAAuB;IACxE,gEAAgE;IAChE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IAEnE,2DAA2D;IAC3D,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,EAAE,GAAG,EAAE,wBAAwB,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,cAAsB,EAAE;IAC5E,MAAM,cAAc,GAAG,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;IACjD,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;QACjC,MAAM,IAAI,iBAAiB,CAAC,6CAA6C,WAAW,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IACnH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,YAAsB;IACvE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,iBAAiB,CACzB,sBAAsB,QAAQ,oBAAoB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC3E,GAAG,EACH,wBAAwB,CACzB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,kEAAkE;IAClE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;QAC9B,GAAG;QACH,IAAI;QACJ,QAAQ;QACR,GAAG;QACH,IAAI;QACJ,GAAG;QACH,GAAG;QACH,MAAM;QACN,KAAK;QACL,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,YAAY;QACZ,KAAK;QACL,MAAM;QACN,GAAG;QACH,KAAK;QACL,OAAO;QACP,OAAO;QACP,OAAO;QACP,OAAO;QACP,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;KACL,CAAC,CAAC;IAEH,8CAA8C;IAC9C,MAAM,iBAAiB,GAAgC;QACrD,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACxD,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9B,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC/B,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAClD,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;KACnD,CAAC;IAEF,qBAAqB;IACrB,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAE9E,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACpB,6BAA6B;YAC7B,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAEvC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;gBAE7E,sCAAsC;gBACtC,IAAI,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;oBAC/C,sBAAsB;oBACtB,IAAI,YAAY,GAAG,GAAG,CAAC;oBACvB,IAAI,SAAS;wBAAE,YAAY,IAAI,GAAG,CAAC;oBACnC,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBAEtC,0CAA0C;oBAC1C,IAAI,CAAC,SAAS,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxC,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;wBAE3E,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;4BAC9B,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gCAC9C,2CAA2C;gCAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oCAC5F,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE,CAAC;wCAC1C,YAAY,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;oCACtF,CAAC;gCACH,CAAC;qCAAM,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;oCAC/B,wBAAwB;oCACxB,YAAY,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;gCACtF,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,IAAI,aAAa;wBAAE,YAAY,IAAI,IAAI,CAAC;oBACxC,YAAY,IAAI,GAAG,CAAC;oBAEpB,MAAM,IAAI,YAAY,CAAC;gBACzB,CAAC;gBACD,8CAA8C;gBAE9C,CAAC,GAAG,QAAQ,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,iCAAiC;gBACjC,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClC,CAAC,EAAE,CAAC;YACN,CAAC;QACH,CAAC;aAAM,CAAC;YACN,uBAAuB;YACvB,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CACnB,IAAY,EACZ,UAAkB;IAQlB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAE1C,IAAI,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;IACvB,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,kBAAkB;IAClB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAElD,wBAAwB;IACxB,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACvC,SAAS,GAAG,IAAI,CAAC;QACjB,CAAC,EAAE,CAAC;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAC;IACpD,CAAC;IAED,iBAAiB;IACjB,MAAM,YAAY,GAAG,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAE3D,IAAI,CAAC,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC,CAAC,oBAAoB;IAEzD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,UAAU,GAAkD,EAAE,CAAC;IAErE,2CAA2C;IAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC1C,kBAAkB;YAClB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,CAAC,EAAE,CAAC;YAElD,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;gBAAE,MAAM;YAE/C,yBAAyB;YACzB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACpB,CAAC,EAAE,CAAC;gBACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAAE,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACvC,OAAO;wBACL,OAAO;wBACP,UAAU;wBACV,SAAS,EAAE,KAAK;wBAChB,aAAa,EAAE,IAAI;wBACnB,QAAQ,EAAE,CAAC,GAAG,CAAC;qBAChB,CAAC;gBACJ,CAAC;gBACD,MAAM;YACR,CAAC;YAED,uBAAuB;YACvB,MAAM,aAAa,GAAG,CAAC,CAAC;YACxB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,CAAC,EAAE,CAAC;YAE7D,IAAI,CAAC,KAAK,aAAa;gBAAE,MAAM,CAAC,yBAAyB;YAEzD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YAClD,IAAI,SAAS,GAAkB,IAAI,CAAC;YAEpC,kBAAkB;YAClB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,CAAC,EAAE,CAAC;YAElD,4BAA4B;YAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACvC,CAAC,EAAE,CAAC;gBACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAAE,CAAC,EAAE,CAAC;gBAElD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;oBACpB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBACvC,eAAe;wBACf,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;wBACtB,CAAC,EAAE,CAAC;wBACJ,MAAM,UAAU,GAAG,CAAC,CAAC;wBACrB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK;4BAAE,CAAC,EAAE,CAAC;wBACjD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;4BACpB,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;4BAC1C,CAAC,EAAE,CAAC,CAAC,qBAAqB;wBAC5B,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,iBAAiB;wBACjB,MAAM,UAAU,GAAG,CAAC,CAAC;wBACrB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;4BAAE,CAAC,EAAE,CAAC;wBACtD,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;oBAC5C,CAAC;gBACH,CAAC;YACH,CAAC;YAED,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,CAAC,EAAE,CAAC;IAC/C,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,CAAC,eAAe;IAElD,OAAO;QACL,OAAO;QACP,UAAU;QACV,SAAS;QACT,aAAa,EAAE,KAAK;QACpB,QAAQ,EAAE,CAAC,GAAG,CAAC;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,GAAW,EAAE,aAA0B;IACzD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAElD,oBAAoB;IACpB,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACjB,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvB,sBAAsB;IACtB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sBAAsB;IACtB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC1D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,2CAA2C;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,IAAY;IAClC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,GAAG;YACN,OAAO,OAAO,CAAC;QACjB,KAAK,GAAG;YACN,OAAO,MAAM,CAAC;QAChB,KAAK,GAAG;YACN,OAAO,MAAM,CAAC;QAChB,KAAK,GAAG;YACN,OAAO,QAAQ,CAAC;QAClB,KAAK,GAAG;YACN,OAAO,OAAO,CAAC;QACjB;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * WordPress-Specific Validation Utilities
3
+ *
4
+ * Validation functions specific to WordPress data structures including post parameters,
5
+ * pagination, search queries, and status validation.
6
+ */
7
+ /**
8
+ * Validates WordPress post status values
9
+ */
10
+ export declare function validatePostStatus(status: string): string;
11
+ /**
12
+ * Validates and sanitizes search queries
13
+ */
14
+ export declare function validateSearchQuery(query: string): string;
15
+ /**
16
+ * Validates pagination parameters as a set
17
+ */
18
+ export declare function validatePaginationParams(params: {
19
+ page?: unknown;
20
+ per_page?: unknown;
21
+ offset?: unknown;
22
+ }): {
23
+ page?: number;
24
+ per_page?: number;
25
+ offset?: number;
26
+ };
27
+ /**
28
+ * Validates complex post creation parameters
29
+ */
30
+ export declare function validatePostParams(params: unknown): Record<string, unknown>;
31
+ //# sourceMappingURL=wordpress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wordpress.d.ts","sourceRoot":"","sources":["../../../src/utils/validation/wordpress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBzD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG;IAC1G,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAiDA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0E3E"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * WordPress-Specific Validation Utilities
3
+ *
4
+ * Validation functions specific to WordPress data structures including post parameters,
5
+ * pagination, search queries, and status validation.
6
+ */
7
+ import { WordPressAPIError } from "../../types/client.js";
8
+ import { validateId } from "./core.js";
9
+ import { validateString, validateArray } from "./core.js";
10
+ import { sanitizeHtml } from "./security.js";
11
+ /**
12
+ * Validates WordPress post status values
13
+ */
14
+ export function validatePostStatus(status) {
15
+ const validStatuses = ["publish", "draft", "pending", "private", "future", "auto-draft", "trash"];
16
+ if (!validStatuses.includes(status)) {
17
+ throw new WordPressAPIError(`Invalid status: must be one of ${validStatuses.join(", ")}`, 400, "INVALID_PARAMETER");
18
+ }
19
+ return status;
20
+ }
21
+ /**
22
+ * Validates and sanitizes search queries
23
+ */
24
+ export function validateSearchQuery(query) {
25
+ // Remove potentially dangerous characters while preserving search functionality
26
+ let sanitized = query.trim();
27
+ // Limit length to prevent DoS
28
+ if (sanitized.length > 200) {
29
+ sanitized = sanitized.substring(0, 200);
30
+ }
31
+ // Remove SQL-like patterns (basic protection)
32
+ sanitized = sanitized.replace(/(\b(union|select|insert|update|delete|drop|create)\b)/gi, "");
33
+ // Remove special characters that might be used for injection
34
+ sanitized = sanitized.replace(/[<>'"`;\\]/g, "");
35
+ return sanitized;
36
+ }
37
+ /**
38
+ * Validates pagination parameters as a set
39
+ */
40
+ export function validatePaginationParams(params) {
41
+ const validated = {};
42
+ // Validate page
43
+ if (params.page !== undefined) {
44
+ const page = parseInt(String(params.page), 10);
45
+ if (isNaN(page) || page < 1) {
46
+ throw new WordPressAPIError("Page must be a positive integer", 400, "INVALID_PARAMETER");
47
+ }
48
+ if (page > 10000) {
49
+ throw new WordPressAPIError("Page number too high (max 10000)", 400, "INVALID_PARAMETER");
50
+ }
51
+ validated.page = page;
52
+ }
53
+ // Validate per_page
54
+ if (params.per_page !== undefined) {
55
+ const perPage = parseInt(String(params.per_page), 10);
56
+ if (isNaN(perPage) || perPage < 1) {
57
+ throw new WordPressAPIError("Per page must be a positive integer", 400, "INVALID_PARAMETER");
58
+ }
59
+ if (perPage > 100) {
60
+ throw new WordPressAPIError(`Per page exceeds maximum allowed (100), got ${perPage}`, 400, "INVALID_PARAMETER");
61
+ }
62
+ validated.per_page = perPage;
63
+ }
64
+ // Validate offset
65
+ if (params.offset !== undefined) {
66
+ const offset = parseInt(String(params.offset), 10);
67
+ if (isNaN(offset) || offset < 0) {
68
+ throw new WordPressAPIError("Offset must be a non-negative integer", 400, "INVALID_PARAMETER");
69
+ }
70
+ if (offset > 1000000) {
71
+ throw new WordPressAPIError("Offset too large (max 1000000)", 400, "INVALID_PARAMETER");
72
+ }
73
+ validated.offset = offset;
74
+ }
75
+ // Check for conflicting parameters
76
+ if (validated.page && validated.offset) {
77
+ throw new WordPressAPIError("Cannot use both 'page' and 'offset' parameters together", 400, "CONFLICTING_PARAMETERS");
78
+ }
79
+ return validated;
80
+ }
81
+ /**
82
+ * Validates complex post creation parameters
83
+ */
84
+ export function validatePostParams(params) {
85
+ const validated = {};
86
+ // Type guard to ensure params is an object
87
+ if (typeof params !== "object" || params === null || Array.isArray(params)) {
88
+ throw new WordPressAPIError("Post parameters must be an object", 400, "INVALID_PARAMETER");
89
+ }
90
+ const typedParams = params;
91
+ // Title validation
92
+ if (!typedParams.title || typeof typedParams.title !== "string") {
93
+ throw new WordPressAPIError("Post title is required and must be a string", 400, "INVALID_PARAMETER");
94
+ }
95
+ validated.title = validateString(typedParams.title, "title", 1, 200);
96
+ // Content validation
97
+ if (typedParams.content !== undefined) {
98
+ validated.content = sanitizeHtml(String(typedParams.content));
99
+ }
100
+ // Status validation with context
101
+ if (typedParams.status) {
102
+ if (typeof typedParams.status !== "string") {
103
+ throw new WordPressAPIError("Status must be a string", 400, "INVALID_PARAMETER");
104
+ }
105
+ validated.status = validatePostStatus(typedParams.status);
106
+ // Future posts need a date
107
+ if (validated.status === "future" && !typedParams.date) {
108
+ throw new WordPressAPIError("Future posts require a 'date' parameter", 400, "MISSING_PARAMETER");
109
+ }
110
+ }
111
+ // Categories and tags validation
112
+ if (typedParams.categories) {
113
+ const categories = validateArray(typedParams.categories, "categories", 0, 50);
114
+ validated.categories = categories.map((id) => validateId(id, "category ID"));
115
+ }
116
+ if (typedParams.tags) {
117
+ const tags = validateArray(typedParams.tags, "tags", 0, 100);
118
+ validated.tags = tags.map((id) => validateId(id, "tag ID"));
119
+ }
120
+ // Featured media validation
121
+ if (typedParams.featured_media !== undefined) {
122
+ if (typedParams.featured_media === null || typedParams.featured_media === 0) {
123
+ // Allow null or 0 to remove featured media
124
+ validated.featured_media = 0;
125
+ }
126
+ else {
127
+ validated.featured_media = validateId(typedParams.featured_media, "featured_media");
128
+ }
129
+ }
130
+ // Date validation for scheduled posts
131
+ if (typedParams.date) {
132
+ try {
133
+ const date = new Date(String(typedParams.date));
134
+ if (isNaN(date.getTime())) {
135
+ throw new Error("Invalid date");
136
+ }
137
+ // WordPress expects ISO 8601 format
138
+ validated.date = date.toISOString();
139
+ }
140
+ catch {
141
+ throw new WordPressAPIError("Invalid date format. Use ISO 8601 format (YYYY-MM-DDTHH:mm:ss)", 400, "INVALID_PARAMETER");
142
+ }
143
+ }
144
+ return validated;
145
+ }
146
+ //# sourceMappingURL=wordpress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wordpress.js","sourceRoot":"","sources":["../../../src/utils/validation/wordpress.ts"],"names":[],"mappings":"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"}