dsh-vault 1.9.0 → 1.9.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/lib/client.js CHANGED
@@ -17,91 +17,91 @@ window.__ModuleLoader__.load({
17
17
  document.head.appendChild(tag);
18
18
  }
19
19
  var VaultSection_module_css_default = {
20
- "reportSub": "t_j5va_reportSub",
21
- "backupButton": "t_j5va_backupButton",
22
- "dangerButton": "t_j5va_dangerButton",
20
+ "scoreRing": "t_j5va_scoreRing",
21
+ "copied": "t_j5va_copied",
22
+ "editor": "t_j5va_editor",
23
+ "badgeWarn": "t_j5va_badgeWarn",
24
+ "modeAuto": "t_j5va_modeAuto",
25
+ "rowDue": "t_j5va_rowDue",
26
+ "modeReadonly": "t_j5va_modeReadonly",
27
+ "rowExpired": "t_j5va_rowExpired",
28
+ "kindFilter": "t_j5va_kindFilter",
29
+ "trashButton": "t_j5va_trashButton",
30
+ "totpRing": "t_j5va_totpRing",
31
+ "section": "t_j5va_section",
23
32
  "pwFair": "t_j5va_pwFair",
24
- "pwLabel": "t_j5va_pwLabel",
25
- "reportBox": "t_j5va_reportBox",
26
- "pinStar": "t_j5va_pinStar",
27
- "dupMerge": "t_j5va_dupMerge",
28
- "genHist": "t_j5va_genHist",
29
- "modeAsk": "t_j5va_modeAsk",
33
+ "secretField": "t_j5va_secretField",
34
+ "dupGroup": "t_j5va_dupGroup",
35
+ "tab": "t_j5va_tab",
36
+ "status": "t_j5va_status",
37
+ "checkField": "t_j5va_checkField",
38
+ "reportLine": "t_j5va_reportLine",
39
+ "saveButton": "t_j5va_saveButton",
30
40
  "badgeDanger": "t_j5va_badgeDanger",
31
- "reportTitle": "t_j5va_reportTitle",
32
41
  "sortButton": "t_j5va_sortButton",
33
- "totp": "t_j5va_totp",
34
- "checkField": "t_j5va_checkField",
35
- "genOptRow": "t_j5va_genOptRow",
36
- "pwMeter": "t_j5va_pwMeter",
37
- "modeReadonly": "t_j5va_modeReadonly",
38
- "tabActive": "t_j5va_tabActive",
39
- "rowMain": "t_j5va_rowMain",
40
- "kindIcon": "t_j5va_kindIcon",
41
- "uriCode": "t_j5va_uriCode",
42
- "modeAuto": "t_j5va_modeAuto",
43
- "section": "t_j5va_section",
42
+ "dupMerge": "t_j5va_dupMerge",
43
+ "resultCount": "t_j5va_resultCount",
44
+ "auditRow": "t_j5va_auditRow",
45
+ "modeAsk": "t_j5va_modeAsk",
44
46
  "badgeOk": "t_j5va_badgeOk",
45
- "status": "t_j5va_status",
46
- "dupGroup": "t_j5va_dupGroup",
47
- "intro": "t_j5va_intro",
48
- "secretField": "t_j5va_secretField",
49
- "tabs": "t_j5va_tabs",
50
- "editor": "t_j5va_editor",
51
- "pinOff": "t_j5va_pinOff",
52
- "retryButton": "t_j5va_retryButton",
47
+ "pinOn": "t_j5va_pinOn",
48
+ "emptyBox": "t_j5va_emptyBox",
53
49
  "identity": "t_j5va_identity",
54
50
  "srOnly": "t_j5va_srOnly",
55
- "clearButton": "t_j5va_clearButton",
56
- "badge": "t_j5va_badge",
57
- "policyField": "t_j5va_policyField",
58
- "auditIssues": "t_j5va_auditIssues",
59
- "emptyHint": "t_j5va_emptyHint",
60
- "pwWeak": "t_j5va_pwWeak",
51
+ "rowActions": "t_j5va_rowActions",
52
+ "intro": "t_j5va_intro",
53
+ "editorActions": "t_j5va_editorActions",
54
+ "reportSub": "t_j5va_reportSub",
55
+ "pinStar": "t_j5va_pinStar",
56
+ "healthBar": "t_j5va_healthBar",
61
57
  "deleteButton": "t_j5va_deleteButton",
62
- "rowDue": "t_j5va_rowDue",
63
- "kindFilter": "t_j5va_kindFilter",
64
- "copied": "t_j5va_copied",
65
- "saveButton": "t_j5va_saveButton",
66
- "title": "t_j5va_title",
67
- "emptyBox": "t_j5va_emptyBox",
58
+ "auditIssues": "t_j5va_auditIssues",
59
+ "list": "t_j5va_list",
68
60
  "searchBox": "t_j5va_searchBox",
69
- "dueBadge": "t_j5va_dueBadge",
70
- "rowActions": "t_j5va_rowActions",
71
- "reportLine": "t_j5va_reportLine",
72
- "error": "t_j5va_error",
73
- "lockedBanner": "t_j5va_lockedBanner",
74
- "trashButton": "t_j5va_trashButton",
75
- "row": "t_j5va_row",
76
- "badgeWarn": "t_j5va_badgeWarn",
77
- "scoreRing": "t_j5va_scoreRing",
78
- "detailBox": "t_j5va_detailBox",
79
- "pinOn": "t_j5va_pinOn",
80
- "footer": "t_j5va_footer",
81
- "revealButton": "t_j5va_revealButton",
82
- "addButton": "t_j5va_addButton",
83
- "rowExpired": "t_j5va_rowExpired",
84
- "detailItem": "t_j5va_detailItem",
61
+ "pwLabel": "t_j5va_pwLabel",
62
+ "highBadge": "t_j5va_highBadge",
63
+ "lockedTag": "t_j5va_lockedTag",
85
64
  "dupNames": "t_j5va_dupNames",
86
- "auditRow": "t_j5va_auditRow",
87
- "list": "t_j5va_list",
88
- "editorBody": "t_j5va_editorBody",
89
- "editorActions": "t_j5va_editorActions",
65
+ "tabs": "t_j5va_tabs",
66
+ "tabActive": "t_j5va_tabActive",
67
+ "pwWeak": "t_j5va_pwWeak",
68
+ "backupButton": "t_j5va_backupButton",
69
+ "dangerButton": "t_j5va_dangerButton",
70
+ "genOpts": "t_j5va_genOpts",
71
+ "dueBadge": "t_j5va_dueBadge",
72
+ "pwMeter": "t_j5va_pwMeter",
90
73
  "pwBar": "t_j5va_pwBar",
91
- "resultCount": "t_j5va_resultCount",
92
- "pwStrong": "t_j5va_pwStrong",
93
- "lockedTag": "t_j5va_lockedTag",
74
+ "uriCode": "t_j5va_uriCode",
75
+ "addButton": "t_j5va_addButton",
76
+ "kindChip": "t_j5va_kindChip",
77
+ "rowMain": "t_j5va_rowMain",
78
+ "detailBox": "t_j5va_detailBox",
79
+ "policyField": "t_j5va_policyField",
94
80
  "tabPane": "t_j5va_tabPane",
95
- "toolbar": "t_j5va_toolbar",
96
- "totpRing": "t_j5va_totpRing",
97
- "highBadge": "t_j5va_highBadge",
81
+ "retryButton": "t_j5va_retryButton",
98
82
  "policyBar": "t_j5va_policyBar",
99
- "kindChip": "t_j5va_kindChip",
100
- "healthBar": "t_j5va_healthBar",
83
+ "reportTitle": "t_j5va_reportTitle",
84
+ "toolbar": "t_j5va_toolbar",
85
+ "emptyHint": "t_j5va_emptyHint",
86
+ "editorBody": "t_j5va_editorBody",
87
+ "field": "t_j5va_field",
88
+ "reportBox": "t_j5va_reportBox",
89
+ "genOptRow": "t_j5va_genOptRow",
90
+ "footer": "t_j5va_footer",
91
+ "detailItem": "t_j5va_detailItem",
92
+ "genHist": "t_j5va_genHist",
93
+ "pinOff": "t_j5va_pinOff",
101
94
  "empty": "t_j5va_empty",
102
- "genOpts": "t_j5va_genOpts",
103
- "tab": "t_j5va_tab",
104
- "field": "t_j5va_field"
95
+ "revealButton": "t_j5va_revealButton",
96
+ "kindIcon": "t_j5va_kindIcon",
97
+ "badge": "t_j5va_badge",
98
+ "clearButton": "t_j5va_clearButton",
99
+ "totp": "t_j5va_totp",
100
+ "row": "t_j5va_row",
101
+ "lockedBanner": "t_j5va_lockedBanner",
102
+ "title": "t_j5va_title",
103
+ "pwStrong": "t_j5va_pwStrong",
104
+ "error": "t_j5va_error"
105
105
  };
106
106
  //#endregion
107
107
  //#region src/client/VaultSection.tsx
@@ -286,7 +286,7 @@ window.__ModuleLoader__.load({
286
286
  }
287
287
  /** Render the Vault settings section. */
288
288
  function VaultSection(props) {
289
- const { t, config, setAccessMode, setAutoCapture, setAutoLock, list, search, get, add, update, remove, purge, trash, rotation, health, duplicates, duplicateGroups, merge, history, stats, backupStatus, backup, recent, restore, undeleteAll, totp, status, switchVault, listVaults, touch, setFavorite, verifyAll, breachCheck, generatePassword, strength, generateUsername, templates, saveTemplate, lock, totpUri, tags, renameTag, generatorHistory, backups, deleteBackup, restoreBackup, importChrome, importFirefox, import1password, importManagerCsv, importEnpass, importBitwarden, import1pif, importKeePassXml, importKdbx, importBitwardenEncrypted, keychainImport, searchSystem, sessionOpen, sessionCollect, sessionClose, sessionListOpen, sessionListSaved, sessionSave, sessionExport, sessionGet, sessionPrune, vaultRename, vaultDelete, watchtower, export1pux, exportBitwarden, recoveryCode, verifyRecovery, recoveryStatus, unlock } = props;
289
+ const { t, config, setAccessMode, setAutoCapture, setAutoLock, list, search, get, add, update, remove, purge, trash, rotation, health, duplicates, duplicateGroups, merge, history, stats, backupStatus, backup, recent, restore, undeleteAll, totp, status, switchVault, listVaults, touch, setFavorite, attachments, detach, verifyAll, breachCheck, generatePassword, strength, generateUsername, templates, saveTemplate, lock, totpUri, tags, renameTag, generatorHistory, backups, deleteBackup, restoreBackup, importChrome, importFirefox, import1password, importManagerCsv, importEnpass, importBitwarden, import1pif, importKeePassXml, importKdbx, importBitwardenEncrypted, keychainImport, searchSystem, sessionOpen, sessionCollect, sessionClose, sessionListOpen, sessionListSaved, sessionSave, sessionExport, sessionGet, sessionPrune, vaultRename, vaultDelete, watchtower, export1pux, exportBitwarden, recoveryCode, verifyRecovery, recoveryStatus, unlock } = props;
290
290
  const searchId = (0, react.useId)();
291
291
  const [query, setQuery] = (0, react.useState)("");
292
292
  const [state, setState] = (0, react.useState)({ status: "loading" });
@@ -332,6 +332,7 @@ window.__ModuleLoader__.load({
332
332
  const [kindFilter, setKindFilter] = (0, react.useState)("");
333
333
  const [tagFilter, setTagFilter] = (0, react.useState)("");
334
334
  const [expandedId, setExpandedId] = (0, react.useState)(null);
335
+ const [attachmentsMap, setAttachmentsMap] = (0, react.useState)({});
335
336
  const [visibleCount, setVisibleCount] = (0, react.useState)(50);
336
337
  const [sortBy, setSortBy] = (0, react.useState)("alpha");
337
338
  const [activeTab, setActiveTab] = (0, react.useState)("entries");
@@ -350,6 +351,12 @@ window.__ModuleLoader__.load({
350
351
  const [audit, setAudit] = (0, react.useState)([]);
351
352
  const [breach, setBreach] = (0, react.useState)(null);
352
353
  const readonly = policy?.accessMode === "readonly";
354
+ /** Format a byte count for display (e.g. 1536 → "1.5 KB"). */
355
+ function formatSize(bytes) {
356
+ if (bytes < 1024) return `${bytes} B`;
357
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
358
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
359
+ }
353
360
  /** Turn an RPC/Error failure into a specific, localized message instead of
354
361
  * the generic "operation failed" copy. The RPC channel wraps errors as
355
362
  * `vault.<method> failed: <code>: <message>`; unwrap and map the common
@@ -1249,6 +1256,19 @@ window.__ModuleLoader__.load({
1249
1256
  totpMap,
1250
1257
  totp
1251
1258
  ]);
1259
+ (0, react.useEffect)(() => {
1260
+ if (expandedId === null) return;
1261
+ let current = true;
1262
+ attachments(expandedId).then((r) => {
1263
+ if (current && r.found) setAttachmentsMap((prev) => ({
1264
+ ...prev,
1265
+ [expandedId]: r.attachments
1266
+ }));
1267
+ }).catch(() => {});
1268
+ return () => {
1269
+ current = false;
1270
+ };
1271
+ }, [expandedId, attachments]);
1252
1272
  (0, react.useEffect)(() => {
1253
1273
  let current = true;
1254
1274
  const load = () => {
@@ -2950,9 +2970,9 @@ window.__ModuleLoader__.load({
2950
2970
  })
2951
2971
  ]
2952
2972
  }),
2953
- expandedId === entry.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2973
+ expandedId === entry.id && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2954
2974
  className: VaultSection_module_css_default.detailBox,
2955
- children: Object.entries(entry).filter(([k]) => ![
2975
+ children: [Object.entries(entry).filter(([k]) => ![
2956
2976
  "id",
2957
2977
  "title",
2958
2978
  "favorite"
@@ -2971,7 +2991,38 @@ window.__ModuleLoader__.load({
2971
2991
  children: "⧉"
2972
2992
  })
2973
2993
  ]
2974
- }, k))
2994
+ }, k)), (attachmentsMap[entry.id] ?? []).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2995
+ className: VaultSection_module_css_default.attachBox,
2996
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [t("attachmentsTitle"), ":"] }), (attachmentsMap[entry.id] ?? []).map((a) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2997
+ className: VaultSection_module_css_default.detailItem,
2998
+ children: [
2999
+ "📎 ",
3000
+ a.name,
3001
+ " (",
3002
+ formatSize(a.size),
3003
+ ")",
3004
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3005
+ type: "button",
3006
+ className: VaultSection_module_css_default.revealButton,
3007
+ title: t("detachHint"),
3008
+ disabled: busy || readonly || locked,
3009
+ onClick: () => {
3010
+ setBusy(true);
3011
+ detach(entry.id, a.name).then(() => {
3012
+ attachments(entry.id).then((r) => {
3013
+ if (r.found) setAttachmentsMap((prev) => ({
3014
+ ...prev,
3015
+ [entry.id]: r.attachments
3016
+ }));
3017
+ });
3018
+ setBusy(false);
3019
+ }, () => setBusy(false));
3020
+ },
3021
+ children: "✕"
3022
+ })
3023
+ ]
3024
+ }, a.name))]
3025
+ })]
2975
3026
  }),
2976
3027
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2977
3028
  className: VaultSection_module_css_default.rowActions,
@@ -3866,6 +3917,8 @@ window.__ModuleLoader__.load({
3866
3917
  highSensitivity: "HIGH",
3867
3918
  pinned: "Pinned",
3868
3919
  togglePinHint: "Toggle pinned (shows at top in pinned/smart sort)",
3920
+ attachmentsTitle: "Attachments",
3921
+ detachHint: "Remove attachment",
3869
3922
  add: "Add credential",
3870
3923
  quickAdd: "Quick add",
3871
3924
  cancel: "Cancel",
@@ -4190,6 +4243,8 @@ window.__ModuleLoader__.load({
4190
4243
  highSensitivity: "高敏",
4191
4244
  pinned: "已置顶",
4192
4245
  togglePinHint: "切换置顶(置顶/智能排序时显示在最前)",
4246
+ attachmentsTitle: "附件",
4247
+ detachHint: "移除附件",
4193
4248
  add: "新增凭据",
4194
4249
  quickAdd: "快速添加",
4195
4250
  cancel: "取消",
@@ -4329,6 +4384,11 @@ window.__ModuleLoader__.load({
4329
4384
  id,
4330
4385
  favorite
4331
4386
  }),
4387
+ attachments: (id) => invoke("attachments", { id }),
4388
+ detach: (id, name) => invoke("detach", {
4389
+ id,
4390
+ name
4391
+ }),
4332
4392
  lock: () => invoke("lock"),
4333
4393
  unlock: () => invoke("unlock"),
4334
4394
  totpUri: (id) => invoke("totpUri", { id }),