@js-recon/js-recon 1.3.1-beta.2
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.
- package/.gitattributes +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/ISSUE_TEMPLATE/new_tech_support_request.md +26 -0
- package/.github/workflows/build-and-prettify.yaml +121 -0
- package/.github/workflows/pr_checker.yml +22 -0
- package/.github/workflows/publish-js-recon.yml +169 -0
- package/.prettierignore +2 -0
- package/.prettierrc +6 -0
- package/CHANGELOG.md +692 -0
- package/CLAUDE.md +290 -0
- package/Dockerfile +34 -0
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/SECURITY.md +37 -0
- package/build/analyze/engine/astEngine.js +224 -0
- package/build/analyze/engine/astEngine.js.map +1 -0
- package/build/analyze/engine/index.js +59 -0
- package/build/analyze/engine/index.js.map +1 -0
- package/build/analyze/engine/requestEngine.js +100 -0
- package/build/analyze/engine/requestEngine.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/findDirectAssignment.js +37 -0
- package/build/analyze/helpers/engineHelpers/findDirectAssignment.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +29 -0
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js +38 -0
- package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/taintFlow.js +250 -0
- package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -0
- package/build/analyze/helpers/initRules.js +111 -0
- package/build/analyze/helpers/initRules.js.map +1 -0
- package/build/analyze/helpers/outputHelper.js +14 -0
- package/build/analyze/helpers/outputHelper.js.map +1 -0
- package/build/analyze/helpers/schemas.js +57 -0
- package/build/analyze/helpers/schemas.js.map +1 -0
- package/build/analyze/helpers/validate.js +89 -0
- package/build/analyze/helpers/validate.js.map +1 -0
- package/build/analyze/index.js +150 -0
- package/build/analyze/index.js.map +1 -0
- package/build/analyze/types/index.js +2 -0
- package/build/analyze/types/index.js.map +1 -0
- package/build/api_gateway/checkFeasibility.js +41 -0
- package/build/api_gateway/checkFeasibility.js.map +1 -0
- package/build/api_gateway/checkFireWallBlocking.js +33 -0
- package/build/api_gateway/checkFireWallBlocking.js.map +1 -0
- package/build/api_gateway/genReq.js +205 -0
- package/build/api_gateway/genReq.js.map +1 -0
- package/build/api_gateway/index.js +291 -0
- package/build/api_gateway/index.js.map +1 -0
- package/build/endpoints/gen_report/gen_json.js +30 -0
- package/build/endpoints/gen_report/gen_json.js.map +1 -0
- package/build/endpoints/gen_report/utility/iterate_n_store.js +64 -0
- package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -0
- package/build/endpoints/index.js +101 -0
- package/build/endpoints/index.js.map +1 -0
- package/build/endpoints/next_js/client_jsFilesHref.js +100 -0
- package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -0
- package/build/endpoints/next_js/client_jsonParse.js +89 -0
- package/build/endpoints/next_js/client_jsonParse.js.map +1 -0
- package/build/endpoints/next_js/client_mappedJsonFile.js +103 -0
- package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -0
- package/build/endpoints/next_js/client_subsequentRequests.js +211 -0
- package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -0
- package/build/fingerprint/index.js +123 -0
- package/build/fingerprint/index.js.map +1 -0
- package/build/globalConfig.js +16 -0
- package/build/globalConfig.js.map +1 -0
- package/build/index.js +332 -0
- package/build/index.js.map +1 -0
- package/build/lazyLoad/angular/angular_getFromMainJs.js +55 -0
- package/build/lazyLoad/angular/angular_getFromMainJs.js.map +1 -0
- package/build/lazyLoad/angular/angular_getFromPageSource.js +43 -0
- package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -0
- package/build/lazyLoad/downloadFilesUtil.js +127 -0
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js +44 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -0
- package/build/lazyLoad/downloadQueue.js +191 -0
- package/build/lazyLoad/downloadQueue.js.map +1 -0
- package/build/lazyLoad/globals.js +107 -0
- package/build/lazyLoad/globals.js.map +1 -0
- package/build/lazyLoad/index.js +377 -0
- package/build/lazyLoad/index.js.map +1 -0
- package/build/lazyLoad/next_js/NextJsCrawler.js +332 -0
- package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -0
- package/build/lazyLoad/next_js/next_GetJSScript.js +126 -0
- package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -0
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +83 -0
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -0
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +222 -0
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -0
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +208 -0
- package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -0
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +37 -0
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -0
- package/build/lazyLoad/next_js/next_buildId.js +55 -0
- package/build/lazyLoad/next_js/next_buildId.js.map +1 -0
- package/build/lazyLoad/next_js/next_getClientSidePaths.js +83 -0
- package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -0
- package/build/lazyLoad/next_js/next_globals.js +8 -0
- package/build/lazyLoad/next_js/next_globals.js.map +1 -0
- package/build/lazyLoad/next_js/next_parseLayoutJs.js +116 -0
- package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -0
- package/build/lazyLoad/next_js/next_promiseResolve.js +85 -0
- package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -0
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +51 -0
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js +202 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +82 -0
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +108 -0
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -0
- package/build/lazyLoad/react/react_followImports.js +105 -0
- package/build/lazyLoad/react/react_followImports.js.map +1 -0
- package/build/lazyLoad/react/react_getScriptTags.js +52 -0
- package/build/lazyLoad/react/react_getScriptTags.js.map +1 -0
- package/build/lazyLoad/react/react_sourcemapUrls.js +44 -0
- package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -0
- package/build/lazyLoad/react/react_webpackChunkPaths.js +188 -0
- package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -0
- package/build/lazyLoad/sourcemap.js +188 -0
- package/build/lazyLoad/sourcemap.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +162 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js +91 -0
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +180 -0
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +123 -0
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -0
- package/build/lazyLoad/techDetect/checkAngularJS.js +70 -0
- package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -0
- package/build/lazyLoad/techDetect/checkNextJS.js +45 -0
- package/build/lazyLoad/techDetect/checkNextJS.js.map +1 -0
- package/build/lazyLoad/techDetect/checkNuxtJS.js +39 -0
- package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -0
- package/build/lazyLoad/techDetect/checkReact.js +86 -0
- package/build/lazyLoad/techDetect/checkReact.js.map +1 -0
- package/build/lazyLoad/techDetect/checkSvelte.js +69 -0
- package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -0
- package/build/lazyLoad/techDetect/checkVueJS.js +118 -0
- package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -0
- package/build/lazyLoad/techDetect/index.js +161 -0
- package/build/lazyLoad/techDetect/index.js.map +1 -0
- package/build/lazyLoad/vue/vue_RuntimeJs.js +169 -0
- package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -0
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +102 -0
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -0
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +82 -0
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -0
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +155 -0
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -0
- package/build/lazyLoad/vue/vue_jsImports.js +76 -0
- package/build/lazyLoad/vue/vue_jsImports.js.map +1 -0
- package/build/lazyLoad/vue/vue_pageSrc.js +60 -0
- package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -0
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +64 -0
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -0
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +142 -0
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -0
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js +57 -0
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -0
- package/build/lazyLoad/vue/vue_sourcemapExtract.js +166 -0
- package/build/lazyLoad/vue/vue_sourcemapExtract.js.map +1 -0
- package/build/lazyLoad/vue/vue_stringJsFiles.js +148 -0
- package/build/lazyLoad/vue/vue_stringJsFiles.js.map +1 -0
- package/build/lazyLoad/vue/vue_viteMapDeps.js +89 -0
- package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -0
- package/build/load/index.js +316 -0
- package/build/load/index.js.map +1 -0
- package/build/map/graphql/resolveGraphql.js +296 -0
- package/build/map/graphql/resolveGraphql.js.map +1 -0
- package/build/map/index.js +261 -0
- package/build/map/index.js.map +1 -0
- package/build/map/next_js/getAxiosInstances.js +64 -0
- package/build/map/next_js/getAxiosInstances.js.map +1 -0
- package/build/map/next_js/getExports.js +101 -0
- package/build/map/next_js/getExports.js.map +1 -0
- package/build/map/next_js/getFetchInstances.js +139 -0
- package/build/map/next_js/getFetchInstances.js.map +1 -0
- package/build/map/next_js/getTurbopackConnections.js +255 -0
- package/build/map/next_js/getTurbopackConnections.js.map +1 -0
- package/build/map/next_js/getWebpackConnections.js +235 -0
- package/build/map/next_js/getWebpackConnections.js.map +1 -0
- package/build/map/next_js/interactive.js +69 -0
- package/build/map/next_js/interactive.js.map +1 -0
- package/build/map/next_js/interactive_helpers/commandHandler.js +310 -0
- package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -0
- package/build/map/next_js/interactive_helpers/commandHelpers.js +245 -0
- package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -0
- package/build/map/next_js/interactive_helpers/esqueryGen.js +370 -0
- package/build/map/next_js/interactive_helpers/esqueryGen.js.map +1 -0
- package/build/map/next_js/interactive_helpers/helpMenu.js +12 -0
- package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -0
- package/build/map/next_js/interactive_helpers/inputPatch.js +207 -0
- package/build/map/next_js/interactive_helpers/inputPatch.js.map +1 -0
- package/build/map/next_js/interactive_helpers/keybindings.js +90 -0
- package/build/map/next_js/interactive_helpers/keybindings.js.map +1 -0
- package/build/map/next_js/interactive_helpers/printer.js +23 -0
- package/build/map/next_js/interactive_helpers/printer.js.map +1 -0
- package/build/map/next_js/interactive_helpers/ui.js +88 -0
- package/build/map/next_js/interactive_helpers/ui.js.map +1 -0
- package/build/map/next_js/resolveAxios.js +152 -0
- package/build/map/next_js/resolveAxios.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/astNodeToJsonString.js +64 -0
- package/build/map/next_js/resolveAxiosHelpers/astNodeToJsonString.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +48 -0
- package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +34 -0
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +39 -0
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +312 -0
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +173 -0
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +261 -0
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js +206 -0
- package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +168 -0
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +121 -0
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +274 -0
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +518 -0
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -0
- package/build/map/next_js/resolveAxiosHelpers/traceBody.js +913 -0
- package/build/map/next_js/resolveAxiosHelpers/traceBody.js.map +1 -0
- package/build/map/next_js/resolveFetch.js +533 -0
- package/build/map/next_js/resolveFetch.js.map +1 -0
- package/build/map/next_js/resolveNewRequest.js +749 -0
- package/build/map/next_js/resolveNewRequest.js.map +1 -0
- package/build/map/next_js/resolveServerActions.js +449 -0
- package/build/map/next_js/resolveServerActions.js.map +1 -0
- package/build/map/next_js/utils.js +1600 -0
- package/build/map/next_js/utils.js.map +1 -0
- package/build/map/react_js/getReactConnections.js +303 -0
- package/build/map/react_js/getReactConnections.js.map +1 -0
- package/build/map/react_js/interactive.js +4 -0
- package/build/map/react_js/interactive.js.map +1 -0
- package/build/map/react_js/react_resolveFetch.js +6 -0
- package/build/map/react_js/react_resolveFetch.js.map +1 -0
- package/build/map/svelte_js/interactive.js +58 -0
- package/build/map/svelte_js/interactive.js.map +1 -0
- package/build/map/svelte_js/interactive_helpers/commandHandler.js +4 -0
- package/build/map/svelte_js/interactive_helpers/commandHandler.js.map +1 -0
- package/build/map/vue_js/bodyResolver.js +477 -0
- package/build/map/vue_js/bodyResolver.js.map +1 -0
- package/build/map/vue_js/crossFileResolver.js +438 -0
- package/build/map/vue_js/crossFileResolver.js.map +1 -0
- package/build/map/vue_js/getViteConnections.js +343 -0
- package/build/map/vue_js/getViteConnections.js.map +1 -0
- package/build/map/vue_js/interactive.js +67 -0
- package/build/map/vue_js/interactive.js.map +1 -0
- package/build/map/vue_js/interactive_helpers/commandHandler.js +307 -0
- package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -0
- package/build/map/vue_js/interactive_helpers/commandHelpers.js +39 -0
- package/build/map/vue_js/interactive_helpers/commandHelpers.js.map +1 -0
- package/build/map/vue_js/interactive_helpers/helpMenu.js +12 -0
- package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -0
- package/build/map/vue_js/taint_utils.js +621 -0
- package/build/map/vue_js/taint_utils.js.map +1 -0
- package/build/map/vue_js/vue_resolveFetch.js +416 -0
- package/build/map/vue_js/vue_resolveFetch.js.map +1 -0
- package/build/map/vue_js/vue_resolveHttpClient.js +738 -0
- package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -0
- package/build/map/vue_js/vue_resolveXhr.js +282 -0
- package/build/map/vue_js/vue_resolveXhr.js.map +1 -0
- package/build/mcp/chatOneShot.js +101 -0
- package/build/mcp/chatOneShot.js.map +1 -0
- package/build/mcp/claudeCodeCreds.js +150 -0
- package/build/mcp/claudeCodeCreds.js.map +1 -0
- package/build/mcp/cli.js +372 -0
- package/build/mcp/cli.js.map +1 -0
- package/build/mcp/commands.js +227 -0
- package/build/mcp/commands.js.map +1 -0
- package/build/mcp/config.js +68 -0
- package/build/mcp/config.js.map +1 -0
- package/build/mcp/index.js +50 -0
- package/build/mcp/index.js.map +1 -0
- package/build/mcp/intent.js +204 -0
- package/build/mcp/intent.js.map +1 -0
- package/build/mcp/jobs.js +199 -0
- package/build/mcp/jobs.js.map +1 -0
- package/build/mcp/mcpServer.js +241 -0
- package/build/mcp/mcpServer.js.map +1 -0
- package/build/mcp/providers.js +170 -0
- package/build/mcp/providers.js.map +1 -0
- package/build/mcp/skills.js +115 -0
- package/build/mcp/skills.js.map +1 -0
- package/build/mcp/tools.js +185 -0
- package/build/mcp/tools.js.map +1 -0
- package/build/refactor/index.js +85 -0
- package/build/refactor/index.js.map +1 -0
- package/build/refactor/next/index.js +109 -0
- package/build/refactor/next/index.js.map +1 -0
- package/build/refactor/react/index.js +636 -0
- package/build/refactor/react/index.js.map +1 -0
- package/build/report/index.js +68 -0
- package/build/report/index.js.map +1 -0
- package/build/report/utility/dataTables/genDataTablesPage.js +158 -0
- package/build/report/utility/dataTables/genDataTablesPage.js.map +1 -0
- package/build/report/utility/genHtml.js +516 -0
- package/build/report/utility/genHtml.js.map +1 -0
- package/build/report/utility/initReportDb.js +96 -0
- package/build/report/utility/initReportDb.js.map +1 -0
- package/build/report/utility/markdownGen/addAnalyze.js +53 -0
- package/build/report/utility/markdownGen/addAnalyze.js.map +1 -0
- package/build/report/utility/markdownGen/addMappedJson.js +33 -0
- package/build/report/utility/markdownGen/addMappedJson.js.map +1 -0
- package/build/report/utility/populateDb/populateAnalysisFindings.js +31 -0
- package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -0
- package/build/report/utility/populateDb/populateEndpoints.js +50 -0
- package/build/report/utility/populateDb/populateEndpoints.js.map +1 -0
- package/build/report/utility/populateDb/populateMappedJson.js +31 -0
- package/build/report/utility/populateDb/populateMappedJson.js.map +1 -0
- package/build/report/utility/populateDb/populateMappedOpenapi.js +49 -0
- package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -0
- package/build/run/index.js +446 -0
- package/build/run/index.js.map +1 -0
- package/build/run/interruptHandler.js +93 -0
- package/build/run/interruptHandler.js.map +1 -0
- package/build/strings/index.js +239 -0
- package/build/strings/index.js.map +1 -0
- package/build/strings/openapi.js +63 -0
- package/build/strings/openapi.js.map +1 -0
- package/build/strings/permutate.js +62 -0
- package/build/strings/permutate.js.map +1 -0
- package/build/strings/secrets.js +102 -0
- package/build/strings/secrets.js.map +1 -0
- package/build/utility/ai.js +97 -0
- package/build/utility/ai.js.map +1 -0
- package/build/utility/configureSandbox.js +14 -0
- package/build/utility/configureSandbox.js.map +1 -0
- package/build/utility/globals.js +322 -0
- package/build/utility/globals.js.map +1 -0
- package/build/utility/interfaces.js +2 -0
- package/build/utility/interfaces.js.map +1 -0
- package/build/utility/makeReq.js +448 -0
- package/build/utility/makeReq.js.map +1 -0
- package/build/utility/openapiGenerator.js +254 -0
- package/build/utility/openapiGenerator.js.map +1 -0
- package/build/utility/postmanGenerator.js +216 -0
- package/build/utility/postmanGenerator.js.map +1 -0
- package/build/utility/progressLog.js +50 -0
- package/build/utility/progressLog.js.map +1 -0
- package/build/utility/puppeteerInstance.js +5 -0
- package/build/utility/puppeteerInstance.js.map +1 -0
- package/build/utility/replaceUrlPlaceholders.js +48 -0
- package/build/utility/replaceUrlPlaceholders.js.map +1 -0
- package/build/utility/resolvePath.js +44 -0
- package/build/utility/resolvePath.js.map +1 -0
- package/build/utility/runSandboxed.js +42 -0
- package/build/utility/runSandboxed.js.map +1 -0
- package/build/utility/urlUtils.js +21 -0
- package/build/utility/urlUtils.js.map +1 -0
- package/contributing/nextjs.md +410 -0
- package/package.json +75 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import { APIGatewayClient, CreateRestApiCommand, DeleteRestApiCommand } from "@aws-sdk/client-api-gateway";
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import checkFeasibility from "./checkFeasibility.js";
|
|
14
|
+
/**
|
|
15
|
+
* Selects a random AWS region from the available API Gateway regions.
|
|
16
|
+
*
|
|
17
|
+
* @returns A randomly selected AWS region identifier
|
|
18
|
+
*/
|
|
19
|
+
const randomRegion = () => {
|
|
20
|
+
const apiGatewayRegions = [
|
|
21
|
+
"us-east-2", // US East (Ohio)
|
|
22
|
+
"us-east-1", // US East (N. Virginia)
|
|
23
|
+
"us-west-1", // US West (N. California)
|
|
24
|
+
"us-west-2", // US West (Oregon)
|
|
25
|
+
"af-south-1", // Africa (Cape Town)
|
|
26
|
+
"ap-east-1", // Asia Pacific (Hong Kong)
|
|
27
|
+
"ap-south-2", // Asia Pacific (Hyderabad)
|
|
28
|
+
"ap-southeast-3", // Asia Pacific (Jakarta)
|
|
29
|
+
"ap-southeast-5", // Asia Pacific (Malaysia)
|
|
30
|
+
"ap-southeast-4", // Asia Pacific (Melbourne)
|
|
31
|
+
"ap-south-1", // Asia Pacific (Mumbai)
|
|
32
|
+
"ap-northeast-3", // Asia Pacific (Osaka)
|
|
33
|
+
"ap-northeast-2", // Asia Pacific (Seoul)
|
|
34
|
+
"ap-southeast-1", // Asia Pacific (Singapore)
|
|
35
|
+
"ap-southeast-2", // Asia Pacific (Sydney)
|
|
36
|
+
"ap-east-2", // Asia Pacific (Taipei)
|
|
37
|
+
"ap-southeast-7", // Asia Pacific (Thailand)
|
|
38
|
+
"ap-northeast-1", // Asia Pacific (Tokyo)
|
|
39
|
+
"ca-central-1", // Canada (Central)
|
|
40
|
+
"ca-west-1", // Canada West (Calgary)
|
|
41
|
+
"eu-central-1", // Europe (Frankfurt)
|
|
42
|
+
"eu-west-1", // Europe (Ireland)
|
|
43
|
+
"eu-west-2", // Europe (London)
|
|
44
|
+
"eu-south-1", // Europe (Milan)
|
|
45
|
+
"eu-west-3", // Europe (Paris)
|
|
46
|
+
"eu-south-2", // Europe (Spain)
|
|
47
|
+
"eu-north-1", // Europe (Stockholm)
|
|
48
|
+
"eu-central-2", // Europe (Zurich)
|
|
49
|
+
"il-central-1", // Israel (Tel Aviv)
|
|
50
|
+
"mx-central-1", // Mexico (Central)
|
|
51
|
+
"me-south-1", // Middle East (Bahrain)
|
|
52
|
+
"me-central-1", // Middle East (UAE)
|
|
53
|
+
"sa-east-1", // South America (São Paulo)
|
|
54
|
+
];
|
|
55
|
+
return apiGatewayRegions[Math.floor(Math.random() * apiGatewayRegions.length)];
|
|
56
|
+
};
|
|
57
|
+
let aws_access_key;
|
|
58
|
+
let aws_secret_key;
|
|
59
|
+
let region;
|
|
60
|
+
let configFile = "";
|
|
61
|
+
/**
|
|
62
|
+
* Utility function to pause execution for a specified duration.
|
|
63
|
+
*
|
|
64
|
+
* @param ms - Number of milliseconds to sleep
|
|
65
|
+
* @returns Promise that resolves after the specified delay
|
|
66
|
+
*/
|
|
67
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
68
|
+
/**
|
|
69
|
+
* Create a new API Gateway.
|
|
70
|
+
*
|
|
71
|
+
* @async
|
|
72
|
+
* @returns {Promise<void>}
|
|
73
|
+
*/
|
|
74
|
+
const createGateway = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
|
+
console.log(chalk.cyan("[i] Creating API Gateway"));
|
|
76
|
+
const client = new APIGatewayClient({
|
|
77
|
+
region,
|
|
78
|
+
credentials: {
|
|
79
|
+
accessKeyId: aws_access_key,
|
|
80
|
+
secretAccessKey: aws_secret_key,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const apigw_created_at = Date.now();
|
|
84
|
+
const apigw_name = `js_recon-${apigw_created_at}-${Math.floor(Math.random() * 1000)}`;
|
|
85
|
+
const command = new CreateRestApiCommand({
|
|
86
|
+
name: apigw_name,
|
|
87
|
+
description: `API Gateway for JS Recon created at ${new Intl.DateTimeFormat("en-US", {
|
|
88
|
+
year: "numeric",
|
|
89
|
+
month: "long",
|
|
90
|
+
day: "2-digit",
|
|
91
|
+
hour: "2-digit",
|
|
92
|
+
minute: "2-digit",
|
|
93
|
+
second: "2-digit",
|
|
94
|
+
timeZoneName: "short",
|
|
95
|
+
}).format(apigw_created_at)}`,
|
|
96
|
+
endpointConfiguration: {
|
|
97
|
+
ipAddressType: "dualstack",
|
|
98
|
+
types: ["REGIONAL"],
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
const response = yield client.send(command);
|
|
102
|
+
yield sleep(3000);
|
|
103
|
+
console.log(chalk.green(`[✓] Created API Gateway`));
|
|
104
|
+
console.log(chalk.bgGreen("ID:"), chalk.green(response.id));
|
|
105
|
+
console.log(chalk.bgGreen("Name:"), chalk.green(apigw_name));
|
|
106
|
+
console.log(chalk.bgGreen("Region:"), chalk.green(region));
|
|
107
|
+
// load the config file if any. Else, create a new one
|
|
108
|
+
let config = {};
|
|
109
|
+
try {
|
|
110
|
+
config = JSON.parse(fs.readFileSync(configFile, "utf8"));
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
config = {};
|
|
114
|
+
}
|
|
115
|
+
config[apigw_name] = {
|
|
116
|
+
id: response.id,
|
|
117
|
+
name: apigw_name,
|
|
118
|
+
description: response.description,
|
|
119
|
+
created_at: apigw_created_at,
|
|
120
|
+
region: region,
|
|
121
|
+
access_key: aws_access_key,
|
|
122
|
+
secret_key: aws_secret_key,
|
|
123
|
+
};
|
|
124
|
+
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
125
|
+
console.log(chalk.green(`[✓] Config saved to ${configFile}`));
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Destroy an API Gateway.
|
|
129
|
+
*
|
|
130
|
+
* @async
|
|
131
|
+
* @param {string} id - The ID of the API Gateway to destroy.
|
|
132
|
+
* @returns {Promise<void>}
|
|
133
|
+
*/
|
|
134
|
+
const destroyGateway = (id) => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
+
console.log(chalk.cyan("[i] Destroying API Gateway"));
|
|
136
|
+
if (!id) {
|
|
137
|
+
console.error(chalk.red("[!] Please provide an API Gateway ID"));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// read the config file
|
|
141
|
+
let config = JSON.parse(fs.readFileSync(configFile, "utf8"));
|
|
142
|
+
// get the name of the api gateway
|
|
143
|
+
let name = Object.keys(config).find((key) => config[key].id === id);
|
|
144
|
+
console.log(chalk.bgGreen("Name:"), chalk.green(name));
|
|
145
|
+
console.log(chalk.bgGreen("ID:"), chalk.green(id));
|
|
146
|
+
console.log(chalk.bgGreen("Region:"), chalk.green(config[name].region));
|
|
147
|
+
region = config[name].region;
|
|
148
|
+
const client = new APIGatewayClient({
|
|
149
|
+
region,
|
|
150
|
+
credentials: {
|
|
151
|
+
accessKeyId: aws_access_key,
|
|
152
|
+
secretAccessKey: aws_secret_key,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
const command = new DeleteRestApiCommand({
|
|
156
|
+
restApiId: id,
|
|
157
|
+
});
|
|
158
|
+
yield client.send(command);
|
|
159
|
+
// remove from the config file
|
|
160
|
+
delete config[name];
|
|
161
|
+
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
162
|
+
yield sleep(30000);
|
|
163
|
+
console.log(chalk.green(`[✓] Destroyed API Gateway: ${id}`));
|
|
164
|
+
});
|
|
165
|
+
/**
|
|
166
|
+
* Destroy all API Gateways.
|
|
167
|
+
*
|
|
168
|
+
* @async
|
|
169
|
+
* @returns {Promise<void>}
|
|
170
|
+
*/
|
|
171
|
+
const destroyAllGateways = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
172
|
+
console.log(chalk.cyan("[i] Destroying all API Gateways"));
|
|
173
|
+
// read the config file
|
|
174
|
+
let config = JSON.parse(fs.readFileSync(configFile, "utf8"));
|
|
175
|
+
// destroy all the gateways
|
|
176
|
+
for (const [key, value] of Object.entries(config)) {
|
|
177
|
+
const client = new APIGatewayClient({
|
|
178
|
+
region: value.region,
|
|
179
|
+
credentials: {
|
|
180
|
+
accessKeyId: aws_access_key,
|
|
181
|
+
secretAccessKey: aws_secret_key,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
console.log(chalk.cyan(`[i] Destroying API Gateway: ${key} : ${value.id} : ${value.region}`));
|
|
185
|
+
const command = new DeleteRestApiCommand({
|
|
186
|
+
restApiId: value.id,
|
|
187
|
+
});
|
|
188
|
+
yield sleep(30000);
|
|
189
|
+
yield client.send(command);
|
|
190
|
+
console.log(chalk.green(`[✓] Destroyed API Gateway: ${key} : ${value.id} : ${value.region}`));
|
|
191
|
+
}
|
|
192
|
+
// nullify the config file
|
|
193
|
+
fs.writeFileSync(configFile, JSON.stringify({}, null, 2));
|
|
194
|
+
console.log(chalk.green("[✓] Destroyed all API Gateways"));
|
|
195
|
+
});
|
|
196
|
+
/**
|
|
197
|
+
* List all API Gateways.
|
|
198
|
+
*
|
|
199
|
+
* @async
|
|
200
|
+
* @returns {Promise<void>}
|
|
201
|
+
*/
|
|
202
|
+
const listGateways = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
203
|
+
console.log(chalk.cyan("[i] Listing all API Gateways"));
|
|
204
|
+
// read the config file, and list these
|
|
205
|
+
// check if the config file exists
|
|
206
|
+
if (!fs.existsSync(configFile)) {
|
|
207
|
+
console.error(chalk.red("[!] Config file does not exist"));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const config = JSON.parse(fs.readFileSync(configFile, "utf8"));
|
|
211
|
+
// if list is empty
|
|
212
|
+
if (Object.keys(config).length === 0) {
|
|
213
|
+
console.error(chalk.red("[!] No API Gateways found"));
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
console.log(chalk.green("[✓] List of API Gateways"));
|
|
217
|
+
for (const [key, value] of Object.entries(config)) {
|
|
218
|
+
console.log(chalk.bgGreen("Name:"), chalk.green(key));
|
|
219
|
+
console.log(chalk.bgGreen("ID:"), chalk.green(value.id));
|
|
220
|
+
console.log(chalk.bgGreen("Region:"), chalk.green(value.region));
|
|
221
|
+
console.log("\n");
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
/**
|
|
225
|
+
* Main function for API Gateway.
|
|
226
|
+
*
|
|
227
|
+
* @async
|
|
228
|
+
* @param {boolean} initInput - Whether to initialize the API Gateway.
|
|
229
|
+
* @param {string} destroyInput - The ID of the API Gateway to destroy.
|
|
230
|
+
* @param {boolean} destroyAllInput - Whether to destroy all API Gateways.
|
|
231
|
+
* @param {boolean} listInput - Whether to list all API Gateways.
|
|
232
|
+
* @param {string} regionInput - The region to use.
|
|
233
|
+
* @param {string} accessKey - The access key to use.
|
|
234
|
+
* @param {string} secretKey - The secret key to use.
|
|
235
|
+
* @param {string} configInput - The config file to use.
|
|
236
|
+
* @param {boolean} feasibilityInput - Whether to check feasibility.
|
|
237
|
+
* @param {string} feasibilityUrlInput - The URL to check feasibility for.
|
|
238
|
+
* @returns {Promise<void>}
|
|
239
|
+
*/
|
|
240
|
+
const apiGateway = (initInput, destroyInput, destroyAllInput, listInput, regionInput, accessKey, secretKey, configInput, feasibilityInput, feasibilityUrlInput) => __awaiter(void 0, void 0, void 0, function* () {
|
|
241
|
+
console.log(chalk.cyan("[i] Loading 'API Gateway' module"));
|
|
242
|
+
// if feasibility is true, check feasibility
|
|
243
|
+
if (feasibilityInput) {
|
|
244
|
+
if (!feasibilityUrlInput) {
|
|
245
|
+
console.error(chalk.red("[!] Please provide a URL to check feasibility of"));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
yield checkFeasibility(feasibilityUrlInput);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// configure the access and secret key
|
|
252
|
+
aws_access_key = accessKey || process.env.AWS_ACCESS_KEY_ID || undefined;
|
|
253
|
+
aws_secret_key = secretKey || process.env.AWS_SECRET_ACCESS_KEY || undefined;
|
|
254
|
+
region = regionInput || randomRegion();
|
|
255
|
+
configFile = configInput || "config.json";
|
|
256
|
+
if (!aws_access_key || !aws_secret_key) {
|
|
257
|
+
console.error(chalk.red("[!] AWS Access Key or Secret Key not found. Run with -h to see help"));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
console.log(chalk.cyan(`[i] Using region: ${region}`));
|
|
261
|
+
/**
|
|
262
|
+
* Masks an API key for secure display by showing only first and last 4 characters.
|
|
263
|
+
*
|
|
264
|
+
* @param key - The API key to mask
|
|
265
|
+
* @returns Masked version of the key
|
|
266
|
+
*/
|
|
267
|
+
const keyMask = (key) => {
|
|
268
|
+
if (key.length < 6)
|
|
269
|
+
return key;
|
|
270
|
+
return key.slice(0, 4) + "..." + key.slice(-4);
|
|
271
|
+
};
|
|
272
|
+
console.log(chalk.cyan(`[i] Using access key: ${keyMask(aws_access_key)}`));
|
|
273
|
+
// create a new API gateway
|
|
274
|
+
if (initInput) {
|
|
275
|
+
yield createGateway();
|
|
276
|
+
}
|
|
277
|
+
else if (destroyInput) {
|
|
278
|
+
yield destroyGateway(destroyInput);
|
|
279
|
+
}
|
|
280
|
+
else if (destroyAllInput) {
|
|
281
|
+
yield destroyAllGateways();
|
|
282
|
+
}
|
|
283
|
+
else if (listInput) {
|
|
284
|
+
yield listGateways();
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
console.error(chalk.red("[!] Please provide a valid action (-i/--init or -d/--destroy or --destroy-all)"));
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
export default apiGateway;
|
|
291
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api_gateway/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import iterate_n_store from "./utility/iterate_n_store.js";
|
|
13
|
+
/**
|
|
14
|
+
* Generates a JSON report from a list of URLs.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} url - The base URL to resolve relative URLs against
|
|
17
|
+
* @param {string[]} hrefs - The list of URLs to iterate over
|
|
18
|
+
* @param {string} output - The output file path
|
|
19
|
+
* @returns {Promise<string>} - A promise that resolves to the generated JSON report
|
|
20
|
+
*/
|
|
21
|
+
const gen_json = (url, hrefs, output) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
// iterate over hrefs
|
|
23
|
+
const result = yield iterate_n_store(url, hrefs);
|
|
24
|
+
const finalJSON = JSON.stringify(result, null, 2);
|
|
25
|
+
fs.writeFileSync(`${output}.json`, finalJSON);
|
|
26
|
+
console.log(chalk.green(`[✓] Generated JSON report at ${output}.json`));
|
|
27
|
+
return finalJSON;
|
|
28
|
+
});
|
|
29
|
+
export default gen_json;
|
|
30
|
+
//# sourceMappingURL=gen_json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen_json.js","sourceRoot":"","sources":["../../../src/endpoints/gen_report/gen_json.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,eAAe,MAAM,8BAA8B,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,QAAQ,GAAG,CAAO,GAAW,EAAE,KAAe,EAAE,MAAc,EAAE,EAAE;IACpE,qBAAqB;IACrB,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClD,EAAE,CAAC,aAAa,CAAC,GAAG,MAAM,OAAO,EAAE,SAAS,CAAC,CAAC;IAE9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gCAAgC,MAAM,OAAO,CAAC,CAAC,CAAC;IACxE,OAAO,SAAS,CAAC;AACrB,CAAC,CAAA,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import resolvePath from "../../../utility/resolvePath.js";
|
|
11
|
+
/**
|
|
12
|
+
* Iterate over a list of URLs and store them in a nested object structure.
|
|
13
|
+
*
|
|
14
|
+
* For each URL, the function will:
|
|
15
|
+
* - Ignore URLs that start with "mailto:" or "tel:"
|
|
16
|
+
* - Resolve relative URLs against the given base URL
|
|
17
|
+
* - Parse the URL and extract the origin and pathname
|
|
18
|
+
* - Create a nested object structure with the origin as the top-level key
|
|
19
|
+
* - Create a nested object structure with the pathname as the key
|
|
20
|
+
* - Ensure that every origin has a root path ("/") inserted
|
|
21
|
+
*
|
|
22
|
+
* The resulting object structure will have the following shape:
|
|
23
|
+
* - { origin: { /path/to/resource: {}, ... } }
|
|
24
|
+
*
|
|
25
|
+
* @param {string} baseUrl - The base URL to resolve relative URLs against
|
|
26
|
+
* @param {string[]} urls - The list of URLs to iterate over
|
|
27
|
+
* @returns {Promise<object>} - A promise that resolves to the nested object structure
|
|
28
|
+
*/
|
|
29
|
+
const iterate_n_store = (baseUrl, urls) => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
let result = {};
|
|
31
|
+
for (let url of urls) {
|
|
32
|
+
if (url.startsWith("mailto:") || url.startsWith("tel:")) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (url.startsWith("/")) {
|
|
36
|
+
url = resolvePath(baseUrl, url);
|
|
37
|
+
}
|
|
38
|
+
// Parse the URL once and extract the bits we need
|
|
39
|
+
const { origin, pathname } = new URL(url);
|
|
40
|
+
// Ensure we have a container object for this origin
|
|
41
|
+
if (!result[origin]) {
|
|
42
|
+
result[origin] = {};
|
|
43
|
+
}
|
|
44
|
+
// Always insert the root path for this origin
|
|
45
|
+
if (!result[origin]["/"]) {
|
|
46
|
+
result[origin]["/"] = {};
|
|
47
|
+
}
|
|
48
|
+
// Normalise the pathname – strip leading/trailing slashes and split into segments
|
|
49
|
+
const segments = pathname === "/" ? [] : pathname.replace(/^\/|\/$/g, "").split("/");
|
|
50
|
+
let cumulativePath = ""; // will build up like "/app", "/app/dashboard"
|
|
51
|
+
let currentNode = result[origin];
|
|
52
|
+
for (const segment of segments) {
|
|
53
|
+
cumulativePath += `/${segment}`;
|
|
54
|
+
if (!currentNode[cumulativePath]) {
|
|
55
|
+
currentNode[cumulativePath] = {};
|
|
56
|
+
}
|
|
57
|
+
// descend into the newly created / already existing child
|
|
58
|
+
currentNode = currentNode[cumulativePath];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
});
|
|
63
|
+
export default iterate_n_store;
|
|
64
|
+
//# sourceMappingURL=iterate_n_store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterate_n_store.js","sourceRoot":"","sources":["../../../../src/endpoints/gen_report/utility/iterate_n_store.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,eAAe,GAAG,CAAO,OAAe,EAAE,IAAc,EAAE,EAAE;IAC9D,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACnB,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACtD,SAAS;QACb,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACpC,CAAC;QAED,kDAAkD;QAClD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAE1C,oDAAoD;QACpD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAClB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACxB,CAAC;QAED,8CAA8C;QAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QAC7B,CAAC;QAED,kFAAkF;QAClF,MAAM,QAAQ,GAAG,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAErF,IAAI,cAAc,GAAG,EAAE,CAAC,CAAC,8CAA8C;QACvE,IAAI,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAEjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,cAAc,IAAI,IAAI,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC/B,WAAW,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC;YACrC,CAAC;YACD,0DAA0D;YAC1D,WAAW,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;QAC9C,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAA,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
// Next.JS
|
|
13
|
+
import client_subsequentRequests from "./next_js/client_subsequentRequests.js";
|
|
14
|
+
import client_jsFilesHref from "./next_js/client_jsFilesHref.js";
|
|
15
|
+
import client_jsonParse from "./next_js/client_jsonParse.js";
|
|
16
|
+
import client_mappedJsonFile from "./next_js/client_mappedJsonFile.js";
|
|
17
|
+
// Report Generation
|
|
18
|
+
import gen_json from "./gen_report/gen_json.js";
|
|
19
|
+
/** Available technology stacks for endpoint extraction */
|
|
20
|
+
const techs = ["Next.JS (next)"];
|
|
21
|
+
/** Supported output formats for endpoint results */
|
|
22
|
+
const outputFormats = ["json"];
|
|
23
|
+
/**
|
|
24
|
+
* Extracts client-side endpoints from JavaScript applications.
|
|
25
|
+
*
|
|
26
|
+
* Analyzes JavaScript files and mapped data to discover client-side routes,
|
|
27
|
+
* API endpoints, and other paths used by the application. Supports different
|
|
28
|
+
* technology stacks and output formats.
|
|
29
|
+
*
|
|
30
|
+
* @param url - Base URL for resolving relative paths
|
|
31
|
+
* @param directory - Directory containing JavaScript files to analyze
|
|
32
|
+
* @param output - Output filename (without extension) for results
|
|
33
|
+
* @param outputFormat - Array of output formats to generate (e.g., ['json'])
|
|
34
|
+
* @param tech - Technology stack identifier (e.g., 'next' for Next.js)
|
|
35
|
+
* @param list - Whether to list available technologies instead of running extraction
|
|
36
|
+
* @param mappedJsonFile - Path to mapped JSON file for additional analysis
|
|
37
|
+
* @returns Promise that resolves when endpoint extraction is complete
|
|
38
|
+
*/
|
|
39
|
+
const endpoints = (url, directory, output, outputFormat, tech, list, mappedJsonFile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
console.log(chalk.cyan("[i] Loading endpoints module"));
|
|
41
|
+
// list available technologies
|
|
42
|
+
if (list) {
|
|
43
|
+
console.log(chalk.cyan("[i] Listing available technologies"));
|
|
44
|
+
for (const tech of techs) {
|
|
45
|
+
console.log(chalk.greenBright(`- ${tech}`));
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// iterate over the output format, and match it with the available output formats
|
|
50
|
+
for (const format of outputFormat) {
|
|
51
|
+
if (!outputFormats.includes(format)) {
|
|
52
|
+
console.error(chalk.red("[!] Invalid output format"));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// check if the technology is present
|
|
57
|
+
if (!tech) {
|
|
58
|
+
console.error(chalk.red("[!] Please provide a technology"));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// check if the output file is present
|
|
62
|
+
if (!output) {
|
|
63
|
+
console.error(chalk.red("[!] Please provide an output file"));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// check if the url is present
|
|
67
|
+
if (!url) {
|
|
68
|
+
console.error(chalk.red("[!] Please provide a URL"));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
console.log(chalk.cyan("[i] Extracting endpoints"));
|
|
72
|
+
if (tech === "next") {
|
|
73
|
+
console.log(chalk.cyan("[i] Checking for client-side paths for Next.JS"));
|
|
74
|
+
// var to store all the paths found
|
|
75
|
+
let final_client_side = [];
|
|
76
|
+
if (directory) {
|
|
77
|
+
const subsequentRequestsDir = directory + "/___subsequent_requests";
|
|
78
|
+
if (!fs.existsSync(subsequentRequestsDir)) {
|
|
79
|
+
console.error(chalk.yellow("[!] Directory containing subsequent requests does not exist — skipping subsequent requests extraction"));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const client_subsequentRequestsResult = yield client_subsequentRequests(subsequentRequestsDir, url);
|
|
83
|
+
final_client_side.push(...client_subsequentRequestsResult);
|
|
84
|
+
}
|
|
85
|
+
const client_jsFilesHrefResult = yield client_jsFilesHref(directory);
|
|
86
|
+
final_client_side.push(...client_jsFilesHrefResult);
|
|
87
|
+
const client_jsonParseResult = yield client_jsonParse(directory);
|
|
88
|
+
final_client_side.push(...client_jsonParseResult);
|
|
89
|
+
}
|
|
90
|
+
// now, use the mapped JSON file to find more paths
|
|
91
|
+
if (mappedJsonFile) {
|
|
92
|
+
const client_mappedJsonFileResult = yield client_mappedJsonFile(mappedJsonFile);
|
|
93
|
+
final_client_side.push(...client_mappedJsonFileResult);
|
|
94
|
+
}
|
|
95
|
+
if (outputFormat.includes("json")) {
|
|
96
|
+
const gen_jsonResult = yield gen_json(url, final_client_side, output);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
export default endpoints;
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/endpoints/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import parser from "@babel/parser";
|
|
13
|
+
import _traverse from "@babel/traverse";
|
|
14
|
+
import chalk from "chalk";
|
|
15
|
+
const traverse = _traverse.default;
|
|
16
|
+
/**
|
|
17
|
+
* Searches for href attributes in JavaScript files to discover client-side paths.
|
|
18
|
+
*
|
|
19
|
+
* Parses JavaScript files using AST traversal to find object properties with 'href' keys
|
|
20
|
+
* and extracts their values, which typically represent client-side routes or URLs.
|
|
21
|
+
* Handles various patterns including string literals and concatenation calls.
|
|
22
|
+
*
|
|
23
|
+
* @param directory - The directory path containing JavaScript files to analyze
|
|
24
|
+
* @returns Promise that resolves to an array of discovered paths/URLs
|
|
25
|
+
*/
|
|
26
|
+
const client_jsFilesHref = (directory) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
console.log(chalk.cyan("[i] Searching for `href` in the JS chunks"));
|
|
28
|
+
let discoveredPaths = [];
|
|
29
|
+
// index all the files in the directory
|
|
30
|
+
let files;
|
|
31
|
+
files = fs.readdirSync(directory, { recursive: true });
|
|
32
|
+
// filter out the directories
|
|
33
|
+
files = files.filter((file) => !fs.statSync(path.join(directory, file)).isDirectory());
|
|
34
|
+
// filter out the subsequent requests files
|
|
35
|
+
files = files.filter((file) => !file.startsWith("___subsequent_requests"));
|
|
36
|
+
for (const file of files) {
|
|
37
|
+
const code = fs.readFileSync(path.join(directory, file), "utf8");
|
|
38
|
+
// parse the code with ast
|
|
39
|
+
let ast;
|
|
40
|
+
try {
|
|
41
|
+
ast = parser.parse(code, {
|
|
42
|
+
sourceType: "unambiguous",
|
|
43
|
+
plugins: ["jsx", "typescript"],
|
|
44
|
+
errorRecovery: true,
|
|
45
|
+
});
|
|
46
|
+
traverse(ast, {
|
|
47
|
+
ObjectProperty(path) {
|
|
48
|
+
var _a;
|
|
49
|
+
const keyNode = path.node.key;
|
|
50
|
+
let keyName;
|
|
51
|
+
if (keyNode.type === "Identifier") {
|
|
52
|
+
keyName = keyNode.name;
|
|
53
|
+
}
|
|
54
|
+
else if (keyNode.type === "StringLiteral") {
|
|
55
|
+
keyName = keyNode.value;
|
|
56
|
+
}
|
|
57
|
+
if (keyName !== "href") {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const valueNode = path.node.value;
|
|
61
|
+
let hrefValue = null;
|
|
62
|
+
if (valueNode.type === "StringLiteral") {
|
|
63
|
+
hrefValue = valueNode.value;
|
|
64
|
+
}
|
|
65
|
+
else if (valueNode.type === "CallExpression" &&
|
|
66
|
+
valueNode.callee.type === "MemberExpression" &&
|
|
67
|
+
valueNode.callee.property.type === "Identifier" &&
|
|
68
|
+
valueNode.callee.property.name === "concat") {
|
|
69
|
+
// It's a .concat() call.
|
|
70
|
+
// Let's find string literal arguments that look like paths.
|
|
71
|
+
const pathArg = valueNode.arguments.find((arg) => arg.type === "StringLiteral" &&
|
|
72
|
+
(arg.value.startsWith("/") || arg.value.startsWith("http")));
|
|
73
|
+
if (pathArg && pathArg.type === "StringLiteral") {
|
|
74
|
+
hrefValue = pathArg.value;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Handle fallback case: e.g. "".concat(s || "/docs/guides")
|
|
78
|
+
const logicalExprArg = valueNode.arguments.find((arg) => arg.type === "LogicalExpression" && arg.operator === "||");
|
|
79
|
+
if (logicalExprArg && ((_a = logicalExprArg.right) === null || _a === void 0 ? void 0 : _a.type) === "StringLiteral") {
|
|
80
|
+
hrefValue = logicalExprArg.right.value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (hrefValue) {
|
|
85
|
+
const isPath = hrefValue.startsWith("/") || hrefValue.startsWith("http");
|
|
86
|
+
if (isPath && !discoveredPaths.includes(hrefValue)) {
|
|
87
|
+
discoveredPaths.push(hrefValue);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return discoveredPaths;
|
|
98
|
+
});
|
|
99
|
+
export default client_jsFilesHref;
|
|
100
|
+
//# sourceMappingURL=client_jsFilesHref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client_jsFilesHref.js","sourceRoot":"","sources":["../../../src/endpoints/next_js/client_jsFilesHref.ts"],"names":[],"mappings":"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"}
|