dsh-vault 1.5.0 → 1.6.0-rc.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-zh.md +3 -0
- package/README.md +3 -0
- package/lib/client.js +126 -78
- package/lib/client.js.map +1 -1
- package/lib/index.js +172 -20
- package/lib/store.js +59 -1
- package/package.json +1 -1
package/README-zh.md
CHANGED
|
@@ -51,6 +51,9 @@ dsh-vault 是一个面向 DeepSeek Harness 的安全加密插件:把你在使
|
|
|
51
51
|
| `vault_totp` | 为存储的 otpSecret(或直接传入的 Base32/otpauth URI)生成当前 6 位动态验证码 |
|
|
52
52
|
| `vault_generate_password` | 生成强随机密码(长度/字符集/分组可选)**或易记口令短语**(`passphrase: true`,EFF 词表,`words`/`separator`/`wordDigits`) |
|
|
53
53
|
| `vault_strength` | 零依赖密码强度评估(0–100 分,weak/fair/strong/very strong) |
|
|
54
|
+
| `vault_password_history` | 列出条目的历史密码(1Password/Bitwarden 风格,最新在前,上限 10 条;不含当前密码) |
|
|
55
|
+
| `kind: card` | 银行卡/信用卡条目:`cardNumber`/`cardExpiry`(MM/YY)/`cardCvv`/`cardHolder`;搜索摘要只暴露有效期和持卡人(绝不显示卡号和 CVV);Bitwarden JSON 导出映射为 card 条目(type 3,自动识别卡品牌) |
|
|
56
|
+
| `vault_password_rollback` | 将条目密码回滚到某条历史记录(当前密码先归档,可逆) |
|
|
54
57
|
| `vault_rekey` | 原地升级 scrypt KDF 参数并重加密 |
|
|
55
58
|
| `vault_backup` | 带时间戳的加密备份,支持保留策略:超过 `maxBackups`(默认 10)的旧备份自动清理 |
|
|
56
59
|
| `vault_import_csv` | 从 CSV 批量导入凭据(自定义列变为 fields;`overwrite: true` 合并字段到已有条目,不再产生重复) |
|
package/README.md
CHANGED
|
@@ -53,6 +53,9 @@ Each record has a `title`, an optional `kind`, and any combination of fields:
|
|
|
53
53
|
| `vault_totp` | Generate the current 6-digit code for a stored otpSecret (or a bare Base32 / otpauth URI) |
|
|
54
54
|
| `vault_generate_password` | Generate a strong random password (length/classes/grouping) **or a memorable passphrase** (`passphrase: true`, EFF-style word list, `words`/`separator`/`wordDigits`) |
|
|
55
55
|
| `vault_strength` | Zero-dependency password strength estimate (score 0–100, weak/fair/strong/very strong) |
|
|
56
|
+
| `vault_password_history` | List an entry's previous passwords (1Password/Bitwarden-style, newest first, capped at 10; current password excluded) |
|
|
57
|
+
| `kind: card` | Bank/credit-card entries: `cardNumber`/`cardExpiry` (MM/YY)/`cardCvv`/`cardHolder`; search summaries expose expiry + holder only (never the number or CVV); Bitwarden JSON export maps to a `card` item (type 3, brand inferred) |
|
|
58
|
+
| `vault_password_rollback` | Restore an entry password to a stored history entry (current password is archived first, so it is reversible) |
|
|
56
59
|
| `vault_rekey` | Upgrade the vault to fresh scrypt KDF parameters in place |
|
|
57
60
|
| `vault_backup` | Timestamped encrypted backup with retention; optional `note` |
|
|
58
61
|
| `vault_import_csv` | Bulk-import credentials from a CSV file (custom columns become fields; `overwrite: true` merges fields into existing entries instead of duplicating) |
|
package/lib/client.js
CHANGED
|
@@ -17,89 +17,89 @@ window.__ModuleLoader__.load({
|
|
|
17
17
|
document.head.appendChild(tag);
|
|
18
18
|
}
|
|
19
19
|
var VaultSection_module_css_default = {
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"badgeWarn": "t_j5va_badgeWarn",
|
|
28
|
-
"genOptRow": "t_j5va_genOptRow",
|
|
29
|
-
"tabPane": "t_j5va_tabPane",
|
|
30
|
-
"identity": "t_j5va_identity",
|
|
20
|
+
"pwFair": "t_j5va_pwFair",
|
|
21
|
+
"kindChip": "t_j5va_kindChip",
|
|
22
|
+
"auditRow": "t_j5va_auditRow",
|
|
23
|
+
"clearButton": "t_j5va_clearButton",
|
|
24
|
+
"healthBar": "t_j5va_healthBar",
|
|
25
|
+
"title": "t_j5va_title",
|
|
26
|
+
"rowDue": "t_j5va_rowDue",
|
|
31
27
|
"dupNames": "t_j5va_dupNames",
|
|
28
|
+
"pinStar": "t_j5va_pinStar",
|
|
29
|
+
"saveButton": "t_j5va_saveButton",
|
|
30
|
+
"tabPane": "t_j5va_tabPane",
|
|
31
|
+
"secretField": "t_j5va_secretField",
|
|
32
32
|
"srOnly": "t_j5va_srOnly",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
33
|
+
"dueBadge": "t_j5va_dueBadge",
|
|
34
|
+
"genOptRow": "t_j5va_genOptRow",
|
|
35
|
+
"backupButton": "t_j5va_backupButton",
|
|
36
|
+
"resultCount": "t_j5va_resultCount",
|
|
37
|
+
"rowMain": "t_j5va_rowMain",
|
|
38
|
+
"editorActions": "t_j5va_editorActions",
|
|
39
|
+
"kindIcon": "t_j5va_kindIcon",
|
|
40
|
+
"highBadge": "t_j5va_highBadge",
|
|
41
|
+
"policyBar": "t_j5va_policyBar",
|
|
36
42
|
"pwWeak": "t_j5va_pwWeak",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"policyField": "t_j5va_policyField",
|
|
43
|
+
"reportTitle": "t_j5va_reportTitle",
|
|
44
|
+
"genOpts": "t_j5va_genOpts",
|
|
40
45
|
"modeAuto": "t_j5va_modeAuto",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
46
|
+
"reportLine": "t_j5va_reportLine",
|
|
47
|
+
"field": "t_j5va_field",
|
|
48
|
+
"rowExpired": "t_j5va_rowExpired",
|
|
49
|
+
"pwLabel": "t_j5va_pwLabel",
|
|
50
|
+
"dangerButton": "t_j5va_dangerButton",
|
|
51
|
+
"genHist": "t_j5va_genHist",
|
|
43
52
|
"tabs": "t_j5va_tabs",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
53
|
+
"toolbar": "t_j5va_toolbar",
|
|
54
|
+
"totp": "t_j5va_totp",
|
|
55
|
+
"row": "t_j5va_row",
|
|
47
56
|
"status": "t_j5va_status",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
57
|
+
"editorBody": "t_j5va_editorBody",
|
|
58
|
+
"dupGroup": "t_j5va_dupGroup",
|
|
59
|
+
"dupMerge": "t_j5va_dupMerge",
|
|
51
60
|
"pwBar": "t_j5va_pwBar",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
61
|
+
"modeReadonly": "t_j5va_modeReadonly",
|
|
62
|
+
"reportSub": "t_j5va_reportSub",
|
|
63
|
+
"sortButton": "t_j5va_sortButton",
|
|
64
|
+
"retryButton": "t_j5va_retryButton",
|
|
55
65
|
"error": "t_j5va_error",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
66
|
+
"detailBox": "t_j5va_detailBox",
|
|
67
|
+
"lockedTag": "t_j5va_lockedTag",
|
|
68
|
+
"searchBox": "t_j5va_searchBox",
|
|
69
|
+
"section": "t_j5va_section",
|
|
70
|
+
"modeAsk": "t_j5va_modeAsk",
|
|
71
|
+
"pwMeter": "t_j5va_pwMeter",
|
|
72
|
+
"lockedBanner": "t_j5va_lockedBanner",
|
|
73
|
+
"reportBox": "t_j5va_reportBox",
|
|
74
|
+
"totpRing": "t_j5va_totpRing",
|
|
75
|
+
"detailItem": "t_j5va_detailItem",
|
|
76
|
+
"tab": "t_j5va_tab",
|
|
77
|
+
"badge": "t_j5va_badge",
|
|
78
|
+
"emptyHint": "t_j5va_emptyHint",
|
|
79
|
+
"empty": "t_j5va_empty",
|
|
80
|
+
"policyField": "t_j5va_policyField",
|
|
81
|
+
"badgeOk": "t_j5va_badgeOk",
|
|
82
|
+
"badgeWarn": "t_j5va_badgeWarn",
|
|
83
|
+
"tabActive": "t_j5va_tabActive",
|
|
84
|
+
"intro": "t_j5va_intro",
|
|
85
|
+
"revealButton": "t_j5va_revealButton",
|
|
86
|
+
"pwStrong": "t_j5va_pwStrong",
|
|
87
|
+
"deleteButton": "t_j5va_deleteButton",
|
|
60
88
|
"scoreRing": "t_j5va_scoreRing",
|
|
61
89
|
"footer": "t_j5va_footer",
|
|
62
|
-
"
|
|
90
|
+
"uriCode": "t_j5va_uriCode",
|
|
63
91
|
"copied": "t_j5va_copied",
|
|
92
|
+
"kindFilter": "t_j5va_kindFilter",
|
|
64
93
|
"rowActions": "t_j5va_rowActions",
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"genOpts": "t_j5va_genOpts",
|
|
70
|
-
"totpRing": "t_j5va_totpRing",
|
|
71
|
-
"clearButton": "t_j5va_clearButton",
|
|
94
|
+
"list": "t_j5va_list",
|
|
95
|
+
"emptyBox": "t_j5va_emptyBox",
|
|
96
|
+
"identity": "t_j5va_identity",
|
|
97
|
+
"trashButton": "t_j5va_trashButton",
|
|
72
98
|
"badgeDanger": "t_j5va_badgeDanger",
|
|
73
|
-
"badge": "t_j5va_badge",
|
|
74
|
-
"pwStrong": "t_j5va_pwStrong",
|
|
75
|
-
"row": "t_j5va_row",
|
|
76
|
-
"title": "t_j5va_title",
|
|
77
|
-
"checkField": "t_j5va_checkField",
|
|
78
|
-
"pwMeter": "t_j5va_pwMeter",
|
|
79
|
-
"lockedTag": "t_j5va_lockedTag",
|
|
80
|
-
"auditIssues": "t_j5va_auditIssues",
|
|
81
|
-
"badgeOk": "t_j5va_badgeOk",
|
|
82
|
-
"pinStar": "t_j5va_pinStar",
|
|
83
|
-
"resultCount": "t_j5va_resultCount",
|
|
84
|
-
"modeReadonly": "t_j5va_modeReadonly",
|
|
85
|
-
"intro": "t_j5va_intro",
|
|
86
|
-
"highBadge": "t_j5va_highBadge",
|
|
87
|
-
"editorBody": "t_j5va_editorBody",
|
|
88
|
-
"empty": "t_j5va_empty",
|
|
89
|
-
"sortButton": "t_j5va_sortButton",
|
|
90
|
-
"emptyHint": "t_j5va_emptyHint",
|
|
91
|
-
"editorActions": "t_j5va_editorActions",
|
|
92
99
|
"addButton": "t_j5va_addButton",
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"dueBadge": "t_j5va_dueBadge",
|
|
97
|
-
"kindIcon": "t_j5va_kindIcon",
|
|
98
|
-
"rowExpired": "t_j5va_rowExpired",
|
|
99
|
-
"section": "t_j5va_section",
|
|
100
|
-
"pwLabel": "t_j5va_pwLabel",
|
|
101
|
-
"uriCode": "t_j5va_uriCode",
|
|
102
|
-
"tab": "t_j5va_tab"
|
|
100
|
+
"checkField": "t_j5va_checkField",
|
|
101
|
+
"editor": "t_j5va_editor",
|
|
102
|
+
"auditIssues": "t_j5va_auditIssues"
|
|
103
103
|
};
|
|
104
104
|
//#endregion
|
|
105
105
|
//#region src/client/VaultSection.tsx
|
|
@@ -161,6 +161,22 @@ window.__ModuleLoader__.load({
|
|
|
161
161
|
key: "otpSecret",
|
|
162
162
|
label: "fieldOtpSecret"
|
|
163
163
|
},
|
|
164
|
+
{
|
|
165
|
+
key: "cardNumber",
|
|
166
|
+
label: "fieldCardNumber"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
key: "cardExpiry",
|
|
170
|
+
label: "fieldCardExpiry"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
key: "cardCvv",
|
|
174
|
+
label: "fieldCardCvv"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
key: "cardHolder",
|
|
178
|
+
label: "fieldCardHolder"
|
|
179
|
+
},
|
|
164
180
|
{
|
|
165
181
|
key: "url",
|
|
166
182
|
label: "fieldUrl"
|
|
@@ -232,6 +248,7 @@ window.__ModuleLoader__.load({
|
|
|
232
248
|
secret: "kindSecret",
|
|
233
249
|
oauth: "kindOauth",
|
|
234
250
|
cookie: "kindCookie",
|
|
251
|
+
card: "kindCard",
|
|
235
252
|
custom: "kindCustom"
|
|
236
253
|
};
|
|
237
254
|
function emptyForm() {
|
|
@@ -360,7 +377,10 @@ window.__ModuleLoader__.load({
|
|
|
360
377
|
}, 250);
|
|
361
378
|
return () => window.clearTimeout(timer);
|
|
362
379
|
}, [form.password, strength]);
|
|
363
|
-
/** Apply a template's field values to the current form.
|
|
380
|
+
/** Apply a template's field values to the current form. The form is reset
|
|
381
|
+
* to its empty state first (so fields the template does not set are cleared
|
|
382
|
+
* rather than leaking the previous template's values), then the template's
|
|
383
|
+
* fields are applied. Secret-ish fields are never filled from a template. */
|
|
364
384
|
function applyTemplate(name) {
|
|
365
385
|
const tpl = tplList.find((t) => t.name === name);
|
|
366
386
|
if (!tpl) return;
|
|
@@ -370,10 +390,26 @@ window.__ModuleLoader__.load({
|
|
|
370
390
|
if (key === "password" || key === "otpSecret" || key === "apiKey" || key === "secret") continue;
|
|
371
391
|
next[key] = value;
|
|
372
392
|
}
|
|
373
|
-
setForm(
|
|
374
|
-
...
|
|
393
|
+
setForm({
|
|
394
|
+
...emptyForm(),
|
|
375
395
|
...next
|
|
376
|
-
})
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
/** Change the entry kind. When CREATING a new entry, unrelated fields from
|
|
399
|
+
* the previous kind are cleared so the form does not carry stale values; when
|
|
400
|
+
* EDITING an existing entry the other fields are kept (they may be valid for
|
|
401
|
+
* the new kind too, and clearing would risk data loss). */
|
|
402
|
+
function changeKind(kind) {
|
|
403
|
+
setForm((previous) => {
|
|
404
|
+
if (editor.status === "creating") return {
|
|
405
|
+
...emptyForm(),
|
|
406
|
+
kind
|
|
407
|
+
};
|
|
408
|
+
return {
|
|
409
|
+
...previous,
|
|
410
|
+
kind
|
|
411
|
+
};
|
|
412
|
+
});
|
|
377
413
|
}
|
|
378
414
|
/** Save the current form as a reusable template. */
|
|
379
415
|
async function saveAsTemplate() {
|
|
@@ -1296,6 +1332,7 @@ window.__ModuleLoader__.load({
|
|
|
1296
1332
|
case "oauth": return "🔐";
|
|
1297
1333
|
case "secret": return "🤫";
|
|
1298
1334
|
case "cookie": return "🍪";
|
|
1335
|
+
case "card": return "💳";
|
|
1299
1336
|
case "custom": return "🧩";
|
|
1300
1337
|
default: return "👤";
|
|
1301
1338
|
}
|
|
@@ -2923,14 +2960,15 @@ window.__ModuleLoader__.load({
|
|
|
2923
2960
|
children: t("tplSave")
|
|
2924
2961
|
})]
|
|
2925
2962
|
}),
|
|
2926
|
-
FORM_FIELDS.
|
|
2963
|
+
FORM_FIELDS.filter((f) => {
|
|
2964
|
+
const kind = form.kind ?? "login";
|
|
2965
|
+
if (f.key === "cardNumber" || f.key === "cardExpiry" || f.key === "cardCvv" || f.key === "cardHolder") return kind === "card";
|
|
2966
|
+
return kind !== "card" || f.key === "title" || f.key === "kind" || f.key === "notes" || f.key === "icon" || f.key === "color";
|
|
2967
|
+
}).map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2927
2968
|
className: VaultSection_module_css_default.field,
|
|
2928
2969
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(field.label) }), field.key === "kind" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
2929
2970
|
value: form.kind ?? "login",
|
|
2930
|
-
onChange: (event) =>
|
|
2931
|
-
...previous,
|
|
2932
|
-
kind: event.target.value
|
|
2933
|
-
})),
|
|
2971
|
+
onChange: (event) => changeKind(event.target.value),
|
|
2934
2972
|
children: Object.entries(KIND_KEYS).map(([value, key]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2935
2973
|
value,
|
|
2936
2974
|
children: t(key)
|
|
@@ -3419,6 +3457,10 @@ window.__ModuleLoader__.load({
|
|
|
3419
3457
|
fieldRefreshToken: "Refresh token",
|
|
3420
3458
|
fieldOtpSecret: "OTP secret",
|
|
3421
3459
|
fieldUrl: "URL",
|
|
3460
|
+
fieldCardNumber: "Card number",
|
|
3461
|
+
fieldCardExpiry: "Expiry (MM/YY)",
|
|
3462
|
+
fieldCardCvv: "CVV",
|
|
3463
|
+
fieldCardHolder: "Card holder",
|
|
3422
3464
|
fieldNotes: "Notes",
|
|
3423
3465
|
fieldTags: "Tags",
|
|
3424
3466
|
fieldIcon: "Icon (emoji)",
|
|
@@ -3439,6 +3481,7 @@ window.__ModuleLoader__.load({
|
|
|
3439
3481
|
kindSecret: "Secret",
|
|
3440
3482
|
kindOauth: "OAuth",
|
|
3441
3483
|
kindCookie: "Session cookies",
|
|
3484
|
+
kindCard: "Card",
|
|
3442
3485
|
kindCustom: "Custom"
|
|
3443
3486
|
};
|
|
3444
3487
|
/** Chinese strings (same keys as English). */
|
|
@@ -3687,6 +3730,10 @@ window.__ModuleLoader__.load({
|
|
|
3687
3730
|
fieldRefreshToken: "刷新令牌",
|
|
3688
3731
|
fieldOtpSecret: "TOTP 密钥",
|
|
3689
3732
|
fieldUrl: "URL",
|
|
3733
|
+
fieldCardNumber: "卡号",
|
|
3734
|
+
fieldCardExpiry: "有效期(MM/YY)",
|
|
3735
|
+
fieldCardCvv: "CVV",
|
|
3736
|
+
fieldCardHolder: "持卡人",
|
|
3690
3737
|
fieldNotes: "备注",
|
|
3691
3738
|
fieldTags: "标签",
|
|
3692
3739
|
fieldIcon: "图标(emoji)",
|
|
@@ -3707,6 +3754,7 @@ window.__ModuleLoader__.load({
|
|
|
3707
3754
|
kindSecret: "Secret",
|
|
3708
3755
|
kindOauth: "OAuth",
|
|
3709
3756
|
kindCookie: "会话 Cookies",
|
|
3757
|
+
kindCard: "银行卡",
|
|
3710
3758
|
kindCustom: "自定义"
|
|
3711
3759
|
};
|
|
3712
3760
|
//#endregion
|