dsh-vault 0.9.8 → 1.0.0
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 +76 -55
- package/lib/client.js.map +1 -1
- package/lib/index.js +67 -30
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -17,69 +17,69 @@ window.__ModuleLoader__.load({
|
|
|
17
17
|
document.head.appendChild(tag);
|
|
18
18
|
}
|
|
19
19
|
var VaultSection_module_css_default = {
|
|
20
|
-
"
|
|
21
|
-
"rowDue": "t_j5va_rowDue",
|
|
22
|
-
"saveButton": "t_j5va_saveButton",
|
|
23
|
-
"checkField": "t_j5va_checkField",
|
|
24
|
-
"detailBox": "t_j5va_detailBox",
|
|
25
|
-
"title": "t_j5va_title",
|
|
26
|
-
"dupGroup": "t_j5va_dupGroup",
|
|
27
|
-
"editor": "t_j5va_editor",
|
|
28
|
-
"revealButton": "t_j5va_revealButton",
|
|
29
|
-
"rowExpired": "t_j5va_rowExpired",
|
|
30
|
-
"error": "t_j5va_error",
|
|
20
|
+
"reportBox": "t_j5va_reportBox",
|
|
31
21
|
"kindIcon": "t_j5va_kindIcon",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"auditRow": "t_j5va_auditRow",
|
|
35
|
-
"dupMerge": "t_j5va_dupMerge",
|
|
36
|
-
"badgeWarn": "t_j5va_badgeWarn",
|
|
37
|
-
"dangerButton": "t_j5va_dangerButton",
|
|
38
|
-
"deleteButton": "t_j5va_deleteButton",
|
|
39
|
-
"reportTitle": "t_j5va_reportTitle",
|
|
40
|
-
"toolbar": "t_j5va_toolbar",
|
|
41
|
-
"row": "t_j5va_row",
|
|
42
|
-
"copied": "t_j5va_copied",
|
|
43
|
-
"secretField": "t_j5va_secretField",
|
|
22
|
+
"error": "t_j5va_error",
|
|
23
|
+
"addButton": "t_j5va_addButton",
|
|
44
24
|
"intro": "t_j5va_intro",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
25
|
+
"trashButton": "t_j5va_trashButton",
|
|
26
|
+
"dupGroup": "t_j5va_dupGroup",
|
|
27
|
+
"clearButton": "t_j5va_clearButton",
|
|
28
|
+
"totpRing": "t_j5va_totpRing",
|
|
29
|
+
"detailItem": "t_j5va_detailItem",
|
|
30
|
+
"rowMain": "t_j5va_rowMain",
|
|
31
|
+
"editor": "t_j5va_editor",
|
|
32
|
+
"backupButton": "t_j5va_backupButton",
|
|
50
33
|
"list": "t_j5va_list",
|
|
51
|
-
"modeReadonly": "t_j5va_modeReadonly",
|
|
52
|
-
"identity": "t_j5va_identity",
|
|
53
34
|
"kindFilter": "t_j5va_kindFilter",
|
|
54
|
-
"pinStar": "t_j5va_pinStar",
|
|
55
35
|
"badge": "t_j5va_badge",
|
|
56
|
-
"
|
|
57
|
-
"badgeDanger": "t_j5va_badgeDanger",
|
|
58
|
-
"backupButton": "t_j5va_backupButton",
|
|
36
|
+
"row": "t_j5va_row",
|
|
59
37
|
"reportSub": "t_j5va_reportSub",
|
|
60
|
-
"trashButton": "t_j5va_trashButton",
|
|
61
|
-
"detailItem": "t_j5va_detailItem",
|
|
62
|
-
"editorActions": "t_j5va_editorActions",
|
|
63
38
|
"sortButton": "t_j5va_sortButton",
|
|
39
|
+
"secretField": "t_j5va_secretField",
|
|
40
|
+
"highBadge": "t_j5va_highBadge",
|
|
41
|
+
"footer": "t_j5va_footer",
|
|
42
|
+
"badgeWarn": "t_j5va_badgeWarn",
|
|
43
|
+
"field": "t_j5va_field",
|
|
44
|
+
"searchBox": "t_j5va_searchBox",
|
|
45
|
+
"modeAuto": "t_j5va_modeAuto",
|
|
46
|
+
"modeAsk": "t_j5va_modeAsk",
|
|
47
|
+
"badgeOk": "t_j5va_badgeOk",
|
|
48
|
+
"rowActions": "t_j5va_rowActions",
|
|
49
|
+
"healthBar": "t_j5va_healthBar",
|
|
50
|
+
"section": "t_j5va_section",
|
|
51
|
+
"empty": "t_j5va_empty",
|
|
64
52
|
"lockedBanner": "t_j5va_lockedBanner",
|
|
65
53
|
"emptyHint": "t_j5va_emptyHint",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
54
|
+
"modeReadonly": "t_j5va_modeReadonly",
|
|
55
|
+
"saveButton": "t_j5va_saveButton",
|
|
56
|
+
"policyField": "t_j5va_policyField",
|
|
68
57
|
"editorBody": "t_j5va_editorBody",
|
|
69
|
-
"clearButton": "t_j5va_clearButton",
|
|
70
|
-
"reportBox": "t_j5va_reportBox",
|
|
71
58
|
"reportLine": "t_j5va_reportLine",
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"section": "t_j5va_section",
|
|
78
|
-
"highBadge": "t_j5va_highBadge",
|
|
79
|
-
"modeAuto": "t_j5va_modeAuto",
|
|
80
|
-
"field": "t_j5va_field",
|
|
59
|
+
"revealButton": "t_j5va_revealButton",
|
|
60
|
+
"dangerButton": "t_j5va_dangerButton",
|
|
61
|
+
"dueBadge": "t_j5va_dueBadge",
|
|
62
|
+
"auditRow": "t_j5va_auditRow",
|
|
63
|
+
"title": "t_j5va_title",
|
|
81
64
|
"auditIssues": "t_j5va_auditIssues",
|
|
82
|
-
"
|
|
65
|
+
"toolbar": "t_j5va_toolbar",
|
|
66
|
+
"reportTitle": "t_j5va_reportTitle",
|
|
67
|
+
"detailBox": "t_j5va_detailBox",
|
|
68
|
+
"identity": "t_j5va_identity",
|
|
69
|
+
"policyBar": "t_j5va_policyBar",
|
|
70
|
+
"totp": "t_j5va_totp",
|
|
71
|
+
"emptyBox": "t_j5va_emptyBox",
|
|
72
|
+
"rowExpired": "t_j5va_rowExpired",
|
|
73
|
+
"badgeDanger": "t_j5va_badgeDanger",
|
|
74
|
+
"editorActions": "t_j5va_editorActions",
|
|
75
|
+
"status": "t_j5va_status",
|
|
76
|
+
"pinStar": "t_j5va_pinStar",
|
|
77
|
+
"checkField": "t_j5va_checkField",
|
|
78
|
+
"dupNames": "t_j5va_dupNames",
|
|
79
|
+
"deleteButton": "t_j5va_deleteButton",
|
|
80
|
+
"copied": "t_j5va_copied",
|
|
81
|
+
"dupMerge": "t_j5va_dupMerge",
|
|
82
|
+
"rowDue": "t_j5va_rowDue"
|
|
83
83
|
};
|
|
84
84
|
//#endregion
|
|
85
85
|
//#region src/client/VaultSection.tsx
|
|
@@ -555,6 +555,16 @@ window.__ModuleLoader__.load({
|
|
|
555
555
|
setBusy(false);
|
|
556
556
|
}
|
|
557
557
|
}
|
|
558
|
+
/** Relative time like "5m ago" / "2d ago". */
|
|
559
|
+
function relTime(epoch) {
|
|
560
|
+
const n = Number(epoch);
|
|
561
|
+
if (!Number.isFinite(n) || n <= 0) return "";
|
|
562
|
+
const secs = Math.max(0, Math.floor((Date.now() - n) / 1e3));
|
|
563
|
+
if (secs < 60) return `${secs}s`;
|
|
564
|
+
if (secs < 3600) return `${Math.floor(secs / 60)}m`;
|
|
565
|
+
if (secs < 86400) return `${Math.floor(secs / 3600)}h`;
|
|
566
|
+
return `${Math.floor(secs / 86400)}d`;
|
|
567
|
+
}
|
|
558
568
|
/** Human-friendly value formatting for the expanded detail box. */
|
|
559
569
|
function formatDetail(key, value) {
|
|
560
570
|
if (key === "expiresAt" || key === "updatedAt" || key === "createdAt") {
|
|
@@ -782,9 +792,9 @@ window.__ModuleLoader__.load({
|
|
|
782
792
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
783
793
|
className: VaultSection_module_css_default.reportTitle,
|
|
784
794
|
children: t("recentlyAdded")
|
|
785
|
-
}), recentEntries.map((e, i) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
795
|
+
}), recentEntries.map((e, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
786
796
|
className: VaultSection_module_css_default.reportLine,
|
|
787
|
-
children: String(e.title ?? "")
|
|
797
|
+
children: [String(e.title ?? ""), relTime(e.updatedAt) !== "" && ` · ${relTime(e.updatedAt)}`]
|
|
788
798
|
}, i))]
|
|
789
799
|
}),
|
|
790
800
|
recentEvents.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -797,7 +807,8 @@ window.__ModuleLoader__.load({
|
|
|
797
807
|
children: [
|
|
798
808
|
String(ev.action ?? ""),
|
|
799
809
|
" · ",
|
|
800
|
-
String(ev.title ?? ev.id ?? "")
|
|
810
|
+
String(ev.title ?? ev.id ?? ""),
|
|
811
|
+
relTime(ev.at) !== "" && ` · ${relTime(ev.at)}`
|
|
801
812
|
]
|
|
802
813
|
}, i))]
|
|
803
814
|
}),
|
|
@@ -1172,6 +1183,14 @@ window.__ModuleLoader__.load({
|
|
|
1172
1183
|
report.rotation.length
|
|
1173
1184
|
]
|
|
1174
1185
|
}),
|
|
1186
|
+
vaultStats !== null && typeof vaultStats.expired === "number" && vaultStats.expired > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1187
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
|
|
1188
|
+
children: [
|
|
1189
|
+
t("dueExpired"),
|
|
1190
|
+
": ",
|
|
1191
|
+
String(vaultStats.expired)
|
|
1192
|
+
]
|
|
1193
|
+
}),
|
|
1175
1194
|
report !== null && report.weak.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1176
1195
|
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
|
|
1177
1196
|
children: [
|
|
@@ -1206,7 +1225,9 @@ window.__ModuleLoader__.load({
|
|
|
1206
1225
|
t("healthBackup"),
|
|
1207
1226
|
": ",
|
|
1208
1227
|
backupInfo.daysSinceBackup,
|
|
1209
|
-
"d"
|
|
1228
|
+
"d (",
|
|
1229
|
+
backupInfo.backups,
|
|
1230
|
+
")"
|
|
1210
1231
|
]
|
|
1211
1232
|
}),
|
|
1212
1233
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["css"],"sources":["../src/client/VaultSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Vault settings section: list, search, add, edit, delete, and copy encrypted\n * credentials. All mutations go through the host VaultGateway remote; secrets\n * are shown only inside the edit form or a copy action, never in the list.\n */\n\nimport { useEffect, useId, useMemo, useState, type ReactNode } from 'react'\nimport type { PropsLocale, PropsRuntime, InjectFace, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { VaultLocaleKey } from './locales.ts'\nimport css from './VaultSection.module.css'\n\n/** Wire shapes shared with the host gateway (mirror of src/index.ts types). */\nexport interface VaultSummaryWire {\n id: string\n title: string\n sensitivity?: string\n kind?: string\n username?: string\n email?: string\n phone?: string\n host?: string\n port?: string\n url?: string\n tags?: string[]\n icon?: string\n color?: string\n updatedAt?: number\n}\n\nexport interface VaultFullWire {\n id: string\n title: string\n kind?: string\n username?: string\n email?: string\n phone?: string\n password?: string\n host?: string\n port?: string\n privateKey?: string\n apiKey?: string\n secret?: string\n accessToken?: string\n refreshToken?: string\n expiresAt?: number\n rotationDays?: number\n sensitivity?: string\n favorite?: boolean\n otpSecret?: string\n url?: string\n notes?: string\n tags?: string[]\n icon?: string\n color?: string\n fields?: Record<string, unknown>\n}\n\n/** Patch shape accepted by vault.add / vault.update. */\nexport type VaultPatch = Partial<Omit<VaultFullWire, 'id'>>\n\n/** Registration-side business face supplied by the plugin entry. */\nexport interface VaultSectionInjected {\n t: TranslateNS<'settings.vault'>\n config: () => Promise<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }>\n setAccessMode: (mode: 'readonly' | 'ask' | 'auto') => Promise<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }>\n setAutoCapture: (enabled: boolean) => Promise<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }>\n list: () => Promise<VaultSummaryWire[]>\n search: (query: string, limit?: number) => Promise<VaultSummaryWire[]>\n get: (id: string) => Promise<{ found: boolean; entry?: VaultFullWire }>\n add: (patch: VaultPatch & { title: string }) => Promise<VaultSummaryWire>\n update: (id: string, patch: VaultPatch) => Promise<{ found: boolean; entry?: VaultSummaryWire }>\n remove: (id: string) => Promise<{ deleted: boolean }>\n trash: () => Promise<VaultSummaryWire[]>\n rotation: () => Promise<unknown[]>\n history: () => Promise<unknown[]>\n stats: () => Promise<Record<string, unknown>>\n recent: () => Promise<unknown[]>\n backupStatus: () => Promise<{ daysSinceBackup: number; backups: number }>\n backup: (maxBackups?: number) => Promise<{ path: string; kept: number; pruned: number }>\n health: () => Promise<{ weak: unknown[]; reused: unknown[]; strength: { weak: number; fair: number; strong: number } }>\n duplicates: () => Promise<{ groups: number }>\n duplicateGroups: () => Promise<Array<Array<{ id: string; title: string }>>>\n status: () => Promise<{ locked: boolean; entries: number }>\n switchVault: (name: string) => Promise<{ switched: boolean; name: string }>\n listVaults: () => Promise<Array<{ name: string; active: boolean }>>\n touch: (id: string) => Promise<{ touched: boolean }>\n verifyAll: () => Promise<Array<{ id: string; title: string; issues: string[] }>>\n merge: (fromId: string, toId: string, keepSource?: boolean) => Promise<{ found: boolean }>\n restore: (id: string) => Promise<{ restored: boolean }>\n undeleteAll: () => Promise<{ restored: number }>\n totp: (id: string) => Promise<{ code: string; label?: string; secondsRemaining: number }>\n}\n\n/** Type-level alias so consumers can reference the wire shapes without values. */\nexport type VaultSectionTypes = {\n entries: VaultSummaryWire[]\n fullEntry: VaultFullWire\n summaryEntry: VaultSummaryWire\n config: { accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }\n accessModes: Array<'readonly' | 'ask' | 'auto'>\n}\n\n/** Full component props assembled by the Settings slot renderer. */\nexport type VaultSectionProps =\n PropsRuntime<'settings.section'>\n & PropsLocale<'settings.vault'>\n & InjectFace<VaultSectionInjected>\n\n/** The editable form fields we render (subset of the full wire). */\ntype FormFields = {\n title?: string | undefined\n kind?: string | undefined\n username?: string | undefined\n email?: string | undefined\n phone?: string | undefined\n password?: string | undefined\n host?: string | undefined\n port?: string | undefined\n privateKey?: string | undefined\n apiKey?: string | undefined\n secret?: string | undefined\n accessToken?: string | undefined\n refreshToken?: string | undefined\n otpSecret?: string | undefined\n url?: string | undefined\n notes?: string | undefined\n icon?: string | undefined\n color?: string | undefined\n expiresAt?: number | undefined\n rotationDays?: number | undefined\n sensitivity?: string | undefined\n favorite?: boolean | undefined\n}\n\nconst FORM_FIELDS: Array<{ key: keyof FormFields; label: VaultLocaleKey }> = [\n { key: 'title', label: 'fieldTitle' },\n { key: 'kind', label: 'fieldKind' },\n { key: 'username', label: 'fieldUsername' },\n { key: 'email', label: 'fieldEmail' },\n { key: 'phone', label: 'fieldPhone' },\n { key: 'password', label: 'fieldPassword' },\n { key: 'host', label: 'fieldHost' },\n { key: 'port', label: 'fieldPort' },\n { key: 'apiKey', label: 'fieldApiKey' },\n { key: 'secret', label: 'fieldSecret' },\n { key: 'accessToken', label: 'fieldAccessToken' },\n { key: 'refreshToken', label: 'fieldRefreshToken' },\n { key: 'otpSecret', label: 'fieldOtpSecret' },\n { key: 'url', label: 'fieldUrl' },\n { key: 'notes', label: 'fieldNotes' },\n { key: 'expiresAt', label: 'fieldExpiresAt' },\n { key: 'rotationDays', label: 'fieldRotationDays' },\n { key: 'sensitivity', label: 'fieldSensitivity' },\n { key: 'favorite', label: 'fieldFavorite' },\n { key: 'icon', label: 'fieldIcon' },\n { key: 'color', label: 'fieldColor' },\n]\n\nconst KIND_KEYS: Record<string, VaultLocaleKey> = {\n login: 'kindLogin',\n ssh: 'kindSsh',\n 'api-key': 'kindApiKey',\n secret: 'kindSecret',\n oauth: 'kindOauth',\n custom: 'kindCustom',\n}\n\ntype ViewState =\n | { readonly status: 'loading' }\n | { readonly status: 'error' }\n | { readonly status: 'ready'; readonly entries: VaultSummaryWire[] }\n\ntype EditorState =\n | { readonly status: 'closed' }\n | { readonly status: 'creating' }\n | { readonly status: 'editing'; readonly entry: VaultFullWire }\n\nfunction emptyForm(): FormFields {\n return { title: '', kind: 'login', username: '', email: '', phone: '', password: '', host: '', port: '', icon: '', color: '' }\n}\n\n/** Render the Vault settings section. */\nexport function VaultSection(props: VaultSectionProps): ReactNode {\n const { t, config, setAccessMode, setAutoCapture, list, search, get, add, update, remove, trash, rotation, health, duplicates, duplicateGroups, merge, history, stats, backupStatus, backup, recent, restore, undeleteAll, totp, status, switchVault, listVaults, touch, verifyAll } = props\n const searchId = useId()\n const [query, setQuery] = useState('')\n const [state, setState] = useState<ViewState>({ status: 'loading' })\n const [editor, setEditor] = useState<EditorState>({ status: 'closed' })\n const [form, setForm] = useState<FormFields>(emptyForm())\n const [busy, setBusy] = useState(false)\n const [message, setMessage] = useState<string | null>(null)\n const [copiedId, setCopiedId] = useState<string | null>(null)\n const [totpMap, setTotpMap] = useState<Record<string, { code: string; until: number }>>({})\n const [nowTick, setNowTick] = useState(Date.now())\n const [tagsDraft, setTagsDraft] = useState('')\n const [fieldsDraft, setFieldsDraft] = useState('')\n const [revealed, setRevealed] = useState<Record<string, boolean>>({})\n const [kindFilter, setKindFilter] = useState('')\n const [tagFilter, setTagFilter] = useState('')\n const [expandedId, setExpandedId] = useState<string | null>(null)\n const [sortBy, setSortBy] = useState<'alpha' | 'recent'>('alpha')\n const [policy, setPolicy] = useState<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean } | null>(null)\n const [showTrash, setShowTrash] = useState(false)\n const [trashEntries, setTrashEntries] = useState<VaultSummaryWire[]>([])\n const [report, setReport] = useState<{ rotation: unknown[]; weak: unknown[]; reused: unknown[]; strength: { weak: number; fair: number; strong: number } | null } | null>(null)\n const [dueMap, setDueMap] = useState<Record<string, { due: string; daysLeft: number }>>({})\n const [recentEvents, setRecentEvents] = useState<Array<Record<string, unknown>>>([])\n const [vaultStats, setVaultStats] = useState<Record<string, unknown> | null>(null)\n const [backupInfo, setBackupInfo] = useState<{ daysSinceBackup: number; backups: number } | null>(null)\n const [recentEntries, setRecentEntries] = useState<Array<Record<string, unknown>>>([])\n const [dupGroups, setDupGroups] = useState<number>(0)\n const [dupList, setDupList] = useState<Array<Array<{ id: string; title: string }>>>([])\n const [locked, setLocked] = useState(false)\n const [vaults, setVaults] = useState<Array<{ name: string; active: boolean }>>([])\n const [audit, setAudit] = useState<Array<{ id: string; title: string; issues: string[] }>>([])\n\n const readonly = policy?.accessMode === 'readonly'\n\n /** Switch the active vault and reload everything. */\n async function switchVaultTo(name: string): Promise<void> {\n setBusy(true)\n setMessage(null)\n try {\n await switchVault(name)\n await listVaults().then(setVaults)\n setQuery('')\n void refresh()\n status().then(value => setLocked(value.locked)).catch(() => {})\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Merge one duplicate into another (first keeps gaps filled), then refresh. */\n async function mergeEntries(group: Array<{ id: string; title: string }>): Promise<void> {\n if (group.length < 2) return\n setBusy(true)\n setMessage(null)\n try {\n const [first, second] = group\n await merge(second!.id, first!.id, false)\n await duplicateGroups().then(setDupList)\n void refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Run an encrypted backup now and refresh the backup-age badge. */\n async function backupNow(): Promise<void> {\n setBusy(true)\n setMessage(null)\n try {\n const result = await backup()\n setBackupInfo({ daysSinceBackup: 0, backups: result.kept })\n setMessage(`${t('backupDone')} (${result.kept} kept, ${result.pruned} pruned)`)\n void refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n useEffect(() => {\n let current = true\n void config().then(\n value => { if (current) setPolicy(value) },\n () => { /* policy is informational; ignore failures */ },\n )\n void status().then(\n value => { if (current) setLocked(value.locked) },\n () => { /* ignore */ },\n )\n void listVaults().then(setVaults).catch(() => {})\n return () => { current = false }\n }, [config, status, listVaults])\n\n const refresh = useMemo(() => async () => {\n setState({ status: 'loading' })\n try {\n const entries = query.trim().length === 0\n ? await list()\n : await search(query.trim())\n setState({ status: 'ready', entries })\n status().then(value => setLocked(value.locked)).catch(() => {})\n } catch {\n setState({ status: 'error' })\n }\n }, [list, search, query])\n\n useEffect(() => {\n let current = true\n const timer = window.setTimeout(() => {\n void refresh().then(\n () => { /* state already set inside refresh */ },\n () => { if (current) setState({ status: 'error' }) },\n )\n }, 250)\n return () => { current = false; window.clearTimeout(timer) }\n // refresh is memoized on query (debounced); list/search are stable.\n }, [refresh])\n\n // TOTP countdown: tick every second so the progress ring stays live, and\n // auto-refresh any code whose 30s window just expired.\n useEffect(() => {\n const timer = window.setInterval(() => setNowTick(Date.now()), 1000)\n return () => window.clearInterval(timer)\n }, [])\n\n useEffect(() => {\n for (const [id, info] of Object.entries(totpMap)) {\n if (info.until > 0 && nowTick >= info.until && info.code !== t('error')) {\n void totp(id).then(\n result => setTotpMap(previous => ({\n ...previous,\n [id]: { code: result.code, until: Date.now() + result.secondsRemaining * 1000 },\n })),\n () => { /* keep the last code; next window retries */ },\n )\n }\n }\n }, [nowTick, totpMap, totp])\n\n // Vault health & meta: load once on mount (stats, backup age, rotation,\n // weak/reused scan, recent activity) and refresh on window focus.\n useEffect(() => {\n let current = true\n const load = (): void => {\n void Promise.all([\n stats().catch(() => null),\n backupStatus().catch(() => null),\n rotation().catch(() => []),\n health().catch(() => null),\n recent().catch(() => []),\n duplicates().catch(() => null),\n ]).then(([st, bk, rot, hl, rc, dp]) => {\n if (dp !== null && typeof dp === 'object' && (dp as { groups?: number }).groups !== undefined) {\n setDupGroups((dp as { groups: number }).groups)\n }\n duplicateGroups().then(setDupList).catch(() => {})\n verifyAll().then(setAudit).catch(() => {})\n if (!current) return\n if (st !== null) setVaultStats(st as Record<string, unknown>)\n if (bk !== null) setBackupInfo(bk)\n setReport({ rotation: (rot ?? []) as unknown[], weak: ((hl?.weak ?? []) as unknown[]), reused: ((hl?.reused ?? []) as unknown[]), strength: (hl?.strength ?? null) as { weak: number; fair: number; strong: number } | null })\n const due: Record<string, { due: string; daysLeft: number }> = {}\n for (const item of (rot ?? []) as Array<{ id?: string; due?: string; daysLeft?: number }>) {\n if (item.id !== undefined && item.due !== undefined) due[item.id] = { due: item.due, daysLeft: item.daysLeft ?? 0 }\n }\n setDueMap(due)\n setRecentEntries((rc ?? []) as Array<Record<string, unknown>>)\n })\n }\n load()\n const onFocus = (): void => { load() }\n window.addEventListener('focus', onFocus)\n return () => { current = false; window.removeEventListener('focus', onFocus) }\n }, [stats, backupStatus, rotation, health, recent, duplicates, duplicateGroups, verifyAll])\n\n /** Open the editor for a new entry. */\n function startCreate(): void {\n setForm(emptyForm())\n setTagsDraft('')\n setFieldsDraft('')\n setMessage(null)\n setEditor({ status: 'creating' })\n }\n\n /** Open the editor for an existing entry (fetches full secrets). */\n async function startEdit(id: string): Promise<void> {\n setBusy(true)\n setMessage(null)\n try {\n const result = await get(id)\n if (!result.found || result.entry === undefined) {\n setMessage(t('error'))\n return\n }\n const entry = result.entry\n setForm({\n title: entry.title ?? '',\n kind: entry.kind ?? 'login',\n username: entry.username ?? '',\n email: entry.email ?? '',\n phone: entry.phone ?? '',\n password: entry.password ?? '',\n host: entry.host ?? '',\n port: entry.port ?? '',\n privateKey: entry.privateKey ?? '',\n apiKey: entry.apiKey ?? '',\n secret: entry.secret ?? '',\n accessToken: entry.accessToken ?? '',\n refreshToken: entry.refreshToken ?? '',\n otpSecret: entry.otpSecret ?? '',\n url: entry.url ?? '',\n notes: entry.notes ?? '',\n icon: entry.icon ?? '',\n color: entry.color ?? '',\n expiresAt: entry.expiresAt,\n rotationDays: entry.rotationDays,\n sensitivity: entry.sensitivity,\n favorite: entry.favorite ?? false,\n })\n setTagsDraft((entry.tags ?? []).join(', '))\n setFieldsDraft(entry.fields !== undefined ? Object.entries(entry.fields).map(([k, v]) => `${k}=${String(v)}`).join('\\n') : '')\n setEditor({ status: 'editing', entry })\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Save the current form (create or update). */\n async function save(): Promise<void> {\n if (!(form.title ?? '').trim()) {\n setMessage(t('error'))\n return\n }\n setBusy(true)\n setMessage(null)\n try {\n const tags = tagsDraft.split(',').map(x => x.trim()).filter(x => x.length > 0)\n const fields: Record<string, string> = {}\n for (const line of fieldsDraft.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.length === 0) continue\n const eq = trimmed.indexOf('=')\n if (eq <= 0) continue\n fields[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim()\n }\n const patch: VaultPatch = {\n title: (form.title ?? '').trim(),\n ...(form.kind !== undefined ? { kind: form.kind } : {}),\n ...(form.username !== undefined ? { username: form.username } : {}),\n ...(form.email !== undefined ? { email: form.email } : {}),\n ...(form.phone !== undefined ? { phone: form.phone } : {}),\n ...(form.password !== undefined ? { password: form.password } : {}),\n ...(form.host !== undefined ? { host: form.host } : {}),\n ...(form.port !== undefined ? { port: form.port } : {}),\n ...(form.privateKey !== undefined ? { privateKey: form.privateKey } : {}),\n ...(form.apiKey !== undefined ? { apiKey: form.apiKey } : {}),\n ...(form.secret !== undefined ? { secret: form.secret } : {}),\n ...(form.accessToken !== undefined ? { accessToken: form.accessToken } : {}),\n ...(form.refreshToken !== undefined ? { refreshToken: form.refreshToken } : {}),\n ...(form.otpSecret !== undefined ? { otpSecret: form.otpSecret } : {}),\n ...(form.url !== undefined ? { url: form.url } : {}),\n ...(form.notes !== undefined ? { notes: form.notes } : {}),\n ...(form.icon !== undefined ? { icon: form.icon } : {}),\n ...(form.color !== undefined ? { color: form.color } : {}),\n ...(form.expiresAt !== undefined ? { expiresAt: form.expiresAt } : {}),\n ...(form.rotationDays !== undefined ? { rotationDays: form.rotationDays } : {}),\n ...(form.sensitivity !== undefined ? { sensitivity: form.sensitivity } : {}),\n ...(form.favorite !== undefined ? { favorite: form.favorite } : {}),\n // Always send tags: an empty array clears them, and the host store\n // treats empty string values as \"clear this field\" too.\n tags,\n fields,\n }\n if (editor.status === 'creating') {\n await add(patch as VaultPatch & { title: string })\n } else if (editor.status === 'editing') {\n await update(editor.entry.id, patch)\n }\n setEditor({ status: 'closed' })\n await refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Delete an entry after confirmation. */\n async function removeEntry(id: string): Promise<void> {\n if (!window.confirm(t('deleteConfirm'))) return\n setBusy(true)\n try {\n await remove(id)\n await refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Copy a field value to the clipboard and flash the row. */\n async function copyValue(id: string, value: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(value)\n } catch {\n // Clipboard may be blocked; fall back to a temporary textarea.\n const textarea = document.createElement('textarea')\n textarea.value = value\n document.body.appendChild(textarea)\n textarea.select()\n document.execCommand('copy')\n textarea.remove()\n }\n setCopiedId(id)\n window.setTimeout(() => setCopiedId(null), 1500)\n }\n\n /** Fetch and display a TOTP code for an entry with an otpSecret. */\n async function showTotp(id: string): Promise<void> {\n setBusy(true)\n try {\n const result = await totp(id)\n setTotpMap(previous => ({ ...previous, [id]: { code: result.code, until: Date.now() + result.secondsRemaining * 1000 } }))\n } catch {\n setTotpMap(previous => ({ ...previous, [id]: { code: t('error'), until: 0 } }))\n } finally {\n setBusy(false)\n }\n }\n\n /** Human-friendly value formatting for the expanded detail box. */\n function formatDetail(key: string, value: unknown): string {\n if (key === 'expiresAt' || key === 'updatedAt' || key === 'createdAt') {\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? new Date(n).toISOString().slice(0, 16).replace('T', ' ') : String(value)\n }\n if (key === 'sensitivity' && value === 'high') return t('sensitivityHigh')\n if (key === 'kind') return t(KIND_KEYS[String(value)] ?? 'kindCustom')\n if (Array.isArray(value)) return value.join(', ')\n if (typeof value === 'object' && value !== null) return JSON.stringify(value)\n return String(value)\n }\n\n /** Field-set summary line for one entry (non-secret). */\n function kindIcon(kind?: string): string {\n switch (kind ?? 'login') {\n case 'ssh': return '🖥️'\n case 'api-key': return '🔑'\n case 'oauth': return '🔐'\n case 'secret': return '🤫'\n case 'custom': return '🧩'\n default: return '👤'\n }\n }\n\n function identityLine(entry: VaultSummaryWire): string {\n const parts = [\n entry.kind !== undefined ? t(KIND_KEYS[entry.kind] ?? 'kindCustom') : t('kindLogin'),\n entry.username,\n entry.email,\n entry.phone,\n entry.host !== undefined ? `${entry.host}${entry.port !== undefined ? `:${entry.port}` : ''}` : undefined,\n entry.url,\n ].filter((value): value is string => value !== undefined && value.length > 0)\n return parts.join(' · ')\n }\n\n return (\n <section className={css.section} aria-labelledby=\"vault-heading\">\n <h2 id=\"vault-heading\">{t('heading')}</h2>\n <p className={css.intro}>{t('intro')}</p>\n\n {locked && (\n <p role=\"alert\" className={css.lockedBanner}>{t('lockedBanner')}</p>\n )}\n\n <div className={css.toolbar}>\n {vaults.length > 0 && (\n <select\n className={css.kindFilter}\n value={vaults.find(v => v.active)?.name ?? ''}\n onChange={event => void switchVaultTo(event.target.value)}\n aria-label={t('vaultSelect')}\n >\n {vaults.map(v => (\n <option key={v.name} value={v.name}>{v.name}{v.active ? ' *' : ''}</option>\n ))}\n </select>\n )}\n <label className={css.searchBox}>\n <span className=\"sr-only\">{t('searchPlaceholder')}</span>\n <input\n id={searchId}\n type=\"search\"\n placeholder={t('searchPlaceholder')}\n value={query}\n onChange={event => setQuery(event.target.value)}\n />\n {query.length > 0 && (\n <button type=\"button\" className={css.clearButton} onClick={() => setQuery('')} aria-label={t('clearSearch')}>×</button>\n )}\n </label>\n <select className={css.kindFilter} value={kindFilter} onChange={e => setKindFilter(e.target.value)} aria-label={t('fieldKind')}>\n <option value=\"\">{t('allKinds')}</option>\n {Object.entries(KIND_KEYS).map(([value, key]) => (\n <option key={value} value={value}>{t(key)}</option>\n ))}\n </select>\n <select className={css.kindFilter} value={tagFilter} onChange={e => setTagFilter(e.target.value)} aria-label={t('fieldTags')}>\n <option value=\"\">{t('allTags')}</option>\n {[...new Set(state.status === 'ready' ? state.entries.flatMap(e => e.tags ?? []) : [])].sort().map(tag => (\n <option key={tag} value={tag}>{tag}</option>\n ))}\n </select>\n <button\n type=\"button\"\n className={css.sortButton}\n onClick={() => setSortBy(sortBy === 'alpha' ? 'recent' : 'alpha')}\n >{sortBy === 'alpha' ? t('sortAlpha') : t('sortRecent')}</button>\n <button type=\"button\" className={css.addButton} onClick={startCreate} disabled={busy || readonly}>\n + {t('add')}\n </button>\n </div>\n\n {policy !== null && (\n <div className={css.policyBar}>\n <label className={css.policyField}>\n <span>{t('modeLabel')}</span>\n <select\n value={policy.accessMode}\n disabled={busy}\n onChange={event => {\n const next = event.target.value as 'readonly' | 'ask' | 'auto'\n setBusy(true)\n setMessage(null)\n void setAccessMode(next).then(\n value => { setPolicy(value); setBusy(false) },\n () => { setMessage(t('error')); setBusy(false) },\n )\n }}\n >\n <option value=\"readonly\">{t('modeReadonly')}</option>\n <option value=\"ask\">{t('modeAsk')}</option>\n <option value=\"auto\">{t('modeAuto')}</option>\n </select>\n </label>\n <label className={css.policyField}>\n <span>{t('autoCaptureLabel')}</span>\n <input\n type=\"checkbox\"\n checked={policy.autoCapture}\n disabled={busy}\n onChange={event => {\n const next = event.target.checked\n setBusy(true)\n setMessage(null)\n void setAutoCapture(next).then(\n value => { setPolicy(value); setBusy(false) },\n () => { setMessage(t('error')); setBusy(false) },\n )\n }}\n />\n </label>\n <p className={policy.accessMode === 'readonly' ? css.modeReadonly : policy.accessMode === 'ask' ? css.modeAsk : css.modeAuto}>\n {policy.accessMode === 'readonly'\n ? t('modeReadonlyHint')\n : policy.accessMode === 'ask'\n ? t('modeAskHint')\n : t('modeAutoHint')}\n {policy.autoCapture ? ` · ${t('autoCaptureOn')}` : ` · ${t('autoCaptureOff')}`}\n </p>\n </div>\n )}\n\n {message !== null && <p role=\"alert\" className={css.error}>{message}</p>}\n\n {state.status === 'loading' && <p className={css.status}>{t('loading')}</p>}\n {state.status === 'error' && <p role=\"alert\" className={css.error}>{t('error')}</p>}\n {state.status === 'ready' && state.entries.length === 0 && (\n <div className={css.emptyBox}>\n <p className={css.empty}>{t('empty')}</p>\n <p className={css.emptyHint}>{readonly ? t('emptyHintReadonly') : t('emptyHint')}</p>\n {!readonly && (\n <button type=\"button\" className={css.addButton} onClick={startCreate}>{t('quickAdd')}</button>\n )}\n </div>\n )}\n\n {recentEntries.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('recentlyAdded')}</p>\n {recentEntries.map((e, i) => (\n <p key={i} className={css.reportLine}>{String(e.title ?? '')}</p>\n ))}\n </div>\n )}\n\n {recentEvents.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('recentActivity')}</p>\n {recentEvents.map((ev, i) => (\n <p key={i} className={css.reportLine}>\n {String(ev.action ?? '')} · {String(ev.title ?? ev.id ?? '')}\n </p>\n ))}\n </div>\n )}\n\n {report !== null && (report.rotation.length > 0 || report.weak.length > 0 || report.reused.length > 0) && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('reportTitle')}</p>\n {report.rotation.length > 0 && (\n <>\n <p className={css.reportLine}>{t('reportRotation')}: {report.rotation.length}</p>\n {(report.rotation as Array<{ title?: string; due?: string; daysLeft?: number }>).slice(0, 8).map((item, i) => (\n <p key={i} className={css.reportSub}>\n · {String(item.title ?? '?')}{item.due === 'expired' ? ` (${t('dueExpired')})` : item.due === 'soon' ? ` (${t('dueExpiring')} ${item.daysLeft ?? 0}d)` : ` (${t('dueNow')})`}\n </p>\n ))}\n </>\n )}\n {report.weak.length > 0 && (\n <>\n <p className={css.reportLine}>{t('reportWeak')}: {report.weak.length}</p>\n {(report.weak as Array<{ title?: string }>).slice(0, 5).map((item, i) => (\n <p key={i} className={css.reportSub}>· {String(item.title ?? '?')}</p>\n ))}\n </>\n )}\n {report.reused.length > 0 && (\n <>\n <p className={css.reportLine}>{t('reportReused')}: {report.reused.length}</p>\n {(report.reused as Array<{ entries?: Array<{ title?: string }> }>).slice(0, 3).map((group, i) => (\n <p key={i} className={css.reportSub}>\n · {(group.entries ?? []).slice(0, 3).map(e => String(e.title ?? '?')).join(' / ')}\n </p>\n ))}\n </>\n )}\n </div>\n )}\n\n {audit.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('auditTitle')} ({audit.length})</p>\n {audit.slice(0, 6).map(item => (\n <div key={item.id} className={css.auditRow}>\n <span className={css.dupNames}>{item.title}</span>\n <span className={css.auditIssues}>{item.issues.join('; ')}</span>\n <button\n type=\"button\"\n className={css.dupMerge}\n onClick={() => void startEdit(item.id)}\n disabled={busy}\n >{t('auditEdit')}</button>\n </div>\n ))}\n </div>\n )}\n\n {dupList.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('dupTitle')} ({dupList.length})</p>\n {dupList.slice(0, 5).map((group, gi) => (\n <div key={gi} className={css.dupGroup}>\n <span className={css.dupNames}>{group.map(g => g.title).join(' / ')}</span>\n <button\n type=\"button\"\n className={css.dupMerge}\n onClick={() => void mergeEntries(group)}\n disabled={busy || readonly}\n >{t('dupMerge')}</button>\n </div>\n ))}\n </div>\n )}\n\n {state.status === 'ready' && (state.entries.length > 0 || trashEntries.length > 0) && (\n <button\n type=\"button\"\n className={css.trashButton}\n onClick={() => {\n if (!showTrash) void trash().then(setTrashEntries)\n setShowTrash(!showTrash)\n }}\n >{showTrash ? t('hideTrash') : t('showTrash')}{trashEntries.length > 0 ? ` (${trashEntries.length})` : ''}</button>\n )}\n\n {showTrash && (\n <ul className={css.list}>\n {trashEntries.map(entry => (\n <li key={entry.id} className={css.row}>\n <div className={css.rowMain}>\n <span className={css.title}>{entry.title}</span>\n <span className={css.identity}>{t('trashed')}</span>\n </div>\n <div className={css.rowActions}>\n <button\n type=\"button\"\n onClick={() => { void restore(entry.id).then(() => { void trash().then(setTrashEntries); void refresh() }) }}\n disabled={busy || readonly}\n >{t('restore')}</button>\n </div>\n </li>\n ))}\n {trashEntries.length === 0 && <p className={css.empty}>{t('trashEmpty')}</p>}\n </ul>\n )}\n {showTrash && trashEntries.length > 0 && (\n <>\n <button\n type=\"button\"\n className={css.trashButton}\n onClick={() => {\n setBusy(true)\n void undeleteAll().then(() => {\n void trash().then(setTrashEntries)\n void refresh()\n setBusy(false)\n }, () => setBusy(false))\n }}\n disabled={busy || readonly}\n >{t('restoreAll')}</button>\n <button\n type=\"button\"\n className={css.dangerButton}\n onClick={() => {\n if (!window.confirm(t('clearTrashConfirm'))) return\n setBusy(true)\n void Promise.all(trashEntries.map(e => remove(e.id))).then(() => {\n void trash().then(setTrashEntries)\n void refresh()\n setBusy(false)\n }, () => setBusy(false))\n }}\n disabled={busy || readonly}\n >{t('clearTrash')}</button>\n </>\n )}\n\n {state.status === 'ready' && state.entries.length > 0 && (\n <ul className={css.list}>\n {state.entries.filter(entry => (kindFilter === '' || entry.kind === kindFilter) && (tagFilter === '' || (entry.tags ?? []).includes(tagFilter))).sort((a, b) => sortBy === 'alpha' ? a.title.localeCompare(b.title) : (b.updatedAt ?? 0) - (a.updatedAt ?? 0)).map(entry => {\n const totpInfo = totpMap[entry.id]\n const remaining = totpInfo !== undefined && totpInfo.until > 0 ? Math.max(0, Math.ceil((totpInfo.until - nowTick) / 1000)) : undefined\n const frac = remaining !== undefined ? remaining / 30 : 0\n const code = totpInfo?.code\n return (\n <li key={entry.id} className={`${css.row}${dueMap[entry.id] !== undefined ? ` ${dueMap[entry.id]!.due === 'expired' ? css.rowExpired : css.rowDue}` : ''}`}>\n <div className={css.rowMain} onClick={() => setExpandedId(expandedId === entry.id ? null : entry.id)}>\n <span className={css.title} style={entry.color !== undefined && entry.color !== '' ? { borderLeft: `3px solid ${entry.color}`, paddingLeft: 6 } : undefined}>\n <span className={css.kindIcon}>{entry.icon ?? kindIcon(entry.kind)}</span>\n {(entry as VaultSummaryWire & { favorite?: boolean }).favorite && (\n <span className={css.pinStar} title={t('pinned')}>★</span>\n )}\n {entry.title}\n {(entry as VaultSummaryWire & { sensitivity?: string }).sensitivity === 'high' && (\n <span className={css.highBadge}>{t('highSensitivity')}</span>\n )}\n {dueMap[entry.id] !== undefined && (\n <span className={`${css.dueBadge} ${dueMap[entry.id]!.due === 'expired' ? css.badgeDanger : css.badgeWarn}`}>\n {dueMap[entry.id]!.due === 'expired' ? t('dueExpired') : dueMap[entry.id]!.due === 'soon' ? `${t('dueExpiring')} ${dueMap[entry.id]!.daysLeft}d` : t('dueNow')}\n </span>\n )}\n </span>\n <span className={css.identity}>{identityLine(entry)}</span>\n {code !== undefined && (\n <span className={css.totp}>\n <svg className={css.totpRing} width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" fill=\"none\" stroke=\"var(--dsh-color-border, #ddd)\" strokeWidth=\"2\" />\n <circle\n cx=\"8\" cy=\"8\" r=\"6.5\" fill=\"none\"\n stroke={remaining !== undefined && remaining <= 5 ? '#cf3d3d' : '#2e9e5b'}\n strokeWidth=\"2\" strokeLinecap=\"round\"\n strokeDasharray={`${(frac * 2 * Math.PI * 6.5).toFixed(1)} ${(2 * Math.PI * 6.5).toFixed(1)}`}\n transform=\"rotate(-90 8 8)\"\n />\n </svg>\n {code}{remaining !== undefined ? ` (${remaining}s)` : ''}\n </span>\n )}\n </div>\n {expandedId === entry.id && (\n <div className={css.detailBox}>\n {Object.entries(entry).filter(([k]) => !['id', 'title', 'favorite'].includes(k) && entry[k as keyof VaultSummaryWire] !== undefined).map(([k, v]) => (\n <span key={k} className={css.detailItem}>\n <strong>{k}</strong>: {formatDetail(k, v)}\n </span>\n ))}\n </div>\n )}\n <div className={css.rowActions}>\n {copiedId === entry.id && <span className={css.copied}>{t('copied')}</span>}\n <button\n type=\"button\"\n onClick={() => void copyValue(entry.id, entry.username ?? entry.title)}\n disabled={busy}\n >{t('copy')}</button>\n <button\n type=\"button\"\n onClick={() => {\n setBusy(true)\n void get(entry.id).then(r => {\n if (r.found && r.entry?.password) void copyValue(entry.id, r.entry.password)\n setBusy(false)\n }, () => setBusy(false))\n }}\n disabled={busy || readonly}\n >{t('copyPassword')}</button>\n <button type=\"button\" onClick={() => void showTotp(entry.id)} disabled={busy}>{t('totp')}</button>\n {code !== undefined && (\n <button type=\"button\" onClick={() => void copyValue(entry.id, code)} disabled={busy}>{t('copyCode')}</button>\n )}\n <button type=\"button\" onClick={() => void touch(entry.id).then(() => void refresh())} disabled={busy || readonly} title={t('touchHint')}>{t('touch')}</button>\n <button type=\"button\" onClick={() => void startEdit(entry.id)} disabled={busy || readonly}>{t('edit')}</button>\n <button\n type=\"button\"\n className={css.deleteButton}\n onClick={() => void removeEntry(entry.id)}\n disabled={busy || readonly}\n >{t('delete')}</button>\n </div>\n </li>\n )\n })}\n </ul>\n )}\n\n {state.status === 'ready' && (\n <div className={css.healthBar}>\n {vaultStats !== null && typeof vaultStats.total === 'number' && (\n <span className={css.badge}>{t('entryCount')}: {String(vaultStats.total)}</span>\n )}\n {vaultStats !== null && typeof vaultStats.withTotp === 'number' && (\n <span className={css.badge}>TOTP: {String(vaultStats.withTotp)}</span>\n )}\n {vaultStats !== null && typeof vaultStats.highSensitivity === 'number' && (\n <span className={css.badge}>{t('highSensitivity')}: {String(vaultStats.highSensitivity)}</span>\n )}\n {report !== null && report.strength !== null && (\n <span className={`${css.badge} ${report.strength.weak > 0 ? css.badgeDanger : css.badgeOk}`}>\n {t('healthStrength')}: {report.strength.weak}W/{report.strength.fair}F/{report.strength.strong}S\n </span>\n )}\n {report !== null && report.rotation.length > 0 && (\n <span className={`${css.badge} ${css.badgeWarn}`}>{t('reportRotation')}: {report.rotation.length}</span>\n )}\n {report !== null && report.weak.length > 0 && (\n <span className={`${css.badge} ${css.badgeDanger}`}>{t('reportWeak')}: {report.weak.length}</span>\n )}\n {report !== null && report.reused.length > 0 && (\n <span className={`${css.badge} ${css.badgeDanger}`}>{t('reportReused')}: {report.reused.length}</span>\n )}\n {dupGroups > 0 && (\n <span className={`${css.badge} ${css.badgeWarn}`}>{t('dupGroups')}: {dupGroups}</span>\n )}\n {report !== null && report.rotation.length === 0 && report.weak.length === 0 && report.reused.length === 0 && (\n <span className={`${css.badge} ${css.badgeOk}`}>{t('healthOk')}</span>\n )}\n {backupInfo !== null && backupInfo.daysSinceBackup >= 0 && (\n <span className={`${css.badge} ${backupInfo.daysSinceBackup > 14 ? css.badgeDanger : backupInfo.daysSinceBackup > 7 ? css.badgeWarn : ''}`}>\n {t('healthBackup')}: {backupInfo.daysSinceBackup}d\n </span>\n )}\n <button type=\"button\" className={css.backupButton} onClick={() => void backupNow()} disabled={busy}>\n {t('backupNow')}\n </button>\n </div>\n )}\n {state.status === 'ready' && (\n <p className={css.footer}>\n {t('entryCount')}: {state.entries.length}\n {vaultStats !== null && typeof vaultStats.withTotp === 'number' && ` · TOTP: ${String(vaultStats.withTotp)}`}\n {vaultStats !== null && typeof vaultStats.highSensitivity === 'number' && ` · ${t('highSensitivity')}: ${String(vaultStats.highSensitivity)}`}\n {backupInfo !== null && backupInfo.daysSinceBackup >= 0 && ` · backup: ${backupInfo.daysSinceBackup}d ago`}\n {vaultStats !== null && typeof vaultStats.byTag === 'object' && vaultStats.byTag !== null\n && Object.keys(vaultStats.byTag as Record<string, unknown>).length > 0\n && ` · tags: ${Object.entries(vaultStats.byTag as Record<string, unknown>).map(([k, v]) => `${k}(${String(v)})`).join(' ')}`}\n </p>\n )}\n\n {editor.status !== 'closed' && (\n <div className={css.editor} role=\"dialog\" aria-label={editor.status === 'creating' ? t('add') : t('edit')}>\n <div className={css.editorBody}>\n {FORM_FIELDS.map(field => (\n <label key={field.key} className={css.field}>\n <span>{t(field.label)}</span>\n {field.key === 'kind' ? (\n <select\n value={form.kind ?? 'login'}\n onChange={event => setForm(previous => ({ ...previous, kind: event.target.value }))}\n >\n {Object.entries(KIND_KEYS).map(([value, key]) => (\n <option key={value} value={value}>{t(key)}</option>\n ))}\n </select>\n ) : field.key === 'title' ? (\n <input\n value={form.title ?? ''}\n onChange={event => setForm(previous => ({ ...previous, title: event.target.value }))}\n />\n ) : field.key === 'password' || field.key === 'otpSecret' || field.key === 'apiKey'\n || field.key === 'secret' || field.key === 'accessToken' || field.key === 'refreshToken'\n || field.key === 'privateKey' ? (\n <span className={css.secretField}>\n <input\n type={revealed[field.key] ? 'text' : 'password'}\n value={(form[field.key] as string | undefined) ?? ''}\n onChange={event => setForm(previous => ({ ...previous, [field.key]: event.target.value }))}\n />\n <button\n type=\"button\"\n className={css.revealButton}\n onClick={() => setRevealed(previous => ({ ...previous, [field.key]: !previous[field.key] }))}\n >{revealed[field.key] ? t('hide') : t('show')}</button>\n </span>\n ) : field.key === 'expiresAt' ? (\n <input\n type=\"datetime-local\"\n value={form.expiresAt !== undefined ? new Date(form.expiresAt).toISOString().slice(0, 16) : ''}\n onChange={event => {\n const raw = event.target.value\n const epoch = raw.length > 0 ? Date.parse(raw) : NaN\n setForm(previous => ({ ...previous, expiresAt: Number.isNaN(epoch) ? undefined : epoch }))\n }}\n />\n ) : field.key === 'rotationDays' ? (\n <input\n type=\"number\"\n min={0}\n max={3650}\n placeholder={t('rotationClearHint')}\n value={form.rotationDays ?? ''}\n onChange={event => {\n const raw = event.target.value\n setForm(previous => ({ ...previous, rotationDays: raw.length > 0 ? Number(raw) : undefined }))\n }}\n />\n ) : field.key === 'sensitivity' ? (\n <select\n value={form.sensitivity ?? 'normal'}\n onChange={event => setForm(previous => ({ ...previous, sensitivity: event.target.value === 'high' ? 'high' : 'normal' }))}\n >\n <option value=\"normal\">{t('sensitivityNormal')}</option>\n <option value=\"high\">{t('sensitivityHigh')}</option>\n </select>\n ) : field.key === 'favorite' ? (\n <label className={css.checkField}>\n <input\n type=\"checkbox\"\n checked={form.favorite ?? false}\n onChange={event => setForm(previous => ({ ...previous, favorite: event.target.checked }))}\n />\n {t('favoriteHint')}\n </label>\n ) : (\n <input\n type=\"text\"\n value={(form[field.key] as string | undefined) ?? ''}\n onChange={event => setForm(previous => ({ ...previous, [field.key]: event.target.value }))}\n />\n )}\n </label>\n ))}\n <label className={css.field}>\n <span>{t('fieldTags')}</span>\n <input\n value={tagsDraft}\n onChange={event => setTagsDraft(event.target.value)}\n placeholder=\"dev, prod\"\n />\n </label>\n <label className={css.field}>\n <span>{t('fieldCustom')}</span>\n <textarea\n value={fieldsDraft}\n onChange={event => setFieldsDraft(event.target.value)}\n rows={3}\n placeholder=\"region=us-east-1 team=infra\"\n />\n </label>\n </div>\n <div className={css.editorActions}>\n <button type=\"button\" onClick={() => setEditor({ status: 'closed' })} disabled={busy}>{t('cancel')}</button>\n <button type=\"button\" className={css.saveButton} onClick={() => void save()} disabled={busy}>{t('save')}</button>\n </div>\n </div>\n )}\n </section>\n )\n}\n","/** Copy dictionaries for the Vault settings section. */\n\n/** English strings (the key-set source of truth for this pair). */\nexport const en = {\n nav: 'Vault',\n heading: 'Vault',\n intro: 'Encrypted credentials stored on this machine.',\n searchPlaceholder: 'Search title, username, email, host…',\n loading: 'Loading…',\n empty: 'No credentials yet. Add one to get started.',\n emptyHint: 'Tip: you can ask the assistant to save an API key or token you share in chat — with auto-capture on it offers to store it for you. Bulk importing? Ask for vault_import_csv with a CSV file path.',\n emptyHintReadonly: 'The vault is in readonly mode — credentials can be read but not added here. Switch accessMode to \"readwrite\" to enable writes.',\n modeLabel: 'Access mode',\n autoCaptureLabel: 'Auto-capture credentials from chat',\n modeReadonly: 'Read-only',\n modeAsk: 'Ask before writing',\n modeAuto: 'Automatic read-write',\n modeReadonlyHint: 'Read-only — mutations disabled',\n modeAskHint: 'Prompt before writing — every add/update/delete asks you',\n modeAutoHint: 'Automatic read-write — no per-call prompt',\n autoCaptureOn: 'auto-capture on',\n autoCaptureOff: 'auto-capture off',\n clearSearch: 'Clear search',\n entryCount: 'Entries',\n reportTitle: 'Health & rotation',\n recentActivity: 'Recent activity',\n recentlyAdded: 'Recently added',\n reportRotation: 'expired / due for rotation',\n reportWeak: 'weak passwords',\n reportReused: 'credentials reused across entries',\n dupGroups: 'duplicate groups',\n dupTitle: 'Duplicate entries',\n dupMerge: 'Merge',\n healthOk: 'vault healthy',\n healthBackup: 'backup',\n backupNow: 'Backup now',\n backupDone: 'Backup created',\n lockedBanner: 'Vault is locked — unlock it with vault_unlock to read or write entries.',\n vaultSelect: 'Active vault',\n touch: 'Used',\n touchHint: 'Mark as recently used',\n auditTitle: 'Needs attention',\n auditEdit: 'Edit',\n healthStrength: 'strength',\n dueExpired: 'EXPIRED',\n dueExpiring: 'expires in',\n dueNow: 'rotation due',\n showTrash: 'Trash',\n hideTrash: 'Hide trash',\n trashed: 'in trash',\n trashEmpty: 'Trash is empty',\n restore: 'Restore',\n clearTrash: 'Empty trash',\n restoreAll: 'Restore all',\n clearTrashConfirm: 'Permanently delete ALL trashed entries? This cannot be undone.',\n show: 'Show',\n hide: 'Hide',\n allKinds: 'All kinds',\n allTags: 'All tags',\n sortAlpha: 'Sort: A–Z',\n sortRecent: 'Sort: recent',\n highSensitivity: 'HIGH',\n pinned: 'Pinned',\n add: 'Add credential',\n quickAdd: 'Quick add',\n cancel: 'Cancel',\n save: 'Save',\n edit: 'Edit',\n delete: 'Delete',\n deleteConfirm: 'Delete this entry? This cannot be undone.',\n copy: 'Copy',\n copyPassword: 'Copy password',\n copyCode: 'Copy code',\n copied: 'Copied',\n totp: 'Code',\n fieldTitle: 'Title',\n fieldKind: 'Kind',\n fieldUsername: 'Username',\n fieldEmail: 'Email',\n fieldPhone: 'Phone',\n fieldPassword: 'Password',\n fieldHost: 'Host',\n fieldPort: 'Port',\n fieldApiKey: 'API key',\n fieldSecret: 'Secret',\n fieldAccessToken: 'Access token',\n fieldRefreshToken: 'Refresh token',\n fieldOtpSecret: 'OTP secret',\n fieldUrl: 'URL',\n fieldNotes: 'Notes',\n fieldTags: 'Tags',\n fieldIcon: 'Icon (emoji)',\n fieldExpiresAt: 'Expires at',\n fieldRotationDays: 'Rotation (days, 0 = never)',\n fieldSensitivity: 'Sensitivity',\n fieldFavorite: 'Pinned',\n sensitivityNormal: 'normal',\n sensitivityHigh: 'high',\n favoriteHint: 'Show at top',\n rotationClearHint: '0 clears rotation',\n fieldColor: 'Color',\n fieldCustom: 'Custom fields (key=value per line)',\n error: 'Something went wrong.',\n kindLogin: 'Login',\n kindSsh: 'SSH',\n kindApiKey: 'API key',\n kindSecret: 'Secret',\n kindOauth: 'OAuth',\n kindCustom: 'Custom',\n} as const\n\nexport type VaultLocaleKey = keyof typeof en\n\n/** Chinese strings (same keys as English). */\nexport const zh: Record<VaultLocaleKey, string> = {\n nav: '凭据库',\n heading: 'Vault 凭据库',\n intro: '本机加密存储的凭据。',\n searchPlaceholder: '搜索标题、用户名、邮箱、主机…',\n loading: '加载中…',\n empty: '还没有凭据,添加一条开始使用。',\n emptyHint: '提示:你可以在对话中把 API Key 或 token 交给助手保存——开启自动捕获后,它会在你同意时帮你存入本库。批量导入?让助手调用 vault_import_csv 并给出 CSV 路径即可。',\n emptyHintReadonly: '当前为只读模式——只能读取凭据,不能在此添加。将 accessMode 改为 \"readwrite\" 即可启用写入。',\n modeLabel: '访问模式',\n autoCaptureLabel: '自动捕获对话中的凭据',\n modeReadonly: '只读',\n modeAsk: '写入前询问',\n modeAuto: '自动读写',\n modeReadonlyHint: '只读 —— 变更已禁用',\n modeAskHint: '写入前询问 —— 每次增/改/删都会征求你的确认',\n modeAutoHint: '自动读写 —— 无需逐次确认',\n autoCaptureOn: '自动捕获已开启',\n autoCaptureOff: '自动捕获已关闭',\n clearSearch: '清除搜索',\n entryCount: '条目数',\n reportTitle: '健康与轮换',\n recentActivity: '最近活动',\n recentlyAdded: '最近添加',\n reportRotation: '已过期 / 待轮换',\n reportWeak: '弱密码',\n reportReused: '跨条目复用的凭据',\n dupGroups: '重复分组',\n dupTitle: '重复条目',\n dupMerge: '合并',\n healthOk: '凭据库健康',\n healthBackup: '备份',\n backupNow: '立即备份',\n backupDone: '备份已创建',\n lockedBanner: '保险库已锁定 —— 请使用 vault_unlock 解锁后再读写条目。',\n vaultSelect: '当前保险库',\n touch: '标记已用',\n touchHint: '标记为最近使用',\n auditTitle: '需要处理',\n auditEdit: '编辑',\n healthStrength: '强度',\n dueExpired: '已过期',\n dueExpiring: '将于',\n dueNow: '待轮换',\n showTrash: '回收站',\n hideTrash: '隐藏回收站',\n trashed: '已删除',\n trashEmpty: '回收站为空',\n restore: '恢复',\n clearTrash: '清空回收站',\n restoreAll: '全部恢复',\n clearTrashConfirm: '永久删除回收站中全部条目?此操作不可撤销。',\n show: '显示',\n hide: '隐藏',\n allKinds: '全部类型',\n allTags: '全部标签',\n sortAlpha: '排序:A–Z',\n sortRecent: '排序:最近',\n highSensitivity: '高敏',\n pinned: '已置顶',\n add: '新增凭据',\n quickAdd: '快速添加',\n cancel: '取消',\n save: '保存',\n edit: '编辑',\n delete: '删除',\n deleteConfirm: '确定删除该条目?此操作不可撤销。',\n copy: '复制',\n copyPassword: '复制密码',\n copyCode: '复制验证码',\n copied: '已复制',\n totp: '验证码',\n fieldTitle: '标题',\n fieldKind: '类型',\n fieldUsername: '用户名',\n fieldEmail: '邮箱',\n fieldPhone: '手机号',\n fieldPassword: '密码',\n fieldHost: '主机',\n fieldPort: '端口',\n fieldApiKey: 'API 密钥',\n fieldSecret: 'Secret',\n fieldAccessToken: '访问令牌',\n fieldRefreshToken: '刷新令牌',\n fieldOtpSecret: 'TOTP 密钥',\n fieldUrl: 'URL',\n fieldNotes: '备注',\n fieldTags: '标签',\n fieldIcon: '图标(emoji)',\n fieldExpiresAt: '过期时间',\n fieldRotationDays: '轮换周期(天,0=永不)',\n fieldSensitivity: '敏感级别',\n fieldFavorite: '置顶',\n sensitivityNormal: '普通',\n sensitivityHigh: '高敏',\n favoriteHint: '列表置顶显示',\n rotationClearHint: '0 清除轮换',\n fieldColor: '颜色',\n fieldCustom: '自定义字段(每行 key=value)',\n error: '操作失败。',\n kindLogin: '登录',\n kindSsh: 'SSH',\n kindApiKey: 'API 密钥',\n kindSecret: 'Secret',\n kindOauth: 'OAuth',\n kindCustom: '自定义',\n}\n","/**\n * dsh-vault browser half: a Vault settings page managing encrypted\n * credentials — list, search, add, edit, delete, and copy — through the host\n * VaultGateway remote over the /api RPC channel.\n *\n * @module dsh-vault/client\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { VaultSection, type VaultSectionInjected } from './VaultSection.tsx'\nimport type { VaultSectionTypes } from './VaultSection.tsx'\nimport { en, zh, type VaultLocaleKey } from './locales.ts'\n\nexport type { VaultSectionInjected, VaultSectionProps } from './VaultSection.tsx'\nexport type { VaultSectionTypes } from './VaultSection.tsx'\nexport type { VaultLocaleKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Vault settings page copy. */\n 'settings.vault': VaultLocaleKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'settings.vault'\n\n/** Services required by the Settings registration and the RPC face. */\nexport const inject = ['slots', 'locale', 'connection']\n\n/**\n * Register the Vault settings section once the `settings.section` declaration\n * is on the ledger. The section talks to the host through the connection RPC\n * channel (endpoints `vault/*` served by the host VaultGateway remote).\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-vault: dictionaries')\n\n const t = ctx.locale.bind(NS)\n const connection = ctx.get('connection') as ConnectionHandle\n\n /** Invoke one host vault remote and normalize the RPC envelope. */\n async function invoke<T>(method: string, args: Record<string, unknown> = {}): Promise<T> {\n const result = await connection.rpc.call('/api', `vault/${method}`, { args })\n if (!result.ok) {\n throw new Error(`vault.${method} failed: ${result.error.code}: ${result.error.message}`)\n }\n return result.value as T\n }\n\n const injected = (): VaultSectionInjected => ({\n t,\n config: () => invoke<VaultSectionTypes['config']>('config'),\n setAccessMode: (mode) => invoke<VaultSectionTypes['config']>('setAccessMode', { mode }),\n setAutoCapture: (enabled) => invoke<VaultSectionTypes['config']>('setAutoCapture', { enabled }),\n list: () => invoke<{ entries: VaultSectionTypes['entries'] }>('list').then(r => r.entries),\n search: (query, limit) => invoke<{ entries: VaultSectionTypes['entries'] }>('search', { query, limit: limit ?? 50 }).then(r => r.entries),\n get: (id) => invoke<{ found: boolean; entry?: VaultSectionTypes['fullEntry'] }>('get', { id }),\n add: (patch) => invoke<VaultSectionTypes['summaryEntry']>('add', { patch }),\n update: (id, patch) => invoke<{ found: boolean; entry?: VaultSectionTypes['summaryEntry'] }>('update', { id, patch }),\n remove: (id) => invoke<{ deleted: boolean }>('delete', { id }),\n trash: () => invoke<{ entries: VaultSectionTypes['entries'] }>('trash').then(r => r.entries),\n rotation: () => invoke<{ entries: unknown[] }>('rotation').then(r => r.entries),\n history: () => invoke<{ events: unknown[] }>('history').then(r => r.events),\n stats: () => invoke<Record<string, unknown>>('stats'),\n recent: () => invoke<{ entries: unknown[] }>('recent').then(r => r.entries),\n backupStatus: () => invoke<{ daysSinceBackup: number; backups: number }>('backupStatus'),\n backup: (maxBackups) => invoke<{ path: string; kept: number; pruned: number }>('backup', { ...(maxBackups !== undefined ? { maxBackups } : {}) }),\n health: () => invoke<{ weak: unknown[]; reused: unknown[]; strength: { weak: number; fair: number; strong: number } }>('health'),\n duplicates: () => invoke<{ groups: number }>('duplicates'),\n status: () => invoke<{ locked: boolean; entries: number }>('status'),\n switchVault: (name) => invoke<{ switched: boolean; name: string }>('switchVault', { name }),\n listVaults: () => invoke<Array<{ name: string; active: boolean }>>('listVaults'),\n touch: (id) => invoke<{ touched: boolean }>('touch', { id }),\n verifyAll: () => invoke<Array<{ id: string; title: string; issues: string[] }>>('verifyAll'),\n duplicateGroups: () => invoke<Array<Array<{ id: string; title: string }>>>('duplicateGroups'),\n merge: (fromId, toId, keepSource) => invoke<{ found: boolean }>('merge', { fromId, toId, keepSource: keepSource ?? false }),\n restore: (id) => invoke<{ restored: boolean }>('restore', { id }),\n undeleteAll: () => invoke<{ restored: number }>('undeleteAll'),\n totp: (id) => invoke<{ code: string; label?: string; secondsRemaining: number }>('totp', { id }),\n })\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'vault',\n order: 30,\n label: () => t('nav'),\n inject: injected,\n }, VaultSection))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["css"],"sources":["../src/client/VaultSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Vault settings section: list, search, add, edit, delete, and copy encrypted\n * credentials. All mutations go through the host VaultGateway remote; secrets\n * are shown only inside the edit form or a copy action, never in the list.\n */\n\nimport { useEffect, useId, useMemo, useState, type ReactNode } from 'react'\nimport type { PropsLocale, PropsRuntime, InjectFace, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { VaultLocaleKey } from './locales.ts'\nimport css from './VaultSection.module.css'\n\n/** Wire shapes shared with the host gateway (mirror of src/index.ts types). */\nexport interface VaultSummaryWire {\n id: string\n title: string\n sensitivity?: string\n kind?: string\n username?: string\n email?: string\n phone?: string\n host?: string\n port?: string\n url?: string\n tags?: string[]\n icon?: string\n color?: string\n updatedAt?: number\n}\n\nexport interface VaultFullWire {\n id: string\n title: string\n kind?: string\n username?: string\n email?: string\n phone?: string\n password?: string\n host?: string\n port?: string\n privateKey?: string\n apiKey?: string\n secret?: string\n accessToken?: string\n refreshToken?: string\n expiresAt?: number\n rotationDays?: number\n sensitivity?: string\n favorite?: boolean\n otpSecret?: string\n url?: string\n notes?: string\n tags?: string[]\n icon?: string\n color?: string\n fields?: Record<string, unknown>\n}\n\n/** Patch shape accepted by vault.add / vault.update. */\nexport type VaultPatch = Partial<Omit<VaultFullWire, 'id'>>\n\n/** Registration-side business face supplied by the plugin entry. */\nexport interface VaultSectionInjected {\n t: TranslateNS<'settings.vault'>\n config: () => Promise<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }>\n setAccessMode: (mode: 'readonly' | 'ask' | 'auto') => Promise<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }>\n setAutoCapture: (enabled: boolean) => Promise<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }>\n list: () => Promise<VaultSummaryWire[]>\n search: (query: string, limit?: number) => Promise<VaultSummaryWire[]>\n get: (id: string) => Promise<{ found: boolean; entry?: VaultFullWire }>\n add: (patch: VaultPatch & { title: string }) => Promise<VaultSummaryWire>\n update: (id: string, patch: VaultPatch) => Promise<{ found: boolean; entry?: VaultSummaryWire }>\n remove: (id: string) => Promise<{ deleted: boolean }>\n trash: () => Promise<VaultSummaryWire[]>\n rotation: () => Promise<unknown[]>\n history: () => Promise<unknown[]>\n stats: () => Promise<Record<string, unknown>>\n recent: () => Promise<unknown[]>\n backupStatus: () => Promise<{ daysSinceBackup: number; backups: number }>\n backup: (maxBackups?: number) => Promise<{ path: string; kept: number; pruned: number }>\n health: () => Promise<{ weak: unknown[]; reused: unknown[]; strength: { weak: number; fair: number; strong: number } }>\n duplicates: () => Promise<{ groups: number }>\n duplicateGroups: () => Promise<Array<Array<{ id: string; title: string }>>>\n status: () => Promise<{ locked: boolean; entries: number }>\n switchVault: (name: string) => Promise<{ switched: boolean; name: string }>\n listVaults: () => Promise<Array<{ name: string; active: boolean }>>\n touch: (id: string) => Promise<{ touched: boolean }>\n verifyAll: () => Promise<Array<{ id: string; title: string; issues: string[] }>>\n merge: (fromId: string, toId: string, keepSource?: boolean) => Promise<{ found: boolean }>\n restore: (id: string) => Promise<{ restored: boolean }>\n undeleteAll: () => Promise<{ restored: number }>\n totp: (id: string) => Promise<{ code: string; label?: string; secondsRemaining: number }>\n}\n\n/** Type-level alias so consumers can reference the wire shapes without values. */\nexport type VaultSectionTypes = {\n entries: VaultSummaryWire[]\n fullEntry: VaultFullWire\n summaryEntry: VaultSummaryWire\n config: { accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean }\n accessModes: Array<'readonly' | 'ask' | 'auto'>\n}\n\n/** Full component props assembled by the Settings slot renderer. */\nexport type VaultSectionProps =\n PropsRuntime<'settings.section'>\n & PropsLocale<'settings.vault'>\n & InjectFace<VaultSectionInjected>\n\n/** The editable form fields we render (subset of the full wire). */\ntype FormFields = {\n title?: string | undefined\n kind?: string | undefined\n username?: string | undefined\n email?: string | undefined\n phone?: string | undefined\n password?: string | undefined\n host?: string | undefined\n port?: string | undefined\n privateKey?: string | undefined\n apiKey?: string | undefined\n secret?: string | undefined\n accessToken?: string | undefined\n refreshToken?: string | undefined\n otpSecret?: string | undefined\n url?: string | undefined\n notes?: string | undefined\n icon?: string | undefined\n color?: string | undefined\n expiresAt?: number | undefined\n rotationDays?: number | undefined\n sensitivity?: string | undefined\n favorite?: boolean | undefined\n}\n\nconst FORM_FIELDS: Array<{ key: keyof FormFields; label: VaultLocaleKey }> = [\n { key: 'title', label: 'fieldTitle' },\n { key: 'kind', label: 'fieldKind' },\n { key: 'username', label: 'fieldUsername' },\n { key: 'email', label: 'fieldEmail' },\n { key: 'phone', label: 'fieldPhone' },\n { key: 'password', label: 'fieldPassword' },\n { key: 'host', label: 'fieldHost' },\n { key: 'port', label: 'fieldPort' },\n { key: 'apiKey', label: 'fieldApiKey' },\n { key: 'secret', label: 'fieldSecret' },\n { key: 'accessToken', label: 'fieldAccessToken' },\n { key: 'refreshToken', label: 'fieldRefreshToken' },\n { key: 'otpSecret', label: 'fieldOtpSecret' },\n { key: 'url', label: 'fieldUrl' },\n { key: 'notes', label: 'fieldNotes' },\n { key: 'expiresAt', label: 'fieldExpiresAt' },\n { key: 'rotationDays', label: 'fieldRotationDays' },\n { key: 'sensitivity', label: 'fieldSensitivity' },\n { key: 'favorite', label: 'fieldFavorite' },\n { key: 'icon', label: 'fieldIcon' },\n { key: 'color', label: 'fieldColor' },\n]\n\nconst KIND_KEYS: Record<string, VaultLocaleKey> = {\n login: 'kindLogin',\n ssh: 'kindSsh',\n 'api-key': 'kindApiKey',\n secret: 'kindSecret',\n oauth: 'kindOauth',\n custom: 'kindCustom',\n}\n\ntype ViewState =\n | { readonly status: 'loading' }\n | { readonly status: 'error' }\n | { readonly status: 'ready'; readonly entries: VaultSummaryWire[] }\n\ntype EditorState =\n | { readonly status: 'closed' }\n | { readonly status: 'creating' }\n | { readonly status: 'editing'; readonly entry: VaultFullWire }\n\nfunction emptyForm(): FormFields {\n return { title: '', kind: 'login', username: '', email: '', phone: '', password: '', host: '', port: '', icon: '', color: '' }\n}\n\n/** Render the Vault settings section. */\nexport function VaultSection(props: VaultSectionProps): ReactNode {\n const { t, config, setAccessMode, setAutoCapture, list, search, get, add, update, remove, trash, rotation, health, duplicates, duplicateGroups, merge, history, stats, backupStatus, backup, recent, restore, undeleteAll, totp, status, switchVault, listVaults, touch, verifyAll } = props\n const searchId = useId()\n const [query, setQuery] = useState('')\n const [state, setState] = useState<ViewState>({ status: 'loading' })\n const [editor, setEditor] = useState<EditorState>({ status: 'closed' })\n const [form, setForm] = useState<FormFields>(emptyForm())\n const [busy, setBusy] = useState(false)\n const [message, setMessage] = useState<string | null>(null)\n const [copiedId, setCopiedId] = useState<string | null>(null)\n const [totpMap, setTotpMap] = useState<Record<string, { code: string; until: number }>>({})\n const [nowTick, setNowTick] = useState(Date.now())\n const [tagsDraft, setTagsDraft] = useState('')\n const [fieldsDraft, setFieldsDraft] = useState('')\n const [revealed, setRevealed] = useState<Record<string, boolean>>({})\n const [kindFilter, setKindFilter] = useState('')\n const [tagFilter, setTagFilter] = useState('')\n const [expandedId, setExpandedId] = useState<string | null>(null)\n const [sortBy, setSortBy] = useState<'alpha' | 'recent'>('alpha')\n const [policy, setPolicy] = useState<{ accessMode: 'readonly' | 'ask' | 'auto'; autoCapture: boolean } | null>(null)\n const [showTrash, setShowTrash] = useState(false)\n const [trashEntries, setTrashEntries] = useState<VaultSummaryWire[]>([])\n const [report, setReport] = useState<{ rotation: unknown[]; weak: unknown[]; reused: unknown[]; strength: { weak: number; fair: number; strong: number } | null } | null>(null)\n const [dueMap, setDueMap] = useState<Record<string, { due: string; daysLeft: number }>>({})\n const [recentEvents, setRecentEvents] = useState<Array<Record<string, unknown>>>([])\n const [vaultStats, setVaultStats] = useState<Record<string, unknown> | null>(null)\n const [backupInfo, setBackupInfo] = useState<{ daysSinceBackup: number; backups: number } | null>(null)\n const [recentEntries, setRecentEntries] = useState<Array<Record<string, unknown>>>([])\n const [dupGroups, setDupGroups] = useState<number>(0)\n const [dupList, setDupList] = useState<Array<Array<{ id: string; title: string }>>>([])\n const [locked, setLocked] = useState(false)\n const [vaults, setVaults] = useState<Array<{ name: string; active: boolean }>>([])\n const [audit, setAudit] = useState<Array<{ id: string; title: string; issues: string[] }>>([])\n\n const readonly = policy?.accessMode === 'readonly'\n\n /** Switch the active vault and reload everything. */\n async function switchVaultTo(name: string): Promise<void> {\n setBusy(true)\n setMessage(null)\n try {\n await switchVault(name)\n await listVaults().then(setVaults)\n setQuery('')\n void refresh()\n status().then(value => setLocked(value.locked)).catch(() => {})\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Merge one duplicate into another (first keeps gaps filled), then refresh. */\n async function mergeEntries(group: Array<{ id: string; title: string }>): Promise<void> {\n if (group.length < 2) return\n setBusy(true)\n setMessage(null)\n try {\n const [first, second] = group\n await merge(second!.id, first!.id, false)\n await duplicateGroups().then(setDupList)\n void refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Run an encrypted backup now and refresh the backup-age badge. */\n async function backupNow(): Promise<void> {\n setBusy(true)\n setMessage(null)\n try {\n const result = await backup()\n setBackupInfo({ daysSinceBackup: 0, backups: result.kept })\n setMessage(`${t('backupDone')} (${result.kept} kept, ${result.pruned} pruned)`)\n void refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n useEffect(() => {\n let current = true\n void config().then(\n value => { if (current) setPolicy(value) },\n () => { /* policy is informational; ignore failures */ },\n )\n void status().then(\n value => { if (current) setLocked(value.locked) },\n () => { /* ignore */ },\n )\n void listVaults().then(setVaults).catch(() => {})\n return () => { current = false }\n }, [config, status, listVaults])\n\n const refresh = useMemo(() => async () => {\n setState({ status: 'loading' })\n try {\n const entries = query.trim().length === 0\n ? await list()\n : await search(query.trim())\n setState({ status: 'ready', entries })\n status().then(value => setLocked(value.locked)).catch(() => {})\n } catch {\n setState({ status: 'error' })\n }\n }, [list, search, query])\n\n useEffect(() => {\n let current = true\n const timer = window.setTimeout(() => {\n void refresh().then(\n () => { /* state already set inside refresh */ },\n () => { if (current) setState({ status: 'error' }) },\n )\n }, 250)\n return () => { current = false; window.clearTimeout(timer) }\n // refresh is memoized on query (debounced); list/search are stable.\n }, [refresh])\n\n // TOTP countdown: tick every second so the progress ring stays live, and\n // auto-refresh any code whose 30s window just expired.\n useEffect(() => {\n const timer = window.setInterval(() => setNowTick(Date.now()), 1000)\n return () => window.clearInterval(timer)\n }, [])\n\n useEffect(() => {\n for (const [id, info] of Object.entries(totpMap)) {\n if (info.until > 0 && nowTick >= info.until && info.code !== t('error')) {\n void totp(id).then(\n result => setTotpMap(previous => ({\n ...previous,\n [id]: { code: result.code, until: Date.now() + result.secondsRemaining * 1000 },\n })),\n () => { /* keep the last code; next window retries */ },\n )\n }\n }\n }, [nowTick, totpMap, totp])\n\n // Vault health & meta: load once on mount (stats, backup age, rotation,\n // weak/reused scan, recent activity) and refresh on window focus.\n useEffect(() => {\n let current = true\n const load = (): void => {\n void Promise.all([\n stats().catch(() => null),\n backupStatus().catch(() => null),\n rotation().catch(() => []),\n health().catch(() => null),\n recent().catch(() => []),\n duplicates().catch(() => null),\n ]).then(([st, bk, rot, hl, rc, dp]) => {\n if (dp !== null && typeof dp === 'object' && (dp as { groups?: number }).groups !== undefined) {\n setDupGroups((dp as { groups: number }).groups)\n }\n duplicateGroups().then(setDupList).catch(() => {})\n verifyAll().then(setAudit).catch(() => {})\n if (!current) return\n if (st !== null) setVaultStats(st as Record<string, unknown>)\n if (bk !== null) setBackupInfo(bk)\n setReport({ rotation: (rot ?? []) as unknown[], weak: ((hl?.weak ?? []) as unknown[]), reused: ((hl?.reused ?? []) as unknown[]), strength: (hl?.strength ?? null) as { weak: number; fair: number; strong: number } | null })\n const due: Record<string, { due: string; daysLeft: number }> = {}\n for (const item of (rot ?? []) as Array<{ id?: string; due?: string; daysLeft?: number }>) {\n if (item.id !== undefined && item.due !== undefined) due[item.id] = { due: item.due, daysLeft: item.daysLeft ?? 0 }\n }\n setDueMap(due)\n setRecentEntries((rc ?? []) as Array<Record<string, unknown>>)\n })\n }\n load()\n const onFocus = (): void => { load() }\n window.addEventListener('focus', onFocus)\n return () => { current = false; window.removeEventListener('focus', onFocus) }\n }, [stats, backupStatus, rotation, health, recent, duplicates, duplicateGroups, verifyAll])\n\n /** Open the editor for a new entry. */\n function startCreate(): void {\n setForm(emptyForm())\n setTagsDraft('')\n setFieldsDraft('')\n setMessage(null)\n setEditor({ status: 'creating' })\n }\n\n /** Open the editor for an existing entry (fetches full secrets). */\n async function startEdit(id: string): Promise<void> {\n setBusy(true)\n setMessage(null)\n try {\n const result = await get(id)\n if (!result.found || result.entry === undefined) {\n setMessage(t('error'))\n return\n }\n const entry = result.entry\n setForm({\n title: entry.title ?? '',\n kind: entry.kind ?? 'login',\n username: entry.username ?? '',\n email: entry.email ?? '',\n phone: entry.phone ?? '',\n password: entry.password ?? '',\n host: entry.host ?? '',\n port: entry.port ?? '',\n privateKey: entry.privateKey ?? '',\n apiKey: entry.apiKey ?? '',\n secret: entry.secret ?? '',\n accessToken: entry.accessToken ?? '',\n refreshToken: entry.refreshToken ?? '',\n otpSecret: entry.otpSecret ?? '',\n url: entry.url ?? '',\n notes: entry.notes ?? '',\n icon: entry.icon ?? '',\n color: entry.color ?? '',\n expiresAt: entry.expiresAt,\n rotationDays: entry.rotationDays,\n sensitivity: entry.sensitivity,\n favorite: entry.favorite ?? false,\n })\n setTagsDraft((entry.tags ?? []).join(', '))\n setFieldsDraft(entry.fields !== undefined ? Object.entries(entry.fields).map(([k, v]) => `${k}=${String(v)}`).join('\\n') : '')\n setEditor({ status: 'editing', entry })\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Save the current form (create or update). */\n async function save(): Promise<void> {\n if (!(form.title ?? '').trim()) {\n setMessage(t('error'))\n return\n }\n setBusy(true)\n setMessage(null)\n try {\n const tags = tagsDraft.split(',').map(x => x.trim()).filter(x => x.length > 0)\n const fields: Record<string, string> = {}\n for (const line of fieldsDraft.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.length === 0) continue\n const eq = trimmed.indexOf('=')\n if (eq <= 0) continue\n fields[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim()\n }\n const patch: VaultPatch = {\n title: (form.title ?? '').trim(),\n ...(form.kind !== undefined ? { kind: form.kind } : {}),\n ...(form.username !== undefined ? { username: form.username } : {}),\n ...(form.email !== undefined ? { email: form.email } : {}),\n ...(form.phone !== undefined ? { phone: form.phone } : {}),\n ...(form.password !== undefined ? { password: form.password } : {}),\n ...(form.host !== undefined ? { host: form.host } : {}),\n ...(form.port !== undefined ? { port: form.port } : {}),\n ...(form.privateKey !== undefined ? { privateKey: form.privateKey } : {}),\n ...(form.apiKey !== undefined ? { apiKey: form.apiKey } : {}),\n ...(form.secret !== undefined ? { secret: form.secret } : {}),\n ...(form.accessToken !== undefined ? { accessToken: form.accessToken } : {}),\n ...(form.refreshToken !== undefined ? { refreshToken: form.refreshToken } : {}),\n ...(form.otpSecret !== undefined ? { otpSecret: form.otpSecret } : {}),\n ...(form.url !== undefined ? { url: form.url } : {}),\n ...(form.notes !== undefined ? { notes: form.notes } : {}),\n ...(form.icon !== undefined ? { icon: form.icon } : {}),\n ...(form.color !== undefined ? { color: form.color } : {}),\n ...(form.expiresAt !== undefined ? { expiresAt: form.expiresAt } : {}),\n ...(form.rotationDays !== undefined ? { rotationDays: form.rotationDays } : {}),\n ...(form.sensitivity !== undefined ? { sensitivity: form.sensitivity } : {}),\n ...(form.favorite !== undefined ? { favorite: form.favorite } : {}),\n // Always send tags: an empty array clears them, and the host store\n // treats empty string values as \"clear this field\" too.\n tags,\n fields,\n }\n if (editor.status === 'creating') {\n await add(patch as VaultPatch & { title: string })\n } else if (editor.status === 'editing') {\n await update(editor.entry.id, patch)\n }\n setEditor({ status: 'closed' })\n await refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Delete an entry after confirmation. */\n async function removeEntry(id: string): Promise<void> {\n if (!window.confirm(t('deleteConfirm'))) return\n setBusy(true)\n try {\n await remove(id)\n await refresh()\n } catch {\n setMessage(t('error'))\n } finally {\n setBusy(false)\n }\n }\n\n /** Copy a field value to the clipboard and flash the row. */\n async function copyValue(id: string, value: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(value)\n } catch {\n // Clipboard may be blocked; fall back to a temporary textarea.\n const textarea = document.createElement('textarea')\n textarea.value = value\n document.body.appendChild(textarea)\n textarea.select()\n document.execCommand('copy')\n textarea.remove()\n }\n setCopiedId(id)\n window.setTimeout(() => setCopiedId(null), 1500)\n }\n\n /** Fetch and display a TOTP code for an entry with an otpSecret. */\n async function showTotp(id: string): Promise<void> {\n setBusy(true)\n try {\n const result = await totp(id)\n setTotpMap(previous => ({ ...previous, [id]: { code: result.code, until: Date.now() + result.secondsRemaining * 1000 } }))\n } catch {\n setTotpMap(previous => ({ ...previous, [id]: { code: t('error'), until: 0 } }))\n } finally {\n setBusy(false)\n }\n }\n\n /** Relative time like \"5m ago\" / \"2d ago\". */\n function relTime(epoch: unknown): string {\n const n = Number(epoch)\n if (!Number.isFinite(n) || n <= 0) return ''\n const secs = Math.max(0, Math.floor((Date.now() - n) / 1000))\n if (secs < 60) return `${secs}s`\n if (secs < 3600) return `${Math.floor(secs / 60)}m`\n if (secs < 86400) return `${Math.floor(secs / 3600)}h`\n return `${Math.floor(secs / 86400)}d`\n }\n\n /** Human-friendly value formatting for the expanded detail box. */\n function formatDetail(key: string, value: unknown): string {\n if (key === 'expiresAt' || key === 'updatedAt' || key === 'createdAt') {\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? new Date(n).toISOString().slice(0, 16).replace('T', ' ') : String(value)\n }\n if (key === 'sensitivity' && value === 'high') return t('sensitivityHigh')\n if (key === 'kind') return t(KIND_KEYS[String(value)] ?? 'kindCustom')\n if (Array.isArray(value)) return value.join(', ')\n if (typeof value === 'object' && value !== null) return JSON.stringify(value)\n return String(value)\n }\n\n /** Field-set summary line for one entry (non-secret). */\n function kindIcon(kind?: string): string {\n switch (kind ?? 'login') {\n case 'ssh': return '🖥️'\n case 'api-key': return '🔑'\n case 'oauth': return '🔐'\n case 'secret': return '🤫'\n case 'custom': return '🧩'\n default: return '👤'\n }\n }\n\n function identityLine(entry: VaultSummaryWire): string {\n const parts = [\n entry.kind !== undefined ? t(KIND_KEYS[entry.kind] ?? 'kindCustom') : t('kindLogin'),\n entry.username,\n entry.email,\n entry.phone,\n entry.host !== undefined ? `${entry.host}${entry.port !== undefined ? `:${entry.port}` : ''}` : undefined,\n entry.url,\n ].filter((value): value is string => value !== undefined && value.length > 0)\n return parts.join(' · ')\n }\n\n return (\n <section className={css.section} aria-labelledby=\"vault-heading\">\n <h2 id=\"vault-heading\">{t('heading')}</h2>\n <p className={css.intro}>{t('intro')}</p>\n\n {locked && (\n <p role=\"alert\" className={css.lockedBanner}>{t('lockedBanner')}</p>\n )}\n\n <div className={css.toolbar}>\n {vaults.length > 0 && (\n <select\n className={css.kindFilter}\n value={vaults.find(v => v.active)?.name ?? ''}\n onChange={event => void switchVaultTo(event.target.value)}\n aria-label={t('vaultSelect')}\n >\n {vaults.map(v => (\n <option key={v.name} value={v.name}>{v.name}{v.active ? ' *' : ''}</option>\n ))}\n </select>\n )}\n <label className={css.searchBox}>\n <span className=\"sr-only\">{t('searchPlaceholder')}</span>\n <input\n id={searchId}\n type=\"search\"\n placeholder={t('searchPlaceholder')}\n value={query}\n onChange={event => setQuery(event.target.value)}\n />\n {query.length > 0 && (\n <button type=\"button\" className={css.clearButton} onClick={() => setQuery('')} aria-label={t('clearSearch')}>×</button>\n )}\n </label>\n <select className={css.kindFilter} value={kindFilter} onChange={e => setKindFilter(e.target.value)} aria-label={t('fieldKind')}>\n <option value=\"\">{t('allKinds')}</option>\n {Object.entries(KIND_KEYS).map(([value, key]) => (\n <option key={value} value={value}>{t(key)}</option>\n ))}\n </select>\n <select className={css.kindFilter} value={tagFilter} onChange={e => setTagFilter(e.target.value)} aria-label={t('fieldTags')}>\n <option value=\"\">{t('allTags')}</option>\n {[...new Set(state.status === 'ready' ? state.entries.flatMap(e => e.tags ?? []) : [])].sort().map(tag => (\n <option key={tag} value={tag}>{tag}</option>\n ))}\n </select>\n <button\n type=\"button\"\n className={css.sortButton}\n onClick={() => setSortBy(sortBy === 'alpha' ? 'recent' : 'alpha')}\n >{sortBy === 'alpha' ? t('sortAlpha') : t('sortRecent')}</button>\n <button type=\"button\" className={css.addButton} onClick={startCreate} disabled={busy || readonly}>\n + {t('add')}\n </button>\n </div>\n\n {policy !== null && (\n <div className={css.policyBar}>\n <label className={css.policyField}>\n <span>{t('modeLabel')}</span>\n <select\n value={policy.accessMode}\n disabled={busy}\n onChange={event => {\n const next = event.target.value as 'readonly' | 'ask' | 'auto'\n setBusy(true)\n setMessage(null)\n void setAccessMode(next).then(\n value => { setPolicy(value); setBusy(false) },\n () => { setMessage(t('error')); setBusy(false) },\n )\n }}\n >\n <option value=\"readonly\">{t('modeReadonly')}</option>\n <option value=\"ask\">{t('modeAsk')}</option>\n <option value=\"auto\">{t('modeAuto')}</option>\n </select>\n </label>\n <label className={css.policyField}>\n <span>{t('autoCaptureLabel')}</span>\n <input\n type=\"checkbox\"\n checked={policy.autoCapture}\n disabled={busy}\n onChange={event => {\n const next = event.target.checked\n setBusy(true)\n setMessage(null)\n void setAutoCapture(next).then(\n value => { setPolicy(value); setBusy(false) },\n () => { setMessage(t('error')); setBusy(false) },\n )\n }}\n />\n </label>\n <p className={policy.accessMode === 'readonly' ? css.modeReadonly : policy.accessMode === 'ask' ? css.modeAsk : css.modeAuto}>\n {policy.accessMode === 'readonly'\n ? t('modeReadonlyHint')\n : policy.accessMode === 'ask'\n ? t('modeAskHint')\n : t('modeAutoHint')}\n {policy.autoCapture ? ` · ${t('autoCaptureOn')}` : ` · ${t('autoCaptureOff')}`}\n </p>\n </div>\n )}\n\n {message !== null && <p role=\"alert\" className={css.error}>{message}</p>}\n\n {state.status === 'loading' && <p className={css.status}>{t('loading')}</p>}\n {state.status === 'error' && <p role=\"alert\" className={css.error}>{t('error')}</p>}\n {state.status === 'ready' && state.entries.length === 0 && (\n <div className={css.emptyBox}>\n <p className={css.empty}>{t('empty')}</p>\n <p className={css.emptyHint}>{readonly ? t('emptyHintReadonly') : t('emptyHint')}</p>\n {!readonly && (\n <button type=\"button\" className={css.addButton} onClick={startCreate}>{t('quickAdd')}</button>\n )}\n </div>\n )}\n\n {recentEntries.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('recentlyAdded')}</p>\n {recentEntries.map((e, i) => (\n <p key={i} className={css.reportLine}>{String(e.title ?? '')}{relTime((e as Record<string, unknown>).updatedAt) !== '' && ` · ${relTime((e as Record<string, unknown>).updatedAt)}`}</p>\n ))}\n </div>\n )}\n\n {recentEvents.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('recentActivity')}</p>\n {recentEvents.map((ev, i) => (\n <p key={i} className={css.reportLine}>\n {String(ev.action ?? '')} · {String(ev.title ?? ev.id ?? '')}{relTime((ev as Record<string, unknown>).at) !== '' && ` · ${relTime((ev as Record<string, unknown>).at)}`}\n </p>\n ))}\n </div>\n )}\n\n {report !== null && (report.rotation.length > 0 || report.weak.length > 0 || report.reused.length > 0) && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('reportTitle')}</p>\n {report.rotation.length > 0 && (\n <>\n <p className={css.reportLine}>{t('reportRotation')}: {report.rotation.length}</p>\n {(report.rotation as Array<{ title?: string; due?: string; daysLeft?: number }>).slice(0, 8).map((item, i) => (\n <p key={i} className={css.reportSub}>\n · {String(item.title ?? '?')}{item.due === 'expired' ? ` (${t('dueExpired')})` : item.due === 'soon' ? ` (${t('dueExpiring')} ${item.daysLeft ?? 0}d)` : ` (${t('dueNow')})`}\n </p>\n ))}\n </>\n )}\n {report.weak.length > 0 && (\n <>\n <p className={css.reportLine}>{t('reportWeak')}: {report.weak.length}</p>\n {(report.weak as Array<{ title?: string }>).slice(0, 5).map((item, i) => (\n <p key={i} className={css.reportSub}>· {String(item.title ?? '?')}</p>\n ))}\n </>\n )}\n {report.reused.length > 0 && (\n <>\n <p className={css.reportLine}>{t('reportReused')}: {report.reused.length}</p>\n {(report.reused as Array<{ entries?: Array<{ title?: string }> }>).slice(0, 3).map((group, i) => (\n <p key={i} className={css.reportSub}>\n · {(group.entries ?? []).slice(0, 3).map(e => String(e.title ?? '?')).join(' / ')}\n </p>\n ))}\n </>\n )}\n </div>\n )}\n\n {audit.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('auditTitle')} ({audit.length})</p>\n {audit.slice(0, 6).map(item => (\n <div key={item.id} className={css.auditRow}>\n <span className={css.dupNames}>{item.title}</span>\n <span className={css.auditIssues}>{item.issues.join('; ')}</span>\n <button\n type=\"button\"\n className={css.dupMerge}\n onClick={() => void startEdit(item.id)}\n disabled={busy}\n >{t('auditEdit')}</button>\n </div>\n ))}\n </div>\n )}\n\n {dupList.length > 0 && (\n <div className={css.reportBox}>\n <p className={css.reportTitle}>{t('dupTitle')} ({dupList.length})</p>\n {dupList.slice(0, 5).map((group, gi) => (\n <div key={gi} className={css.dupGroup}>\n <span className={css.dupNames}>{group.map(g => g.title).join(' / ')}</span>\n <button\n type=\"button\"\n className={css.dupMerge}\n onClick={() => void mergeEntries(group)}\n disabled={busy || readonly}\n >{t('dupMerge')}</button>\n </div>\n ))}\n </div>\n )}\n\n {state.status === 'ready' && (state.entries.length > 0 || trashEntries.length > 0) && (\n <button\n type=\"button\"\n className={css.trashButton}\n onClick={() => {\n if (!showTrash) void trash().then(setTrashEntries)\n setShowTrash(!showTrash)\n }}\n >{showTrash ? t('hideTrash') : t('showTrash')}{trashEntries.length > 0 ? ` (${trashEntries.length})` : ''}</button>\n )}\n\n {showTrash && (\n <ul className={css.list}>\n {trashEntries.map(entry => (\n <li key={entry.id} className={css.row}>\n <div className={css.rowMain}>\n <span className={css.title}>{entry.title}</span>\n <span className={css.identity}>{t('trashed')}</span>\n </div>\n <div className={css.rowActions}>\n <button\n type=\"button\"\n onClick={() => { void restore(entry.id).then(() => { void trash().then(setTrashEntries); void refresh() }) }}\n disabled={busy || readonly}\n >{t('restore')}</button>\n </div>\n </li>\n ))}\n {trashEntries.length === 0 && <p className={css.empty}>{t('trashEmpty')}</p>}\n </ul>\n )}\n {showTrash && trashEntries.length > 0 && (\n <>\n <button\n type=\"button\"\n className={css.trashButton}\n onClick={() => {\n setBusy(true)\n void undeleteAll().then(() => {\n void trash().then(setTrashEntries)\n void refresh()\n setBusy(false)\n }, () => setBusy(false))\n }}\n disabled={busy || readonly}\n >{t('restoreAll')}</button>\n <button\n type=\"button\"\n className={css.dangerButton}\n onClick={() => {\n if (!window.confirm(t('clearTrashConfirm'))) return\n setBusy(true)\n void Promise.all(trashEntries.map(e => remove(e.id))).then(() => {\n void trash().then(setTrashEntries)\n void refresh()\n setBusy(false)\n }, () => setBusy(false))\n }}\n disabled={busy || readonly}\n >{t('clearTrash')}</button>\n </>\n )}\n\n {state.status === 'ready' && state.entries.length > 0 && (\n <ul className={css.list}>\n {state.entries.filter(entry => (kindFilter === '' || entry.kind === kindFilter) && (tagFilter === '' || (entry.tags ?? []).includes(tagFilter))).sort((a, b) => sortBy === 'alpha' ? a.title.localeCompare(b.title) : (b.updatedAt ?? 0) - (a.updatedAt ?? 0)).map(entry => {\n const totpInfo = totpMap[entry.id]\n const remaining = totpInfo !== undefined && totpInfo.until > 0 ? Math.max(0, Math.ceil((totpInfo.until - nowTick) / 1000)) : undefined\n const frac = remaining !== undefined ? remaining / 30 : 0\n const code = totpInfo?.code\n return (\n <li key={entry.id} className={`${css.row}${dueMap[entry.id] !== undefined ? ` ${dueMap[entry.id]!.due === 'expired' ? css.rowExpired : css.rowDue}` : ''}`}>\n <div className={css.rowMain} onClick={() => setExpandedId(expandedId === entry.id ? null : entry.id)}>\n <span className={css.title} style={entry.color !== undefined && entry.color !== '' ? { borderLeft: `3px solid ${entry.color}`, paddingLeft: 6 } : undefined}>\n <span className={css.kindIcon}>{entry.icon ?? kindIcon(entry.kind)}</span>\n {(entry as VaultSummaryWire & { favorite?: boolean }).favorite && (\n <span className={css.pinStar} title={t('pinned')}>★</span>\n )}\n {entry.title}\n {(entry as VaultSummaryWire & { sensitivity?: string }).sensitivity === 'high' && (\n <span className={css.highBadge}>{t('highSensitivity')}</span>\n )}\n {dueMap[entry.id] !== undefined && (\n <span className={`${css.dueBadge} ${dueMap[entry.id]!.due === 'expired' ? css.badgeDanger : css.badgeWarn}`}>\n {dueMap[entry.id]!.due === 'expired' ? t('dueExpired') : dueMap[entry.id]!.due === 'soon' ? `${t('dueExpiring')} ${dueMap[entry.id]!.daysLeft}d` : t('dueNow')}\n </span>\n )}\n </span>\n <span className={css.identity}>{identityLine(entry)}</span>\n {code !== undefined && (\n <span className={css.totp}>\n <svg className={css.totpRing} width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" fill=\"none\" stroke=\"var(--dsh-color-border, #ddd)\" strokeWidth=\"2\" />\n <circle\n cx=\"8\" cy=\"8\" r=\"6.5\" fill=\"none\"\n stroke={remaining !== undefined && remaining <= 5 ? '#cf3d3d' : '#2e9e5b'}\n strokeWidth=\"2\" strokeLinecap=\"round\"\n strokeDasharray={`${(frac * 2 * Math.PI * 6.5).toFixed(1)} ${(2 * Math.PI * 6.5).toFixed(1)}`}\n transform=\"rotate(-90 8 8)\"\n />\n </svg>\n {code}{remaining !== undefined ? ` (${remaining}s)` : ''}\n </span>\n )}\n </div>\n {expandedId === entry.id && (\n <div className={css.detailBox}>\n {Object.entries(entry).filter(([k]) => !['id', 'title', 'favorite'].includes(k) && entry[k as keyof VaultSummaryWire] !== undefined).map(([k, v]) => (\n <span key={k} className={css.detailItem}>\n <strong>{k}</strong>: {formatDetail(k, v)}\n </span>\n ))}\n </div>\n )}\n <div className={css.rowActions}>\n {copiedId === entry.id && <span className={css.copied}>{t('copied')}</span>}\n <button\n type=\"button\"\n onClick={() => void copyValue(entry.id, entry.username ?? entry.title)}\n disabled={busy}\n >{t('copy')}</button>\n <button\n type=\"button\"\n onClick={() => {\n setBusy(true)\n void get(entry.id).then(r => {\n if (r.found && r.entry?.password) void copyValue(entry.id, r.entry.password)\n setBusy(false)\n }, () => setBusy(false))\n }}\n disabled={busy || readonly}\n >{t('copyPassword')}</button>\n <button type=\"button\" onClick={() => void showTotp(entry.id)} disabled={busy}>{t('totp')}</button>\n {code !== undefined && (\n <button type=\"button\" onClick={() => void copyValue(entry.id, code)} disabled={busy}>{t('copyCode')}</button>\n )}\n <button type=\"button\" onClick={() => void touch(entry.id).then(() => void refresh())} disabled={busy || readonly} title={t('touchHint')}>{t('touch')}</button>\n <button type=\"button\" onClick={() => void startEdit(entry.id)} disabled={busy || readonly}>{t('edit')}</button>\n <button\n type=\"button\"\n className={css.deleteButton}\n onClick={() => void removeEntry(entry.id)}\n disabled={busy || readonly}\n >{t('delete')}</button>\n </div>\n </li>\n )\n })}\n </ul>\n )}\n\n {state.status === 'ready' && (\n <div className={css.healthBar}>\n {vaultStats !== null && typeof vaultStats.total === 'number' && (\n <span className={css.badge}>{t('entryCount')}: {String(vaultStats.total)}</span>\n )}\n {vaultStats !== null && typeof vaultStats.withTotp === 'number' && (\n <span className={css.badge}>TOTP: {String(vaultStats.withTotp)}</span>\n )}\n {vaultStats !== null && typeof vaultStats.highSensitivity === 'number' && (\n <span className={css.badge}>{t('highSensitivity')}: {String(vaultStats.highSensitivity)}</span>\n )}\n {report !== null && report.strength !== null && (\n <span className={`${css.badge} ${report.strength.weak > 0 ? css.badgeDanger : css.badgeOk}`}>\n {t('healthStrength')}: {report.strength.weak}W/{report.strength.fair}F/{report.strength.strong}S\n </span>\n )}\n {report !== null && report.rotation.length > 0 && (\n <span className={`${css.badge} ${css.badgeWarn}`}>{t('reportRotation')}: {report.rotation.length}</span>\n )}\n {vaultStats !== null && typeof vaultStats.expired === 'number' && vaultStats.expired > 0 && (\n <span className={`${css.badge} ${css.badgeDanger}`}>{t('dueExpired')}: {String(vaultStats.expired)}</span>\n )}\n {report !== null && report.weak.length > 0 && (\n <span className={`${css.badge} ${css.badgeDanger}`}>{t('reportWeak')}: {report.weak.length}</span>\n )}\n {report !== null && report.reused.length > 0 && (\n <span className={`${css.badge} ${css.badgeDanger}`}>{t('reportReused')}: {report.reused.length}</span>\n )}\n {dupGroups > 0 && (\n <span className={`${css.badge} ${css.badgeWarn}`}>{t('dupGroups')}: {dupGroups}</span>\n )}\n {report !== null && report.rotation.length === 0 && report.weak.length === 0 && report.reused.length === 0 && (\n <span className={`${css.badge} ${css.badgeOk}`}>{t('healthOk')}</span>\n )}\n {backupInfo !== null && backupInfo.daysSinceBackup >= 0 && (\n <span className={`${css.badge} ${backupInfo.daysSinceBackup > 14 ? css.badgeDanger : backupInfo.daysSinceBackup > 7 ? css.badgeWarn : ''}`}>\n {t('healthBackup')}: {backupInfo.daysSinceBackup}d ({backupInfo.backups})\n </span>\n )}\n <button type=\"button\" className={css.backupButton} onClick={() => void backupNow()} disabled={busy}>\n {t('backupNow')}\n </button>\n </div>\n )}\n {state.status === 'ready' && (\n <p className={css.footer}>\n {t('entryCount')}: {state.entries.length}\n {vaultStats !== null && typeof vaultStats.withTotp === 'number' && ` · TOTP: ${String(vaultStats.withTotp)}`}\n {vaultStats !== null && typeof vaultStats.highSensitivity === 'number' && ` · ${t('highSensitivity')}: ${String(vaultStats.highSensitivity)}`}\n {backupInfo !== null && backupInfo.daysSinceBackup >= 0 && ` · backup: ${backupInfo.daysSinceBackup}d ago`}\n {vaultStats !== null && typeof vaultStats.byTag === 'object' && vaultStats.byTag !== null\n && Object.keys(vaultStats.byTag as Record<string, unknown>).length > 0\n && ` · tags: ${Object.entries(vaultStats.byTag as Record<string, unknown>).map(([k, v]) => `${k}(${String(v)})`).join(' ')}`}\n </p>\n )}\n\n {editor.status !== 'closed' && (\n <div className={css.editor} role=\"dialog\" aria-label={editor.status === 'creating' ? t('add') : t('edit')}>\n <div className={css.editorBody}>\n {FORM_FIELDS.map(field => (\n <label key={field.key} className={css.field}>\n <span>{t(field.label)}</span>\n {field.key === 'kind' ? (\n <select\n value={form.kind ?? 'login'}\n onChange={event => setForm(previous => ({ ...previous, kind: event.target.value }))}\n >\n {Object.entries(KIND_KEYS).map(([value, key]) => (\n <option key={value} value={value}>{t(key)}</option>\n ))}\n </select>\n ) : field.key === 'title' ? (\n <input\n value={form.title ?? ''}\n onChange={event => setForm(previous => ({ ...previous, title: event.target.value }))}\n />\n ) : field.key === 'password' || field.key === 'otpSecret' || field.key === 'apiKey'\n || field.key === 'secret' || field.key === 'accessToken' || field.key === 'refreshToken'\n || field.key === 'privateKey' ? (\n <span className={css.secretField}>\n <input\n type={revealed[field.key] ? 'text' : 'password'}\n value={(form[field.key] as string | undefined) ?? ''}\n onChange={event => setForm(previous => ({ ...previous, [field.key]: event.target.value }))}\n />\n <button\n type=\"button\"\n className={css.revealButton}\n onClick={() => setRevealed(previous => ({ ...previous, [field.key]: !previous[field.key] }))}\n >{revealed[field.key] ? t('hide') : t('show')}</button>\n </span>\n ) : field.key === 'expiresAt' ? (\n <input\n type=\"datetime-local\"\n value={form.expiresAt !== undefined ? new Date(form.expiresAt).toISOString().slice(0, 16) : ''}\n onChange={event => {\n const raw = event.target.value\n const epoch = raw.length > 0 ? Date.parse(raw) : NaN\n setForm(previous => ({ ...previous, expiresAt: Number.isNaN(epoch) ? undefined : epoch }))\n }}\n />\n ) : field.key === 'rotationDays' ? (\n <input\n type=\"number\"\n min={0}\n max={3650}\n placeholder={t('rotationClearHint')}\n value={form.rotationDays ?? ''}\n onChange={event => {\n const raw = event.target.value\n setForm(previous => ({ ...previous, rotationDays: raw.length > 0 ? Number(raw) : undefined }))\n }}\n />\n ) : field.key === 'sensitivity' ? (\n <select\n value={form.sensitivity ?? 'normal'}\n onChange={event => setForm(previous => ({ ...previous, sensitivity: event.target.value === 'high' ? 'high' : 'normal' }))}\n >\n <option value=\"normal\">{t('sensitivityNormal')}</option>\n <option value=\"high\">{t('sensitivityHigh')}</option>\n </select>\n ) : field.key === 'favorite' ? (\n <label className={css.checkField}>\n <input\n type=\"checkbox\"\n checked={form.favorite ?? false}\n onChange={event => setForm(previous => ({ ...previous, favorite: event.target.checked }))}\n />\n {t('favoriteHint')}\n </label>\n ) : (\n <input\n type=\"text\"\n value={(form[field.key] as string | undefined) ?? ''}\n onChange={event => setForm(previous => ({ ...previous, [field.key]: event.target.value }))}\n />\n )}\n </label>\n ))}\n <label className={css.field}>\n <span>{t('fieldTags')}</span>\n <input\n value={tagsDraft}\n onChange={event => setTagsDraft(event.target.value)}\n placeholder=\"dev, prod\"\n />\n </label>\n <label className={css.field}>\n <span>{t('fieldCustom')}</span>\n <textarea\n value={fieldsDraft}\n onChange={event => setFieldsDraft(event.target.value)}\n rows={3}\n placeholder=\"region=us-east-1 team=infra\"\n />\n </label>\n </div>\n <div className={css.editorActions}>\n <button type=\"button\" onClick={() => setEditor({ status: 'closed' })} disabled={busy}>{t('cancel')}</button>\n <button type=\"button\" className={css.saveButton} onClick={() => void save()} disabled={busy}>{t('save')}</button>\n </div>\n </div>\n )}\n </section>\n )\n}\n","/** Copy dictionaries for the Vault settings section. */\n\n/** English strings (the key-set source of truth for this pair). */\nexport const en = {\n nav: 'Vault',\n heading: 'Vault',\n intro: 'Encrypted credentials stored on this machine.',\n searchPlaceholder: 'Search title, username, email, host…',\n loading: 'Loading…',\n empty: 'No credentials yet. Add one to get started.',\n emptyHint: 'Tip: you can ask the assistant to save an API key or token you share in chat — with auto-capture on it offers to store it for you. Bulk importing? Ask for vault_import_csv with a CSV file path.',\n emptyHintReadonly: 'The vault is in readonly mode — credentials can be read but not added here. Switch accessMode to \"readwrite\" to enable writes.',\n modeLabel: 'Access mode',\n autoCaptureLabel: 'Auto-capture credentials from chat',\n modeReadonly: 'Read-only',\n modeAsk: 'Ask before writing',\n modeAuto: 'Automatic read-write',\n modeReadonlyHint: 'Read-only — mutations disabled',\n modeAskHint: 'Prompt before writing — every add/update/delete asks you',\n modeAutoHint: 'Automatic read-write — no per-call prompt',\n autoCaptureOn: 'auto-capture on',\n autoCaptureOff: 'auto-capture off',\n clearSearch: 'Clear search',\n entryCount: 'Entries',\n reportTitle: 'Health & rotation',\n recentActivity: 'Recent activity',\n recentlyAdded: 'Recently added',\n reportRotation: 'expired / due for rotation',\n reportWeak: 'weak passwords',\n reportReused: 'credentials reused across entries',\n dupGroups: 'duplicate groups',\n dupTitle: 'Duplicate entries',\n dupMerge: 'Merge',\n healthOk: 'vault healthy',\n healthBackup: 'backup',\n backupNow: 'Backup now',\n backupDone: 'Backup created',\n lockedBanner: 'Vault is locked — unlock it with vault_unlock to read or write entries.',\n vaultSelect: 'Active vault',\n touch: 'Used',\n touchHint: 'Mark as recently used',\n auditTitle: 'Needs attention',\n auditEdit: 'Edit',\n healthStrength: 'strength',\n dueExpired: 'EXPIRED',\n dueExpiring: 'expires in',\n dueNow: 'rotation due',\n showTrash: 'Trash',\n hideTrash: 'Hide trash',\n trashed: 'in trash',\n trashEmpty: 'Trash is empty',\n restore: 'Restore',\n clearTrash: 'Empty trash',\n restoreAll: 'Restore all',\n clearTrashConfirm: 'Permanently delete ALL trashed entries? This cannot be undone.',\n show: 'Show',\n hide: 'Hide',\n allKinds: 'All kinds',\n allTags: 'All tags',\n sortAlpha: 'Sort: A–Z',\n sortRecent: 'Sort: recent',\n highSensitivity: 'HIGH',\n pinned: 'Pinned',\n add: 'Add credential',\n quickAdd: 'Quick add',\n cancel: 'Cancel',\n save: 'Save',\n edit: 'Edit',\n delete: 'Delete',\n deleteConfirm: 'Delete this entry? This cannot be undone.',\n copy: 'Copy',\n copyPassword: 'Copy password',\n copyCode: 'Copy code',\n copied: 'Copied',\n totp: 'Code',\n fieldTitle: 'Title',\n fieldKind: 'Kind',\n fieldUsername: 'Username',\n fieldEmail: 'Email',\n fieldPhone: 'Phone',\n fieldPassword: 'Password',\n fieldHost: 'Host',\n fieldPort: 'Port',\n fieldApiKey: 'API key',\n fieldSecret: 'Secret',\n fieldAccessToken: 'Access token',\n fieldRefreshToken: 'Refresh token',\n fieldOtpSecret: 'OTP secret',\n fieldUrl: 'URL',\n fieldNotes: 'Notes',\n fieldTags: 'Tags',\n fieldIcon: 'Icon (emoji)',\n fieldExpiresAt: 'Expires at',\n fieldRotationDays: 'Rotation (days, 0 = never)',\n fieldSensitivity: 'Sensitivity',\n fieldFavorite: 'Pinned',\n sensitivityNormal: 'normal',\n sensitivityHigh: 'high',\n favoriteHint: 'Show at top',\n rotationClearHint: '0 clears rotation',\n fieldColor: 'Color',\n fieldCustom: 'Custom fields (key=value per line)',\n error: 'Something went wrong.',\n kindLogin: 'Login',\n kindSsh: 'SSH',\n kindApiKey: 'API key',\n kindSecret: 'Secret',\n kindOauth: 'OAuth',\n kindCustom: 'Custom',\n} as const\n\nexport type VaultLocaleKey = keyof typeof en\n\n/** Chinese strings (same keys as English). */\nexport const zh: Record<VaultLocaleKey, string> = {\n nav: '凭据库',\n heading: 'Vault 凭据库',\n intro: '本机加密存储的凭据。',\n searchPlaceholder: '搜索标题、用户名、邮箱、主机…',\n loading: '加载中…',\n empty: '还没有凭据,添加一条开始使用。',\n emptyHint: '提示:你可以在对话中把 API Key 或 token 交给助手保存——开启自动捕获后,它会在你同意时帮你存入本库。批量导入?让助手调用 vault_import_csv 并给出 CSV 路径即可。',\n emptyHintReadonly: '当前为只读模式——只能读取凭据,不能在此添加。将 accessMode 改为 \"readwrite\" 即可启用写入。',\n modeLabel: '访问模式',\n autoCaptureLabel: '自动捕获对话中的凭据',\n modeReadonly: '只读',\n modeAsk: '写入前询问',\n modeAuto: '自动读写',\n modeReadonlyHint: '只读 —— 变更已禁用',\n modeAskHint: '写入前询问 —— 每次增/改/删都会征求你的确认',\n modeAutoHint: '自动读写 —— 无需逐次确认',\n autoCaptureOn: '自动捕获已开启',\n autoCaptureOff: '自动捕获已关闭',\n clearSearch: '清除搜索',\n entryCount: '条目数',\n reportTitle: '健康与轮换',\n recentActivity: '最近活动',\n recentlyAdded: '最近添加',\n reportRotation: '已过期 / 待轮换',\n reportWeak: '弱密码',\n reportReused: '跨条目复用的凭据',\n dupGroups: '重复分组',\n dupTitle: '重复条目',\n dupMerge: '合并',\n healthOk: '凭据库健康',\n healthBackup: '备份',\n backupNow: '立即备份',\n backupDone: '备份已创建',\n lockedBanner: '保险库已锁定 —— 请使用 vault_unlock 解锁后再读写条目。',\n vaultSelect: '当前保险库',\n touch: '标记已用',\n touchHint: '标记为最近使用',\n auditTitle: '需要处理',\n auditEdit: '编辑',\n healthStrength: '强度',\n dueExpired: '已过期',\n dueExpiring: '将于',\n dueNow: '待轮换',\n showTrash: '回收站',\n hideTrash: '隐藏回收站',\n trashed: '已删除',\n trashEmpty: '回收站为空',\n restore: '恢复',\n clearTrash: '清空回收站',\n restoreAll: '全部恢复',\n clearTrashConfirm: '永久删除回收站中全部条目?此操作不可撤销。',\n show: '显示',\n hide: '隐藏',\n allKinds: '全部类型',\n allTags: '全部标签',\n sortAlpha: '排序:A–Z',\n sortRecent: '排序:最近',\n highSensitivity: '高敏',\n pinned: '已置顶',\n add: '新增凭据',\n quickAdd: '快速添加',\n cancel: '取消',\n save: '保存',\n edit: '编辑',\n delete: '删除',\n deleteConfirm: '确定删除该条目?此操作不可撤销。',\n copy: '复制',\n copyPassword: '复制密码',\n copyCode: '复制验证码',\n copied: '已复制',\n totp: '验证码',\n fieldTitle: '标题',\n fieldKind: '类型',\n fieldUsername: '用户名',\n fieldEmail: '邮箱',\n fieldPhone: '手机号',\n fieldPassword: '密码',\n fieldHost: '主机',\n fieldPort: '端口',\n fieldApiKey: 'API 密钥',\n fieldSecret: 'Secret',\n fieldAccessToken: '访问令牌',\n fieldRefreshToken: '刷新令牌',\n fieldOtpSecret: 'TOTP 密钥',\n fieldUrl: 'URL',\n fieldNotes: '备注',\n fieldTags: '标签',\n fieldIcon: '图标(emoji)',\n fieldExpiresAt: '过期时间',\n fieldRotationDays: '轮换周期(天,0=永不)',\n fieldSensitivity: '敏感级别',\n fieldFavorite: '置顶',\n sensitivityNormal: '普通',\n sensitivityHigh: '高敏',\n favoriteHint: '列表置顶显示',\n rotationClearHint: '0 清除轮换',\n fieldColor: '颜色',\n fieldCustom: '自定义字段(每行 key=value)',\n error: '操作失败。',\n kindLogin: '登录',\n kindSsh: 'SSH',\n kindApiKey: 'API 密钥',\n kindSecret: 'Secret',\n kindOauth: 'OAuth',\n kindCustom: '自定义',\n}\n","/**\n * dsh-vault browser half: a Vault settings page managing encrypted\n * credentials — list, search, add, edit, delete, and copy — through the host\n * VaultGateway remote over the /api RPC channel.\n *\n * @module dsh-vault/client\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { VaultSection, type VaultSectionInjected } from './VaultSection.tsx'\nimport type { VaultSectionTypes } from './VaultSection.tsx'\nimport { en, zh, type VaultLocaleKey } from './locales.ts'\n\nexport type { VaultSectionInjected, VaultSectionProps } from './VaultSection.tsx'\nexport type { VaultSectionTypes } from './VaultSection.tsx'\nexport type { VaultLocaleKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Vault settings page copy. */\n 'settings.vault': VaultLocaleKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'settings.vault'\n\n/** Services required by the Settings registration and the RPC face. */\nexport const inject = ['slots', 'locale', 'connection']\n\n/**\n * Register the Vault settings section once the `settings.section` declaration\n * is on the ledger. The section talks to the host through the connection RPC\n * channel (endpoints `vault/*` served by the host VaultGateway remote).\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-vault: dictionaries')\n\n const t = ctx.locale.bind(NS)\n const connection = ctx.get('connection') as ConnectionHandle\n\n /** Invoke one host vault remote and normalize the RPC envelope. */\n async function invoke<T>(method: string, args: Record<string, unknown> = {}): Promise<T> {\n const result = await connection.rpc.call('/api', `vault/${method}`, { args })\n if (!result.ok) {\n throw new Error(`vault.${method} failed: ${result.error.code}: ${result.error.message}`)\n }\n return result.value as T\n }\n\n const injected = (): VaultSectionInjected => ({\n t,\n config: () => invoke<VaultSectionTypes['config']>('config'),\n setAccessMode: (mode) => invoke<VaultSectionTypes['config']>('setAccessMode', { mode }),\n setAutoCapture: (enabled) => invoke<VaultSectionTypes['config']>('setAutoCapture', { enabled }),\n list: () => invoke<{ entries: VaultSectionTypes['entries'] }>('list').then(r => r.entries),\n search: (query, limit) => invoke<{ entries: VaultSectionTypes['entries'] }>('search', { query, limit: limit ?? 50 }).then(r => r.entries),\n get: (id) => invoke<{ found: boolean; entry?: VaultSectionTypes['fullEntry'] }>('get', { id }),\n add: (patch) => invoke<VaultSectionTypes['summaryEntry']>('add', { patch }),\n update: (id, patch) => invoke<{ found: boolean; entry?: VaultSectionTypes['summaryEntry'] }>('update', { id, patch }),\n remove: (id) => invoke<{ deleted: boolean }>('delete', { id }),\n trash: () => invoke<{ entries: VaultSectionTypes['entries'] }>('trash').then(r => r.entries),\n rotation: () => invoke<{ entries: unknown[] }>('rotation').then(r => r.entries),\n history: () => invoke<{ events: unknown[] }>('history').then(r => r.events),\n stats: () => invoke<Record<string, unknown>>('stats'),\n recent: () => invoke<{ entries: unknown[] }>('recent').then(r => r.entries),\n backupStatus: () => invoke<{ daysSinceBackup: number; backups: number }>('backupStatus'),\n backup: (maxBackups) => invoke<{ path: string; kept: number; pruned: number }>('backup', { ...(maxBackups !== undefined ? { maxBackups } : {}) }),\n health: () => invoke<{ weak: unknown[]; reused: unknown[]; strength: { weak: number; fair: number; strong: number } }>('health'),\n duplicates: () => invoke<{ groups: number }>('duplicates'),\n status: () => invoke<{ locked: boolean; entries: number }>('status'),\n switchVault: (name) => invoke<{ switched: boolean; name: string }>('switchVault', { name }),\n listVaults: () => invoke<Array<{ name: string; active: boolean }>>('listVaults'),\n touch: (id) => invoke<{ touched: boolean }>('touch', { id }),\n verifyAll: () => invoke<Array<{ id: string; title: string; issues: string[] }>>('verifyAll'),\n duplicateGroups: () => invoke<Array<Array<{ id: string; title: string }>>>('duplicateGroups'),\n merge: (fromId, toId, keepSource) => invoke<{ found: boolean }>('merge', { fromId, toId, keepSource: keepSource ?? false }),\n restore: (id) => invoke<{ restored: boolean }>('restore', { id }),\n undeleteAll: () => invoke<{ restored: number }>('undeleteAll'),\n totp: (id) => invoke<{ code: string; label?: string; secondsRemaining: number }>('totp', { id }),\n })\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'vault',\n order: 30,\n label: () => t('nav'),\n inject: injected,\n }, VaultSection))\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -834,7 +834,7 @@ export async function apply(ctx, config) {
|
|
|
834
834
|
id: { type: 'string', description: 'Entry id to verify (omit when all is true).' },
|
|
835
835
|
all: { type: 'boolean', description: 'Verify every active entry and return a per-entry audit.' },
|
|
836
836
|
},
|
|
837
|
-
output: { schema: { type: 'object', additionalProperties: false, properties: { ok: { type: 'boolean', required: true }, issues: { type: 'array', required: true, items: { type: 'string' } }, audited: { type: 'integer' }, withIssues: { type: 'integer' }, perEntry: { type: 'array', items: { type: 'json' } } } }, render: (_a, v) => [{ type: 'text', text: v.audited !== undefined ? `audited ${v.audited} entries, ${v.withIssues} with issues` : (v.ok ? 'entry looks complete' : `issues: ${v.issues.join('; ')}`) }] },
|
|
837
|
+
output: { schema: { type: 'object', additionalProperties: false, properties: { ok: { type: 'boolean', required: true }, issues: { type: 'array', required: true, items: { type: 'string' } }, audited: { type: 'integer' }, withIssues: { type: 'integer' }, perEntry: { type: 'array', items: { type: 'json' } }, summary: { type: 'json' } } }, render: (_a, v) => [{ type: 'text', text: v.audited !== undefined ? `audited ${v.audited} entries, ${v.withIssues} with issues` : (v.ok ? 'entry looks complete' : `issues: ${v.issues.join('; ')}`) }] },
|
|
838
838
|
async execute(args) {
|
|
839
839
|
const s = await guardStore();
|
|
840
840
|
if (args.all === true) {
|
|
@@ -866,7 +866,12 @@ export async function apply(ctx, config) {
|
|
|
866
866
|
perEntry.push({ id: e.id, title: e.title, ok: issues.length === 0, issues });
|
|
867
867
|
}
|
|
868
868
|
const withIssues = perEntry.filter(p => !p.ok).length;
|
|
869
|
-
|
|
869
|
+
const summary = {};
|
|
870
|
+
for (const p of perEntry) {
|
|
871
|
+
for (const issue of p.issues)
|
|
872
|
+
summary[issue] = (summary[issue] ?? 0) + 1;
|
|
873
|
+
}
|
|
874
|
+
return { ok: withIssues === 0, issues: [], audited: perEntry.length, withIssues, perEntry, summary };
|
|
870
875
|
}
|
|
871
876
|
if (args.id === undefined)
|
|
872
877
|
throw new Error('vault_verify: provide id or set all: true');
|
|
@@ -2020,8 +2025,9 @@ export async function apply(ctx, config) {
|
|
|
2020
2025
|
parameters: {
|
|
2021
2026
|
ids: { type: 'array', items: { type: 'string' }, description: 'Only export these entry ids (optional).' },
|
|
2022
2027
|
since: { type: 'integer', description: 'Only export active entries created or updated at/after this epoch millis (incremental backup).' },
|
|
2028
|
+
path: { type: 'string', description: 'Optional absolute output path; defaults to <vault dir>/vault-export-<ts>.json.' },
|
|
2023
2029
|
},
|
|
2024
|
-
output: { schema: { type: 'object', additionalProperties: false, properties: { exported: { type: 'boolean', required: true }, note: { type: 'string', required: true } } }, render: (_a, v) => [{ type: 'text', text: v.note }] },
|
|
2030
|
+
output: { schema: { type: 'object', additionalProperties: false, properties: { exported: { type: 'boolean', required: true }, note: { type: 'string', required: true }, count: { type: 'integer', required: true } } }, render: (_a, v) => [{ type: 'text', text: v.note }] },
|
|
2025
2031
|
async execute(args) {
|
|
2026
2032
|
const exportPassword = resolveExportPassword(config);
|
|
2027
2033
|
const s = await guardStore();
|
|
@@ -2036,10 +2042,15 @@ export async function apply(ctx, config) {
|
|
|
2036
2042
|
else {
|
|
2037
2043
|
blob = await s.exportEncrypted(exportPassword);
|
|
2038
2044
|
}
|
|
2039
|
-
const file = join(dirname(resolveVaultPath(config)), `vault-export-${Date.now()}.json`);
|
|
2045
|
+
const file = args.path ?? join(dirname(resolveVaultPath(config)), `vault-export-${Date.now()}.json`);
|
|
2040
2046
|
await mkdir(dirname(file), { recursive: true, mode: 0o700 });
|
|
2041
2047
|
await writeFile(file, blob, { mode: 0o600 });
|
|
2042
|
-
|
|
2048
|
+
const count = args.ids !== undefined && args.ids.length > 0
|
|
2049
|
+
? args.ids.length
|
|
2050
|
+
: args.since !== undefined
|
|
2051
|
+
? s.list().filter(e => e.createdAt >= args.since || e.updatedAt >= args.since).length
|
|
2052
|
+
: s.list().length + s.listTrash().length;
|
|
2053
|
+
return { exported: true, note: `vault exported to ${file}`, count };
|
|
2043
2054
|
},
|
|
2044
2055
|
}));
|
|
2045
2056
|
ctx.tools.register(defineTool({
|
|
@@ -2048,7 +2059,8 @@ export async function apply(ctx, config) {
|
|
|
2048
2059
|
+ 'id (gaps filled) or replacing them with overwrite. dryRun previews without writing. Pass the '
|
|
2049
2060
|
+ 'document path; the export password comes from the exportPasswordEnv config.',
|
|
2050
2061
|
parameters: {
|
|
2051
|
-
path: { type: 'string',
|
|
2062
|
+
path: { type: 'string', description: 'Absolute path of the exported vault JSON file (provide exactly one of path or blob).' },
|
|
2063
|
+
blob: { type: 'string', description: 'The exported vault document content directly (provide exactly one of path or blob).' },
|
|
2052
2064
|
overwrite: { type: 'boolean', description: 'Replace existing entries with the same id instead of merging (default false).' },
|
|
2053
2065
|
dryRun: { type: 'boolean', description: 'Preview how many entries would be imported without writing anything (default false).' },
|
|
2054
2066
|
},
|
|
@@ -2057,7 +2069,10 @@ export async function apply(ctx, config) {
|
|
|
2057
2069
|
assertWritable('vault_import');
|
|
2058
2070
|
const exportPassword = resolveExportPassword(config);
|
|
2059
2071
|
const s = await guardStore();
|
|
2060
|
-
|
|
2072
|
+
if (args.path === undefined && args.blob === undefined) {
|
|
2073
|
+
throw new Error('vault_import: provide either path or blob');
|
|
2074
|
+
}
|
|
2075
|
+
const blob = args.path !== undefined ? await readFile(args.path, 'utf8') : args.blob;
|
|
2061
2076
|
const count = await s.importEncrypted(blob, exportPassword, args.overwrite === true, args.dryRun === true);
|
|
2062
2077
|
return { imported: count };
|
|
2063
2078
|
},
|
|
@@ -2413,7 +2428,7 @@ export async function apply(ctx, config) {
|
|
|
2413
2428
|
description: 'Switch the active vault for this session. Future vault_* calls operate on the named '
|
|
2414
2429
|
+ 'vault (created on first use). Returns the newly active vault name.',
|
|
2415
2430
|
parameters: { name: { type: 'string', required: true, description: 'Vault name (e.g. "work" or "personal").' } },
|
|
2416
|
-
output: { schema: { type: 'object', additionalProperties: false, properties: { active: { type: 'string', required: true } } }, render: (_a, v) => [{ type: 'text', text: `switched to vault "${v.active}"` }] },
|
|
2431
|
+
output: { schema: { type: 'object', additionalProperties: false, properties: { active: { type: 'string', required: true }, vaults: { type: 'array', required: true, items: { type: 'json' } } } }, render: (_a, v) => [{ type: 'text', text: `switched to vault "${v.active}"` }] },
|
|
2417
2432
|
async execute(args) {
|
|
2418
2433
|
const name = args.name.trim();
|
|
2419
2434
|
if (name.length === 0)
|
|
@@ -2421,7 +2436,21 @@ export async function apply(ctx, config) {
|
|
|
2421
2436
|
if (!/^[a-zA-Z0-9._-]+$/.test(name))
|
|
2422
2437
|
throw new Error('vault_switch: name may contain only letters, digits, . _ -');
|
|
2423
2438
|
currentVaultName = name;
|
|
2424
|
-
|
|
2439
|
+
// List known vaults (mirrors vault_list) so the caller sees the roster.
|
|
2440
|
+
let names = [];
|
|
2441
|
+
try {
|
|
2442
|
+
const entries = await readdir(dirname(resolveVaultPath(config)));
|
|
2443
|
+
for (const entry of entries) {
|
|
2444
|
+
const m = /^(.*)\.json$/.exec(entry);
|
|
2445
|
+
if (!m)
|
|
2446
|
+
continue;
|
|
2447
|
+
if (['access', 'meta'].includes(m[1]) || m[1].startsWith('vault-export-'))
|
|
2448
|
+
continue;
|
|
2449
|
+
names.push(m[1]);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
catch { /* no dir yet */ }
|
|
2453
|
+
return { active: name, vaults: names.sort().map(v => ({ name: v, active: v === name })) };
|
|
2425
2454
|
},
|
|
2426
2455
|
}));
|
|
2427
2456
|
// ── vault_rekey: upgrade the scrypt KDF parameters in place ────────────────
|
|
@@ -2570,6 +2599,14 @@ let VaultGateway = (() => {
|
|
|
2570
2599
|
...(this.activeName !== undefined ? { name: this.activeName } : {}),
|
|
2571
2600
|
});
|
|
2572
2601
|
}
|
|
2602
|
+
/** Ensure the store and refuse reads/writes while the vault is locked. */
|
|
2603
|
+
async guardedStore() {
|
|
2604
|
+
const store = await this.ensureStore();
|
|
2605
|
+
if (store.isLocked) {
|
|
2606
|
+
throw new Error('vault is locked — run vault_unlock first');
|
|
2607
|
+
}
|
|
2608
|
+
return store;
|
|
2609
|
+
}
|
|
2573
2610
|
/** Reject mutations when the vault is in readonly mode (UI surface). */
|
|
2574
2611
|
assertWritable(action) {
|
|
2575
2612
|
if (this.accessPolicy.mode === 'readonly') {
|
|
@@ -2607,18 +2644,18 @@ let VaultGateway = (() => {
|
|
|
2607
2644
|
}
|
|
2608
2645
|
/** List every entry as a non-secret summary. */
|
|
2609
2646
|
async list() {
|
|
2610
|
-
const store = await this.
|
|
2647
|
+
const store = await this.guardedStore();
|
|
2611
2648
|
return { entries: store.list().map(toSummary) };
|
|
2612
2649
|
}
|
|
2613
2650
|
/** List trashed (soft-deleted) entries as non-secret summaries. */
|
|
2614
2651
|
async trash() {
|
|
2615
|
-
const store = await this.
|
|
2652
|
+
const store = await this.guardedStore();
|
|
2616
2653
|
return { entries: store.listTrash().map(toSummary) };
|
|
2617
2654
|
}
|
|
2618
2655
|
/** Restore every trashed entry; returns how many were restored. */
|
|
2619
2656
|
async undeleteAll() {
|
|
2620
2657
|
this.assertWritable('undeleteAll');
|
|
2621
|
-
const store = await this.
|
|
2658
|
+
const store = await this.guardedStore();
|
|
2622
2659
|
let restored = 0;
|
|
2623
2660
|
for (const e of store.listTrash()) {
|
|
2624
2661
|
if (await store.restore(e.id))
|
|
@@ -2629,7 +2666,7 @@ let VaultGateway = (() => {
|
|
|
2629
2666
|
/** Restore a trashed entry (non-secret summary returned). */
|
|
2630
2667
|
async restore(id) {
|
|
2631
2668
|
this.assertWritable('restore');
|
|
2632
|
-
const store = await this.
|
|
2669
|
+
const store = await this.guardedStore();
|
|
2633
2670
|
return { restored: await store.restore(id) };
|
|
2634
2671
|
}
|
|
2635
2672
|
/** Days since last backup + backup count (no secrets). */
|
|
@@ -2676,33 +2713,33 @@ let VaultGateway = (() => {
|
|
|
2676
2713
|
}
|
|
2677
2714
|
/** Vault overview stats (no secrets). */
|
|
2678
2715
|
async stats() {
|
|
2679
|
-
const store = await this.
|
|
2716
|
+
const store = await this.guardedStore();
|
|
2680
2717
|
return store.stats();
|
|
2681
2718
|
}
|
|
2682
2719
|
/** Most recently created entries (no secrets). */
|
|
2683
2720
|
async recent() {
|
|
2684
|
-
const store = await this.
|
|
2721
|
+
const store = await this.guardedStore();
|
|
2685
2722
|
return { entries: store.recent(5) };
|
|
2686
2723
|
}
|
|
2687
2724
|
/** Recent mutation history (no secrets). */
|
|
2688
2725
|
async history() {
|
|
2689
|
-
const store = await this.
|
|
2726
|
+
const store = await this.guardedStore();
|
|
2690
2727
|
return { events: store.getHistory().slice(0, 20) };
|
|
2691
2728
|
}
|
|
2692
2729
|
/** Rotation/expiry report (no secrets). */
|
|
2693
2730
|
async rotation(soonWindowDays) {
|
|
2694
|
-
const store = await this.
|
|
2731
|
+
const store = await this.guardedStore();
|
|
2695
2732
|
const window = soonWindowDays === undefined ? 7 : soonWindowDays;
|
|
2696
2733
|
return { entries: store.rotationReport(Date.now(), window) };
|
|
2697
2734
|
}
|
|
2698
2735
|
/** Health scan findings (no secrets). */
|
|
2699
2736
|
async health() {
|
|
2700
|
-
const store = await this.
|
|
2737
|
+
const store = await this.guardedStore();
|
|
2701
2738
|
return store.health();
|
|
2702
2739
|
}
|
|
2703
2740
|
/** Duplicate groups count for the UI health badge (title+kind matches). */
|
|
2704
2741
|
async duplicates() {
|
|
2705
|
-
const store = await this.
|
|
2742
|
+
const store = await this.guardedStore();
|
|
2706
2743
|
const byKey = new Map();
|
|
2707
2744
|
for (const e of store.list()) {
|
|
2708
2745
|
const key = `${e.title.toLowerCase()}::${e.kind ?? 'login'}`;
|
|
@@ -2714,7 +2751,7 @@ let VaultGateway = (() => {
|
|
|
2714
2751
|
}
|
|
2715
2752
|
/** Duplicate groups with ids+titles for the UI cleanup panel (title+kind). */
|
|
2716
2753
|
async duplicateGroups() {
|
|
2717
|
-
const store = await this.
|
|
2754
|
+
const store = await this.guardedStore();
|
|
2718
2755
|
const byKey = new Map();
|
|
2719
2756
|
for (const e of store.list()) {
|
|
2720
2757
|
const key = `${e.title.toLowerCase()}::${e.kind ?? 'login'}`;
|
|
@@ -2726,7 +2763,7 @@ let VaultGateway = (() => {
|
|
|
2726
2763
|
}
|
|
2727
2764
|
/** Per-entry verification issues for the UI audit panel (no secrets). */
|
|
2728
2765
|
async verifyAll() {
|
|
2729
|
-
const store = await this.
|
|
2766
|
+
const store = await this.guardedStore();
|
|
2730
2767
|
const out = [];
|
|
2731
2768
|
for (const e of store.list()) {
|
|
2732
2769
|
const issues = [];
|
|
@@ -2759,7 +2796,7 @@ let VaultGateway = (() => {
|
|
|
2759
2796
|
}
|
|
2760
2797
|
/** Vault lock/entry status for the UI banner. */
|
|
2761
2798
|
async status() {
|
|
2762
|
-
const store = await this.
|
|
2799
|
+
const store = await this.guardedStore();
|
|
2763
2800
|
return { locked: store.isLocked, entries: store.isLocked ? 0 : store.list().length };
|
|
2764
2801
|
}
|
|
2765
2802
|
/** Switch the active vault by name (same master password), then re-open. */
|
|
@@ -2791,19 +2828,19 @@ let VaultGateway = (() => {
|
|
|
2791
2828
|
}
|
|
2792
2829
|
/** Mark an entry as recently used (touches updatedAt). */
|
|
2793
2830
|
async touch(id) {
|
|
2794
|
-
const store = await this.
|
|
2831
|
+
const store = await this.guardedStore();
|
|
2795
2832
|
const updated = await store.markUsed(id);
|
|
2796
2833
|
return { touched: updated !== undefined };
|
|
2797
2834
|
}
|
|
2798
2835
|
/** Merge one entry into another (Bitwarden-style dedup); keepSource optional. */
|
|
2799
2836
|
async merge(fromId, toId, keepSource) {
|
|
2800
|
-
const store = await this.
|
|
2837
|
+
const store = await this.guardedStore();
|
|
2801
2838
|
const merged = await store.merge(fromId, toId, { keepSource: keepSource === true });
|
|
2802
2839
|
return { found: merged !== undefined };
|
|
2803
2840
|
}
|
|
2804
2841
|
/** Read one full entry (including secrets) by id. */
|
|
2805
2842
|
async get(id) {
|
|
2806
|
-
const store = await this.
|
|
2843
|
+
const store = await this.guardedStore();
|
|
2807
2844
|
const entry = store.get(id);
|
|
2808
2845
|
if (entry === undefined)
|
|
2809
2846
|
return { found: false };
|
|
@@ -2811,7 +2848,7 @@ let VaultGateway = (() => {
|
|
|
2811
2848
|
}
|
|
2812
2849
|
/** Search entries across text fields; returns non-secret summaries. */
|
|
2813
2850
|
async search(query, limit) {
|
|
2814
|
-
const store = await this.
|
|
2851
|
+
const store = await this.guardedStore();
|
|
2815
2852
|
return { entries: store.search(query, limit) };
|
|
2816
2853
|
}
|
|
2817
2854
|
/** Add a new entry; returns its id and summary. */
|
|
@@ -2819,14 +2856,14 @@ let VaultGateway = (() => {
|
|
|
2819
2856
|
this.assertWritable('add');
|
|
2820
2857
|
if (!patch.title.trim())
|
|
2821
2858
|
throw new Error('vault: title must not be empty');
|
|
2822
|
-
const store = await this.
|
|
2859
|
+
const store = await this.guardedStore();
|
|
2823
2860
|
const entry = await store.add(patch);
|
|
2824
2861
|
return toSummary(entry);
|
|
2825
2862
|
}
|
|
2826
2863
|
/** Update an existing entry's fields; returns the updated summary or not-found. */
|
|
2827
2864
|
async update(id, patch) {
|
|
2828
2865
|
this.assertWritable('update');
|
|
2829
|
-
const store = await this.
|
|
2866
|
+
const store = await this.guardedStore();
|
|
2830
2867
|
const updated = await store.update(id, patch);
|
|
2831
2868
|
if (updated === undefined)
|
|
2832
2869
|
return { found: false };
|
|
@@ -2835,7 +2872,7 @@ let VaultGateway = (() => {
|
|
|
2835
2872
|
/** Delete an entry by id. */
|
|
2836
2873
|
async delete(id) {
|
|
2837
2874
|
this.assertWritable('delete');
|
|
2838
|
-
const store = await this.
|
|
2875
|
+
const store = await this.guardedStore();
|
|
2839
2876
|
return { deleted: await store.delete(id) };
|
|
2840
2877
|
}
|
|
2841
2878
|
/** Generate the current TOTP code for a stored otpSecret (or bare secret). */
|
|
@@ -2846,7 +2883,7 @@ let VaultGateway = (() => {
|
|
|
2846
2883
|
let input;
|
|
2847
2884
|
let label;
|
|
2848
2885
|
if (id !== undefined) {
|
|
2849
|
-
const store = await this.
|
|
2886
|
+
const store = await this.guardedStore();
|
|
2850
2887
|
const entry = store.get(id);
|
|
2851
2888
|
if (entry?.otpSecret === undefined)
|
|
2852
2889
|
throw new Error(`vault.totp: entry ${id} has no otpSecret`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vault",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Encrypted credential vault for DeepSeek Harness: store and retrieve usernames, emails, phone numbers, passwords, TOTP secrets, SSH/API-key/OAuth developer credentials through model tools and a Settings UI page.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|