dsh-gitbash-shell 0.41.0 → 0.41.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  > 倒序排列,新版本条目在最上面。条目格式:`## vX.Y.Z — YYYY-MM-DD` + 类型(feat / fix / docs / chore)+ 要点 + 相关链接。
4
4
  > 纪律见 AGENTS.md「变更记录纪律」:发版前先更新本文件并随版本提交;事故复盘、复现与真机验证记录也记在这里。
5
5
 
6
+ ## v0.41.1 — 2026-10-19
7
+
8
+ ### fix:桌面版设置页「安装 / 升级选中」无反应(栅栏 no-origin 误伤 Electron + 前端静默吞 403)
9
+
10
+ - 报告:[issue #33](https://github.com/KannaKuron/dsh-gitbash-shell/issues/33)(@AncherEven,报告自带完整根因定位,感谢)。dsh 桌面版(Electron)设置 → 插件 → 终端工具,点「安装 / 升级选中」不报错、不出进度、按钮复原。
11
+ - **fix(栅栏侧,tool-runner.js)**:`fenceToolRequest` 原要求改写类请求必须携带同源 Origin/Referer,而桌面版 Electron 渲染进程的同源 fetch **不携带**这两个头 → 恒 403 `no-origin`。现改为:缺 Origin 时放行 origin 半(信任围栏的真防线是 loopback 限定,保持不变);**携带** Origin/Referer 时仍必须同源,跨站一律拒。安全性论证:浏览器对一切改写请求(同站与跨站)都附加 Origin,缺头请求不可能来自网页 CSRF,只能来自非浏览器客户端——而后者本就能伪造同源头,栅栏对其原本就不构成额外防线。
12
+ - **fix(前端侧,client.js)**:`runTools()` 对非 2xx 响应直接 `res.json()` 解析错误体、取不到 `job` 静默吞掉;现与 `loadTools()` 一致先判 `res.ok`,栅栏拒绝等失败会显示「HTTP 403」类错误而不是无反应。
13
+ - 验证:`npm test` 263 项全绿;栅栏测试矩阵更新(缺头 POST 放行 / 携带跨源 POST 仍拒 / LAN 携带同源头仍 not-loopback / 前端 res.ok 守卫断言)。
14
+
6
15
  ## v0.41.0 — 2026-10-19
7
16
 
8
17
  ### feat:官方「持久终端」实验包 Git Bash 化自动接管;dsh-ops 并存时剔除其 shell 工具;terminal_* 方言说明
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-gitbash-shell",
3
- "version": "0.41.0",
3
+ "version": "0.41.1",
4
4
  "main": "./src/index.js",
5
5
  "description": "Windows 全模式 Git Bash:自带 bash 工具(私有 Git Bash 执行器实例,官方 PowerShell 执行器原样保留),官方四个模式经行内工具补位直接获得 Git Bash(v0.35.0 起;v0.39.0 起不再替换宿主执行器),四个 *·Git Bash 变体 preset 可开关;官方 pwsh 工具默认隐藏、开关可见(真 PowerShell);附带 gb_* FastCtx 文件工具,检测到 dsh-ops 自动让位。联动:dsh-ptc-cordis-preset(PTC 创造模式带 Git Bash 行且可去重)+ dsh-better-sidebar(终端标签自动切 Git Bash)。",
6
6
  "engines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-gitbash-shell",
3
- "version": "0.41.0",
3
+ "version": "0.41.1",
4
4
  "description": "Windows 上给 agent 一个真正的 Git Bash 命令工具:私有 Git Bash 执行器实例(官方 PowerShell 执行器原样保留),统一 MSYS 盘根路径方言,官方 pwsh 工具默认隐藏可开关,物化四个内置预设的 Git Bash 变体,侧栏终端接管可开关。· Give agents a real Git Bash tool on Windows: a private Git Bash executor instance (the official PowerShell executor stays untouched), a unified MSYS drive-root path dialect, an opt-in official pwsh tool, and four Git Bash preset variants.",
5
5
  "type": "module",
6
6
  "repository": {
package/src/client.js CHANGED
@@ -2551,7 +2551,12 @@ window.__ModuleLoader__.load({
2551
2551
  headers: { "content-type": "application/json" },
2552
2552
  body: JSON.stringify({ action: "auto", ids: ids }),
2553
2553
  })
2554
- .then(function (res) { return res.json(); })
2554
+ // Issue #33: a non-2xx answer (e.g. a 403 fence refusal) is a JSON
2555
+ // body too — parsing it and finding no job silently ate the error.
2556
+ .then(function (res) {
2557
+ if (!res.ok) throw new Error("HTTP " + res.status);
2558
+ return res.json();
2559
+ })
2555
2560
  .then(function (data) { setToolJob(data !== null && typeof data === "object" && data.job ? data.job : null); })
2556
2561
  .catch(function (err) { setToolErr(String((err && err.message) || err)); })
2557
2562
  .then(function () { setToolBusy(false); });
@@ -290,9 +290,16 @@ export function isSameOriginValue(value, host) {
290
290
  /**
291
291
  * The fence for the tools route. Installing is a side effect, so:
292
292
  * - the peer must be loopback (a LAN or tunnel client never gets to install);
293
- * - a mutating request must carry an Origin or Referer that matches Host.
293
+ * - a mutating request that CARRIES an Origin or Referer must match Host.
294
294
  * A same-origin GET from the settings page passes; a form/fetch posted by any
295
295
  * other page fails on the origin check.
296
+ * A mutating request with NO origin header passes the origin half (issue #33):
297
+ * the desktop Electron renderer's same-origin fetch sends no Origin/Referer,
298
+ * and browsers attach Origin to every mutating request — same-site and
299
+ * cross-site alike — so a missing header cannot be web-page CSRF; it can only
300
+ * come from a non-browser client, which could forge a same-origin header just
301
+ * as easily. The loopback requirement stays (the real fence) and a carried
302
+ * cross-origin value is still refused.
296
303
  * @param {{ method?: string, headers?: object, socket?: object }} req
297
304
  * @returns {{ ok: boolean, reason: string }}
298
305
  */
@@ -304,7 +311,7 @@ export function fenceToolRequest(req) {
304
311
  const headers = (req && req.headers) || {}
305
312
  const host = headers.host || ''
306
313
  const origin = headers.origin || headers.referer || ''
307
- if (origin === '') return { ok: false, reason: 'no-origin' }
314
+ if (origin === '') return { ok: true, reason: '' }
308
315
  if (!isSameOriginValue(origin, host)) return { ok: false, reason: 'cross-origin' }
309
316
  return { ok: true, reason: '' }
310
317
  }