@js-recon/js-recon 1.4.4 → 2.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/.claude-sync/sync.sh +1 -1
  2. package/.github/workflows/build-and-prettify.yaml +49 -19
  3. package/.github/workflows/codeql.yml +33 -0
  4. package/.github/workflows/exploit-smoke-test.yaml +160 -0
  5. package/.github/workflows/framework-detection-smoke-test.yaml +135 -0
  6. package/.github/workflows/plumber.yml +20 -0
  7. package/.github/workflows/promote-js-recon.yml +5 -3
  8. package/.github/workflows/publish-js-recon.yml +6 -1
  9. package/.github/workflows/rules-smoke-test.yaml +13 -5
  10. package/.nvmrc +1 -0
  11. package/.plumber.yaml +151 -0
  12. package/CHANGELOG.md +35 -0
  13. package/CONTRIBUTING.md +32 -0
  14. package/Dockerfile +1 -0
  15. package/README.md +3 -2
  16. package/SECURITY.md +1 -1
  17. package/build/analyze/engine/astEngine.js +10 -9
  18. package/build/analyze/engine/astEngine.js.map +1 -1
  19. package/build/analyze/engine/csMastSEngine.js +6 -6
  20. package/build/analyze/engine/csMastSEngine.js.map +1 -1
  21. package/build/analyze/engine/index.js +1 -1
  22. package/build/analyze/engine/index.js.map +1 -1
  23. package/build/analyze/engine/requestEngine.js +6 -6
  24. package/build/analyze/engine/requestEngine.js.map +1 -1
  25. package/build/analyze/helpers/determineCompatibleVersion.js +70 -0
  26. package/build/analyze/helpers/determineCompatibleVersion.js.map +1 -0
  27. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +9 -3
  28. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
  29. package/build/analyze/helpers/initRules.js +9 -9
  30. package/build/analyze/helpers/initRules.js.map +1 -1
  31. package/build/analyze/helpers/outputHelper.js +3 -3
  32. package/build/analyze/helpers/outputHelper.js.map +1 -1
  33. package/build/analyze/helpers/schemas.js +1 -0
  34. package/build/analyze/helpers/schemas.js.map +1 -1
  35. package/build/analyze/helpers/validate.js +9 -5
  36. package/build/analyze/helpers/validate.js.map +1 -1
  37. package/build/analyze/index.js +26 -16
  38. package/build/analyze/index.js.map +1 -1
  39. package/build/cliProgram.js +710 -0
  40. package/build/cliProgram.js.map +1 -0
  41. package/build/completion/index.js +247 -382
  42. package/build/completion/index.js.map +1 -1
  43. package/build/completion/introspect.js +17 -0
  44. package/build/completion/introspect.js.map +1 -0
  45. package/build/config/applicationConfig.js +3 -2
  46. package/build/config/applicationConfig.js.map +1 -1
  47. package/build/cs_mast/index.js +18 -17
  48. package/build/cs_mast/index.js.map +1 -1
  49. package/build/endpoints/gen_report/gen_json.js +2 -2
  50. package/build/endpoints/gen_report/gen_json.js.map +1 -1
  51. package/build/endpoints/gen_report/utility/iterate_n_store.js +1 -1
  52. package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -1
  53. package/build/endpoints/index.js +12 -12
  54. package/build/endpoints/index.js.map +1 -1
  55. package/build/endpoints/next_js/client_jsFilesHref.js +3 -3
  56. package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
  57. package/build/endpoints/next_js/client_jsonParse.js +4 -4
  58. package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
  59. package/build/endpoints/next_js/client_mappedJsonFile.js +6 -6
  60. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
  61. package/build/endpoints/next_js/client_subsequentRequests.js +5 -5
  62. package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
  63. package/build/exploit/angular/cve-2026-68945.js +61 -0
  64. package/build/exploit/angular/cve-2026-68945.js.map +1 -0
  65. package/build/exploit/index.js +60 -0
  66. package/build/exploit/index.js.map +1 -0
  67. package/build/exploit/next/cve-2025-29927.js +65 -0
  68. package/build/exploit/next/cve-2025-29927.js.map +1 -0
  69. package/build/exploit/next/cve-2026-64645.js +51 -0
  70. package/build/exploit/next/cve-2026-64645.js.map +1 -0
  71. package/build/exploit/nuxt/cve-2026-71315.js +47 -0
  72. package/build/exploit/nuxt/cve-2026-71315.js.map +1 -0
  73. package/build/exploit/nuxt/cve-2026-71320.js +114 -0
  74. package/build/exploit/nuxt/cve-2026-71320.js.map +1 -0
  75. package/build/exploit/react/cve-2025-55182.js +116 -0
  76. package/build/exploit/react/cve-2025-55182.js.map +1 -0
  77. package/build/exploit/registry/cveRegistry.js +115 -0
  78. package/build/exploit/registry/cveRegistry.js.map +1 -0
  79. package/build/exploit/types.js +2 -0
  80. package/build/exploit/types.js.map +1 -0
  81. package/build/exploit/utility/compareResponses.js +29 -0
  82. package/build/exploit/utility/compareResponses.js.map +1 -0
  83. package/build/exploit/utility/outputHelper.js +22 -0
  84. package/build/exploit/utility/outputHelper.js.map +1 -0
  85. package/build/exploit/utility/rawRequest.js +54 -0
  86. package/build/exploit/utility/rawRequest.js.map +1 -0
  87. package/build/exploit/utility/sandboxRce.js +49 -0
  88. package/build/exploit/utility/sandboxRce.js.map +1 -0
  89. package/build/exploit/utility/toEngineOutput.js +28 -0
  90. package/build/exploit/utility/toEngineOutput.js.map +1 -0
  91. package/build/exploit/utility/wsClient.js +78 -0
  92. package/build/exploit/utility/wsClient.js.map +1 -0
  93. package/build/exploit/vite/cve-2025-30208.js +44 -0
  94. package/build/exploit/vite/cve-2025-30208.js.map +1 -0
  95. package/build/exploit/vite/cve-2026-39363.js +60 -0
  96. package/build/exploit/vite/cve-2026-39363.js.map +1 -0
  97. package/build/fingerprint/index.js +3 -2
  98. package/build/fingerprint/index.js.map +1 -1
  99. package/build/globalConfig.js +2 -2
  100. package/build/globalConfig.js.map +1 -1
  101. package/build/index.js +5 -596
  102. package/build/index.js.map +1 -1
  103. package/build/lazyLoad/angular/angular_getFromPageSource.js +3 -3
  104. package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -1
  105. package/build/lazyLoad/downloadFilesUtil.js +14 -11
  106. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  107. package/build/lazyLoad/downloadQueue.js +5 -1
  108. package/build/lazyLoad/downloadQueue.js.map +1 -1
  109. package/build/lazyLoad/downloadResponse.js +1 -0
  110. package/build/lazyLoad/downloadResponse.js.map +1 -1
  111. package/build/lazyLoad/generic/generic_crawlPages.js +186 -0
  112. package/build/lazyLoad/generic/generic_crawlPages.js.map +1 -0
  113. package/build/lazyLoad/generic/generic_downloadFiles.js +81 -0
  114. package/build/lazyLoad/generic/generic_downloadFiles.js.map +1 -0
  115. package/build/lazyLoad/generic/generic_extractLinks.js +79 -0
  116. package/build/lazyLoad/generic/generic_extractLinks.js.map +1 -0
  117. package/build/lazyLoad/generic/generic_getScriptTags.js +152 -0
  118. package/build/lazyLoad/generic/generic_getScriptTags.js.map +1 -0
  119. package/build/lazyLoad/generic/generic_importMapDiscovery.js +87 -0
  120. package/build/lazyLoad/generic/generic_importMapDiscovery.js.map +1 -0
  121. package/build/lazyLoad/generic/generic_resolveScope.js +61 -0
  122. package/build/lazyLoad/generic/generic_resolveScope.js.map +1 -0
  123. package/build/lazyLoad/generic/generic_scanAttributesForJs.js +122 -0
  124. package/build/lazyLoad/generic/generic_scanAttributesForJs.js.map +1 -0
  125. package/build/lazyLoad/generic/generic_stringsDiscovery.js +103 -0
  126. package/build/lazyLoad/generic/generic_stringsDiscovery.js.map +1 -0
  127. package/build/lazyLoad/generic/generic_webpackChunkPaths.js +56 -0
  128. package/build/lazyLoad/generic/generic_webpackChunkPaths.js.map +1 -0
  129. package/build/lazyLoad/globals.js +31 -0
  130. package/build/lazyLoad/globals.js.map +1 -1
  131. package/build/lazyLoad/index.js +129 -66
  132. package/build/lazyLoad/index.js.map +1 -1
  133. package/build/lazyLoad/methodFilter.js +2 -0
  134. package/build/lazyLoad/methodFilter.js.map +1 -1
  135. package/build/lazyLoad/next_js/NextJsCrawler.js +38 -14
  136. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  137. package/build/lazyLoad/next_js/next_GetJSScript.js +3 -3
  138. package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -1
  139. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +4 -4
  140. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
  141. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +13 -11
  142. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  143. package/build/lazyLoad/next_js/next_SubsequentRequests.js +7 -6
  144. package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -1
  145. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +1 -1
  146. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -1
  147. package/build/lazyLoad/next_js/next_buildId.js +2 -2
  148. package/build/lazyLoad/next_js/next_buildId.js.map +1 -1
  149. package/build/lazyLoad/next_js/next_getClientSidePaths.js +2 -2
  150. package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -1
  151. package/build/lazyLoad/next_js/next_parseLayoutJs.js +6 -6
  152. package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
  153. package/build/lazyLoad/next_js/next_promiseResolve.js +1 -1
  154. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
  155. package/build/lazyLoad/next_js/next_routerStateForge.js +341 -0
  156. package/build/lazyLoad/next_js/next_routerStateForge.js.map +1 -0
  157. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +1 -1
  158. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -1
  159. package/build/lazyLoad/next_js/next_serverActionIdScan.js +77 -0
  160. package/build/lazyLoad/next_js/next_serverActionIdScan.js.map +1 -0
  161. package/build/lazyLoad/nuxt_js/nuxt_astParse.js +15 -13
  162. package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
  163. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +2 -2
  164. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -1
  165. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -3
  166. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
  167. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +2 -2
  168. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
  169. package/build/lazyLoad/react/react_webpackChunkPaths.js +10 -202
  170. package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
  171. package/build/lazyLoad/researchUtils.js +15 -0
  172. package/build/lazyLoad/researchUtils.js.map +1 -0
  173. package/build/lazyLoad/shared/webpackChunkParsers.js +218 -0
  174. package/build/lazyLoad/shared/webpackChunkParsers.js.map +1 -0
  175. package/build/lazyLoad/stagnation/stagnationMonitor.js +63 -0
  176. package/build/lazyLoad/stagnation/stagnationMonitor.js.map +1 -0
  177. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +1 -0
  178. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -1
  179. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +5 -5
  180. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  181. package/build/lazyLoad/svelte/svelte_getVersionJson.js +2 -2
  182. package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -1
  183. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +6 -6
  184. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -1
  185. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +2 -2
  186. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  187. package/build/lazyLoad/techDetect/checkAngularJS.js +1 -1
  188. package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
  189. package/build/lazyLoad/techDetect/checkNuxtJS.js +3 -3
  190. package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -1
  191. package/build/lazyLoad/techDetect/checkSvelte.js +0 -1
  192. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
  193. package/build/lazyLoad/techDetect/checkVueJS.js +6 -6
  194. package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -1
  195. package/build/lazyLoad/techDetect/index.js +13 -1
  196. package/build/lazyLoad/techDetect/index.js.map +1 -1
  197. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -2
  198. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
  199. package/build/lazyLoad/vue/vue_discoverJsFiles.js +12 -10
  200. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
  201. package/build/lazyLoad/vue/vue_getClientSidePaths.js +1 -1
  202. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
  203. package/build/lazyLoad/vue/vue_pageSrc.js +1 -1
  204. package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
  205. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +2 -2
  206. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
  207. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
  208. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  209. package/build/lazyLoad/vue/vue_severalJsFilesHome.js +3 -3
  210. package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
  211. package/build/load/index.js +8 -7
  212. package/build/load/index.js.map +1 -1
  213. package/build/map/angular_js/getAngularConnections.js +6 -6
  214. package/build/map/angular_js/getAngularConnections.js.map +1 -1
  215. package/build/map/graphql/resolveGraphql.js +6 -6
  216. package/build/map/graphql/resolveGraphql.js.map +1 -1
  217. package/build/map/index.js +17 -17
  218. package/build/map/index.js.map +1 -1
  219. package/build/map/interactive-mode/commandHandler.js +278 -0
  220. package/build/map/interactive-mode/commandHandler.js.map +1 -0
  221. package/build/map/interactive-mode/commandHelpers.js +189 -0
  222. package/build/map/interactive-mode/commandHelpers.js.map +1 -0
  223. package/build/map/interactive-mode/esqueryGen.js.map +1 -0
  224. package/build/map/interactive-mode/helpMenu.js +11 -0
  225. package/build/map/interactive-mode/helpMenu.js.map +1 -0
  226. package/build/map/interactive-mode/inputPatch.js.map +1 -0
  227. package/build/map/interactive-mode/interactive.js +71 -0
  228. package/build/map/interactive-mode/interactive.js.map +1 -0
  229. package/build/map/interactive-mode/keybindings.js.map +1 -0
  230. package/build/map/interactive-mode/printer.js.map +1 -0
  231. package/build/map/interactive-mode/ui.js.map +1 -0
  232. package/build/map/next_js/getAxiosInstances.js +5 -5
  233. package/build/map/next_js/getAxiosInstances.js.map +1 -1
  234. package/build/map/next_js/getExports.js +4 -4
  235. package/build/map/next_js/getExports.js.map +1 -1
  236. package/build/map/next_js/getFetchInstances.js +10 -10
  237. package/build/map/next_js/getFetchInstances.js.map +1 -1
  238. package/build/map/next_js/getTurbopackConnections.js +8 -8
  239. package/build/map/next_js/getTurbopackConnections.js.map +1 -1
  240. package/build/map/next_js/getWebpackConnections.js +27 -16
  241. package/build/map/next_js/getWebpackConnections.js.map +1 -1
  242. package/build/map/next_js/interactive.js +3 -65
  243. package/build/map/next_js/interactive.js.map +1 -1
  244. package/build/map/next_js/interactive_helpers/commandHandler.js +38 -290
  245. package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -1
  246. package/build/map/next_js/interactive_helpers/commandHelpers.js +0 -184
  247. package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
  248. package/build/map/next_js/interactive_helpers/helpMenu.js +2 -10
  249. package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -1
  250. package/build/map/next_js/resolveAxios.js +6 -6
  251. package/build/map/next_js/resolveAxios.js.map +1 -1
  252. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +4 -4
  253. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
  254. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -2
  255. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
  256. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +5 -5
  257. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
  258. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +10 -10
  259. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
  260. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +13 -9
  261. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
  262. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +12 -8
  263. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
  264. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +12 -8
  265. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -1
  266. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +11 -11
  267. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
  268. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +16 -16
  269. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
  270. package/build/map/next_js/resolveFetch.js +23 -23
  271. package/build/map/next_js/resolveFetch.js.map +1 -1
  272. package/build/map/next_js/resolveNewRequest.js +10 -10
  273. package/build/map/next_js/resolveNewRequest.js.map +1 -1
  274. package/build/map/next_js/resolveServerActions.js +4 -4
  275. package/build/map/next_js/resolveServerActions.js.map +1 -1
  276. package/build/map/next_js/utils.js +8 -2
  277. package/build/map/next_js/utils.js.map +1 -1
  278. package/build/map/react_js/getReactConnections.js +21 -14
  279. package/build/map/react_js/getReactConnections.js.map +1 -1
  280. package/build/map/svelte_js/interactive.js +3 -54
  281. package/build/map/svelte_js/interactive.js.map +1 -1
  282. package/build/map/vue_js/getViteConnections.js +23 -16
  283. package/build/map/vue_js/getViteConnections.js.map +1 -1
  284. package/build/map/vue_js/interactive.js +3 -63
  285. package/build/map/vue_js/interactive.js.map +1 -1
  286. package/build/map/vue_js/interactive_helpers/commandHandler.js +34 -283
  287. package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -1
  288. package/build/map/vue_js/interactive_helpers/helpMenu.js +2 -10
  289. package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -1
  290. package/build/map/vue_js/taint_utils.js +1 -1
  291. package/build/map/vue_js/taint_utils.js.map +1 -1
  292. package/build/map/vue_js/vue_resolveFetch.js +12 -12
  293. package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
  294. package/build/map/vue_js/vue_resolveHttpClient.js +18 -18
  295. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
  296. package/build/map/vue_js/vue_resolveXhr.js +11 -11
  297. package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
  298. package/build/mcp/chatOneShot.js +7 -7
  299. package/build/mcp/chatOneShot.js.map +1 -1
  300. package/build/mcp/claudeCodeCreds.js +5 -5
  301. package/build/mcp/claudeCodeCreds.js.map +1 -1
  302. package/build/mcp/cli.js +36 -35
  303. package/build/mcp/cli.js.map +1 -1
  304. package/build/mcp/config.js +4 -4
  305. package/build/mcp/config.js.map +1 -1
  306. package/build/mcp/index.js +7 -7
  307. package/build/mcp/index.js.map +1 -1
  308. package/build/mcp/mcpServer.js +3 -2
  309. package/build/mcp/mcpServer.js.map +1 -1
  310. package/build/mcp/skills.js +1 -0
  311. package/build/mcp/skills.js.map +1 -1
  312. package/build/mcp/tools.js +5 -4
  313. package/build/mcp/tools.js.map +1 -1
  314. package/build/proxy/detectBlockedResponse.js +2 -0
  315. package/build/proxy/detectBlockedResponse.js.map +1 -1
  316. package/build/proxy/index.js +3 -3
  317. package/build/proxy/index.js.map +1 -1
  318. package/build/refactor/index.js +83 -79
  319. package/build/refactor/index.js.map +1 -1
  320. package/build/refactor/next/index.js +69 -26
  321. package/build/refactor/next/index.js.map +1 -1
  322. package/build/refactor/next/transform.js +11 -4
  323. package/build/refactor/next/transform.js.map +1 -1
  324. package/build/refactor/next/validator.js +7 -7
  325. package/build/refactor/next/validator.js.map +1 -1
  326. package/build/refactor/react/index.js +13 -13
  327. package/build/refactor/react/index.js.map +1 -1
  328. package/build/refactor/react/validator.js +7 -7
  329. package/build/refactor/react/validator.js.map +1 -1
  330. package/build/refactor/react-vite/index.js +3 -3
  331. package/build/refactor/react-vite/index.js.map +1 -1
  332. package/build/refactor/remote/hf-client.js +1 -0
  333. package/build/refactor/remote/hf-client.js.map +1 -1
  334. package/build/refactor/remote/version-detect.js +12 -12
  335. package/build/refactor/remote/version-detect.js.map +1 -1
  336. package/build/refactor/vue/index.js +6 -6
  337. package/build/refactor/vue/index.js.map +1 -1
  338. package/build/refactor/vue/vite.js +6 -6
  339. package/build/refactor/vue/vite.js.map +1 -1
  340. package/build/report/index.js +30 -8
  341. package/build/report/index.js.map +1 -1
  342. package/build/report/swaggerJacker.js +63 -0
  343. package/build/report/swaggerJacker.js.map +1 -0
  344. package/build/report/utility/genHtml.js +7 -7
  345. package/build/report/utility/genHtml.js.map +1 -1
  346. package/build/report/utility/populateDb/populateAnalysisFindings.js +2 -2
  347. package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -1
  348. package/build/report/utility/populateDb/populateEndpoints.js +3 -3
  349. package/build/report/utility/populateDb/populateEndpoints.js.map +1 -1
  350. package/build/report/utility/populateDb/populateMappedJson.js +2 -2
  351. package/build/report/utility/populateDb/populateMappedJson.js.map +1 -1
  352. package/build/report/utility/populateDb/populateMappedOpenapi.js +3 -3
  353. package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -1
  354. package/build/run/bundler-detect.js +45 -9
  355. package/build/run/bundler-detect.js.map +1 -1
  356. package/build/run/dashboard/dashboardHtml.js +150 -0
  357. package/build/run/dashboard/dashboardHtml.js.map +1 -0
  358. package/build/run/dashboard/fsBrowser.js +43 -0
  359. package/build/run/dashboard/fsBrowser.js.map +1 -0
  360. package/build/run/dashboard/server.js +123 -0
  361. package/build/run/dashboard/server.js.map +1 -0
  362. package/build/run/dashboard/state.js +97 -0
  363. package/build/run/dashboard/state.js.map +1 -0
  364. package/build/run/index.js +177 -110
  365. package/build/run/index.js.map +1 -1
  366. package/build/run/interruptHandler.js +18 -0
  367. package/build/run/interruptHandler.js.map +1 -1
  368. package/build/sourcemaps/index.js +7 -6
  369. package/build/sourcemaps/index.js.map +1 -1
  370. package/build/strings/index.js +27 -24
  371. package/build/strings/index.js.map +1 -1
  372. package/build/strings/openapi.js +4 -4
  373. package/build/strings/openapi.js.map +1 -1
  374. package/build/strings/permutate.js +4 -4
  375. package/build/strings/permutate.js.map +1 -1
  376. package/build/strings/secrets.js +1 -0
  377. package/build/strings/secrets.js.map +1 -1
  378. package/build/strings/trufflehog.js +66 -19
  379. package/build/strings/trufflehog.js.map +1 -1
  380. package/build/strings/trufflehogConfig.js +36 -0
  381. package/build/strings/trufflehogConfig.js.map +1 -0
  382. package/build/strings/trufflehogDownload.js +115 -0
  383. package/build/strings/trufflehogDownload.js.map +1 -0
  384. package/build/utility/ai.js +33 -4
  385. package/build/utility/ai.js.map +1 -1
  386. package/build/utility/banner.js +4 -3
  387. package/build/utility/banner.js.map +1 -1
  388. package/build/utility/configureSandbox.js +2 -2
  389. package/build/utility/configureSandbox.js.map +1 -1
  390. package/build/utility/globals.js +19 -11
  391. package/build/utility/globals.js.map +1 -1
  392. package/build/utility/heap.js +2 -1
  393. package/build/utility/heap.js.map +1 -1
  394. package/build/utility/makeReq.js +1 -1
  395. package/build/utility/makeReq.js.map +1 -1
  396. package/build/utility/openapiGenerator.js +2 -2
  397. package/build/utility/openapiGenerator.js.map +1 -1
  398. package/build/utility/printMsg.js +53 -0
  399. package/build/utility/printMsg.js.map +1 -0
  400. package/build/utility/progressLog.js +4 -3
  401. package/build/utility/progressLog.js.map +1 -1
  402. package/build/utility/resolvePath.js +2 -1
  403. package/build/utility/resolvePath.js.map +1 -1
  404. package/build/utility/ruleVersionMap.js +73 -0
  405. package/build/utility/ruleVersionMap.js.map +1 -0
  406. package/contributing/testing.md +106 -0
  407. package/eslint.config.js +24 -0
  408. package/package.json +22 -5
  409. package/scripts/exploit-smoke-test.js +82 -0
  410. package/scripts/framework-detect-smoke-test.js +64 -0
  411. package/scripts/postinstall-completion.mjs +40 -0
  412. package/scripts/smoke-test.js +12 -0
  413. package/build/lazyLoad/downloadLoadedJsUtil.js +0 -98
  414. package/build/lazyLoad/downloadLoadedJsUtil.js.map +0 -1
  415. package/build/map/next_js/interactive_helpers/esqueryGen.js.map +0 -1
  416. package/build/map/next_js/interactive_helpers/inputPatch.js.map +0 -1
  417. package/build/map/next_js/interactive_helpers/keybindings.js.map +0 -1
  418. package/build/map/next_js/interactive_helpers/printer.js.map +0 -1
  419. package/build/map/next_js/interactive_helpers/ui.js.map +0 -1
  420. /package/build/map/{next_js/interactive_helpers → interactive-mode}/esqueryGen.js +0 -0
  421. /package/build/map/{next_js/interactive_helpers → interactive-mode}/inputPatch.js +0 -0
  422. /package/build/map/{next_js/interactive_helpers → interactive-mode}/keybindings.js +0 -0
  423. /package/build/map/{next_js/interactive_helpers → interactive-mode}/printer.js +0 -0
  424. /package/build/map/{next_js/interactive_helpers → interactive-mode}/ui.js +0 -0
