@rubytech/create-maxy 1.0.660 → 1.0.662
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/package.json +1 -1
- package/payload/platform/neo4j/schema.cypher +18 -0
- package/payload/platform/plugins/docs/references/memory-guide.md +4 -2
- package/payload/platform/plugins/docs/references/platform.md +4 -0
- package/payload/platform/plugins/docs/references/troubleshooting.md +20 -4
- package/payload/server/public/assets/{admin-BFIYSS4u.js → admin-C9qoVb2l.js} +63 -63
- package/payload/server/public/assets/{data-BmeeI1Ix.js → data-C-WE3FGr.js} +1 -1
- package/payload/server/public/assets/{file-D4Qulqz_.js → file-lmzx24EO.js} +1 -1
- package/payload/server/public/assets/{graph-MoIys9Ub.js → graph-Bcao42cE.js} +17 -17
- package/payload/server/public/assets/{house-B0Hukxjp.js → house-ClhI06TA.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-C6owBiFB.css → jsx-runtime-CLCFnMYD.css} +1 -1
- package/payload/server/public/assets/{public-LvjJTLGn.js → public-Dz33-dIE.js} +1 -1
- package/payload/server/public/assets/{share-2-BafZBLp9.js → share-2-MZ4MqbjS.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-dLOpmcYJ.js → useVoiceRecorder-Cm0G51D_.js} +1 -1
- package/payload/server/public/assets/{x-BOZIeV0f.js → x-CLhtM_Mh.js} +1 -1
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +277 -72
- /package/payload/server/public/assets/{jsx-runtime-CmCvZzVE.js → jsx-runtime-ImbU973I.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -1201,14 +1201,14 @@ var Hono = class _Hono {
|
|
|
1201
1201
|
* app.route("/api", app2) // GET /api/user
|
|
1202
1202
|
* ```
|
|
1203
1203
|
*/
|
|
1204
|
-
route(path2,
|
|
1204
|
+
route(path2, app35) {
|
|
1205
1205
|
const subApp = this.basePath(path2);
|
|
1206
|
-
|
|
1206
|
+
app35.routes.map((r) => {
|
|
1207
1207
|
let handler;
|
|
1208
|
-
if (
|
|
1208
|
+
if (app35.errorHandler === errorHandler) {
|
|
1209
1209
|
handler = r.handler;
|
|
1210
1210
|
} else {
|
|
1211
|
-
handler = async (c, next) => (await compose([],
|
|
1211
|
+
handler = async (c, next) => (await compose([], app35.errorHandler)(c, () => r.handler(c, next))).res;
|
|
1212
1212
|
handler[COMPOSED_HANDLER] = r.handler;
|
|
1213
1213
|
}
|
|
1214
1214
|
subApp.#addRoute(r.method, r.path, handler);
|
|
@@ -3855,6 +3855,8 @@ function terminalLog(phase, fields = {}) {
|
|
|
3855
3855
|
// server/ws-proxy-terminal.ts
|
|
3856
3856
|
var WS_PATH2 = "/admin/terminal/ws";
|
|
3857
3857
|
var UPSTREAM_TIMEOUT_MS2 = 5e3;
|
|
3858
|
+
var FLOW_TICK_MS = 5e3;
|
|
3859
|
+
var FLOW_IDLE_EMIT_MS = 3e4;
|
|
3858
3860
|
var HOP_BY_HOP2 = /* @__PURE__ */ new Set([
|
|
3859
3861
|
"connection",
|
|
3860
3862
|
"keep-alive",
|
|
@@ -3979,9 +3981,17 @@ function handleUpgrade2(req, clientSocket, head, opts) {
|
|
|
3979
3981
|
let bytesUpstreamToClient = 0;
|
|
3980
3982
|
let closedBy = null;
|
|
3981
3983
|
let proxyOpened = false;
|
|
3984
|
+
let lastUpstreamByteTs = 0;
|
|
3985
|
+
let flowInterval = null;
|
|
3986
|
+
let lastEmittedAt = 0;
|
|
3987
|
+
let lastEmittedUpstreamBytes = 0;
|
|
3982
3988
|
const finish = (side, reason) => {
|
|
3983
3989
|
if (closedBy) return;
|
|
3984
3990
|
closedBy = side;
|
|
3991
|
+
if (flowInterval) {
|
|
3992
|
+
clearInterval(flowInterval);
|
|
3993
|
+
flowInterval = null;
|
|
3994
|
+
}
|
|
3985
3995
|
if (proxyOpened) {
|
|
3986
3996
|
terminalLog("proxy-close", {
|
|
3987
3997
|
corrId,
|
|
@@ -4025,9 +4035,28 @@ function handleUpgrade2(req, clientSocket, head, opts) {
|
|
|
4025
4035
|
});
|
|
4026
4036
|
upstream.on("data", (chunk) => {
|
|
4027
4037
|
bytesUpstreamToClient += chunk.length;
|
|
4038
|
+
lastUpstreamByteTs = Date.now();
|
|
4028
4039
|
});
|
|
4029
4040
|
clientSocket.pipe(upstream);
|
|
4030
4041
|
upstream.pipe(clientSocket);
|
|
4042
|
+
lastEmittedAt = Date.now();
|
|
4043
|
+
lastEmittedUpstreamBytes = 0;
|
|
4044
|
+
flowInterval = setInterval(() => {
|
|
4045
|
+
const now = Date.now();
|
|
4046
|
+
const idleMs = lastUpstreamByteTs === 0 ? now - lastEmittedAt : now - lastUpstreamByteTs;
|
|
4047
|
+
const upstreamMoved = bytesUpstreamToClient !== lastEmittedUpstreamBytes;
|
|
4048
|
+
const sinceLastEmit = now - lastEmittedAt;
|
|
4049
|
+
if (upstreamMoved || sinceLastEmit >= FLOW_IDLE_EMIT_MS) {
|
|
4050
|
+
terminalLog("proxy-flow", {
|
|
4051
|
+
corrId,
|
|
4052
|
+
clientBytes: bytesClientToUpstream,
|
|
4053
|
+
upstreamBytes: bytesUpstreamToClient,
|
|
4054
|
+
idleMs
|
|
4055
|
+
});
|
|
4056
|
+
lastEmittedAt = now;
|
|
4057
|
+
lastEmittedUpstreamBytes = bytesUpstreamToClient;
|
|
4058
|
+
}
|
|
4059
|
+
}, FLOW_TICK_MS);
|
|
4031
4060
|
clientSocket.once("close", (hadError) => {
|
|
4032
4061
|
finish("client", hadError ? "error" : "normal");
|
|
4033
4062
|
});
|
|
@@ -20870,7 +20899,7 @@ var ALL_GRAPH_LABELS = Object.freeze(
|
|
|
20870
20899
|
Object.keys(GRAPH_LABEL_COLOURS)
|
|
20871
20900
|
);
|
|
20872
20901
|
var HIDDEN_BY_DEFAULT_LABELS = Object.freeze(
|
|
20873
|
-
/* @__PURE__ */ new Set(["Chunk"])
|
|
20902
|
+
/* @__PURE__ */ new Set(["Chunk", "GraphPreference"])
|
|
20874
20903
|
);
|
|
20875
20904
|
function isKnownLabel(label) {
|
|
20876
20905
|
return Object.prototype.hasOwnProperty.call(GRAPH_LABEL_COLOURS, label);
|
|
@@ -21270,9 +21299,183 @@ app28.post("/", requireAdminSession, async (c) => {
|
|
|
21270
21299
|
});
|
|
21271
21300
|
var graph_restore_default = app28;
|
|
21272
21301
|
|
|
21273
|
-
// server/routes/admin/
|
|
21302
|
+
// server/routes/admin/graph-labels-in-graph.ts
|
|
21274
21303
|
var app29 = new Hono2();
|
|
21275
|
-
app29.
|
|
21304
|
+
app29.get("/", requireAdminSession, async (c) => {
|
|
21305
|
+
const sessionKey = c.var.sessionKey;
|
|
21306
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
21307
|
+
if (!accountId) {
|
|
21308
|
+
console.error('[graph-page] labels-in-graph-rejected reason="no account for session"');
|
|
21309
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
21310
|
+
}
|
|
21311
|
+
const started = Date.now();
|
|
21312
|
+
const session = getSession();
|
|
21313
|
+
try {
|
|
21314
|
+
const hidden = [...HIDDEN_BY_DEFAULT_LABELS];
|
|
21315
|
+
const result = await session.executeRead(async (tx) => {
|
|
21316
|
+
return await tx.run(LABELS_IN_GRAPH_CYPHER, { accountId, hidden });
|
|
21317
|
+
});
|
|
21318
|
+
const record = result.records[0];
|
|
21319
|
+
const rawLabels = record?.get("labels") ?? [];
|
|
21320
|
+
const labels = [...new Set(rawLabels)].sort();
|
|
21321
|
+
const elapsed = Date.now() - started;
|
|
21322
|
+
console.error(
|
|
21323
|
+
`[graph-page] labels-in-graph account=${accountId} labels=${labels.join(",")} ms=${elapsed}`
|
|
21324
|
+
);
|
|
21325
|
+
return c.json({ labels });
|
|
21326
|
+
} catch (err) {
|
|
21327
|
+
const elapsed = Date.now() - started;
|
|
21328
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21329
|
+
console.error(
|
|
21330
|
+
`[graph-page] labels-in-graph-rejected account=${accountId} reason="${message}" ms=${elapsed}`
|
|
21331
|
+
);
|
|
21332
|
+
return c.json({ error: `Graph labels unavailable: ${message}` }, 503);
|
|
21333
|
+
} finally {
|
|
21334
|
+
try {
|
|
21335
|
+
await session.close();
|
|
21336
|
+
} catch {
|
|
21337
|
+
}
|
|
21338
|
+
}
|
|
21339
|
+
});
|
|
21340
|
+
var LABELS_IN_GRAPH_CYPHER = `
|
|
21341
|
+
MATCH (n)
|
|
21342
|
+
WHERE n.accountId = $accountId
|
|
21343
|
+
AND NOT n:Trashed
|
|
21344
|
+
AND n.deletedAt IS NULL
|
|
21345
|
+
UNWIND labels(n) AS lbl
|
|
21346
|
+
WITH DISTINCT lbl
|
|
21347
|
+
WHERE NOT lbl IN $hidden
|
|
21348
|
+
RETURN collect(lbl) AS labels
|
|
21349
|
+
`;
|
|
21350
|
+
var graph_labels_in_graph_default = app29;
|
|
21351
|
+
|
|
21352
|
+
// server/routes/admin/graph-default-view.ts
|
|
21353
|
+
var app30 = new Hono2();
|
|
21354
|
+
app30.get("/", requireAdminSession, async (c) => {
|
|
21355
|
+
const sessionKey = c.var.sessionKey;
|
|
21356
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
21357
|
+
const userId = getUserIdForSession(sessionKey);
|
|
21358
|
+
if (!accountId || !userId) {
|
|
21359
|
+
console.error('[graph-page] default-view-rejected reason="missing account or user context"');
|
|
21360
|
+
return c.json({ error: "Account and user context required for default view" }, 401);
|
|
21361
|
+
}
|
|
21362
|
+
const started = Date.now();
|
|
21363
|
+
const session = getSession();
|
|
21364
|
+
try {
|
|
21365
|
+
const result = await session.executeRead(async (tx) => {
|
|
21366
|
+
return await tx.run(READ_CYPHER, { accountId, userId });
|
|
21367
|
+
});
|
|
21368
|
+
const record = result.records[0];
|
|
21369
|
+
const rawLabels = record?.get("labels");
|
|
21370
|
+
const rawIncludeTrashed = record?.get("includeTrashed");
|
|
21371
|
+
const labels = Array.isArray(rawLabels) ? rawLabels : [];
|
|
21372
|
+
const includeTrashed = rawIncludeTrashed === true;
|
|
21373
|
+
const elapsed = Date.now() - started;
|
|
21374
|
+
console.error(
|
|
21375
|
+
`[graph-page] default-view-load account=${accountId} labels=${labels.join(",")} includeTrashed=${includeTrashed ? 1 : 0} ms=${elapsed}`
|
|
21376
|
+
);
|
|
21377
|
+
return c.json({ labels, includeTrashed });
|
|
21378
|
+
} catch (err) {
|
|
21379
|
+
const elapsed = Date.now() - started;
|
|
21380
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21381
|
+
console.error(
|
|
21382
|
+
`[graph-page] default-view-rejected op=load account=${accountId} reason="${message}" ms=${elapsed}`
|
|
21383
|
+
);
|
|
21384
|
+
return c.json({ error: `Graph default view unavailable: ${message}` }, 503);
|
|
21385
|
+
} finally {
|
|
21386
|
+
try {
|
|
21387
|
+
await session.close();
|
|
21388
|
+
} catch {
|
|
21389
|
+
}
|
|
21390
|
+
}
|
|
21391
|
+
});
|
|
21392
|
+
app30.put("/", requireAdminSession, async (c) => {
|
|
21393
|
+
const sessionKey = c.var.sessionKey;
|
|
21394
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
21395
|
+
const userId = getUserIdForSession(sessionKey);
|
|
21396
|
+
if (!accountId || !userId) {
|
|
21397
|
+
console.error('[graph-page] default-view-rejected reason="missing account or user context"');
|
|
21398
|
+
return c.json({ error: "Account and user context required for default view" }, 401);
|
|
21399
|
+
}
|
|
21400
|
+
const body = await safeJson(c);
|
|
21401
|
+
if (!body) {
|
|
21402
|
+
return c.json({ error: "Request body must be JSON" }, 400);
|
|
21403
|
+
}
|
|
21404
|
+
const validation = validateBody2(body);
|
|
21405
|
+
if (!validation.ok) {
|
|
21406
|
+
console.error(
|
|
21407
|
+
`[graph-page] default-view-rejected op=save account=${accountId} reason="${validation.reason}"`
|
|
21408
|
+
);
|
|
21409
|
+
return c.json({ error: validation.reason }, 400);
|
|
21410
|
+
}
|
|
21411
|
+
const { labels, includeTrashed } = validation;
|
|
21412
|
+
const session = getSession();
|
|
21413
|
+
try {
|
|
21414
|
+
await session.executeWrite(async (tx) => {
|
|
21415
|
+
return await tx.run(WRITE_CYPHER, {
|
|
21416
|
+
accountId,
|
|
21417
|
+
userId,
|
|
21418
|
+
labels,
|
|
21419
|
+
includeTrashed,
|
|
21420
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
21421
|
+
});
|
|
21422
|
+
});
|
|
21423
|
+
console.error(
|
|
21424
|
+
`[graph-page] default-view-save account=${accountId} labels=${labels.join(",")} includeTrashed=${includeTrashed ? 1 : 0}`
|
|
21425
|
+
);
|
|
21426
|
+
return c.json({ labels, includeTrashed });
|
|
21427
|
+
} catch (err) {
|
|
21428
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21429
|
+
console.error(
|
|
21430
|
+
`[graph-page] default-view-rejected op=save account=${accountId} reason="${message}"`
|
|
21431
|
+
);
|
|
21432
|
+
return c.json({ error: `Failed to save graph default view: ${message}` }, 503);
|
|
21433
|
+
} finally {
|
|
21434
|
+
try {
|
|
21435
|
+
await session.close();
|
|
21436
|
+
} catch {
|
|
21437
|
+
}
|
|
21438
|
+
}
|
|
21439
|
+
});
|
|
21440
|
+
function validateBody2(body) {
|
|
21441
|
+
if (!Array.isArray(body.labels)) {
|
|
21442
|
+
return { ok: false, reason: "labels must be an array of strings" };
|
|
21443
|
+
}
|
|
21444
|
+
if (typeof body.includeTrashed !== "boolean") {
|
|
21445
|
+
return { ok: false, reason: "includeTrashed must be a boolean" };
|
|
21446
|
+
}
|
|
21447
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21448
|
+
for (const lbl of body.labels) {
|
|
21449
|
+
if (typeof lbl !== "string") {
|
|
21450
|
+
return { ok: false, reason: "labels must be an array of strings" };
|
|
21451
|
+
}
|
|
21452
|
+
if (!isKnownLabel(lbl)) {
|
|
21453
|
+
return { ok: false, reason: `unknown label "${lbl}" \u2014 not registered in graph-labels.ts` };
|
|
21454
|
+
}
|
|
21455
|
+
if (isHiddenByDefault(lbl)) {
|
|
21456
|
+
return { ok: false, reason: `label "${lbl}" is hidden by default and cannot be a default view selection` };
|
|
21457
|
+
}
|
|
21458
|
+
seen.add(lbl);
|
|
21459
|
+
}
|
|
21460
|
+
const labels = [...seen].sort();
|
|
21461
|
+
return { ok: true, labels, includeTrashed: body.includeTrashed };
|
|
21462
|
+
}
|
|
21463
|
+
var READ_CYPHER = `
|
|
21464
|
+
OPTIONAL MATCH (p:GraphPreference {accountId: $accountId, userId: $userId})
|
|
21465
|
+
RETURN p.labels AS labels, p.includeTrashed AS includeTrashed
|
|
21466
|
+
`;
|
|
21467
|
+
var WRITE_CYPHER = `
|
|
21468
|
+
MERGE (p:GraphPreference {accountId: $accountId, userId: $userId})
|
|
21469
|
+
SET p.labels = $labels,
|
|
21470
|
+
p.includeTrashed = $includeTrashed,
|
|
21471
|
+
p.updatedAt = $updatedAt
|
|
21472
|
+
RETURN p.labels AS labels
|
|
21473
|
+
`;
|
|
21474
|
+
var graph_default_view_default = app30;
|
|
21475
|
+
|
|
21476
|
+
// server/routes/admin/file-attach.ts
|
|
21477
|
+
var app31 = new Hono2();
|
|
21478
|
+
app31.post("/", async (c) => {
|
|
21276
21479
|
try {
|
|
21277
21480
|
const body = await c.req.json();
|
|
21278
21481
|
const { filePath, accountId } = body;
|
|
@@ -21295,11 +21498,11 @@ app29.post("/", async (c) => {
|
|
|
21295
21498
|
return c.json({ error: message }, 500);
|
|
21296
21499
|
}
|
|
21297
21500
|
});
|
|
21298
|
-
var file_attach_default =
|
|
21501
|
+
var file_attach_default = app31;
|
|
21299
21502
|
|
|
21300
21503
|
// server/routes/admin/adherence.ts
|
|
21301
|
-
var
|
|
21302
|
-
|
|
21504
|
+
var app32 = new Hono2();
|
|
21505
|
+
app32.get("/", requireAdminSession, async (c) => {
|
|
21303
21506
|
const agent = c.req.query("agent") ?? "admin";
|
|
21304
21507
|
const includeBlock = c.req.query("block") === "1";
|
|
21305
21508
|
const account = resolveAccount();
|
|
@@ -21320,32 +21523,34 @@ app30.get("/", requireAdminSession, async (c) => {
|
|
|
21320
21523
|
return c.json({ error: "Failed to read adherence ledger", agent }, 500);
|
|
21321
21524
|
}
|
|
21322
21525
|
});
|
|
21323
|
-
var adherence_default =
|
|
21526
|
+
var adherence_default = app32;
|
|
21324
21527
|
|
|
21325
21528
|
// server/routes/admin/index.ts
|
|
21326
|
-
var
|
|
21327
|
-
|
|
21328
|
-
|
|
21329
|
-
|
|
21330
|
-
|
|
21331
|
-
|
|
21332
|
-
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21336
|
-
|
|
21337
|
-
|
|
21338
|
-
|
|
21339
|
-
|
|
21340
|
-
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21529
|
+
var app33 = new Hono2();
|
|
21530
|
+
app33.route("/session", session_default2);
|
|
21531
|
+
app33.route("/chat", chat_default2);
|
|
21532
|
+
app33.route("/compact", compact_default);
|
|
21533
|
+
app33.route("/logs", logs_default);
|
|
21534
|
+
app33.route("/claude-info", claude_info_default);
|
|
21535
|
+
app33.route("/attachment", attachment_default);
|
|
21536
|
+
app33.route("/account", account_default);
|
|
21537
|
+
app33.route("/agents", agents_default);
|
|
21538
|
+
app33.route("/version", version_default);
|
|
21539
|
+
app33.route("/sessions", sessions_default);
|
|
21540
|
+
app33.route("/browser", browser_default);
|
|
21541
|
+
app33.route("/device-browser", device_browser_default);
|
|
21542
|
+
app33.route("/events", events_default);
|
|
21543
|
+
app33.route("/cloudflare", cloudflare_default);
|
|
21544
|
+
app33.route("/files", files_default);
|
|
21545
|
+
app33.route("/graph-search", graph_search_default);
|
|
21546
|
+
app33.route("/graph-subgraph", graph_subgraph_default);
|
|
21547
|
+
app33.route("/graph-delete", graph_delete_default);
|
|
21548
|
+
app33.route("/graph-restore", graph_restore_default);
|
|
21549
|
+
app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
21550
|
+
app33.route("/graph-default-view", graph_default_view_default);
|
|
21551
|
+
app33.route("/file-attach", file_attach_default);
|
|
21552
|
+
app33.route("/adherence", adherence_default);
|
|
21553
|
+
var admin_default = app33;
|
|
21349
21554
|
|
|
21350
21555
|
// server/index.ts
|
|
21351
21556
|
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
@@ -21403,9 +21608,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
21403
21608
|
function isPublicHost(host) {
|
|
21404
21609
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
21405
21610
|
}
|
|
21406
|
-
var
|
|
21407
|
-
|
|
21408
|
-
|
|
21611
|
+
var app34 = new Hono2();
|
|
21612
|
+
app34.use("*", clientIpMiddleware);
|
|
21613
|
+
app34.use("*", async (c, next) => {
|
|
21409
21614
|
await next();
|
|
21410
21615
|
c.header("X-Content-Type-Options", "nosniff");
|
|
21411
21616
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -21428,7 +21633,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
21428
21633
|
"/g/"
|
|
21429
21634
|
];
|
|
21430
21635
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
21431
|
-
|
|
21636
|
+
app34.use("*", async (c, next) => {
|
|
21432
21637
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21433
21638
|
if (!isPublicHost(host)) {
|
|
21434
21639
|
await next();
|
|
@@ -21468,7 +21673,7 @@ function resolveRemoteAuthOpts() {
|
|
|
21468
21673
|
return brandLoginOpts;
|
|
21469
21674
|
}
|
|
21470
21675
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
21471
|
-
|
|
21676
|
+
app34.post("/__remote-auth/login", async (c) => {
|
|
21472
21677
|
const clientIp = c.var.clientIp || "unknown";
|
|
21473
21678
|
const rateLimited = checkRateLimit(clientIp);
|
|
21474
21679
|
if (rateLimited) {
|
|
@@ -21504,7 +21709,7 @@ app32.post("/__remote-auth/login", async (c) => {
|
|
|
21504
21709
|
}
|
|
21505
21710
|
});
|
|
21506
21711
|
});
|
|
21507
|
-
|
|
21712
|
+
app34.get("/__remote-auth/logout", (c) => {
|
|
21508
21713
|
const cookieHeader = c.req.header("cookie");
|
|
21509
21714
|
const token = parseCookie(cookieHeader, "__remote_session");
|
|
21510
21715
|
if (token) invalidateRemoteSession(token);
|
|
@@ -21517,7 +21722,7 @@ app32.get("/__remote-auth/logout", (c) => {
|
|
|
21517
21722
|
}
|
|
21518
21723
|
});
|
|
21519
21724
|
});
|
|
21520
|
-
|
|
21725
|
+
app34.post("/__remote-auth/change-password", async (c) => {
|
|
21521
21726
|
const clientIp = c.var.clientIp || "unknown";
|
|
21522
21727
|
const rateLimited = checkRateLimit(clientIp);
|
|
21523
21728
|
if (rateLimited) {
|
|
@@ -21566,13 +21771,13 @@ app32.post("/__remote-auth/change-password", async (c) => {
|
|
|
21566
21771
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
21567
21772
|
}
|
|
21568
21773
|
});
|
|
21569
|
-
|
|
21774
|
+
app34.get("/__remote-auth/setup", (c) => {
|
|
21570
21775
|
if (isRemoteAuthConfigured()) {
|
|
21571
21776
|
return c.redirect("/");
|
|
21572
21777
|
}
|
|
21573
21778
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
21574
21779
|
});
|
|
21575
|
-
|
|
21780
|
+
app34.post("/__remote-auth/set-initial-password", async (c) => {
|
|
21576
21781
|
if (isRemoteAuthConfigured()) {
|
|
21577
21782
|
return c.redirect("/");
|
|
21578
21783
|
}
|
|
@@ -21608,10 +21813,10 @@ app32.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
21608
21813
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
21609
21814
|
}
|
|
21610
21815
|
});
|
|
21611
|
-
|
|
21816
|
+
app34.get("/api/remote-auth/status", (c) => {
|
|
21612
21817
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
21613
21818
|
});
|
|
21614
|
-
|
|
21819
|
+
app34.post("/api/remote-auth/set-password", async (c) => {
|
|
21615
21820
|
let body;
|
|
21616
21821
|
try {
|
|
21617
21822
|
body = await c.req.json();
|
|
@@ -21641,9 +21846,9 @@ app32.post("/api/remote-auth/set-password", async (c) => {
|
|
|
21641
21846
|
return c.json({ error: "Failed to save password" }, 500);
|
|
21642
21847
|
}
|
|
21643
21848
|
});
|
|
21644
|
-
|
|
21849
|
+
app34.route("/api/_client-error", client_error_default);
|
|
21645
21850
|
console.log("[client-error-route] mounted");
|
|
21646
|
-
|
|
21851
|
+
app34.use("*", async (c, next) => {
|
|
21647
21852
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21648
21853
|
const path2 = c.req.path;
|
|
21649
21854
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -21683,15 +21888,15 @@ function parseCookie(cookieHeader, name) {
|
|
|
21683
21888
|
return null;
|
|
21684
21889
|
}
|
|
21685
21890
|
}
|
|
21686
|
-
|
|
21687
|
-
|
|
21688
|
-
|
|
21689
|
-
|
|
21690
|
-
|
|
21691
|
-
|
|
21692
|
-
|
|
21693
|
-
|
|
21694
|
-
|
|
21891
|
+
app34.route("/api/health", health_default);
|
|
21892
|
+
app34.route("/api/session", session_default);
|
|
21893
|
+
app34.route("/api/chat", chat_default);
|
|
21894
|
+
app34.route("/api/group", group_default);
|
|
21895
|
+
app34.route("/api/access", access_default);
|
|
21896
|
+
app34.route("/api/telegram", telegram_default);
|
|
21897
|
+
app34.route("/api/whatsapp", whatsapp_default);
|
|
21898
|
+
app34.route("/api/onboarding", onboarding_default);
|
|
21899
|
+
app34.route("/api/admin", admin_default);
|
|
21695
21900
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
21696
21901
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
21697
21902
|
var IMAGE_MIME = {
|
|
@@ -21703,7 +21908,7 @@ var IMAGE_MIME = {
|
|
|
21703
21908
|
".svg": "image/svg+xml",
|
|
21704
21909
|
".ico": "image/x-icon"
|
|
21705
21910
|
};
|
|
21706
|
-
|
|
21911
|
+
app34.get("/agent-assets/:slug/:filename", (c) => {
|
|
21707
21912
|
const slug = c.req.param("slug");
|
|
21708
21913
|
const filename = c.req.param("filename");
|
|
21709
21914
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -21738,7 +21943,7 @@ app32.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
21738
21943
|
"Cache-Control": "public, max-age=3600"
|
|
21739
21944
|
});
|
|
21740
21945
|
});
|
|
21741
|
-
|
|
21946
|
+
app34.get("/generated/:filename", (c) => {
|
|
21742
21947
|
const filename = c.req.param("filename");
|
|
21743
21948
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
21744
21949
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -21903,7 +22108,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
21903
22108
|
function escapeHtml2(s) {
|
|
21904
22109
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
21905
22110
|
}
|
|
21906
|
-
|
|
22111
|
+
app34.get("/", (c) => {
|
|
21907
22112
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21908
22113
|
if (isPublicHost(host)) {
|
|
21909
22114
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -21911,12 +22116,12 @@ app32.get("/", (c) => {
|
|
|
21911
22116
|
}
|
|
21912
22117
|
return c.html(cachedHtml("index.html"));
|
|
21913
22118
|
});
|
|
21914
|
-
|
|
22119
|
+
app34.get("/public", (c) => {
|
|
21915
22120
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21916
22121
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21917
22122
|
return c.html(cachedHtml("public.html"));
|
|
21918
22123
|
});
|
|
21919
|
-
|
|
22124
|
+
app34.get("/chat", (c) => {
|
|
21920
22125
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21921
22126
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21922
22127
|
return c.html(cachedHtml("public.html"));
|
|
@@ -21935,9 +22140,9 @@ async function logViewerFetch(c, next) {
|
|
|
21935
22140
|
duration_ms: Date.now() - start
|
|
21936
22141
|
});
|
|
21937
22142
|
}
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
22143
|
+
app34.use("/vnc-viewer.html", logViewerFetch);
|
|
22144
|
+
app34.use("/vnc-popout.html", logViewerFetch);
|
|
22145
|
+
app34.get("/vnc-popout.html", (c) => {
|
|
21941
22146
|
let html = htmlCache.get("vnc-popout.html");
|
|
21942
22147
|
if (!html) {
|
|
21943
22148
|
html = readFileSync26(resolve30(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -21950,7 +22155,7 @@ app32.get("/vnc-popout.html", (c) => {
|
|
|
21950
22155
|
}
|
|
21951
22156
|
return c.html(html);
|
|
21952
22157
|
});
|
|
21953
|
-
|
|
22158
|
+
app34.post("/api/vnc/client-event", async (c) => {
|
|
21954
22159
|
let body;
|
|
21955
22160
|
try {
|
|
21956
22161
|
body = await c.req.json();
|
|
@@ -21971,20 +22176,20 @@ app32.post("/api/vnc/client-event", async (c) => {
|
|
|
21971
22176
|
});
|
|
21972
22177
|
return c.json({ ok: true });
|
|
21973
22178
|
});
|
|
21974
|
-
|
|
22179
|
+
app34.get("/g/:slug", (c) => {
|
|
21975
22180
|
return c.html(brandedPublicHtml());
|
|
21976
22181
|
});
|
|
21977
|
-
|
|
22182
|
+
app34.get("/graph", (c) => {
|
|
21978
22183
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21979
22184
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21980
22185
|
return c.html(cachedHtml("graph.html"));
|
|
21981
22186
|
});
|
|
21982
|
-
|
|
22187
|
+
app34.get("/data", (c) => {
|
|
21983
22188
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21984
22189
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21985
22190
|
return c.html(cachedHtml("data.html"));
|
|
21986
22191
|
});
|
|
21987
|
-
|
|
22192
|
+
app34.get("/:slug", async (c, next) => {
|
|
21988
22193
|
const slug = c.req.param("slug");
|
|
21989
22194
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
21990
22195
|
const branding = loadBrandingCache(slug);
|
|
@@ -21993,10 +22198,10 @@ app32.get("/:slug", async (c, next) => {
|
|
|
21993
22198
|
}
|
|
21994
22199
|
await next();
|
|
21995
22200
|
});
|
|
21996
|
-
|
|
22201
|
+
app34.use("/*", serveStatic({ root: "./public" }));
|
|
21997
22202
|
var port = parseInt(process.env.PORT ?? "19200", 10);
|
|
21998
22203
|
var hostname = process.env.HOSTNAME ?? "0.0.0.0";
|
|
21999
|
-
var httpServer = serve({ fetch:
|
|
22204
|
+
var httpServer = serve({ fetch: app34.fetch, port, hostname });
|
|
22000
22205
|
attachVncWsProxy(httpServer, {
|
|
22001
22206
|
isPublicHost,
|
|
22002
22207
|
upstreamHost: "127.0.0.1",
|
|
@@ -22042,7 +22247,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
22042
22247
|
}
|
|
22043
22248
|
try {
|
|
22044
22249
|
const registered = [];
|
|
22045
|
-
for (const r of
|
|
22250
|
+
for (const r of app34.routes ?? []) {
|
|
22046
22251
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
22047
22252
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
22048
22253
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
File without changes
|