dsh-vault 1.9.2 → 1.9.3
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 +389 -97
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -7,7 +7,7 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
9
|
//#region \0dsh-css:/Users/zhipeng/Desktop/work/dsh test/dsh-vault/src/client/VaultSection.module.css.mjs
|
|
10
|
-
const css = ".t_j5va_section{flex-direction:column;gap:12px;padding:16px 0;display:flex}.t_j5va_intro{opacity:.75;margin:0;font-size:13px}.t_j5va_srOnly{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.t_j5va_toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.t_j5va_searchBox{flex:150px;min-width:150px;display:flex}.t_j5va_searchBox input{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}.t_j5va_addButton,.t_j5va_saveButton{background:var(--color-accent,#4f8cff);color:#fff;cursor:pointer;border:1px solid #0000;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_addButton:disabled,.t_j5va_saveButton:disabled,.t_j5va_rowActions button:disabled{opacity:.5;cursor:not-allowed}.t_j5va_list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.t_j5va_row{border:1px solid var(--color-border,#333);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:8px 10px;display:flex}.t_j5va_rowMain{flex-direction:column;gap:2px;min-width:0;display:flex}.t_j5va_title{font-size:14px;font-weight:600}.t_j5va_identity{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_totp{font-family:var(--font-mono,monospace);color:var(--color-accent,#4f8cff);font-size:13px}.t_j5va_totpRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_rowActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.t_j5va_rowActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:4px 8px;font-size:12px}.t_j5va_deleteButton{color:#e5484d}.t_j5va_copied{color:#30a46c;font-size:12px}.t_j5va_empty,.t_j5va_status,.t_j5va_error{opacity:.8;font-size:13px}.t_j5va_lockedBanner{color:#8a5a00;background:#fff4e5;border:1px solid #e0a83a;border-radius:6px;margin:0 0 10px;padding:8px 12px;font-size:13px}.t_j5va_modeReadonly,.t_j5va_modeAsk,.t_j5va_modeAuto{border-radius:999px;width:fit-content;margin:0;padding:4px 10px;font-size:12px;display:inline-block}.t_j5va_modeReadonly{color:#e5484d;border:1px solid #e5484d80}.t_j5va_modeAsk{color:#f5a524;border:1px solid #f5a52480}.t_j5va_modeAuto{color:#30a46c;border:1px solid #30a46c80}.t_j5va_policyBar{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.t_j5va_policyField{align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_policyField select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:4px 8px;font-size:13px}.t_j5va_emptyBox{flex-direction:column;gap:4px;display:flex}.t_j5va_emptyHint{opacity:.65;margin:0;font-size:12px}.t_j5va_error{color:#e5484d}.t_j5va_editor{border:1px solid var(--color-border,#444);border-radius:8px;padding:12px}.t_j5va_editorBody{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 12px;display:grid}.t_j5va_checkField{align-items:center;gap:8px;font-size:13px;display:inline-flex}.t_j5va_field{flex-direction:column;gap:4px;font-size:12px;display:flex}.t_j5va_field input,.t_j5va_field select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:5px 8px;font-size:13px}.t_j5va_editorActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.t_j5va_editorActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_reportBox{border:1px solid #f5a52466;border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;font-size:12px;display:flex}.t_j5va_reportTitle{margin:0;font-weight:600}.t_j5va_reportLine{opacity:.8;margin:0}.t_j5va_reportSub{color:var(--dsh-color-text-2,#666);margin:2px 0 0 10px;font-size:12px}.t_j5va_trashButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_secretField{gap:4px;display:flex}.t_j5va_secretField input{flex:1;min-width:0}.t_j5va_revealButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 8px;font-size:12px}.t_j5va_kindFilter{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:6px 8px;font-size:13px}.t_j5va_highBadge{color:#e5484d;vertical-align:middle;background:#e5484d26;border-radius:4px;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:600}.t_j5va_pinStar{color:#f5a524;cursor:pointer;background:0 0;border:none;margin-right:4px;padding:0 2px;font-size:13px;line-height:1}.t_j5va_pinOff{color:#80808073}.t_j5va_pinOn{color:#f5a524}.t_j5va_clearButton{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 8px;font-size:16px}.t_j5va_field textarea{border:1px solid var(--color-border,#444);color:inherit;resize:vertical;background:0 0;border-radius:6px;padding:5px 8px;font-family:inherit;font-size:13px}.t_j5va_row{transition:background .12s}.t_j5va_row:hover{background:var(--color-hover,#80808014)}.t_j5va_healthBar{flex-wrap:wrap;gap:6px;margin:0 0 10px;display:flex}.t_j5va_badge{border:1px solid var(--dsh-color-border,#ddd);background:var(--dsh-color-surface-2,#f7f7f8);color:var(--dsh-color-text-2,#555);border-radius:999px;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_backupButton{border:1px solid var(--dsh-color-border,#ccc);background:var(--dsh-color-surface-2,#f7f7f8);cursor:pointer;border-radius:999px;align-self:flex-start;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_badgeOk{color:#2e9e5b;border-color:#2e9e5b}.t_j5va_badgeWarn{color:#b57f1a;border-color:#c98a1b}.t_j5va_rowDue{border-left:3px solid #c98a1b}.t_j5va_rowExpired{border-left:3px solid #cf3d3d}.t_j5va_dueBadge{border-radius:999px;margin-left:6px;padding:3px 8px;font-size:11px;font-weight:600;line-height:1}.t_j5va_badgeDanger{color:#c03a3a;border-color:#cf3d3d}.t_j5va_footer{opacity:.6;margin:0;font-size:12px}.t_j5va_kindIcon{margin-right:4px;font-size:12px}.t_j5va_dangerButton{color:#e5484d;cursor:pointer;background:0 0;border:1px solid #e5484d80;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_rowMain{cursor:pointer}.t_j5va_detailBox{background:var(--color-hover,#8080800f);border-radius:6px;flex-wrap:wrap;grid-column:1/-1;gap:4px 12px;padding:6px 8px;font-size:12px;display:flex}.t_j5va_detailItem{opacity:.85}.t_j5va_sortButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 10px;font-size:13px}.t_j5va_dupGroup{justify-content:space-between;align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_dupNames{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_dupMerge{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;flex-shrink:0;padding:2px 8px;font-size:12px}.t_j5va_auditRow{align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_auditIssues{color:var(--dsh-color-text-2,#666);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.t_j5va_retryButton{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;margin-left:6px;padding:2px 8px;font-size:12px}.t_j5va_scoreRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_genOpts{border:1px solid var(--dsh-color-border,#ddd);border-radius:8px;flex-direction:column;gap:6px;padding:8px 10px;display:flex}.t_j5va_genOptRow{justify-content:space-between;align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_genOptRow input[type=number]{width:64px}.t_j5va_pwMeter{align-items:center;gap:8px;font-size:12px;display:flex}.t_j5va_pwBar{border-radius:999px;height:6px;transition:width .2s}.t_j5va_pwWeak{background:#cf3d3d}.t_j5va_pwFair{background:#c98a1b}.t_j5va_pwStrong{background:#2e9e5b}.t_j5va_pwLabel{color:var(--dsh-color-text-2,#666)}.t_j5va_resultCount{color:var(--dsh-color-text-2,#666);flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 6px;font-size:12px;display:flex}.t_j5va_kindChip{border:1px solid var(--dsh-color-border,#ddd);border-radius:999px;padding:2px 8px;font-size:11px}.t_j5va_uriCode{overflow-wrap:anywhere;opacity:.85;font-size:10px}.t_j5va_genHist{flex-wrap:wrap;gap:4px;font-size:12px;display:flex}.t_j5va_genHist span{align-self:center}.t_j5va_lockedTag{color:#c98a1b;font-size:12px;font-weight:600}.t_j5va_tabs{flex-wrap:wrap;gap:6px;margin:0 0 12px;display:flex}.t_j5va_tab{border:1px solid var(--dsh-color-border,#ccc);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:5px 14px;font-size:13px}.t_j5va_tabActive{background:var(--dsh-color-primary,#4a6cf7);color:#fff;border-color:#0000}.t_j5va_tabPane{margin-top:2px}";
|
|
10
|
+
const css = ".t_j5va_section{flex-direction:column;gap:12px;padding:16px 0;display:flex}.t_j5va_intro{opacity:.75;margin:0;font-size:13px}.t_j5va_srOnly{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.t_j5va_toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.t_j5va_healthSummary{flex-wrap:wrap;align-items:center;gap:4px;display:inline-flex}.t_j5va_selectActive{border-color:var(--dsh-color-primary,#2e9e5b);color:var(--dsh-color-primary,#2e9e5b)}.t_j5va_bulkBar{background:var(--dsh-color-surface-2,#80808014);border-radius:6px;flex-wrap:wrap;align-items:center;gap:10px;margin:6px 0;padding:6px 10px;display:flex}.t_j5va_bulkItem{align-items:center;gap:6px;font-size:13px;display:inline-flex}.t_j5va_bulkCount{opacity:.8;font-size:13px}.t_j5va_rowCheck{flex-shrink:0;align-self:center;margin:0 8px 0 0}.t_j5va_rowSelected{outline:1px solid var(--dsh-color-primary,#2e9e5b);border-radius:4px}.t_j5va_searchBox{flex:150px;min-width:150px;display:flex}.t_j5va_searchBox input{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}.t_j5va_addButton,.t_j5va_saveButton{background:var(--color-accent,#4f8cff);color:#fff;cursor:pointer;border:1px solid #0000;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_addButton:disabled,.t_j5va_saveButton:disabled,.t_j5va_rowActions button:disabled{opacity:.5;cursor:not-allowed}.t_j5va_list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.t_j5va_row{border:1px solid var(--color-border,#333);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:8px 10px;display:flex}.t_j5va_rowMain{flex-direction:column;gap:2px;min-width:0;display:flex}.t_j5va_title{font-size:14px;font-weight:600}.t_j5va_identity{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_totp{font-family:var(--font-mono,monospace);color:var(--color-accent,#4f8cff);font-size:13px}.t_j5va_totpRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_rowActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.t_j5va_rowActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:4px 8px;font-size:12px}.t_j5va_deleteButton{color:#e5484d}.t_j5va_copied{color:#30a46c;font-size:12px}.t_j5va_empty,.t_j5va_status,.t_j5va_error{opacity:.8;font-size:13px}.t_j5va_lockedBanner{color:#8a5a00;background:#fff4e5;border:1px solid #e0a83a;border-radius:6px;margin:0 0 10px;padding:8px 12px;font-size:13px}.t_j5va_modeReadonly,.t_j5va_modeAsk,.t_j5va_modeAuto{border-radius:999px;width:fit-content;margin:0;padding:4px 10px;font-size:12px;display:inline-block}.t_j5va_modeReadonly{color:#e5484d;border:1px solid #e5484d80}.t_j5va_modeAsk{color:#f5a524;border:1px solid #f5a52480}.t_j5va_modeAuto{color:#30a46c;border:1px solid #30a46c80}.t_j5va_policyBar{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.t_j5va_policyField{align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_policyField select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:4px 8px;font-size:13px}.t_j5va_emptyBox{flex-direction:column;gap:4px;display:flex}.t_j5va_emptyHint{opacity:.65;margin:0;font-size:12px}.t_j5va_error{color:#e5484d}.t_j5va_editor{border:1px solid var(--color-border,#444);border-radius:8px;padding:12px}.t_j5va_editorBody{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 12px;display:grid}.t_j5va_checkField{align-items:center;gap:8px;font-size:13px;display:inline-flex}.t_j5va_field{flex-direction:column;gap:4px;font-size:12px;display:flex}.t_j5va_field input,.t_j5va_field select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:5px 8px;font-size:13px}.t_j5va_editorActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.t_j5va_editorActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_reportBox{border:1px solid #f5a52466;border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;font-size:12px;display:flex}.t_j5va_reportTitle{margin:0;font-weight:600}.t_j5va_reportLine{opacity:.8;margin:0}.t_j5va_histAdd{color:#2e9e5b}.t_j5va_histDanger{color:#cf3d3d}.t_j5va_histUpdate{color:#c98a1b}.t_j5va_histNeutral{opacity:.7}.t_j5va_reportSub{color:var(--dsh-color-text-2,#666);margin:2px 0 0 10px;font-size:12px}.t_j5va_trashButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_secretField{gap:4px;display:flex}.t_j5va_secretField input{flex:1;min-width:0}.t_j5va_revealButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 8px;font-size:12px}.t_j5va_kindFilter{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:6px 8px;font-size:13px}.t_j5va_highBadge{color:#e5484d;vertical-align:middle;background:#e5484d26;border-radius:4px;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:600}.t_j5va_pinStar{color:#f5a524;cursor:pointer;background:0 0;border:none;margin-right:4px;padding:0 2px;font-size:13px;line-height:1}.t_j5va_pinOff{color:#80808073}.t_j5va_pinOn{color:#f5a524}.t_j5va_clearButton{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 8px;font-size:16px}.t_j5va_field textarea{border:1px solid var(--color-border,#444);color:inherit;resize:vertical;background:0 0;border-radius:6px;padding:5px 8px;font-family:inherit;font-size:13px}.t_j5va_row{transition:background .12s}.t_j5va_row:hover{background:var(--color-hover,#80808014)}.t_j5va_healthBar{flex-wrap:wrap;gap:6px;margin:0 0 10px;display:flex}.t_j5va_badge{border:1px solid var(--dsh-color-border,#ddd);background:var(--dsh-color-surface-2,#f7f7f8);color:var(--dsh-color-text-2,#555);border-radius:999px;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_backupButton{border:1px solid var(--dsh-color-border,#ccc);background:var(--dsh-color-surface-2,#f7f7f8);cursor:pointer;border-radius:999px;align-self:flex-start;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_badgeOk{color:#2e9e5b;border-color:#2e9e5b}.t_j5va_badgeWarn{color:#b57f1a;border-color:#c98a1b}.t_j5va_rowDue{border-left:3px solid #c98a1b}.t_j5va_rowExpired{border-left:3px solid #cf3d3d}.t_j5va_dueBadge{border-radius:999px;margin-left:6px;padding:3px 8px;font-size:11px;font-weight:600;line-height:1}.t_j5va_badgeDanger{color:#c03a3a;border-color:#cf3d3d}.t_j5va_footer{opacity:.6;margin:0;font-size:12px}.t_j5va_kindIcon{margin-right:4px;font-size:12px}.t_j5va_dangerButton{color:#e5484d;cursor:pointer;background:0 0;border:1px solid #e5484d80;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_rowMain{cursor:pointer}.t_j5va_detailBox{background:var(--color-hover,#8080800f);border-radius:6px;flex-wrap:wrap;grid-column:1/-1;gap:4px 12px;padding:6px 8px;font-size:12px;display:flex}.t_j5va_detailItem{opacity:.85}.t_j5va_sortButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 10px;font-size:13px}.t_j5va_dupGroup{justify-content:space-between;align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_dupNames{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_dupMerge{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;flex-shrink:0;padding:2px 8px;font-size:12px}.t_j5va_auditRow{align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_auditIssues{color:var(--dsh-color-text-2,#666);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.t_j5va_retryButton{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;margin-left:6px;padding:2px 8px;font-size:12px}.t_j5va_scoreRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_genOpts{border:1px solid var(--dsh-color-border,#ddd);border-radius:8px;flex-direction:column;gap:6px;padding:8px 10px;display:flex}.t_j5va_genOptRow{justify-content:space-between;align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_genOptRow input[type=number]{width:64px}.t_j5va_pwMeter{align-items:center;gap:8px;font-size:12px;display:flex}.t_j5va_pwBar{border-radius:999px;height:6px;transition:width .2s}.t_j5va_pwWeak{background:#cf3d3d}.t_j5va_pwFair{background:#c98a1b}.t_j5va_pwStrong{background:#2e9e5b}.t_j5va_pwLabel{color:var(--dsh-color-text-2,#666)}.t_j5va_resultCount{color:var(--dsh-color-text-2,#666);flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 6px;font-size:12px;display:flex}.t_j5va_kindChip{border:1px solid var(--dsh-color-border,#ddd);border-radius:999px;padding:2px 8px;font-size:11px}.t_j5va_uriCode{overflow-wrap:anywhere;opacity:.85;font-size:10px}.t_j5va_genHist{flex-wrap:wrap;gap:4px;font-size:12px;display:flex}.t_j5va_genHist span{align-self:center}.t_j5va_lockedTag{color:#c98a1b;font-size:12px;font-weight:600}.t_j5va_tabs{flex-wrap:wrap;gap:6px;margin:0 0 12px;display:flex}.t_j5va_tab{border:1px solid var(--dsh-color-border,#ccc);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:5px 14px;font-size:13px}.t_j5va_tabActive{background:var(--dsh-color-primary,#4a6cf7);color:#fff;border-color:#0000}.t_j5va_tabPane{margin-top:2px}";
|
|
11
11
|
const tagId = "dsh-vault/VaultSection.module.css";
|
|
12
12
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
13
13
|
const tag = document.createElement("style");
|
|
@@ -17,91 +17,102 @@ window.__ModuleLoader__.load({
|
|
|
17
17
|
document.head.appendChild(tag);
|
|
18
18
|
}
|
|
19
19
|
var VaultSection_module_css_default = {
|
|
20
|
-
"deleteButton": "t_j5va_deleteButton",
|
|
21
|
-
"trashButton": "t_j5va_trashButton",
|
|
22
|
-
"pwMeter": "t_j5va_pwMeter",
|
|
23
|
-
"uriCode": "t_j5va_uriCode",
|
|
24
|
-
"srOnly": "t_j5va_srOnly",
|
|
25
|
-
"reportBox": "t_j5va_reportBox",
|
|
26
|
-
"intro": "t_j5va_intro",
|
|
27
|
-
"dueBadge": "t_j5va_dueBadge",
|
|
28
|
-
"field": "t_j5va_field",
|
|
29
|
-
"totp": "t_j5va_totp",
|
|
30
|
-
"title": "t_j5va_title",
|
|
31
|
-
"rowMain": "t_j5va_rowMain",
|
|
32
|
-
"searchBox": "t_j5va_searchBox",
|
|
33
|
-
"badgeOk": "t_j5va_badgeOk",
|
|
34
|
-
"reportTitle": "t_j5va_reportTitle",
|
|
35
|
-
"toolbar": "t_j5va_toolbar",
|
|
36
|
-
"policyBar": "t_j5va_policyBar",
|
|
37
|
-
"tab": "t_j5va_tab",
|
|
38
20
|
"addButton": "t_j5va_addButton",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"list": "t_j5va_list",
|
|
43
|
-
"reportSub": "t_j5va_reportSub",
|
|
21
|
+
"identity": "t_j5va_identity",
|
|
22
|
+
"pinOff": "t_j5va_pinOff",
|
|
23
|
+
"badgeWarn": "t_j5va_badgeWarn",
|
|
44
24
|
"retryButton": "t_j5va_retryButton",
|
|
45
|
-
"modeAsk": "t_j5va_modeAsk",
|
|
46
25
|
"editorBody": "t_j5va_editorBody",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"kindChip": "t_j5va_kindChip",
|
|
57
|
-
"saveButton": "t_j5va_saveButton",
|
|
58
|
-
"auditIssues": "t_j5va_auditIssues",
|
|
59
|
-
"editor": "t_j5va_editor",
|
|
60
|
-
"healthBar": "t_j5va_healthBar",
|
|
61
|
-
"clearButton": "t_j5va_clearButton",
|
|
62
|
-
"dupMerge": "t_j5va_dupMerge",
|
|
63
|
-
"pwStrong": "t_j5va_pwStrong",
|
|
64
|
-
"emptyHint": "t_j5va_emptyHint",
|
|
26
|
+
"dueBadge": "t_j5va_dueBadge",
|
|
27
|
+
"scoreRing": "t_j5va_scoreRing",
|
|
28
|
+
"genHist": "t_j5va_genHist",
|
|
29
|
+
"bulkCount": "t_j5va_bulkCount",
|
|
30
|
+
"empty": "t_j5va_empty",
|
|
31
|
+
"lockedBanner": "t_j5va_lockedBanner",
|
|
32
|
+
"modeAsk": "t_j5va_modeAsk",
|
|
33
|
+
"reportBox": "t_j5va_reportBox",
|
|
34
|
+
"row": "t_j5va_row",
|
|
65
35
|
"secretField": "t_j5va_secretField",
|
|
66
|
-
"highBadge": "t_j5va_highBadge",
|
|
67
|
-
"rowActions": "t_j5va_rowActions",
|
|
68
|
-
"rowExpired": "t_j5va_rowExpired",
|
|
69
36
|
"modeAuto": "t_j5va_modeAuto",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"error": "t_j5va_error",
|
|
73
|
-
"genHist": "t_j5va_genHist",
|
|
74
|
-
"tabActive": "t_j5va_tabActive",
|
|
75
|
-
"rowDue": "t_j5va_rowDue",
|
|
76
|
-
"kindIcon": "t_j5va_kindIcon",
|
|
77
|
-
"editorActions": "t_j5va_editorActions",
|
|
37
|
+
"rowExpired": "t_j5va_rowExpired",
|
|
38
|
+
"footer": "t_j5va_footer",
|
|
78
39
|
"pinOn": "t_j5va_pinOn",
|
|
79
|
-
"lockedBanner": "t_j5va_lockedBanner",
|
|
80
|
-
"copied": "t_j5va_copied",
|
|
81
|
-
"section": "t_j5va_section",
|
|
82
|
-
"detailBox": "t_j5va_detailBox",
|
|
83
|
-
"detailItem": "t_j5va_detailItem",
|
|
84
|
-
"badgeDanger": "t_j5va_badgeDanger",
|
|
85
|
-
"scoreRing": "t_j5va_scoreRing",
|
|
86
|
-
"backupButton": "t_j5va_backupButton",
|
|
87
|
-
"pwFair": "t_j5va_pwFair",
|
|
88
|
-
"tabs": "t_j5va_tabs",
|
|
89
40
|
"emptyBox": "t_j5va_emptyBox",
|
|
41
|
+
"checkField": "t_j5va_checkField",
|
|
42
|
+
"histUpdate": "t_j5va_histUpdate",
|
|
43
|
+
"clearButton": "t_j5va_clearButton",
|
|
44
|
+
"healthBar": "t_j5va_healthBar",
|
|
90
45
|
"dupNames": "t_j5va_dupNames",
|
|
91
|
-
"
|
|
46
|
+
"selectActive": "t_j5va_selectActive",
|
|
47
|
+
"searchBox": "t_j5va_searchBox",
|
|
48
|
+
"histAdd": "t_j5va_histAdd",
|
|
49
|
+
"deleteButton": "t_j5va_deleteButton",
|
|
50
|
+
"kindChip": "t_j5va_kindChip",
|
|
51
|
+
"tabPane": "t_j5va_tabPane",
|
|
52
|
+
"editorActions": "t_j5va_editorActions",
|
|
53
|
+
"list": "t_j5va_list",
|
|
54
|
+
"status": "t_j5va_status",
|
|
55
|
+
"bulkItem": "t_j5va_bulkItem",
|
|
56
|
+
"kindIcon": "t_j5va_kindIcon",
|
|
57
|
+
"dupGroup": "t_j5va_dupGroup",
|
|
58
|
+
"detailItem": "t_j5va_detailItem",
|
|
59
|
+
"kindFilter": "t_j5va_kindFilter",
|
|
60
|
+
"rowSelected": "t_j5va_rowSelected",
|
|
61
|
+
"pwStrong": "t_j5va_pwStrong",
|
|
62
|
+
"histDanger": "t_j5va_histDanger",
|
|
92
63
|
"pinStar": "t_j5va_pinStar",
|
|
93
|
-
"
|
|
64
|
+
"policyBar": "t_j5va_policyBar",
|
|
94
65
|
"lockedTag": "t_j5va_lockedTag",
|
|
95
|
-
"checkField": "t_j5va_checkField",
|
|
96
|
-
"tabPane": "t_j5va_tabPane",
|
|
97
66
|
"dangerButton": "t_j5va_dangerButton",
|
|
98
|
-
"
|
|
99
|
-
"
|
|
67
|
+
"dupMerge": "t_j5va_dupMerge",
|
|
68
|
+
"resultCount": "t_j5va_resultCount",
|
|
69
|
+
"bulkBar": "t_j5va_bulkBar",
|
|
70
|
+
"revealButton": "t_j5va_revealButton",
|
|
100
71
|
"totpRing": "t_j5va_totpRing",
|
|
72
|
+
"detailBox": "t_j5va_detailBox",
|
|
73
|
+
"reportTitle": "t_j5va_reportTitle",
|
|
74
|
+
"section": "t_j5va_section",
|
|
75
|
+
"histNeutral": "t_j5va_histNeutral",
|
|
76
|
+
"reportSub": "t_j5va_reportSub",
|
|
77
|
+
"rowDue": "t_j5va_rowDue",
|
|
78
|
+
"pwMeter": "t_j5va_pwMeter",
|
|
101
79
|
"pwWeak": "t_j5va_pwWeak",
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
80
|
+
"rowMain": "t_j5va_rowMain",
|
|
81
|
+
"rowActions": "t_j5va_rowActions",
|
|
82
|
+
"badgeOk": "t_j5va_badgeOk",
|
|
83
|
+
"genOpts": "t_j5va_genOpts",
|
|
84
|
+
"tabActive": "t_j5va_tabActive",
|
|
85
|
+
"reportLine": "t_j5va_reportLine",
|
|
86
|
+
"highBadge": "t_j5va_highBadge",
|
|
87
|
+
"error": "t_j5va_error",
|
|
88
|
+
"intro": "t_j5va_intro",
|
|
89
|
+
"modeReadonly": "t_j5va_modeReadonly",
|
|
90
|
+
"badgeDanger": "t_j5va_badgeDanger",
|
|
91
|
+
"genOptRow": "t_j5va_genOptRow",
|
|
92
|
+
"uriCode": "t_j5va_uriCode",
|
|
93
|
+
"saveButton": "t_j5va_saveButton",
|
|
94
|
+
"toolbar": "t_j5va_toolbar",
|
|
95
|
+
"sortButton": "t_j5va_sortButton",
|
|
96
|
+
"srOnly": "t_j5va_srOnly",
|
|
97
|
+
"rowCheck": "t_j5va_rowCheck",
|
|
98
|
+
"trashButton": "t_j5va_trashButton",
|
|
99
|
+
"auditIssues": "t_j5va_auditIssues",
|
|
100
|
+
"copied": "t_j5va_copied",
|
|
101
|
+
"emptyHint": "t_j5va_emptyHint",
|
|
102
|
+
"editor": "t_j5va_editor",
|
|
103
|
+
"field": "t_j5va_field",
|
|
104
|
+
"tabs": "t_j5va_tabs",
|
|
105
|
+
"auditRow": "t_j5va_auditRow",
|
|
106
|
+
"policyField": "t_j5va_policyField",
|
|
107
|
+
"pwLabel": "t_j5va_pwLabel",
|
|
108
|
+
"title": "t_j5va_title",
|
|
109
|
+
"healthSummary": "t_j5va_healthSummary",
|
|
110
|
+
"totp": "t_j5va_totp",
|
|
111
|
+
"backupButton": "t_j5va_backupButton",
|
|
112
|
+
"tab": "t_j5va_tab",
|
|
113
|
+
"pwFair": "t_j5va_pwFair",
|
|
114
|
+
"pwBar": "t_j5va_pwBar",
|
|
115
|
+
"badge": "t_j5va_badge"
|
|
105
116
|
};
|
|
106
117
|
//#endregion
|
|
107
118
|
//#region src/client/VaultSection.tsx
|
|
@@ -333,6 +344,8 @@ window.__ModuleLoader__.load({
|
|
|
333
344
|
const [tagFilter, setTagFilter] = (0, react.useState)("");
|
|
334
345
|
const [expandedId, setExpandedId] = (0, react.useState)(null);
|
|
335
346
|
const [attachmentsMap, setAttachmentsMap] = (0, react.useState)({});
|
|
347
|
+
const [selectMode, setSelectMode] = (0, react.useState)(false);
|
|
348
|
+
const [selectedIds, setSelectedIds] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
336
349
|
const [visibleCount, setVisibleCount] = (0, react.useState)(50);
|
|
337
350
|
const [sortBy, setSortBy] = (0, react.useState)("alpha");
|
|
338
351
|
const [activeTab, setActiveTab] = (0, react.useState)("entries");
|
|
@@ -425,7 +438,8 @@ window.__ModuleLoader__.load({
|
|
|
425
438
|
const timer = window.setTimeout(() => {
|
|
426
439
|
strength(pw).then((r) => setPwStrength({
|
|
427
440
|
score: r.score,
|
|
428
|
-
verdict: r.verdict
|
|
441
|
+
verdict: r.verdict,
|
|
442
|
+
bits: r.bits
|
|
429
443
|
}), () => setPwStrength(null));
|
|
430
444
|
}, 250);
|
|
431
445
|
return () => window.clearTimeout(timer);
|
|
@@ -616,6 +630,7 @@ window.__ModuleLoader__.load({
|
|
|
616
630
|
try {
|
|
617
631
|
setMessage((await import1password(path.trim(), false)).note);
|
|
618
632
|
refresh();
|
|
633
|
+
refreshHealth();
|
|
619
634
|
} catch (err) {
|
|
620
635
|
setMessage(errText(err));
|
|
621
636
|
} finally {
|
|
@@ -650,6 +665,7 @@ window.__ModuleLoader__.load({
|
|
|
650
665
|
try {
|
|
651
666
|
setMessage((await importManagerCsv(path.trim(), false)).note);
|
|
652
667
|
refresh();
|
|
668
|
+
refreshHealth();
|
|
653
669
|
} catch (err) {
|
|
654
670
|
setMessage(errText(err));
|
|
655
671
|
} finally {
|
|
@@ -665,6 +681,7 @@ window.__ModuleLoader__.load({
|
|
|
665
681
|
try {
|
|
666
682
|
setMessage((await importEnpass(path.trim(), false)).note);
|
|
667
683
|
refresh();
|
|
684
|
+
refreshHealth();
|
|
668
685
|
} catch (err) {
|
|
669
686
|
setMessage(errText(err));
|
|
670
687
|
} finally {
|
|
@@ -680,6 +697,7 @@ window.__ModuleLoader__.load({
|
|
|
680
697
|
try {
|
|
681
698
|
setMessage((await importBitwarden(path.trim(), false)).note);
|
|
682
699
|
refresh();
|
|
700
|
+
refreshHealth();
|
|
683
701
|
} catch (err) {
|
|
684
702
|
setMessage(errText(err));
|
|
685
703
|
} finally {
|
|
@@ -697,6 +715,7 @@ window.__ModuleLoader__.load({
|
|
|
697
715
|
try {
|
|
698
716
|
setMessage((await importBitwardenEncrypted(path.trim(), password, false)).note);
|
|
699
717
|
refresh();
|
|
718
|
+
refreshHealth();
|
|
700
719
|
} catch (err) {
|
|
701
720
|
setMessage(errText(err));
|
|
702
721
|
} finally {
|
|
@@ -712,6 +731,7 @@ window.__ModuleLoader__.load({
|
|
|
712
731
|
try {
|
|
713
732
|
setMessage((await import1pif(path.trim(), false)).note);
|
|
714
733
|
refresh();
|
|
734
|
+
refreshHealth();
|
|
715
735
|
} catch (err) {
|
|
716
736
|
setMessage(errText(err));
|
|
717
737
|
} finally {
|
|
@@ -727,6 +747,7 @@ window.__ModuleLoader__.load({
|
|
|
727
747
|
try {
|
|
728
748
|
setMessage((await importKeePassXml(path.trim(), false)).note);
|
|
729
749
|
refresh();
|
|
750
|
+
refreshHealth();
|
|
730
751
|
} catch (err) {
|
|
731
752
|
setMessage(errText(err));
|
|
732
753
|
} finally {
|
|
@@ -743,6 +764,7 @@ window.__ModuleLoader__.load({
|
|
|
743
764
|
try {
|
|
744
765
|
setMessage((await importKdbx(path.trim(), password, "", false)).note);
|
|
745
766
|
refresh();
|
|
767
|
+
refreshHealth();
|
|
746
768
|
} catch (err) {
|
|
747
769
|
setMessage(errText(err));
|
|
748
770
|
} finally {
|
|
@@ -1269,6 +1291,32 @@ window.__ModuleLoader__.load({
|
|
|
1269
1291
|
current = false;
|
|
1270
1292
|
};
|
|
1271
1293
|
}, [expandedId, attachments]);
|
|
1294
|
+
/** Recompute just the health report (weak/reused/no-2FA/rotation) after a
|
|
1295
|
+
* write so the toolbar badges stay current without a full reload. */
|
|
1296
|
+
const refreshHealth = (0, react.useCallback)(() => {
|
|
1297
|
+
health().then((hl) => {
|
|
1298
|
+
setReport((previous) => ({
|
|
1299
|
+
...previous ?? {
|
|
1300
|
+
rotation: [],
|
|
1301
|
+
weak: [],
|
|
1302
|
+
reused: [],
|
|
1303
|
+
strength: null,
|
|
1304
|
+
no2fa: [],
|
|
1305
|
+
httpSites: [],
|
|
1306
|
+
score: 100,
|
|
1307
|
+
verdict: "good"
|
|
1308
|
+
},
|
|
1309
|
+
weak: hl?.weak ?? [],
|
|
1310
|
+
reused: hl?.reused ?? [],
|
|
1311
|
+
strength: hl?.strength ?? null,
|
|
1312
|
+
no2fa: hl?.no2fa ?? [],
|
|
1313
|
+
httpSites: hl?.httpSites ?? [],
|
|
1314
|
+
score: Number(hl?.score ?? 100),
|
|
1315
|
+
verdict: String(hl?.verdict ?? "good")
|
|
1316
|
+
}));
|
|
1317
|
+
}).catch(() => {});
|
|
1318
|
+
history().then((events) => setRecentEvents(events ?? [])).catch(() => {});
|
|
1319
|
+
}, [health, history]);
|
|
1272
1320
|
(0, react.useEffect)(() => {
|
|
1273
1321
|
let current = true;
|
|
1274
1322
|
const load = () => {
|
|
@@ -1278,9 +1326,11 @@ window.__ModuleLoader__.load({
|
|
|
1278
1326
|
rotation().catch(() => []),
|
|
1279
1327
|
health().catch(() => null),
|
|
1280
1328
|
recent().catch(() => []),
|
|
1329
|
+
history().catch(() => []),
|
|
1281
1330
|
duplicates().catch(() => null)
|
|
1282
|
-
]).then(([st, bk, rot, hl, rc, dp]) => {
|
|
1331
|
+
]).then(([st, bk, rot, hl, rc, hst, dp]) => {
|
|
1283
1332
|
if (dp !== null && typeof dp === "object" && dp.groups !== void 0) setDupGroups(dp.groups);
|
|
1333
|
+
if (Array.isArray(hst)) setRecentEvents(hst);
|
|
1284
1334
|
duplicateGroups().then(setDupList).catch(() => {});
|
|
1285
1335
|
verifyAll().then(setAudit).catch(() => {});
|
|
1286
1336
|
tags().then(setTagList).catch(() => {});
|
|
@@ -1444,6 +1494,7 @@ window.__ModuleLoader__.load({
|
|
|
1444
1494
|
}
|
|
1445
1495
|
setEditor({ status: "closed" });
|
|
1446
1496
|
await refresh();
|
|
1497
|
+
refreshHealth();
|
|
1447
1498
|
} catch (err) {
|
|
1448
1499
|
setMessage(errText(err));
|
|
1449
1500
|
} finally {
|
|
@@ -1453,10 +1504,40 @@ window.__ModuleLoader__.load({
|
|
|
1453
1504
|
/** Delete an entry after confirmation. */
|
|
1454
1505
|
async function removeEntry(id) {
|
|
1455
1506
|
if (!window.confirm(t("deleteConfirm"))) return;
|
|
1507
|
+
const title = state.status === "ready" ? state.entries.find((e) => e.id === id)?.title ?? "" : "";
|
|
1456
1508
|
setBusy(true);
|
|
1457
1509
|
try {
|
|
1458
1510
|
await remove(id);
|
|
1459
1511
|
await refresh();
|
|
1512
|
+
refreshHealth();
|
|
1513
|
+
setMessage(title !== "" ? t("deletedWithTitle").replace("{name}", title) : t("deleted"));
|
|
1514
|
+
} catch (err) {
|
|
1515
|
+
setMessage(errText(err));
|
|
1516
|
+
} finally {
|
|
1517
|
+
setBusy(false);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
/** Toggle batch-select mode (Bitwarden-style bulk operations). */
|
|
1521
|
+
function toggleSelectMode() {
|
|
1522
|
+
setSelectMode((m) => {
|
|
1523
|
+
const next = !m;
|
|
1524
|
+
if (!next) setSelectedIds(/* @__PURE__ */ new Set());
|
|
1525
|
+
return next;
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
/** Delete all selected entries after one confirmation (bulk operation). */
|
|
1529
|
+
async function removeSelected() {
|
|
1530
|
+
if (selectedIds.size === 0) return;
|
|
1531
|
+
if (!window.confirm(t("bulkDeleteConfirm").replace("{n}", String(selectedIds.size)))) return;
|
|
1532
|
+
const count = selectedIds.size;
|
|
1533
|
+
setBusy(true);
|
|
1534
|
+
try {
|
|
1535
|
+
await Promise.all([...selectedIds].map((id) => remove(id)));
|
|
1536
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
1537
|
+
setSelectMode(false);
|
|
1538
|
+
await refresh();
|
|
1539
|
+
refreshHealth();
|
|
1540
|
+
setMessage(t("bulkDeleted").replace("{n}", String(count)));
|
|
1460
1541
|
} catch (err) {
|
|
1461
1542
|
setMessage(errText(err));
|
|
1462
1543
|
} finally {
|
|
@@ -1621,9 +1702,9 @@ window.__ModuleLoader__.load({
|
|
|
1621
1702
|
children: t(TAB_KEYS[tab])
|
|
1622
1703
|
}, tab))
|
|
1623
1704
|
}),
|
|
1624
|
-
activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1705
|
+
activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1625
1706
|
className: VaultSection_module_css_default.tabPane,
|
|
1626
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1707
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1627
1708
|
className: VaultSection_module_css_default.toolbar,
|
|
1628
1709
|
children: [
|
|
1629
1710
|
locked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1743,15 +1824,106 @@ window.__ModuleLoader__.load({
|
|
|
1743
1824
|
})
|
|
1744
1825
|
]
|
|
1745
1826
|
}),
|
|
1827
|
+
report !== null && (report.weak.length > 0 || report.reused.length > 0 || report.no2fa.length > 0 || report.httpSites.length > 0 || report.rotation.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1828
|
+
className: VaultSection_module_css_default.healthSummary,
|
|
1829
|
+
title: t("healthSummaryHint"),
|
|
1830
|
+
children: [
|
|
1831
|
+
report.weak.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1832
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
|
|
1833
|
+
children: [
|
|
1834
|
+
t("reportWeak"),
|
|
1835
|
+
": ",
|
|
1836
|
+
report.weak.length
|
|
1837
|
+
]
|
|
1838
|
+
}),
|
|
1839
|
+
report.reused.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1840
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
|
|
1841
|
+
children: [
|
|
1842
|
+
t("reportReused"),
|
|
1843
|
+
": ",
|
|
1844
|
+
report.reused.length
|
|
1845
|
+
]
|
|
1846
|
+
}),
|
|
1847
|
+
report.no2fa.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1848
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
|
|
1849
|
+
children: [
|
|
1850
|
+
t("no2fa"),
|
|
1851
|
+
": ",
|
|
1852
|
+
report.no2fa.length
|
|
1853
|
+
]
|
|
1854
|
+
}),
|
|
1855
|
+
report.httpSites.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1856
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
|
|
1857
|
+
children: [
|
|
1858
|
+
t("httpSites"),
|
|
1859
|
+
": ",
|
|
1860
|
+
report.httpSites.length
|
|
1861
|
+
]
|
|
1862
|
+
}),
|
|
1863
|
+
report.rotation.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1864
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
|
|
1865
|
+
children: [
|
|
1866
|
+
t("reportRotation"),
|
|
1867
|
+
": ",
|
|
1868
|
+
report.rotation.length
|
|
1869
|
+
]
|
|
1870
|
+
})
|
|
1871
|
+
]
|
|
1872
|
+
}),
|
|
1873
|
+
report !== null && report.weak.length === 0 && report.reused.length === 0 && report.no2fa.length === 0 && report.httpSites.length === 0 && report.rotation.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1874
|
+
className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeOk}`,
|
|
1875
|
+
title: t("healthSummaryHint"),
|
|
1876
|
+
children: [t("healthOk"), " ✓"]
|
|
1877
|
+
}),
|
|
1746
1878
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1747
1879
|
type: "button",
|
|
1748
1880
|
className: VaultSection_module_css_default.addButton,
|
|
1749
1881
|
onClick: startCreate,
|
|
1750
1882
|
disabled: busy || readonly || locked,
|
|
1751
1883
|
children: ["+ ", t("add")]
|
|
1884
|
+
}),
|
|
1885
|
+
!readonly && !locked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1886
|
+
type: "button",
|
|
1887
|
+
className: selectMode ? `${VaultSection_module_css_default.dupMerge} ${VaultSection_module_css_default.selectActive}` : VaultSection_module_css_default.dupMerge,
|
|
1888
|
+
onClick: toggleSelectMode,
|
|
1889
|
+
disabled: busy,
|
|
1890
|
+
children: selectMode ? t("bulkDone") : t("bulkSelect")
|
|
1752
1891
|
})
|
|
1753
1892
|
]
|
|
1754
|
-
})
|
|
1893
|
+
}), selectMode && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1894
|
+
className: VaultSection_module_css_default.bulkBar,
|
|
1895
|
+
children: [
|
|
1896
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1897
|
+
className: VaultSection_module_css_default.bulkItem,
|
|
1898
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1899
|
+
type: "checkbox",
|
|
1900
|
+
checked: state.status === "ready" && state.entries.length > 0 && [...state.entries].every((e) => selectedIds.has(e.id)),
|
|
1901
|
+
onChange: (event) => {
|
|
1902
|
+
if (state.status !== "ready") return;
|
|
1903
|
+
const ids = new Set(selectedIds);
|
|
1904
|
+
for (const e of state.entries) if (event.target.checked) ids.add(e.id);
|
|
1905
|
+
else ids.delete(e.id);
|
|
1906
|
+
setSelectedIds(ids);
|
|
1907
|
+
}
|
|
1908
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("bulkSelectAll") })]
|
|
1909
|
+
}),
|
|
1910
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1911
|
+
className: VaultSection_module_css_default.bulkCount,
|
|
1912
|
+
children: [
|
|
1913
|
+
t("bulkSelected"),
|
|
1914
|
+
": ",
|
|
1915
|
+
selectedIds.size
|
|
1916
|
+
]
|
|
1917
|
+
}),
|
|
1918
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1919
|
+
type: "button",
|
|
1920
|
+
className: VaultSection_module_css_default.dangerButton,
|
|
1921
|
+
onClick: () => void removeSelected(),
|
|
1922
|
+
disabled: busy || selectedIds.size === 0,
|
|
1923
|
+
children: t("bulkDelete")
|
|
1924
|
+
})
|
|
1925
|
+
]
|
|
1926
|
+
})]
|
|
1755
1927
|
}),
|
|
1756
1928
|
message !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1757
1929
|
role: "alert",
|
|
@@ -1776,11 +1948,61 @@ window.__ModuleLoader__.load({
|
|
|
1776
1948
|
})
|
|
1777
1949
|
]
|
|
1778
1950
|
}),
|
|
1779
|
-
activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1951
|
+
activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1780
1952
|
className: VaultSection_module_css_default.tabPane,
|
|
1781
|
-
children: state.status === "ready" && state.entries.length
|
|
1782
|
-
className: VaultSection_module_css_default.
|
|
1953
|
+
children: [state.status === "ready" && state.entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1954
|
+
className: VaultSection_module_css_default.healthBar,
|
|
1783
1955
|
children: [
|
|
1956
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1957
|
+
className: VaultSection_module_css_default.badge,
|
|
1958
|
+
children: [
|
|
1959
|
+
t("entryCount"),
|
|
1960
|
+
": ",
|
|
1961
|
+
state.entries.length
|
|
1962
|
+
]
|
|
1963
|
+
}),
|
|
1964
|
+
(() => {
|
|
1965
|
+
const byKind = /* @__PURE__ */ new Map();
|
|
1966
|
+
for (const e of state.entries) {
|
|
1967
|
+
const k = e.kind ?? "login";
|
|
1968
|
+
byKind.set(k, (byKind.get(k) ?? 0) + 1);
|
|
1969
|
+
}
|
|
1970
|
+
return [...byKind.entries()].map(([k, n]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1971
|
+
className: VaultSection_module_css_default.badge,
|
|
1972
|
+
children: [
|
|
1973
|
+
t(KIND_KEYS[k] ?? "kindCustom"),
|
|
1974
|
+
": ",
|
|
1975
|
+
n
|
|
1976
|
+
]
|
|
1977
|
+
}, k));
|
|
1978
|
+
})(),
|
|
1979
|
+
vaultStats !== null && typeof vaultStats.withTotp === "number" && vaultStats.withTotp > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1980
|
+
className: VaultSection_module_css_default.badge,
|
|
1981
|
+
children: ["TOTP: ", String(vaultStats.withTotp)]
|
|
1982
|
+
})
|
|
1983
|
+
]
|
|
1984
|
+
}), state.status === "ready" && state.entries.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1985
|
+
className: VaultSection_module_css_default.emptyBox,
|
|
1986
|
+
children: query.trim().length > 0 || kindFilter !== "" || tagFilter !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1987
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1988
|
+
className: VaultSection_module_css_default.empty,
|
|
1989
|
+
children: t("noFiltered")
|
|
1990
|
+
}),
|
|
1991
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1992
|
+
className: VaultSection_module_css_default.emptyHint,
|
|
1993
|
+
children: t("noFilteredHint")
|
|
1994
|
+
}),
|
|
1995
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1996
|
+
type: "button",
|
|
1997
|
+
className: VaultSection_module_css_default.addButton,
|
|
1998
|
+
onClick: () => {
|
|
1999
|
+
setQuery("");
|
|
2000
|
+
setKindFilter("");
|
|
2001
|
+
setTagFilter("");
|
|
2002
|
+
},
|
|
2003
|
+
children: t("clearFilters")
|
|
2004
|
+
})
|
|
2005
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1784
2006
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1785
2007
|
className: VaultSection_module_css_default.empty,
|
|
1786
2008
|
children: t("empty")
|
|
@@ -1795,8 +2017,8 @@ window.__ModuleLoader__.load({
|
|
|
1795
2017
|
onClick: startCreate,
|
|
1796
2018
|
children: t("quickAdd")
|
|
1797
2019
|
})
|
|
1798
|
-
]
|
|
1799
|
-
})
|
|
2020
|
+
] })
|
|
2021
|
+
})]
|
|
1800
2022
|
}),
|
|
1801
2023
|
activeTab === "security" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1802
2024
|
className: VaultSection_module_css_default.tabPane,
|
|
@@ -1816,15 +2038,22 @@ window.__ModuleLoader__.load({
|
|
|
1816
2038
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1817
2039
|
className: VaultSection_module_css_default.reportTitle,
|
|
1818
2040
|
children: t("recentActivity")
|
|
1819
|
-
}), recentEvents.map((ev, i) =>
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
2041
|
+
}), recentEvents.slice(0, 12).map((ev, i) => {
|
|
2042
|
+
const action = String(ev.action ?? "");
|
|
2043
|
+
const icon = action === "add" ? "➕" : action === "delete" ? "🗑️" : action === "restore" ? "♻️" : action === "purge" ? "🔥" : action === "update" ? "✏️" : "•";
|
|
2044
|
+
const cls = action === "delete" || action === "purge" ? VaultSection_module_css_default.histDanger : action === "add" ? VaultSection_module_css_default.histAdd : action === "update" ? VaultSection_module_css_default.histUpdate : VaultSection_module_css_default.histNeutral;
|
|
2045
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
2046
|
+
className: `${VaultSection_module_css_default.reportLine} ${cls}`,
|
|
2047
|
+
children: [
|
|
2048
|
+
icon,
|
|
2049
|
+
" ",
|
|
2050
|
+
action,
|
|
2051
|
+
" · ",
|
|
2052
|
+
String(ev.title ?? ev.id ?? ""),
|
|
2053
|
+
relTime(ev.at) !== "" && ` · ${relTime(ev.at)}`
|
|
2054
|
+
]
|
|
2055
|
+
}, i);
|
|
2056
|
+
})]
|
|
1828
2057
|
}),
|
|
1829
2058
|
report !== null && (report.rotation.length > 0 || report.weak.length > 0 || report.reused.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1830
2059
|
className: VaultSection_module_css_default.reportBox,
|
|
@@ -2783,6 +3012,7 @@ window.__ModuleLoader__.load({
|
|
|
2783
3012
|
restore(entry.id).then(() => {
|
|
2784
3013
|
trash().then(setTrashEntries);
|
|
2785
3014
|
refresh();
|
|
3015
|
+
refreshHealth();
|
|
2786
3016
|
});
|
|
2787
3017
|
},
|
|
2788
3018
|
disabled: busy || readonly || locked,
|
|
@@ -2811,6 +3041,7 @@ window.__ModuleLoader__.load({
|
|
|
2811
3041
|
undeleteAll().then(() => {
|
|
2812
3042
|
trash().then(setTrashEntries);
|
|
2813
3043
|
refresh();
|
|
3044
|
+
refreshHealth();
|
|
2814
3045
|
setBusy(false);
|
|
2815
3046
|
}, () => setBusy(false));
|
|
2816
3047
|
},
|
|
@@ -2878,11 +3109,34 @@ window.__ModuleLoader__.load({
|
|
|
2878
3109
|
const frac = remaining !== void 0 ? remaining / 30 : 0;
|
|
2879
3110
|
const code = totpInfo?.code;
|
|
2880
3111
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
2881
|
-
className: `${VaultSection_module_css_default.row}${dueMap[entry.id] !== void 0 ? ` ${dueMap[entry.id].due === "expired" ? VaultSection_module_css_default.rowExpired : VaultSection_module_css_default.rowDue}` : ""}`,
|
|
3112
|
+
className: `${VaultSection_module_css_default.row}${dueMap[entry.id] !== void 0 ? ` ${dueMap[entry.id].due === "expired" ? VaultSection_module_css_default.rowExpired : VaultSection_module_css_default.rowDue}` : ""}${selectedIds.has(entry.id) ? ` ${VaultSection_module_css_default.rowSelected}` : ""}`,
|
|
2882
3113
|
children: [
|
|
3114
|
+
selectMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
3115
|
+
type: "checkbox",
|
|
3116
|
+
className: VaultSection_module_css_default.rowCheck,
|
|
3117
|
+
checked: selectedIds.has(entry.id),
|
|
3118
|
+
onChange: (event) => {
|
|
3119
|
+
setSelectedIds((prev) => {
|
|
3120
|
+
const next = new Set(prev);
|
|
3121
|
+
if (event.target.checked) next.add(entry.id);
|
|
3122
|
+
else next.delete(entry.id);
|
|
3123
|
+
return next;
|
|
3124
|
+
});
|
|
3125
|
+
},
|
|
3126
|
+
"aria-label": entry.title
|
|
3127
|
+
}),
|
|
2883
3128
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2884
3129
|
className: VaultSection_module_css_default.rowMain,
|
|
3130
|
+
role: "button",
|
|
3131
|
+
tabIndex: 0,
|
|
3132
|
+
"aria-expanded": expandedId === entry.id,
|
|
2885
3133
|
onClick: () => setExpandedId(expandedId === entry.id ? null : entry.id),
|
|
3134
|
+
onKeyDown: (event) => {
|
|
3135
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
3136
|
+
event.preventDefault();
|
|
3137
|
+
setExpandedId(expandedId === entry.id ? null : entry.id);
|
|
3138
|
+
}
|
|
3139
|
+
},
|
|
2886
3140
|
children: [
|
|
2887
3141
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2888
3142
|
className: VaultSection_module_css_default.title,
|
|
@@ -2905,6 +3159,7 @@ window.__ModuleLoader__.load({
|
|
|
2905
3159
|
const next = !entry.favorite;
|
|
2906
3160
|
setFavorite(entry.id, next).then(() => void refresh());
|
|
2907
3161
|
},
|
|
3162
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
2908
3163
|
children: "★"
|
|
2909
3164
|
}),
|
|
2910
3165
|
entry.title,
|
|
@@ -3043,7 +3298,8 @@ window.__ModuleLoader__.load({
|
|
|
3043
3298
|
type: "button",
|
|
3044
3299
|
onClick: () => void copyValue(entry.id, entry.username ?? entry.title),
|
|
3045
3300
|
disabled: busy || readonly || locked,
|
|
3046
|
-
|
|
3301
|
+
title: entry.username !== void 0 && entry.username !== "" ? t("copyUsernameHint") : t("copyTitleHint"),
|
|
3302
|
+
children: entry.username !== void 0 && entry.username !== "" ? t("copyUsername") : t("copy")
|
|
3047
3303
|
}),
|
|
3048
3304
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3049
3305
|
type: "button",
|
|
@@ -3525,7 +3781,11 @@ window.__ModuleLoader__.load({
|
|
|
3525
3781
|
pwStrength.score,
|
|
3526
3782
|
"/100 (",
|
|
3527
3783
|
t(VERDICT_KEYS_SHORT[pwStrength.verdict] ?? "verdictGood"),
|
|
3528
|
-
")"
|
|
3784
|
+
") · ",
|
|
3785
|
+
t("entropyLabel"),
|
|
3786
|
+
": ",
|
|
3787
|
+
pwStrength.bits,
|
|
3788
|
+
" bits"
|
|
3529
3789
|
]
|
|
3530
3790
|
})]
|
|
3531
3791
|
}),
|
|
@@ -3681,6 +3941,8 @@ window.__ModuleLoader__.load({
|
|
|
3681
3941
|
loading: "Loading…",
|
|
3682
3942
|
empty: "No credentials yet. Add one to get started.",
|
|
3683
3943
|
noFiltered: "No entries match the current filter.",
|
|
3944
|
+
noFilteredHint: "Try a different search or clear the filters.",
|
|
3945
|
+
clearFilters: "Clear filters",
|
|
3684
3946
|
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.",
|
|
3685
3947
|
emptyHintReadonly: "The vault is in readonly mode — credentials can be read but not added here. Switch accessMode to \"readwrite\" to enable writes.",
|
|
3686
3948
|
modeLabel: "Access mode",
|
|
@@ -3700,6 +3962,7 @@ window.__ModuleLoader__.load({
|
|
|
3700
3962
|
recentlyAdded: "Recently added",
|
|
3701
3963
|
reportRotation: "expired / due for rotation",
|
|
3702
3964
|
reportWeak: "weak passwords",
|
|
3965
|
+
healthSummaryHint: "Vault health: weak/reused/no-2FA/HTTP/rotation counts",
|
|
3703
3966
|
reportReused: "credentials reused across entries",
|
|
3704
3967
|
dupGroups: "duplicate groups",
|
|
3705
3968
|
dupTitle: "Duplicate entries",
|
|
@@ -3750,6 +4013,7 @@ window.__ModuleLoader__.load({
|
|
|
3750
4013
|
genOptSymbols: "Symbols",
|
|
3751
4014
|
genOptExcludeAmbiguous: "No ambiguous chars",
|
|
3752
4015
|
strengthLabel: "Strength",
|
|
4016
|
+
entropyLabel: "Entropy",
|
|
3753
4017
|
tplApply: "Apply template",
|
|
3754
4018
|
tplSave: "Save as template",
|
|
3755
4019
|
tplNamePrompt: "Template name:",
|
|
@@ -3931,8 +4195,20 @@ window.__ModuleLoader__.load({
|
|
|
3931
4195
|
savedUpdated: "Entry updated.",
|
|
3932
4196
|
edit: "Edit",
|
|
3933
4197
|
delete: "Delete",
|
|
3934
|
-
deleteConfirm: "
|
|
4198
|
+
deleteConfirm: "Move this entry to the trash? You can restore it later.",
|
|
4199
|
+
deleted: "Entry moved to trash.",
|
|
4200
|
+
deletedWithTitle: "{name} moved to trash.",
|
|
3935
4201
|
copy: "Copy",
|
|
4202
|
+
copyUsername: "Copy username",
|
|
4203
|
+
copyUsernameHint: "Copy the username",
|
|
4204
|
+
copyTitleHint: "Copy the title",
|
|
4205
|
+
bulkSelect: "Select",
|
|
4206
|
+
bulkDone: "Done",
|
|
4207
|
+
bulkSelectAll: "Select all",
|
|
4208
|
+
bulkSelected: "Selected",
|
|
4209
|
+
bulkDelete: "Delete selected",
|
|
4210
|
+
bulkDeleteConfirm: "Delete {n} selected entries? They move to the trash.",
|
|
4211
|
+
bulkDeleted: "Deleted {n} entries.",
|
|
3936
4212
|
copyPassword: "Copy password",
|
|
3937
4213
|
copyCode: "Copy code",
|
|
3938
4214
|
copied: "Copied",
|
|
@@ -4007,6 +4283,8 @@ window.__ModuleLoader__.load({
|
|
|
4007
4283
|
loading: "加载中…",
|
|
4008
4284
|
empty: "还没有凭据,添加一条开始使用。",
|
|
4009
4285
|
noFiltered: "当前过滤条件下没有匹配的条目。",
|
|
4286
|
+
noFilteredHint: "试试其他搜索词, 或清除过滤条件。",
|
|
4287
|
+
clearFilters: "清除过滤",
|
|
4010
4288
|
emptyHint: "提示:你可以在对话中把 API Key 或 token 交给助手保存——开启自动捕获后,它会在你同意时帮你存入本库。批量导入?让助手调用 vault_import_csv 并给出 CSV 路径即可。",
|
|
4011
4289
|
emptyHintReadonly: "当前为只读模式——只能读取凭据,不能在此添加。将 accessMode 改为 \"readwrite\" 即可启用写入。",
|
|
4012
4290
|
modeLabel: "访问模式",
|
|
@@ -4026,6 +4304,7 @@ window.__ModuleLoader__.load({
|
|
|
4026
4304
|
recentlyAdded: "最近添加",
|
|
4027
4305
|
reportRotation: "已过期 / 待轮换",
|
|
4028
4306
|
reportWeak: "弱密码",
|
|
4307
|
+
healthSummaryHint: "保险库健康: 弱密码/复用/缺2FA/HTTP站点/到期轮换计数",
|
|
4029
4308
|
reportReused: "跨条目复用的凭据",
|
|
4030
4309
|
dupGroups: "重复分组",
|
|
4031
4310
|
dupTitle: "重复条目",
|
|
@@ -4076,6 +4355,7 @@ window.__ModuleLoader__.load({
|
|
|
4076
4355
|
genOptSymbols: "符号",
|
|
4077
4356
|
genOptExcludeAmbiguous: "排除易混淆字符",
|
|
4078
4357
|
strengthLabel: "强度",
|
|
4358
|
+
entropyLabel: "熵值",
|
|
4079
4359
|
tplApply: "套用模板",
|
|
4080
4360
|
tplSave: "存为模板",
|
|
4081
4361
|
tplNamePrompt: "模板名称:",
|
|
@@ -4257,8 +4537,20 @@ window.__ModuleLoader__.load({
|
|
|
4257
4537
|
savedUpdated: "条目已更新。",
|
|
4258
4538
|
edit: "编辑",
|
|
4259
4539
|
delete: "删除",
|
|
4260
|
-
deleteConfirm: "
|
|
4540
|
+
deleteConfirm: "将该条目移入回收站?之后可恢复。",
|
|
4541
|
+
deleted: "条目已移入回收站。",
|
|
4542
|
+
deletedWithTitle: "「{name}」已移入回收站。",
|
|
4261
4543
|
copy: "复制",
|
|
4544
|
+
copyUsername: "复制用户名",
|
|
4545
|
+
copyUsernameHint: "复制用户名",
|
|
4546
|
+
copyTitleHint: "复制标题",
|
|
4547
|
+
bulkSelect: "批量选择",
|
|
4548
|
+
bulkDone: "完成",
|
|
4549
|
+
bulkSelectAll: "全选",
|
|
4550
|
+
bulkSelected: "已选择",
|
|
4551
|
+
bulkDelete: "删除所选",
|
|
4552
|
+
bulkDeleteConfirm: "删除所选 {n} 条条目?它们将移入回收站。",
|
|
4553
|
+
bulkDeleted: "已删除 {n} 条条目。",
|
|
4262
4554
|
copyPassword: "复制密码",
|
|
4263
4555
|
copyCode: "复制验证码",
|
|
4264
4556
|
copied: "已复制",
|