@@ -19,10 +19,11 @@ import report from "../report/index.js";
19
19
  import refactor from "../refactor/index.js";
20
20
  import initGlobalReportDb from "../report/utility/initGlobalReportDb.js";
21
21
  import mergeDomainIntoGlobalDb from "../report/utility/mergeDomainIntoGlobalDb.js";
22
- import { clearJsUrls, clearJsonUrls, getJsUrls } from "../lazyLoad/globals.js";
22
+ import { clearJsUrls, clearJsonUrls, clearJsFileHashCounts, getJsUrls } from "../lazyLoad/globals.js";
23
23
  import path from "path";
24
24
  import { installSigintHandler, removeSigintHandler, getSkipStepPromise, resetSkipStep, shouldSkipTarget, resetSkipTarget, waitForPendingInterrupt, } from "./interruptHandler.js";
25
25
  import { detectBundler } from "./bundler-detect.js";
26
+ import { printMsg, MSG, setHeaderListener } from "../utility/printMsg.js";
26
27
  import configureProxy from "../utility/configureProxy.js";
27
28
  import { getOxylabsFallbackConfiguration } from "../proxy/oxylabsFallback.js";
28
29
  import { probeFeasibility } from "../proxy/checkFeasibility.js";
@@ -31,6 +32,8 @@ import { resolveHostOutputDirectory } from "../lazyLoad/outputPath.js";
31
32
  import { awaitCancellableStep } from "./cancellableStep.js";
