@js-recon/js-recon 1.4.1-alpha.9 → 1.4.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/.claude-sync/capture-new.sh +61 -0
- package/.claude-sync/capture-scan.sh +55 -0
- package/.claude-sync/hooks/post-checkout +16 -0
- package/.claude-sync/hooks/pre-commit +3 -0
- package/.claude-sync/setup.sh +17 -0
- package/.claude-sync/sync.sh +64 -0
- package/.claude-sync/watch.sh +17 -0
- package/.github/workflows/build-and-prettify.yaml +42 -0
- package/.github/workflows/promote-js-recon.yml +299 -0
- package/.vscode/tasks.json +42 -0
- package/CHANGELOG.md +35 -0
- package/Dockerfile.w-rules +13 -0
- package/README.md +4 -2
- package/build/analyze/helpers/initRules.js +28 -6
- package/build/analyze/helpers/initRules.js.map +1 -1
- package/build/analyze/index.js +3 -2
- package/build/analyze/index.js.map +1 -1
- package/build/completion/index.js +17 -11
- package/build/completion/index.js.map +1 -1
- package/build/globalConfig.js +1 -1
- package/build/globalConfig.js.map +1 -1
- package/build/index.js +55 -23
- package/build/index.js.map +1 -1
- package/build/lazyLoad/generic/generic_jsMimeTypes.js +19 -0
- package/build/lazyLoad/generic/generic_jsMimeTypes.js.map +1 -0
- package/build/lazyLoad/index.js +1 -0
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +8 -2
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/techDetect/checkInterceptedEvidence.js +18 -0
- package/build/lazyLoad/techDetect/checkInterceptedEvidence.js.map +1 -0
- package/build/lazyLoad/techDetect/index.js +58 -13
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/mcp/mcpServer.js +1 -2
- package/build/mcp/mcpServer.js.map +1 -1
- package/build/mcp/tools.js +1 -2
- package/build/mcp/tools.js.map +1 -1
- package/build/proxy/awsConfig.js +45 -0
- package/build/proxy/awsConfig.js.map +1 -0
- package/build/proxy/checkFeasibility.js.map +1 -0
- package/build/proxy/checkFireWallBlocking.js.map +1 -0
- package/build/proxy/configFile.js +31 -0
- package/build/proxy/configFile.js.map +1 -0
- package/build/{api_gateway → proxy}/genReq.js +4 -5
- package/build/proxy/genReq.js.map +1 -0
- package/build/proxy/genericProxy.js +21 -0
- package/build/proxy/genericProxy.js.map +1 -0
- package/build/proxy/index.js +421 -0
- package/build/proxy/index.js.map +1 -0
- package/build/proxy/oxylabsProxy.js +34 -0
- package/build/proxy/oxylabsProxy.js.map +1 -0
- package/build/proxy/resolveProxyConfig.js +38 -0
- package/build/proxy/resolveProxyConfig.js.map +1 -0
- package/build/report/utility/initGlobalReportDb.js +111 -0
- package/build/report/utility/initGlobalReportDb.js.map +1 -0
- package/build/report/utility/mergeDomainIntoGlobalDb.js +39 -0
- package/build/report/utility/mergeDomainIntoGlobalDb.js.map +1 -0
- package/build/run/index.js +110 -74
- package/build/run/index.js.map +1 -1
- package/build/run/interruptHandler.js +17 -1
- package/build/run/interruptHandler.js.map +1 -1
- package/build/utility/configureProxy.js +60 -0
- package/build/utility/configureProxy.js.map +1 -0
- package/build/utility/globals.js +108 -13
- package/build/utility/globals.js.map +1 -1
- package/build/utility/makeReq.js +103 -10
- package/build/utility/makeReq.js.map +1 -1
- package/package.json +5 -1
- package/.claude/settings.local.json +0 -10
- package/CLAUDE.md +0 -629
- package/build/api_gateway/checkFeasibility.js.map +0 -1
- package/build/api_gateway/checkFireWallBlocking.js.map +0 -1
- package/build/api_gateway/genReq.js.map +0 -1
- package/build/api_gateway/index.js +0 -291
- package/build/api_gateway/index.js.map +0 -1
- package/urls.txt +0 -5
- /package/build/{api_gateway → proxy}/checkFeasibility.js +0 -0
- /package/build/{api_gateway → proxy}/checkFireWallBlocking.js +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composes the Oxylabs datacenter-proxy username: auth is entirely encoded here, no separate API.
|
|
3
|
+
* user-USERNAME[-country-XX]
|
|
4
|
+
*
|
|
5
|
+
* Verified against a live Oxylabs datacenter account (dc.oxylabs.io:8000) — the previous
|
|
6
|
+
* `customer-USERNAME-cc-XX` residential-style scheme returns a 407 Proxy Authentication Required
|
|
7
|
+
* against real datacenter credentials; this is the confirmed-working format per
|
|
8
|
+
* https://developers.oxylabs.io/products/proxies/datacenter-proxies/select-country.
|
|
9
|
+
*
|
|
10
|
+
* `city` and `sessionId` are not supported here: Oxylabs' datacenter tier has no documented
|
|
11
|
+
* username-level city targeting, and sticky sessions are selected by port number, not by a
|
|
12
|
+
* username suffix — silently encoding either into the username would produce a wrong username
|
|
13
|
+
* that fails auth, so both are rejected explicitly instead.
|
|
14
|
+
*/
|
|
15
|
+
export const composeOxylabsUsername = (cfg) => {
|
|
16
|
+
if (cfg.city) {
|
|
17
|
+
throw new Error("Oxylabs config: `city` is not supported (no documented username-level city targeting for datacenter proxies). Omit `city`.");
|
|
18
|
+
}
|
|
19
|
+
if (cfg.sessionId) {
|
|
20
|
+
throw new Error("Oxylabs config: `sessionId` is not supported via username for datacenter proxies (sticky sessions are selected by port, not username). Omit `sessionId`.");
|
|
21
|
+
}
|
|
22
|
+
let username = `user-${cfg.username}`;
|
|
23
|
+
if (cfg.country) {
|
|
24
|
+
username += `-country-${cfg.country}`;
|
|
25
|
+
}
|
|
26
|
+
return username;
|
|
27
|
+
};
|
|
28
|
+
const OXYLABS_ENTRY_ENDPOINT = "dc.oxylabs.io:8000";
|
|
29
|
+
/** Composes the full Oxylabs datacenter proxy URL. */
|
|
30
|
+
export const buildOxylabsProxyUrl = (cfg) => {
|
|
31
|
+
const username = composeOxylabsUsername(cfg);
|
|
32
|
+
return `http://${encodeURIComponent(username)}:${encodeURIComponent(cfg.password)}@${OXYLABS_ENTRY_ENDPOINT}`;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=oxylabsProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oxylabsProxy.js","sourceRoot":"","sources":["../../src/proxy/oxylabsProxy.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAkB,EAAU,EAAE;IACjE,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACX,4HAA4H,CAC/H,CAAC;IACN,CAAC;IACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACX,0JAA0J,CAC7J,CAAC;IACN,CAAC;IAED,IAAI,QAAQ,GAAG,QAAQ,GAAG,CAAC,QAAQ,EAAE,CAAC;IACtC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,QAAQ,IAAI,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAEpD,sDAAsD;AACtD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAkB,EAAU,EAAE;IAC/D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO,UAAU,kBAAkB,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC;AAClH,CAAC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const isValidMethod = (value) => {
|
|
2
|
+
return value === "aws" || value === "socks" || value === "http" || value === "oxylabs";
|
|
3
|
+
};
|
|
4
|
+
export const resolveProxyConfig = (input) => {
|
|
5
|
+
var _a;
|
|
6
|
+
const { cli, env, ignoreEnv, configFileParsed } = input;
|
|
7
|
+
const envMethod = ignoreEnv ? undefined : env.JS_RECON_PROXY_METHOD;
|
|
8
|
+
const rawMethod = cli.proxyMethod || envMethod || configFileParsed.method;
|
|
9
|
+
const method = isValidMethod(rawMethod) ? rawMethod : null;
|
|
10
|
+
if (method === null) {
|
|
11
|
+
return { method: null };
|
|
12
|
+
}
|
|
13
|
+
if (method === "socks" || method === "http") {
|
|
14
|
+
const envUrl = ignoreEnv ? undefined : env.JS_RECON_PROXY_URL;
|
|
15
|
+
const url = cli.proxyUrl || envUrl || ((_a = configFileParsed[method]) === null || _a === void 0 ? void 0 : _a.url);
|
|
16
|
+
return { method, url };
|
|
17
|
+
}
|
|
18
|
+
if (method === "oxylabs") {
|
|
19
|
+
const envUsername = ignoreEnv ? undefined : env.JS_RECON_OXYLABS_USERNAME;
|
|
20
|
+
const envPassword = ignoreEnv ? undefined : env.JS_RECON_OXYLABS_PASSWORD;
|
|
21
|
+
const envCountry = ignoreEnv ? undefined : env.JS_RECON_OXYLABS_COUNTRY;
|
|
22
|
+
const envCity = ignoreEnv ? undefined : env.JS_RECON_OXYLABS_CITY;
|
|
23
|
+
const envSessionId = ignoreEnv ? undefined : env.JS_RECON_OXYLABS_SESSION_ID;
|
|
24
|
+
const fileOxylabs = configFileParsed.oxylabs || {};
|
|
25
|
+
const username = cli.oxylabsUsername || envUsername || fileOxylabs.username;
|
|
26
|
+
const password = cli.oxylabsPassword || envPassword || fileOxylabs.password;
|
|
27
|
+
const country = cli.oxylabsCountry || envCountry || fileOxylabs.country;
|
|
28
|
+
const city = cli.oxylabsCity || envCity || fileOxylabs.city;
|
|
29
|
+
const sessionId = cli.oxylabsSessionId || envSessionId || fileOxylabs.sessionId;
|
|
30
|
+
if (!username || !password) {
|
|
31
|
+
return { method: null };
|
|
32
|
+
}
|
|
33
|
+
return { method, oxylabs: { username, password, country, city, sessionId } };
|
|
34
|
+
}
|
|
35
|
+
// method === "aws"
|
|
36
|
+
return { method, awsGatewayMap: configFileParsed.aws || {} };
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=resolveProxyConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveProxyConfig.js","sourceRoot":"","sources":["../../src/proxy/resolveProxyConfig.ts"],"names":[],"mappings":"AA4CA,MAAM,aAAa,GAAG,CAAC,KAAc,EAAwB,EAAE;IAC3D,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,CAAC;AAC3F,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAA8B,EAAuB,EAAE;;IACtF,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IAExD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACpE,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,IAAI,SAAS,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAC1E,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3D,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,IAAI,MAAM,KAAI,MAAA,gBAAgB,CAAC,MAAM,CAAC,0CAAE,GAAG,CAAA,CAAC;QACpE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC1E,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC1E,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC;QACxE,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAClE,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,2BAA2B,CAAC;QAC7E,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,IAAI,EAAE,CAAC;QAEnD,MAAM,QAAQ,GAAG,GAAG,CAAC,eAAe,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC;QAC5E,MAAM,QAAQ,GAAG,GAAG,CAAC,eAAe,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC;QAC5E,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,IAAI,UAAU,IAAI,WAAW,CAAC,OAAO,CAAC;QACxE,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,IAAI,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC;QAC5D,MAAM,SAAS,GAAG,GAAG,CAAC,gBAAgB,IAAI,YAAY,IAAI,WAAW,CAAC,SAAS,CAAC;QAEhF,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YACzB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;IACjF,CAAC;IAED,mBAAmB;IACnB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,gBAAgB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC;AACjE,CAAC,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
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 Database from "better-sqlite3";
|
|
11
|
+
/**
|
|
12
|
+
* Creates the mapped table in the global database. Adds a `domain` column and a
|
|
13
|
+
* `globalId` surrogate key since the original `id` (chunk module id) is only
|
|
14
|
+
* unique within a single domain's bundle, not across domains.
|
|
15
|
+
*
|
|
16
|
+
* @param db - The database to create the table in
|
|
17
|
+
*/
|
|
18
|
+
const createMappedTable = (db) => {
|
|
19
|
+
db.prepare(`
|
|
20
|
+
CREATE TABLE IF NOT EXISTS mapped (
|
|
21
|
+
globalId INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
22
|
+
domain TEXT,
|
|
23
|
+
id TEXT,
|
|
24
|
+
description TEXT,
|
|
25
|
+
loadedOn TEXT,
|
|
26
|
+
containsFetch BOOLEAN,
|
|
27
|
+
isAxiosClient BOOLEAN,
|
|
28
|
+
exports TEXT,
|
|
29
|
+
callStack TEXT,
|
|
30
|
+
code TEXT,
|
|
31
|
+
imports TEXT,
|
|
32
|
+
file TEXT
|
|
33
|
+
)
|
|
34
|
+
`).run();
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Creates the mapped OpenAPI table in the global database. The primary key is
|
|
38
|
+
* widened to include `domain` since the same path/method can exist on
|
|
39
|
+
* different domains.
|
|
40
|
+
*
|
|
41
|
+
* @param db - The database to create the table in
|
|
42
|
+
*/
|
|
43
|
+
const createMappedOpenapiTable = (db) => {
|
|
44
|
+
db.prepare(`
|
|
45
|
+
CREATE TABLE IF NOT EXISTS mapped_openapi (
|
|
46
|
+
domain TEXT,
|
|
47
|
+
path TEXT,
|
|
48
|
+
method TEXT,
|
|
49
|
+
summary TEXT,
|
|
50
|
+
parameters TEXT,
|
|
51
|
+
requestBody TEXT,
|
|
52
|
+
tags TEXT,
|
|
53
|
+
PRIMARY KEY (domain, path, method)
|
|
54
|
+
)
|
|
55
|
+
`).run();
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Creates the endpoints table in the global database. The primary key is
|
|
59
|
+
* widened to include `domain` since the same URL can exist on different
|
|
60
|
+
* domains.
|
|
61
|
+
*
|
|
62
|
+
* @param db - The database to create the table in
|
|
63
|
+
*/
|
|
64
|
+
const createEndpointsTable = (db) => {
|
|
65
|
+
db.prepare(`
|
|
66
|
+
CREATE TABLE IF NOT EXISTS endpoints (
|
|
67
|
+
domain TEXT,
|
|
68
|
+
url TEXT,
|
|
69
|
+
PRIMARY KEY (domain, url)
|
|
70
|
+
)
|
|
71
|
+
`).run();
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Creates the analysis findings table in the global database. Adds a `domain`
|
|
75
|
+
* column and a `globalId` surrogate key.
|
|
76
|
+
*
|
|
77
|
+
* @param db - The database to create the table in
|
|
78
|
+
*/
|
|
79
|
+
const createAnalysisFindingsTable = (db) => {
|
|
80
|
+
db.prepare(`
|
|
81
|
+
CREATE TABLE IF NOT EXISTS analysis_findings (
|
|
82
|
+
globalId INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
83
|
+
domain TEXT,
|
|
84
|
+
ruleId TEXT,
|
|
85
|
+
ruleName TEXT,
|
|
86
|
+
ruleType TEXT,
|
|
87
|
+
ruleDescription TEXT,
|
|
88
|
+
ruleAuthor TEXT,
|
|
89
|
+
ruleTech TEXT,
|
|
90
|
+
severity TEXT,
|
|
91
|
+
message TEXT,
|
|
92
|
+
findingLocation TEXT
|
|
93
|
+
)
|
|
94
|
+
`).run();
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Initializes the global report database used to aggregate the per-domain
|
|
98
|
+
* `js-recon.db` files produced during a batch (`-u <file>`) run.
|
|
99
|
+
*
|
|
100
|
+
* @param sqliteDbPath - The path to the global SQLite database file
|
|
101
|
+
*/
|
|
102
|
+
const initGlobalReportDb = (sqliteDbPath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
const db = new Database(sqliteDbPath);
|
|
104
|
+
createMappedTable(db);
|
|
105
|
+
createMappedOpenapiTable(db);
|
|
106
|
+
createEndpointsTable(db);
|
|
107
|
+
createAnalysisFindingsTable(db);
|
|
108
|
+
db.close();
|
|
109
|
+
});
|
|
110
|
+
export default initGlobalReportDb;
|
|
111
|
+
//# sourceMappingURL=initGlobalReportDb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initGlobalReportDb.js","sourceRoot":"","sources":["../../../src/report/utility/initGlobalReportDb.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,CAAC,EAAqB,EAAE,EAAE;IAChD,EAAE,CAAC,OAAO,CACN;;;;;;;;;;;;;;;KAeH,CACA,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,wBAAwB,GAAG,CAAC,EAAqB,EAAE,EAAE;IACvD,EAAE,CAAC,OAAO,CACN;;;;;;;;;;;KAWH,CACA,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,CAAC,EAAqB,EAAE,EAAE;IACnD,EAAE,CAAC,OAAO,CACN;;;;;;KAMH,CACA,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,2BAA2B,GAAG,CAAC,EAAqB,EAAE,EAAE;IAC1D,EAAE,CAAC,OAAO,CACN;;;;;;;;;;;;;;KAcH,CACA,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,CAAO,YAAoB,EAAE,EAAE;IACtD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEtC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtB,wBAAwB,CAAC,EAAE,CAAC,CAAC;IAC7B,oBAAoB,CAAC,EAAE,CAAC,CAAC;IACzB,2BAA2B,CAAC,EAAE,CAAC,CAAC;IAEhC,EAAE,CAAC,KAAK,EAAE,CAAC;AACf,CAAC,CAAA,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
/**
|
|
3
|
+
* Merges a single domain's fully-populated `js-recon.db` into the batch-wide
|
|
4
|
+
* global database, tagging every copied row with `domain` so it can be
|
|
5
|
+
* traced back to its source directory. Uses `ATTACH DATABASE` so rows are
|
|
6
|
+
* copied directly via SQL instead of re-reading the domain's JSON inputs.
|
|
7
|
+
*
|
|
8
|
+
* @param globalDbPath - Path to the global SQLite database file
|
|
9
|
+
* @param domainDbPath - Path to the domain's own `js-recon.db`
|
|
10
|
+
* @param domain - The domain identifier (sanitized host) to tag rows with
|
|
11
|
+
*/
|
|
12
|
+
const mergeDomainIntoGlobalDb = (globalDbPath, domainDbPath, domain) => {
|
|
13
|
+
const db = new Database(globalDbPath);
|
|
14
|
+
try {
|
|
15
|
+
db.prepare(`ATTACH DATABASE ? AS src`).run(domainDbPath);
|
|
16
|
+
db.prepare(`
|
|
17
|
+
INSERT INTO mapped (domain, id, description, loadedOn, containsFetch, isAxiosClient, exports, callStack, code, imports, file)
|
|
18
|
+
SELECT ?, id, description, loadedOn, containsFetch, isAxiosClient, exports, callStack, code, imports, file FROM src.mapped
|
|
19
|
+
`).run(domain);
|
|
20
|
+
db.prepare(`
|
|
21
|
+
INSERT OR REPLACE INTO mapped_openapi (domain, path, method, summary, parameters, requestBody, tags)
|
|
22
|
+
SELECT ?, path, method, summary, parameters, requestBody, tags FROM src.mapped_openapi
|
|
23
|
+
`).run(domain);
|
|
24
|
+
db.prepare(`
|
|
25
|
+
INSERT OR IGNORE INTO endpoints (domain, url)
|
|
26
|
+
SELECT ?, url FROM src.endpoints
|
|
27
|
+
`).run(domain);
|
|
28
|
+
db.prepare(`
|
|
29
|
+
INSERT INTO analysis_findings (domain, ruleId, ruleName, ruleType, ruleDescription, ruleAuthor, ruleTech, severity, message, findingLocation)
|
|
30
|
+
SELECT ?, ruleId, ruleName, ruleType, ruleDescription, ruleAuthor, ruleTech, severity, message, findingLocation FROM src.analysis_findings
|
|
31
|
+
`).run(domain);
|
|
32
|
+
db.prepare(`DETACH DATABASE src`).run();
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
db.close();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export default mergeDomainIntoGlobalDb;
|
|
39
|
+
//# sourceMappingURL=mergeDomainIntoGlobalDb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeDomainIntoGlobalDb.js","sourceRoot":"","sources":["../../../src/report/utility/mergeDomainIntoGlobalDb.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,uBAAuB,GAAG,CAAC,YAAoB,EAAE,YAAoB,EAAE,MAAc,EAAE,EAAE;IAC3F,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEtC,IAAI,CAAC;QACD,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEzD,EAAE,CAAC,OAAO,CACN;;;SAGH,CACA,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEd,EAAE,CAAC,OAAO,CACN;;;SAGH,CACA,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEd,EAAE,CAAC,OAAO,CACN;;;SAGH,CACA,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEd,EAAE,CAAC,OAAO,CACN;;;SAGH,CACA,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEd,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,GAAG,EAAE,CAAC;IAC5C,CAAC;YAAS,CAAC;QACP,EAAE,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;AACL,CAAC,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
package/build/run/index.js
CHANGED
|
@@ -18,10 +18,13 @@ import CONFIG from "../globalConfig.js";
|
|
|
18
18
|
import analyze from "../analyze/index.js";
|
|
19
19
|
import report from "../report/index.js";
|
|
20
20
|
import refactor from "../refactor/index.js";
|
|
21
|
+
import initGlobalReportDb from "../report/utility/initGlobalReportDb.js";
|
|
22
|
+
import mergeDomainIntoGlobalDb from "../report/utility/mergeDomainIntoGlobalDb.js";
|
|
21
23
|
import { clearJsUrls, clearJsonUrls, getJsUrls } from "../lazyLoad/globals.js";
|
|
22
24
|
import path from "path";
|
|
23
|
-
import { installSigintHandler, removeSigintHandler, getSkipStepPromise, resetSkipStep, shouldSkipTarget, resetSkipTarget, } from "./interruptHandler.js";
|
|
25
|
+
import { installSigintHandler, removeSigintHandler, getSkipStepPromise, resetSkipStep, shouldSkipTarget, resetSkipTarget, waitForPendingInterrupt, } from "./interruptHandler.js";
|
|
24
26
|
import { detectBundler } from "./bundler-detect.js";
|
|
27
|
+
import configureProxy from "../utility/configureProxy.js";
|
|
25
28
|
/**
|
|
26
29
|
* Determines the directory for a Content Delivery Network (CDN) if used by the target.
|
|
27
30
|
*
|
|
@@ -131,7 +134,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
131
134
|
resetSkipStep();
|
|
132
135
|
// @ts-ignore
|
|
133
136
|
yield Promise.race([
|
|
134
|
-
analyze(cmd.rules || "", mappedJsonFileReact, "react", false, openapiFile, false, analyzeFile),
|
|
137
|
+
analyze(cmd.rules || "", mappedJsonFileReact, "react", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
135
138
|
getSkipStepPromise(),
|
|
136
139
|
]);
|
|
137
140
|
console.log(chalk.bgGreen("[+] Analyze complete."));
|
|
@@ -150,24 +153,29 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
150
153
|
console.log(chalk.bgGreen("[+] Report complete."));
|
|
151
154
|
if (shouldSkipTarget())
|
|
152
155
|
return;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
fs.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
156
|
+
if (!cmd.disableRefactor) {
|
|
157
|
+
console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
|
|
158
|
+
const detectedBundlerTechReact = yield detectBundler(mappedJsonFileReact, "react", Number((_a = cmd.csMastTechDetectThreshold) !== null && _a !== void 0 ? _a : 50));
|
|
159
|
+
if (detectedBundlerTechReact) {
|
|
160
|
+
const refactorOutputDirReact = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
161
|
+
if (fs.existsSync(refactorOutputDirReact))
|
|
162
|
+
fs.rmSync(refactorOutputDirReact, { recursive: true });
|
|
163
|
+
console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechReact})...`));
|
|
164
|
+
resetSkipStep();
|
|
165
|
+
yield Promise.race([
|
|
166
|
+
refactor(mappedJsonFileReact, refactorOutputDirReact, detectedBundlerTechReact, false),
|
|
167
|
+
getSkipStepPromise(),
|
|
168
|
+
]);
|
|
169
|
+
if (shouldSkipTarget())
|
|
170
|
+
return;
|
|
171
|
+
console.log(chalk.bgGreen("[+] Refactor complete."));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
|
|
175
|
+
}
|
|
168
176
|
}
|
|
169
177
|
else {
|
|
170
|
-
console.log(chalk.yellow("[!]
|
|
178
|
+
console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
|
|
171
179
|
}
|
|
172
180
|
console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
|
|
173
181
|
return;
|
|
@@ -205,7 +213,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
205
213
|
resetSkipStep();
|
|
206
214
|
// @ts-ignore
|
|
207
215
|
yield Promise.race([
|
|
208
|
-
analyze(cmd.rules || "", mappedJsonFileVue, "vue", false, openapiFile, false, analyzeFile),
|
|
216
|
+
analyze(cmd.rules || "", mappedJsonFileVue, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
209
217
|
getSkipStepPromise(),
|
|
210
218
|
]);
|
|
211
219
|
console.log(chalk.bgGreen("[+] Analyze complete."));
|
|
@@ -225,24 +233,29 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
225
233
|
console.log(chalk.bgGreen("[+] Report complete."));
|
|
226
234
|
if (shouldSkipTarget())
|
|
227
235
|
return;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
fs.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
236
|
+
if (!cmd.disableRefactor) {
|
|
237
|
+
console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
|
|
238
|
+
const detectedBundlerTechVue = yield detectBundler(mappedJsonFileVue, "vue", Number((_b = cmd.csMastTechDetectThreshold) !== null && _b !== void 0 ? _b : 50));
|
|
239
|
+
if (detectedBundlerTechVue) {
|
|
240
|
+
const refactorOutputDirVue = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
241
|
+
if (fs.existsSync(refactorOutputDirVue))
|
|
242
|
+
fs.rmSync(refactorOutputDirVue, { recursive: true });
|
|
243
|
+
console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechVue})...`));
|
|
244
|
+
resetSkipStep();
|
|
245
|
+
yield Promise.race([
|
|
246
|
+
refactor(mappedJsonFileVue, refactorOutputDirVue, detectedBundlerTechVue, false),
|
|
247
|
+
getSkipStepPromise(),
|
|
248
|
+
]);
|
|
249
|
+
if (shouldSkipTarget())
|
|
250
|
+
return;
|
|
251
|
+
console.log(chalk.bgGreen("[+] Refactor complete."));
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
|
|
255
|
+
}
|
|
243
256
|
}
|
|
244
257
|
else {
|
|
245
|
-
console.log(chalk.yellow("[!]
|
|
258
|
+
console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
|
|
246
259
|
}
|
|
247
260
|
console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
|
|
248
261
|
return;
|
|
@@ -278,7 +291,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
278
291
|
resetSkipStep();
|
|
279
292
|
// @ts-ignore
|
|
280
293
|
yield Promise.race([
|
|
281
|
-
analyze(cmd.rules || "", mappedJsonFileNuxt, "vue", false, openapiFile, false, analyzeFile),
|
|
294
|
+
analyze(cmd.rules || "", mappedJsonFileNuxt, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
282
295
|
getSkipStepPromise(),
|
|
283
296
|
]);
|
|
284
297
|
console.log(chalk.bgGreen("[+] Analyze complete."));
|
|
@@ -297,24 +310,29 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
297
310
|
console.log(chalk.bgGreen("[+] Report complete."));
|
|
298
311
|
if (shouldSkipTarget())
|
|
299
312
|
return;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
fs.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
if (!cmd.disableRefactor) {
|
|
314
|
+
console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
|
|
315
|
+
const detectedBundlerTechNuxt = yield detectBundler(mappedJsonFileNuxt, "nuxt", Number((_c = cmd.csMastTechDetectThreshold) !== null && _c !== void 0 ? _c : 50));
|
|
316
|
+
if (detectedBundlerTechNuxt) {
|
|
317
|
+
const refactorOutputDirNuxt = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
318
|
+
if (fs.existsSync(refactorOutputDirNuxt))
|
|
319
|
+
fs.rmSync(refactorOutputDirNuxt, { recursive: true });
|
|
320
|
+
console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechNuxt})...`));
|
|
321
|
+
resetSkipStep();
|
|
322
|
+
yield Promise.race([
|
|
323
|
+
refactor(mappedJsonFileNuxt, refactorOutputDirNuxt, detectedBundlerTechNuxt, false),
|
|
324
|
+
getSkipStepPromise(),
|
|
325
|
+
]);
|
|
326
|
+
if (shouldSkipTarget())
|
|
327
|
+
return;
|
|
328
|
+
console.log(chalk.bgGreen("[+] Refactor complete."));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
|
|
332
|
+
}
|
|
315
333
|
}
|
|
316
334
|
else {
|
|
317
|
-
console.log(chalk.yellow("[!]
|
|
335
|
+
console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
|
|
318
336
|
}
|
|
319
337
|
console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
|
|
320
338
|
return;
|
|
@@ -349,7 +367,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
349
367
|
resetSkipStep();
|
|
350
368
|
// @ts-ignore
|
|
351
369
|
yield Promise.race([
|
|
352
|
-
analyze(cmd.rules || "", mappedJsonFileSvelte, "svelte", false, openapiFile, false, analyzeFile),
|
|
370
|
+
analyze(cmd.rules || "", mappedJsonFileSvelte, "svelte", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
353
371
|
getSkipStepPromise(),
|
|
354
372
|
]);
|
|
355
373
|
console.log(chalk.bgGreen("[+] Analyze complete."));
|
|
@@ -403,7 +421,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
403
421
|
resetSkipStep();
|
|
404
422
|
// @ts-ignore
|
|
405
423
|
yield Promise.race([
|
|
406
|
-
analyze(cmd.rules || "", mappedJsonFileAngular, "angular", false, openapiFile, false, analyzeFile),
|
|
424
|
+
analyze(cmd.rules || "", mappedJsonFileAngular, "angular", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
407
425
|
getSkipStepPromise(),
|
|
408
426
|
]);
|
|
409
427
|
console.log(chalk.bgGreen("[+] Analyze complete."));
|
|
@@ -527,8 +545,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
527
545
|
console.log(chalk.bgCyan("[7/8] Running analyze to extract endpoints..."));
|
|
528
546
|
resetSkipStep();
|
|
529
547
|
yield Promise.race([
|
|
530
|
-
|
|
531
|
-
analyze(cmd.rules || "", mappedJsonFile, detectedTech, false, openapiFile, false, analyzeFile),
|
|
548
|
+
analyze(cmd.rules || "", mappedJsonFile, detectedTech, false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
532
549
|
getSkipStepPromise(),
|
|
533
550
|
]);
|
|
534
551
|
console.log(chalk.bgGreen("[+] Analyze complete."));
|
|
@@ -543,24 +560,29 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
543
560
|
console.log(chalk.bgGreen("[+] Report complete."));
|
|
544
561
|
if (shouldSkipTarget())
|
|
545
562
|
return;
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
fs.
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
563
|
+
if (!cmd.disableRefactor) {
|
|
564
|
+
console.log(chalk.bgCyan("[*] Detecting bundler via CS-MAST-S for refactor..."));
|
|
565
|
+
const detectedBundlerTechNext = yield detectBundler(mappedJsonFile, detectedTech, Number((_d = cmd.csMastTechDetectThreshold) !== null && _d !== void 0 ? _d : 50));
|
|
566
|
+
if (detectedBundlerTechNext) {
|
|
567
|
+
const refactorOutputDirNext = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
568
|
+
if (fs.existsSync(refactorOutputDirNext))
|
|
569
|
+
fs.rmSync(refactorOutputDirNext, { recursive: true });
|
|
570
|
+
console.log(chalk.bgCyan(`[*] Running refactor (${detectedBundlerTechNext})...`));
|
|
571
|
+
resetSkipStep();
|
|
572
|
+
yield Promise.race([
|
|
573
|
+
refactor(mappedJsonFile, refactorOutputDirNext, detectedBundlerTechNext, false),
|
|
574
|
+
getSkipStepPromise(),
|
|
575
|
+
]);
|
|
576
|
+
if (shouldSkipTarget())
|
|
577
|
+
return;
|
|
578
|
+
console.log(chalk.bgGreen("[+] Refactor complete."));
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
console.log(chalk.yellow("[!] Bundler not detected via CS-MAST-S, skipping refactor."));
|
|
582
|
+
}
|
|
561
583
|
}
|
|
562
584
|
else {
|
|
563
|
-
console.log(chalk.yellow("[!]
|
|
585
|
+
console.log(chalk.yellow("[!] Refactor step disabled via --disable-refactor, skipping."));
|
|
564
586
|
}
|
|
565
587
|
console.log(chalk.bgGreenBright(`[+] Analysis complete for ${url}.`));
|
|
566
588
|
});
|
|
@@ -576,8 +598,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
576
598
|
*/
|
|
577
599
|
export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
578
600
|
var _a, _b, _c, _d, _e;
|
|
579
|
-
|
|
580
|
-
globalsUtil.setUseApiGateway(cmd.apiGateway);
|
|
601
|
+
configureProxy(cmd);
|
|
581
602
|
globalsUtil.setDisableCache(cmd.disableCache);
|
|
582
603
|
globalsUtil.setRespCacheFile(cmd.cacheFile);
|
|
583
604
|
globalsUtil.setYes(cmd.yes);
|
|
@@ -612,6 +633,8 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
612
633
|
if (!fs.existsSync(cmd.output)) {
|
|
613
634
|
fs.mkdirSync(cmd.output, { recursive: true });
|
|
614
635
|
}
|
|
636
|
+
const globalDbPath = `${cmd.output}/js-recon.db`;
|
|
637
|
+
yield initGlobalReportDb(globalDbPath);
|
|
615
638
|
for (const url of urls) {
|
|
616
639
|
resetSkipTarget();
|
|
617
640
|
// Validate URL only
|
|
@@ -632,10 +655,23 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
632
655
|
}
|
|
633
656
|
fs.mkdirSync(thisTargetDir, { recursive: true });
|
|
634
657
|
yield processUrl(url, thisTargetDir, thisTargetDir, cmd, true, (_c = cmd._includeMethods) !== null && _c !== void 0 ? _c : [], (_d = cmd._excludeMethods) !== null && _d !== void 0 ? _d : []);
|
|
658
|
+
const domainDbPath = `${thisTargetDir}/js-recon.db`;
|
|
659
|
+
if (fs.existsSync(domainDbPath)) {
|
|
660
|
+
try {
|
|
661
|
+
mergeDomainIntoGlobalDb(globalDbPath, domainDbPath, hostDir);
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
console.error(chalk.yellow(`[!] Failed to merge ${hostDir} into the global js-recon.db: ${error}`));
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
console.log(chalk.yellow(`[i] No js-recon.db found for ${hostDir}, skipping merge into the global database.`));
|
|
669
|
+
}
|
|
635
670
|
}
|
|
636
671
|
}
|
|
637
672
|
}
|
|
638
673
|
finally {
|
|
674
|
+
yield waitForPendingInterrupt();
|
|
639
675
|
removeSigintHandler();
|
|
640
676
|
process.exit((_e = process.exitCode) !== null && _e !== void 0 ? _e : 0);
|
|
641
677
|
}
|