dsh-vaultwarden 0.0.0-stage → 0.8.8
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 +522 -0
- package/LICENSE +21 -0
- package/README.md +290 -2
- package/THIRD-PARTY-NOTICES.md +93 -0
- package/assets/panel-detail-dark.png +0 -0
- package/assets/panel-detail.png +0 -0
- package/assets/panel-editor.png +0 -0
- package/assets/panel-list.png +0 -0
- package/cordis.patch.yml +5 -0
- package/docs/release.md +69 -0
- package/docs/ui-design.md +149 -0
- package/icon.svg +6 -0
- package/lib/cache-store.js +266 -0
- package/lib/client.js +6450 -0
- package/lib/gateway.js +572 -0
- package/lib/index.js +710 -0
- package/lib/mutations.js +706 -0
- package/lib/notifications.js +297 -0
- package/lib/session-store.js +181 -0
- package/lib/totp.js +80 -0
- package/lib/vault.js +2710 -0
- package/package.json +102 -4
- package/screenshots.json +4 -0
- package/scripts/build.sh +188 -0
- package/scripts/stamp-build.mjs +39 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `dsh-vaultwarden` are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.8.8] — 2026-10-18
|
|
8
|
+
|
|
9
|
+
### 新增
|
|
10
|
+
|
|
11
|
+
- 面板标题行改为「Vaultwarden 凭据库 + dsh-vaultwarden + 版本号 + GitHub 链接」,版本号与仓库地址由构建时从 package.json 写入、宿主 boot 回报时以宿主为准。
|
|
12
|
+
- 侧栏与条目图标按宿主图标语言重绘:16 网格、1px 描边、0.16 淡体块,视觉框统一留白。
|
|
13
|
+
- 新增统一徽章体系:19px / 11px / 全圆角 / 扁平无描边,按语义分蓝绿琥珀灰墨五档,底色取宿主状态 tertiary 色并随主题翻转。
|
|
14
|
+
|
|
15
|
+
### 修复
|
|
16
|
+
|
|
17
|
+
- 修复移动端字段行竖排规则从未生效:620px 标签列规则排在 480px 之后且特异性相同,导致密码掩码折两行、显示/复制按钮漂出卡片。
|
|
18
|
+
- 修复面板横向溢出:滚动区负边距使其始终比列宽多 4px,改用 scrollbar-gutter;侧栏与列表项补 border-box。
|
|
19
|
+
- 修复手机窄面板下详情头部与操作按钮溢出卡片。
|
|
20
|
+
- 修复「显示」与「复制」按钮高度字号不一致(28/30/32px 三套字面量)。
|
|
21
|
+
- 修复字段行未顶端对齐,标签与控件随值长度漂移。
|
|
22
|
+
- 修复掩码点在窄屏折成两行。
|
|
23
|
+
- 修复标题行折行时只拆下半截(包名留在上行、版本号落到下行);改为标题组与元信息组整体换行。
|
|
24
|
+
## [0.8.7] — 2026-10-17
|
|
25
|
+
|
|
26
|
+
### 安全
|
|
27
|
+
|
|
28
|
+
- **TOTP 读取曾绕过「重新验证」门禁**:`vw/totp` → `totpEntry()` 直接从种子算码,完全不查 reprompt 授权,而同族路径(`get()`、`draftEntry()`、`getFreshTotp()`)都查。面板「验证码」分区每一行都在调它(每秒一次),等于开了「重新验证」的条目把实时二次验证码交给任何走到屏幕前的人。现在与其它字段同一道门:没有主密码证明时返回 `repromptRequired`,面板显示「需重新验证」而不是码。
|
|
29
|
+
- **面板 RPC 曾可自行提升写权限**:`vw/configure` 接受 `accessMode`,而门禁闭包读的是同一份实时设置——一次面板调用就能把 `readonly` 抬到 `auto`,进而让**模型工具**开始无审批写入每一个凭据。该参数不再生效(签名保留但忽略),只能在 DSH 设置里改。
|
|
30
|
+
- **RPC 侧的彻底删除已移除**:`vw/remove` 以前接受 `permanent` + `confirm`,两个布尔由同一个调用方在同一次调用里给出,"不可逆且经人确认"实际是"自己确认自己"。彻底删除现在只有 `bitwarden_delete` 工具能发起(`ask` 档带真实审批),面板与 RPC 只能移入回收站。
|
|
31
|
+
- **面板曾明文展示自定义字段与备注正文**:打开条目就把每条自定义字段的值、每条备注的正文渲染成文本节点。Bitwarden 的 hidden 字段专放 PIN、API key、恢复码,安全笔记正文常常是某个凭据的唯一副本——现在与卡号、SSH 私钥同一档:默认圆点,点「显示」才展开,复制按钮不必展开即可用。
|
|
32
|
+
- **授权到期会收回已展开的明文**:reprompt 的 5 分钟窗口以前只在轮询里更新一个数字,已展开的密码/卡号/私钥、已取回的窄字段、打开着的编辑器都不会关。现在窗口一失效就收起。
|
|
33
|
+
- **编辑器保存后不再长期持有整条明文**:编辑保存后基线仍是宿主返回的完整 draft(含 `passwordHistory` 里每一条旧密码),一直留在 React state 里。现在改用表单值重建基线,并清空密码/TOTP 输入。
|
|
34
|
+
- **剪贴板 20 秒后自动清除**:复制密码/验证码/私钥后以前只改按钮文案,系统剪贴板里的值永久留存(剪贴板管理器、其它应用都能读)。现在写入后定时回读,确认仍是自己写的那一段才清除——读者中途复制了别的东西就不动。
|
|
35
|
+
- **本地快照过期即擦除**:`localStorage` 里的列表快照(条目名、用户名、网址、自定义字段名)过期只返回 null 不删除,切换账号时也只在内存里丢弃。现在过期即删、账号不匹配即删。
|
|
36
|
+
- **`vw/config` 不再回传会话文件绝对路径**:这条元数据给出了数据目录与会话落点,面板渲染用不到。
|
|
37
|
+
- **`passwordHistory` 不再随 `field=all` 明文返回**:历史密码每一条都可能仍能登录同一账号。`all` 只回 `passwordHistoryCount` 与时间,取明文需 `field=passwordHistory`。
|
|
38
|
+
- **写入层缺门禁时拒绝构造**:`VaultMutations` 缺 `guard` 以前等于放行,现在直接抛 `guard_missing`(测试显式传 `guard: () => null` 表示"不限制")。彻底删除的 confirm 检查也移到任何网络调用之前。
|
|
39
|
+
|
|
40
|
+
## [0.8.6] — 2026-10-17
|
|
41
|
+
|
|
42
|
+
### 新增
|
|
43
|
+
|
|
44
|
+
- `bitwarden_get` 新增 `waitFresh` / `minRemaining` 参数(仅对 `field=totp` 生效):剩余时间低于门槛(默认 20 秒)时等到下一个 30 秒窗口再返回。此前取码只是瞬时快照,遇到 `remaining=1` 只能拿到必然过期的码,白耗一次提交机会;实测剩 9 秒时等 10 秒跨过边界,交出的码剩 29 秒。
|
|
45
|
+
|
|
46
|
+
### 修复
|
|
47
|
+
|
|
48
|
+
- `field=totp` 返回值补上 `freshFor`,明确这枚码还剩多少秒可用,不必再猜「来不来得及」。
|
|
49
|
+
|
|
50
|
+
## [0.8.5] — 2026-10-17
|
|
51
|
+
|
|
52
|
+
### 修复
|
|
53
|
+
|
|
54
|
+
- 修复手机上点「编辑」后编辑表单不可见的问题:drill 态隐藏侧栏的样式规则缺少 `!important`,被侧栏自身的内联 `display:flex` 压制,侧栏仍占整列并把表单推出可视区。
|
|
55
|
+
- 修复保存要等十几秒才出提示的问题:去掉保存路径上冗余的第二次全量同步,写入改成就地更新本地条目并在后台刷新。
|
|
56
|
+
- 修复保存成功时提示文案与实际相反的问题:改为「已保存到服务器;本地列表尚未刷新」。
|
|
57
|
+
- 修复打开编辑器时先闪一张类型错误的空白表单的问题:draft 未返回前按条目自身类型渲染。
|
|
58
|
+
- 修复保存失败时提示不可见的问题:结果与错误行移到保存按钮下方,并在出现时滚动到可见位置。
|
|
59
|
+
- 修复连续点开两个条目时慢响应覆盖新内容的问题:加入代次校验丢弃过期响应。
|
|
60
|
+
- 修复未改动任何字段也会真的发起写入的问题:改为与归一化后的基线比较,无改动时直接提示「没有改动」。
|
|
61
|
+
- 修复连接中断时保存提示直接暴露浏览器原文(`Load failed`)的问题:改为人话提示,并对连接中断自动重试(最多 3 次)。
|
|
62
|
+
|
|
63
|
+
### 优化
|
|
64
|
+
|
|
65
|
+
- 优化写入耗时:单次保存从 2.7–16 秒降到 0.5–1.3 秒。
|
|
66
|
+
- 优化保存后的条目更新:只重投影被写入的那一条,不再下载整个保险库。
|
|
67
|
+
|
|
68
|
+
### 测试
|
|
69
|
+
|
|
70
|
+
- 765 项离线测试全绿。
|
|
71
|
+
|
|
72
|
+
## [0.8.4] — 2026-10-16
|
|
73
|
+
|
|
74
|
+
### 优化
|
|
75
|
+
|
|
76
|
+
- 优化面板打开速度:目录与侧栏计数不再挡在条目列表前面,同步状态探针也不再让列表等它。
|
|
77
|
+
- 优化分区切换:切换分区不再重走会话与目录读取,已读过的分区直接出内容。
|
|
78
|
+
- 优化站点图标:改为在面板空闲时批量获取,不再挤在打开面板的瞬间。
|
|
79
|
+
- 优化重开面板:已读过的分区先出内容,再在后台刷新。
|
|
80
|
+
|
|
81
|
+
### 修复
|
|
82
|
+
|
|
83
|
+
- 修复切到「验证码」分区时,上一分区的条目被当成验证码行显示、且每行每秒请求一次验证码的问题。
|
|
84
|
+
- 修复重新打开设置后,新建与编辑按钮消失的问题。
|
|
85
|
+
- 修复重开面板时写权限回落成只读、写操作按钮不显示的问题。
|
|
86
|
+
- 修复宿主拒绝分页后整个会话都改用整表读取的问题,改为 10 分钟后重试。
|
|
87
|
+
|
|
88
|
+
### 测试
|
|
89
|
+
|
|
90
|
+
- 794 项离线测试全绿(新增 4 项回归断言:accessMode=ask 重开面板后写操作与新建按钮仍在、重开不再重发会话读取)。
|
|
91
|
+
|
|
92
|
+
## [0.8.3] — 2026-10-15
|
|
93
|
+
|
|
94
|
+
### 修复
|
|
95
|
+
|
|
96
|
+
- 修复工具行展开体未继承宿主卡片字体的问题,字号、行高与字族与原生工具行一致。
|
|
97
|
+
- 修复工具行展开体正文样式未生效、换行塌陷成一整段的问题。
|
|
98
|
+
|
|
99
|
+
### 测试
|
|
100
|
+
|
|
101
|
+
- 785 项离线测试全绿(新增 4 项原生行断言:卡片字体简写、正文样式对象与属性泄漏)。
|
|
102
|
+
|
|
103
|
+
## [0.8.2] — 2026-10-15
|
|
104
|
+
|
|
105
|
+
### 优化
|
|
106
|
+
|
|
107
|
+
- 优化对话中 bitwarden 工具行的外观:改用宿主原生 DisclosureRow、官方图标集与输入/输出卡片版式,与「运行命令」等原生行一致。
|
|
108
|
+
- 去掉工具行的「密码等敏感值已隐藏」提示文案,脱敏本身不变。
|
|
109
|
+
|
|
110
|
+
### 测试
|
|
111
|
+
|
|
112
|
+
- 781 项离线测试全绿(新增 20 项原生行测试:加载宿主真实 DisclosureRow 断言渲染与交互)。
|
|
113
|
+
- 修复 peer 软链缺失时原生行测试静默跳过的问题,改为门禁中直接失败。
|
|
114
|
+
|
|
115
|
+
## [0.8.1] — 2026-10-14
|
|
116
|
+
|
|
117
|
+
### 修复
|
|
118
|
+
|
|
119
|
+
- 修复窄面板下打开编辑器后表单不可见、工具栏新建按钮随之消失的问题。
|
|
120
|
+
- 修复设置图标绘制成太阳样式的问题,改为标准齿轮。
|
|
121
|
+
- 修复面板宽度不足 300px 时工具栏控件重叠、计数文字压住按钮的问题。
|
|
122
|
+
- 修复对话中 bitwarden 工具卡片明文显示密码、TOTP、卡号、安全码、SSH 私钥、安全笔记正文与自定义字段值的问题。
|
|
123
|
+
- 修复登出后迟到的解锁结果会恢复旧保险库、并写回会话文件的问题。
|
|
124
|
+
|
|
125
|
+
### 优化
|
|
126
|
+
|
|
127
|
+
- 冷启动提速:并发读共用一次解锁、修订探针与下载并行、列表不再等待状态探测、站点图标批量重绘。冷开 6222ms → 1640ms,热开 95ms。
|
|
128
|
+
|
|
129
|
+
### 测试
|
|
130
|
+
|
|
131
|
+
- 761 项离线测试全绿(新增 30 项:编辑器可见性、齿轮轮廓、转录卡片逐类脱敏、并发单飞、登出竞态)。
|
|
132
|
+
|
|
133
|
+
## [0.8.0] — 2026-10-14
|
|
134
|
+
|
|
135
|
+
### 新增
|
|
136
|
+
|
|
137
|
+
- 新增条目编辑器:详情「操作」区可编辑,工具栏可新建条目(`accessMode` 为 `ask`/`auto` 时)。
|
|
138
|
+
- 新增五类条目的全字段表单:登录、安全笔记、银行卡、身份信息、SSH 密钥;另有收藏、需要重新验证、文件夹与自定义字段。
|
|
139
|
+
- 新增 `vw/draft`:一次取回整条明文供表单填充;TOTP 种子不在其中,留空即保留原设置。
|
|
140
|
+
- 新增轮询实时同步:宿主处于轮询模式时,面板按宿主自报间隔安静重读列表。
|
|
141
|
+
- 新增 reprompt 条目的编辑入口:主密码时间窗内可直接编辑。
|
|
142
|
+
- 新增保存后强制同步与列表重读;保存只发变化过的字段,未触碰的密码与 TOTP 种子不进请求。
|
|
143
|
+
|
|
144
|
+
### 修复
|
|
145
|
+
|
|
146
|
+
- 修复并发修改被静默覆盖的问题:宿主以 `stale_revision` 拒绝写入,编辑器停用保存并提示重新打开。
|
|
147
|
+
- 修复锁着的条目仍显示无法填写的表单的问题。
|
|
148
|
+
- 修复工具栏动作文字在手机宽度占掉一整排、把计数挤成「共 4」的问题。
|
|
149
|
+
- 修复密码行显示/复制按钮在窄宽下被挤出卡片的问题。
|
|
150
|
+
- 修复网址字段为多行输入框的问题。
|
|
151
|
+
- 修复同步徽标被旧失败长期染红的问题。
|
|
152
|
+
|
|
153
|
+
### 测试
|
|
154
|
+
|
|
155
|
+
- 731 项离线测试全绿(新增 54 项:编辑器链路、draft 契约、并发冲突、只读档门禁)。
|
|
156
|
+
|
|
157
|
+
## [0.7.1] — 2026-10-08
|
|
158
|
+
|
|
159
|
+
详情页补上站点图标:列表里认得出来的那个图标,点进去就没了。
|
|
160
|
+
|
|
161
|
+
### 修复
|
|
162
|
+
|
|
163
|
+
- **打开条目后,头像位显示的是字母而不是站点图标**。列表行走的是 `iconFor(item) ?? monogram(item)`,而详情卡片的图标位直接把 `monogram(value)` 画进那个 36px 的圆枕里,从没走过站点图标那条路——于是列表行挂着图标,点开却退回成一个字母。详情头部现在与列表行共用同一套取图逻辑:服务器有图标就显示图标,没有才退回字母圆枕。
|
|
164
|
+
- **reprompt 条目的头部也拿得到图标**。`reprompt` 的门只挡字段,不挡条目身份:网址本来就在打开它的那一行里露着,所以 `projectItem` 的 reprompt 分支现在一并带出 `uris`,门仍然照旧一个字也不放(`password`/`notes`/自定义字段一个都不给)。
|
|
165
|
+
- **详情头部的图标跟着瓦片放大**。`iconFor` 收一个可选的图片样式:列表行的 18px 不变,36px 的大圆枕里用 22px,不再是一个 18px 的小点浮在正中间。
|
|
166
|
+
|
|
167
|
+
### 测试
|
|
168
|
+
|
|
169
|
+
- `test/client-card.test.mjs`(250 → 252):新增「打开的条目带着它列表行上那个站点图标」「头部瓦片把图标放大,而不是在 36px 里放 18px」。
|
|
170
|
+
|
|
171
|
+
## [0.7.0] — 2026-10-08
|
|
172
|
+
|
|
173
|
+
收紧两处明文出口:`bitwarden_get` 不再一次性把整条凭据倒出来,Bitwarden 的「重新验证」也不再靠一个调用方自己能打的勾。
|
|
174
|
+
|
|
175
|
+
### 变更
|
|
176
|
+
|
|
177
|
+
- **`field=all` 不再是散弹**。`all` 现在只回密码、用户名、网址、备注与自定义字段,加上 `hasTotp`/`hasCard`/`hasIdentity`/`hasSshKey` 这类存在位与 SSH 指纹。**TOTP 验证码**要 `field=totp`(30 秒即失效,进了 transcript 对调用方无用、对后人是活密钥);**银行卡 / 身份信息 / SSH 私钥 / 安全笔记正文**要 `field=card` / `identity` / `sshKey` / `secureNote` 各自点名。安全笔记的正文原先走 `notes` 一并带出——对一条笔记来说正文**就是**那个秘密,所以它同样收窄到 `field=secureNote`。
|
|
178
|
+
- **reprompt 的门由主密码开,不由 `confirm: true` 开**。过去 `bitwarden_get { confirm: true }` 就能读 `reprompt: 1` 的条目:那是模型自己给自己打的复选框。现在 `confirm` 参数**已从工具面上删除**,`reveal` RPC 也不再收它。打开门只能走 `vw/authorizeReprompt`——面板里由本人输入主密码,宿主用会话主密钥 `timingSafeEqual` 比对(Argon2id/PBKDF2 派生,KDF 参数随会话缓存,不额外回服务器)。通过后开一个**纯内存**时间窗(`repromptGrantMinutes`,默认 5 分钟)给整条解锁;插件重启或会话失效即作废。
|
|
179
|
+
- **reprompt 的门覆盖条目的每一个字段**。原来只挡 `password`/`totp`/`all`,`notes` 与自定义字段从旁边绕了过去。
|
|
180
|
+
- **面板与工具面同规则**:详情页的 reprompt 条目从「确认读取」按钮换成主密码输入框(回车即提交,输错留在原地并报错);窄字段改为「含银行卡 · 读取这一项」这样的一行,点一下才单独取那一个字段。
|
|
181
|
+
|
|
182
|
+
### 测试
|
|
183
|
+
|
|
184
|
+
- `test/live-sync.test.mjs`:reprompt 用例改写为新契约——`confirm: true` 不再开门、错密码被拒且门保持关闭、对的主密码开门并解出明文、`notes` 同样受门保护。
|
|
185
|
+
- `test/client-card.test.mjs`:新增「错误主密码被拒且不泄露明文」「解锁只走 `vw/authorizeReprompt`、永不带 reveal 的 confirm 布尔」「打开卡片条目不交出卡号与持卡人姓名」「打开 SSH 条目只给指纹、不给公钥与私钥」「只读该字段时才请求它」;reprompt 竞态用例改挂在解锁往返上(迟到的解锁答复不得画进新条目、不得留下 reveal 标志)。grant 轮询只在门真的在屏幕上时才发 `vw/repromptGrant`,否则每次打开面板都要多一次往返。
|
|
186
|
+
- `test/mutations.test.mjs` / `test/write-back.test.mjs`:安全笔记正文改从 `field=secureNote` 取。
|
|
187
|
+
|
|
188
|
+
## [0.6.3] — 2026-10-08
|
|
189
|
+
|
|
190
|
+
修 v0.6.2 引入的一处回归:把「窄面板就解钉」当成宽度问题,结果窄窗口的**鼠标**用户也丢了分区菜单——收藏、验证码、未归类这些行跟着列表一起滚出视野。解钉现在只对**手指**(`pointer: coarse`)生效。
|
|
191
|
+
|
|
192
|
+
### 修复
|
|
193
|
+
|
|
194
|
+
- **窄窗口下的鼠标用户重新拿回固定的分区菜单**。v0.6.2 让左栏在桌面端 `position: sticky; top: 0`,却把「解钉」的判据写成面板宽度(`@container vw-panel (max-width: 480px)`,无容器查询时是 760px 窗口):窗口小于约 800px 时面板只剩 ~476px,规则命中,左栏退回 `static`,于是收藏 / 验证码 / 未归类这些行和条目一起滚走——读者正站着的那个筛选离开了屏幕。现在解钉只写在 `@media (pointer: coarse)` 里(容器查询版与无容器查询回退版各一份),**鼠标在任意宽度都保持钉住**;只有手指(手机 / 平板单列)才把左栏交回列表上方、跟着列表滑动。
|
|
195
|
+
- **左栏不加高度截断**。sticky 元素高过滚动口时本来就会随列表滚动、直到自身末尾进入视野,文件夹多时左栏自己走完就停住,不需要 `max-height`。中途试过 `max-height: min(52vh, 340px)` + `overflow-y: auto`,结果把最后一行「回收站」截在半个高度上,看着像坏掉的盒子,已放弃。
|
|
196
|
+
|
|
197
|
+
### 测试
|
|
198
|
+
|
|
199
|
+
- `test/client-card.test.mjs` 241 → 244 项:新增「解钉必须位于 coarse 指针闸门之后(容器查询版与无容器查询回退版都查)」「窄面板不再给左栏加高度截断」两条断言;原有的 sticky 内联样式、解钉字面量出现 ≥2 次、单一滚动容器等断言保留。
|
|
200
|
+
- 十三套离线测试全部通过。
|
|
201
|
+
|
|
202
|
+
## [0.6.2] — 2026-10-08
|
|
203
|
+
|
|
204
|
+
修两个 v0.6.1 之后报上来的布局问题:API 密钥模式的设置卡片被高度预算压扁、字段溢出到卡片外;桌面端左栏跟着列表一起滚走。
|
|
205
|
+
|
|
206
|
+
### 修复
|
|
207
|
+
|
|
208
|
+
- **API 密钥模式的设置表单不再「错位」**。滚动区是 `display:flex; flex-direction:column` 且带高度预算(`max-height: min(58vh, 560px)`),而 flex 子项默认 `flex-shrink: 1`:卡片内容比预算高时,**卡片盒子被压到预算高度,内容却继续画到卡片底衬之外**。API 密钥模式比主密码模式多两行(client_id / client_secret,各带一行说明),829px 高的窗口下 58vh 只有 480px,于是 client_secret、它的说明和按钮整块浮在弹窗底色上,读起来就像字段没有对齐。滚动区的直接子项现在一律 `flex: none`(新的 `S.scrollItem`),卡片按自身内容高度撑开,超出部分交给滚动区滚动——实测卡片 `clientHeight` 与 `scrollHeight` 相等,六个控件左缘与宽度完全一致。
|
|
209
|
+
- **桌面端左栏在列表滚动时固定不动**。左栏与列表同在一个滚动容器里,列表一长,左栏就跟着滚出视野。左栏改为 `position: sticky; top: 0`(位移空间由 `align-items: start` 的网格提供,且只有侧栏父级按内容自然高度排布时才有处可粘——这正是上一条修的事)。窄面板里左栏搬到顶部、成为普通内容,因此 `@container vw-panel (max-width: 480px)` 与无容器查询的 760px 窗口回退各显式写一条 `position: static !important`:**手机上这一栏要跟着列表滑动**,固定住反而把条目压在底下。
|
|
210
|
+
|
|
211
|
+
### 测试
|
|
212
|
+
|
|
213
|
+
- `test/client-card.test.mjs` 235 → 241 项:新增「滚动区子项保持自然高度」「设置卡片不会被压扁且仍限制宽度」「左栏在桌面端 sticky、窄面板规则里回到 static(含无容器查询回退那一份)」等断言;测试文件补了最小的 `document` 桩,用来接住 `ensureStyles` 注入的样式表文本——容器查询规则本来就只能这样验。
|
|
214
|
+
- 十三套离线测试共 647 → 653 项全部通过。
|
|
215
|
+
|
|
216
|
+
## [0.6.1] — 2026-10-07
|
|
217
|
+
|
|
218
|
+
修两个 v0.6.0 带出来的显示问题:侧栏图标与计数徽章重画,手机端工具栏错位;顺带修好站点图标不刷新与验证码行被切。
|
|
219
|
+
|
|
220
|
+
### 修复
|
|
221
|
+
|
|
222
|
+
- **站点图标现在会自己出现**。v0.6.0 的图标探测答回来时只把模块里的版本号 +1,而 React 看不见模块作用域变量的变化——于是行上一直留着首字母圆枕,直到碰巧有别的原因重绘(实测:在搜索框里多敲一个空格才出现)。`bumpIcons` 现在同时通知已挂载的面板,探测的答案本身就能唤醒那一行。新增回归测试走真实的 `Image` 加载路径(此前只有 `__setIcons` 预设答案的用例,恰好绕过这条链)。
|
|
223
|
+
- **验证码分区的行不再被切**。`listRow` 是 `width:100%` 加自身内边距:`<button>` 行从 UA 样式表拿到 border-box,而这一区的行是 `<div>`(行里不能再套按钮),少了 `boxSizing: 'border-box'` 就比列表宽 28px,复制按钮被切在面板右缘之外。桌面 800px 与手机 390px 都复现,现已修正并加断言。
|
|
224
|
+
- **手机端 设置/刷新 不再错位**。窄屏规则原先把工具栏最后一项整行铺满成第三行,两个按钮飘在半行空白下面。现在搜索框独占一行,下面一行左侧是同步胶囊、右侧是操作按钮(`@container vw-panel (max-width: 520px)` 与无容器查询回退各一份)。操作区加了 `data-vw-actions` 标记,规则按名字选中它而不是按位置。
|
|
225
|
+
|
|
226
|
+
### 变更
|
|
227
|
+
|
|
228
|
+
- **侧栏图标改为画出来的 SVG 线稿**(`NAV_ICON_SHAPES` → `navGlyph`,16×16、1.3px 描边、`currentColor`),替换 `▦ ★ ⏱ ◍ ▸ · ⌸ ⌫` 这些字体字符:字体字符的视觉大小与基线随宿主字体走(半个高度的三角挨着满高的方框,未归类的中间点落在文字基线上)。登录/安全笔记/银行卡/身份信息/SSH 密钥各有自己的记号,未知类型退到通用记号。图标是装饰(`aria-hidden`),颜色比标签浅一档,当前行加深。
|
|
229
|
+
- **计数改为统一的扁平药丸**:`min-width 22` / 高 20 / `border-radius: 999px` / `tabular-nums`,一位数的回收站与三位数的全部条目等重、数字对齐成一列;当前行的药丸反色成面板底色(bg-2 叠 bg-2 会看不见)。计数元素里始终只有裸数字,样式只是它外面的壳。
|
|
230
|
+
|
|
231
|
+
### 测试
|
|
232
|
+
|
|
233
|
+
- `test/client-card.test.mjs` 225 → 235 项:新增「图标是画出来的、每行一个 16×16 svg、是装饰」「计数药丸保留裸数字且满宽一致、当前行反色」「验证码行的 box-sizing 不会撑破列表」「探测答回来时那一行自己重绘(走真实 onload)」等断言。
|
|
234
|
+
- 十三套离线测试共 637 → 647 项全部通过。
|
|
235
|
+
## [0.6.0] — 2026-10-07
|
|
236
|
+
|
|
237
|
+
面板改成 Bitwarden App 那样的层级分区菜单,加分区缓存、站点图标与桌面布局;宿主侧新增 `vw/overview`,`vw/list` 支持按分区取数。
|
|
238
|
+
|
|
239
|
+
### 新增
|
|
240
|
+
|
|
241
|
+
- **层级分区菜单**:左栏按 Bitwarden App 的组织方式列出**全部条目 / 收藏 / 验证码**三行,然后是「类型 (n)」(登录、安全笔记、银行卡、身份信息、SSH 密钥)与「文件夹 (n)」(各文件夹 + 未归类)两组,最后是「归档」「回收站」;每行右侧写明条数,当前分区带 `aria-current` 高亮。点一行即把列表切成那个分区。
|
|
242
|
+
- **宿主侧分区取数**:新增 `vw/overview`(分区计数 + 类型/文件夹分组,一次取回侧栏要的全部数字;类型与文件夹都只数**未归档**的那半,因为分区读也只给这半——徽标不能承诺点进去看不到的行);`vw/list` 增加 `section` / `sectionValue` 参数,由宿主先把整个库收窄到该分区的池子、再计数、再分页——侧栏上的数字和点进去看到的条目数因此永远一致,分页也只在该分区内翻。旧版做法(把整窗结果拿到前端过滤)会让计数与游标描述一个没人看见的列表。
|
|
243
|
+
- **分区缓存**:切回刚离开的分区时,若该分区快照在 5 分钟内(`SECTION_CACHE_MS`)就直接重绘、**零 RPC**;首次进入某分区仍是「先画后拉」。搜索、刷新按钮与写操作一律绕过缓存。分页游标与「还有 N 条」状态随分区一起重置。同一份列表 memo 的键补上了分区(原先只有一个槽位,换分区会把上一区的行漏进下一区)。
|
|
244
|
+
- **服务端站点图标**:列表行改用 Bitwarden 服务端已缓存的 favicon(`<serverUrl>/icons/<host>/icon.png`,服务器返回 `cache-control: immutable`)。图标通过 `<img>` 加载——面板里 `fetch()` 会被宿主的 URL 白名单挡掉;加载失败或像素小于 24px 的行退回原来的首字母圆枕(纯数字名如 IP 不会退化成同一个「1」)。
|
|
245
|
+
- **验证码分区行**:进入「验证码」分区后,每行是 App 的形态——图标 + 名称 + 用户名 + 30px 倒计时圆环 + 分组的 6 位动态码(`686 029`)+ 复制按钮;点码复制而不会打开条目,动态码只在画出来的这几行里每秒请求。
|
|
246
|
+
|
|
247
|
+
### 变更
|
|
248
|
+
|
|
249
|
+
- **桌面布局:侧栏常驻 + 内容区单栏**。打开条目时列表让位给详情(列表上方留「‹ 返回列表」),侧栏始终可见,不再是手机式的「点进去换屏」。
|
|
250
|
+
- **断点改用 CSS 容器查询**(`@container vw-panel`):宿主设置弹窗宽度固定在 800px(其中约 280px 是宿主的设置导航),面板自己只拿到 ~560px——按窗口宽度判断会永远判成「桌面」,把 377px 的内容列再拆两半,两边都窄到读不出一行值。现在断点跟着**面板自身**的宽度走:`<480px` 侧栏才搬到顶部、钻取时藏侧栏,`<620px` 字段标签列从 92px 收到 72px。不支持容器查询的浏览器回退到 `@supports not (container-type: inline-size)` + 760px 窗口断点。
|
|
251
|
+
- 面板主区从「列表 + 详情两列并排」改为内容列内切换(`S.split` 单轨),删除不再使用的 `splitAlone` 与死样式 `panelBody`。
|
|
252
|
+
- 侧栏 184px(`minmax(150px, 184px)`),内容列吃满剩下的宽度——宿主弹窗就这么宽,先保证两栏都读得出来。
|
|
253
|
+
- 老宿主降级:`vw/overview` 不可用时侧栏只渲染「全部条目」一行,列表与搜索照常工作。
|
|
254
|
+
|
|
255
|
+
### 测试
|
|
256
|
+
|
|
257
|
+
- `test/client-card.test.mjs` 217 → 225 项:新增侧栏分区导航(分区行与计数、分组标题、`aria-current`、进入分区时 `section`/`sectionValue` 真的传到 RPC、**切回命中快照零 RPC**、老宿主只剩「全部条目」一行)、服务端图标(命中出 `<img>` 且 `src` 正确、`none` 退回字母圆枕)、验证码分区行(3+3 分组、圆环、复制按钮)等断言;回收站条目改为从侧栏进入;`makeRpc` 增加 `vw/overview` 路由并让 `list` 按分区取池。
|
|
258
|
+
- `test/mock-e2e.test.mjs` 42 → 54 项:新增侧栏分区段(计数、分区读与 `overview.types` 一致、memo 不跨分区漏行)。
|
|
259
|
+
- `test/gateway-flow.test.mjs` 67 → 73 项:新增分区读(类型/文件夹/未归类/回收站四种 `section` 真的收窄池子、归档行不出现在任何分区读里)与「徽标数与分区读数一致」的断言;`test/host-entry.test.mjs` 的线面方法白名单增至 20 个。
|
|
260
|
+
- 十三套离线测试共 637 项全部通过。
|
|
261
|
+
## [0.5.3] — 2026-10-07
|
|
262
|
+
|
|
263
|
+
把动态码那行的 30 秒横条换成会缩短的圆环,并按剩余时间连续换色。
|
|
264
|
+
|
|
265
|
+
### 变更
|
|
266
|
+
|
|
267
|
+
- **动态码倒计时改为圆环**:详情页「动态码」一行右侧原先是一条 4px 横进度条加一个秒数——两段式读法,先看条再读秒。现在是一个 30px 的 SVG 圆环(r12、3.5px 描边、`stroke-dashoffset` 驱动),剩余秒数写在环心;环随剩余时间逐秒缩短,1 秒一格的 `stroke-dashoffset` 过渡让弧线扫过去而不是跳格。`role="img"` + `aria-label`「动态码剩余 N 秒」——颜色不是唯一信号;`prefers-reduced-motion` 下退化为逐格步进。
|
|
268
|
+
- **颜色改为连续渐变,末端落到红**:三档色块(绿/橙/黄)换成 `rampTone()` 的两段插值——剩余 ≥50% 纯绿,50%→20% 用 `color-mix()` 从绿混到橙,20%→0 从橙混到红,最后一秒落在 `state-error` 令牌上。两侧都是 `var()` 链(明暗主题各自解析),JS 无法算色,所以交给 `color-mix()` 让浏览器插值;不支持 `color-mix()` 的浏览器取就近端点,而不是丢掉描边把环画没。
|
|
269
|
+
|
|
270
|
+
### 测试
|
|
271
|
+
|
|
272
|
+
- `test/client-card.test.mjs` 204 → 217 项:新增圆环回归(三档色令牌 `--vw-ok`/`--vw-warn`/`--vw-err`、`stroke-dashoffset` 与 `2πr` 的换算、环心秒数与 `aria-label`、偏移随秒数单调递增、样式表含 1s 线性过渡与 `prefers-reduced-motion` 覆盖),并要求不支持 `color-mix()` 时环色退化为就近端点而不是消失、渐变终点是 error 令牌而非第三种平色(反向守卫 `--vw-amber`)。
|
|
273
|
+
- 十三套离线测试共 610 项全部通过。
|
|
274
|
+
|
|
275
|
+
## [0.5.2] — 2026-10-07
|
|
276
|
+
|
|
277
|
+
修两个面板缺陷(动态码、搜索闪烁),并把 peer 范围补到当前运行时。
|
|
278
|
+
|
|
279
|
+
### 修复
|
|
280
|
+
|
|
281
|
+
- **动态码恒显「—」**:详情页那行读的是 `value.totpSecret`,而种子的投影从不跨 RPC 边界(`totpSecret` 是投影内部字段),宿主也没在 `vw/reveal` 的 `all` 投影里给出任何「有没有第二因子」的信号——门永远为假,每个带动态码的条目都显示一个破折号。宿主现在随投影带一个布尔 `hasTotp`(种子仍在宿主内),面板据此开合该行。
|
|
282
|
+
- **搜索框每敲一个字整块白屏**:按键触发的重查会把状态推回 `loading`,整个行列表被「正在读取」占位替换,工具栏(连同搜索框本身)跟着卸载——一次按键就是一次整页闪。现在加了 `refreshing` 状态:旧行留在屏幕上,工具栏与搜索框挂载一次就不再卸载,等答复落地再整体替换;计数格改为播报「正在刷新…」。
|
|
283
|
+
|
|
284
|
+
### 测试
|
|
285
|
+
|
|
286
|
+
- `test/client-card.test.mjs` 194 → 204 项:新增「按键不得清空列表」回归(挂起中的搜索请求期间旧行留屏、无占位、搜索框存活、刷新提示到位、答复落地后行被替换、提示消失),并要求 reveal 夹具只带 `hasTotp` 布尔、绝不带种子。
|
|
287
|
+
- `test/peer-ranges.test.mjs` 31 → 34 项:**peer 范围补上 0.2.1 线与 3.18.5 / 4.0.5 预发布分支**。原先 `@deepseek-ai/cordis` 的 `>=4.0.1-rc.1 <5` 按 npm 的预发布规则并不放行运行时实际带的 `4.0.5-alpha.1`,`npm install` 路径会 `ERESOLVE`;`@deepseek-ai/dsh-tools` / `dsh-typert-protocol` 同样漏了 `^0.2.1-0`,`schemastery` 漏了 `^3.18.5-0`。四条范围现在各自接纳已发布的全部受支持构建,`0.0.1-rc.*` 与 `0.3.0`+ 仍被拒。
|
|
288
|
+
- 十三套离线测试共 597 项全部通过。
|
|
289
|
+
|
|
290
|
+
## [0.5.1] — 2026-10-06
|
|
291
|
+
|
|
292
|
+
修一处 v0.5.0 的排序回归:打开回收站筛选后,软删条目并没有像说明那样排在列表最前。
|
|
293
|
+
|
|
294
|
+
### 修复
|
|
295
|
+
|
|
296
|
+
- **回收站条目没有排到列表最前**:`findEntries` 把回收站条目拼在正常条目之前,但紧接着的排序是「分数 → 名称」两级比较器,名称 tiebreak 让「拼在前面」失效(稳定排序只在比较器返回 0 时保留输入顺序),空查询下软删条目按名字混在正常条目里,大库中落到第一页之外——面板点开「回收站 {n}」chip 后第一屏看不到任何回收站条目。现在回收站标志写进比较器本身(分数 → 回收站 → 名称),软删条目稳定领先合并列表。
|
|
297
|
+
|
|
298
|
+
### 测试
|
|
299
|
+
|
|
300
|
+
- `test/write-back.test.mjs` 46 → 48 项:新增「回收站条目领先合并列表、其余条目保持原顺序」两处检查;修复前该用例失败(`46 passed, 2 failed`)。
|
|
301
|
+
- 十三套离线测试共 584 项全部通过。
|
|
302
|
+
|
|
303
|
+
## [0.5.0] — 2026-10-06
|
|
304
|
+
|
|
305
|
+
v0.4.0 攒下的读写能力搬进面板:条目页能归档、移入回收站、恢复、移动文件夹,列表页有回收站与归档筛选,详情页补齐五类条目的投影。
|
|
306
|
+
|
|
307
|
+
### 新增
|
|
308
|
+
|
|
309
|
+
- **面板写操作(归档/取消归档、移入回收站、恢复、移动文件夹)**:详情页新增「操作」区,按条目当前状态给按钮——普通条目给归档、移入回收站、移动文件夹,归档条目给取消归档,回收站条目只给恢复。每个动作都过一道确认框,框内固定写着「面板操作不受 accessMode 门禁保护,请谨慎操作。」;`readonly` 档不显示任何按钮,只留一行说明。写操作进行中/完成/失败各有一行状态,失败按 `stale_revision` 等错误码翻译。
|
|
310
|
+
- **回收站独立入口**:列表上方新增筛选行,「回收站 {n}」chip 显示回收站条数(来自 `vw/status`),点开后软删条目排到列表最前、条目名划掉并带「回收站」徽标;选中后可查看内容并就地恢复。回收站为空、筛选无结果各有专门的空态提示。
|
|
311
|
+
- **文件夹与归档筛选**:筛选行里还有文件夹下拉(全部文件夹/未归类/各文件夹)与归档三档(含归档/只看归档/隐藏归档),改动即重查;任一筛选生效时出现「清除筛选」。文件夹筛选只过滤已取回的这一窗条目,不改变宿主侧的分页游标。
|
|
312
|
+
- **五类条目详情投影**:信用卡(卡号掩码、持卡人、品牌、有效期、安全码)、身份信息(姓名/邮箱/电话/地址)、SSH 密钥(公钥与指纹明文,私钥掩码可显示);带通行密钥的条目显示「含通行密钥」徽标。
|
|
313
|
+
- **附件与密码历史折叠区**:附件列出文件名与大小(只显示信息,不下载内容);历史密码按最近使用时间列出,不显示明文。
|
|
314
|
+
- **回收站横幅与会话事件行**:回收站条目的详情页顶部有「该条目在回收站中(软删除)」横幅;同步徽标悬停详情新增一行后台会话事件(重新登录/被拒/需两步验证),不再只有 token 倒计时。
|
|
315
|
+
|
|
316
|
+
### 修复
|
|
317
|
+
|
|
318
|
+
- **`vw/folders` 返回未解析的 JSON 字符串**:`VaultGateway.folders()` 把 `folderList()` 的 JSON 文本原样透传给调用方。v0.4.0 起一直没有消费方所以没暴露;面板文件夹筛选是第一个消费方,顺手修掉。
|
|
319
|
+
|
|
320
|
+
### 变更
|
|
321
|
+
|
|
322
|
+
- **网关读参数透传**:`vw/list` 增加 `includeArchived` / `includeTrashed`(缺省仍含归档),`vw/reveal` 增加 `includeTrashed`。回收站条目此前只能靠 `vw/status` 的计数看到,现在能直接读、能恢复。
|
|
323
|
+
- **`findEntries` 支持回收站**:`options.includeTrashed` 参与结果合并与记忆键;回收站条目排在结果最前,空查询时不会落到第一页之外。
|
|
324
|
+
|
|
325
|
+
### 测试
|
|
326
|
+
|
|
327
|
+
- `test/client-card.test.mjs` 145 → 194 项:筛选行(chip 计数与勾选、文件夹与归档筛选、清除筛选)、写操作全链路(确认框文案、`archived`/`folderId`/软删参数、回收站条目 `includeTrashed`、`readonly` 只读说明)、五类条目详情与折叠区。
|
|
328
|
+
- `test/gateway-flow.test.mjs` 52 → 67 项:读/写参数透传(归档与回收站开关真正到达后端、回收站条目要 `includeTrashed` 才能读、`vw/folders` 返回解析后的对象、软删与恢复走通网关)。
|
|
329
|
+
- `test/host-entry.test.mjs` 线面方法白名单 16 → 19(补 `boot`/`restore`/`folders`)。
|
|
330
|
+
- 十三套离线测试共 582 项全部通过。
|
|
331
|
+
|
|
332
|
+
## [0.4.0] — 2026-10-06
|
|
333
|
+
|
|
334
|
+
实现《dsh-vaultwarden 缺失功能优先级排序》里的全部 6 项 P0 与 8 项 P1:写回不再丢字段,删除链路可回滚,回收站有出口,写回带并发保护,五类条目都能读写,文件夹 id 可见可清。
|
|
335
|
+
|
|
336
|
+
### 修复
|
|
337
|
+
|
|
338
|
+
- **软删实际是彻底删除(P0)**:`remove()` 的非 permanent 分支原来请求 `POST /api/ciphers/{id}/delete`——在 Vaultwarden 里这是**彻底删除**,条目从数据库直接消失,插件却回复"已进入回收站"。现在软删改走 `PUT /api/ciphers/{id}/delete`;`permanent: true` 走 `DELETE` 且必须同时传 `confirm: true`,否则拒绝并在响应里说明。`test/mock-server.mjs` 同步改成分支语义(它此前把 POST 实现成软删,正是这条错误一直没被测试发现的原因)。
|
|
339
|
+
- **写回静默丢字段(P0)**:写回改为**复用条目原有的 item key**,只对本次变更的字段重新加密,其余键原样带回——`login.fido2Credentials`(通行密钥)、`passwordHistory`、`login.passwordRevisionDate`、`login.uri`(单数旧字段)、`uris[].match` 匹配策略、`archivedDate`、附件元数据都不再丢。此前任何一次改密都会顺手抹掉前五类数据,且没有任何提示。
|
|
340
|
+
- **写回覆盖并发修改(P0)**:PUT 现在带 `lastKnownRevisionDate`;服务端发现条目已被其他客户端改过时返回 400,插件翻译成"条目已被其他客户端修改,请重新读取后再试"(`stale_revision`)。
|
|
341
|
+
- **非 login 类型不能读写(P0)**:`type` 不再硬编码为 1,支持 `secureNote`/`card`/`identity`/`sshKey` 的创建与更新,读侧同步投影这四类内容。安全笔记的 `type` 是明文 JSON 而不是 EncString,按官方格式单独处理(加密它会让官方客户端读到乱码)。
|
|
342
|
+
- **文件夹 id 出不来、清不掉(P0)**:列表投影 `folderId`,新增 `bitwarden_folders`(id + 名字 + 条目数 + 未归类条数);`folderId` 三态——不传=不动、传 id=移入、传 `null` 或空串=移出(原来的 `??` 回退让"移出"永远失败)。
|
|
343
|
+
- **回收站没有出口(P0)**:`bitwarden_find`/`bitwarden_get` 加 `includeTrashed`,`bitwarden_status` 报回收站与归档条数,新增 `bitwarden_restore` 工具与 `vw/restore` RPC。后端 `restore()` 早已实现,只是没有暴露。
|
|
344
|
+
- **归档条目混在正式列表里(P1)**:投影 `archived`;`bitwarden_find` 默认排除归档并提示"还有 N 条归档",`includeArchived` 可查;`bitwarden_update` 支持归档/取消归档。此前写回还会把归档条目悄悄拽出归档(服务端把"没带 archivedDate"解释为取消归档)。
|
|
345
|
+
- **令牌失效后的后台兜底登录没有状态(P1)**:重新登录成功、失败、被拒绝、需要两步验证都会记录 `lastSessionEvent`,`bitwarden_status` 与面板状态接口都会带上;失败后有 60 秒冷却,不对同一个失效会话反复重试。
|
|
346
|
+
- **网关 `configure` 会静默丢掉 `ask` 档**:accessMode 白名单以前内联写成 `readonly || auto`,`ask` 传进来会被忽略;现在统一为 `['readonly', 'ask', 'auto']`。
|
|
347
|
+
|
|
348
|
+
### 新增
|
|
349
|
+
|
|
350
|
+
- **`encryptedFor` 写回字段(P1)**:创建与更新都带当前用户 uuid。Vaultwarden main 已把它列为必填(PR #7693),不带的话升级到该版本后所有写回会整条 422。
|
|
351
|
+
- **附件与密码历史读取(P1)**:投影 `attachments`(文件名、大小、下载地址,不下载内容)与 `passwordHistory`(含 `lastUsedDate`),并用 `hasFido2` 标记条目是否带通行密钥。
|
|
352
|
+
- **组织条目写入(P1)**:创建组织条目传 `organizationId` + `collectionIds` 走 `POST /api/ciphers/create`,字段用组织密钥包裹;更新组织条目复用组织密钥与条目原 key。
|
|
353
|
+
- **文件夹工具与回收站/归档开关**:全局工具 7 → 9(新增 `bitwarden_folders`、`bitwarden_restore`)。
|
|
354
|
+
- **面板归档徽标**:面板列表保留显示归档条目并带「已归档」徽标(模型侧搜索默认不返回归档)。
|
|
355
|
+
|
|
356
|
+
### 变更
|
|
357
|
+
|
|
358
|
+
- **写回权限门禁下沉**:readonly 档的拒绝判断从工具包装层下沉到 `VaultMutations` 的 guard(`write_disabled`),工具层与网关层共用同一个判断;`ask` 档的审批流程不变。
|
|
359
|
+
- **落盘缓存加完整性校验**:密文缓存用 HMAC-SHA256 签名(密钥 `~/.dsh/data/dsh-vaultwarden/cache.key`,0600,随机 32 字节),并严格比对服务器地址与邮箱;缓存版本升到 2,未签名、签名不符或账号不匹配的缓存一律丢弃重下。
|
|
360
|
+
- **协议事实修正**:Vaultwarden 的 `/api/sync` 没有 `syncToken` 增量(1.37.3 的 `SyncData` 只有 `excludeDomains` 一个参数),"协议支持增量同步"的说法不成立;当前实现是"密文落盘缓存 + 13 字节修订号探针 + 需要时全量下载"。
|
|
361
|
+
- **构建脚本修一处漏链**:`scripts/build.sh` 在两处 `npm install` 之后的补链只写了三个包,漏了 `@deepseek-ai/dsh-typert-protocol`;npm 会剪掉不是自己建立的符号链接,于是**全新检出**跑 build.sh 会在 host-entry 套件以 `ERR_MODULE_NOT_FOUND` 中断(本仓库工作区因为第一次链接没被剪过,一直没暴露)。改为把 peer 清单提成 `PEERS` 并用 `relink_peers()` 全量重链。
|
|
362
|
+
|
|
363
|
+
### 测试
|
|
364
|
+
|
|
365
|
+
- 新增第十三套离线测试 `test/write-back.test.mjs`(46 项):软删端点与回收站可见性、字段保真(通行密钥/密码历史/URI 匹配策略/附件/归档日期/原 key 不轮换)、并发 400 的翻译、文件夹三态、归档开关、面板列表缓存。
|
|
366
|
+
- `test/mutations.test.mjs` 扩到 38 项:五类条目的创建与更新、组织条目更新、软删/恢复/彻底删除的确认、旧版(账号键)条目的写回。
|
|
367
|
+
- `test/mock-server.mjs` 对齐真实服务端语义:`POST /delete` 改回彻底删除,新增 `PUT /delete`(软删)与 `PUT /restore`;PUT 保留请求未带的附件;新增 `richCipher` 夹具(通行密钥/密码历史/匹配策略/附件/归档)。
|
|
368
|
+
- 十三套离线测试共 518 项全部通过。
|
|
369
|
+
|
|
370
|
+
## [0.3.2] — 2026-10-05
|
|
371
|
+
|
|
372
|
+
### 修复
|
|
373
|
+
|
|
374
|
+
- **Argon2id 账号永远登录失败(P0)**:`kdfMemory` 的单位是 MiB(Bitwarden/Vaultwarden 默认 64),而 `hash-wasm` 的 `memorySize` 按 KiB 计数。此前把 64 直接当成 64 KiB 交给 KDF,派生出完全错误的主密钥,服务器按「邮箱或主密码不正确」拒绝——用户看到的是密码错,实际是单位错。现在统一 ×1024(`lib/vault.js` 的 `deriveMasterKey`),mock 服务端同步修正,并新增固定向量测试锁死两家单位(见下)。
|
|
375
|
+
- **「确认读取」的迟到答复会串条目(P0)**:为条目 B 点「确认读取」后立刻切到条目 A,B 的明文密码会被画进 A 的详情面板,且 `revealed` 标志遗留,A 自己的密码会随后直接显示。详情面板现在按「选中项世代号」判定,迟到的答复(含失败分支)一律丢弃。
|
|
376
|
+
- **被放弃的列表查询会覆盖新查询**:快速改搜索词时,先发后到的旧答复会把旧行画上屏幕,首屏还会把这批旧行写进 localStorage 快照。`readVault` 现在在写入 state 前比对世代号,过期答复(含错误分支)直接返回。
|
|
377
|
+
- 前端套件在缺少 `react` / `react-test-renderer` 时打印一行「skipping」后以退出码 0 结束,等于把 129 项面板检查静默变成「全绿」。现在报错并非零退出,缺依赖就是失败。
|
|
378
|
+
|
|
379
|
+
### 测试
|
|
380
|
+
|
|
381
|
+
- 新增第十二套离线测试 `test/kdf-units.test.mjs`(13 项):用固定摘要同时锁住 Argon2id 的正确单位(64 MiB 对应 `memorySize: 64 * 1024`)与旧错误单位(64 KiB),并交叉验证 mock 服务端、`hash-wasm` 直接调用与 `node:crypto` 的 PBKDF2 结果。
|
|
382
|
+
- `test/client-card.test.mjs` 增加两处竞态回归(129 → 142 项):换条目后迟到的「确认读取」不得画进新条目、被放弃查询的迟到行不得覆盖新查询也不得写进快照。
|
|
383
|
+
- 十二套离线测试共 444 项全部通过。
|
|
384
|
+
|
|
385
|
+
## [0.3.1] — 2026-10-02
|
|
386
|
+
|
|
387
|
+
### 修复
|
|
388
|
+
|
|
389
|
+
- 换令牌失败不再无差别删除会话:只有服务器**明确拒绝** refresh token(`invalid_grant` / 401)才清除盘上会话;断网、超时、429 限流、5xx 一律保留内存令牌与 `session.json`。此前任何一种失败都会删掉整份会话,于是一次网络抖动就导致下次打开必须重输主密码 + 验证码——这就是「重启一次输一次密码」的来源。
|
|
390
|
+
- 后台换令牌失败改为向上抛错,不再掉进「用主密码重新登录」:两步验证账号不会因为一次网络错误被拖到验证码界面;网络恢复后下一次使用静默续上。
|
|
391
|
+
- 新增会话丢失诊断:会话被服务器拒绝而清除时记录 `lastSessionLoss`(时间、原因、服务器消息),面板状态接口与 `bitwarden_status` 都会带上它,回答「为什么又让我输密码」。
|
|
392
|
+
|
|
393
|
+
### 测试
|
|
394
|
+
|
|
395
|
+
- 新增第十一套离线测试 `test/session-resilience.test.mjs`(22 项):断网 / 429 / 5xx 下 `resumeSession()`、`boot()`、`ensureToken()` 均保留会话与 refresh token、不发密码授权;网络恢复后复用同一 refresh token 静默续上;服务端明确拒绝时才清盘,且之后仍可重新登录。
|
|
396
|
+
|
|
397
|
+
## [0.3.0] — 2026-10-02
|
|
398
|
+
|
|
399
|
+
### 新增
|
|
400
|
+
|
|
401
|
+
- 密文落盘缓存:每次成功同步后,把服务器**原样返回的密文**(不是明文)gzip 后写到 `~/.dsh/data/dsh-vaultwarden/vault-cache.json.gz`(权限 `0600`,先写临时文件再原子改名)。下次冷启动先读这份缓存,列表立刻出来,不必等整份保险库下载完。
|
|
402
|
+
- 账号修订号探针:出完缓存后向服务器问一次 `GET /api/accounts/revision-date`(响应只有 13 字节)。**修订号没变就完全不下载**(省掉一次约 660 KB 的 `/api/sync`);变了才在后台全量同步一次并刷新缓存,界面先显示旧数据、随后无缝换成新的。
|
|
403
|
+
- 新设置项 `localCache`(默认开启):关掉则每次启动都重新全量下载,行为与 0.2.7 一致;登出、切换账号、关闭该开关都会立即删掉缓存文件。
|
|
404
|
+
- 缓存信任上限:缓存超过 **7 天**未更新时,即使探针说没变也强制全量同步一次(兜住上游可能漏推修订号的边缘路径);探针报错、缓存损坏、解密失败一律退回全量下载。
|
|
405
|
+
- 状态报告新增 `cached` 与 `cache` 两个字段(是否来自缓存、缓存开关/文件/写入时间/记录的修订号),`syncedAt` 在缓存命中时报告的是缓存写入时间。
|
|
406
|
+
|
|
407
|
+
### 测试
|
|
408
|
+
|
|
409
|
+
- 新增第十套离线测试 `test/cache-store.test.mjs`(61 项):缓存读写与权限、账号/版本/损坏数据的拒绝、7 天信任窗口边界、以及 VaultClient 的完整路径——冷启动写缓存、热启动跳过下载、修订号变化后台补一次、探针失败保留缓存但不再授权快路径、超 7 天强制全量、换账号与登出清文件、关闭 `localCache` 不落文件也不发探针。
|
|
410
|
+
- mock 服务端实现 `/api/accounts/revision-date` 路由,并提供 `revision()` / `bumpRevision()` / `failRevision()` 三个测试挂钩。
|
|
411
|
+
- 十套离线测试共 396 项全部通过(未安装官方 `bw` CLI 时 `cli-interop` 自跳过)。
|
|
412
|
+
|
|
413
|
+
## [0.2.7] — 2026-10-01
|
|
414
|
+
|
|
415
|
+
### 新增
|
|
416
|
+
|
|
417
|
+
- 条目列表渐进式加载:首屏一次只取 50 条,向下滚动自动续读下一页;滑得比加载快时,尾部出现「还有 N 条,点击继续显示」按钮兜底。宿主不接受分页参数时自动回退为整表读取(上限 200,与旧版一致)。
|
|
418
|
+
- 条目列表支持 `offset` 分页参数,`vw/list` 返回 `offset` 与 `hasMore`。
|
|
419
|
+
|
|
420
|
+
### 修复
|
|
421
|
+
|
|
422
|
+
- 修掉「点加载点不动」:宿主一次最多取 200 条时,之前给出的「还有 N 条」按钮再点也只会读回同样 200 条。现在改为就地提示「本机只同步到 200/总数 条,其余请在 Bitwarden 网页端查看」,不再提供点了没有反应的按钮。
|
|
423
|
+
- 旧宿主不支持分页参数时不再停在「50 行 + 点不动的按钮」,自动回退为整表读取。
|
|
424
|
+
- 拒绝分页的宿主会被记住:本次会话内下次打开面板直接整表读取,不再先画 50 行、再被拒、再重画一遍。
|
|
425
|
+
- 修复旧宿主上打开面板可能直接报错的问题:现在按网关的错误码判断,能正确回退;宿主明确拒绝调用时仍照常报错。
|
|
426
|
+
- 修复分页续读可能错位、漏条目的问题:上游在两页之间新增条目时,续读位置跟住宿主上报的窗口端点。
|
|
427
|
+
- 修复面板在续读途中关闭时留下无人回收的读取。
|
|
428
|
+
|
|
429
|
+
### 测试
|
|
430
|
+
|
|
431
|
+
- 客户端组件测试覆盖分页场景(129 项,原 85):首屏 50 行、滚动续读、滑得比加载快时出按钮、旧宿主拒绝分页参数后回退整表、页读失败保留列表、无布局度量时滚动不发请求、窗口漂移时续读不重不漏、废弃列表的迟到页不写入新列表、200 条上限截断时改显示诚实提示且不再重试、拒绝分页的宿主下次打开直接整表、无此方法与拒绝调用的边界。
|
|
432
|
+
- mock-e2e 新增分页断言(41 项,原 38);gateway-flow 新增分页参数透传断言(52 项,原 51)。
|
|
433
|
+
- 八套离线测试共 335 项全部通过(未安装官方 `bw` CLI 时 `cli-interop` 自跳过)。
|
|
434
|
+
|
|
435
|
+
## [0.2.6] — 2026-10-01
|
|
436
|
+
|
|
437
|
+
### 新增
|
|
438
|
+
|
|
439
|
+
- 插件列表显示彩色图标:双层盾牌(紫 #6C4DF6 + 蓝 #2E6BE6)配白色镂空钥匙孔,与官方插件同一套 artwork 规范(包根 icon.svg + package.json icon 字段)。
|
|
440
|
+
- 设置页「凭证据库」一行换成插件自己的盾牌图标,不再用宿主默认齿轮;图标随行内文字流式排布,桌面列与移动 tab 条都不错位、不夺位。
|
|
441
|
+
- 设置页图标跟随行文字颜色,明暗双主题无需额外处理。
|
|
442
|
+
|
|
443
|
+
### 测试
|
|
444
|
+
|
|
445
|
+
- Host 入口测试新增插件列表图标契约断言(27 项,原 23)。
|
|
446
|
+
- 客户端组件测试覆盖设置行盾牌图标(85 项,原 83)。
|
|
447
|
+
- 全套测试 287 项,8 个文件全部通过。
|
|
448
|
+
|
|
449
|
+
## [0.2.5] — 2026-10-01
|
|
450
|
+
|
|
451
|
+
### 新增
|
|
452
|
+
|
|
453
|
+
- 打开凭据库面板自动恢复登录:访问令牌过期或重启后,直接用已保存的会话自动续期,不再要求重新登录。
|
|
454
|
+
- 打开面板立即显示条目:列表先渲染本地快照,再后台从服务器刷新。
|
|
455
|
+
- 插件启动即预热:插件加载时就在后台恢复会话、填充解密缓存,重启后第一次打开面板不再等待。
|
|
456
|
+
- 新增 `vw/boot` 接口:一次请求同时拿到配置与登录状态;不支持的旧宿主自动回退原逻辑,条目列表照常打开、不要求登录。
|
|
457
|
+
- 列表读取与连接状态探测并行执行,探测失败不再拖累列表。
|
|
458
|
+
|
|
459
|
+
### 修复
|
|
460
|
+
|
|
461
|
+
- 修复每隔一小时就要求重新登录的问题。
|
|
462
|
+
- 修复已保存的会话被误删、每次登录都要重输两步验证码的问题。
|
|
463
|
+
- 修复旧宿主上打不开条目列表的问题。
|
|
464
|
+
|
|
465
|
+
### 测试
|
|
466
|
+
|
|
467
|
+
- 客户端组件测试改用 `boot` 接口(83 项,原 72),覆盖快照先渲染、登出后不渲染列表等场景。
|
|
468
|
+
- 网关流程测试新增 `boot` 一节(51 项,原 35),含旧宿主回退两条断言(仍能打开列表、不要求登录)。
|
|
469
|
+
- 全套测试 279 项,8 个文件全部通过。
|
|
470
|
+
|
|
471
|
+
## [0.2.4] — 2026-09-30
|
|
472
|
+
|
|
473
|
+
Installable again from npm. No breaking changes.
|
|
474
|
+
|
|
475
|
+
### Fixed
|
|
476
|
+
|
|
477
|
+
- **`npm install` failed with `ERESOLVE` against every current DSH build.**
|
|
478
|
+
Every published `@deepseek-ai/dsh-*` build is a prerelease, and npm only
|
|
479
|
+
admits a prerelease when the range carries an explicit branch for its
|
|
480
|
+
`major.minor.patch` tuple. `>=0.1.0-rc.1 <0.3.0-0` therefore admitted 5 of
|
|
481
|
+
the 30 published `@deepseek-ai/dsh-tools` builds and rejected the rest,
|
|
482
|
+
including the harness this plugin runs on. The harness loader itself checks
|
|
483
|
+
peers with `{ includePrerelease: true }`, so nothing failed at load time —
|
|
484
|
+
only the npm path, which is exactly the path the marketplace falls back to.
|
|
485
|
+
Both `@deepseek-ai/dsh-tools` and `@deepseek-ai/dsh-typert-protocol` now
|
|
486
|
+
enumerate the published release lines (`^0.1.0-0 || … || ^0.2.0-0`), which
|
|
487
|
+
admits 26 of 30 builds — everything from the 0.1.0 line onward.
|
|
488
|
+
- **`@deepseek-ai/schemastery` had the same trap.** `^3.18.0` rejected the
|
|
489
|
+
published `3.18.1-rc.1` / `3.18.1-rc.4` builds; the range now carries a
|
|
490
|
+
`^3.18.1-0` branch and admits all six published versions.
|
|
491
|
+
- **The `cordis` peer named a package the runtime does not ship.** The
|
|
492
|
+
declaration was the bare name `cordis` (an unrelated npm package, and not
|
|
493
|
+
installed anywhere in a DSH tree), so the peer could never resolve; it is
|
|
494
|
+
now `@deepseek-ai/cordis` with the range `>=4.0.1-rc.1 <5`, which admits
|
|
495
|
+
every published build and refuses `4.0.0-rc.x` / `5.x`.
|
|
496
|
+
|
|
497
|
+
### Added
|
|
498
|
+
|
|
499
|
+
- **`test/peer-ranges.test.mjs`** — a manifest guard that resolves a semver
|
|
500
|
+
copy from the local DSH installation, checks every peer range against the
|
|
501
|
+
hard-coded `npm view <pkg> versions` fixtures, and pins the versions that
|
|
502
|
+
must stay refused (`0.0.1-rc.*`, `0.3.0`, `4.0.0-rc.10`, `5.0.0`, …). It
|
|
503
|
+
fails with 13 checks against the previous manifest and passes against the
|
|
504
|
+
new one, so the trap cannot come back unnoticed. Skips itself (exit 0) when
|
|
505
|
+
no DSH installation is reachable, like the CLI interop suite.
|
|
506
|
+
|
|
507
|
+
### Notes
|
|
508
|
+
|
|
509
|
+
- The version lists in the guard are fixtures, not a live lookup: update them
|
|
510
|
+
when the harness publishes a release.
|
|
511
|
+
- 252 offline tests across eight suites (`bash scripts/build.sh`).
|
|
512
|
+
|
|
513
|
+
## [0.2.3] — 2026-09-29
|
|
514
|
+
|
|
515
|
+
Panel copy and phone layout. No breaking changes.
|
|
516
|
+
|
|
517
|
+
### Changed
|
|
518
|
+
|
|
519
|
+
- **The title is just "Bitwarden 凭据库".** The old
|
|
520
|
+
"Bitwarden / Vaultwarden 凭据库" spent the whole heading on two product
|
|
521
|
+
names. Vaultwarden support now rides alongside in small type
|
|
522
|
+
(`(支持 Bitwarden / Vaultwarden)`), which says the same thing without
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-vaultwarden contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|