32
33
  import { resolveTargetInputs } from "../utility/targetInputs.js";
33
34
  import { clearRunOutputDirectory, getBatchTargetDirectoryName, reserveRunOutputDirectory } from "./outputDirectory.js";
35
+ import { startDashboardServer } from "./dashboard/server.js";
36
+ import * as dashboardState from "./dashboard/state.js";
34
37
  /**
35
38
  * Determines the directory for a Content Delivery Network (CDN) if used by the target.
36
39
  *
@@ -78,10 +81,11 @@ const getCdnDir = (host, outputDir, isBatch) => __awaiter(void 0, void 0, void 0
78
81
  const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_1) => __awaiter(void 0, [url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_1], void 0, function* (url, outputDir, workingDir, cmd, isBatch, includeMethods = [], excludeMethods = []) {
79
82
  var _a, _b, _c, _d;
80
83
  const targetHost = new URL(url).host;
81
- console.log(chalk.bgGreenBright(`[+] Starting analysis for ${url}...`));
84
+ printMsg(MSG.Run, `[+] Starting analysis for ${url}...`);
82
85
  if (isBatch) {
83
86
  clearJsUrls();
84
87
  clearJsonUrls();
88
+ clearJsFileHashCounts();
85
89
  globalsUtil.clearOpenapiOutput();
86
90
  }
87
91
  if (cmd.proxyWafFallback && cmd._proxyConfigured) {
@@ -92,39 +96,39 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
92
96
  outcome = yield probeFeasibility(resolved, url);
93
97
  }
94
98
  catch (error) {
95
- console.error(chalk.bgRed(`[!] Proxy WAF fallback check failed: ${error}. ${isBatch ? "Skipping this target." : "Quitting."}`));
99
+ printMsg(MSG.Err, `[!] Proxy WAF fallback check failed: ${error}. ${isBatch ? "Skipping this target." : "Quitting."}`);
96
100
  if (isBatch)
97
101
  return;
98
102
  process.exit(29);
99
103
  }
100
- console.log(outcome.code === 0 ? chalk.green(outcome.message) : chalk.yellow(outcome.message));
104
+ printMsg(outcome.code === 0 ? MSG.Run : MSG.Warn, outcome.message);
101
105
  if (outcome.code === 27) {
102
106
  // no firewall detected without a proxy - don't use it for this target
103
107
  globalsUtil.setUseProxy(false);
104
108
  }
105
109
  else if (outcome.code === 28) {
106
- console.error(chalk.bgRed(`[!] Proxy could not bypass the firewall for this target. ${isBatch ? "Skipping this target." : "Quitting."}`));
110
+ printMsg(MSG.Err, `[!] Proxy could not bypass the firewall for this target. ${isBatch ? "Skipping this target." : "Quitting."}`);
107
111
  if (isBatch)
108
112
  return;
109
113
  process.exit(29);
110
114
  }
111
115
  // outcome.code === 0: firewall present, proxy bypasses it - keep using the proxy
112
116
  }
113
- console.log(chalk.bgCyan("[1/8] Running lazyload to download JavaScript files..."));
117
+ printMsg(MSG.Header, "[1/8] Running lazyload to download JavaScript files...");
114
118
  resetSkipStep();
115
- yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, false, "", cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch), getSkipStepPromise());
116
- console.log(chalk.bgGreen("[+] Lazyload complete."));
119
+ yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, false, "", cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch, Number(cmd.maxRedirects), cmd.strings, Number(cmd.stringsMaxIterations), Number(cmd.stagnationTimein) * 60 * 1000, Number(cmd.stagnationPercentage), Number(cmd.stagnationMonitor) * 60 * 1000, Number(cmd.rscParamBruteforceLimit)), getSkipStepPromise());
120
+ printMsg(MSG.Run, "[+] Lazyload complete.");
117
121
  if (shouldSkipTarget())
118
122
  return;
119
123
  if (globalsUtil.getTech() === "") {
120
- console.error(chalk.bgRed(`[!] Technology not detected. ${isBatch ? "Skipping this target." : "Quitting."}`));
124
+ printMsg(MSG.Err, `[!] Technology not detected. ${isBatch ? "Skipping this target." : "Quitting."}`);
121
125
  if (isBatch) {
122
126
  return;
123
127
  }
124
128
  process.exit(10);
125
129
  }
126
130
  if (!["next", "vue", "nuxt", "react", "svelte", "angular"].includes(globalsUtil.getTech())) {
127
- console.log(chalk.bgYellow(`[!] The tool supports Next.JS, Vue.JS, Nuxt.JS, React, Svelte/Astro, and Angular in the run module. For ${globalsUtil.getTech()}, only downloading JS files is supported`));
131
+ printMsg(MSG.Warn, `[!] The tool supports Next.JS, Vue.JS, Nuxt.JS, React, Svelte/Astro, and Angular in the run module. For ${globalsUtil.getTech()}, only downloading JS files is supported`);
128
132
  return;
129
133
  }
130
134
  // Capture the tech here — subsequent lazyload passes (steps 3, 4.5) re-run framework
@@ -140,7 +144,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
140
144
  const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
141
145
  const reportFile = isBatch ? `${workingDir}/report` : "report";
142
146
  const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
143
- console.log(chalk.bgCyan("[2/4] Running map to find functions and API calls..."));
147
+ printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
144
148
  globalsUtil.setOpenapi(true);
145
149
  if (isBatch) {
146
150
  globalsUtil.setOpenapiOutputFile(openapiFile);
@@ -155,40 +159,39 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
155
159
  map(outputDir, mappedFileReact, ["json"], "react", false, false, cmd.command || []),
156
160
  getSkipStepPromise(),
157
161
  ]);
158
- console.log(chalk.bgGreen("[+] Map complete."));
162
+ printMsg(MSG.Run, "[+] Map complete.");
159
163
  if (shouldSkipTarget())
160
164
  return;
161
- console.log(chalk.bgCyan("[3/4] Running analyze..."));
165
+ printMsg(MSG.Header, "[3/4] Running analyze...");
162
166
  resetSkipStep();
163
- // @ts-ignore
164
167
  yield Promise.race([
165
- analyze(cmd.rules || "", mappedJsonFileReact, "react", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
168
+ analyze(cmd.rules || "", mappedJsonFileReact, "react", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
166
169
  getSkipStepPromise(),
167
170
  ]);
168
- console.log(chalk.bgGreen("[+] Analyze complete."));
171
+ printMsg(MSG.Run, "[+] Analyze complete.");
169
172
  if (shouldSkipTarget())
170
173
  return;
171
- console.log(chalk.bgCyan("[4/4] Running report module..."));
174
+ printMsg(MSG.Header, "[4/4] Running report module...");
172
175
  const endpointsJson = `${endpointsFile}.json`;
173
176
  if (!fs.existsSync(endpointsJson)) {
174
177
  fs.writeFileSync(endpointsJson, "[]");
175
178
  }
176
179
  resetSkipStep();
177
180
  yield Promise.race([
178
- report(reportDbFile, mappedJsonFileReact, analyzeFile, endpointsJson, openapiFile, reportFile),
181
+ report(reportDbFile, mappedJsonFileReact, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
179
182
  getSkipStepPromise(),
180
183
  ]);
181
- console.log(chalk.bgGreen("[+] Report complete."));
184
+ printMsg(MSG.Run, "[+] Report complete.");
182
185
  if (shouldSkipTarget())
183
186
  return;
184
187
  if (!cmd.disableRefactor) {
185
- console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
188
+ printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
186
189
  const detectedBundlerTechReact = yield detectBundler(mappedJsonFileReact, "react", Number((_a = cmd.csMastTechDetectThreshold) !== null && _a !== void 0 ? _a : 50));
187
190
  if (detectedBundlerTechReact) {
188
191
  const refactorOutputDirReact = isBatch ? `${workingDir}/refactored` : "refactored";
189
192
  if (fs.existsSync(refactorOutputDirReact))
190
193
  fs.rmSync(refactorOutputDirReact, { recursive: true });
191
- console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechReact})...`));
194
+ printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechReact})...`);
192
195
  // Vendor chunks may have been downloaded under a different host than the target
193
196
  // (CDN) — resolve the assets dir from an actual downloaded JS URL's host instead
194
197
  // of always assuming targetHost, mirroring getCdnDir's approach for the map step.
@@ -207,16 +210,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
207
210
  ]);
208
211
  if (shouldSkipTarget())
209
212
  return;
210
- console.log(chalk.bgGreen("[+] Refactor complete."));
213
+ printMsg(MSG.Run, "[+] Refactor complete.");
211
214
  }
212
215
  else {
213
- console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
216
+ printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
214
217
  }
215
218
  }
216
219
  else {
217
- console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
220
+ printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
218
221
  }
219
- console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
222
+ printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
220
223
  return;
221
224
  }
222
225
  if (detectedTech === "vue") {
@@ -230,7 +233,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
230
233
  const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
231
234
  const reportFile = isBatch ? `${workingDir}/report` : "report";
232
235
  const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
233
- console.log(chalk.bgCyan("[2/4] Running map to find functions and API calls..."));
236
+ printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
234
237
  globalsUtil.setOpenapi(true);
235
238
  if (isBatch) {
236
239
  globalsUtil.setOpenapiOutputFile(openapiFile);
@@ -245,20 +248,19 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
245
248
  map(outputDir, mappedFileVue, ["json"], "vue", false, false, cmd.command || []),
246
249
  getSkipStepPromise(),
247
250
  ]);
248
- console.log(chalk.bgGreen("[+] Map complete."));
251
+ printMsg(MSG.Run, "[+] Map complete.");
249
252
  if (shouldSkipTarget())
250
253
  return;
251
- console.log(chalk.bgCyan("[3/4] Running analyze..."));
254
+ printMsg(MSG.Header, "[3/4] Running analyze...");
252
255
  resetSkipStep();
253
- // @ts-ignore
254
256
  yield Promise.race([
255
- analyze(cmd.rules || "", mappedJsonFileVue, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
257
+ analyze(cmd.rules || "", mappedJsonFileVue, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
256
258
  getSkipStepPromise(),
257
259
  ]);
258
- console.log(chalk.bgGreen("[+] Analyze complete."));
260
+ printMsg(MSG.Run, "[+] Analyze complete.");
259
261
  if (shouldSkipTarget())
260
262
  return;
261
- console.log(chalk.bgCyan("[4/4] Running report module..."));
263
+ printMsg(MSG.Header, "[4/4] Running report module...");
262
264
  // Endpoints extraction isn't implemented for Vue yet; pass an empty file if absent.
263
265
  const endpointsJson = `${endpointsFile}.json`;
264
266
  if (!fs.existsSync(endpointsJson)) {
@@ -266,20 +268,20 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
266
268
  }
267
269
  resetSkipStep();
268
270
  yield Promise.race([
269
- report(reportDbFile, mappedJsonFileVue, analyzeFile, endpointsJson, openapiFile, reportFile),
271
+ report(reportDbFile, mappedJsonFileVue, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
270
272
  getSkipStepPromise(),
271
273
  ]);
272
- console.log(chalk.bgGreen("[+] Report complete."));
274
+ printMsg(MSG.Run, "[+] Report complete.");
273
275
  if (shouldSkipTarget())
274
276
  return;
275
277
  if (!cmd.disableRefactor) {
276
- console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
278
+ printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
277
279
  const detectedBundlerTechVue = yield detectBundler(mappedJsonFileVue, "vue", Number((_b = cmd.csMastTechDetectThreshold) !== null && _b !== void 0 ? _b : 50));
278
280
  if (detectedBundlerTechVue) {
279
281
  const refactorOutputDirVue = isBatch ? `${workingDir}/refactored` : "refactored";
280
282
  if (fs.existsSync(refactorOutputDirVue))
281
283
  fs.rmSync(refactorOutputDirVue, { recursive: true });
282
- console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechVue})...`));
284
+ printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechVue})...`);
283
285
  resetSkipStep();
284
286
  yield Promise.race([
285
287
  refactor(mappedJsonFileVue, refactorOutputDirVue, detectedBundlerTechVue, false),
@@ -287,16 +289,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
287
289
  ]);
288
290
  if (shouldSkipTarget())
289
291
  return;
290
- console.log(chalk.bgGreen("[+] Refactor complete."));
292
+ printMsg(MSG.Run, "[+] Refactor complete.");
291
293
  }
292
294
  else {
293
- console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
295
+ printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
294
296
  }
295
297
  }
296
298
  else {
297
- console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
299
+ printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
298
300
  }
299
- console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
301
+ printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
300
302
  return;
301
303
  }
302
304
  if (detectedTech === "nuxt") {
@@ -308,7 +310,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
308
310
  const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
309
311
  const reportFile = isBatch ? `${workingDir}/report` : "report";
310
312
  const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
311
- console.log(chalk.bgCyan("[2/4] Running map to find functions and API calls..."));
313
+ printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
312
314
  globalsUtil.setOpenapi(true);
313
315
  if (isBatch) {
314
316
  globalsUtil.setOpenapiOutputFile(openapiFile);
@@ -323,40 +325,39 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
323
325
  map(outputDir, mappedFileNuxt, ["json"], "vue", false, false, cmd.command || []),
324
326
  getSkipStepPromise(),
325
327
  ]);
326
- console.log(chalk.bgGreen("[+] Map complete."));
328
+ printMsg(MSG.Run, "[+] Map complete.");
327
329
  if (shouldSkipTarget())
328
330
  return;
329
- console.log(chalk.bgCyan("[3/4] Running analyze..."));
331
+ printMsg(MSG.Header, "[3/4] Running analyze...");
330
332
  resetSkipStep();
331
- // @ts-ignore
332
333
  yield Promise.race([
333
- analyze(cmd.rules || "", mappedJsonFileNuxt, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
334
+ analyze(cmd.rules || "", mappedJsonFileNuxt, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
334
335
  getSkipStepPromise(),
335
336
  ]);
336
- console.log(chalk.bgGreen("[+] Analyze complete."));
337
+ printMsg(MSG.Run, "[+] Analyze complete.");
337
338
  if (shouldSkipTarget())
338
339
  return;
339
- console.log(chalk.bgCyan("[4/4] Running report module..."));
340
+ printMsg(MSG.Header, "[4/4] Running report module...");
340
341
  const endpointsJson = `${endpointsFile}.json`;
341
342
  if (!fs.existsSync(endpointsJson)) {
342
343
  fs.writeFileSync(endpointsJson, "[]");
343
344
  }
344
345
  resetSkipStep();
345
346
  yield Promise.race([
346
- report(reportDbFile, mappedJsonFileNuxt, analyzeFile, endpointsJson, openapiFile, reportFile),
347
+ report(reportDbFile, mappedJsonFileNuxt, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
347
348
  getSkipStepPromise(),
348
349
  ]);
349
- console.log(chalk.bgGreen("[+] Report complete."));
350
+ printMsg(MSG.Run, "[+] Report complete.");
350
351
  if (shouldSkipTarget())
351
352
  return;
352
353
  if (!cmd.disableRefactor) {
353
- console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
354
+ printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
354
355
  const detectedBundlerTechNuxt = yield detectBundler(mappedJsonFileNuxt, "nuxt", Number((_c = cmd.csMastTechDetectThreshold) !== null && _c !== void 0 ? _c : 50));
355
356
  if (detectedBundlerTechNuxt) {
356
357
  const refactorOutputDirNuxt = isBatch ? `${workingDir}/refactored` : "refactored";
357
358
  if (fs.existsSync(refactorOutputDirNuxt))
358
359
  fs.rmSync(refactorOutputDirNuxt, { recursive: true });
359
- console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechNuxt})...`));
360
+ printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechNuxt})...`);
360
361
  resetSkipStep();
361
362
  yield Promise.race([
362
363
  refactor(mappedJsonFileNuxt, refactorOutputDirNuxt, detectedBundlerTechNuxt, false),
@@ -364,16 +365,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
364
365
  ]);
365
366
  if (shouldSkipTarget())
366
367
  return;
367
- console.log(chalk.bgGreen("[+] Refactor complete."));
368
+ printMsg(MSG.Run, "[+] Refactor complete.");
368
369
  }
369
370
  else {
370
- console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
371
+ printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
371
372
  }
372
373
  }
373
374
  else {
374
- console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
375
+ printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
375
376
  }
376
- console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
377
+ printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
377
378
  return;
378
379
  }
379
380
  if (detectedTech === "svelte") {
@@ -384,7 +385,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
384
385
  const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
385
386
  const reportFile = isBatch ? `${workingDir}/report` : "report";
386
387
  const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
387
- console.log(chalk.bgCyan("[2/4] Running map to find functions and API calls..."));
388
+ printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
388
389
  globalsUtil.setOpenapi(true);
389
390
  if (isBatch) {
390
391
  globalsUtil.setOpenapiOutputFile(openapiFile);
@@ -399,31 +400,30 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
399
400
  map(outputDir, mappedFileSvelte, ["json"], "svelte", false, false, cmd.command || []),
400
401
  getSkipStepPromise(),
401
402
  ]);
402
- console.log(chalk.bgGreen("[+] Map complete."));
403
+ printMsg(MSG.Run, "[+] Map complete.");
403
404
  if (shouldSkipTarget())
404
405
  return;
405
- console.log(chalk.bgCyan("[3/4] Running analyze..."));
406
+ printMsg(MSG.Header, "[3/4] Running analyze...");
406
407
  resetSkipStep();
407
- // @ts-ignore
408
408
  yield Promise.race([
409
- analyze(cmd.rules || "", mappedJsonFileSvelte, "svelte", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
409
+ analyze(cmd.rules || "", mappedJsonFileSvelte, "svelte", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
410
410
  getSkipStepPromise(),
411
411
  ]);
412
- console.log(chalk.bgGreen("[+] Analyze complete."));
412
+ printMsg(MSG.Run, "[+] Analyze complete.");
413
413
  if (shouldSkipTarget())
414
414
  return;
415
- console.log(chalk.bgCyan("[4/4] Running report module..."));
415
+ printMsg(MSG.Header, "[4/4] Running report module...");
416
416
  const endpointsJson = `${endpointsFile}.json`;
417
417
  if (!fs.existsSync(endpointsJson)) {
418
418
  fs.writeFileSync(endpointsJson, "[]");
419
419
  }
420
420
  resetSkipStep();
421
421
  yield Promise.race([
422
- report(reportDbFile, mappedJsonFileSvelte, analyzeFile, endpointsJson, openapiFile, reportFile),
422
+ report(reportDbFile, mappedJsonFileSvelte, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
423
423
  getSkipStepPromise(),
424
424
  ]);
425
- console.log(chalk.bgGreen("[+] Report complete."));
426
- console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
425
+ printMsg(MSG.Run, "[+] Report complete.");
426
+ printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
427
427
  return;
428
428
  }
429
429
  if (detectedTech === "angular") {
@@ -438,7 +438,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
438
438
  const reportFile = isBatch ? `${workingDir}/report` : "report";
439
439
  const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
440
440
  const angularHostDir = resolveHostOutputDirectory(outputDir, targetHost, isBatch);
441
- console.log(chalk.bgCyan("[2/4] Running map to find functions and API calls..."));
441
+ printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
442
442
  globalsUtil.setOpenapi(true);
443
443
  if (isBatch) {
444
444
  globalsUtil.setOpenapiOutputFile(openapiFile);
@@ -453,31 +453,30 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
453
453
  map(angularHostDir, mappedFileAngular, ["json"], "angular", false, false, cmd.command || []),
454
454
  getSkipStepPromise(),
455
455
  ]);
456
- console.log(chalk.bgGreen("[+] Map complete."));
456
+ printMsg(MSG.Run, "[+] Map complete.");
457
457
  if (shouldSkipTarget())
458
458
  return;
459
- console.log(chalk.bgCyan("[3/4] Running analyze..."));
459
+ printMsg(MSG.Header, "[3/4] Running analyze...");
460
460
  resetSkipStep();
461
- // @ts-ignore
462
461
  yield Promise.race([
463
- analyze(cmd.rules || "", mappedJsonFileAngular, "angular", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
462
+ analyze(cmd.rules || "", mappedJsonFileAngular, "angular", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
464
463
  getSkipStepPromise(),
465
464
  ]);
466
- console.log(chalk.bgGreen("[+] Analyze complete."));
465
+ printMsg(MSG.Run, "[+] Analyze complete.");
467
466
  if (shouldSkipTarget())
468
467
  return;
469
- console.log(chalk.bgCyan("[4/4] Running report module..."));
468
+ printMsg(MSG.Header, "[4/4] Running report module...");
470
469
  const endpointsJson = `${endpointsFile}.json`;
471
470
  if (!fs.existsSync(endpointsJson)) {
472
471
  fs.writeFileSync(endpointsJson, "[]");
473
472
  }
474
473
  resetSkipStep();
475
474
  yield Promise.race([
476
- report(reportDbFile, mappedJsonFileAngular, analyzeFile, endpointsJson, openapiFile, reportFile),
475
+ report(reportDbFile, mappedJsonFileAngular, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
477
476
  getSkipStepPromise(),
478
477
  ]);
479
- console.log(chalk.bgGreen("[+] Report complete."));
480
- console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
478
+ printMsg(MSG.Run, "[+] Report complete.");
479
+ printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
481
480
  return;
482
481
  }
483
482
  const stringsFile = isBatch ? `${workingDir}/strings.json` : "strings.json";
@@ -494,50 +493,50 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
494
493
  // One IMPORTANT thing: this is only meant for modules that rely on just the code (map)
495
494
  const cdnDir = yield getCdnDir(url, outputDir, isBatch);
496
495
  const cdnOutputDir = cdnDir ? cdnDir : resolveHostOutputDirectory(outputDir, targetHost, isBatch);
497
- console.log(chalk.bgCyan("[2/8] Running strings to extract endpoints..."));
496
+ printMsg(MSG.Header, "[2/8] Running strings to extract endpoints...");
498
497
  resetSkipStep();
499
498
  yield Promise.race([
500
499
  strings(outputDir, stringsFile, true, extractedUrlsFile, false, false, false, false),
501
500
  getSkipStepPromise(),
502
501
  ]);
503
- console.log(chalk.bgGreen("[+] Strings complete."));
502
+ printMsg(MSG.Run, "[+] Strings complete.");
504
503
  if (shouldSkipTarget())
505
504
  return;
506
- console.log(chalk.bgCyan("[3/8] Running lazyload with subsequent requests to download JavaScript files..."));
505
+ printMsg(MSG.Header, "[3/8] Running lazyload with subsequent requests to download JavaScript files...");
507
506
  resetSkipStep();
508
- yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, true, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch), getSkipStepPromise());
509
- console.log(chalk.bgGreen("[+] Lazyload with subsequent requests complete."));
507
+ yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, true, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch, Number(cmd.maxRedirects), cmd.strings, Number(cmd.stringsMaxIterations), Number(cmd.stagnationTimein) * 60 * 1000, Number(cmd.stagnationPercentage), Number(cmd.stagnationMonitor) * 60 * 1000, Number(cmd.rscParamBruteforceLimit)), getSkipStepPromise());
508
+ printMsg(MSG.Run, "[+] Lazyload with subsequent requests complete.");
510
509
  if (shouldSkipTarget())
511
510
  return;
512
- console.log(chalk.bgCyan("[4/8] Running strings again to extract endpoints..."));
511
+ printMsg(MSG.Header, "[4/8] Running strings again to extract endpoints...");
513
512
  resetSkipStep();
514
513
  yield Promise.race([
515
- strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog),
514
+ strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog, cmd.trufflehogBin, cmd.trufflehogAcceptTerms),
516
515
  getSkipStepPromise(),
517
516
  ]);
518
- console.log(chalk.bgGreen("[+] Strings complete."));
517
+ printMsg(MSG.Run, "[+] Strings complete.");
519
518
  if (shouldSkipTarget())
520
519
  return;
521
520
  // a second subsequent_requests pass: the first strings pass only sees initial chunks,
522
521
  // so dynamic routes such as `/post/1` are only discovered after the first subsequent
523
522
  // crawl + second strings extraction. Re-running subsequent_requests with the freshly
524
523
  // updated paths picks up chunks for those dynamic routes (e.g. the post page).
525
- console.log(chalk.bgCyan("[4.5/8] Re-running lazyload with subsequent requests for newly discovered paths..."));
524
+ printMsg(MSG.Header, "[4.5/8] Re-running lazyload with subsequent requests for newly discovered paths...");
526
525
  resetSkipStep();
527
- yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch), getSkipStepPromise());
528
- console.log(chalk.bgGreen("[+] Lazyload re-pass complete."));
526
+ yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch, Number(cmd.maxRedirects), cmd.strings, Number(cmd.stringsMaxIterations), Number(cmd.stagnationTimein) * 60 * 1000, Number(cmd.stagnationPercentage), Number(cmd.stagnationMonitor) * 60 * 1000, Number(cmd.rscParamBruteforceLimit)), getSkipStepPromise());
527
+ printMsg(MSG.Run, "[+] Lazyload re-pass complete.");
529
528
  if (shouldSkipTarget())
530
529
  return;
531
- console.log(chalk.bgCyan("[4.6/8] Re-running strings for chunks from the re-pass..."));
530
+ printMsg(MSG.Header, "[4.6/8] Re-running strings for chunks from the re-pass...");
532
531
  resetSkipStep();
533
532
  yield Promise.race([
534
- strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog),
533
+ strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog, cmd.trufflehogBin, cmd.trufflehogAcceptTerms),
535
534
  getSkipStepPromise(),
536
535
  ]);
537
- console.log(chalk.bgGreen("[+] Strings re-pass complete."));
536
+ printMsg(MSG.Run, "[+] Strings re-pass complete.");
538
537
  if (shouldSkipTarget())
539
538
  return;
540
- console.log(chalk.bgCyan("[5/8] Running map to find functions..."));
539
+ printMsg(MSG.Header, "[5/8] Running map to find functions...");
541
540
  globalsUtil.setOpenapi(true);
542
541
  if (isBatch) {
543
542
  globalsUtil.setOpenapiOutputFile(openapiFile);
@@ -555,10 +554,10 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
555
554
  map(cdnOutputDir, mappedFile, ["json"], detectedTech, false, false, cmd.command || []),
556
555
  getSkipStepPromise(),
557
556
  ]);
558
- console.log(chalk.bgGreen("[+] Map complete."));
557
+ printMsg(MSG.Run, "[+] Map complete.");
559
558
  if (shouldSkipTarget())
560
559
  return;
561
- console.log(chalk.bgCyan("[6/8] Running endpoints to extract endpoints..."));
560
+ printMsg(MSG.Header, "[6/8] Running endpoints to extract endpoints...");
562
561
  resetSkipStep();
563
562
  const targetOutputDir = resolveHostOutputDirectory(outputDir, targetHost, isBatch);
564
563
  if (fs.existsSync(path.join(targetOutputDir, "___subsequent_requests"))) {
@@ -573,35 +572,35 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
573
572
  getSkipStepPromise(),
574
573
  ]);
575
574
  }
576
- console.log(chalk.bgGreen("[+] Endpoints complete."));
575
+ printMsg(MSG.Run, "[+] Endpoints complete.");
577
576
  if (shouldSkipTarget())
578
577
  return;
579
- console.log(chalk.bgCyan("[7/8] Running analyze to extract endpoints..."));
578
+ printMsg(MSG.Header, "[7/8] Running analyze to extract endpoints...");
580
579
  resetSkipStep();
581
580
  yield Promise.race([
582
- analyze(cmd.rules || "", mappedJsonFile, detectedTech, false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
581
+ analyze(cmd.rules || "", mappedJsonFile, detectedTech, false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
583
582
  getSkipStepPromise(),
584
583
  ]);
585
- console.log(chalk.bgGreen("[+] Analyze complete."));
584
+ printMsg(MSG.Run, "[+] Analyze complete.");
586
585
  if (shouldSkipTarget())
587
586
  return;
588
- console.log(chalk.bgCyan("[8/8] Running report module..."));
587
+ printMsg(MSG.Header, "[8/8] Running report module...");
589
588
  resetSkipStep();
590
589
  yield Promise.race([
591
- report(reportDbFile, mappedJsonFile, analyzeFile, `${endpointsFile}.json`, openapiFile, reportFile),
590
+ report(reportDbFile, mappedJsonFile, analyzeFile, `${endpointsFile}.json`, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
592
591
  getSkipStepPromise(),
593
592
  ]);
594
- console.log(chalk.bgGreen("[+] Report complete."));
593
+ printMsg(MSG.Run, "[+] Report complete.");
595
594
  if (shouldSkipTarget())
596
595
  return;
597
596
  if (!cmd.disableRefactor) {
598
- console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
597
+ printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
599
598
  const detectedBundlerTechNext = yield detectBundler(mappedJsonFile, detectedTech, Number((_d = cmd.csMastTechDetectThreshold) !== null && _d !== void 0 ? _d : 50));
600
599
  if (detectedBundlerTechNext) {
601
600
  const refactorOutputDirNext = isBatch ? `${workingDir}/refactored` : "refactored";
602
601
  if (fs.existsSync(refactorOutputDirNext))
603
602
  fs.rmSync(refactorOutputDirNext, { recursive: true });
604
- console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechNext})...`));
603
+ printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechNext})...`);
605
604
  resetSkipStep();
606
605
  yield Promise.race([
607
606
  refactor(mappedJsonFile, refactorOutputDirNext, detectedBundlerTechNext, false),
@@ -609,16 +608,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
609
608
  ]);
610
609
  if (shouldSkipTarget())
611
610
  return;
612
- console.log(chalk.bgGreen("[+] Refactor complete."));
611
+ printMsg(MSG.Run, "[+] Refactor complete.");
613
612
  }
614
613
  else {
615
- console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
614
+ printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
616
615
  }
617
616
  }
618
617
  else {
619
- console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
618
+ printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
620
619
  }
621
- console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
620
+ printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
622
621
  });
623
622
  /**
624
623
  * Main handler for the 'run' command that executes the complete js-recon analysis pipeline.
@@ -630,6 +629,32 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
630
629
  * @param cmd - The command-line options object from commander.js
631
630
  * @returns Promise that resolves when all URL processing is complete
632
631
  */
