dsh-msg9-kit 0.2.0 → 0.2.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/README.md CHANGED
@@ -73,6 +73,7 @@ themes alike.
73
73
  | `msg9_peers` | List the sibling workspaces' inboxes (address book for cross-workspace sync) |
74
74
  | `msg9_rotate` | Rotate the current workspace's key (recover from a lost/leaked key) |
75
75
  | `msg9_status` | Owner + current workspace + cursor + state file; `verify=true` checks the key |
76
+ | `msg9_notify` | Pause/resume new-mail wake-ups for this instance (`on` / `off` / `status`) — the same mute switch as the panel bell |
76
77
 
77
78
  Plus `/msg9` to print the owner and the registered workspace inboxes.
78
79
 
@@ -137,10 +138,16 @@ The panel resolves the same workspace from the current session's `cwd` (the
137
138
 
138
139
  ## Install
139
140
 
141
+ ```bash
142
+ dsh plugin --profile web add dsh-msg9-kit
143
+ # then restart dsh web and refresh the browser
144
+ ```
145
+
146
+ From source (for development):
147
+
140
148
  ```bash
141
149
  npm install && npm run build # builds lib/index.js + lib/client.js
142
150
  bash scripts/install-personal.sh # dsh plugin --profile web add <this dir>
143
- # then restart dsh web and refresh the browser
144
151
  ```
145
152
 
146
153
  The plugin is one Loader entry; its `dsh.client` manifest makes the browser load
@@ -200,6 +207,12 @@ State (`~/.dsh/msg9-kit/state.json`, 0600, written atomically):
200
207
  A state file that fails to parse is never silently discarded: it is copied to
201
208
  `state.json.corrupt-*` and reported, because it holds irreplaceable inbox keys.
202
209
 
210
+ One `DSH_HOME` supports **one dsh instance**: writes are serialized with a
211
+ `state.json.lock` file lock, so a second instance sharing the same state file
212
+ fails loudly (`state file is locked by another process`) instead of silently
213
+ overwriting irreplaceable inbox keys. Run each instance with its own
214
+ `DSH_HOME` / `MSG9_STATE_FILE`.
215
+
203
216
  ## Typical use
204
217
 
205
218
  ```
@@ -219,8 +232,16 @@ what it sent, and the address book it messages most.
219
232
 
220
233
  ## HTTP bridge
221
234
 
222
- The panel talks to these same-origin routes (loopback / same-origin only, never
223
- a key in the response):
235
+ The panel talks to these same-origin routes (never a key in the response).
236
+ Requests are accepted only when the connection itself comes from loopback
237
+ (`remoteAddress`), plus a same-origin `Origin` check for browsers — a forged
238
+ `Host` header from another local process does not pass.
239
+
240
+ Threat-model boundary (per audit): a local process connecting via loopback is
241
+ still trusted — deliberately, since it could read `~/.dsh/msg9-kit/state.json`
242
+ directly anyway; HTTP-layer defence cannot and need not keep out the machine's
243
+ owner. What this check actually closes is remote clients forging `Host` when
244
+ dsh web binds a non-loopback address, and cross-origin browser pages:
224
245
 
225
246
  | Route | Purpose |
226
247
  |---|---|
package/README.zh-CN.md CHANGED
@@ -61,6 +61,7 @@
61
61
  | `msg9_peers` | 列出**兄弟 workspace** 的收件箱(跨 workspace 同步的地址簿) |
62
62
  | `msg9_rotate` | 轮换当前 workspace 的 key(本地 key 丢失/泄漏时恢复) |
63
63
  | `msg9_status` | owner + 当前 workspace + 游标 + 状态文件;`verify=true` 校验 key |
64
+ | `msg9_notify` | 暂停/恢复本实例的新邮件唤醒(`on` / `off` / `status`)——和面板铃铛是同一个静音开关 |
64
65
 
65
66
  另有 `/msg9` 命令,打印 owner 与已登记的 workspace 收件箱。
66
67
 
@@ -102,10 +103,16 @@ dsh-<slug>-<hash4>@msg9.io
102
103
 
103
104
  ## 安装
104
105
 
106
+ ```bash
107
+ dsh plugin --profile web add dsh-msg9-kit
108
+ # 然后重启 dsh web 并刷新浏览器
109
+ ```
110
+
111
+ 从源码改装(开发时):
112
+
105
113
  ```bash
106
114
  npm install && npm run build # 产出 lib/index.js + lib/client.js
107
115
  bash scripts/install-personal.sh # 等价于 dsh plugin --profile web add <本目录>
108
- # 然后重启 dsh web 并刷新浏览器
109
116
  ```
110
117
 
111
118
  插件只有一个 Loader entry,包内的 `dsh.client` 声明让浏览器从同一个包加载 `./client` 面,因此图标和面板无需额外配置。
@@ -155,6 +162,8 @@ bash scripts/install-personal.sh # 等价于 dsh plugin --profile web add <
155
162
 
156
163
  状态文件解析失败时**不会**被静默清空:它会先被复制为 `state.json.corrupt-*` 再报错——因为里面存着不可再生的收件箱 key。
157
164
 
165
+ 一个 `DSH_HOME` 只支持**一个 dsh 实例**:写入前会对 `state.json.lock` 加文件锁,第二个共享同一状态文件的实例会响亮报错(`state file is locked by another process`),而不是互相覆盖不可再生的收件箱 key。多实例请各用各的 `DSH_HOME` / `MSG9_STATE_FILE`。
166
+
158
167
  ## 典型用法
159
168
 
160
169
  ```
@@ -173,7 +182,9 @@ msg9_send({ to: "dsh-alpha-a1b2@msg9.io", text: "schema 已更新", correlation_
173
182
 
174
183
  ## HTTP 桥
175
184
 
176
- 面板调用的同源接口(只接受本机 / 同源请求,响应里永不含 key):
185
+ 面板调用的同源接口(响应里永不含 key)。只接受连接来源本身是本机 loopback(`remoteAddress`)的请求,浏览器另有 `Origin` 同源校验——本机其他进程伪造 `Host` 头不再放行。
186
+
187
+ 威胁模型边界(审计澄清):本机进程经 loopback 连接仍会被信任——这是有意的,因为这类进程本就可以直读 `~/.dsh/msg9-kit/state.json`,HTTP 层防不住也不必防「机器主人」。这层校验真正关掉的是:dsh web 绑定非 loopback 地址时远程伪造 `Host` 的客户端,以及跨源浏览器页面。
177
188
 
178
189
  | 路由 | 用途 |
179
190
  |---|---|