- main.cjs: 从 env 读 AGENTMAIL_GATEWAY_URL / AGENTMAIL_TOKEN(USER_KEY), 通过 additionalArguments 传给 preload;API_BASE = <gateway>/api/v1 - preload.cjs: 从 process.argv 读注入参数,contextBridge 暴露 window.__AGENTMAIL_API_BASE__ / __AGENTMAIL_TOKEN__ → web/src 的 config.ts 自动读取,client.ts/sse.ts 零改动 - 效果:Electron 启动后 api.me() 带 Bearer 返回用户,直接进入主界面 (无登录页),收件箱等功能立即可用 验证(xvfb headless): - 注入链路:渲染进程拿到 apiBase=192.168.2.60:8180 + token ✅ - 端到端:gui-lab key 注入 → 界面呈现 收件/授权/发件/日历/联系 导航 + 空收件箱, 无登录表单(inputCount=0, hasLogin=false)✅
37 lines
1.6 KiB
JavaScript
37 lines
1.6 KiB
JavaScript
/**
|
||
* AgentMail Electron preload —— 通过 contextBridge 暴露安全 API 给渲染进程。
|
||
*
|
||
* 渲染进程是 web/src 的 React,跑在 sandbox: true 下(无 nodeIntegration)。
|
||
* 需要桌面能力时(文件选择、通知、托盘角标、SSE 转发)走这里暴露的桥。
|
||
*
|
||
* Phase 1 只暴露最小集;后续 Phase 逐步加。
|
||
*/
|
||
|
||
const { contextBridge, ipcRenderer } = require('electron');
|
||
|
||
// 注入 API 基地址与 token:渲染进程的 config.ts 在读 window.__AGENTMAIL_API_BASE__
|
||
// 与 __AGENTMAIL_TOKEN__ 时拿到它们,于是现有 client.ts/sse.ts **零改动**复用。
|
||
// 这两个值由主进程在创建窗口时通过附加参数传进来(见 main.cjs 的 additionalArguments)。
|
||
function getInjected(name) {
|
||
const prefix = `--agentmail-${name}=`;
|
||
const arg = process.argv.find(a => a.startsWith(prefix));
|
||
return arg ? arg.slice(prefix.length) : undefined;
|
||
}
|
||
|
||
contextBridge.exposeInMainWorld('__AGENTMAIL_API_BASE__', getInjected('api-base') || 'http://127.0.0.1:8180/api/v1');
|
||
contextBridge.exposeInMainWorld('__AGENTMAIL_TOKEN__', getInjected('token') || undefined);
|
||
|
||
contextBridge.exposeInMainWorld('agentmail', {
|
||
/** Gateway 基础地址(主进程 env 或默认 127.0.0.1:8180) */
|
||
gatewayUrl: () => ipcRenderer.invoke('get-gateway-url'),
|
||
|
||
/** 版本信息(渲染进程可显示在 About 页) */
|
||
versions: {
|
||
electron: process.versions.electron,
|
||
chrome: process.versions.chrome,
|
||
node: process.versions.node,
|
||
},
|
||
|
||
/** 平台标识:win32 / linux / darwin */
|
||
platform: process.platform,
|
||
}); |