@js-recon/js-recon 1.4.3 → 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.
- package/.claude-sync/sync.sh +1 -1
- package/.github/workflows/build-and-prettify.yaml +55 -25
- package/.github/workflows/codeql.yml +33 -0
- package/.github/workflows/exploit-smoke-test.yaml +160 -0
- package/.github/workflows/framework-detection-smoke-test.yaml +135 -0
- package/.github/workflows/plumber.yml +20 -0
- package/.github/workflows/promote-js-recon.yml +5 -3
- package/.github/workflows/publish-js-recon.yml +6 -1
- package/.github/workflows/rules-smoke-test.yaml +15 -7
- package/.nvmrc +1 -0
- package/.plumber.yaml +151 -0
- package/CHANGELOG.md +54 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +1 -0
- package/README.md +55 -2
- package/SECURITY.md +1 -1
- package/build/analyze/engine/astEngine.js +10 -9
- package/build/analyze/engine/astEngine.js.map +1 -1
- package/build/analyze/engine/csMastSEngine.js +6 -6
- package/build/analyze/engine/csMastSEngine.js.map +1 -1
- package/build/analyze/engine/index.js +1 -1
- package/build/analyze/engine/index.js.map +1 -1
- package/build/analyze/engine/requestEngine.js +6 -6
- package/build/analyze/engine/requestEngine.js.map +1 -1
- package/build/analyze/helpers/determineCompatibleVersion.js +70 -0
- package/build/analyze/helpers/determineCompatibleVersion.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +9 -3
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
- package/build/analyze/helpers/initRules.js +42 -24
- package/build/analyze/helpers/initRules.js.map +1 -1
- package/build/analyze/helpers/outputHelper.js +3 -3
- package/build/analyze/helpers/outputHelper.js.map +1 -1
- package/build/analyze/helpers/schemas.js +1 -0
- package/build/analyze/helpers/schemas.js.map +1 -1
- package/build/analyze/helpers/validate.js +9 -5
- package/build/analyze/helpers/validate.js.map +1 -1
- package/build/analyze/index.js +26 -16
- package/build/analyze/index.js.map +1 -1
- package/build/cliProgram.js +710 -0
- package/build/cliProgram.js.map +1 -0
- package/build/completion/index.js +245 -339
- package/build/completion/index.js.map +1 -1
- package/build/completion/introspect.js +17 -0
- package/build/completion/introspect.js.map +1 -0
- package/build/config/applicationConfig.js +494 -0
- package/build/config/applicationConfig.js.map +1 -0
- package/build/cs_mast/index.js +18 -17
- package/build/cs_mast/index.js.map +1 -1
- package/build/endpoints/gen_report/gen_json.js +2 -2
- package/build/endpoints/gen_report/gen_json.js.map +1 -1
- package/build/endpoints/gen_report/utility/iterate_n_store.js +1 -1
- package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -1
- package/build/endpoints/index.js +12 -12
- package/build/endpoints/index.js.map +1 -1
- package/build/endpoints/next_js/client_jsFilesHref.js +3 -3
- package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
- package/build/endpoints/next_js/client_jsonParse.js +4 -4
- package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
- package/build/endpoints/next_js/client_mappedJsonFile.js +6 -6
- package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
- package/build/endpoints/next_js/client_subsequentRequests.js +5 -5
- package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
- package/build/exploit/angular/cve-2026-68945.js +61 -0
- package/build/exploit/angular/cve-2026-68945.js.map +1 -0
- package/build/exploit/index.js +60 -0
- package/build/exploit/index.js.map +1 -0
- package/build/exploit/next/cve-2025-29927.js +65 -0
- package/build/exploit/next/cve-2025-29927.js.map +1 -0
- package/build/exploit/next/cve-2026-64645.js +51 -0
- package/build/exploit/next/cve-2026-64645.js.map +1 -0
- package/build/exploit/nuxt/cve-2026-71315.js +47 -0
- package/build/exploit/nuxt/cve-2026-71315.js.map +1 -0
- package/build/exploit/nuxt/cve-2026-71320.js +114 -0
- package/build/exploit/nuxt/cve-2026-71320.js.map +1 -0
- package/build/exploit/react/cve-2025-55182.js +116 -0
- package/build/exploit/react/cve-2025-55182.js.map +1 -0
- package/build/exploit/registry/cveRegistry.js +115 -0
- package/build/exploit/registry/cveRegistry.js.map +1 -0
- package/build/exploit/types.js +2 -0
- package/build/exploit/types.js.map +1 -0
- package/build/exploit/utility/compareResponses.js +29 -0
- package/build/exploit/utility/compareResponses.js.map +1 -0
- package/build/exploit/utility/outputHelper.js +22 -0
- package/build/exploit/utility/outputHelper.js.map +1 -0
- package/build/exploit/utility/rawRequest.js +54 -0
- package/build/exploit/utility/rawRequest.js.map +1 -0
- package/build/exploit/utility/sandboxRce.js +49 -0
- package/build/exploit/utility/sandboxRce.js.map +1 -0
- package/build/exploit/utility/toEngineOutput.js +28 -0
- package/build/exploit/utility/toEngineOutput.js.map +1 -0
- package/build/exploit/utility/wsClient.js +78 -0
- package/build/exploit/utility/wsClient.js.map +1 -0
- package/build/exploit/vite/cve-2025-30208.js +44 -0
- package/build/exploit/vite/cve-2025-30208.js.map +1 -0
- package/build/exploit/vite/cve-2026-39363.js +60 -0
- package/build/exploit/vite/cve-2026-39363.js.map +1 -0
- package/build/fingerprint/index.js +11 -21
- package/build/fingerprint/index.js.map +1 -1
- package/build/globalConfig.js +2 -2
- package/build/globalConfig.js.map +1 -1
- package/build/index.js +16 -555
- package/build/index.js.map +1 -1
- package/build/lazyLoad/angular/angular_getFromPageSource.js +3 -3
- package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/downloadFilesUtil.js +51 -40
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/downloadQueue.js +154 -50
- package/build/lazyLoad/downloadQueue.js.map +1 -1
- package/build/lazyLoad/downloadResponse.js +113 -0
- package/build/lazyLoad/downloadResponse.js.map +1 -0
- package/build/lazyLoad/generic/generic_crawlPages.js +186 -0
- package/build/lazyLoad/generic/generic_crawlPages.js.map +1 -0
- package/build/lazyLoad/generic/generic_downloadFiles.js +81 -0
- package/build/lazyLoad/generic/generic_downloadFiles.js.map +1 -0
- package/build/lazyLoad/generic/generic_extractLinks.js +79 -0
- package/build/lazyLoad/generic/generic_extractLinks.js.map +1 -0
- package/build/lazyLoad/generic/generic_getScriptTags.js +152 -0
- package/build/lazyLoad/generic/generic_getScriptTags.js.map +1 -0
- package/build/lazyLoad/generic/generic_importMapDiscovery.js +87 -0
- package/build/lazyLoad/generic/generic_importMapDiscovery.js.map +1 -0
- package/build/lazyLoad/generic/generic_resolveScope.js +61 -0
- package/build/lazyLoad/generic/generic_resolveScope.js.map +1 -0
- package/build/lazyLoad/generic/generic_scanAttributesForJs.js +122 -0
- package/build/lazyLoad/generic/generic_scanAttributesForJs.js.map +1 -0
- package/build/lazyLoad/generic/generic_stringsDiscovery.js +103 -0
- package/build/lazyLoad/generic/generic_stringsDiscovery.js.map +1 -0
- package/build/lazyLoad/generic/generic_webpackChunkPaths.js +56 -0
- package/build/lazyLoad/generic/generic_webpackChunkPaths.js.map +1 -0
- package/build/lazyLoad/globals.js +35 -0
- package/build/lazyLoad/globals.js.map +1 -1
- package/build/lazyLoad/index.js +311 -175
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/methodFilter.js +2 -0
- package/build/lazyLoad/methodFilter.js.map +1 -1
- package/build/lazyLoad/next_js/NextJsCrawler.js +39 -14
- package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetJSScript.js +3 -3
- package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +4 -4
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +21 -20
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +100 -99
- package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -1
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +1 -1
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -1
- package/build/lazyLoad/next_js/next_buildId.js +2 -2
- package/build/lazyLoad/next_js/next_buildId.js.map +1 -1
- package/build/lazyLoad/next_js/next_getClientSidePaths.js +2 -2
- package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/next_js/next_parseLayoutJs.js +6 -6
- package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
- package/build/lazyLoad/next_js/next_routerStateForge.js +341 -0
- package/build/lazyLoad/next_js/next_routerStateForge.js.map +1 -0
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +1 -1
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -1
- package/build/lazyLoad/next_js/next_serverActionIdScan.js +77 -0
- package/build/lazyLoad/next_js/next_serverActionIdScan.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js +15 -13
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +2 -2
- package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -3
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +2 -2
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/outputPath.js +92 -0
- package/build/lazyLoad/outputPath.js.map +1 -0
- package/build/lazyLoad/react/react_followImports.js +15 -5
- package/build/lazyLoad/react/react_followImports.js.map +1 -1
- package/build/lazyLoad/react/react_getScriptTags.js +11 -6
- package/build/lazyLoad/react/react_getScriptTags.js.map +1 -1
- package/build/lazyLoad/react/react_sourcemapUrls.js +3 -2
- package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -1
- package/build/lazyLoad/react/react_webpackChunkPaths.js +12 -203
- package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
- package/build/lazyLoad/researchUtils.js +15 -0
- package/build/lazyLoad/researchUtils.js.map +1 -0
- package/build/lazyLoad/shared/webpackChunkParsers.js +218 -0
- package/build/lazyLoad/shared/webpackChunkParsers.js.map +1 -0
- package/build/lazyLoad/stagnation/stagnationMonitor.js +63 -0
- package/build/lazyLoad/stagnation/stagnationMonitor.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js +5 -5
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_getVersionJson.js +2 -2
- package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +6 -6
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +2 -2
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkNuxtJS.js +3 -3
- package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkSvelte.js +0 -1
- package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
- package/build/lazyLoad/techDetect/checkVueJS.js +6 -6
- package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -1
- package/build/lazyLoad/techDetect/index.js +106 -60
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_RuntimeJs.js +20 -15
- package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +10 -5
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +20 -17
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +70 -46
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/vue/vue_jsImports.js +3 -2
- package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js +3 -2
- package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +6 -5
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +10 -21
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js +5 -4
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_stringJsFiles.js +28 -25
- package/build/lazyLoad/vue/vue_stringJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_viteMapDeps.js +8 -2
- package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -1
- package/build/load/index.js +8 -7
- package/build/load/index.js.map +1 -1
- package/build/map/angular_js/getAngularConnections.js +6 -6
- package/build/map/angular_js/getAngularConnections.js.map +1 -1
- package/build/map/graphql/resolveGraphql.js +6 -6
- package/build/map/graphql/resolveGraphql.js.map +1 -1
- package/build/map/index.js +17 -17
- package/build/map/index.js.map +1 -1
- package/build/map/interactive-mode/commandHandler.js +278 -0
- package/build/map/interactive-mode/commandHandler.js.map +1 -0
- package/build/map/interactive-mode/commandHelpers.js +189 -0
- package/build/map/interactive-mode/commandHelpers.js.map +1 -0
- package/build/map/interactive-mode/esqueryGen.js.map +1 -0
- package/build/map/interactive-mode/helpMenu.js +11 -0
- package/build/map/interactive-mode/helpMenu.js.map +1 -0
- package/build/map/interactive-mode/inputPatch.js.map +1 -0
- package/build/map/interactive-mode/interactive.js +71 -0
- package/build/map/interactive-mode/interactive.js.map +1 -0
- package/build/map/interactive-mode/keybindings.js.map +1 -0
- package/build/map/interactive-mode/printer.js.map +1 -0
- package/build/map/interactive-mode/ui.js.map +1 -0
- package/build/map/next_js/getAxiosInstances.js +5 -5
- package/build/map/next_js/getAxiosInstances.js.map +1 -1
- package/build/map/next_js/getExports.js +4 -4
- package/build/map/next_js/getExports.js.map +1 -1
- package/build/map/next_js/getFetchInstances.js +10 -10
- package/build/map/next_js/getFetchInstances.js.map +1 -1
- package/build/map/next_js/getTurbopackConnections.js +8 -8
- package/build/map/next_js/getTurbopackConnections.js.map +1 -1
- package/build/map/next_js/getWebpackConnections.js +27 -16
- package/build/map/next_js/getWebpackConnections.js.map +1 -1
- package/build/map/next_js/interactive.js +3 -65
- package/build/map/next_js/interactive.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHandler.js +38 -290
- package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHelpers.js +0 -184
- package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
- package/build/map/next_js/interactive_helpers/helpMenu.js +2 -10
- package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -1
- package/build/map/next_js/resolveAxios.js +6 -6
- package/build/map/next_js/resolveAxios.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +4 -4
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -2
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +5 -5
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +10 -10
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +13 -9
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +12 -8
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +12 -8
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +11 -11
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +16 -16
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
- package/build/map/next_js/resolveFetch.js +23 -23
- package/build/map/next_js/resolveFetch.js.map +1 -1
- package/build/map/next_js/resolveNewRequest.js +10 -10
- package/build/map/next_js/resolveNewRequest.js.map +1 -1
- package/build/map/next_js/resolveServerActions.js +4 -4
- package/build/map/next_js/resolveServerActions.js.map +1 -1
- package/build/map/next_js/utils.js +8 -2
- package/build/map/next_js/utils.js.map +1 -1
- package/build/map/react_js/getReactConnections.js +21 -14
- package/build/map/react_js/getReactConnections.js.map +1 -1
- package/build/map/svelte_js/interactive.js +3 -54
- package/build/map/svelte_js/interactive.js.map +1 -1
- package/build/map/vue_js/getViteConnections.js +23 -16
- package/build/map/vue_js/getViteConnections.js.map +1 -1
- package/build/map/vue_js/interactive.js +3 -63
- package/build/map/vue_js/interactive.js.map +1 -1
- package/build/map/vue_js/interactive_helpers/commandHandler.js +34 -283
- package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -1
- package/build/map/vue_js/interactive_helpers/helpMenu.js +2 -10
- package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -1
- package/build/map/vue_js/taint_utils.js +1 -1
- package/build/map/vue_js/taint_utils.js.map +1 -1
- package/build/map/vue_js/vue_resolveFetch.js +12 -12
- package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
- package/build/map/vue_js/vue_resolveHttpClient.js +18 -18
- package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
- package/build/map/vue_js/vue_resolveXhr.js +11 -11
- package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
- package/build/mcp/chatOneShot.js +7 -7
- package/build/mcp/chatOneShot.js.map +1 -1
- package/build/mcp/claudeCodeCreds.js +5 -5
- package/build/mcp/claudeCodeCreds.js.map +1 -1
- package/build/mcp/cli.js +36 -35
- package/build/mcp/cli.js.map +1 -1
- package/build/mcp/config.js +4 -4
- package/build/mcp/config.js.map +1 -1
- package/build/mcp/index.js +7 -7
- package/build/mcp/index.js.map +1 -1
- package/build/mcp/mcpServer.js +3 -2
- package/build/mcp/mcpServer.js.map +1 -1
- package/build/mcp/skills.js +1 -0
- package/build/mcp/skills.js.map +1 -1
- package/build/mcp/tools.js +5 -4
- package/build/mcp/tools.js.map +1 -1
- package/build/proxy/checkFeasibility.js +8 -4
- package/build/proxy/checkFeasibility.js.map +1 -1
- package/build/proxy/checkFireWallBlocking.js +23 -13
- package/build/proxy/checkFireWallBlocking.js.map +1 -1
- package/build/proxy/detectBlockedResponse.js +205 -0
- package/build/proxy/detectBlockedResponse.js.map +1 -0
- package/build/proxy/genReq.js +434 -127
- package/build/proxy/genReq.js.map +1 -1
- package/build/proxy/index.js +3 -3
- package/build/proxy/index.js.map +1 -1
- package/build/proxy/oxylabsFallback.js +110 -0
- package/build/proxy/oxylabsFallback.js.map +1 -0
- package/build/proxy/proxyFeasibilityRequest.js +11 -9
- package/build/proxy/proxyFeasibilityRequest.js.map +1 -1
- package/build/refactor/index.js +83 -79
- package/build/refactor/index.js.map +1 -1
- package/build/refactor/next/index.js +69 -26
- package/build/refactor/next/index.js.map +1 -1
- package/build/refactor/next/transform.js +11 -4
- package/build/refactor/next/transform.js.map +1 -1
- package/build/refactor/next/validator.js +7 -7
- package/build/refactor/next/validator.js.map +1 -1
- package/build/refactor/react/index.js +13 -13
- package/build/refactor/react/index.js.map +1 -1
- package/build/refactor/react/validator.js +7 -7
- package/build/refactor/react/validator.js.map +1 -1
- package/build/refactor/react-vite/index.js +3 -3
- package/build/refactor/react-vite/index.js.map +1 -1
- package/build/refactor/remote/hf-client.js +1 -0
- package/build/refactor/remote/hf-client.js.map +1 -1
- package/build/refactor/remote/version-detect.js +12 -12
- package/build/refactor/remote/version-detect.js.map +1 -1
- package/build/refactor/vue/index.js +6 -6
- package/build/refactor/vue/index.js.map +1 -1
- package/build/refactor/vue/vite.js +6 -6
- package/build/refactor/vue/vite.js.map +1 -1
- package/build/report/index.js +30 -8
- package/build/report/index.js.map +1 -1
- package/build/report/swaggerJacker.js +63 -0
- package/build/report/swaggerJacker.js.map +1 -0
- package/build/report/utility/genHtml.js +7 -7
- package/build/report/utility/genHtml.js.map +1 -1
- package/build/report/utility/populateDb/populateAnalysisFindings.js +2 -2
- package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -1
- package/build/report/utility/populateDb/populateEndpoints.js +3 -3
- package/build/report/utility/populateDb/populateEndpoints.js.map +1 -1
- package/build/report/utility/populateDb/populateMappedJson.js +2 -2
- package/build/report/utility/populateDb/populateMappedJson.js.map +1 -1
- package/build/report/utility/populateDb/populateMappedOpenapi.js +3 -3
- package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -1
- package/build/run/bundler-detect.js +45 -9
- package/build/run/bundler-detect.js.map +1 -1
- package/build/run/cancellableStep.js +27 -0
- package/build/run/cancellableStep.js.map +1 -0
- package/build/run/dashboard/dashboardHtml.js +150 -0
- package/build/run/dashboard/dashboardHtml.js.map +1 -0
- package/build/run/dashboard/fsBrowser.js +43 -0
- package/build/run/dashboard/fsBrowser.js.map +1 -0
- package/build/run/dashboard/server.js +123 -0
- package/build/run/dashboard/server.js.map +1 -0
- package/build/run/dashboard/state.js +97 -0
- package/build/run/dashboard/state.js.map +1 -0
- package/build/run/index.js +239 -204
- package/build/run/index.js.map +1 -1
- package/build/run/interruptHandler.js +18 -0
- package/build/run/interruptHandler.js.map +1 -1
- package/build/run/outputDirectory.js +377 -0
- package/build/run/outputDirectory.js.map +1 -0
- package/build/sourcemaps/index.js +116 -29
- package/build/sourcemaps/index.js.map +1 -1
- package/build/strings/index.js +38 -28
- package/build/strings/index.js.map +1 -1
- package/build/strings/openapi.js +4 -4
- package/build/strings/openapi.js.map +1 -1
- package/build/strings/permutate.js +4 -4
- package/build/strings/permutate.js.map +1 -1
- package/build/strings/secrets.js +1 -0
- package/build/strings/secrets.js.map +1 -1
- package/build/strings/trufflehog.js +66 -19
- package/build/strings/trufflehog.js.map +1 -1
- package/build/strings/trufflehogConfig.js +36 -0
- package/build/strings/trufflehogConfig.js.map +1 -0
- package/build/strings/trufflehogDownload.js +115 -0
- package/build/strings/trufflehogDownload.js.map +1 -0
- package/build/utility/ai.js +33 -4
- package/build/utility/ai.js.map +1 -1
- package/build/utility/banner.js +4 -3
- package/build/utility/banner.js.map +1 -1
- package/build/utility/configureSandbox.js +2 -2
- package/build/utility/configureSandbox.js.map +1 -1
- package/build/utility/downloadProgress.js +99 -0
- package/build/utility/downloadProgress.js.map +1 -0
- package/build/utility/globals.js +19 -11
- package/build/utility/globals.js.map +1 -1
- package/build/utility/heap.js +2 -1
- package/build/utility/heap.js.map +1 -1
- package/build/utility/makeReq.js +490 -257
- package/build/utility/makeReq.js.map +1 -1
- package/build/utility/openapiGenerator.js +2 -2
- package/build/utility/openapiGenerator.js.map +1 -1
- package/build/utility/printMsg.js +53 -0
- package/build/utility/printMsg.js.map +1 -0
- package/build/utility/progressLog.js +68 -7
- package/build/utility/progressLog.js.map +1 -1
- package/build/utility/resolvePath.js +2 -1
- package/build/utility/resolvePath.js.map +1 -1
- package/build/utility/ruleVersionMap.js +73 -0
- package/build/utility/ruleVersionMap.js.map +1 -0
- package/build/utility/targetInputs.js +177 -0
- package/build/utility/targetInputs.js.map +1 -0
- package/build/utility/urlUtils.js +37 -1
- package/build/utility/urlUtils.js.map +1 -1
- package/config.dist.yaml +251 -0
- package/contributing/testing.md +106 -0
- package/eslint.config.js +24 -0
- package/package.json +22 -5
- package/scripts/exploit-smoke-test.js +82 -0
- package/scripts/framework-detect-smoke-test.js +64 -0
- package/scripts/postinstall-completion.mjs +40 -0
- package/scripts/smoke-test.js +12 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js +0 -98
- package/build/lazyLoad/downloadLoadedJsUtil.js.map +0 -1
- package/build/map/next_js/interactive_helpers/esqueryGen.js.map +0 -1
- package/build/map/next_js/interactive_helpers/inputPatch.js.map +0 -1
- package/build/map/next_js/interactive_helpers/keybindings.js.map +0 -1
- package/build/map/next_js/interactive_helpers/printer.js.map +0 -1
- package/build/map/next_js/interactive_helpers/ui.js.map +0 -1
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/esqueryGen.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/inputPatch.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/keybindings.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/printer.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/ui.js +0 -0
package/build/proxy/genReq.js
CHANGED
|
@@ -11,79 +11,371 @@ import { APIGatewayClient, CreateResourceCommand, GetResourcesCommand, PutMethod
|
|
|
11
11
|
// CreateDeploymentCommand,
|
|
12
12
|
// CreateStageCommand,
|
|
13
13
|
PutIntegrationResponseCommand, PutMethodResponseCommand, TestInvokeMethodCommand, DeleteResourceCommand, } from "@aws-sdk/client-api-gateway";
|
|
14
|
-
import md5 from "md5";
|
|
15
14
|
import chalk from "chalk";
|
|
15
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
16
|
+
import fs from "node:fs";
|
|
16
17
|
import * as globals from "../utility/globals.js";
|
|
18
|
+
import { progressError } from "../utility/progressLog.js";
|
|
17
19
|
import { readAwsGatewayMap } from "./awsConfig.js";
|
|
20
|
+
const AWS_CLEANUP_TIMEOUT_MS = 5000;
|
|
21
|
+
const AWS_CLEANUP_MAX_ATTEMPTS = 3;
|
|
22
|
+
const AWS_CLEANUP_RETRY_DELAY_MS = 100;
|
|
23
|
+
const AWS_CLEANUP_ABSENCE_GRACE_MS = 30000;
|
|
24
|
+
const AWS_CLEANUP_MAX_PAGES = 100;
|
|
25
|
+
const AWS_CLEANUP_LEASE_MS = 5 * 60000;
|
|
26
|
+
const AWS_OPERATION_TIMEOUT_MS = 4 * 60000;
|
|
27
|
+
const AWS_CLEANUP_RETRY_BASE_MS = 30000;
|
|
28
|
+
const AWS_CLEANUP_RETRY_MAX_MS = 15 * 60000;
|
|
29
|
+
const cleanupReplayLocks = new Map();
|
|
30
|
+
const isCleanupRecord = (value) => {
|
|
31
|
+
if (typeof value !== "object" || value === null)
|
|
32
|
+
return false;
|
|
33
|
+
const candidate = value;
|
|
34
|
+
return (candidate.version === 1 &&
|
|
35
|
+
typeof candidate.recordId === "string" &&
|
|
36
|
+
/^[0-9a-f-]{36}$/i.test(candidate.recordId) &&
|
|
37
|
+
typeof candidate.recordedAt === "string" &&
|
|
38
|
+
Number.isFinite(Date.parse(candidate.recordedAt)) &&
|
|
39
|
+
typeof candidate.leaseExpiresAt === "string" &&
|
|
40
|
+
Number.isFinite(Date.parse(candidate.leaseExpiresAt)) &&
|
|
41
|
+
typeof candidate.nextRetryAt === "string" &&
|
|
42
|
+
Number.isFinite(Date.parse(candidate.nextRetryAt)) &&
|
|
43
|
+
typeof candidate.retryCount === "number" &&
|
|
44
|
+
Number.isSafeInteger(candidate.retryCount) &&
|
|
45
|
+
candidate.retryCount >= 0 &&
|
|
46
|
+
typeof candidate.gatewayId === "string" &&
|
|
47
|
+
typeof candidate.region === "string" &&
|
|
48
|
+
typeof candidate.resourcePathPart === "string" &&
|
|
49
|
+
/^[0-9a-f]{32}$/i.test(candidate.resourcePathPart) &&
|
|
50
|
+
(candidate.resourceId === undefined ||
|
|
51
|
+
(typeof candidate.resourceId === "string" && /^[A-Za-z0-9_-]{1,256}$/.test(candidate.resourceId))));
|
|
52
|
+
};
|
|
53
|
+
const withCleanupReplaySingleFlight = (key, work) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
const existing = cleanupReplayLocks.get(key);
|
|
55
|
+
if (existing)
|
|
56
|
+
return existing;
|
|
57
|
+
const current = work();
|
|
58
|
+
cleanupReplayLocks.set(key, current);
|
|
59
|
+
try {
|
|
60
|
+
yield current;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
if (cleanupReplayLocks.get(key) === current)
|
|
64
|
+
cleanupReplayLocks.delete(key);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
18
67
|
/**
|
|
19
68
|
* Utility function to pause execution for a specified duration.
|
|
20
69
|
*
|
|
21
70
|
* @param ms - Number of milliseconds to sleep
|
|
22
71
|
* @returns Promise that resolves after the specified delay
|
|
23
72
|
*/
|
|
24
|
-
const sleep = (ms) => new Promise((resolve) =>
|
|
73
|
+
const sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
74
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
75
|
+
reject(signal.reason);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const finish = () => {
|
|
79
|
+
clearTimeout(timeout);
|
|
80
|
+
signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", cancel);
|
|
81
|
+
resolve();
|
|
82
|
+
};
|
|
83
|
+
const cancel = () => {
|
|
84
|
+
clearTimeout(timeout);
|
|
85
|
+
reject(signal === null || signal === void 0 ? void 0 : signal.reason);
|
|
86
|
+
};
|
|
87
|
+
const timeout = setTimeout(finish, ms);
|
|
88
|
+
signal === null || signal === void 0 ? void 0 : signal.addEventListener("abort", cancel, { once: true });
|
|
89
|
+
});
|
|
25
90
|
/**
|
|
26
|
-
* Given a URL, generates a new API Gateway for it and returns the response of the URL
|
|
91
|
+
* Given a URL, generates a new API Gateway for it and returns the response of the URL,
|
|
92
|
+
* along with the real HTTP status/headers so callers can corroborate WAF/CDN block detection.
|
|
27
93
|
* @param {string} url The URL to generate an API Gateway for.
|
|
28
94
|
* @param {object} [headers] The headers to include in the request.
|
|
29
|
-
* @
|
|
95
|
+
* @param {AbortSignal} [signal] Cancels pending AWS operations and retry delays.
|
|
96
|
+
* @returns {Promise<AwsGatewayResponse>} The response of the URL, with status/headers.
|
|
30
97
|
*/
|
|
31
|
-
const
|
|
98
|
+
const getWithMetadata = (url_1, ...args_1) => __awaiter(void 0, [url_1, ...args_1], void 0, function* (url, headers = {}, signal) {
|
|
99
|
+
var _a, _b, _c, _d, _e;
|
|
100
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
101
|
+
throw signal.reason;
|
|
32
102
|
// read the aws gateway map from the proxy config file
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
103
|
+
const config = (() => {
|
|
104
|
+
try {
|
|
105
|
+
return readAwsGatewayMap(globals.getProxyConfigFile());
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
throw new Error(`Failed to read or parse proxy config file: ${error.message}`);
|
|
109
|
+
}
|
|
110
|
+
})();
|
|
111
|
+
const gatewayNames = Object.keys(config);
|
|
112
|
+
if (gatewayNames.length === 0) {
|
|
113
|
+
throw new Error("No AWS API Gateway configuration is available");
|
|
39
114
|
}
|
|
40
|
-
|
|
41
|
-
|
|
115
|
+
const apiGateway = gatewayNames[Math.floor(Math.random() * gatewayNames.length)];
|
|
116
|
+
const gateway = config[apiGateway];
|
|
42
117
|
const client = new APIGatewayClient({
|
|
43
|
-
region:
|
|
118
|
+
region: gateway.region,
|
|
44
119
|
credentials: {
|
|
45
|
-
accessKeyId:
|
|
46
|
-
secretAccessKey:
|
|
120
|
+
accessKeyId: gateway.access_key,
|
|
121
|
+
secretAccessKey: gateway.secret_key,
|
|
47
122
|
},
|
|
48
123
|
});
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
124
|
+
const operationController = new AbortController();
|
|
125
|
+
const operationTimeout = setTimeout(() => operationController.abort(new DOMException("AWS API Gateway operation exceeded its ownership lease budget", "TimeoutError")), AWS_OPERATION_TIMEOUT_MS);
|
|
126
|
+
(_a = operationTimeout.unref) === null || _a === void 0 ? void 0 : _a.call(operationTimeout);
|
|
127
|
+
const operationSignal = signal ? AbortSignal.any([signal, operationController.signal]) : operationController.signal;
|
|
128
|
+
const sendOptions = { abortSignal: operationSignal };
|
|
129
|
+
const operationId = randomUUID();
|
|
130
|
+
// Derived from the URL alone (not operationId) so repeat requests to the same
|
|
131
|
+
// URL resolve to the same pathPart, letting the existing-resource lookup below
|
|
132
|
+
// reuse an already-provisioned resource instead of creating a new one every call.
|
|
133
|
+
const resourcePathPart = createHash("sha256").update(url).digest("hex").slice(0, 32);
|
|
134
|
+
const cleanupOptions = () => ({ abortSignal: AbortSignal.timeout(AWS_CLEANUP_TIMEOUT_MS) });
|
|
135
|
+
const cleanupDirectory = `${globals.getProxyConfigFile()}.cleanup`;
|
|
136
|
+
const cleanupRecordPath = (recordId) => `${cleanupDirectory}/${recordId}.json`;
|
|
137
|
+
const persistCleanupRecord = (record) => {
|
|
138
|
+
const recordPath = cleanupRecordPath(record.recordId);
|
|
139
|
+
const temporaryPath = `${recordPath}.${process.pid}.${randomUUID()}.tmp`;
|
|
140
|
+
try {
|
|
141
|
+
fs.mkdirSync(cleanupDirectory, { recursive: true, mode: 0o700 });
|
|
142
|
+
fs.writeFileSync(temporaryPath, JSON.stringify(record), { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
143
|
+
fs.renameSync(temporaryPath, recordPath);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
progressError(chalk.red(`[!] Failed to record pending AWS API Gateway cleanup: ${err}`));
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
try {
|
|
152
|
+
if (fs.existsSync(temporaryPath))
|
|
153
|
+
fs.unlinkSync(temporaryPath);
|
|
154
|
+
}
|
|
155
|
+
catch (_a) {
|
|
156
|
+
// A stale temporary file has no ownership authority and can be ignored.
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const retireCleanupRecord = (record) => {
|
|
161
|
+
try {
|
|
162
|
+
fs.unlinkSync(cleanupRecordPath(record.recordId));
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
const code = typeof err === "object" && err !== null ? Reflect.get(err, "code") : undefined;
|
|
166
|
+
if (code !== "ENOENT") {
|
|
167
|
+
progressError(chalk.red(`[!] Failed to retire completed AWS API Gateway cleanup record: ${err}`));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const beginCleanupOwnership = () => {
|
|
172
|
+
const recordedAt = new Date();
|
|
173
|
+
const record = Object.freeze({
|
|
174
|
+
version: 1,
|
|
175
|
+
recordId: operationId,
|
|
176
|
+
recordedAt: recordedAt.toISOString(),
|
|
177
|
+
leaseExpiresAt: new Date(recordedAt.getTime() + AWS_CLEANUP_LEASE_MS).toISOString(),
|
|
178
|
+
nextRetryAt: new Date(recordedAt.getTime() + AWS_CLEANUP_LEASE_MS).toISOString(),
|
|
179
|
+
retryCount: 0,
|
|
180
|
+
gatewayId: gateway.id,
|
|
181
|
+
region: gateway.region,
|
|
182
|
+
resourcePathPart,
|
|
80
183
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
184
|
+
if (!persistCleanupRecord(record)) {
|
|
185
|
+
throw new Error("Refusing to create a temporary AWS API Gateway resource without a cleanup record");
|
|
186
|
+
}
|
|
187
|
+
return record;
|
|
188
|
+
};
|
|
189
|
+
const loadCleanupRecords = () => {
|
|
190
|
+
if (!fs.existsSync(cleanupDirectory))
|
|
191
|
+
return [];
|
|
192
|
+
try {
|
|
193
|
+
return Object.freeze(fs
|
|
194
|
+
.readdirSync(cleanupDirectory, { withFileTypes: true })
|
|
195
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
|
|
196
|
+
.flatMap((entry) => {
|
|
197
|
+
try {
|
|
198
|
+
const parsed = JSON.parse(fs.readFileSync(`${cleanupDirectory}/${entry.name}`, "utf8"));
|
|
199
|
+
return isCleanupRecord(parsed) ? [Object.freeze(Object.assign({}, parsed))] : [];
|
|
200
|
+
}
|
|
201
|
+
catch (_a) {
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
progressError(chalk.red(`[!] Failed to read pending AWS API Gateway cleanup records: ${err}`));
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const deferCleanupRecord = (record) => {
|
|
212
|
+
const retryDelay = Math.min(AWS_CLEANUP_RETRY_BASE_MS * Math.pow(2, Math.min(record.retryCount, 10)), AWS_CLEANUP_RETRY_MAX_MS);
|
|
213
|
+
persistCleanupRecord(Object.freeze(Object.assign(Object.assign({}, record), { retryCount: record.retryCount + 1, nextRetryAt: new Date(Date.now() + retryDelay).toISOString() })));
|
|
214
|
+
};
|
|
215
|
+
const isNotFoundError = (err) => {
|
|
216
|
+
var _a;
|
|
217
|
+
if (typeof err !== "object" || err === null)
|
|
218
|
+
return false;
|
|
219
|
+
const candidate = err;
|
|
220
|
+
return candidate.name === "NotFoundException" || ((_a = candidate.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 404;
|
|
221
|
+
};
|
|
222
|
+
const deleteResource = (resourceId_1, ...args_2) => __awaiter(void 0, [resourceId_1, ...args_2], void 0, function* (resourceId, cleanupClient = client, restApiId = gateway.id) {
|
|
223
|
+
const deleteResourceCommand = new DeleteResourceCommand({
|
|
224
|
+
restApiId,
|
|
225
|
+
resourceId,
|
|
226
|
+
});
|
|
227
|
+
let lastError;
|
|
228
|
+
for (let attempt = 1; attempt <= AWS_CLEANUP_MAX_ATTEMPTS; attempt++) {
|
|
229
|
+
try {
|
|
230
|
+
// Cleanup deliberately gets its own request rather than the cancelled
|
|
231
|
+
// discovery signal so an aborted run does not leak temporary resources.
|
|
232
|
+
yield cleanupClient.send(deleteResourceCommand, cleanupOptions());
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
if (isNotFoundError(err))
|
|
237
|
+
return true;
|
|
238
|
+
lastError = err;
|
|
239
|
+
if (attempt < AWS_CLEANUP_MAX_ATTEMPTS) {
|
|
240
|
+
yield sleep(AWS_CLEANUP_RETRY_DELAY_MS * attempt);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
progressError(chalk.red(`[!] Error when deleting temporary AWS API Gateway resource: ${lastError}`));
|
|
245
|
+
return false;
|
|
246
|
+
});
|
|
247
|
+
const listCleanupResources = (...args_2) => __awaiter(void 0, [...args_2], void 0, function* (cleanupClient = client, restApiId = gateway.id) {
|
|
248
|
+
var _a;
|
|
249
|
+
const items = [];
|
|
250
|
+
const seenPositions = new Set();
|
|
251
|
+
let position;
|
|
252
|
+
for (let page = 0; page < AWS_CLEANUP_MAX_PAGES; page++) {
|
|
253
|
+
const resources = yield cleanupClient.send(new GetResourcesCommand(Object.assign({ restApiId, limit: 500 }, (position ? { position } : {}))), cleanupOptions());
|
|
254
|
+
items.push(...((_a = resources.items) !== null && _a !== void 0 ? _a : []));
|
|
255
|
+
if (!resources.position)
|
|
256
|
+
return Object.freeze(items);
|
|
257
|
+
if (seenPositions.has(resources.position)) {
|
|
258
|
+
throw new Error("AWS API Gateway returned a repeated cleanup pagination cursor");
|
|
259
|
+
}
|
|
260
|
+
seenPositions.add(resources.position);
|
|
261
|
+
position = resources.position;
|
|
262
|
+
}
|
|
263
|
+
throw new Error(`AWS API Gateway cleanup exceeded ${AWS_CLEANUP_MAX_PAGES} resource pages`);
|
|
264
|
+
});
|
|
265
|
+
const reconcileResource = (expectedPathPart, expectedResourceId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
266
|
+
var _a;
|
|
267
|
+
let lastError;
|
|
268
|
+
let observedCompleteListing = false;
|
|
269
|
+
for (let attempt = 1; attempt <= AWS_CLEANUP_MAX_ATTEMPTS; attempt++) {
|
|
270
|
+
try {
|
|
271
|
+
const resources = yield listCleanupResources();
|
|
272
|
+
observedCompleteListing = true;
|
|
273
|
+
const resourceId = (_a = resources.find((item) => item.pathPart === expectedPathPart &&
|
|
274
|
+
(expectedResourceId === undefined || item.id === expectedResourceId))) === null || _a === void 0 ? void 0 : _a.id;
|
|
275
|
+
if (resourceId) {
|
|
276
|
+
return (yield deleteResource(resourceId)) ? "deleted" : "unresolved";
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
lastError = err;
|
|
281
|
+
}
|
|
282
|
+
if (attempt < AWS_CLEANUP_MAX_ATTEMPTS) {
|
|
283
|
+
yield sleep(AWS_CLEANUP_RETRY_DELAY_MS * attempt);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (!observedCompleteListing && lastError !== undefined) {
|
|
287
|
+
progressError(chalk.red(`[!] Error when reconciling temporary AWS API Gateway resource: ${lastError}`));
|
|
288
|
+
return "unresolved";
|
|
289
|
+
}
|
|
290
|
+
return "absent";
|
|
291
|
+
});
|
|
292
|
+
const replayGatewayRecords = (records, replayGateway, replayClient) => __awaiter(void 0, void 0, void 0, function* () {
|
|
293
|
+
var _a;
|
|
294
|
+
let resources = null;
|
|
295
|
+
let lastError;
|
|
296
|
+
for (let attempt = 1; attempt <= AWS_CLEANUP_MAX_ATTEMPTS; attempt++) {
|
|
297
|
+
try {
|
|
298
|
+
resources = yield listCleanupResources(replayClient, replayGateway.id);
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
lastError = err;
|
|
303
|
+
if (attempt < AWS_CLEANUP_MAX_ATTEMPTS) {
|
|
304
|
+
yield sleep(AWS_CLEANUP_RETRY_DELAY_MS * attempt);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (!resources) {
|
|
309
|
+
progressError(chalk.red(`[!] Error when replaying pending AWS API Gateway cleanup for ${replayGateway.id}: ${lastError}`));
|
|
310
|
+
for (const record of records)
|
|
311
|
+
deferCleanupRecord(record);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
for (const record of records) {
|
|
315
|
+
const resourceId = (_a = resources.find((item) => item.pathPart === record.resourcePathPart &&
|
|
316
|
+
(record.resourceId === undefined || item.id === record.resourceId))) === null || _a === void 0 ? void 0 : _a.id;
|
|
317
|
+
if (resourceId) {
|
|
318
|
+
if (yield deleteResource(resourceId, replayClient, replayGateway.id)) {
|
|
319
|
+
retireCleanupRecord(record);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
deferCleanupRecord(record);
|
|
323
|
+
}
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const oldEnoughToConfirmAbsence = Date.now() - Date.parse(record.recordedAt) >= AWS_CLEANUP_ABSENCE_GRACE_MS;
|
|
327
|
+
if (oldEnoughToConfirmAbsence)
|
|
328
|
+
retireCleanupRecord(record);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
const replayCleanupRecords = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
332
|
+
return withCleanupReplaySingleFlight(cleanupDirectory, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
333
|
+
const now = Date.now();
|
|
334
|
+
const expiredRecords = loadCleanupRecords().filter((record) => Date.parse(record.leaseExpiresAt) <= now && Date.parse(record.nextRetryAt) <= now);
|
|
335
|
+
if (expiredRecords.length === 0)
|
|
336
|
+
return;
|
|
337
|
+
const replayedGateways = new Set();
|
|
338
|
+
for (const replayGateway of Object.values(config)) {
|
|
339
|
+
const gatewayKey = `${replayGateway.region}\0${replayGateway.id}`;
|
|
340
|
+
if (replayedGateways.has(gatewayKey))
|
|
341
|
+
continue;
|
|
342
|
+
replayedGateways.add(gatewayKey);
|
|
343
|
+
const records = expiredRecords.filter((record) => record.gatewayId === replayGateway.id && record.region === replayGateway.region);
|
|
344
|
+
if (records.length === 0)
|
|
345
|
+
continue;
|
|
346
|
+
const useCurrentClient = replayGateway === gateway;
|
|
347
|
+
const replayClient = useCurrentClient
|
|
348
|
+
? client
|
|
349
|
+
: new APIGatewayClient({
|
|
350
|
+
region: replayGateway.region,
|
|
351
|
+
credentials: {
|
|
352
|
+
accessKeyId: replayGateway.access_key,
|
|
353
|
+
secretAccessKey: replayGateway.secret_key,
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
try {
|
|
357
|
+
yield replayGatewayRecords(records, replayGateway, replayClient);
|
|
358
|
+
}
|
|
359
|
+
finally {
|
|
360
|
+
if (!useCurrentClient)
|
|
361
|
+
replayClient.destroy();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}));
|
|
365
|
+
});
|
|
366
|
+
const reconcileAmbiguousResource = (record) => __awaiter(void 0, void 0, void 0, function* () {
|
|
367
|
+
const outcome = yield reconcileResource(record.resourcePathPart);
|
|
368
|
+
if (outcome === "deleted") {
|
|
369
|
+
retireCleanupRecord(record);
|
|
370
|
+
}
|
|
371
|
+
else if (outcome === "unresolved") {
|
|
372
|
+
progressError(chalk.red(`[!] Temporary AWS API Gateway ownership remains pending in ${cleanupRecordPath(record.recordId)}`));
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
const configureResource = (resourceId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
376
|
+
yield client.send(new PutMethodCommand({
|
|
377
|
+
restApiId: gateway.id,
|
|
378
|
+
resourceId,
|
|
87
379
|
httpMethod: "GET",
|
|
88
380
|
authorizationType: "NONE",
|
|
89
381
|
requestParameters: {
|
|
@@ -105,93 +397,108 @@ const get = (url_1, ...args_1) => __awaiter(void 0, [url_1, ...args_1], void 0,
|
|
|
105
397
|
"method.request.header.Sec-Fetch-Mode": false,
|
|
106
398
|
"method.request.header.Sec-Fetch-Dest": false,
|
|
107
399
|
},
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
yield
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
restApiId: config[apiGateway].id,
|
|
114
|
-
resourceId: newResourceResponse.id,
|
|
400
|
+
}), sendOptions);
|
|
401
|
+
yield sleep(100, operationSignal);
|
|
402
|
+
yield client.send(new PutIntegrationCommand({
|
|
403
|
+
restApiId: gateway.id,
|
|
404
|
+
resourceId,
|
|
115
405
|
httpMethod: "GET",
|
|
116
406
|
integrationHttpMethod: "GET",
|
|
117
407
|
type: "HTTP",
|
|
118
408
|
timeoutInMillis: 29000,
|
|
119
409
|
uri: url,
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
yield
|
|
123
|
-
// create a new method response
|
|
124
|
-
const newMethodResponseCommand = new PutMethodResponseCommand({
|
|
410
|
+
}), sendOptions);
|
|
411
|
+
yield sleep(100, operationSignal);
|
|
412
|
+
yield client.send(new PutMethodResponseCommand({
|
|
125
413
|
httpMethod: "GET",
|
|
126
|
-
resourceId
|
|
127
|
-
restApiId:
|
|
414
|
+
resourceId,
|
|
415
|
+
restApiId: gateway.id,
|
|
128
416
|
statusCode: "200",
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
yield
|
|
132
|
-
// put integration response
|
|
133
|
-
const putIntegrationResponseCommand = new PutIntegrationResponseCommand({
|
|
417
|
+
}), sendOptions);
|
|
418
|
+
yield sleep(100, operationSignal);
|
|
419
|
+
yield client.send(new PutIntegrationResponseCommand({
|
|
134
420
|
httpMethod: "GET",
|
|
135
|
-
resourceId
|
|
136
|
-
restApiId:
|
|
421
|
+
resourceId,
|
|
422
|
+
restApiId: gateway.id,
|
|
137
423
|
statusCode: "200",
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
yield sleep(100);
|
|
141
|
-
}
|
|
142
|
-
// Generate dynamic stage name
|
|
143
|
-
// const dynamicStageName = `prod-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;
|
|
144
|
-
// console.log(chalk.blue(`[*] Using dynamic stage name: ${dynamicStageName}`));
|
|
145
|
-
// Create a deployment
|
|
146
|
-
// const createDeploymentCommand = new CreateDeploymentCommand({
|
|
147
|
-
// restApiId: config[apiGateway].id,
|
|
148
|
-
// stageName: dynamicStageName,
|
|
149
|
-
// description: `Deployment for ${url} at ${new Date().toISOString()} to stage ${dynamicStageName}`,
|
|
150
|
-
// });
|
|
151
|
-
// const deploymentResponse = await client.send(createDeploymentCommand);
|
|
152
|
-
// console.log(chalk.green("[+] Deployment created:"), deploymentResponse.id);
|
|
153
|
-
// await sleep(100);
|
|
154
|
-
const testInvokeMethodQuery = new TestInvokeMethodCommand({
|
|
155
|
-
httpMethod: "GET",
|
|
156
|
-
resourceId: newResourceResponse.id,
|
|
157
|
-
restApiId: config[apiGateway].id,
|
|
158
|
-
headers: headers || {},
|
|
424
|
+
}), sendOptions);
|
|
425
|
+
yield sleep(100, operationSignal);
|
|
159
426
|
});
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
427
|
+
const createResource = (parentId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
428
|
+
const initialCleanupRecord = beginCleanupOwnership();
|
|
429
|
+
let resourceId;
|
|
430
|
+
try {
|
|
431
|
+
const created = yield client.send(new CreateResourceCommand({
|
|
432
|
+
restApiId: gateway.id,
|
|
433
|
+
parentId,
|
|
434
|
+
pathPart: resourcePathPart,
|
|
435
|
+
}), sendOptions);
|
|
436
|
+
if (!created.id)
|
|
437
|
+
throw new Error("AWS API Gateway did not return a resource ID");
|
|
438
|
+
resourceId = created.id;
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
// CreateResource can commit remotely even when cancellation or a
|
|
442
|
+
// transport failure loses its response. Reconcile by deterministic
|
|
443
|
+
// pathPart before returning the original failure.
|
|
444
|
+
yield reconcileAmbiguousResource(initialCleanupRecord);
|
|
445
|
+
throw error;
|
|
446
|
+
}
|
|
447
|
+
const cleanupRecord = Object.freeze(Object.assign(Object.assign({}, initialCleanupRecord), { resourceId }));
|
|
448
|
+
// The original pathPart-only record remains sufficient for replay if
|
|
449
|
+
// this best-effort enrichment cannot be persisted.
|
|
450
|
+
persistCleanupRecord(cleanupRecord);
|
|
451
|
+
try {
|
|
452
|
+
yield sleep(200, operationSignal);
|
|
453
|
+
yield configureResource(resourceId);
|
|
454
|
+
return Object.freeze({ id: resourceId, cleanupRecord });
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
if (yield deleteResource(resourceId))
|
|
458
|
+
retireCleanupRecord(cleanupRecord);
|
|
459
|
+
throw error;
|
|
460
|
+
}
|
|
167
461
|
});
|
|
168
462
|
try {
|
|
169
|
-
yield
|
|
463
|
+
yield replayCleanupRecords();
|
|
464
|
+
const resources = yield listCleanupResources();
|
|
465
|
+
yield sleep(200, operationSignal);
|
|
466
|
+
const existingResource = resources.find((item) => item.pathPart === resourcePathPart);
|
|
467
|
+
const rootId = (_c = (_b = resources.find((item) => item.path === "/")) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : (_d = resources[0]) === null || _d === void 0 ? void 0 : _d.parentId;
|
|
468
|
+
if (!(existingResource === null || existingResource === void 0 ? void 0 : existingResource.id) && !rootId) {
|
|
469
|
+
throw new Error("AWS API Gateway did not return a root resource ID");
|
|
470
|
+
}
|
|
471
|
+
const resource = (existingResource === null || existingResource === void 0 ? void 0 : existingResource.id)
|
|
472
|
+
? { id: existingResource.id, cleanupRecord: null }
|
|
473
|
+
: yield createResource(rootId);
|
|
474
|
+
try {
|
|
475
|
+
const invoked = yield client.send(new TestInvokeMethodCommand({
|
|
476
|
+
httpMethod: "GET",
|
|
477
|
+
resourceId: resource.id,
|
|
478
|
+
restApiId: gateway.id,
|
|
479
|
+
headers,
|
|
480
|
+
}), sendOptions);
|
|
481
|
+
yield sleep(100, operationSignal);
|
|
482
|
+
return { body: (_e = invoked.body) !== null && _e !== void 0 ? _e : "", status: invoked.status, headers: invoked.headers };
|
|
483
|
+
}
|
|
484
|
+
finally {
|
|
485
|
+
if (resource.cleanupRecord && (yield deleteResource(resource.id))) {
|
|
486
|
+
retireCleanupRecord(resource.cleanupRecord);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
170
489
|
}
|
|
171
|
-
|
|
172
|
-
|
|
490
|
+
finally {
|
|
491
|
+
clearTimeout(operationTimeout);
|
|
492
|
+
client.destroy();
|
|
173
493
|
}
|
|
174
|
-
return body;
|
|
175
|
-
// create a new stage
|
|
176
|
-
// dynamicStageName = `prod-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;
|
|
177
|
-
// const newStageCommand = new CreateStageCommand({
|
|
178
|
-
// restApiId: config[apiGateway].id,
|
|
179
|
-
// stageName: dynamicStageName, // Use dynamic stage name
|
|
180
|
-
// deploymentId: deploymentResponse.id, // Use the ID from the deployment
|
|
181
|
-
// cacheClusterEnabled: false,
|
|
182
|
-
// // cacheClusterSize: "0", // Removed as cacheClusterEnabled is false
|
|
183
|
-
// methodSettings: [
|
|
184
|
-
// {
|
|
185
|
-
// httpMethod: "*",
|
|
186
|
-
// // resourceId: "*", // This might need to be more specific if you don't want it for all resources
|
|
187
|
-
// throttlingBurstLimit: 5,
|
|
188
|
-
// throttlingRateLimit: 10,
|
|
189
|
-
// },
|
|
190
|
-
// ],
|
|
191
|
-
// });
|
|
192
|
-
// const newStageResponse = await client.send(newStageCommand);
|
|
193
|
-
// await sleep(100);
|
|
194
|
-
// console.log(newStageResponse);
|
|
195
494
|
});
|
|
196
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Given a URL, generates a new API Gateway for it and returns the response body as text.
|
|
497
|
+
* @param {string} url The URL to generate an API Gateway for.
|
|
498
|
+
* @param {object} [headers] The headers to include in the request.
|
|
499
|
+
* @param {AbortSignal} [signal] Cancels pending AWS operations and retry delays.
|
|
500
|
+
* @returns {Promise<string>} The response body of the URL.
|
|
501
|
+
*/
|
|
502
|
+
const get = (url_1, ...args_1) => __awaiter(void 0, [url_1, ...args_1], void 0, function* (url, headers = {}, signal) { return (yield getWithMetadata(url, headers, signal)).body; });
|
|
503
|
+
export { get, getWithMetadata };
|
|
197
504
|
//# sourceMappingURL=genReq.js.map
|