chainlesschain 0.162.150 → 0.162.151
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/README.md +1 -1
- package/package.json +3 -2
- package/src/assets/web-panel/assets/{AIOps-CBLvrjeG.js → AIOps-DuEOzebi.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DYv2GtE0.js → ActionButton-C6GiJa5H.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CL6PZ-Ww.js → Analytics-BBIiL_pO.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-xuyHt4uA.js → AppLayout-CuI2gZRy.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-DOvSVycq.js → Audit-CbUjfr-K.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DMhfTswr.js → Backup-CsSW9ljf.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CQxDdm63.js → BaseInput-kM3rLe7F.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BEeNhK2a.js → Chat-kfE51YN3.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-8nul8eTq.js → ChatBubbleRenderer-Bg2FTW6A.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CL04O-ER.js → Checkbox-jYb1uj-M.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-C50o-n7x.js → Codegen-X9XiD5Lj.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CH-bDkzs.js → Col-BfbHu1xI.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DqAIMvSe.js → Community-c4oJMFS-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-C43fo_my.js → Compact-BFmnZpH7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BERnMrdP.js → Compliance-s9shVHBS.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Baw3w1gp.js → Cowork-C5da--TC.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-BEqAHF1-.js → Cron-9kNbyNE4.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CvnmKwK4.js → Crosschain-C1k3NJD4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-iMPxgVdt.js → DID-DkheEvNK.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard--4SJX3YR.js → Dashboard-C3FuSGmJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BgLV6xgz.js → Dropdown-CAV6FMFD.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Bvb8oUD8.js → EmailListRenderer-Cc-Ulc4l.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DpXPjJB5.js → FamilyGuardDashboard-8CitHEtv.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BbFfJ1Xi.js → Federation-DFSZ5KDt.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DeGq1B-q.js → FormItemContext-CEWCtnG2.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CNW7s9zM.js → GenericCardRenderer-CwRzNzmX.js} +1 -1
- package/src/assets/web-panel/assets/{Git-L1PjW-lT.js → Git-0rgDM7cJ.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-PK-X58to.js → Governance-CfBKtK9F.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BePWEH-d.js → Inference-CzcUVvud.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-LF_sBvdL.js → KnowledgeGraph-Dwc4YL4A.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BKkfk9hy.js → Logs-DgFPwR2F.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-BNMqUDla.js → Marketplace-DnpPTbGU.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-w4WPiyz2.js → McpTools-DRxxINyW.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-DUKMVGNi.js → Memory-OhmW_6Z3.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BWhiEyTJ.js → MobileBridge-DkTW-RK5.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Ocf5JEkX.js → MobileProjects-DpCGV_lI.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-D2B6MMhU.js → Mtc--vmkL0AS.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-DdYjCq1O.js → MtcAudit-DGoFWjD4.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-Cb1hfuUZ.js → Multisig-B4kWgq95.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CTeImGp7.js → NLProgramming-YQwvommE.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BjYNc7eQ.js → Notes-CgjtUADJ.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-Dn_NtRXQ.js → NotificationSettings-6JDrpBG5.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DVYYIizh.js → OrderTableRenderer-PM6IlxjO.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Be2Kmr5j.js → Organization-8McOT_OF.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Cu_-qRlR.js → Overflow-DAZpSCGc.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DD2HoGzE.js → P2P-B7l2ZWLy.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BRI7DVth.js → PdhVaultBrowser-W1Ud-NAL.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-C9Srcs2M.js → Permissions-Czm_w9u_.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CUqcMgo1.js → PersonalDataHub-B4F0_ZVM.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-HBrQGLXt.js → Pipeline-B37aFiWv.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-D-B0vjwh.js → Privacy-94KBnRrD.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-eTeLIu9e.js → ProjectInit-B5h8_dlh.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DrRqCsC6.js → ProjectSettings-lmeI3Lpm.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-1G9DNOhI.js → Projects-D5AYOasl.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-RkTZzpxP.js → Providers-B3cNWwJg.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BSCUgsgC.js → QrScannerModal-CHRvOw1R.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CHgyM3Bz.js → QuickAsk-D1JMgFEd.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-0lry4OZq.js → Recommend-EYWGR79p.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Cn45UroZ.js → RemoteSession-BAMC2pJt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Q-Zjb707.js → Reputation-X2Hk1XG_.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BdM70oda.js → Row-Eq98LRtU.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DmOAKKap.js → RssFeed-i76s6z_o.js} +2 -2
- package/src/assets/web-panel/assets/{Search-Dwavbm07.js → Search-D_Es7CAI.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DukXFCnk.js → Security-kayD2e94.js} +3 -3
- package/src/assets/web-panel/assets/{Services-BIlRnITu.js → Services-Ctsm6ul8.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-YYVQdhhQ.js → Skeleton-CRNYlfdf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-B8_iYHz2.js → Skills-DkZYpF4-.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BdVrhT31.js → Sla-DXkoBcOP.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CD3ggRx7.js → SpeechSettings-DXi_GI1d.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Bp02VZFH.js → SyncSettings-rNKpfomn.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DEVmCEsr.js → Tasks-XF4uPtG-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-B6czWc4N.js → Templates-i0Hzfeyu.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BCJLv17r.js → Tenant-sMpHAi27.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-ZB-CvkZl.js → TimelineRenderer-yuC6K7Rf.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BnSY0S-s.js → Tokens-B8O8i0s6.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-VZw9Oy2w.js → Trigger-Bv6yrlCr.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-pZq7Hjd2.js → Trust-C4mW95Ev.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DnQaqk4q.js → UkeySign-DV6yKaHn.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BEUfmvJV.js → VideoEditing-UI479-sD.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CoZKMXJ2.js → Wallet-M5oV9EVP.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CBOGVx1I.js → WebAuthn-DDyDHPDR.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-huSKn7TT.js → WorkflowEditor-RoBv4rqk.js} +1 -1
- package/src/assets/web-panel/assets/{chat-A_3w6FBO.js → chat-Cw1mE5LS.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D1Bem9Oy.js → colors-BFP62Gwf.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CJYJj0oO.js → compact-item-17HL6pyC.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BkbFiKT4.js → createContext-D55X4fZX.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CKvUafVY.js → hasIn-D3E5mNsP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVS8Ymuq.js → index--44J50mc.js} +1 -1
- package/src/assets/web-panel/assets/{index-qNTtOVi_.js → index-ASPYTzMK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpW9cf3e.js → index-BC6zxOlU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSgWxAOG.js → index-BEa1RW4c.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjYrecNb.js → index-BQmZg5si.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8i0lViZ.js → index-BY_xZ2jy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfgCdFrN.js → index-BgN5G5vF.js} +3 -3
- package/src/assets/web-panel/assets/{index-ChkXUj3f.js → index-BnGpft-Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHdHSX06.js → index-Bq83UBDr.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9bWmTcO.js → index-Bzpp2z2S.js} +1 -1
- package/src/assets/web-panel/assets/{index-ttDQVhZy.js → index-CFYGn88j.js} +1 -1
- package/src/assets/web-panel/assets/{index-C37f6iey.js → index-CGyTos4p.js} +1 -1
- package/src/assets/web-panel/assets/index-CKBI1U5K.js +1 -0
- package/src/assets/web-panel/assets/{index-By5a0T_W.js → index-CLEzsZ8A.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBlBVJ_m.js → index-CR9rNUvi.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiDWxzbn.js → index-CW6LLoJO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cj0OZ-37.js → index-C_MfcrLf.js} +1 -1
- package/src/assets/web-panel/assets/{index-JEAGMii9.js → index-Cdvk2_2q.js} +1 -1
- package/src/assets/web-panel/assets/{index-F--HuPG1.js → index-CjCwi7we.js} +1 -1
- package/src/assets/web-panel/assets/index-CkLp6DTO.js +1 -0
- package/src/assets/web-panel/assets/{index-CUj-l7GM.js → index-CvCFKojj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Crp8CbRg.js → index-D4LHSde4.js} +1 -1
- package/src/assets/web-panel/assets/{index-Co3OFL0t.js → index-DCLu84x-.js} +1 -1
- package/src/assets/web-panel/assets/{index-tgO8iza6.js → index-DD_qGBrt.js} +1 -1
- package/src/assets/web-panel/assets/{index-Fuk6t_3K.js → index-DIRvdwBX.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9Svn0zc.js → index-DOjA8bvj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOoAQjJz.js → index-Da27u6j0.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBaosWRO.js → index-DkBVYlE4.js} +1 -1
- package/src/assets/web-panel/assets/{index-D22zNXiS.js → index-DtAnPBWP.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-WIY-FQ.js → index-DzG7mkgW.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJwlEnYo.js → index-H9_X1Cg_.js} +1 -1
- package/src/assets/web-panel/assets/{index-pyvMVX8r.js → index-ITeEHb8L.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHdailyo.js → index-KtLJXn4s.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdutMsne.js → index-RYZgFIwo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTs_D1OL.js → index-gAVxDiTZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-b-sbVdjQ.js → index-paVubXzn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CD62EEGo.js → index-tUH_6bdJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-PF-mpv8K.js → index-tVRPgYGr.js} +1 -1
- package/src/assets/web-panel/assets/{index-AjrSPnvv.js → index-uSsiwgZ2.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DtrnfsZH.js → initDefaultProps-Ckp7xVZS.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D4zqSaX3.js → motion-DUZgCpn6.js} +1 -1
- package/src/assets/web-panel/assets/{move-CGFGOUQj.js → move-B2rttglH.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DH2HvkJl.js → mtc-parser-BYWcLTuN.js} +1 -1
- package/src/assets/web-panel/assets/{omit-jJ2at5HX.js → omit-DhHqKeFx.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CRyMT1Fv.js → pickAttrs-ANpJaWMO.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DZ_CX0Pt.js → placementArrow-CfZWe7CA.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-wruHk-h5.js → responsiveObserve-D7Xz2y-R.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BGgx8q67.js → slide-DekqCBY9.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Do5M7gKm.js → statusUtils-BET6XU7h.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CRa-GZpX.js → styleChecker-qHmJjV62.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BxPcq6pj.js → useFlexGapSupport-BoMCTNyu.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-v5O2ZcJm.js → useFs-TdW-NgFC.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub--z2FU0Px.js → usePersonalDataHub-Dyox7wCu.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-1emidVKd.js → vnode-XUn5S8CP.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CcJaRyHs.js → zoom-Ls77i8hn.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-manifest.json +8 -1
- package/src/commands/changelog.js +148 -0
- package/src/data/changelog.json +189 -0
- package/src/gateways/ws/remote-session-protocol.js +9 -2
- package/src/index.js +2 -0
- package/src/lib/changelog.js +252 -0
- package/src/lib/lsp/lsp-server-registry.js +15 -4
- package/src/lib/plugin-runtime/hooks.js +20 -4
- package/src/lib/plugin-runtime/monitors.js +20 -4
- package/src/lib/plugin-runtime/signature.js +16 -0
- package/src/lib/sandbox-egress-proxy.js +38 -2
- package/src/lib/sandbox-network-policy.js +26 -4
- package/src/lib/telemetry/span-recorder.js +12 -1
- package/src/assets/web-panel/assets/Terminal-CD132d2Y.js +0 -3
- package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +0 -1
- package/src/assets/web-panel/assets/index-Dwix3p4g.js +0 -1
- package/src/assets/web-panel/assets/index-SHaoZ0CA.js +0 -1
|
@@ -77,6 +77,22 @@ export function verifyInstalledSignature(plugin, opts = {}) {
|
|
|
77
77
|
return { signed: false, reason: "lock is not signature-verified" };
|
|
78
78
|
}
|
|
79
79
|
const manifestFile = path.join(plugin.root, lock.manifest || "plugin.json");
|
|
80
|
+
// `lock.manifest` is untrusted — it lives in the (writable) plugin dir. A lock
|
|
81
|
+
// pointing OUTSIDE the plugin root (`manifest: "../../secret"`) would make us
|
|
82
|
+
// re-hash an arbitrary file and, with a matching locked sha256, forge
|
|
83
|
+
// signed:true — which gates load-time requireSignedPlugins. A plugin's manifest
|
|
84
|
+
// is ALWAYS inside its own root, so reject any path that escapes it (boundary
|
|
85
|
+
// via path.relative, not startsWith — the sandbox-fs-policy pattern).
|
|
86
|
+
const rel = path.relative(
|
|
87
|
+
path.resolve(plugin.root),
|
|
88
|
+
path.resolve(manifestFile),
|
|
89
|
+
);
|
|
90
|
+
if (!rel || rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
91
|
+
return {
|
|
92
|
+
signed: false,
|
|
93
|
+
reason: "lock manifest path escapes the plugin root",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
80
96
|
if (!_deps.existsSync(manifestFile)) {
|
|
81
97
|
return { signed: false, reason: "locked manifest file is missing" };
|
|
82
98
|
}
|
|
@@ -72,6 +72,42 @@ async function guardResolvedTarget(host, policy, lookup) {
|
|
|
72
72
|
return { ok: true, ip: typeof first === "string" ? first : first.address };
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Parse a CONNECT request target ("host:port") into `{ host, port }`. A naive
|
|
77
|
+
* `split(":")` mangles IPv6 literals — `[2001:db8::1]:8443` would yield host
|
|
78
|
+
* `"[2001"` and a NaN port that silently defaults to 443, so even an IP-pinned
|
|
79
|
+
* tunnel connects to the WRONG port (and, when unpinned, the wrong host). Handle
|
|
80
|
+
* the bracketed-IPv6, bare-IPv6, and `name[:port]` forms explicitly. Port
|
|
81
|
+
* defaults to 443 (the CONNECT/HTTPS default).
|
|
82
|
+
*/
|
|
83
|
+
export function parseConnectTarget(target) {
|
|
84
|
+
const s = String(target == null ? "" : target).trim();
|
|
85
|
+
const toPort = (v) => {
|
|
86
|
+
const n = parseInt(v, 10);
|
|
87
|
+
return Number.isInteger(n) && n > 0 && n <= 65535 ? n : 443;
|
|
88
|
+
};
|
|
89
|
+
// Bracketed IPv6: "[::1]" or "[::1]:8443"
|
|
90
|
+
if (s.startsWith("[")) {
|
|
91
|
+
const end = s.indexOf("]");
|
|
92
|
+
if (end > 0) {
|
|
93
|
+
const host = s.slice(1, end);
|
|
94
|
+
const rest = s.slice(end + 1); // "" or ":8443"
|
|
95
|
+
return { host, port: rest.startsWith(":") ? toPort(rest.slice(1)) : 443 };
|
|
96
|
+
}
|
|
97
|
+
// malformed bracket — fall through to the generic handling
|
|
98
|
+
}
|
|
99
|
+
// Bare IPv6 literal (2+ colons, no brackets) → no port component to split off.
|
|
100
|
+
if ((s.match(/:/g) || []).length > 1) {
|
|
101
|
+
return { host: s, port: 443 };
|
|
102
|
+
}
|
|
103
|
+
// "name:port" (rsplit on the single colon) or bare "name".
|
|
104
|
+
const idx = s.lastIndexOf(":");
|
|
105
|
+
if (idx > 0) {
|
|
106
|
+
return { host: s.slice(0, idx), port: toPort(s.slice(idx + 1)) };
|
|
107
|
+
}
|
|
108
|
+
return { host: s, port: 443 };
|
|
109
|
+
}
|
|
110
|
+
|
|
75
111
|
/**
|
|
76
112
|
* Build the proxy env vars a child process needs to route through the proxy.
|
|
77
113
|
* `NO_PROXY` is intentionally empty so nothing bypasses the filter.
|
|
@@ -204,8 +240,8 @@ export function createEgressProxy(policy = {}, opts = {}) {
|
|
|
204
240
|
clientSocket.end();
|
|
205
241
|
return;
|
|
206
242
|
}
|
|
207
|
-
|
|
208
|
-
const port =
|
|
243
|
+
// Parse host:port properly (IPv6 literals break a naive split).
|
|
244
|
+
const { host, port } = parseConnectTarget(req.url);
|
|
209
245
|
// Connect to the pinned validated IP so a rebind at connect time can't
|
|
210
246
|
// swap in a private address between our check and the socket.
|
|
211
247
|
const upstream = net.connect(port, ip || host, () => {
|
|
@@ -60,6 +60,24 @@ function anyMatch(host, patterns) {
|
|
|
60
60
|
return (patterns || []).some((p) => matchesDomain(host, p));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* If `h` is an IPv4-mapped IPv6 address, return the embedded IPv4 in dotted
|
|
65
|
+
* form; else null. Handles both the dotted tail ("::ffff:127.0.0.1", how a user
|
|
66
|
+
* might type it) and the compressed-hex tail ("::ffff:7f00:1", how Node's URL
|
|
67
|
+
* parser serializes it). The hex tail is two 16-bit groups = the 32-bit IPv4.
|
|
68
|
+
*/
|
|
69
|
+
function mappedIpv4Tail(h) {
|
|
70
|
+
const dotted = h.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i);
|
|
71
|
+
if (dotted) return dotted[1];
|
|
72
|
+
const hex = h.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
|
|
73
|
+
if (hex) {
|
|
74
|
+
const high = parseInt(hex[1], 16);
|
|
75
|
+
const low = parseInt(hex[2], 16);
|
|
76
|
+
return `${(high >> 8) & 0xff}.${high & 0xff}.${(low >> 8) & 0xff}.${low & 0xff}`;
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
63
81
|
/** Private / loopback / link-local / cloud-metadata target? (SSRF guard) */
|
|
64
82
|
export function isPrivateHost(host) {
|
|
65
83
|
if (!host) return false;
|
|
@@ -70,10 +88,14 @@ export function isPrivateHost(host) {
|
|
|
70
88
|
// IPv6 loopback / unique-local / link-local.
|
|
71
89
|
if (h === "::1" || h === "::") return true;
|
|
72
90
|
if (/^f[cd][0-9a-f]{2}:/i.test(h)) return true; // fc00::/7 unique-local
|
|
73
|
-
if (/^
|
|
74
|
-
// IPv4-mapped IPv6
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
if (/^fe[89ab][0-9a-f]:/i.test(h)) return true; // fe80::/10 link-local (fe80–febf)
|
|
92
|
+
// IPv4-mapped IPv6 — check the embedded IPv4 tail. Node's WHATWG URL parser
|
|
93
|
+
// serializes "[::ffff:127.0.0.1]" as COMPRESSED HEX ("::ffff:7f00:1"), never
|
|
94
|
+
// dotted-decimal, so we must decode BOTH forms or the guard is dead code for
|
|
95
|
+
// any URL/bracketed input (loopback, private ranges, AND 169.254.169.254 all
|
|
96
|
+
// sail through — confirmed SSRF bypass). Bare non-URL hosts may still arrive
|
|
97
|
+
// dotted, so keep that form too.
|
|
98
|
+
const ipv4 = mappedIpv4Tail(h) || h;
|
|
77
99
|
const m = ipv4.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
78
100
|
if (m) {
|
|
79
101
|
const [a, b] = [Number(m[1]), Number(m[2])];
|
|
@@ -20,6 +20,16 @@ function spanId() {
|
|
|
20
20
|
return _seq.toString(16).padStart(16, "0");
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// One trace per recorder (a "run"). The OTLP/OTel spec treats an ALL-ZERO
|
|
24
|
+
// traceId as INVALID, so a strict collector would drop every span exported with
|
|
25
|
+
// `"0".repeat(32)` — defeating toOtlp()'s purpose. Derive a non-zero, monotonic
|
|
26
|
+
// (RNG-free, snapshot-replayable) 32-hex traceId per recorder instead.
|
|
27
|
+
let _traceSeq = 0;
|
|
28
|
+
function newTraceId() {
|
|
29
|
+
_traceSeq = (_traceSeq + 1) % Number.MAX_SAFE_INTEGER;
|
|
30
|
+
return _traceSeq.toString(16).padStart(32, "0"); // never all-zero (starts at 1)
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
export class TelemetryRecorder {
|
|
24
34
|
constructor({
|
|
25
35
|
now = () => Date.now(),
|
|
@@ -27,6 +37,7 @@ export class TelemetryRecorder {
|
|
|
27
37
|
} = {}) {
|
|
28
38
|
this._now = typeof now === "function" ? now : () => now;
|
|
29
39
|
this.serviceName = serviceName;
|
|
40
|
+
this.traceId = newTraceId(); // one trace per recorder (valid non-zero id)
|
|
30
41
|
this._spans = []; // completed spans
|
|
31
42
|
this._counters = new Map(); // name → { total, byAttr }
|
|
32
43
|
this._failures = new Map(); // category → count
|
|
@@ -171,7 +182,7 @@ export class TelemetryRecorder {
|
|
|
171
182
|
{
|
|
172
183
|
scope: { name: "chainlesschain.cli" },
|
|
173
184
|
spans: this._spans.map((s) => ({
|
|
174
|
-
traceId:
|
|
185
|
+
traceId: this.traceId,
|
|
175
186
|
spanId: s.id,
|
|
176
187
|
parentSpanId: s.parentId || "",
|
|
177
188
|
name: s.name,
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{u as fe,_ as me,d as B,e as U}from"./index-DfgCdFrN.js";import{I as z,J as x,U as _,Q as D,S as K,K as T,V as R,c as A,F as Q,Z,R as E,o as G,f as H,w as $,n as V,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-BMxUs6UX.js";import{R as ye,b as pe,as as ge}from"./icons-BsDmGpcT.js";const k=new Map,C=new Map,N=new Set,F=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),N.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),F.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(L=>({seq:L.seq,data:ae(L.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(N.add(a),()=>N.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(F.add(a),()=>F.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function L(t){return t?t.slice(0,8):""}let O=null,M=null;async function I(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await U(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await U(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await U(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function q(t){await V();const{xtermMod:l,fitAddonMod:p}=await I(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?B.warning("该命令被桌面端拦截(高危关键字)"):B.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
|
|
3
|
-
\x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const J of v)m.write(J.data),t.lastSeq=J.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const j=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});j.observe(b);const ue=t.offs;t.offs=()=>{try{j.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await q(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,V(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function X(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await q(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}G(async()=>{await X()}),H(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{V(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const Y={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:I,mountXterm:q,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:G,onBeforeUnmount:H,nextTick:V,watch:$,get message(){return B},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(Y,"__isScriptSetup",{enumerable:!1,value:!0}),Y}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={key:1,class:"terminal-footer"},Ve={key:0,class:"footer-exit"};function qe(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=D(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Z(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Z(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",Ve,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",qe],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-1VVfY7/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-DfgCdFrN.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-BdM70oda.js";import{a0 as t}from"./index-DfgCdFrN.js";import"./vendor-BMxUs6UX.js";import"./responsiveObserve-wruHk-h5.js";import"./useFlexGapSupport-BxPcq6pj.js";import"./styleChecker-CRa-GZpX.js";import"./index-Cj0OZ-37.js";import"./icons-BsDmGpcT.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-CH-bDkzs.js";import{a0 as t}from"./index-DfgCdFrN.js";import"./vendor-BMxUs6UX.js";import"./index-Cj0OZ-37.js";import"./icons-BsDmGpcT.js";const s=t(o);export{s as default};
|