@node9/proxy 1.10.1 → 1.10.3
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/README.md +105 -4
- package/dist/cli.js +2300 -480
- package/dist/cli.mjs +2279 -458
- package/dist/index.js +52 -8
- package/dist/index.mjs +52 -8
- package/dist/shields/builtin/bash-safe.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -239,7 +239,8 @@ var ConfigFileSchema = import_zod.z.object({
|
|
|
239
239
|
enableTrustSessions: import_zod.z.boolean().optional(),
|
|
240
240
|
allowGlobalPause: import_zod.z.boolean().optional(),
|
|
241
241
|
auditHashArgs: import_zod.z.boolean().optional(),
|
|
242
|
-
agentPolicy: import_zod.z.enum(["require_approval", "block_on_rules"]).optional()
|
|
242
|
+
agentPolicy: import_zod.z.enum(["require_approval", "block_on_rules"]).optional(),
|
|
243
|
+
cloudSyncIntervalHours: import_zod.z.number().positive().optional()
|
|
243
244
|
}).optional(),
|
|
244
245
|
policy: import_zod.z.object({
|
|
245
246
|
sandboxPaths: import_zod.z.array(import_zod.z.string()).optional(),
|
|
@@ -441,7 +442,8 @@ var DEFAULT_CONFIG = {
|
|
|
441
442
|
// 120-second auto-deny timeout
|
|
442
443
|
flightRecorder: true,
|
|
443
444
|
auditHashArgs: true,
|
|
444
|
-
approvers: { native: true, browser: true, cloud: false, terminal: true }
|
|
445
|
+
approvers: { native: true, browser: true, cloud: false, terminal: true },
|
|
446
|
+
cloudSyncIntervalHours: 5
|
|
445
447
|
},
|
|
446
448
|
policy: {
|
|
447
449
|
sandboxPaths: ["/tmp/**", "**/sandbox/**", "**/test-results/**"],
|
|
@@ -756,6 +758,8 @@ function getConfig(cwd) {
|
|
|
756
758
|
if (s.approvalTimeoutSeconds !== void 0 && s.approvalTimeoutMs === void 0)
|
|
757
759
|
mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
|
|
758
760
|
if (s.environment !== void 0) mergedSettings.environment = s.environment;
|
|
761
|
+
if (s.cloudSyncIntervalHours !== void 0)
|
|
762
|
+
mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
|
|
759
763
|
if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
|
|
760
764
|
if (p.sandboxPaths) mergedPolicy.sandboxPaths.push(...p.sandboxPaths);
|
|
761
765
|
if (p.ignoredTools) mergedPolicy.ignoredTools.push(...p.ignoredTools);
|
|
@@ -765,7 +769,12 @@ function getConfig(cwd) {
|
|
|
765
769
|
if (p.smartRules) {
|
|
766
770
|
const defaultBlocks = mergedPolicy.smartRules.filter((r) => r.verdict === "block");
|
|
767
771
|
const defaultNonBlocks = mergedPolicy.smartRules.filter((r) => r.verdict !== "block");
|
|
768
|
-
|
|
772
|
+
const userRuleNames = new Set(p.smartRules.filter((r) => r.name).map((r) => r.name));
|
|
773
|
+
const filteredBlocks = defaultBlocks.filter((r) => !r.name || !userRuleNames.has(r.name));
|
|
774
|
+
const filteredNonBlocks = defaultNonBlocks.filter(
|
|
775
|
+
(r) => !r.name || !userRuleNames.has(r.name)
|
|
776
|
+
);
|
|
777
|
+
mergedPolicy.smartRules = [...filteredBlocks, ...p.smartRules, ...filteredNonBlocks];
|
|
769
778
|
}
|
|
770
779
|
if (p.snapshot) {
|
|
771
780
|
const s2 = p.snapshot;
|
|
@@ -799,6 +808,16 @@ function getConfig(cwd) {
|
|
|
799
808
|
};
|
|
800
809
|
applyLayer(globalConfig);
|
|
801
810
|
applyLayer(projectConfig);
|
|
811
|
+
{
|
|
812
|
+
const cacheFile = import_path3.default.join(import_os3.default.homedir(), ".node9", "rules-cache.json");
|
|
813
|
+
try {
|
|
814
|
+
const raw = JSON.parse(import_fs3.default.readFileSync(cacheFile, "utf-8"));
|
|
815
|
+
if (Array.isArray(raw.rules) && raw.rules.length > 0) {
|
|
816
|
+
applyLayer({ policy: { smartRules: raw.rules } });
|
|
817
|
+
}
|
|
818
|
+
} catch {
|
|
819
|
+
}
|
|
820
|
+
}
|
|
802
821
|
const shieldOverrides = readShieldOverrides();
|
|
803
822
|
for (const shieldName of readActiveShields()) {
|
|
804
823
|
const shield = getShield(shieldName);
|
|
@@ -1990,19 +2009,44 @@ function getInternalToken() {
|
|
|
1990
2009
|
function isDaemonRunning() {
|
|
1991
2010
|
const pidFile = import_path10.default.join(import_os7.default.homedir(), ".node9", "daemon.pid");
|
|
1992
2011
|
if (import_fs8.default.existsSync(pidFile)) {
|
|
2012
|
+
let pid;
|
|
2013
|
+
let port;
|
|
1993
2014
|
try {
|
|
1994
|
-
const
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
return true;
|
|
2015
|
+
const data = JSON.parse(import_fs8.default.readFileSync(pidFile, "utf-8"));
|
|
2016
|
+
pid = data.pid;
|
|
2017
|
+
port = data.port;
|
|
1998
2018
|
} catch {
|
|
1999
2019
|
return false;
|
|
2000
2020
|
}
|
|
2021
|
+
if (port !== DAEMON_PORT) {
|
|
2022
|
+
return false;
|
|
2023
|
+
}
|
|
2024
|
+
const MAX_PID = 4194304;
|
|
2025
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || pid > MAX_PID) {
|
|
2026
|
+
return false;
|
|
2027
|
+
}
|
|
2028
|
+
try {
|
|
2029
|
+
process.kill(pid, 0);
|
|
2030
|
+
} catch (err) {
|
|
2031
|
+
if (err instanceof Error && "code" in err && err.code === "ESRCH") {
|
|
2032
|
+
try {
|
|
2033
|
+
import_fs8.default.unlinkSync(pidFile);
|
|
2034
|
+
} catch {
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
return false;
|
|
2038
|
+
}
|
|
2039
|
+
const r = (0, import_child_process.spawnSync)("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
|
|
2040
|
+
encoding: "utf8",
|
|
2041
|
+
timeout: 300
|
|
2042
|
+
});
|
|
2043
|
+
if (r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`)) return true;
|
|
2044
|
+
return false;
|
|
2001
2045
|
}
|
|
2002
2046
|
try {
|
|
2003
2047
|
const r = (0, import_child_process.spawnSync)("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
|
|
2004
2048
|
encoding: "utf8",
|
|
2005
|
-
timeout:
|
|
2049
|
+
timeout: 300
|
|
2006
2050
|
});
|
|
2007
2051
|
return r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`);
|
|
2008
2052
|
} catch {
|
package/dist/index.mjs
CHANGED
|
@@ -209,7 +209,8 @@ var ConfigFileSchema = z.object({
|
|
|
209
209
|
enableTrustSessions: z.boolean().optional(),
|
|
210
210
|
allowGlobalPause: z.boolean().optional(),
|
|
211
211
|
auditHashArgs: z.boolean().optional(),
|
|
212
|
-
agentPolicy: z.enum(["require_approval", "block_on_rules"]).optional()
|
|
212
|
+
agentPolicy: z.enum(["require_approval", "block_on_rules"]).optional(),
|
|
213
|
+
cloudSyncIntervalHours: z.number().positive().optional()
|
|
213
214
|
}).optional(),
|
|
214
215
|
policy: z.object({
|
|
215
216
|
sandboxPaths: z.array(z.string()).optional(),
|
|
@@ -411,7 +412,8 @@ var DEFAULT_CONFIG = {
|
|
|
411
412
|
// 120-second auto-deny timeout
|
|
412
413
|
flightRecorder: true,
|
|
413
414
|
auditHashArgs: true,
|
|
414
|
-
approvers: { native: true, browser: true, cloud: false, terminal: true }
|
|
415
|
+
approvers: { native: true, browser: true, cloud: false, terminal: true },
|
|
416
|
+
cloudSyncIntervalHours: 5
|
|
415
417
|
},
|
|
416
418
|
policy: {
|
|
417
419
|
sandboxPaths: ["/tmp/**", "**/sandbox/**", "**/test-results/**"],
|
|
@@ -726,6 +728,8 @@ function getConfig(cwd) {
|
|
|
726
728
|
if (s.approvalTimeoutSeconds !== void 0 && s.approvalTimeoutMs === void 0)
|
|
727
729
|
mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
|
|
728
730
|
if (s.environment !== void 0) mergedSettings.environment = s.environment;
|
|
731
|
+
if (s.cloudSyncIntervalHours !== void 0)
|
|
732
|
+
mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
|
|
729
733
|
if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
|
|
730
734
|
if (p.sandboxPaths) mergedPolicy.sandboxPaths.push(...p.sandboxPaths);
|
|
731
735
|
if (p.ignoredTools) mergedPolicy.ignoredTools.push(...p.ignoredTools);
|
|
@@ -735,7 +739,12 @@ function getConfig(cwd) {
|
|
|
735
739
|
if (p.smartRules) {
|
|
736
740
|
const defaultBlocks = mergedPolicy.smartRules.filter((r) => r.verdict === "block");
|
|
737
741
|
const defaultNonBlocks = mergedPolicy.smartRules.filter((r) => r.verdict !== "block");
|
|
738
|
-
|
|
742
|
+
const userRuleNames = new Set(p.smartRules.filter((r) => r.name).map((r) => r.name));
|
|
743
|
+
const filteredBlocks = defaultBlocks.filter((r) => !r.name || !userRuleNames.has(r.name));
|
|
744
|
+
const filteredNonBlocks = defaultNonBlocks.filter(
|
|
745
|
+
(r) => !r.name || !userRuleNames.has(r.name)
|
|
746
|
+
);
|
|
747
|
+
mergedPolicy.smartRules = [...filteredBlocks, ...p.smartRules, ...filteredNonBlocks];
|
|
739
748
|
}
|
|
740
749
|
if (p.snapshot) {
|
|
741
750
|
const s2 = p.snapshot;
|
|
@@ -769,6 +778,16 @@ function getConfig(cwd) {
|
|
|
769
778
|
};
|
|
770
779
|
applyLayer(globalConfig);
|
|
771
780
|
applyLayer(projectConfig);
|
|
781
|
+
{
|
|
782
|
+
const cacheFile = path3.join(os3.homedir(), ".node9", "rules-cache.json");
|
|
783
|
+
try {
|
|
784
|
+
const raw = JSON.parse(fs3.readFileSync(cacheFile, "utf-8"));
|
|
785
|
+
if (Array.isArray(raw.rules) && raw.rules.length > 0) {
|
|
786
|
+
applyLayer({ policy: { smartRules: raw.rules } });
|
|
787
|
+
}
|
|
788
|
+
} catch {
|
|
789
|
+
}
|
|
790
|
+
}
|
|
772
791
|
const shieldOverrides = readShieldOverrides();
|
|
773
792
|
for (const shieldName of readActiveShields()) {
|
|
774
793
|
const shield = getShield(shieldName);
|
|
@@ -1960,19 +1979,44 @@ function getInternalToken() {
|
|
|
1960
1979
|
function isDaemonRunning() {
|
|
1961
1980
|
const pidFile = path10.join(os7.homedir(), ".node9", "daemon.pid");
|
|
1962
1981
|
if (fs8.existsSync(pidFile)) {
|
|
1982
|
+
let pid;
|
|
1983
|
+
let port;
|
|
1963
1984
|
try {
|
|
1964
|
-
const
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
return true;
|
|
1985
|
+
const data = JSON.parse(fs8.readFileSync(pidFile, "utf-8"));
|
|
1986
|
+
pid = data.pid;
|
|
1987
|
+
port = data.port;
|
|
1968
1988
|
} catch {
|
|
1969
1989
|
return false;
|
|
1970
1990
|
}
|
|
1991
|
+
if (port !== DAEMON_PORT) {
|
|
1992
|
+
return false;
|
|
1993
|
+
}
|
|
1994
|
+
const MAX_PID = 4194304;
|
|
1995
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || pid > MAX_PID) {
|
|
1996
|
+
return false;
|
|
1997
|
+
}
|
|
1998
|
+
try {
|
|
1999
|
+
process.kill(pid, 0);
|
|
2000
|
+
} catch (err) {
|
|
2001
|
+
if (err instanceof Error && "code" in err && err.code === "ESRCH") {
|
|
2002
|
+
try {
|
|
2003
|
+
fs8.unlinkSync(pidFile);
|
|
2004
|
+
} catch {
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
return false;
|
|
2008
|
+
}
|
|
2009
|
+
const r = spawnSync("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
|
|
2010
|
+
encoding: "utf8",
|
|
2011
|
+
timeout: 300
|
|
2012
|
+
});
|
|
2013
|
+
if (r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`)) return true;
|
|
2014
|
+
return false;
|
|
1971
2015
|
}
|
|
1972
2016
|
try {
|
|
1973
2017
|
const r = spawnSync("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
|
|
1974
2018
|
encoding: "utf8",
|
|
1975
|
-
timeout:
|
|
2019
|
+
timeout: 300
|
|
1976
2020
|
});
|
|
1977
2021
|
return r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`);
|
|
1978
2022
|
} catch {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"field": "command",
|
|
12
12
|
"op": "matches",
|
|
13
|
-
"value": "(curl|wget)\\s+[^|]*\\|\\s*(bash|sh|zsh|fish|python3?|ruby|perl|node)",
|
|
13
|
+
"value": "(curl|wget)\\s+[^|]*\\|\\s*(?:(bash|sh|zsh|fish)|(python3?|ruby|perl|node)\\b(?!\\s+-[cem]\\b))",
|
|
14
14
|
"flags": "i"
|
|
15
15
|
}
|
|
16
16
|
],
|