dsh-notify-me 1.14.0 → 1.14.2
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 +36 -4
- package/README.en.md +158 -136
- package/README.md +97 -71
- package/lib/client.js +102 -13
- package/lib/index.js +83 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to **dsh-notify-me** are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.14.2] — 2026-10-24
|
|
6
|
+
|
|
7
|
+
### 修复
|
|
8
|
+
|
|
9
|
+
- **桌面端「测试「审批按钮」」不再无声失败**:Windows 拒收 tag 超过 64 字符的通知,而 Chromium 交给平台的最终 tag 是 `n#<origin>#<tag>`——`dsh-app://app` 先占 16 字符。旧测试 key 是 `test:approval:<13 位毫秒>`,tag 51 字符、整条 67,`new Notification()` 构造时直接抛 `The size of the notification tag is too large`,异常被 `showToast()` 的空 catch 吞掉,设置页却已经写了「已发送」(issue #18)。现在所有 tag 统一走 `toastTag()`:按 `location.origin` 算出平台前缀的占位,超长时保留可读前缀、尾部换 FNV-1a base36 哈希收口;审批 tag 仍由 `closeNotificationTag()` 用记录里的同一个字符串关闭。
|
|
10
|
+
- **测试 key 缩短**:`"t" + Date.now().toString(36)`(10 字符),tag 33 字符,离桌面端 48 的天花板有余量。
|
|
11
|
+
- **拒收不再静默**:`showToast()` 的 catch 与 Service Worker `showNotification()` 的异步 reject 都记一条 `lastToastReject`(tag 长度 + 平台原文),写进 `debug()`;设置页测试按钮命中拒收时改报「系统拒收了这条通知:<原因>」,`window.__dshNotifyMe.test()` 的返回串带上 `refused=`。
|
|
12
|
+
|
|
13
|
+
### 测试
|
|
14
|
+
|
|
15
|
+
- 冒烟新增 `toastTagLimits()`:桌面 origin(`dsh-app://app`)下 budget 为 48、审批测试 tag ≤ 48 且不再含 51 字符的旧 key;100 字符的交互 key 被哈希收口、仍以 `dsh-notify-me-attention-` 开头、两个不同长 key 收口后不撞;28 字符的 Web origin 把 budget 压到 33 并让同一条审批 tag 跟着缩短;`Notification` 构造抛错时 `debug().lastToastReject` 记下平台原文与 tag 长度,`api.test()` 报 `refused=`。`npm test` 全绿。
|
|
16
|
+
|
|
17
|
+
### 文档
|
|
18
|
+
|
|
19
|
+
- `docs/listing.md` 版本口径同步到 1.14.2。
|
|
20
|
+
|
|
21
|
+
## [1.14.1] — 2026-10-23
|
|
22
|
+
|
|
23
|
+
### 修复
|
|
24
|
+
|
|
25
|
+
- **抬窗路由的 CSRF 闸门换成本地性校验**:1.14.0 把 `x-dsh-notify-me-focus: focus` 头当成防线,理由写的是「跨源页面带这个头要先过预检」。这条对 DNS rebinding 不成立——rebinding 出来的页面和目标地址同源,能带任意自定义头、不会触发预检。现在改成三层:对端地址必须 loopback;`Host` 必须是 loopback 名(`127.0.0.1` / `localhost` / `[::1]`,可带端口);带了 `Origin` 就必须与 `Host` 同源。任一条不满足回 `403`,`reason` 写 `bad-remote` / `bad-host` / `cross-origin`。
|
|
26
|
+
- **`Host` 这一层是真正的分界**:壳转发 `dsh-app://app` 时会把 `host` 一起删掉,由 fetch 按 loopback URL 重填,所以桌面页面永远带 loopback 的 `Host`;rebinding 的页面 Host 仍是攻击者域名。自定义头保留,但只当「这是页面发的」标记,不再承担安全职责。
|
|
27
|
+
- **`OPTIONS` 一律 `405` 且从不回 CORS 头**:预检不会被应答,跨源页面拿不到放行。
|
|
28
|
+
|
|
29
|
+
### 测试
|
|
30
|
+
|
|
31
|
+
- cordis 冒烟的路由段补五组断言:外边 `Host` → `403 bad-host`;非 loopback 对端 → `403 bad-remote`;跨源 `Origin` → `403 cross-origin`;同源 `Origin` 通过闸门后走到 `501`;换端口的 `Origin` 也算跨源;预检 `OPTIONS` → `405`。假请求补齐 `socket.remoteAddress` 与默认 `Host`。
|
|
32
|
+
- 另用真 socket 复现过 1.14.0 的行为:`POST` 带 `Host: evil.example` + 跨源 `Origin` 仍返回 `200 focused:true`(打进 OS 激活路径),硬化后同样请求回 `403 bad-host`。`npm test` 全绿。
|
|
33
|
+
|
|
34
|
+
### 文档
|
|
35
|
+
|
|
36
|
+
- 中英 README 与 `docs/listing.md` 的安全段改口径:不再说「自定义头挡跨源」,改成本地性三层闸门与各自的 `reason`。
|
|
37
|
+
|
|
5
38
|
## [1.14.0] — 2026-10-23
|
|
6
39
|
|
|
7
40
|
### 新增
|
|
@@ -17,7 +50,7 @@ All notable changes to **dsh-notify-me** are documented here.
|
|
|
17
50
|
### 说明
|
|
18
51
|
|
|
19
52
|
- **为什么走 PowerShell 而不是原生模块**:插件宿主是普通 Node 进程(壳以 `ELECTRON_RUN_AS_NODE=1` 拉起),拿不到 Electron API;带原生依赖还得跟宿主 ABI 对齐。`powershell.exe` 在 Windows 10/11 上必在,脚本用 `Add-Type` 现编译 P/Invoke,零安装。
|
|
20
|
-
- **抬窗顺序是实的,不是拍脑袋**:已在前台就什么都不做;最小化了先 `SW_RESTORE`;然后合成 ALT 抖动给本线程前台权限再 `SetForegroundWindow`;都不行才走 `SW_MINIMIZE` + `SW_RESTORE` 兜底。单独调 `SetForegroundWindow` 被前台锁拒,退到 ALT
|
|
53
|
+
- **抬窗顺序是实的,不是拍脑袋**:已在前台就什么都不做;最小化了先 `SW_RESTORE`;然后合成 ALT 抖动给本线程前台权限再 `SetForegroundWindow`;都不行才走 `SW_MINIMIZE` + `SW_RESTORE` 兜底。单独调 `SetForegroundWindow` 被前台锁拒,退到 ALT 抖动那一步就过,这也解释了此前「时灵时不灵」的观感。
|
|
21
54
|
- **等待上限 8 秒、400 毫秒内合并**:脚本自身最坏 0.4 秒,超时按 `FOCUSED=0` 收口并 kill 掉;连点两条通知只跑一次。
|
|
22
55
|
- **只 Windows**:`process.platform === "win32"` 且宿主跑在 Electron 里(`process.versions.electron`)才启用,其余平台一律 `501`,页面的抬窗行为跟以前一样。
|
|
23
56
|
|
|
@@ -30,7 +63,6 @@ All notable changes to **dsh-notify-me** are documented here.
|
|
|
30
63
|
### 文档
|
|
31
64
|
|
|
32
65
|
- README 中英重写[桌面端怎么抬窗的](README.md#桌面端怎么抬窗的):删掉 1.5.2 深链那套叙述,换成宿主路由 + 原生激活的链路、实测数据与失败时的回退行为;已知限制里「桌面端不一定上前台」换成「提权窗口 / 虚拟桌面 / 前台被连续抢占时仍可能抬不起来,此时返回 `202` 但对话照常切」。
|
|
33
|
-
- 致谢加上 [@xinming-chenniang](https://github.com/xinming-chenniang):[discussions #10446](https://github.com/deepseek-ai/deepseek-harness/discussions/10446#discussioncomment-19143913) 里给的五种手法实测表与「宿主自定义路由 + 同源校验 + PowerShell 兜底链」的思路,是这一版落地的直接依据。
|
|
34
66
|
|
|
35
67
|
## [1.13.0] — 2026-10-23
|
|
36
68
|
|
|
@@ -193,7 +225,7 @@ All notable changes to **dsh-notify-me** are documented here.
|
|
|
193
225
|
|
|
194
226
|
- **修正 1.9.4 的口径过重**:实测补充了「有时能上前台」的反馈后重测——1.9.4 说的「0.2.1-rc.2 上失效」不准确,实际是**不稳定**:有时窗口会上前,有时只切对话。
|
|
195
227
|
- 复测方法:把 `dsh://open` 深链单独拿出来,三种走法(直接带参启动 exe、走系统协议激活、`WM_SYSCOMMAND` 真实最小化后再发)各 3 次,**全部失败**——带参第二实例每次约 130 ms 后退出码 1(不带参数约 260 ms 退出码 0,正常单实例让位),最小化窗口的 `IsIconic` 每次保持 `true`。⇒ 能抬起来的那些次大概率是系统/Chromium 在通知点击时自己激活了窗口,不是深链。
|
|
196
|
-
- README
|
|
228
|
+
- README(中英)与设置页提示改为「不稳定」,并写明隔离复测结论。
|
|
197
229
|
|
|
198
230
|
### 测试
|
|
199
231
|
|
|
@@ -203,7 +235,7 @@ All notable changes to **dsh-notify-me** are documented here.
|
|
|
203
235
|
|
|
204
236
|
### 说明
|
|
205
237
|
|
|
206
|
-
- **改口径:桌面端「点通知抬窗」不再当成必然**。DSH Desktop 0.2.1-rc.2(Windows)实测这条链路失效——通知点击回调照常执行(`navigator.userActivation.isActive === true`),但窗口不上前台;带 `dsh://open` 参数的第二实例 133 ms 后以退出码 1 结束,不带参数则 258 ms 退出码 0;用 `WM_SYSCOMMAND` 真实最小化后发深链,`IsIconic` 仍为 `true`,`focusPrimaryWindow()` 的 `restore()` 没生效;壳的 preload 也没有 focus/raise 类 IPC
|
|
238
|
+
- **改口径:桌面端「点通知抬窗」不再当成必然**。DSH Desktop 0.2.1-rc.2(Windows)实测这条链路失效——通知点击回调照常执行(`navigator.userActivation.isActive === true`),但窗口不上前台;带 `dsh://open` 参数的第二实例 133 ms 后以退出码 1 结束,不带参数则 258 ms 退出码 0;用 `WM_SYSCOMMAND` 真实最小化后发深链,`IsIconic` 仍为 `true`,`focusPrimaryWindow()` 的 `restore()` 没生效;壳的 preload 也没有 focus/raise 类 IPC。
|
|
207
239
|
- README(中英):设置清单、「运行环境」说明、「桌面端怎么抬窗的」、已知限制四处按实测结果改写——插件照发深链,原生窗口能否上前台由壳决定;0.2.0-rc.2 上验证通过的结论与「深链必须在用户手势里发」的口径保留。
|
|
208
240
|
|
|
209
241
|
### 变更
|