@rubytech/create-maxy-code 0.1.126 → 0.1.127
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +12 -0
- package/package.json +1 -1
- package/payload/platform/config/brand.json +20 -1
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.d.ts +33 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.js +119 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.js.map +1 -0
- package/payload/platform/lib/aeo-llms-txt-writer/src/index.ts +172 -0
- package/payload/platform/lib/aeo-llms-txt-writer/tsconfig.json +8 -0
- package/payload/platform/package.json +2 -2
- 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/mcp/dist/index.js +73 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.d.ts +34 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.js +176 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.js.map +1 -0
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +19 -57
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.d.ts +5 -38
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.d.ts.map +1 -1
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.js +7 -114
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.js.map +1 -1
- package/payload/platform/templates/specialists/agents/content-producer.md +3 -3
- package/payload/server/public/consent.css +97 -0
- package/payload/server/public/consent.js +259 -0
- package/payload/server/public/privacy.html +68 -5
- package/payload/server/public/v.js +53 -0
- package/payload/server/server.js +229 -84
package/payload/server/server.js
CHANGED
|
@@ -12396,11 +12396,161 @@ function verifyVisitorToken(token, now = Date.now()) {
|
|
|
12396
12396
|
var VISITOR_COOKIE_NAME = "mxy_v";
|
|
12397
12397
|
var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
|
|
12398
12398
|
|
|
12399
|
+
// app/lib/brand-config.ts
|
|
12400
|
+
import { existsSync as existsSync22, readFileSync as readFileSync19 } from "fs";
|
|
12401
|
+
import { join as join14 } from "path";
|
|
12402
|
+
var cached2 = null;
|
|
12403
|
+
var cachedAttempted = false;
|
|
12404
|
+
function readBrandConfig() {
|
|
12405
|
+
if (cachedAttempted) return cached2;
|
|
12406
|
+
cachedAttempted = true;
|
|
12407
|
+
const platformRoot = process.env.MAXY_PLATFORM_ROOT;
|
|
12408
|
+
if (!platformRoot) return null;
|
|
12409
|
+
const brandPath = join14(platformRoot, "config", "brand.json");
|
|
12410
|
+
if (!existsSync22(brandPath)) return null;
|
|
12411
|
+
try {
|
|
12412
|
+
cached2 = JSON.parse(readFileSync19(brandPath, "utf-8"));
|
|
12413
|
+
return cached2;
|
|
12414
|
+
} catch {
|
|
12415
|
+
return null;
|
|
12416
|
+
}
|
|
12417
|
+
}
|
|
12418
|
+
|
|
12419
|
+
// server/routes/visitor-consent.ts
|
|
12420
|
+
var app35 = new Hono();
|
|
12421
|
+
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
12422
|
+
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
12423
|
+
var DEFAULT_CONSENT_COPY = {
|
|
12424
|
+
title: "Before you browse",
|
|
12425
|
+
body: "We use a small first-party script to count page views, scrolls and clicks on this listing. Nothing is shared with third parties. You can change your mind at any time.",
|
|
12426
|
+
accept: "Accept",
|
|
12427
|
+
reject: "Reject",
|
|
12428
|
+
manage: "Manage cookies",
|
|
12429
|
+
policyLinkText: "Read the cookie policy",
|
|
12430
|
+
policyHref: "/privacy.html#cookies"
|
|
12431
|
+
};
|
|
12432
|
+
var DEFAULT_CONSENT_PALETTE = {
|
|
12433
|
+
bg: "#FFFFFF",
|
|
12434
|
+
fg: "#1F1F1F",
|
|
12435
|
+
accent: "#1F1F1F",
|
|
12436
|
+
accentFg: "#FFFFFF",
|
|
12437
|
+
border: "#E5E5E2"
|
|
12438
|
+
};
|
|
12439
|
+
function getOrigin(c) {
|
|
12440
|
+
return c.req.header("origin") ?? c.req.header("referer") ?? "";
|
|
12441
|
+
}
|
|
12442
|
+
function setCorsHeaders(c, origin) {
|
|
12443
|
+
if (origin) c.header("Access-Control-Allow-Origin", origin);
|
|
12444
|
+
c.header("Access-Control-Allow-Credentials", "true");
|
|
12445
|
+
c.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
|
|
12446
|
+
c.header("Access-Control-Allow-Headers", "Content-Type");
|
|
12447
|
+
c.header("Vary", "Origin");
|
|
12448
|
+
}
|
|
12449
|
+
function parseConsent(body) {
|
|
12450
|
+
if (!body || typeof body !== "object") return null;
|
|
12451
|
+
const b = body;
|
|
12452
|
+
if (b.decision !== "yes" && b.decision !== "no") return null;
|
|
12453
|
+
const v = typeof b.v === "string" && b.v.length > 0 && b.v.length <= 2048 ? b.v : null;
|
|
12454
|
+
return { decision: b.decision, v };
|
|
12455
|
+
}
|
|
12456
|
+
function siteSlugFromReferer(referer) {
|
|
12457
|
+
try {
|
|
12458
|
+
const u = new URL(referer);
|
|
12459
|
+
const parts = u.pathname.split("/").filter(Boolean);
|
|
12460
|
+
return parts[parts.length - 1]?.slice(0, 120) ?? "";
|
|
12461
|
+
} catch {
|
|
12462
|
+
return "";
|
|
12463
|
+
}
|
|
12464
|
+
}
|
|
12465
|
+
app35.options("/consent", (c) => {
|
|
12466
|
+
const origin = getOrigin(c);
|
|
12467
|
+
setCorsHeaders(c, origin);
|
|
12468
|
+
return c.body(null, 204);
|
|
12469
|
+
});
|
|
12470
|
+
app35.options("/brand-config", (c) => {
|
|
12471
|
+
const origin = getOrigin(c);
|
|
12472
|
+
setCorsHeaders(c, origin);
|
|
12473
|
+
return c.body(null, 204);
|
|
12474
|
+
});
|
|
12475
|
+
app35.post("/consent", async (c) => {
|
|
12476
|
+
const origin = getOrigin(c);
|
|
12477
|
+
setCorsHeaders(c, origin);
|
|
12478
|
+
let raw;
|
|
12479
|
+
try {
|
|
12480
|
+
raw = await c.req.json();
|
|
12481
|
+
} catch {
|
|
12482
|
+
console.error("[consent-error] reason=bad-json");
|
|
12483
|
+
return c.text("Bad Request", 400);
|
|
12484
|
+
}
|
|
12485
|
+
const parsed = parseConsent(raw);
|
|
12486
|
+
if (!parsed) {
|
|
12487
|
+
console.error("[consent-error] reason=bad-body");
|
|
12488
|
+
return c.text("Bad Request", 400);
|
|
12489
|
+
}
|
|
12490
|
+
const referer = c.req.header("referer") ?? "";
|
|
12491
|
+
const site = siteSlugFromReferer(referer);
|
|
12492
|
+
const brand = readBrandConfig();
|
|
12493
|
+
const brandName = brand?.productName ?? "-";
|
|
12494
|
+
const cookies = [];
|
|
12495
|
+
cookies.push(
|
|
12496
|
+
`${CONSENT_COOKIE_NAME}=${parsed.decision}; Max-Age=${CONSENT_COOKIE_MAX_AGE_SECONDS}; Path=/; SameSite=Lax; Secure`
|
|
12497
|
+
);
|
|
12498
|
+
let tokenBound = false;
|
|
12499
|
+
if (parsed.decision === "yes" && parsed.v) {
|
|
12500
|
+
const verify = verifyVisitorToken(parsed.v);
|
|
12501
|
+
if (verify.ok) {
|
|
12502
|
+
cookies.push(
|
|
12503
|
+
`${VISITOR_COOKIE_NAME}=${parsed.v}; Max-Age=${VISITOR_COOKIE_MAX_AGE_SECONDS}; Path=/; SameSite=Lax; Secure; HttpOnly`
|
|
12504
|
+
);
|
|
12505
|
+
tokenBound = true;
|
|
12506
|
+
console.log(`[token-bind] via=consent site=${site} person=${verify.personId}`);
|
|
12507
|
+
} else {
|
|
12508
|
+
console.error(`[token-bind] reject reason=${verify.reason} via=consent site=${site}`);
|
|
12509
|
+
}
|
|
12510
|
+
}
|
|
12511
|
+
for (const cookie of cookies) c.header("Set-Cookie", cookie, { append: true });
|
|
12512
|
+
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
12513
|
+
return c.body(null, 204);
|
|
12514
|
+
});
|
|
12515
|
+
app35.get("/brand-config", (c) => {
|
|
12516
|
+
const origin = getOrigin(c);
|
|
12517
|
+
setCorsHeaders(c, origin);
|
|
12518
|
+
const brand = readBrandConfig();
|
|
12519
|
+
const consent = brand?.consent ?? {};
|
|
12520
|
+
const copy = { ...DEFAULT_CONSENT_COPY, ...consent.copy ?? {} };
|
|
12521
|
+
const palette = { ...DEFAULT_CONSENT_PALETTE, ...consent.palette ?? {} };
|
|
12522
|
+
c.header("Cache-Control", "public, max-age=300");
|
|
12523
|
+
return c.json({ consent: { copy, palette } });
|
|
12524
|
+
});
|
|
12525
|
+
var visitor_consent_default = app35;
|
|
12526
|
+
|
|
12399
12527
|
// server/routes/listings.ts
|
|
12528
|
+
function getCookie(headerValue, name) {
|
|
12529
|
+
if (!headerValue) return null;
|
|
12530
|
+
for (const part of headerValue.split(";")) {
|
|
12531
|
+
const [k, ...rest] = part.trim().split("=");
|
|
12532
|
+
if (k === name) return rest.join("=");
|
|
12533
|
+
}
|
|
12534
|
+
return null;
|
|
12535
|
+
}
|
|
12536
|
+
function appendConsentParams(pageUrl, token) {
|
|
12537
|
+
try {
|
|
12538
|
+
const u = new URL(pageUrl);
|
|
12539
|
+
u.searchParams.set("consent", "needed");
|
|
12540
|
+
u.searchParams.set("v", token);
|
|
12541
|
+
return u.toString();
|
|
12542
|
+
} catch {
|
|
12543
|
+
const hashIdx = pageUrl.indexOf("#");
|
|
12544
|
+
const hash = hashIdx >= 0 ? pageUrl.slice(hashIdx) : "";
|
|
12545
|
+
const base = hashIdx >= 0 ? pageUrl.slice(0, hashIdx) : pageUrl;
|
|
12546
|
+
const sep4 = base.indexOf("?") >= 0 ? "&" : "?";
|
|
12547
|
+
return base + sep4 + `consent=needed&v=${encodeURIComponent(token)}` + hash;
|
|
12548
|
+
}
|
|
12549
|
+
}
|
|
12400
12550
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
12401
12551
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
12402
|
-
var
|
|
12403
|
-
|
|
12552
|
+
var app36 = new Hono();
|
|
12553
|
+
app36.get("/:slug/click", async (c) => {
|
|
12404
12554
|
const slug = c.req.param("slug") ?? "";
|
|
12405
12555
|
const rawSession = c.req.query("session") ?? "";
|
|
12406
12556
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -12441,45 +12591,33 @@ app35.get("/:slug/click", async (c) => {
|
|
|
12441
12591
|
console.error(`[property-card-click] reject reason=listing-not-found slug=${slug} sessionKey=${sessionKey} accountId=${account.accountId} status=404`);
|
|
12442
12592
|
return c.text("Not Found", 404);
|
|
12443
12593
|
}
|
|
12594
|
+
let redirectUrl = pageUrl;
|
|
12595
|
+
const consentCookie = getCookie(c.req.header("cookie"), CONSENT_COOKIE_NAME);
|
|
12596
|
+
const consented = consentCookie === "yes";
|
|
12444
12597
|
if (tokenParam) {
|
|
12445
12598
|
const verify = verifyVisitorToken(tokenParam);
|
|
12446
12599
|
if (verify.ok) {
|
|
12447
|
-
|
|
12448
|
-
|
|
12449
|
-
|
|
12450
|
-
|
|
12451
|
-
|
|
12600
|
+
if (consented) {
|
|
12601
|
+
c.header(
|
|
12602
|
+
"Set-Cookie",
|
|
12603
|
+
`${VISITOR_COOKIE_NAME}=${tokenParam}; Max-Age=${VISITOR_COOKIE_MAX_AGE_SECONDS}; Path=/; SameSite=Lax; Secure; HttpOnly`
|
|
12604
|
+
);
|
|
12605
|
+
console.log(`[token-bind] sessionKey=${sessionKey} person=${verify.personId} listingSlug=${slug}`);
|
|
12606
|
+
} else {
|
|
12607
|
+
redirectUrl = appendConsentParams(pageUrl, tokenParam);
|
|
12608
|
+
console.error(`[token-bind] reject reason=no-consent sessionKey=${sessionKey} person=${verify.personId} listingSlug=${slug}`);
|
|
12609
|
+
}
|
|
12452
12610
|
} else {
|
|
12453
12611
|
console.error(`[token-bind] reject reason=${verify.reason} sessionKey=${sessionKey} listingSlug=${slug}`);
|
|
12454
12612
|
}
|
|
12455
12613
|
}
|
|
12456
|
-
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
12457
|
-
return c.redirect(
|
|
12614
|
+
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
12615
|
+
return c.redirect(redirectUrl, 302);
|
|
12458
12616
|
});
|
|
12459
|
-
var listings_default =
|
|
12460
|
-
|
|
12461
|
-
// app/lib/brand-config.ts
|
|
12462
|
-
import { existsSync as existsSync22, readFileSync as readFileSync19 } from "fs";
|
|
12463
|
-
import { join as join14 } from "path";
|
|
12464
|
-
var cached2 = null;
|
|
12465
|
-
var cachedAttempted = false;
|
|
12466
|
-
function readBrandConfig() {
|
|
12467
|
-
if (cachedAttempted) return cached2;
|
|
12468
|
-
cachedAttempted = true;
|
|
12469
|
-
const platformRoot = process.env.MAXY_PLATFORM_ROOT;
|
|
12470
|
-
if (!platformRoot) return null;
|
|
12471
|
-
const brandPath = join14(platformRoot, "config", "brand.json");
|
|
12472
|
-
if (!existsSync22(brandPath)) return null;
|
|
12473
|
-
try {
|
|
12474
|
-
cached2 = JSON.parse(readFileSync19(brandPath, "utf-8"));
|
|
12475
|
-
return cached2;
|
|
12476
|
-
} catch {
|
|
12477
|
-
return null;
|
|
12478
|
-
}
|
|
12479
|
-
}
|
|
12617
|
+
var listings_default = app36;
|
|
12480
12618
|
|
|
12481
12619
|
// server/routes/visitor-event.ts
|
|
12482
|
-
var
|
|
12620
|
+
var app37 = new Hono();
|
|
12483
12621
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
12484
12622
|
var buckets = /* @__PURE__ */ new Map();
|
|
12485
12623
|
var RATE_LIMIT = 60;
|
|
@@ -12512,7 +12650,7 @@ function parseEvent(body) {
|
|
|
12512
12650
|
if (typeof e.ts !== "number" || !Number.isFinite(e.ts)) return null;
|
|
12513
12651
|
return e;
|
|
12514
12652
|
}
|
|
12515
|
-
function
|
|
12653
|
+
function getCookie2(c, name) {
|
|
12516
12654
|
const raw = c.req.header("cookie");
|
|
12517
12655
|
if (!raw) return null;
|
|
12518
12656
|
for (const part of raw.split(";")) {
|
|
@@ -12521,10 +12659,10 @@ function getCookie(c, name) {
|
|
|
12521
12659
|
}
|
|
12522
12660
|
return null;
|
|
12523
12661
|
}
|
|
12524
|
-
function
|
|
12662
|
+
function getOrigin2(c) {
|
|
12525
12663
|
return c.req.header("origin") ?? c.req.header("referer") ?? "";
|
|
12526
12664
|
}
|
|
12527
|
-
function
|
|
12665
|
+
function setCorsHeaders2(c, origin) {
|
|
12528
12666
|
if (origin) c.header("Access-Control-Allow-Origin", origin);
|
|
12529
12667
|
c.header("Access-Control-Allow-Credentials", "true");
|
|
12530
12668
|
c.header("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
@@ -12546,14 +12684,14 @@ function originAllowed(origin, allowlist) {
|
|
|
12546
12684
|
return false;
|
|
12547
12685
|
}
|
|
12548
12686
|
}
|
|
12549
|
-
|
|
12550
|
-
const origin =
|
|
12551
|
-
|
|
12687
|
+
app37.options("/event", (c) => {
|
|
12688
|
+
const origin = getOrigin2(c);
|
|
12689
|
+
setCorsHeaders2(c, origin);
|
|
12552
12690
|
return c.body(null, 204);
|
|
12553
12691
|
});
|
|
12554
|
-
|
|
12555
|
-
const origin =
|
|
12556
|
-
|
|
12692
|
+
app37.post("/event", async (c) => {
|
|
12693
|
+
const origin = getOrigin2(c);
|
|
12694
|
+
setCorsHeaders2(c, origin);
|
|
12557
12695
|
const ua = c.req.header("user-agent") ?? "";
|
|
12558
12696
|
if (BOT_UA_RE.test(ua)) {
|
|
12559
12697
|
console.error(`[v-event-error] reason=bot-ua ua=${JSON.stringify(ua.slice(0, 120))}`);
|
|
@@ -12576,6 +12714,11 @@ app36.post("/event", async (c) => {
|
|
|
12576
12714
|
console.error(`[v-event-error] reason=origin-mismatch origin=${JSON.stringify(origin)} ip=${ip}`);
|
|
12577
12715
|
return c.text("Forbidden", 403);
|
|
12578
12716
|
}
|
|
12717
|
+
const consentCookie = getCookie2(c, CONSENT_COOKIE_NAME);
|
|
12718
|
+
if (consentCookie !== "yes") {
|
|
12719
|
+
console.log(`[v-event] drop reason=no-consent consent=${consentCookie ?? "absent"} ip=${ip} origin=${JSON.stringify(origin)}`);
|
|
12720
|
+
return c.body(null, 204);
|
|
12721
|
+
}
|
|
12579
12722
|
let raw;
|
|
12580
12723
|
try {
|
|
12581
12724
|
raw = await c.req.json();
|
|
@@ -12588,7 +12731,7 @@ app36.post("/event", async (c) => {
|
|
|
12588
12731
|
console.error(`[v-event-error] reason=bad-event ip=${ip}`);
|
|
12589
12732
|
return c.text("Bad Request", 400);
|
|
12590
12733
|
}
|
|
12591
|
-
const cookieVal =
|
|
12734
|
+
const cookieVal = getCookie2(c, VISITOR_COOKIE_NAME);
|
|
12592
12735
|
let personId = null;
|
|
12593
12736
|
if (cookieVal) {
|
|
12594
12737
|
const v = verifyVisitorToken(cookieVal);
|
|
@@ -12618,7 +12761,7 @@ app36.post("/event", async (c) => {
|
|
|
12618
12761
|
});
|
|
12619
12762
|
}
|
|
12620
12763
|
console.log(
|
|
12621
|
-
`[visitor-event] type=${event.type} sessionId=${event.sid} visitorId=${event.vid} personId=${personId ?? "-"} path=${event.path ?? ""} label=${event.label ?? "-"} depth=${event.depth ?? "-"} ms=${event.ms ?? "-"}`
|
|
12764
|
+
`[visitor-event] type=${event.type} sessionId=${event.sid} visitorId=${event.vid} personId=${personId ?? "-"} consent=${consentCookie} path=${event.path ?? ""} label=${event.label ?? "-"} depth=${event.depth ?? "-"} ms=${event.ms ?? "-"}`
|
|
12622
12765
|
);
|
|
12623
12766
|
return c.body(null, 204);
|
|
12624
12767
|
});
|
|
@@ -12751,7 +12894,7 @@ async function writeEvent(opts) {
|
|
|
12751
12894
|
);
|
|
12752
12895
|
}
|
|
12753
12896
|
}
|
|
12754
|
-
var visitor_event_default =
|
|
12897
|
+
var visitor_event_default = app37;
|
|
12755
12898
|
|
|
12756
12899
|
// app/lib/graph-health.ts
|
|
12757
12900
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -13188,9 +13331,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
13188
13331
|
function isPublicHost(host) {
|
|
13189
13332
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
13190
13333
|
}
|
|
13191
|
-
var
|
|
13192
|
-
|
|
13193
|
-
|
|
13334
|
+
var app38 = new Hono();
|
|
13335
|
+
app38.use("*", clientIpMiddleware);
|
|
13336
|
+
app38.use("*", async (c, next) => {
|
|
13194
13337
|
await next();
|
|
13195
13338
|
c.header("X-Content-Type-Options", "nosniff");
|
|
13196
13339
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -13200,7 +13343,7 @@ app37.use("*", async (c, next) => {
|
|
|
13200
13343
|
);
|
|
13201
13344
|
});
|
|
13202
13345
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
13203
|
-
|
|
13346
|
+
app38.use("*", async (c, next) => {
|
|
13204
13347
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
13205
13348
|
await next();
|
|
13206
13349
|
return;
|
|
@@ -13233,7 +13376,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
13233
13376
|
"/sites/"
|
|
13234
13377
|
];
|
|
13235
13378
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
13236
|
-
|
|
13379
|
+
app38.use("*", async (c, next) => {
|
|
13237
13380
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13238
13381
|
if (!isPublicHost(host)) {
|
|
13239
13382
|
await next();
|
|
@@ -13273,7 +13416,7 @@ function resolveRemoteAuthOpts() {
|
|
|
13273
13416
|
return brandLoginOpts;
|
|
13274
13417
|
}
|
|
13275
13418
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
13276
|
-
|
|
13419
|
+
app38.post("/__remote-auth/login", async (c) => {
|
|
13277
13420
|
const client = clientFrom(c);
|
|
13278
13421
|
const clientIp = client.ip || "unknown";
|
|
13279
13422
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -13318,7 +13461,7 @@ app37.post("/__remote-auth/login", async (c) => {
|
|
|
13318
13461
|
}
|
|
13319
13462
|
});
|
|
13320
13463
|
});
|
|
13321
|
-
|
|
13464
|
+
app38.get("/__remote-auth/logout", (c) => {
|
|
13322
13465
|
const client = clientFrom(c);
|
|
13323
13466
|
const clientIp = client.ip || "unknown";
|
|
13324
13467
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -13331,7 +13474,7 @@ app37.get("/__remote-auth/logout", (c) => {
|
|
|
13331
13474
|
}
|
|
13332
13475
|
});
|
|
13333
13476
|
});
|
|
13334
|
-
|
|
13477
|
+
app38.post("/__remote-auth/change-password", async (c) => {
|
|
13335
13478
|
const client = clientFrom(c);
|
|
13336
13479
|
const clientIp = client.ip || "unknown";
|
|
13337
13480
|
const rateLimited = checkRateLimit(client);
|
|
@@ -13382,13 +13525,13 @@ app37.post("/__remote-auth/change-password", async (c) => {
|
|
|
13382
13525
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
13383
13526
|
}
|
|
13384
13527
|
});
|
|
13385
|
-
|
|
13528
|
+
app38.get("/__remote-auth/setup", (c) => {
|
|
13386
13529
|
if (isRemoteAuthConfigured()) {
|
|
13387
13530
|
return c.redirect("/");
|
|
13388
13531
|
}
|
|
13389
13532
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
13390
13533
|
});
|
|
13391
|
-
|
|
13534
|
+
app38.post("/__remote-auth/set-initial-password", async (c) => {
|
|
13392
13535
|
if (isRemoteAuthConfigured()) {
|
|
13393
13536
|
return c.redirect("/");
|
|
13394
13537
|
}
|
|
@@ -13426,10 +13569,10 @@ app37.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
13426
13569
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
13427
13570
|
}
|
|
13428
13571
|
});
|
|
13429
|
-
|
|
13572
|
+
app38.get("/api/remote-auth/status", (c) => {
|
|
13430
13573
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
13431
13574
|
});
|
|
13432
|
-
|
|
13575
|
+
app38.post("/api/remote-auth/set-password", async (c) => {
|
|
13433
13576
|
let body;
|
|
13434
13577
|
try {
|
|
13435
13578
|
body = await c.req.json();
|
|
@@ -13460,9 +13603,9 @@ app37.post("/api/remote-auth/set-password", async (c) => {
|
|
|
13460
13603
|
return c.json({ error: "Failed to save password" }, 500);
|
|
13461
13604
|
}
|
|
13462
13605
|
});
|
|
13463
|
-
|
|
13606
|
+
app38.route("/api/_client-error", client_error_default);
|
|
13464
13607
|
console.log("[client-error-route] mounted");
|
|
13465
|
-
|
|
13608
|
+
app38.use("*", async (c, next) => {
|
|
13466
13609
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13467
13610
|
const path2 = c.req.path;
|
|
13468
13611
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -13495,11 +13638,11 @@ app37.use("*", async (c, next) => {
|
|
|
13495
13638
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
13496
13639
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
13497
13640
|
});
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13641
|
+
app38.route("/api/health", health_default);
|
|
13642
|
+
app38.route("/api/chat", chat_default);
|
|
13643
|
+
app38.route("/api/whatsapp", whatsapp_default);
|
|
13644
|
+
app38.route("/api/onboarding", onboarding_default);
|
|
13645
|
+
app38.route("/api/admin", admin_default);
|
|
13503
13646
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
13504
13647
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
13505
13648
|
var IMAGE_MIME = {
|
|
@@ -13511,7 +13654,7 @@ var IMAGE_MIME = {
|
|
|
13511
13654
|
".svg": "image/svg+xml",
|
|
13512
13655
|
".ico": "image/x-icon"
|
|
13513
13656
|
};
|
|
13514
|
-
|
|
13657
|
+
app38.get("/agent-assets/:slug/:filename", (c) => {
|
|
13515
13658
|
const slug = c.req.param("slug");
|
|
13516
13659
|
const filename = c.req.param("filename");
|
|
13517
13660
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -13546,7 +13689,7 @@ app37.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13546
13689
|
"Cache-Control": "public, max-age=3600"
|
|
13547
13690
|
});
|
|
13548
13691
|
});
|
|
13549
|
-
|
|
13692
|
+
app38.get("/generated/:filename", (c) => {
|
|
13550
13693
|
const filename = c.req.param("filename");
|
|
13551
13694
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
13552
13695
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -13576,9 +13719,10 @@ app37.get("/generated/:filename", (c) => {
|
|
|
13576
13719
|
"Cache-Control": "public, max-age=86400"
|
|
13577
13720
|
});
|
|
13578
13721
|
});
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13722
|
+
app38.route("/sites", sites_default);
|
|
13723
|
+
app38.route("/listings", listings_default);
|
|
13724
|
+
app38.route("/v", visitor_event_default);
|
|
13725
|
+
app38.route("/v", visitor_consent_default);
|
|
13582
13726
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
13583
13727
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
13584
13728
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -13715,7 +13859,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
13715
13859
|
function escapeHtml(s) {
|
|
13716
13860
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
13717
13861
|
}
|
|
13718
|
-
|
|
13862
|
+
app38.get("/", (c) => {
|
|
13719
13863
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13720
13864
|
if (isPublicHost(host)) {
|
|
13721
13865
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -13723,12 +13867,12 @@ app37.get("/", (c) => {
|
|
|
13723
13867
|
}
|
|
13724
13868
|
return c.html(cachedHtml("index.html"));
|
|
13725
13869
|
});
|
|
13726
|
-
|
|
13870
|
+
app38.get("/public", (c) => {
|
|
13727
13871
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13728
13872
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13729
13873
|
return c.html(cachedHtml("public.html"));
|
|
13730
13874
|
});
|
|
13731
|
-
|
|
13875
|
+
app38.get("/chat", (c) => {
|
|
13732
13876
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13733
13877
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13734
13878
|
return c.html(cachedHtml("public.html"));
|
|
@@ -13747,9 +13891,9 @@ async function logViewerFetch(c, next) {
|
|
|
13747
13891
|
duration_ms: Date.now() - start
|
|
13748
13892
|
});
|
|
13749
13893
|
}
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
|
|
13894
|
+
app38.use("/vnc-viewer.html", logViewerFetch);
|
|
13895
|
+
app38.use("/vnc-popout.html", logViewerFetch);
|
|
13896
|
+
app38.get("/vnc-popout.html", (c) => {
|
|
13753
13897
|
let html = htmlCache.get("vnc-popout.html");
|
|
13754
13898
|
if (!html) {
|
|
13755
13899
|
html = readFileSync21(resolve21(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -13762,7 +13906,7 @@ app37.get("/vnc-popout.html", (c) => {
|
|
|
13762
13906
|
}
|
|
13763
13907
|
return c.html(html);
|
|
13764
13908
|
});
|
|
13765
|
-
|
|
13909
|
+
app38.post("/api/vnc/client-event", async (c) => {
|
|
13766
13910
|
let body;
|
|
13767
13911
|
try {
|
|
13768
13912
|
body = await c.req.json();
|
|
@@ -13783,25 +13927,25 @@ app37.post("/api/vnc/client-event", async (c) => {
|
|
|
13783
13927
|
});
|
|
13784
13928
|
return c.json({ ok: true });
|
|
13785
13929
|
});
|
|
13786
|
-
|
|
13930
|
+
app38.get("/g/:slug", (c) => {
|
|
13787
13931
|
return c.html(brandedPublicHtml());
|
|
13788
13932
|
});
|
|
13789
|
-
|
|
13933
|
+
app38.get("/graph", (c) => {
|
|
13790
13934
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13791
13935
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13792
13936
|
return c.html(cachedHtml("graph.html"));
|
|
13793
13937
|
});
|
|
13794
|
-
|
|
13938
|
+
app38.get("/sessions", (c) => {
|
|
13795
13939
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13796
13940
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13797
13941
|
return c.html(cachedHtml("sessions.html"));
|
|
13798
13942
|
});
|
|
13799
|
-
|
|
13943
|
+
app38.get("/data", (c) => {
|
|
13800
13944
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13801
13945
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13802
13946
|
return c.html(cachedHtml("data.html"));
|
|
13803
13947
|
});
|
|
13804
|
-
|
|
13948
|
+
app38.get("/:slug", async (c, next) => {
|
|
13805
13949
|
const slug = c.req.param("slug");
|
|
13806
13950
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
13807
13951
|
const branding = loadBrandingCache(slug);
|
|
@@ -13811,15 +13955,15 @@ app37.get("/:slug", async (c, next) => {
|
|
|
13811
13955
|
await next();
|
|
13812
13956
|
});
|
|
13813
13957
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
13814
|
-
|
|
13958
|
+
app38.get("/favicon.ico", (c) => {
|
|
13815
13959
|
c.header("Cache-Control", "public, max-age=300");
|
|
13816
13960
|
return c.redirect(brandFaviconPath, 302);
|
|
13817
13961
|
});
|
|
13818
13962
|
}
|
|
13819
|
-
|
|
13963
|
+
app38.use("/*", serveStatic({ root: "./public" }));
|
|
13820
13964
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
13821
13965
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
13822
|
-
var httpServer = serve({ fetch:
|
|
13966
|
+
var httpServer = serve({ fetch: app38.fetch, port, hostname });
|
|
13823
13967
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
13824
13968
|
{
|
|
13825
13969
|
const loopHist = monitorEventLoopDelay({ resolution: 50 });
|
|
@@ -13845,7 +13989,8 @@ var SUBAPP_MANIFEST = [
|
|
|
13845
13989
|
{ prefix: "/api/admin", file: "server/routes/admin/index.ts", subapp: admin_default },
|
|
13846
13990
|
{ prefix: "/api/_client-error", file: "server/routes/client-error.ts", subapp: client_error_default },
|
|
13847
13991
|
{ prefix: "/listings", file: "server/routes/listings.ts", subapp: listings_default },
|
|
13848
|
-
{ prefix: "/v", file: "server/routes/visitor-event.ts", subapp: visitor_event_default }
|
|
13992
|
+
{ prefix: "/v", file: "server/routes/visitor-event.ts", subapp: visitor_event_default },
|
|
13993
|
+
{ prefix: "/v", file: "server/routes/visitor-consent.ts", subapp: visitor_consent_default }
|
|
13849
13994
|
];
|
|
13850
13995
|
for (const m of SUBAPP_MANIFEST) {
|
|
13851
13996
|
const routeCount = Array.isArray(m.subapp.routes) ? m.subapp.routes.length : 0;
|
|
@@ -13853,7 +13998,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
13853
13998
|
}
|
|
13854
13999
|
try {
|
|
13855
14000
|
const registered = [];
|
|
13856
|
-
for (const r of
|
|
14001
|
+
for (const r of app38.routes ?? []) {
|
|
13857
14002
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
13858
14003
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
13859
14004
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|