632
+ /**
633
+ * Parses a batch/single `cmd.url` into the `{ url, hostDir, dir }` entries the
634
+ * dashboard state store needs, mirroring the hostDir/dir resolution the batch
635
+ * loop and single-target path use below. Invalid URLs are dropped — they're
636
+ * reported (and skipped) by the existing validation further down.
637
+ */
638
+ const buildDashboardTargetEntries = (cmd, isBatch) => {
639
+ const toEntry = (url, dir) => {
640
+ try {
641
+ return { url, hostDir: new URL(url).host.replace(":", "_"), dir };
642
+ }
643
+ catch (_a) {
644
+ return null;
645
+ }
646
+ };
647
+ if (!isBatch) {
648
+ const entry = toEntry(cmd.url, cmd.output);
649
+ return entry ? [entry] : [];
650
+ }
651
+ return fs
652
+ .readFileSync(cmd.url, "utf-8")
653
+ .split("\n")
654
+ .filter((url) => url !== "")
655
+ .map((url) => toEntry(url, `${cmd.output}/${new URL(url).host.replace(":", "_")}`))
656
+ .filter((e) => e !== null);
657
+ };
633
658
  export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
634
659
  var _a, _b, _c, _d, _e, _f;
635
660
  const resolvedTargets = resolveTargetInputs(cmd.url);
