@axiom-lattice/gateway 2.1.101 → 2.1.102
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/.turbo/turbo-build.log +21 -17
- package/CHANGELOG.md +12 -0
- package/dist/chunk-R4ZO3HZ3.mjs +46 -0
- package/dist/chunk-R4ZO3HZ3.mjs.map +1 -0
- package/dist/index.js +289 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -60
- package/dist/index.mjs.map +1 -1
- package/dist/resources-3DGHISBZ.mjs +183 -0
- package/dist/resources-3DGHISBZ.mjs.map +1 -0
- package/package.json +6 -6
- package/src/controllers/__tests__/mime.test.ts +74 -0
- package/src/controllers/__tests__/resources.test.ts +99 -0
- package/src/controllers/resources.ts +252 -0
- package/src/controllers/sandbox.ts +1 -30
- package/src/controllers/workspace.ts +9 -36
- package/src/index.ts +24 -0
- package/src/routes/resource-routes.ts +24 -0
- package/src/utils/mime.ts +43 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/gateway@2.1.
|
|
2
|
+
> @axiom-lattice/gateway@2.1.102 build /home/runner/work/agentic/agentic/packages/gateway
|
|
3
3
|
> tsup src/index.ts --format cjs,esm --dts --clean --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -9,30 +9,34 @@
|
|
|
9
9
|
[34mCLI[39m Cleaning output folder
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
-
|
|
12
|
+
[warn] [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1m"import.meta" is not available with the "cjs" output format and will be empty[0m [empty-import-meta]
|
|
13
|
+
|
|
14
|
+
src/index.ts:194:33:
|
|
15
|
+
[37m 194 │ const __filename = fileURLToPath([32mimport.meta[37m.url);
|
|
16
|
+
╵ [32m~~~~~~~~~~~[0m
|
|
17
|
+
|
|
18
|
+
You need to set the output format to "esm" for "import.meta" to work correctly.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m271.42 KB[39m
|
|
13
22
|
[32mESM[39m [1mdist/sender-PX32VSHB.mjs [22m[32m873.00 B[39m
|
|
14
23
|
[32mESM[39m [1mdist/WechatChannelAdapter-WSDKR4OA.mjs [22m[32m8.27 KB[39m
|
|
15
24
|
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs [22m[32m6.42 KB[39m
|
|
16
25
|
[32mESM[39m [1mdist/a2a-ERG5RMUW.mjs [22m[32m15.95 KB[39m
|
|
17
|
-
[32mESM[39m [1mdist/
|
|
26
|
+
[32mESM[39m [1mdist/resources-3DGHISBZ.mjs [22m[32m8.12 KB[39m
|
|
27
|
+
[32mESM[39m [1mdist/chunk-R4ZO3HZ3.mjs [22m[32m1.44 KB[39m
|
|
28
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m575.75 KB[39m
|
|
18
29
|
[32mESM[39m [1mdist/sender-PX32VSHB.mjs.map [22m[32m2.07 KB[39m
|
|
19
30
|
[32mESM[39m [1mdist/WechatChannelAdapter-WSDKR4OA.mjs.map [22m[32m16.28 KB[39m
|
|
20
31
|
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs.map [22m[32m14.04 KB[39m
|
|
21
32
|
[32mESM[39m [1mdist/a2a-ERG5RMUW.mjs.map [22m[32m32.14 KB[39m
|
|
22
|
-
[32mESM[39m
|
|
23
|
-
[
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
[
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
You need to set the output format to "esm" for "import.meta" to work correctly.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[32mCJS[39m [1mdist/index.js [22m[32m309.50 KB[39m
|
|
33
|
-
[32mCJS[39m [1mdist/index.js.map [22m[32m640.11 KB[39m
|
|
34
|
-
[32mCJS[39m ⚡️ Build success in 507ms
|
|
33
|
+
[32mESM[39m [1mdist/resources-3DGHISBZ.mjs.map [22m[32m15.35 KB[39m
|
|
34
|
+
[32mESM[39m [1mdist/chunk-R4ZO3HZ3.mjs.map [22m[32m2.35 KB[39m
|
|
35
|
+
[32mESM[39m ⚡️ Build success in 520ms
|
|
36
|
+
[32mCJS[39m [1mdist/index.js [22m[32m320.15 KB[39m
|
|
37
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m658.17 KB[39m
|
|
38
|
+
[32mCJS[39m ⚡️ Build success in 535ms
|
|
35
39
|
[34mDTS[39m Build start
|
|
36
|
-
[32mDTS[39m ⚡️ Build success in
|
|
40
|
+
[32mDTS[39m ⚡️ Build success in 18706ms
|
|
37
41
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m7.57 KB[39m
|
|
38
42
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m7.57 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @axiom-lattice/gateway
|
|
2
2
|
|
|
3
|
+
## 2.1.102
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f2dce99: fix bugs
|
|
8
|
+
- Updated dependencies [f2dce99]
|
|
9
|
+
- @axiom-lattice/agent-eval@2.1.84
|
|
10
|
+
- @axiom-lattice/core@2.1.90
|
|
11
|
+
- @axiom-lattice/pg-stores@1.0.81
|
|
12
|
+
- @axiom-lattice/protocols@2.1.45
|
|
13
|
+
- @axiom-lattice/queue-redis@1.0.44
|
|
14
|
+
|
|
3
15
|
## 2.1.101
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/utils/mime.ts
|
|
2
|
+
var EXT_TO_MIME = {
|
|
3
|
+
".txt": "text/plain",
|
|
4
|
+
".html": "text/html",
|
|
5
|
+
".htm": "text/html",
|
|
6
|
+
".css": "text/css",
|
|
7
|
+
".js": "application/javascript",
|
|
8
|
+
".mjs": "application/javascript",
|
|
9
|
+
".json": "application/json",
|
|
10
|
+
".pdf": "application/pdf",
|
|
11
|
+
".png": "image/png",
|
|
12
|
+
".jpg": "image/jpeg",
|
|
13
|
+
".jpeg": "image/jpeg",
|
|
14
|
+
".gif": "image/gif",
|
|
15
|
+
".webp": "image/webp",
|
|
16
|
+
".svg": "image/svg+xml",
|
|
17
|
+
".ico": "image/x-icon",
|
|
18
|
+
".zip": "application/zip",
|
|
19
|
+
".csv": "text/csv",
|
|
20
|
+
".xml": "application/xml",
|
|
21
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
22
|
+
".xls": "application/vnd.ms-excel",
|
|
23
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
24
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
25
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
26
|
+
".doc": "application/msword",
|
|
27
|
+
".mp4": "video/mp4",
|
|
28
|
+
".webm": "video/webm",
|
|
29
|
+
".mp3": "audio/mpeg",
|
|
30
|
+
".wav": "audio/wav",
|
|
31
|
+
".ogg": "audio/ogg"
|
|
32
|
+
};
|
|
33
|
+
function getContentTypeFromFilename(filename) {
|
|
34
|
+
const ext = filename.includes(".") ? filename.slice(filename.lastIndexOf(".")).toLowerCase() : "";
|
|
35
|
+
return EXT_TO_MIME[ext] ?? "application/octet-stream";
|
|
36
|
+
}
|
|
37
|
+
function getFilenameFromPath(path) {
|
|
38
|
+
const segments = path.replace(/\/+$/, "").split("/");
|
|
39
|
+
return segments[segments.length - 1] || "download";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
getContentTypeFromFilename,
|
|
44
|
+
getFilenameFromPath
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=chunk-R4ZO3HZ3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/mime.ts"],"sourcesContent":["const EXT_TO_MIME: Record<string, string> = {\n \".txt\": \"text/plain\",\n \".html\": \"text/html\",\n \".htm\": \"text/html\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".json\": \"application/json\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".zip\": \"application/zip\",\n \".csv\": \"text/csv\",\n \".xml\": \"application/xml\",\n \".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \".xls\": \"application/vnd.ms-excel\",\n \".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \".ppt\": \"application/vnd.ms-powerpoint\",\n \".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".doc\": \"application/msword\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".ogg\": \"audio/ogg\",\n};\n\nexport function getContentTypeFromFilename(filename: string): string {\n const ext = filename.includes(\".\")\n ? filename.slice(filename.lastIndexOf(\".\")).toLowerCase()\n : \"\";\n return EXT_TO_MIME[ext] ?? \"application/octet-stream\";\n}\n\nexport function getFilenameFromPath(path: string): string {\n const segments = path.replace(/\\/+$/, \"\").split(\"/\");\n return segments[segments.length - 1] || \"download\";\n}\n"],"mappings":";AAAA,IAAM,cAAsC;AAAA,EAC1C,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,SAAS,2BAA2B,UAA0B;AACnE,QAAM,MAAM,SAAS,SAAS,GAAG,IAC7B,SAAS,MAAM,SAAS,YAAY,GAAG,CAAC,EAAE,YAAY,IACtD;AACJ,SAAO,YAAY,GAAG,KAAK;AAC7B;AAEO,SAAS,oBAAoB,MAAsB;AACxD,QAAM,WAAW,KAAK,QAAQ,QAAQ,EAAE,EAAE,MAAM,GAAG;AACnD,SAAO,SAAS,SAAS,SAAS,CAAC,KAAK;AAC1C;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,53 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
+
// src/utils/mime.ts
|
|
34
|
+
function getContentTypeFromFilename(filename) {
|
|
35
|
+
const ext = filename.includes(".") ? filename.slice(filename.lastIndexOf(".")).toLowerCase() : "";
|
|
36
|
+
return EXT_TO_MIME[ext] ?? "application/octet-stream";
|
|
37
|
+
}
|
|
38
|
+
function getFilenameFromPath(path3) {
|
|
39
|
+
const segments = path3.replace(/\/+$/, "").split("/");
|
|
40
|
+
return segments[segments.length - 1] || "download";
|
|
41
|
+
}
|
|
42
|
+
var EXT_TO_MIME;
|
|
43
|
+
var init_mime = __esm({
|
|
44
|
+
"src/utils/mime.ts"() {
|
|
45
|
+
"use strict";
|
|
46
|
+
EXT_TO_MIME = {
|
|
47
|
+
".txt": "text/plain",
|
|
48
|
+
".html": "text/html",
|
|
49
|
+
".htm": "text/html",
|
|
50
|
+
".css": "text/css",
|
|
51
|
+
".js": "application/javascript",
|
|
52
|
+
".mjs": "application/javascript",
|
|
53
|
+
".json": "application/json",
|
|
54
|
+
".pdf": "application/pdf",
|
|
55
|
+
".png": "image/png",
|
|
56
|
+
".jpg": "image/jpeg",
|
|
57
|
+
".jpeg": "image/jpeg",
|
|
58
|
+
".gif": "image/gif",
|
|
59
|
+
".webp": "image/webp",
|
|
60
|
+
".svg": "image/svg+xml",
|
|
61
|
+
".ico": "image/x-icon",
|
|
62
|
+
".zip": "application/zip",
|
|
63
|
+
".csv": "text/csv",
|
|
64
|
+
".xml": "application/xml",
|
|
65
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
66
|
+
".xls": "application/vnd.ms-excel",
|
|
67
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
68
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
69
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
70
|
+
".doc": "application/msword",
|
|
71
|
+
".mp4": "video/mp4",
|
|
72
|
+
".webm": "video/webm",
|
|
73
|
+
".mp3": "audio/mpeg",
|
|
74
|
+
".wav": "audio/wav",
|
|
75
|
+
".ogg": "audio/ogg"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
33
80
|
// src/logger/Logger.ts
|
|
34
81
|
var import_pino, import_pino_pretty, import_pino_roll, PinoLoggerFactory, Logger;
|
|
35
82
|
var init_Logger = __esm({
|
|
@@ -1145,6 +1192,190 @@ var init_a2a = __esm({
|
|
|
1145
1192
|
}
|
|
1146
1193
|
});
|
|
1147
1194
|
|
|
1195
|
+
// src/controllers/resources.ts
|
|
1196
|
+
var resources_exports = {};
|
|
1197
|
+
__export(resources_exports, {
|
|
1198
|
+
ResourceController: () => ResourceController
|
|
1199
|
+
});
|
|
1200
|
+
var import_core35, ResourceController;
|
|
1201
|
+
var init_resources = __esm({
|
|
1202
|
+
"src/controllers/resources.ts"() {
|
|
1203
|
+
"use strict";
|
|
1204
|
+
import_core35 = require("@axiom-lattice/core");
|
|
1205
|
+
init_mime();
|
|
1206
|
+
ResourceController = class {
|
|
1207
|
+
constructor(deps) {
|
|
1208
|
+
this.deps = deps;
|
|
1209
|
+
}
|
|
1210
|
+
async createShare(request, reply) {
|
|
1211
|
+
const userId = request.user ? request.user.id ?? "unknown" : "unknown";
|
|
1212
|
+
const tenantId = request.headers["x-tenant-id"] || "default";
|
|
1213
|
+
const workspaceId = request.headers["x-workspace-id"];
|
|
1214
|
+
const projectId = request.headers["x-project-id"];
|
|
1215
|
+
const body = request.body;
|
|
1216
|
+
if (!workspaceId || !projectId) {
|
|
1217
|
+
return reply.status(400).send({ error: "x-workspace-id and x-project-id headers required" });
|
|
1218
|
+
}
|
|
1219
|
+
const payload = (0, import_core35.createSharePayload)(
|
|
1220
|
+
tenantId,
|
|
1221
|
+
workspaceId,
|
|
1222
|
+
projectId,
|
|
1223
|
+
userId,
|
|
1224
|
+
body
|
|
1225
|
+
);
|
|
1226
|
+
const token = (0, import_core35.generateToken)();
|
|
1227
|
+
try {
|
|
1228
|
+
await this.deps.store.create({ ...payload, token });
|
|
1229
|
+
this.deps.logger.info(
|
|
1230
|
+
"Share created",
|
|
1231
|
+
{ token, resourcePath: body.resourcePath, userId }
|
|
1232
|
+
);
|
|
1233
|
+
} catch {
|
|
1234
|
+
return reply.status(500).send({ error: "Failed to create share" });
|
|
1235
|
+
}
|
|
1236
|
+
return reply.status(201).send({ token, url: `/s/${token}` });
|
|
1237
|
+
}
|
|
1238
|
+
async listShares(request, reply) {
|
|
1239
|
+
const userId = request.user ? request.user.id ?? "unknown" : "unknown";
|
|
1240
|
+
const tenantId = request.headers["x-tenant-id"] || "default";
|
|
1241
|
+
const shares = await this.deps.store.listByUser(tenantId, userId);
|
|
1242
|
+
return reply.send(shares);
|
|
1243
|
+
}
|
|
1244
|
+
async updateShare(request, reply) {
|
|
1245
|
+
const { token } = request.params;
|
|
1246
|
+
const userId = request.user ? request.user.id : void 0;
|
|
1247
|
+
const patch = request.body;
|
|
1248
|
+
const record = await this.deps.store.findByToken(token);
|
|
1249
|
+
if (!record || record.createdBy !== userId) {
|
|
1250
|
+
return reply.status(404).send({ error: "Share not found" });
|
|
1251
|
+
}
|
|
1252
|
+
await this.deps.store.update(token, patch);
|
|
1253
|
+
if (patch.revoked) {
|
|
1254
|
+
this.deps.cache.invalidate(token);
|
|
1255
|
+
}
|
|
1256
|
+
return reply.send({ ok: true });
|
|
1257
|
+
}
|
|
1258
|
+
async revokeShare(request, reply) {
|
|
1259
|
+
const { token } = request.params;
|
|
1260
|
+
const userId = request.user ? request.user.id : void 0;
|
|
1261
|
+
const record = await this.deps.store.findByToken(token);
|
|
1262
|
+
if (!record || record.createdBy !== userId) {
|
|
1263
|
+
return reply.status(404).send({ error: "Share not found" });
|
|
1264
|
+
}
|
|
1265
|
+
await this.deps.store.update(token, { revoked: true });
|
|
1266
|
+
this.deps.cache.invalidate(token);
|
|
1267
|
+
return reply.send({ ok: true });
|
|
1268
|
+
}
|
|
1269
|
+
async resolveResource(request, reply) {
|
|
1270
|
+
const params = request.params;
|
|
1271
|
+
const { token } = params;
|
|
1272
|
+
const subPath = params["*"] ?? "";
|
|
1273
|
+
const cached = this.deps.cache.get(token);
|
|
1274
|
+
if (cached && !cached.requiresUnlock) {
|
|
1275
|
+
return this._serveFile(cached.address, token, subPath, reply);
|
|
1276
|
+
}
|
|
1277
|
+
const record = await this.deps.store.findByToken(token);
|
|
1278
|
+
if (!record || record.revoked) return reply.status(404).send("Not found");
|
|
1279
|
+
if (record.expiresAt && new Date(record.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
1280
|
+
return reply.status(410).send("Expired");
|
|
1281
|
+
}
|
|
1282
|
+
if (!this._isInternalRequest(request)) {
|
|
1283
|
+
if (record.visibility === "password") {
|
|
1284
|
+
const unlocked = this._isUnlocked(request, token);
|
|
1285
|
+
if (!unlocked) {
|
|
1286
|
+
this.deps.cache.set(token, { address: record.address, requiresUnlock: true });
|
|
1287
|
+
return reply.type("text/html").send(this._passwordPage(token));
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
if (record.maxAccess !== null) {
|
|
1292
|
+
const ok = await this.deps.store.atomicIncrementAccess(token);
|
|
1293
|
+
if (!ok) return reply.status(410).send("Access limit reached");
|
|
1294
|
+
} else {
|
|
1295
|
+
this.deps.store.incrementAccess(token).catch(() => {
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
this.deps.cache.set(token, {
|
|
1299
|
+
address: record.address,
|
|
1300
|
+
requiresUnlock: record.visibility === "password" && !this._isInternalRequest(request)
|
|
1301
|
+
});
|
|
1302
|
+
return this._serveFile(record.address, token, subPath, reply);
|
|
1303
|
+
}
|
|
1304
|
+
async unlockShare(request, reply) {
|
|
1305
|
+
const { token } = request.params;
|
|
1306
|
+
const { password } = request.body;
|
|
1307
|
+
const record = await this.deps.store.findByToken(token);
|
|
1308
|
+
if (!record || !record.passwordHash) {
|
|
1309
|
+
return reply.status(404).send({ error: "Invalid request" });
|
|
1310
|
+
}
|
|
1311
|
+
const valid = password === record.passwordHash;
|
|
1312
|
+
if (!valid) {
|
|
1313
|
+
return reply.status(401).send({ error: "Incorrect password" });
|
|
1314
|
+
}
|
|
1315
|
+
reply.header(
|
|
1316
|
+
"Set-Cookie",
|
|
1317
|
+
`share_unlock_${token}=1; Max-Age=86400; Path=/s/${token}; SameSite=Lax; HttpOnly; Secure`
|
|
1318
|
+
);
|
|
1319
|
+
return reply.send({ ok: true });
|
|
1320
|
+
}
|
|
1321
|
+
_isInternalRequest(request) {
|
|
1322
|
+
const user = request.user;
|
|
1323
|
+
return !!user && !!user.id;
|
|
1324
|
+
}
|
|
1325
|
+
_isUnlocked(request, token) {
|
|
1326
|
+
const cookie = request.headers.cookie ?? "";
|
|
1327
|
+
return cookie.includes(`share_unlock_${token}=1`);
|
|
1328
|
+
}
|
|
1329
|
+
async _serveFile(address, token, subPath, reply) {
|
|
1330
|
+
const provider = this.deps.sandboxManager.getDefaultProvider();
|
|
1331
|
+
const resolver = provider.getResourceResolver();
|
|
1332
|
+
const fullPath = subPath ? this._resolveSafeSubPath(address.resourcePath, subPath) : address.resourcePath;
|
|
1333
|
+
let buf;
|
|
1334
|
+
try {
|
|
1335
|
+
buf = await resolver.resolve({ ...address, resourcePath: fullPath });
|
|
1336
|
+
} catch (err) {
|
|
1337
|
+
this.deps.logger.warn(
|
|
1338
|
+
"Resource resolution failed",
|
|
1339
|
+
{ token, resourcePath: fullPath, error: err.message }
|
|
1340
|
+
);
|
|
1341
|
+
return reply.status(404).send("File not found");
|
|
1342
|
+
}
|
|
1343
|
+
const filename = fullPath.split("/").pop() || "download";
|
|
1344
|
+
const isHtml = !subPath && /\.(html|htm)$/i.test(filename);
|
|
1345
|
+
if (isHtml) {
|
|
1346
|
+
buf = this._injectBaseTag(buf, token);
|
|
1347
|
+
}
|
|
1348
|
+
const contentType = getContentTypeFromFilename(filename);
|
|
1349
|
+
return reply.status(200).type(contentType).header("Content-Disposition", `inline; filename="${filename}"`).header("Access-Control-Allow-Origin", "*").send(buf);
|
|
1350
|
+
}
|
|
1351
|
+
_resolveSafeSubPath(entryFile, subPath) {
|
|
1352
|
+
if (!subPath) return entryFile;
|
|
1353
|
+
if (subPath.includes("..")) throw new Error("Path traversal denied");
|
|
1354
|
+
const entryDir = entryFile.replace(/[^/]+$/, "");
|
|
1355
|
+
return (entryDir + subPath).replace(/\/+/g, "/");
|
|
1356
|
+
}
|
|
1357
|
+
_injectBaseTag(buf, token) {
|
|
1358
|
+
const html = buf.toString("utf-8");
|
|
1359
|
+
if (/<base\b/i.test(html)) return buf;
|
|
1360
|
+
const baseTag = `<base href="/s/${token}/">`;
|
|
1361
|
+
if (html.includes("</head>")) {
|
|
1362
|
+
return Buffer.from(html.replace("</head>", `${baseTag}</head>`), "utf-8");
|
|
1363
|
+
}
|
|
1364
|
+
if (html.includes("<head>")) {
|
|
1365
|
+
return Buffer.from(html.replace("<head>", `<head>${baseTag}`), "utf-8");
|
|
1366
|
+
}
|
|
1367
|
+
if (html.includes("<html>")) {
|
|
1368
|
+
return Buffer.from(html.replace("<html>", `<html>${baseTag}`), "utf-8");
|
|
1369
|
+
}
|
|
1370
|
+
return Buffer.from(baseTag + html, "utf-8");
|
|
1371
|
+
}
|
|
1372
|
+
_passwordPage(token) {
|
|
1373
|
+
return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Password Protected</title><style>body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f5f5f5}.card{background:#fff;padding:32px;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.1);width:100%;max-width:360px;text-align:center}h2{margin:0 0 8px;font-size:20px}p{margin:0 0 20px;color:#666;font-size:14px}input{width:100%;padding:10px 12px;border:1px solid #d9d9d9;border-radius:8px;font-size:14px;box-sizing:border-box;margin-bottom:12px}button{width:100%;padding:10px;background:#6366f1;color:#fff;border:none;border-radius:8px;font-size:14px;cursor:pointer}.error{color:#ef4444;font-size:13px;margin-top:8px;display:none}</style></head><body><div class="card"><h2>Password Protected</h2><p>This share requires a password to access.</p><form id="f"><input type="password" id="p" placeholder="Enter password" required><button type="submit">Unlock</button><div class="error" id="e">Incorrect password</div></form></div><script>document.getElementById('f').onsubmit=async(e)=>{e.preventDefault();const r=await fetch('/s/${token}/unlock',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:document.getElementById('p').value})});if(r.ok)location.reload();else document.getElementById('e').style.display='block'}</script></body></html>`;
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
|
|
1148
1379
|
// src/index.ts
|
|
1149
1380
|
var index_exports = {};
|
|
1150
1381
|
__export(index_exports, {
|
|
@@ -4195,31 +4426,7 @@ var sandboxService = new SandboxService();
|
|
|
4195
4426
|
|
|
4196
4427
|
// src/controllers/sandbox.ts
|
|
4197
4428
|
var import_core18 = require("@axiom-lattice/core");
|
|
4198
|
-
|
|
4199
|
-
const segments = path3.replace(/\/+$/, "").split("/");
|
|
4200
|
-
return segments[segments.length - 1] || "download";
|
|
4201
|
-
}
|
|
4202
|
-
var EXT_TO_MIME = {
|
|
4203
|
-
".txt": "text/plain",
|
|
4204
|
-
".html": "text/html",
|
|
4205
|
-
".css": "text/css",
|
|
4206
|
-
".js": "application/javascript",
|
|
4207
|
-
".json": "application/json",
|
|
4208
|
-
".pdf": "application/pdf",
|
|
4209
|
-
".png": "image/png",
|
|
4210
|
-
".jpg": "image/jpeg",
|
|
4211
|
-
".jpeg": "image/jpeg",
|
|
4212
|
-
".gif": "image/gif",
|
|
4213
|
-
".webp": "image/webp",
|
|
4214
|
-
".svg": "image/svg+xml",
|
|
4215
|
-
".zip": "application/zip",
|
|
4216
|
-
".csv": "text/csv",
|
|
4217
|
-
".xml": "application/xml"
|
|
4218
|
-
};
|
|
4219
|
-
function getContentTypeFromFilename(filename) {
|
|
4220
|
-
const ext = filename.includes(".") ? filename.slice(filename.lastIndexOf(".")).toLowerCase() : "";
|
|
4221
|
-
return EXT_TO_MIME[ext] ?? "application/octet-stream";
|
|
4222
|
-
}
|
|
4429
|
+
init_mime();
|
|
4223
4430
|
function registerSandboxProxyRoutes(app2) {
|
|
4224
4431
|
app2.post(
|
|
4225
4432
|
"/api/assistants/:assistantId/threads/:threadId/sandbox/uploadfile",
|
|
@@ -4318,6 +4525,7 @@ var import_core19 = require("@axiom-lattice/core");
|
|
|
4318
4525
|
var import_core20 = require("@axiom-lattice/core");
|
|
4319
4526
|
var import_core21 = require("@axiom-lattice/core");
|
|
4320
4527
|
var import_uuid2 = require("uuid");
|
|
4528
|
+
init_mime();
|
|
4321
4529
|
var WorkspaceController = class {
|
|
4322
4530
|
constructor() {
|
|
4323
4531
|
this.workspaceStore = (0, import_core19.getStoreLattice)("default", "workspace").store;
|
|
@@ -4489,32 +4697,6 @@ var WorkspaceController = class {
|
|
|
4489
4697
|
};
|
|
4490
4698
|
}
|
|
4491
4699
|
}
|
|
4492
|
-
getFilenameFromPath(filePath) {
|
|
4493
|
-
const segments = filePath.split("/");
|
|
4494
|
-
return segments[segments.length - 1] || "download";
|
|
4495
|
-
}
|
|
4496
|
-
getMimeType(filename) {
|
|
4497
|
-
const ext = filename.split(".").pop()?.toLowerCase() || "";
|
|
4498
|
-
const mimeTypes = {
|
|
4499
|
-
pdf: "application/pdf",
|
|
4500
|
-
csv: "text/csv",
|
|
4501
|
-
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
4502
|
-
xls: "application/vnd.ms-excel",
|
|
4503
|
-
txt: "text/plain",
|
|
4504
|
-
json: "application/json",
|
|
4505
|
-
png: "image/png",
|
|
4506
|
-
jpg: "image/jpeg",
|
|
4507
|
-
jpeg: "image/jpeg",
|
|
4508
|
-
gif: "image/gif",
|
|
4509
|
-
svg: "image/svg+xml",
|
|
4510
|
-
html: "text/html",
|
|
4511
|
-
htm: "text/html",
|
|
4512
|
-
mp3: "audio/mpeg",
|
|
4513
|
-
mp4: "video/mp4",
|
|
4514
|
-
webm: "video/webm"
|
|
4515
|
-
};
|
|
4516
|
-
return mimeTypes[ext] || "application/octet-stream";
|
|
4517
|
-
}
|
|
4518
4700
|
isBinaryContentType(filename) {
|
|
4519
4701
|
const ext = filename.split(".").pop()?.toLowerCase() || "";
|
|
4520
4702
|
const binaryExtensions = /* @__PURE__ */ new Set([
|
|
@@ -4567,7 +4749,7 @@ var WorkspaceController = class {
|
|
|
4567
4749
|
workspaceId,
|
|
4568
4750
|
projectId
|
|
4569
4751
|
};
|
|
4570
|
-
const filename2 =
|
|
4752
|
+
const filename2 = getFilenameFromPath(resolvedPath);
|
|
4571
4753
|
const isBinary = this.isBinaryContentType(filename2);
|
|
4572
4754
|
const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, resolvedPath);
|
|
4573
4755
|
let buf;
|
|
@@ -4582,14 +4764,14 @@ var WorkspaceController = class {
|
|
|
4582
4764
|
const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);
|
|
4583
4765
|
buf = await sandbox.file.downloadFile({ file: resolvedPath });
|
|
4584
4766
|
}
|
|
4585
|
-
const inferredContentType =
|
|
4767
|
+
const inferredContentType = getContentTypeFromFilename(filename2);
|
|
4586
4768
|
const contentDisposition = `attachment; filename*=UTF-8''${encodeURIComponent(filename2)}`;
|
|
4587
4769
|
return reply.status(200).type(inferredContentType).header("Content-Disposition", contentDisposition).send(buf);
|
|
4588
4770
|
}
|
|
4589
4771
|
const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, resolvedPath);
|
|
4590
4772
|
const content = await backend.read(resolvedPath, 0, Infinity);
|
|
4591
|
-
const filename =
|
|
4592
|
-
const mimeType =
|
|
4773
|
+
const filename = getFilenameFromPath(resolvedPath);
|
|
4774
|
+
const mimeType = getContentTypeFromFilename(filename);
|
|
4593
4775
|
const buffer = Buffer.from(content, "utf-8");
|
|
4594
4776
|
return reply.status(200).type(mimeType).header("Content-Disposition", `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`).send(buffer);
|
|
4595
4777
|
} catch (error) {
|
|
@@ -4621,7 +4803,7 @@ var WorkspaceController = class {
|
|
|
4621
4803
|
workspaceId,
|
|
4622
4804
|
projectId
|
|
4623
4805
|
};
|
|
4624
|
-
const filename2 =
|
|
4806
|
+
const filename2 = getFilenameFromPath(resolvedPath);
|
|
4625
4807
|
const isBinary = this.isBinaryContentType(filename2);
|
|
4626
4808
|
const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, resolvedPath);
|
|
4627
4809
|
let buf;
|
|
@@ -4636,7 +4818,7 @@ var WorkspaceController = class {
|
|
|
4636
4818
|
const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);
|
|
4637
4819
|
buf = await sandbox.file.downloadFile({ file: resolvedPath });
|
|
4638
4820
|
}
|
|
4639
|
-
const inferredContentType =
|
|
4821
|
+
const inferredContentType = getContentTypeFromFilename(filename2);
|
|
4640
4822
|
try {
|
|
4641
4823
|
const contentType = inferredContentType;
|
|
4642
4824
|
const isHtml = contentType?.toLowerCase().includes("text/html") || filename2.toLowerCase().endsWith(".html") || filename2.toLowerCase().endsWith(".htm");
|
|
@@ -4669,8 +4851,8 @@ var WorkspaceController = class {
|
|
|
4669
4851
|
}
|
|
4670
4852
|
const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, resolvedPath);
|
|
4671
4853
|
const content = await backend.read(resolvedPath, 0, Infinity);
|
|
4672
|
-
const filename =
|
|
4673
|
-
const mimeType =
|
|
4854
|
+
const filename = getFilenameFromPath(resolvedPath);
|
|
4855
|
+
const mimeType = getContentTypeFromFilename(filename);
|
|
4674
4856
|
let finalContent = content;
|
|
4675
4857
|
const isHtmlFs = mimeType?.toLowerCase().includes("text/html") || filename.toLowerCase().endsWith(".html") || filename.toLowerCase().endsWith(".htm");
|
|
4676
4858
|
if (isHtmlFs) {
|
|
@@ -8474,6 +8656,23 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
8474
8656
|
);
|
|
8475
8657
|
};
|
|
8476
8658
|
|
|
8659
|
+
// src/routes/resource-routes.ts
|
|
8660
|
+
function registerResourceRoutes(app2, controller) {
|
|
8661
|
+
app2.get("/s/:token", controller.resolveResource.bind(controller));
|
|
8662
|
+
app2.get("/s/:token/*", controller.resolveResource.bind(controller));
|
|
8663
|
+
app2.post("/s/:token/unlock", controller.unlockShare.bind(controller));
|
|
8664
|
+
app2.options("/s/:token", async (_req, reply) => {
|
|
8665
|
+
reply.header("Access-Control-Allow-Origin", "*");
|
|
8666
|
+
reply.header("Access-Control-Allow-Methods", "GET, OPTIONS, POST");
|
|
8667
|
+
reply.header("Access-Control-Allow-Headers", "Content-Type");
|
|
8668
|
+
return reply.status(204).send();
|
|
8669
|
+
});
|
|
8670
|
+
app2.post("/api/resources/share", controller.createShare.bind(controller));
|
|
8671
|
+
app2.get("/api/resources/shares", controller.listShares.bind(controller));
|
|
8672
|
+
app2.patch("/api/resources/share/:token", controller.updateShare.bind(controller));
|
|
8673
|
+
app2.delete("/api/resources/share/:token", controller.revokeShare.bind(controller));
|
|
8674
|
+
}
|
|
8675
|
+
|
|
8477
8676
|
// src/router/MessageRouter.ts
|
|
8478
8677
|
var import_core32 = require("@axiom-lattice/core");
|
|
8479
8678
|
var import_crypto9 = require("crypto");
|
|
@@ -8958,7 +9157,7 @@ function createAuditLoggerMiddleware() {
|
|
|
8958
9157
|
}
|
|
8959
9158
|
|
|
8960
9159
|
// src/index.ts
|
|
8961
|
-
var
|
|
9160
|
+
var import_core36 = require("@axiom-lattice/core");
|
|
8962
9161
|
|
|
8963
9162
|
// src/swagger.ts
|
|
8964
9163
|
var import_swagger = __toESM(require("@fastify/swagger"));
|
|
@@ -9275,7 +9474,7 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
|
|
|
9275
9474
|
var AgentTaskConsumer = _AgentTaskConsumer;
|
|
9276
9475
|
|
|
9277
9476
|
// src/index.ts
|
|
9278
|
-
var
|
|
9477
|
+
var import_core37 = require("@axiom-lattice/core");
|
|
9279
9478
|
var import_protocols5 = require("@axiom-lattice/protocols");
|
|
9280
9479
|
var import_meta = {};
|
|
9281
9480
|
process.on("unhandledRejection", (reason, promise) => {
|
|
@@ -9291,11 +9490,11 @@ var DEFAULT_LOGGER_CONFIG = {
|
|
|
9291
9490
|
var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
|
|
9292
9491
|
var logger5 = loggerLattice.client;
|
|
9293
9492
|
function initializeLogger(config) {
|
|
9294
|
-
if (
|
|
9295
|
-
|
|
9493
|
+
if (import_core37.loggerLatticeManager.hasLattice("default")) {
|
|
9494
|
+
import_core37.loggerLatticeManager.removeLattice("default");
|
|
9296
9495
|
}
|
|
9297
|
-
(0,
|
|
9298
|
-
return (0,
|
|
9496
|
+
(0, import_core37.registerLoggerLattice)("default", config);
|
|
9497
|
+
return (0, import_core37.getLoggerLattice)("default");
|
|
9299
9498
|
}
|
|
9300
9499
|
var app = (0, import_fastify.default)({
|
|
9301
9500
|
logger: false,
|
|
@@ -9332,6 +9531,7 @@ app.addHook("preHandler", async (request, reply) => {
|
|
|
9332
9531
|
if (!authRequired) return;
|
|
9333
9532
|
if (request.method === "OPTIONS") return;
|
|
9334
9533
|
if (PUBLIC_ROUTES.some((r) => request.url === r)) return;
|
|
9534
|
+
if (request.url.startsWith("/s/")) return;
|
|
9335
9535
|
const urlPath = request.url.split("?")[0];
|
|
9336
9536
|
if (urlPath.includes("/viewfile") || urlPath.includes("/downloadfile")) return;
|
|
9337
9537
|
return reply.status(401).send({
|
|
@@ -9406,7 +9606,7 @@ app.setErrorHandler((error, request, reply) => {
|
|
|
9406
9606
|
});
|
|
9407
9607
|
function getConfiguredSandboxProvider() {
|
|
9408
9608
|
const sandboxProviderType = process.env.SANDBOX_PROVIDER_TYPE || "microsandbox-remote";
|
|
9409
|
-
return (0,
|
|
9609
|
+
return (0, import_core37.createSandboxProvider)({
|
|
9410
9610
|
type: sandboxProviderType,
|
|
9411
9611
|
remoteBaseURL: process.env.SANDBOX_BASE_URL,
|
|
9412
9612
|
microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,
|
|
@@ -9442,7 +9642,7 @@ var start = async (config) => {
|
|
|
9442
9642
|
const { getStoreLattice: getStore2 } = await import("@axiom-lattice/core");
|
|
9443
9643
|
const bindingStore = getStore2("default", "channelBinding").store;
|
|
9444
9644
|
const installationStore = getStore2("default", "channelInstallation").store;
|
|
9445
|
-
(0,
|
|
9645
|
+
(0, import_core36.setBindingRegistry)(bindingStore);
|
|
9446
9646
|
const router = new MessageRouter({
|
|
9447
9647
|
middlewares: [
|
|
9448
9648
|
createDeduplicationMiddleware(),
|
|
@@ -9468,8 +9668,8 @@ var start = async (config) => {
|
|
|
9468
9668
|
});
|
|
9469
9669
|
}
|
|
9470
9670
|
try {
|
|
9471
|
-
const menuStore = (0,
|
|
9472
|
-
(0,
|
|
9671
|
+
const menuStore = (0, import_core37.getStoreLattice)("default", "menu").store;
|
|
9672
|
+
(0, import_core36.setMenuRegistry)(menuStore);
|
|
9473
9673
|
logger5.info("Menu registry initialized");
|
|
9474
9674
|
} catch {
|
|
9475
9675
|
}
|
|
@@ -9477,10 +9677,27 @@ var start = async (config) => {
|
|
|
9477
9677
|
setChannelControllerDeps({ adapterRegistry, router: channelDeps.router });
|
|
9478
9678
|
}
|
|
9479
9679
|
registerLatticeRoutes(app, channelDeps);
|
|
9480
|
-
if (!
|
|
9481
|
-
|
|
9680
|
+
if (!import_core37.sandboxLatticeManager.hasLattice("default")) {
|
|
9681
|
+
import_core37.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
|
|
9482
9682
|
logger5.info("Registered sandbox manager from env configuration");
|
|
9483
9683
|
}
|
|
9684
|
+
try {
|
|
9685
|
+
const { ResourceController: ResourceController2 } = await Promise.resolve().then(() => (init_resources(), resources_exports));
|
|
9686
|
+
const sharedResourceStore = (0, import_core37.getStoreLattice)("default", "sharedResource").store;
|
|
9687
|
+
const cache = new import_core37.TokenCache();
|
|
9688
|
+
const resourceController = new ResourceController2({
|
|
9689
|
+
store: sharedResourceStore,
|
|
9690
|
+
sandboxManager: import_core37.sandboxLatticeManager,
|
|
9691
|
+
cache,
|
|
9692
|
+
logger: logger5
|
|
9693
|
+
});
|
|
9694
|
+
registerResourceRoutes(app, resourceController);
|
|
9695
|
+
logger5.info("Resource share routes registered");
|
|
9696
|
+
} catch (err) {
|
|
9697
|
+
logger5.warn("Resource share infrastructure unavailable", {
|
|
9698
|
+
error: err instanceof Error ? err.message : String(err)
|
|
9699
|
+
});
|
|
9700
|
+
}
|
|
9484
9701
|
if (channelDeps && process.env.CHANNELS_ENABLED !== "false") {
|
|
9485
9702
|
const { connectAllChannels } = await import("@axiom-lattice/core");
|
|
9486
9703
|
try {
|
|
@@ -9510,7 +9727,7 @@ var start = async (config) => {
|
|
|
9510
9727
|
agentTaskConsumer.startPollingQueue();
|
|
9511
9728
|
}
|
|
9512
9729
|
}
|
|
9513
|
-
|
|
9730
|
+
import_core37.agentInstanceManager.restore().then((stats) => {
|
|
9514
9731
|
logger5.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
|
|
9515
9732
|
}).catch((error) => {
|
|
9516
9733
|
logger5.error("Agent recovery failed", { error });
|