@schuttdev/gigai 0.4.0-beta.0 → 0.4.0-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/dist/{chunk-WUAGWZNA.js → chunk-2M2DRMA6.js} +11 -4
- package/dist/{chunk-FR2BGYIC.js → chunk-MMSQIOZJ.js} +5 -4
- package/dist/{chunk-XL27JFUS.js → chunk-RATFNHIS.js} +55 -3
- package/dist/{dist-SDKK67CH.js → dist-NRIA4Z27.js} +8 -7
- package/dist/{filesystem-FTLLT7JC-3DA3AAA7.js → filesystem-XG5X7226-QQZ5PZ5D.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{shell-F2MZGP6N-WUIBVJZF.js → shell-VQR5PWIE-DJ2D4RTS.js} +2 -2
- package/package.json +1 -1
|
@@ -3,10 +3,12 @@ import {
|
|
|
3
3
|
ErrorCode,
|
|
4
4
|
GigaiError,
|
|
5
5
|
canExecuteCommand,
|
|
6
|
-
canUseSudo
|
|
7
|
-
|
|
6
|
+
canUseSudo,
|
|
7
|
+
expandTilde,
|
|
8
|
+
validateCommandArgs
|
|
9
|
+
} from "./chunk-RATFNHIS.js";
|
|
8
10
|
|
|
9
|
-
// ../server/dist/chunk-
|
|
11
|
+
// ../server/dist/chunk-DC6XGDGZ.mjs
|
|
10
12
|
import { spawn } from "child_process";
|
|
11
13
|
var MAX_OUTPUT_SIZE = 10 * 1024 * 1024;
|
|
12
14
|
async function execCommandSafe(command, args, config, tier = "strict") {
|
|
@@ -20,13 +22,18 @@ async function execCommandSafe(command, args, config, tier = "strict") {
|
|
|
20
22
|
if (!check.allowed) {
|
|
21
23
|
throw new GigaiError(ErrorCode.COMMAND_NOT_ALLOWED, check.reason);
|
|
22
24
|
}
|
|
25
|
+
const argCheck = validateCommandArgs(tier, command, args);
|
|
26
|
+
if (!argCheck.allowed) {
|
|
27
|
+
throw new GigaiError(ErrorCode.COMMAND_NOT_ALLOWED, argCheck.reason);
|
|
28
|
+
}
|
|
23
29
|
for (const arg of args) {
|
|
24
30
|
if (arg.includes("\0")) {
|
|
25
31
|
throw new GigaiError(ErrorCode.VALIDATION_ERROR, "Null byte in argument");
|
|
26
32
|
}
|
|
27
33
|
}
|
|
34
|
+
const expandedArgs = args.map(expandTilde);
|
|
28
35
|
return new Promise((resolve, reject) => {
|
|
29
|
-
const child = spawn(command,
|
|
36
|
+
const child = spawn(command, expandedArgs, {
|
|
30
37
|
shell: false,
|
|
31
38
|
stdio: ["ignore", "pipe", "pipe"]
|
|
32
39
|
});
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ErrorCode,
|
|
4
4
|
GigaiError,
|
|
5
|
-
canAccessPath
|
|
6
|
-
|
|
5
|
+
canAccessPath,
|
|
6
|
+
expandTilde
|
|
7
|
+
} from "./chunk-RATFNHIS.js";
|
|
7
8
|
|
|
8
|
-
// ../server/dist/chunk-
|
|
9
|
+
// ../server/dist/chunk-5JL7OKOY.mjs
|
|
9
10
|
import {
|
|
10
11
|
readFile as fsReadFile,
|
|
11
12
|
writeFile as fsWriteFile,
|
|
@@ -17,7 +18,7 @@ import { spawn } from "child_process";
|
|
|
17
18
|
var MAX_OUTPUT_SIZE = 10 * 1024 * 1024;
|
|
18
19
|
var MAX_READ_SIZE = 2 * 1024 * 1024;
|
|
19
20
|
async function validatePath(targetPath, allowedPaths, tier = "strict") {
|
|
20
|
-
const resolved = resolve(targetPath);
|
|
21
|
+
const resolved = resolve(expandTilde(targetPath));
|
|
21
22
|
let real;
|
|
22
23
|
try {
|
|
23
24
|
real = await realpath(resolved);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// ../server/dist/chunk-
|
|
3
|
+
// ../server/dist/chunk-2UGW2XVV.mjs
|
|
4
4
|
import { resolve } from "path";
|
|
5
|
-
import {
|
|
5
|
+
import { userInfo } from "os";
|
|
6
|
+
var SERVER_HOME = userInfo().homedir;
|
|
6
7
|
var DEFAULT_SECURITY = { default: "strict", overrides: {} };
|
|
7
8
|
function getEffectiveTier(config, toolName) {
|
|
8
9
|
const c = config ?? DEFAULT_SECURITY;
|
|
@@ -93,6 +94,48 @@ function canExecuteCommand(tier, command, allowlist) {
|
|
|
93
94
|
return { allowed: true };
|
|
94
95
|
}
|
|
95
96
|
}
|
|
97
|
+
var PROTECTED_PATHS = /* @__PURE__ */ new Set([
|
|
98
|
+
"/",
|
|
99
|
+
"/bin",
|
|
100
|
+
"/boot",
|
|
101
|
+
"/dev",
|
|
102
|
+
"/etc",
|
|
103
|
+
"/home",
|
|
104
|
+
"/lib",
|
|
105
|
+
"/opt",
|
|
106
|
+
"/proc",
|
|
107
|
+
"/root",
|
|
108
|
+
"/sbin",
|
|
109
|
+
"/sys",
|
|
110
|
+
"/usr",
|
|
111
|
+
"/var",
|
|
112
|
+
"/Users",
|
|
113
|
+
"/System",
|
|
114
|
+
"/Library",
|
|
115
|
+
"/Applications"
|
|
116
|
+
]);
|
|
117
|
+
function hasRecursiveFlag(args) {
|
|
118
|
+
for (const a of args) {
|
|
119
|
+
if (a === "--") break;
|
|
120
|
+
if (a === "-r" || a === "-R" || a === "--recursive") return true;
|
|
121
|
+
if (a.startsWith("-") && !a.startsWith("--") && /[rR]/.test(a)) return true;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
function validateCommandArgs(tier, command, args) {
|
|
126
|
+
if (tier === "unrestricted") return { allowed: true };
|
|
127
|
+
if (command === "rm" && hasRecursiveFlag(args)) {
|
|
128
|
+
const home = SERVER_HOME;
|
|
129
|
+
for (const arg of args) {
|
|
130
|
+
if (arg.startsWith("-")) continue;
|
|
131
|
+
const resolved = resolve(arg);
|
|
132
|
+
if (PROTECTED_PATHS.has(resolved) || resolved === home) {
|
|
133
|
+
return { allowed: false, reason: `Refusing to recursively remove critical path: ${resolved}` };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return { allowed: true };
|
|
138
|
+
}
|
|
96
139
|
function canUseSudo(allowSudo) {
|
|
97
140
|
if (allowSudo === false) return { allowed: false, reason: "sudo is not allowed" };
|
|
98
141
|
return { allowed: true };
|
|
@@ -123,7 +166,7 @@ function canAccessPath(tier, resolvedPath, allowedPaths) {
|
|
|
123
166
|
return { allowed: true };
|
|
124
167
|
}
|
|
125
168
|
case "standard": {
|
|
126
|
-
const home =
|
|
169
|
+
const home = SERVER_HOME;
|
|
127
170
|
for (const blocked of STANDARD_BLOCKED_PATHS) {
|
|
128
171
|
const full = resolve(home, blocked);
|
|
129
172
|
if (resolvedPath === full || resolvedPath.startsWith(full + "/")) {
|
|
@@ -136,6 +179,13 @@ function canAccessPath(tier, resolvedPath, allowedPaths) {
|
|
|
136
179
|
return { allowed: true };
|
|
137
180
|
}
|
|
138
181
|
}
|
|
182
|
+
function expandTilde(p) {
|
|
183
|
+
if (p === "~") return SERVER_HOME;
|
|
184
|
+
if (p.startsWith("~/")) return SERVER_HOME + p.slice(1);
|
|
185
|
+
if (p === "/root") return SERVER_HOME;
|
|
186
|
+
if (p.startsWith("/root/")) return SERVER_HOME + p.slice(5);
|
|
187
|
+
return p;
|
|
188
|
+
}
|
|
139
189
|
function shouldInjectSeparator(tier) {
|
|
140
190
|
return tier === "strict";
|
|
141
191
|
}
|
|
@@ -408,8 +458,10 @@ var GigaiConfigSchema = z.object({
|
|
|
408
458
|
export {
|
|
409
459
|
getEffectiveTier,
|
|
410
460
|
canExecuteCommand,
|
|
461
|
+
validateCommandArgs,
|
|
411
462
|
canUseSudo,
|
|
412
463
|
canAccessPath,
|
|
464
|
+
expandTilde,
|
|
413
465
|
shouldInjectSeparator,
|
|
414
466
|
encrypt,
|
|
415
467
|
decrypt,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
execCommandSafe
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2M2DRMA6.js";
|
|
5
5
|
import {
|
|
6
6
|
editBuiltin,
|
|
7
7
|
globBuiltin,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
readFileSafe,
|
|
12
12
|
searchFilesSafe,
|
|
13
13
|
writeBuiltin
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-MMSQIOZJ.js";
|
|
15
15
|
import {
|
|
16
16
|
ErrorCode,
|
|
17
17
|
GigaiConfigSchema,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
generateEncryptionKey,
|
|
22
22
|
getEffectiveTier,
|
|
23
23
|
shouldInjectSeparator
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-RATFNHIS.js";
|
|
25
25
|
|
|
26
26
|
// ../server/dist/index.mjs
|
|
27
27
|
import { parseArgs } from "util";
|
|
@@ -48,7 +48,7 @@ import { nanoid as nanoid3 } from "nanoid";
|
|
|
48
48
|
import { dirname as dirname2 } from "path";
|
|
49
49
|
import { readFileSync } from "fs";
|
|
50
50
|
import { resolve as resolve2 } from "path";
|
|
51
|
-
import { platform, hostname as hostname2 } from "os";
|
|
51
|
+
import { platform, hostname as hostname2, userInfo } from "os";
|
|
52
52
|
import { platform as platform2 } from "os";
|
|
53
53
|
import { writeFile as writeFile2, readFile as readFile2, unlink, mkdir } from "fs/promises";
|
|
54
54
|
import { join } from "path";
|
|
@@ -800,7 +800,7 @@ var cronPlugin = fp5(async (server, opts) => {
|
|
|
800
800
|
const executor = async (tool, args) => {
|
|
801
801
|
const entry = server.registry.get(tool);
|
|
802
802
|
if (entry.type === "builtin") {
|
|
803
|
-
const { execCommandSafe: execCommandSafe2 } = await import("./shell-
|
|
803
|
+
const { execCommandSafe: execCommandSafe2 } = await import("./shell-VQR5PWIE-DJ2D4RTS.js");
|
|
804
804
|
const {
|
|
805
805
|
readFileSafe: readFileSafe2,
|
|
806
806
|
listDirSafe: listDirSafe2,
|
|
@@ -810,7 +810,7 @@ var cronPlugin = fp5(async (server, opts) => {
|
|
|
810
810
|
editBuiltin: editBuiltin2,
|
|
811
811
|
globBuiltin: globBuiltin2,
|
|
812
812
|
grepBuiltin: grepBuiltin2
|
|
813
|
-
} = await import("./filesystem-
|
|
813
|
+
} = await import("./filesystem-XG5X7226-QQZ5PZ5D.js");
|
|
814
814
|
const builtinConfig = entry.config.config ?? {};
|
|
815
815
|
switch (entry.config.builtin) {
|
|
816
816
|
case "filesystem": {
|
|
@@ -891,7 +891,8 @@ async function healthRoutes(server) {
|
|
|
891
891
|
version: startupVersion,
|
|
892
892
|
uptime: Date.now() - startTime,
|
|
893
893
|
platform: platform(),
|
|
894
|
-
hostname: hostname2()
|
|
894
|
+
hostname: hostname2(),
|
|
895
|
+
homeDir: userInfo().homedir
|
|
895
896
|
};
|
|
896
897
|
});
|
|
897
898
|
}
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { defineCommand, runMain } from "citty";
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
|
-
var VERSION = "0.4.0-beta.
|
|
7
|
+
var VERSION = "0.4.0-beta.2";
|
|
8
8
|
|
|
9
9
|
// src/index.ts
|
|
10
10
|
async function requireServer() {
|
|
11
11
|
try {
|
|
12
|
-
return await import("./dist-
|
|
12
|
+
return await import("./dist-NRIA4Z27.js");
|
|
13
13
|
} catch {
|
|
14
14
|
console.error("Server dependencies not installed.");
|
|
15
15
|
console.error("Run: npm install -g @schuttdev/gigai");
|