cicy-desktop 2.1.360 → 2.1.361

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.360",
3
+ "version": "2.1.361",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -385,9 +385,23 @@ class PanelCells {
385
385
  }
386
386
  }
387
387
 
388
+ // 面板页里的 <webview partition="persist:sandbox-N"> 用的是同一批 partition,但它不走
389
+ // PanelCells,没人给它设代理 —— 不设就是直连,账号的真实出口 IP 直接暴露。
390
+ // 面板一打开就把所有 electron profile 的 partition 代理都绑上,webview 和 BrowserView
391
+ // 两种格子都覆盖到。ensureCellSessionProxy 自带去重,重复调用无副作用。
392
+ function ensureAllProfileProxies() {
393
+ try {
394
+ const profileStore = require("../profiles/profile-store");
395
+ for (const p of profileStore.listProfiles("electron") || []) {
396
+ const idx = Number(p && p.accountIdx);
397
+ if (Number.isInteger(idx) && idx > 0) ensureCellSessionProxy(idx);
398
+ }
399
+ } catch (e) {}
400
+ }
401
+
388
402
  function cellsForTab(manager, tab) {
389
403
  let pc = registry.get(tab.id);
390
- if (!pc) { pc = new PanelCells(manager, tab); registry.set(tab.id, pc); }
404
+ if (!pc) { pc = new PanelCells(manager, tab); registry.set(tab.id, pc); ensureAllProfileProxies(); }
391
405
  return pc;
392
406
  }
393
407
 
@@ -414,6 +428,10 @@ function installIpc(findTab) {
414
428
  ipcMain.handle("panelcells:states", (e) => { const pc = ctx(e); return pc ? pc.states() : []; });
415
429
  ipcMain.handle("panelcells:profiles", (e) => {
416
430
  if (!ctx(e)) return [];
431
+ // 面板页开局必调这个接口。借它把所有 profile 的 partition 代理绑一遍 ——
432
+ // 页面里的 <webview partition="persist:sandbox-N"> 不走 PanelCells,没人给它设代理,
433
+ // 不设就是直连,账号真实出口 IP 直接暴露。ensureCellSessionProxy 自带去重。
434
+ ensureAllProfileProxies();
417
435
  try {
418
436
  return require("../profiles/profile-store").listProfiles("electron")
419
437
  .filter((p) => Number.isInteger(Number(p.accountIdx)) && Number(p.accountIdx) > 0 && Number(p.accountIdx) !== 9)
@@ -160,10 +160,18 @@ function buildTabWebPreferences(accountIdx, partition, target, opts = {}) {
160
160
  // home is system-driven (openHomeWindow), never caller-URL-reachable, so it
161
161
  // keeps its privileges without a URL check.
162
162
  if (opts.home) { wp.preload = HOMEPAGE_PRELOAD; wp.webviewTag = true; wp.allowRunningInsecureContent = true; wp.sandbox = false; }
163
- // split panel page: its cells are main-managed BrowserViews (panel-cells.js),
164
- // driven over panelAPI IPC. No webviewTag needed (that path is the file://-dev
165
- // fallback below). Sandbox stays ON the preload only uses contextBridge/ipc.
166
- else if (typeof target === "string" && (target.startsWith(PANEL_URL_BASE) || target.startsWith("cicyui://panel"))) { wp.preload = PANEL_PRELOAD; }
163
+ // split panel page: cells may be main-managed BrowserViews (panel-cells.js, over
164
+ // panelAPI IPC) OR in-page <webview>. BrowserViews are painted by the main process
165
+ // at viewport coordinates, so they do not scroll with the page and are not clipped
166
+ // by the grid's overflow with more than a screenful of cells that is unusable.
167
+ // <webview> lives in the DOM and scrolls/clips for free, so the panel needs
168
+ // webviewTag on. sandbox must go off for the tag to be usable; the preload still
169
+ // only exposes contextBridge/ipcRenderer, and the panel page is our own origin.
170
+ else if (typeof target === "string" && (target.startsWith(PANEL_URL_BASE) || target.startsWith("cicyui://panel"))) {
171
+ wp.preload = PANEL_PRELOAD;
172
+ wp.webviewTag = true;
173
+ wp.sandbox = false;
174
+ }
167
175
  // Every other profile-0 tab carries the electronRPC bridge (WEBVIEW_PRELOAD),
168
176
  // but the bridge is INERT until the page's origin is authorized: the first
169
177
  // rpc:guarded call from a non-allowlisted origin pops a consent modal