@rubytech/create-maxy-code 0.1.246 → 0.1.247
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/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +4 -1
- package/payload/platform/plugins/admin/hooks/__tests__/pin-identity-gate.test.sh +96 -0
- package/payload/platform/plugins/admin/hooks/pin-identity-gate.sh +136 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.d.ts +2 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.js +34 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.d.ts +2 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.js +50 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +8 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.d.ts +6 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.js +32 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.js.map +1 -0
- package/payload/platform/plugins/admin/skills/investigate/SKILL.md +34 -17
- package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +9 -4
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +5 -0
- package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +5 -0
- package/payload/platform/plugins/admin/skills/update-knowledge/SKILL.md +5 -0
- package/payload/platform/plugins/docs/references/admin-identity-gate.md +81 -0
- package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +1 -0
- package/payload/platform/plugins/memory/skills/conversational-memory/SKILL.md +5 -0
- package/payload/platform/plugins/workflows/skills/workflow-manager/SKILL.md +5 -0
- package/payload/platform/scripts/check-skill-frontmatter.mjs +139 -0
- package/payload/platform/scripts/setup-account.sh +5 -0
- package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.d.ts +39 -0
- package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.js +133 -0
- package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +17 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
- package/payload/server/server.js +260 -152
package/payload/server/server.js
CHANGED
|
@@ -600,6 +600,46 @@ var require_dist2 = __commonJS({
|
|
|
600
600
|
}
|
|
601
601
|
});
|
|
602
602
|
|
|
603
|
+
// ../lib/require-port-env/dist/index.js
|
|
604
|
+
var require_dist3 = __commonJS({
|
|
605
|
+
"../lib/require-port-env/dist/index.js"(exports) {
|
|
606
|
+
"use strict";
|
|
607
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
608
|
+
exports.MissingPortEnvError = void 0;
|
|
609
|
+
exports.requirePortEnv = requirePortEnv3;
|
|
610
|
+
var MissingPortEnvError = class extends Error {
|
|
611
|
+
envName;
|
|
612
|
+
tag;
|
|
613
|
+
failLine;
|
|
614
|
+
constructor(envName, tag, failLine, message) {
|
|
615
|
+
super(message);
|
|
616
|
+
this.name = "MissingPortEnvError";
|
|
617
|
+
this.envName = envName;
|
|
618
|
+
this.tag = tag;
|
|
619
|
+
this.failLine = failLine;
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
exports.MissingPortEnvError = MissingPortEnvError;
|
|
623
|
+
var VALID_PORT_MIN = 1;
|
|
624
|
+
var VALID_PORT_MAX = 65535;
|
|
625
|
+
function requirePortEnv3(envName, options = {}) {
|
|
626
|
+
const tag = options.tag ?? "port-env";
|
|
627
|
+
const failLine = options.failLine ?? "missing-port-env";
|
|
628
|
+
const raw = process.env[envName];
|
|
629
|
+
if (raw === void 0 || raw === "") {
|
|
630
|
+
const msg = `[${tag}] ${failLine} reason=missing-env env=${envName}`;
|
|
631
|
+
throw new MissingPortEnvError(envName, tag, failLine, msg);
|
|
632
|
+
}
|
|
633
|
+
const parsed = Number.parseInt(raw, 10);
|
|
634
|
+
if (!Number.isInteger(parsed) || parsed < VALID_PORT_MIN || parsed > VALID_PORT_MAX || String(parsed) !== raw.trim()) {
|
|
635
|
+
const msg = `[${tag}] ${failLine} reason=invalid-port-env env=${envName} value=${JSON.stringify(raw)}`;
|
|
636
|
+
throw new MissingPortEnvError(envName, tag, failLine, msg);
|
|
637
|
+
}
|
|
638
|
+
return parsed;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
|
|
603
643
|
// node_modules/hono/dist/utils/mime.js
|
|
604
644
|
var getMimeType = (filename, mimes = baseMimes) => {
|
|
605
645
|
const regexp = /\.([a-zA-Z0-9]+?)$/;
|
|
@@ -6662,32 +6702,46 @@ app5.post("/", async (c) => {
|
|
|
6662
6702
|
var client_error_default = app5;
|
|
6663
6703
|
|
|
6664
6704
|
// server/routes/admin/session.ts
|
|
6665
|
-
import { readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4, existsSync as existsSync8 } from "fs";
|
|
6666
|
-
import { join as join8 } from "path";
|
|
6667
|
-
import { createHash as createHash2 } from "crypto";
|
|
6668
6705
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
6706
|
+
|
|
6707
|
+
// app/lib/admin-identity/pin-validator.ts
|
|
6708
|
+
import { createHash as createHash2 } from "crypto";
|
|
6709
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
6710
|
+
import { join as join8 } from "path";
|
|
6669
6711
|
function hashPin2(pin) {
|
|
6670
6712
|
return createHash2("sha256").update(pin).digest("hex");
|
|
6671
6713
|
}
|
|
6672
|
-
function readUsersFile2() {
|
|
6673
|
-
if (!existsSync8(
|
|
6674
|
-
const raw = readFileSync9(
|
|
6714
|
+
function readUsersFile2(usersFilePath) {
|
|
6715
|
+
if (!existsSync8(usersFilePath)) return null;
|
|
6716
|
+
const raw = readFileSync9(usersFilePath, "utf-8").trim();
|
|
6675
6717
|
if (!raw) return [];
|
|
6676
6718
|
return JSON.parse(raw);
|
|
6677
6719
|
}
|
|
6678
|
-
function
|
|
6679
|
-
|
|
6720
|
+
function validatePin(pin, usersFilePath) {
|
|
6721
|
+
let users;
|
|
6722
|
+
try {
|
|
6723
|
+
users = readUsersFile2(usersFilePath);
|
|
6724
|
+
} catch (err) {
|
|
6725
|
+
return { kind: "corrupt", message: err instanceof Error ? err.message : String(err) };
|
|
6726
|
+
}
|
|
6727
|
+
if (users === null || users.length === 0) return { kind: "unavailable" };
|
|
6728
|
+
const inputHash = hashPin2(pin);
|
|
6729
|
+
const matched = users.find((u) => u.pin === inputHash);
|
|
6730
|
+
return matched ? { kind: "match", userId: matched.userId } : { kind: "miss" };
|
|
6731
|
+
}
|
|
6732
|
+
function scanForOrphanedAccountAdmins(users, accountsDir) {
|
|
6733
|
+
const known = new Set(users.map((u) => u.userId));
|
|
6680
6734
|
const orphans = [];
|
|
6681
|
-
if (!existsSync8(
|
|
6735
|
+
if (!existsSync8(accountsDir)) return orphans;
|
|
6682
6736
|
let entries;
|
|
6683
6737
|
try {
|
|
6684
|
-
entries = readdirSync4(
|
|
6738
|
+
entries = readdirSync4(accountsDir);
|
|
6685
6739
|
} catch {
|
|
6686
6740
|
return orphans;
|
|
6687
6741
|
}
|
|
6688
6742
|
for (const entry of entries) {
|
|
6689
6743
|
if (entry.startsWith(".")) continue;
|
|
6690
|
-
const accountDir = join8(
|
|
6744
|
+
const accountDir = join8(accountsDir, entry);
|
|
6691
6745
|
try {
|
|
6692
6746
|
if (!statSync4(accountDir).isDirectory()) continue;
|
|
6693
6747
|
} catch {
|
|
@@ -6699,9 +6753,7 @@ function scanForOrphanedAccountAdmins(users) {
|
|
|
6699
6753
|
const config = JSON.parse(readFileSync9(accountJsonPath, "utf-8"));
|
|
6700
6754
|
const admins = config.admins ?? [];
|
|
6701
6755
|
for (const a of admins) {
|
|
6702
|
-
if (typeof a.userId === "string" && !
|
|
6703
|
-
orphans.push(a.userId);
|
|
6704
|
-
}
|
|
6756
|
+
if (typeof a.userId === "string" && !known.has(a.userId)) orphans.push(a.userId);
|
|
6705
6757
|
}
|
|
6706
6758
|
} catch {
|
|
6707
6759
|
continue;
|
|
@@ -6709,6 +6761,8 @@ function scanForOrphanedAccountAdmins(users) {
|
|
|
6709
6761
|
}
|
|
6710
6762
|
return orphans;
|
|
6711
6763
|
}
|
|
6764
|
+
|
|
6765
|
+
// server/routes/admin/session.ts
|
|
6712
6766
|
async function resolveUserIdentity(accountId, userId) {
|
|
6713
6767
|
const result = await loadAdminUserName(accountId, userId);
|
|
6714
6768
|
if (result.source === "neo4j") {
|
|
@@ -6818,20 +6872,21 @@ app6.post("/", async (c) => {
|
|
|
6818
6872
|
return c.json({ error: "Invalid request" }, 400);
|
|
6819
6873
|
}
|
|
6820
6874
|
if (!body.pin) return c.json({ error: "Invalid request" }, 400);
|
|
6821
|
-
const
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
users = readUsersFile2();
|
|
6825
|
-
} catch (err) {
|
|
6826
|
-
console.error(`[session] users.json corrupt: ${err instanceof Error ? err.message : String(err)}`);
|
|
6875
|
+
const verdict = validatePin(body.pin, USERS_FILE);
|
|
6876
|
+
if (verdict.kind === "corrupt") {
|
|
6877
|
+
console.error(`[session] users.json corrupt: ${verdict.message}`);
|
|
6827
6878
|
return c.json({ error: "User configuration is corrupt. Re-run the seed script." }, 503);
|
|
6828
6879
|
}
|
|
6829
|
-
if (
|
|
6880
|
+
if (verdict.kind === "unavailable") {
|
|
6830
6881
|
return c.json({ error: "PIN not configured. Complete onboarding first." }, 503);
|
|
6831
6882
|
}
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6883
|
+
if (verdict.kind === "miss") {
|
|
6884
|
+
let users = [];
|
|
6885
|
+
try {
|
|
6886
|
+
users = readUsersFile2(USERS_FILE) ?? [];
|
|
6887
|
+
} catch {
|
|
6888
|
+
}
|
|
6889
|
+
const orphanUserIds = scanForOrphanedAccountAdmins(users, ACCOUNTS_DIR);
|
|
6835
6890
|
if (orphanUserIds.length > 0) {
|
|
6836
6891
|
const prefix = orphanUserIds[0].slice(0, 8);
|
|
6837
6892
|
console.log(
|
|
@@ -6842,7 +6897,7 @@ app6.post("/", async (c) => {
|
|
|
6842
6897
|
}
|
|
6843
6898
|
return c.json({ error: "Invalid PIN" }, 401);
|
|
6844
6899
|
}
|
|
6845
|
-
const { userId } =
|
|
6900
|
+
const { userId } = verdict;
|
|
6846
6901
|
const accounts = resolveUserAccounts(userId);
|
|
6847
6902
|
if (accounts.length === 0) {
|
|
6848
6903
|
console.log(`[session] user has no accounts: userId=${userId}`);
|
|
@@ -7551,11 +7606,11 @@ app11.delete("/:id", requireAdminSession, async (c) => {
|
|
|
7551
7606
|
const owned = await verifyConversationOwnership(sessionId, accountId);
|
|
7552
7607
|
if (!owned) return c.json({ error: "Conversation not found" }, 404);
|
|
7553
7608
|
const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-conversation-delete" });
|
|
7554
|
-
const
|
|
7609
|
+
const managerBase6 = `http://127.0.0.1:${managerPort}`;
|
|
7555
7610
|
const outcome = await cascadeAdminConversationDelete({
|
|
7556
7611
|
sessionId,
|
|
7557
7612
|
accountId,
|
|
7558
|
-
managerBase:
|
|
7613
|
+
managerBase: managerBase6
|
|
7559
7614
|
});
|
|
7560
7615
|
if (outcome.ok) return c.json({ ok: true, claudeSessionIds: outcome.claudeSessionIds });
|
|
7561
7616
|
if (outcome.reason === "pty-still-alive") {
|
|
@@ -8437,18 +8492,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
8437
8492
|
]);
|
|
8438
8493
|
var app14 = new Hono();
|
|
8439
8494
|
app14.post("/", async (c) => {
|
|
8440
|
-
const
|
|
8495
|
+
const TAG29 = "[admin:events]";
|
|
8441
8496
|
let body;
|
|
8442
8497
|
try {
|
|
8443
8498
|
body = await c.req.json();
|
|
8444
8499
|
} catch (err) {
|
|
8445
8500
|
const detail = err instanceof Error ? err.message : String(err);
|
|
8446
|
-
console.error(`${
|
|
8501
|
+
console.error(`${TAG29} reject reason=body-not-json detail=${detail}`);
|
|
8447
8502
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
8448
8503
|
}
|
|
8449
8504
|
const event = typeof body.event === "string" ? body.event : "";
|
|
8450
8505
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
8451
|
-
console.error(`${
|
|
8506
|
+
console.error(`${TAG29} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
8452
8507
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
8453
8508
|
}
|
|
8454
8509
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -11259,7 +11314,7 @@ app18.post("/", requireAdminSession, async (c) => {
|
|
|
11259
11314
|
return c.json({ error: "AdminConversation node is missing sessionId" }, 500);
|
|
11260
11315
|
}
|
|
11261
11316
|
const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
|
|
11262
|
-
const
|
|
11317
|
+
const managerBase6 = `http://127.0.0.1:${managerPort}`;
|
|
11263
11318
|
try {
|
|
11264
11319
|
await session.close();
|
|
11265
11320
|
} catch {
|
|
@@ -11267,7 +11322,7 @@ app18.post("/", requireAdminSession, async (c) => {
|
|
|
11267
11322
|
const outcome = await cascadeAdminConversationDelete({
|
|
11268
11323
|
sessionId,
|
|
11269
11324
|
accountId,
|
|
11270
|
-
managerBase:
|
|
11325
|
+
managerBase: managerBase6
|
|
11271
11326
|
});
|
|
11272
11327
|
const elapsed2 = Date.now() - started;
|
|
11273
11328
|
const labelSummary2 = preflightLabels.join(",");
|
|
@@ -12899,36 +12954,89 @@ app32.post("/", async (c) => {
|
|
|
12899
12954
|
});
|
|
12900
12955
|
var access_session_evict_default = app32;
|
|
12901
12956
|
|
|
12902
|
-
// server/routes/admin/
|
|
12957
|
+
// server/routes/admin/identity.ts
|
|
12958
|
+
var import_dist4 = __toESM(require_dist3(), 1);
|
|
12903
12959
|
var app33 = new Hono();
|
|
12904
|
-
|
|
12905
|
-
|
|
12906
|
-
|
|
12907
|
-
|
|
12908
|
-
|
|
12909
|
-
app33.
|
|
12910
|
-
|
|
12911
|
-
|
|
12912
|
-
|
|
12913
|
-
|
|
12914
|
-
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
|
|
12918
|
-
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12960
|
+
var TAG25 = "[admin-identity]";
|
|
12961
|
+
function managerBase5() {
|
|
12962
|
+
const port2 = (0, import_dist4.requirePortEnv)("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-identity" });
|
|
12963
|
+
return `http://127.0.0.1:${port2}`;
|
|
12964
|
+
}
|
|
12965
|
+
app33.post("/validate", async (c) => {
|
|
12966
|
+
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
12967
|
+
const isLoopback = remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1";
|
|
12968
|
+
if (!isLoopback || c.req.header("x-forwarded-for")) {
|
|
12969
|
+
return c.json({ error: "forbidden" }, 403);
|
|
12970
|
+
}
|
|
12971
|
+
let body;
|
|
12972
|
+
try {
|
|
12973
|
+
body = await c.req.json();
|
|
12974
|
+
} catch {
|
|
12975
|
+
return c.json({ error: "bad-request" }, 400);
|
|
12976
|
+
}
|
|
12977
|
+
const pin = typeof body.pin === "string" ? body.pin : "";
|
|
12978
|
+
const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
|
|
12979
|
+
if (!pin) return c.json({ error: "bad-request" }, 400);
|
|
12980
|
+
const fireStop = () => {
|
|
12981
|
+
if (sessionId) {
|
|
12982
|
+
void fetch(`${managerBase5()}/${encodeURIComponent(sessionId)}/stop`, { method: "POST" }).catch(
|
|
12983
|
+
() => {
|
|
12984
|
+
}
|
|
12985
|
+
);
|
|
12986
|
+
}
|
|
12987
|
+
};
|
|
12988
|
+
const verdict = validatePin(pin, USERS_FILE);
|
|
12989
|
+
if (verdict.kind !== "match") {
|
|
12990
|
+
if (verdict.kind === "miss") fireStop();
|
|
12991
|
+
console.log(`${TAG25} op=endpoint-validate result=${verdict.kind}${sessionId ? ` sessionId=${sessionId.slice(0, 8)}` : ""}`);
|
|
12992
|
+
return c.json({ kind: verdict.kind });
|
|
12993
|
+
}
|
|
12994
|
+
const { userId } = verdict;
|
|
12995
|
+
const accounts = resolveUserAccounts(userId);
|
|
12996
|
+
if (accounts.length === 0) {
|
|
12997
|
+
fireStop();
|
|
12998
|
+
console.log(`${TAG25} op=endpoint-validate result=no-account userId=${userId.slice(0, 8)}`);
|
|
12999
|
+
return c.json({ kind: "miss" });
|
|
13000
|
+
}
|
|
13001
|
+
const accountId = accounts[0].accountId;
|
|
13002
|
+
const { userName } = await resolveUserIdentity(accountId, userId);
|
|
13003
|
+
const aboutOwner = await resolveOwnerProfileBlock(accountId, userId);
|
|
13004
|
+
console.log(`${TAG25} op=endpoint-validate result=match userId=${userId.slice(0, 8)} aboutOwner=${aboutOwner.ok ? "ok" : `unresolved:${aboutOwner.reason}`}`);
|
|
13005
|
+
return c.json({ kind: "match", userId, userName, aboutOwner });
|
|
13006
|
+
});
|
|
13007
|
+
var identity_default = app33;
|
|
13008
|
+
|
|
13009
|
+
// server/routes/admin/index.ts
|
|
13010
|
+
var app34 = new Hono();
|
|
13011
|
+
app34.route("/session", session_default);
|
|
13012
|
+
app34.route("/identity", identity_default);
|
|
13013
|
+
app34.route("/logs", logs_default);
|
|
13014
|
+
app34.route("/claude-info", claude_info_default);
|
|
13015
|
+
app34.route("/attachment", attachment_default);
|
|
13016
|
+
app34.route("/agents", agents_default);
|
|
13017
|
+
app34.route("/sessions", sessions_default);
|
|
13018
|
+
app34.route("/claude-sessions", claude_sessions_default);
|
|
13019
|
+
app34.route("/log-ingest", log_ingest_default);
|
|
13020
|
+
app34.route("/events", events_default);
|
|
13021
|
+
app34.route("/files", files_default);
|
|
13022
|
+
app34.route("/graph-search", graph_search_default);
|
|
13023
|
+
app34.route("/graph-subgraph", graph_subgraph_default);
|
|
13024
|
+
app34.route("/graph-delete", graph_delete_default);
|
|
13025
|
+
app34.route("/graph-restore", graph_restore_default);
|
|
13026
|
+
app34.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
13027
|
+
app34.route("/graph-default-view", graph_default_view_default);
|
|
13028
|
+
app34.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
13029
|
+
app34.route("/sidebar-sessions", sidebar_sessions_default);
|
|
13030
|
+
app34.route("/session-delete", session_delete_default);
|
|
13031
|
+
app34.route("/session-rc-spawn", session_rc_spawn_default);
|
|
13032
|
+
app34.route("/system-stats", system_stats_default);
|
|
13033
|
+
app34.route("/health-brand", health_default2);
|
|
13034
|
+
app34.route("/linkedin-ingest", linkedin_ingest_default);
|
|
13035
|
+
app34.route("/post-turn-context", post_turn_context_default);
|
|
13036
|
+
app34.route("/public-session-context", public_session_context_default);
|
|
13037
|
+
app34.route("/public-session-exit", public_session_exit_default);
|
|
13038
|
+
app34.route("/access-session-evict", access_session_evict_default);
|
|
13039
|
+
var admin_default = app34;
|
|
12932
13040
|
|
|
12933
13041
|
// app/lib/access-gate.ts
|
|
12934
13042
|
import neo4j4 from "neo4j-driver";
|
|
@@ -13139,11 +13247,11 @@ async function generateNewMagicToken(grantId) {
|
|
|
13139
13247
|
}
|
|
13140
13248
|
|
|
13141
13249
|
// server/routes/access/verify-token.ts
|
|
13142
|
-
var
|
|
13250
|
+
var TAG26 = "[access-verify]";
|
|
13143
13251
|
var MINT_TAG = "[access-session-mint]";
|
|
13144
13252
|
var COOKIE_NAME = "__access_session";
|
|
13145
|
-
var
|
|
13146
|
-
|
|
13253
|
+
var app35 = new Hono();
|
|
13254
|
+
app35.post("/", async (c) => {
|
|
13147
13255
|
const ip = c.var.clientIp || "unknown";
|
|
13148
13256
|
let body;
|
|
13149
13257
|
try {
|
|
@@ -13158,39 +13266,39 @@ app34.post("/", async (c) => {
|
|
|
13158
13266
|
}
|
|
13159
13267
|
const rateMsg = checkAccessRateLimit(ip, agentSlug);
|
|
13160
13268
|
if (rateMsg) {
|
|
13161
|
-
console.error(`${
|
|
13269
|
+
console.error(`${TAG26} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
|
|
13162
13270
|
return c.json({ error: rateMsg }, 429);
|
|
13163
13271
|
}
|
|
13164
13272
|
const grant = await findGrantByMagicToken(token);
|
|
13165
13273
|
if (!grant) {
|
|
13166
13274
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
13167
|
-
console.error(`${
|
|
13275
|
+
console.error(`${TAG26} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
|
|
13168
13276
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
13169
13277
|
}
|
|
13170
13278
|
if (grant.agentSlug !== agentSlug) {
|
|
13171
13279
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
13172
13280
|
console.error(
|
|
13173
|
-
`${
|
|
13281
|
+
`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
|
|
13174
13282
|
);
|
|
13175
13283
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
13176
13284
|
}
|
|
13177
13285
|
if (grant.status === "expired" || grant.status === "revoked") {
|
|
13178
13286
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
13179
13287
|
console.error(
|
|
13180
|
-
`${
|
|
13288
|
+
`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
|
|
13181
13289
|
);
|
|
13182
13290
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
13183
13291
|
}
|
|
13184
13292
|
if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
|
|
13185
13293
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
13186
13294
|
console.error(
|
|
13187
|
-
`${
|
|
13295
|
+
`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
|
|
13188
13296
|
);
|
|
13189
13297
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
13190
13298
|
}
|
|
13191
13299
|
if (!grant.sliceToken) {
|
|
13192
13300
|
console.error(
|
|
13193
|
-
`${
|
|
13301
|
+
`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
|
|
13194
13302
|
);
|
|
13195
13303
|
return c.json({ error: "grant-misconfigured" }, 500);
|
|
13196
13304
|
}
|
|
@@ -13206,12 +13314,12 @@ app34.post("/", async (c) => {
|
|
|
13206
13314
|
await consumeMagicTokenAndActivate(grant.grantId);
|
|
13207
13315
|
} catch (err) {
|
|
13208
13316
|
console.error(
|
|
13209
|
-
`${
|
|
13317
|
+
`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
13210
13318
|
);
|
|
13211
13319
|
return c.json({ error: "verification-failed" }, 500);
|
|
13212
13320
|
}
|
|
13213
13321
|
clearAccessRateLimit(ip, agentSlug);
|
|
13214
|
-
console.log(`${
|
|
13322
|
+
console.log(`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
|
|
13215
13323
|
console.log(
|
|
13216
13324
|
`${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
|
|
13217
13325
|
);
|
|
@@ -13225,7 +13333,7 @@ app34.post("/", async (c) => {
|
|
|
13225
13333
|
displayName: grant.displayName
|
|
13226
13334
|
});
|
|
13227
13335
|
});
|
|
13228
|
-
var verify_token_default =
|
|
13336
|
+
var verify_token_default = app35;
|
|
13229
13337
|
|
|
13230
13338
|
// app/lib/access-email.ts
|
|
13231
13339
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -13287,10 +13395,10 @@ async function sendMagicLinkEmail(payload) {
|
|
|
13287
13395
|
}
|
|
13288
13396
|
|
|
13289
13397
|
// server/routes/access/request-magic-link.ts
|
|
13290
|
-
var
|
|
13291
|
-
var
|
|
13398
|
+
var TAG27 = "[access-request-link]";
|
|
13399
|
+
var app36 = new Hono();
|
|
13292
13400
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
13293
|
-
|
|
13401
|
+
app36.post("/", async (c) => {
|
|
13294
13402
|
let body;
|
|
13295
13403
|
try {
|
|
13296
13404
|
body = await c.req.json();
|
|
@@ -13304,18 +13412,18 @@ app35.post("/", async (c) => {
|
|
|
13304
13412
|
}
|
|
13305
13413
|
const rateMsg = checkRequestLinkRateLimit(contactValue);
|
|
13306
13414
|
if (rateMsg) {
|
|
13307
|
-
console.error(`${
|
|
13415
|
+
console.error(`${TAG27} contactValue=${maskContact(contactValue)} result=rate-limited`);
|
|
13308
13416
|
return c.json({ error: rateMsg }, 429);
|
|
13309
13417
|
}
|
|
13310
13418
|
recordRequestLinkAttempt(contactValue);
|
|
13311
13419
|
const accountId = process.env.ACCOUNT_ID ?? "";
|
|
13312
13420
|
if (!accountId) {
|
|
13313
|
-
console.error(`${
|
|
13421
|
+
console.error(`${TAG27} contactValue=${maskContact(contactValue)} result=no-account-id`);
|
|
13314
13422
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
13315
13423
|
}
|
|
13316
13424
|
const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
|
|
13317
13425
|
if (!grant) {
|
|
13318
|
-
console.log(`${
|
|
13426
|
+
console.log(`${TAG27} contactValue=${maskContact(contactValue)} result=notfound`);
|
|
13319
13427
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
13320
13428
|
}
|
|
13321
13429
|
let token;
|
|
@@ -13323,7 +13431,7 @@ app35.post("/", async (c) => {
|
|
|
13323
13431
|
token = await generateNewMagicToken(grant.grantId);
|
|
13324
13432
|
} catch (err) {
|
|
13325
13433
|
console.error(
|
|
13326
|
-
`${
|
|
13434
|
+
`${TAG27} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
13327
13435
|
);
|
|
13328
13436
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
13329
13437
|
}
|
|
@@ -13355,22 +13463,22 @@ app35.post("/", async (c) => {
|
|
|
13355
13463
|
});
|
|
13356
13464
|
if (!sendResult.ok) {
|
|
13357
13465
|
console.error(
|
|
13358
|
-
`${
|
|
13466
|
+
`${TAG27} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
|
|
13359
13467
|
);
|
|
13360
13468
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
13361
13469
|
}
|
|
13362
13470
|
console.log(
|
|
13363
|
-
`${
|
|
13471
|
+
`${TAG27} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
|
|
13364
13472
|
);
|
|
13365
13473
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
13366
13474
|
});
|
|
13367
|
-
var request_magic_link_default =
|
|
13475
|
+
var request_magic_link_default = app36;
|
|
13368
13476
|
|
|
13369
13477
|
// server/routes/access/index.ts
|
|
13370
|
-
var
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
var access_default =
|
|
13478
|
+
var app37 = new Hono();
|
|
13479
|
+
app37.route("/verify-token", verify_token_default);
|
|
13480
|
+
app37.route("/request-magic-link", request_magic_link_default);
|
|
13481
|
+
var access_default = app37;
|
|
13374
13482
|
|
|
13375
13483
|
// server/routes/sites.ts
|
|
13376
13484
|
import { existsSync as existsSync19, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
|
|
@@ -13405,8 +13513,8 @@ function getExt(p) {
|
|
|
13405
13513
|
if (idx < p.lastIndexOf("/")) return "";
|
|
13406
13514
|
return p.slice(idx).toLowerCase();
|
|
13407
13515
|
}
|
|
13408
|
-
var
|
|
13409
|
-
|
|
13516
|
+
var app38 = new Hono();
|
|
13517
|
+
app38.get("/:rel{.*}", (c) => {
|
|
13410
13518
|
const reqPath = c.req.path;
|
|
13411
13519
|
const rawRel = c.req.param("rel") ?? "";
|
|
13412
13520
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -13509,7 +13617,7 @@ app37.get("/:rel{.*}", (c) => {
|
|
|
13509
13617
|
"X-Content-Type-Options": "nosniff"
|
|
13510
13618
|
});
|
|
13511
13619
|
});
|
|
13512
|
-
var sites_default =
|
|
13620
|
+
var sites_default = app38;
|
|
13513
13621
|
|
|
13514
13622
|
// app/lib/visitor-token.ts
|
|
13515
13623
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -13609,7 +13717,7 @@ function readBrandConfig() {
|
|
|
13609
13717
|
}
|
|
13610
13718
|
|
|
13611
13719
|
// server/routes/visitor-consent.ts
|
|
13612
|
-
var
|
|
13720
|
+
var app39 = new Hono();
|
|
13613
13721
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
13614
13722
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
13615
13723
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -13654,17 +13762,17 @@ function siteSlugFromReferer(referer) {
|
|
|
13654
13762
|
return "";
|
|
13655
13763
|
}
|
|
13656
13764
|
}
|
|
13657
|
-
|
|
13765
|
+
app39.options("/consent", (c) => {
|
|
13658
13766
|
const origin = getOrigin(c);
|
|
13659
13767
|
setCorsHeaders(c, origin);
|
|
13660
13768
|
return c.body(null, 204);
|
|
13661
13769
|
});
|
|
13662
|
-
|
|
13770
|
+
app39.options("/brand-config", (c) => {
|
|
13663
13771
|
const origin = getOrigin(c);
|
|
13664
13772
|
setCorsHeaders(c, origin);
|
|
13665
13773
|
return c.body(null, 204);
|
|
13666
13774
|
});
|
|
13667
|
-
|
|
13775
|
+
app39.post("/consent", async (c) => {
|
|
13668
13776
|
const origin = getOrigin(c);
|
|
13669
13777
|
setCorsHeaders(c, origin);
|
|
13670
13778
|
let raw;
|
|
@@ -13704,7 +13812,7 @@ app38.post("/consent", async (c) => {
|
|
|
13704
13812
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
13705
13813
|
return c.body(null, 204);
|
|
13706
13814
|
});
|
|
13707
|
-
|
|
13815
|
+
app39.get("/brand-config", (c) => {
|
|
13708
13816
|
const origin = getOrigin(c);
|
|
13709
13817
|
setCorsHeaders(c, origin);
|
|
13710
13818
|
const brand = readBrandConfig();
|
|
@@ -13714,7 +13822,7 @@ app38.get("/brand-config", (c) => {
|
|
|
13714
13822
|
c.header("Cache-Control", "public, max-age=300");
|
|
13715
13823
|
return c.json({ consent: { copy, palette } });
|
|
13716
13824
|
});
|
|
13717
|
-
var visitor_consent_default =
|
|
13825
|
+
var visitor_consent_default = app39;
|
|
13718
13826
|
|
|
13719
13827
|
// server/routes/listings.ts
|
|
13720
13828
|
function getCookie(headerValue, name) {
|
|
@@ -13741,8 +13849,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
13741
13849
|
}
|
|
13742
13850
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
13743
13851
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
13744
|
-
var
|
|
13745
|
-
|
|
13852
|
+
var app40 = new Hono();
|
|
13853
|
+
app40.get("/:slug/click", async (c) => {
|
|
13746
13854
|
const slug = c.req.param("slug") ?? "";
|
|
13747
13855
|
const rawSession = c.req.query("session") ?? "";
|
|
13748
13856
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -13806,10 +13914,10 @@ app39.get("/:slug/click", async (c) => {
|
|
|
13806
13914
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
13807
13915
|
return c.redirect(redirectUrl, 302);
|
|
13808
13916
|
});
|
|
13809
|
-
var listings_default =
|
|
13917
|
+
var listings_default = app40;
|
|
13810
13918
|
|
|
13811
13919
|
// server/routes/visitor-event.ts
|
|
13812
|
-
var
|
|
13920
|
+
var app41 = new Hono();
|
|
13813
13921
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
13814
13922
|
var buckets = /* @__PURE__ */ new Map();
|
|
13815
13923
|
var RATE_LIMIT = 60;
|
|
@@ -13876,12 +13984,12 @@ function originAllowed(origin, allowlist) {
|
|
|
13876
13984
|
return false;
|
|
13877
13985
|
}
|
|
13878
13986
|
}
|
|
13879
|
-
|
|
13987
|
+
app41.options("/event", (c) => {
|
|
13880
13988
|
const origin = getOrigin2(c);
|
|
13881
13989
|
setCorsHeaders2(c, origin);
|
|
13882
13990
|
return c.body(null, 204);
|
|
13883
13991
|
});
|
|
13884
|
-
|
|
13992
|
+
app41.post("/event", async (c) => {
|
|
13885
13993
|
const origin = getOrigin2(c);
|
|
13886
13994
|
setCorsHeaders2(c, origin);
|
|
13887
13995
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -14086,7 +14194,7 @@ async function writeEvent(opts) {
|
|
|
14086
14194
|
);
|
|
14087
14195
|
}
|
|
14088
14196
|
}
|
|
14089
|
-
var visitor_event_default =
|
|
14197
|
+
var visitor_event_default = app41;
|
|
14090
14198
|
|
|
14091
14199
|
// server/routes/session.ts
|
|
14092
14200
|
import { resolve as resolve22 } from "path";
|
|
@@ -14123,8 +14231,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
14123
14231
|
headers
|
|
14124
14232
|
});
|
|
14125
14233
|
}
|
|
14126
|
-
var
|
|
14127
|
-
|
|
14234
|
+
var app42 = new Hono();
|
|
14235
|
+
app42.post("/", async (c) => {
|
|
14128
14236
|
let body;
|
|
14129
14237
|
try {
|
|
14130
14238
|
body = await c.req.json();
|
|
@@ -14324,7 +14432,7 @@ app41.post("/", async (c) => {
|
|
|
14324
14432
|
newVisitorId
|
|
14325
14433
|
);
|
|
14326
14434
|
});
|
|
14327
|
-
var session_default2 =
|
|
14435
|
+
var session_default2 = app42;
|
|
14328
14436
|
|
|
14329
14437
|
// app/lib/graph-health.ts
|
|
14330
14438
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -14511,7 +14619,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
14511
14619
|
}
|
|
14512
14620
|
|
|
14513
14621
|
// app/lib/whatsapp/inbound/claude-bridge.ts
|
|
14514
|
-
var
|
|
14622
|
+
var TAG28 = "[whatsapp-adaptor]";
|
|
14515
14623
|
function whatsappTurnTimeoutMs() {
|
|
14516
14624
|
return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
|
|
14517
14625
|
}
|
|
@@ -14533,7 +14641,7 @@ async function dispatchToClaude(input) {
|
|
|
14533
14641
|
await input.reply(result.turnText);
|
|
14534
14642
|
} catch (err) {
|
|
14535
14643
|
const m = err instanceof Error ? err.message : String(err);
|
|
14536
|
-
console.error(`${
|
|
14644
|
+
console.error(`${TAG28} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
|
|
14537
14645
|
}
|
|
14538
14646
|
}
|
|
14539
14647
|
function startReaper2() {
|
|
@@ -14863,9 +14971,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
14863
14971
|
function isPublicHost(host) {
|
|
14864
14972
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
14865
14973
|
}
|
|
14866
|
-
var
|
|
14867
|
-
|
|
14868
|
-
|
|
14974
|
+
var app43 = new Hono();
|
|
14975
|
+
app43.use("*", clientIpMiddleware);
|
|
14976
|
+
app43.use("*", async (c, next) => {
|
|
14869
14977
|
await next();
|
|
14870
14978
|
c.header("X-Content-Type-Options", "nosniff");
|
|
14871
14979
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -14875,7 +14983,7 @@ app42.use("*", async (c, next) => {
|
|
|
14875
14983
|
);
|
|
14876
14984
|
});
|
|
14877
14985
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
14878
|
-
|
|
14986
|
+
app43.use("*", async (c, next) => {
|
|
14879
14987
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
14880
14988
|
await next();
|
|
14881
14989
|
return;
|
|
@@ -14893,7 +15001,7 @@ app42.use("*", async (c, next) => {
|
|
|
14893
15001
|
});
|
|
14894
15002
|
}
|
|
14895
15003
|
});
|
|
14896
|
-
|
|
15004
|
+
app43.use("*", async (c, next) => {
|
|
14897
15005
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14898
15006
|
if (!isPublicHost(host)) {
|
|
14899
15007
|
await next();
|
|
@@ -14924,7 +15032,7 @@ function resolveRemoteAuthOpts() {
|
|
|
14924
15032
|
return brandLoginOpts;
|
|
14925
15033
|
}
|
|
14926
15034
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
14927
|
-
|
|
15035
|
+
app43.post("/__remote-auth/login", async (c) => {
|
|
14928
15036
|
const client = clientFrom(c);
|
|
14929
15037
|
const clientIp = client.ip || "unknown";
|
|
14930
15038
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -14969,7 +15077,7 @@ app42.post("/__remote-auth/login", async (c) => {
|
|
|
14969
15077
|
}
|
|
14970
15078
|
});
|
|
14971
15079
|
});
|
|
14972
|
-
|
|
15080
|
+
app43.get("/__remote-auth/logout", (c) => {
|
|
14973
15081
|
const client = clientFrom(c);
|
|
14974
15082
|
const clientIp = client.ip || "unknown";
|
|
14975
15083
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -14982,7 +15090,7 @@ app42.get("/__remote-auth/logout", (c) => {
|
|
|
14982
15090
|
}
|
|
14983
15091
|
});
|
|
14984
15092
|
});
|
|
14985
|
-
|
|
15093
|
+
app43.post("/__remote-auth/change-password", async (c) => {
|
|
14986
15094
|
const client = clientFrom(c);
|
|
14987
15095
|
const clientIp = client.ip || "unknown";
|
|
14988
15096
|
const rateLimited = checkRateLimit(client);
|
|
@@ -15033,13 +15141,13 @@ app42.post("/__remote-auth/change-password", async (c) => {
|
|
|
15033
15141
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
15034
15142
|
}
|
|
15035
15143
|
});
|
|
15036
|
-
|
|
15144
|
+
app43.get("/__remote-auth/setup", (c) => {
|
|
15037
15145
|
if (isRemoteAuthConfigured()) {
|
|
15038
15146
|
return c.redirect("/");
|
|
15039
15147
|
}
|
|
15040
15148
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
15041
15149
|
});
|
|
15042
|
-
|
|
15150
|
+
app43.post("/__remote-auth/set-initial-password", async (c) => {
|
|
15043
15151
|
if (isRemoteAuthConfigured()) {
|
|
15044
15152
|
return c.redirect("/");
|
|
15045
15153
|
}
|
|
@@ -15077,10 +15185,10 @@ app42.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
15077
15185
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
15078
15186
|
}
|
|
15079
15187
|
});
|
|
15080
|
-
|
|
15188
|
+
app43.get("/api/remote-auth/status", (c) => {
|
|
15081
15189
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
15082
15190
|
});
|
|
15083
|
-
|
|
15191
|
+
app43.post("/api/remote-auth/set-password", async (c) => {
|
|
15084
15192
|
let body;
|
|
15085
15193
|
try {
|
|
15086
15194
|
body = await c.req.json();
|
|
@@ -15111,9 +15219,9 @@ app42.post("/api/remote-auth/set-password", async (c) => {
|
|
|
15111
15219
|
return c.json({ error: "Failed to save password" }, 500);
|
|
15112
15220
|
}
|
|
15113
15221
|
});
|
|
15114
|
-
|
|
15222
|
+
app43.route("/api/_client-error", client_error_default);
|
|
15115
15223
|
console.log("[client-error-route] mounted");
|
|
15116
|
-
|
|
15224
|
+
app43.use("*", async (c, next) => {
|
|
15117
15225
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15118
15226
|
const path2 = c.req.path;
|
|
15119
15227
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -15146,13 +15254,13 @@ app42.use("*", async (c, next) => {
|
|
|
15146
15254
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
15147
15255
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
15148
15256
|
});
|
|
15149
|
-
|
|
15150
|
-
|
|
15151
|
-
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15257
|
+
app43.route("/api/health", health_default);
|
|
15258
|
+
app43.route("/api/chat", chat_default);
|
|
15259
|
+
app43.route("/api/whatsapp", whatsapp_default);
|
|
15260
|
+
app43.route("/api/onboarding", onboarding_default);
|
|
15261
|
+
app43.route("/api/admin", admin_default);
|
|
15262
|
+
app43.route("/api/access", access_default);
|
|
15263
|
+
app43.route("/api/session", session_default2);
|
|
15156
15264
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
15157
15265
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
15158
15266
|
var IMAGE_MIME = {
|
|
@@ -15164,7 +15272,7 @@ var IMAGE_MIME = {
|
|
|
15164
15272
|
".svg": "image/svg+xml",
|
|
15165
15273
|
".ico": "image/x-icon"
|
|
15166
15274
|
};
|
|
15167
|
-
|
|
15275
|
+
app43.get("/agent-assets/:slug/:filename", (c) => {
|
|
15168
15276
|
const slug = c.req.param("slug");
|
|
15169
15277
|
const filename = c.req.param("filename");
|
|
15170
15278
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -15199,7 +15307,7 @@ app42.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
15199
15307
|
"Cache-Control": "public, max-age=3600"
|
|
15200
15308
|
});
|
|
15201
15309
|
});
|
|
15202
|
-
|
|
15310
|
+
app43.get("/generated/:filename", (c) => {
|
|
15203
15311
|
const filename = c.req.param("filename");
|
|
15204
15312
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
15205
15313
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -15229,10 +15337,10 @@ app42.get("/generated/:filename", (c) => {
|
|
|
15229
15337
|
"Cache-Control": "public, max-age=86400"
|
|
15230
15338
|
});
|
|
15231
15339
|
});
|
|
15232
|
-
|
|
15233
|
-
|
|
15234
|
-
|
|
15235
|
-
|
|
15340
|
+
app43.route("/sites", sites_default);
|
|
15341
|
+
app43.route("/listings", listings_default);
|
|
15342
|
+
app43.route("/v", visitor_event_default);
|
|
15343
|
+
app43.route("/v", visitor_consent_default);
|
|
15236
15344
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
15237
15345
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
15238
15346
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -15369,7 +15477,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
15369
15477
|
function escapeHtml(s) {
|
|
15370
15478
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
15371
15479
|
}
|
|
15372
|
-
|
|
15480
|
+
app43.get("/", (c) => {
|
|
15373
15481
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15374
15482
|
if (isPublicHost(host)) {
|
|
15375
15483
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -15377,12 +15485,12 @@ app42.get("/", (c) => {
|
|
|
15377
15485
|
}
|
|
15378
15486
|
return c.html(cachedHtml("index.html"));
|
|
15379
15487
|
});
|
|
15380
|
-
|
|
15488
|
+
app43.get("/public", (c) => {
|
|
15381
15489
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15382
15490
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
15383
15491
|
return c.html(cachedHtml("public.html"));
|
|
15384
15492
|
});
|
|
15385
|
-
|
|
15493
|
+
app43.get("/chat", (c) => {
|
|
15386
15494
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15387
15495
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
15388
15496
|
return c.html(cachedHtml("public.html"));
|
|
@@ -15401,9 +15509,9 @@ async function logViewerFetch(c, next) {
|
|
|
15401
15509
|
duration_ms: Date.now() - start
|
|
15402
15510
|
});
|
|
15403
15511
|
}
|
|
15404
|
-
|
|
15405
|
-
|
|
15406
|
-
|
|
15512
|
+
app43.use("/vnc-viewer.html", logViewerFetch);
|
|
15513
|
+
app43.use("/vnc-popout.html", logViewerFetch);
|
|
15514
|
+
app43.get("/vnc-popout.html", (c) => {
|
|
15407
15515
|
let html = htmlCache.get("vnc-popout.html");
|
|
15408
15516
|
if (!html) {
|
|
15409
15517
|
html = readFileSync22(resolve25(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -15416,7 +15524,7 @@ app42.get("/vnc-popout.html", (c) => {
|
|
|
15416
15524
|
}
|
|
15417
15525
|
return c.html(html);
|
|
15418
15526
|
});
|
|
15419
|
-
|
|
15527
|
+
app43.post("/api/vnc/client-event", async (c) => {
|
|
15420
15528
|
let body;
|
|
15421
15529
|
try {
|
|
15422
15530
|
body = await c.req.json();
|
|
@@ -15437,25 +15545,25 @@ app42.post("/api/vnc/client-event", async (c) => {
|
|
|
15437
15545
|
});
|
|
15438
15546
|
return c.json({ ok: true });
|
|
15439
15547
|
});
|
|
15440
|
-
|
|
15548
|
+
app43.get("/g/:slug", (c) => {
|
|
15441
15549
|
return c.html(brandedPublicHtml());
|
|
15442
15550
|
});
|
|
15443
|
-
|
|
15551
|
+
app43.get("/graph", (c) => {
|
|
15444
15552
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15445
15553
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
15446
15554
|
return c.html(cachedHtml("graph.html"));
|
|
15447
15555
|
});
|
|
15448
|
-
|
|
15556
|
+
app43.get("/sessions", (c) => {
|
|
15449
15557
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15450
15558
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
15451
15559
|
return c.html(cachedHtml("sessions.html"));
|
|
15452
15560
|
});
|
|
15453
|
-
|
|
15561
|
+
app43.get("/data", (c) => {
|
|
15454
15562
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15455
15563
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
15456
15564
|
return c.html(cachedHtml("data.html"));
|
|
15457
15565
|
});
|
|
15458
|
-
|
|
15566
|
+
app43.get("/:slug", async (c, next) => {
|
|
15459
15567
|
const slug = c.req.param("slug");
|
|
15460
15568
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
15461
15569
|
const branding = loadBrandingCache(slug);
|
|
@@ -15465,13 +15573,13 @@ app42.get("/:slug", async (c, next) => {
|
|
|
15465
15573
|
await next();
|
|
15466
15574
|
});
|
|
15467
15575
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
15468
|
-
|
|
15576
|
+
app43.get("/favicon.ico", (c) => {
|
|
15469
15577
|
c.header("Cache-Control", "public, max-age=300");
|
|
15470
15578
|
return c.redirect(brandFaviconPath, 302);
|
|
15471
15579
|
});
|
|
15472
15580
|
}
|
|
15473
|
-
|
|
15474
|
-
|
|
15581
|
+
app43.use("/*", serveStatic({ root: "./public" }));
|
|
15582
|
+
app43.all("*", (c) => {
|
|
15475
15583
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15476
15584
|
const path2 = c.req.path;
|
|
15477
15585
|
if (isPublicHost(host)) {
|
|
@@ -15485,7 +15593,7 @@ app42.all("*", (c) => {
|
|
|
15485
15593
|
});
|
|
15486
15594
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
15487
15595
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
15488
|
-
var httpServer = serve({ fetch:
|
|
15596
|
+
var httpServer = serve({ fetch: app43.fetch, port, hostname });
|
|
15489
15597
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
15490
15598
|
startAuthHealthHeartbeat();
|
|
15491
15599
|
{
|
|
@@ -15523,7 +15631,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
15523
15631
|
}
|
|
15524
15632
|
try {
|
|
15525
15633
|
const registered = [];
|
|
15526
|
-
for (const r of
|
|
15634
|
+
for (const r of app43.routes ?? []) {
|
|
15527
15635
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
15528
15636
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
15529
15637
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|