@@ -653,9 +678,29 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
653
678
  clearRunOutputDirectory(runCommand.output);
654
679
  }
655
680
  installSigintHandler(isBatch);
681
+ let dashboard = null;
682
+ if (cmd.webStatsDashboard) {
683
+ dashboardState.registerTargets(buildDashboardTargetEntries(cmd, isBatch));
684
+ dashboard = yield startDashboardServer(Number(cmd.webStatsPort));
685
+ printMsg(MSG.Run, `[+] Web stats dashboard running at ${dashboard.url}`);
686
+ setHeaderListener((msg) => dashboardState.markStep(msg));
687
+ }
656
688
  try {
657
689
  if (!isBatch) {
658
- yield processUrl(resolvedTargets.targets[0], runCommand.output, ".", runCommand, false, (_a = runCommand._includeMethods) !== null && _a !== void 0 ? _a : [], (_b = runCommand._excludeMethods) !== null && _b !== void 0 ? _b : []);
690
+ if (cmd.webStatsDashboard) {
691
+ dashboardState.setCurrentUrl(resolvedTargets.targets[0]);
692
+ dashboardState.markRunning(resolvedTargets.targets[0]);
693
+ }
694
+ try {
695
+ yield processUrl(resolvedTargets.targets[0], runCommand.output, ".", runCommand, false, (_a = runCommand._includeMethods) !== null && _a !== void 0 ? _a : [], (_b = runCommand._excludeMethods) !== null && _b !== void 0 ? _b : []);
696
+ if (cmd.webStatsDashboard)
697
+ dashboardState.markCompleted(resolvedTargets.targets[0]);
698
+ }
699
+ catch (e) {
700
+ if (cmd.webStatsDashboard)
701
+ dashboardState.markError(resolvedTargets.targets[0], e instanceof Error ? e.message : String(e));
702
+ throw e;
703
+ }
659
704
  }
660
705
  else {
661
706
  const globalDbPath = `${runCommand.output}/js-recon.db`;
@@ -677,12 +722,30 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
677
722
  else if (targetReservation.redirected) {
678
723
  console.log(chalk.yellow(`[i] Target output already exists; using ${thisTargetDir} for ${url}.`));
679
724
  }
725
+ if (cmd.webStatsDashboard && dashboardState.isSkipRequested(url)) {
726
+ printMsg(MSG.Warn, `[!] Skipping ${url} (skipped from the web dashboard).`);
727
+ dashboardState.markSkipped(url);
728
+ targetReservation.release();
729
+ continue;
730
+ }
731
+ if (cmd.webStatsDashboard) {
732
+ dashboardState.setCurrentUrl(url);
733
+ dashboardState.markRunning(url);
734
+ }
680
735
  try {
681
736
  try {
682
737
  yield processUrl(url, thisTargetDir, thisTargetDir, runCommand, true, (_d = runCommand._includeMethods) !== null && _d !== void 0 ? _d : [], (_e = runCommand._excludeMethods) !== null && _e !== void 0 ? _e : []);
738
+ if (cmd.webStatsDashboard) {
739
+ if (shouldSkipTarget())
740
+ dashboardState.markSkipped(url);
741
+ else
742
+ dashboardState.markCompleted(url);
743
+ }
683
744
  }
684
745
  catch (error) {
685
- console.error(chalk.bgRed(`[!] Unhandled error while processing ${url}: ${error}`));
746
+ if (cmd.webStatsDashboard)
747
+ dashboardState.markError(url, error instanceof Error ? error.message : String(error));
748
+ printMsg(MSG.Err, `[!] Unhandled error while processing ${url}: ${error}`);
686
749
  process.exitCode = 1;
687
750
  continue;
688
751
  }
@@ -692,11 +755,11 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
692
755
  mergeDomainIntoGlobalDb(globalDbPath, domainDbPath, hostDir);
693
756
  }
694
757
  catch (error) {
695
- console.error(chalk.yellow(`[!] Failed to merge ${hostDir} into the global js-recon.db: ${error}`));
758
+ printMsg(MSG.Warn, `[!] Failed to merge ${hostDir} into the global js-recon.db: ${error}`);
696
759
  }
697
760
  }
698
761
  else {
699
- console.log(chalk.yellow(`[i] No js-recon.db found for ${hostDir}, skipping merge into the global database.`));
762
+ printMsg(MSG.Warn, `[i] No js-recon.db found for ${hostDir}, skipping merge into the global database.`);
700
763
  }
701
764
  }
702
765
  finally {
@@ -706,10 +769,14 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
706
769
  }
707
770
  }
708
771
  catch (error) {
709
- console.error(chalk.bgRed(`[!] Unhandled error: ${error}`));
772
+ printMsg(MSG.Err, `[!] Unhandled error: ${error}`);
710
773
  process.exitCode = 1;
711
774
  }
712
775
  finally {
776
+ if (dashboard) {
777
+ setHeaderListener(null);
778
+ yield dashboard.stop();
779
+ }
713
780
  try {
714
781
  yield waitForPendingInterrupt();
715
782
  }