feat(加密解密): 优化文档加密交互与文案
build.yaml / build (push) Successful in 41s

This commit is contained in:
xiaoqidun committed 2026-09-30 01:45:13 +08:00
1 parent b0b194895a
commit 4de22f9be7
2 files changed
+22 -12

No files matched your search

+4 -4
View File
@@ -491,10 +491,10 @@
</dialog> </dialog>
<dialog id="encryptionPanel" class="form-dialog" aria-labelledby="encryptionTitle"> <dialog id="encryptionPanel" class="form-dialog" aria-labelledby="encryptionTitle">
<form id="encryptionForm"> <form id="encryptionForm">
<h2 id="encryptionTitle" class="form-title">加密设置</h2> <h2 id="encryptionTitle" class="form-title">加密文档</h2>
<div class="form-row"><label for="encryptionType">方式</label><select id="encryptionType" autofocus><option value="none">明文</option><option value="password">口令</option><option value="certificate">证书</option><option id="encryptionKeep" value="keep" hidden>保留</option></select></div> <div class="form-row"><label for="encryptionType">方式</label><select id="encryptionType" autofocus><option value="none">明文</option><option value="password">口令</option><option value="certificate">证书</option><option id="encryptionKeep" value="keep" hidden>保留</option></select></div>
<div id="encryptionCurrentRow" class="form-row" hidden><span>状态</span><div class="encryption-current"><span id="encryptionCurrent"></span><button id="encryptionChange" class="button" type="button">修改</button></div></div> <div id="encryptionCurrentRow" class="form-row" hidden><span>状态</span><div class="encryption-current"><span id="encryptionCurrent"></span><button id="encryptionChange" class="button" type="button">修改</button></div></div>
<div id="encryptionUserRow" class="form-row"><label for="encryptionUser">用户</label><input id="encryptionUser" type="text" autocomplete="off" spellcheck="false"></div> <div id="encryptionUserRow" class="form-row"><label for="encryptionUser">用户</label><input id="encryptionUser" type="text" placeholder="可选" autocomplete="off" spellcheck="false"></div>
<div id="encryptionPasswordRow" class="form-row"><label for="encryptionPassword">口令</label><input id="encryptionPassword" type="password" autocomplete="new-password"></div> <div id="encryptionPasswordRow" class="form-row"><label for="encryptionPassword">口令</label><input id="encryptionPassword" type="password" autocomplete="new-password"></div>
<div id="encryptionConfirmRow" class="form-row"><label for="encryptionConfirm">确认</label><input id="encryptionConfirm" type="password" autocomplete="new-password"></div> <div id="encryptionConfirmRow" class="form-row"><label for="encryptionConfirm">确认</label><input id="encryptionConfirm" type="password" autocomplete="new-password"></div>
<div id="encryptionCertificatesRow" class="form-row" hidden><label for="encryptionCertificates">证书</label><input id="encryptionCertificates" type="file" accept=".pem,.cer,.crt,.der" multiple></div> <div id="encryptionCertificatesRow" class="form-row" hidden><label for="encryptionCertificates">证书</label><input id="encryptionCertificates" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
@@ -636,8 +636,8 @@
<div id="conversionWarnings" class="attachment-detail"></div> <div id="conversionWarnings" class="attachment-detail"></div>
</details> </details>
<section id="securityPanel" class="security-panel" aria-labelledby="securityPanelTitle" hidden> <section id="securityPanel" class="security-panel" aria-labelledby="securityPanelTitle" hidden>
<div class="panel-row"><div id="securityPanelTitle" class="panel-title compact">安全</div><div class="panel-actions"><button id="encryptSaveButton" class="small-button" type="button" title="加密设置" aria-label="加密设置" aria-haspopup="dialog" aria-controls="encryptionPanel" disabled>加密</button><button id="signButton" class="small-button" type="button" aria-haspopup="dialog" aria-controls="signPanel" disabled>签章</button><button id="verifyButton" class="small-button" type="button" aria-haspopup="dialog" aria-controls="verifyPanel" disabled>验签</button></div></div> <div class="panel-row"><div id="securityPanelTitle" class="panel-title compact">安全</div><div class="panel-actions"><button id="encryptSaveButton" class="small-button" type="button" title="加密文档" aria-label="加密文档" aria-haspopup="dialog" aria-controls="encryptionPanel" disabled>加密</button><button id="signButton" class="small-button" type="button" aria-haspopup="dialog" aria-controls="signPanel" disabled>签章</button><button id="verifyButton" class="small-button" type="button" aria-haspopup="dialog" aria-controls="verifyPanel" disabled>验签</button></div></div>
<dl class="meta-list"><div><dt>加密</dt><dd id="securityEncryption">未加密</dd></div><div id="securityMethodRow" hidden><dt>算法</dt><dd id="securityMethod"></dd></div></dl> <dl class="meta-list"><div><dt>加密</dt><dd id="securityEncryption">未加密</dd></div><div id="securitySchemeRow" hidden><dt>方式</dt><dd id="securityScheme"></dd></div><div id="securityMethodRow" hidden><dt>算法</dt><dd id="securityMethod"></dd></div></dl>
</section> </section>
<section id="attachmentPanel" class="attachment-panel" aria-labelledby="attachmentPanelTitle" hidden> <section id="attachmentPanel" class="attachment-panel" aria-labelledby="attachmentPanelTitle" hidden>
<div id="attachmentPanelTitle" class="panel-title">附件</div> <div id="attachmentPanelTitle" class="panel-title">附件</div>
+18 -8
View File
@@ -162,6 +162,8 @@ const el = {
securityEncryption: document.querySelector("#securityEncryption"), securityEncryption: document.querySelector("#securityEncryption"),
securityMethod: document.querySelector("#securityMethod"), securityMethod: document.querySelector("#securityMethod"),
securityMethodRow: document.querySelector("#securityMethodRow"), securityMethodRow: document.querySelector("#securityMethodRow"),
securityScheme: document.querySelector("#securityScheme"),
securitySchemeRow: document.querySelector("#securitySchemeRow"),
encryptSaveButton: document.querySelector("#encryptSaveButton"), encryptSaveButton: document.querySelector("#encryptSaveButton"),
credentialsPanel: document.querySelector("#credentialsPanel"), credentialsPanel: document.querySelector("#credentialsPanel"),
credentialsType: document.querySelector("#credentialsType"), credentialsType: document.querySelector("#credentialsType"),
@@ -4455,17 +4457,20 @@ function updateEncryptionType() {
const password = mode === "password" && !existing; const password = mode === "password" && !existing;
const certificates = mode === "certificate" && !existing; const certificates = mode === "certificate" && !existing;
el.encryptionCurrentRow.hidden = !existing; el.encryptionCurrentRow.hidden = !existing;
el.encryptionCurrent.textContent = mode === "password" ? "已设置" : (state.doc?.encryption?.users || []).join("、") || "已加密"; el.encryptionCurrent.textContent = mode === "password" ? state.encryptionDirty ? "待保存" : "已加密" : (state.doc?.encryption?.users || []).join("、") || "已加密";
el.encryptionChange.hidden = mode === "keep"; el.encryptionChange.hidden = mode === "keep";
el.encryptionUserRow.hidden = el.encryptionPasswordRow.hidden = el.encryptionConfirmRow.hidden = !password; el.encryptionUserRow.hidden = el.encryptionPasswordRow.hidden = el.encryptionConfirmRow.hidden = !password;
el.encryptionCertificatesRow.hidden = !certificates; el.encryptionCertificatesRow.hidden = !certificates;
el.encryptionPassword.required = el.encryptionConfirm.required = password; el.encryptionPassword.required = el.encryptionConfirm.required = password;
el.encryptionCertificates.required = certificates; el.encryptionCertificates.required = certificates;
el.encryptionUser.value = mode === "password" && encryptionMode() === mode ? state.doc.encryption.users?.[0] || "" : ""; const user = mode === "password" && encryptionMode() === mode ? state.doc.encryption.users?.[0] || "" : "";
el.encryptionUser.value = user === "User" ? "" : user;
el.encryptionPassword.value = el.encryptionConfirm.value = ""; el.encryptionPassword.value = el.encryptionConfirm.value = "";
el.encryptionCertificates.value = ""; el.encryptionCertificates.value = "";
el.encryptionStatus.textContent = mode === "keep" && state.doc?.encryption?.policyRequired ? "请重新设置加密方式" : ""; el.encryptionStatus.textContent = mode === "keep" && state.doc?.encryption?.policyRequired ? "请重新选择加密方式" : "";
el.encryptionSubmit.disabled = mode === "keep" && Boolean(state.doc?.encryption?.policyRequired); el.encryptionSubmit.disabled = mode === "keep" && Boolean(state.doc?.encryption?.policyRequired);
el.encryptionSubmit.textContent = mode === encryptionMode() && !state.encryptionChanged ? "确定"
: mode === "none" ? "解密" : mode !== encryptionMode() ? "加密" : mode === "password" ? "改密" : "修改";
} }
async function applyEncryption(event) { async function applyEncryption(event) {
@@ -4491,9 +4496,11 @@ async function applyEncryption(event) {
return; return;
} }
const openSeq = state.openSeq; const openSeq = state.openSeq;
const status = mode === "none" ? "保存后将解密" : mode !== encryptionMode() ? "保存后将加密"
: mode === "password" ? "保存后将改密" : "保存后将生效";
const options = mode === "none" ? null : { password: new TextEncoder().encode(el.encryptionPassword.value), userName: el.encryptionUser.value.trim() }; const options = mode === "none" ? null : { password: new TextEncoder().encode(el.encryptionPassword.value), userName: el.encryptionUser.value.trim() };
el.encryptionForm.inert = true; el.encryptionForm.inert = true;
setBusy(true, "正在设置加密"); setBusy(true, "正在处理文档");
try { try {
if (mode === "certificate") options.recipients = await encryptionRecipients(Array.from(el.encryptionCertificates.files)); if (mode === "certificate") options.recipients = await encryptionRecipients(Array.from(el.encryptionCertificates.files));
if (openSeq !== state.openSeq) return; if (openSeq !== state.openSeq) return;
@@ -4506,7 +4513,7 @@ async function applyEncryption(event) {
state.ofdBytes = null; state.ofdBytes = null;
el.encryptionPanel.close(); el.encryptionPanel.close();
renderSecurity(); renderSecurity();
setStatus("加密设置已更新"); setStatus(status);
} catch (err) { } catch (err) {
if (openSeq === state.openSeq) el.encryptionStatus.textContent = err.message; if (openSeq === state.openSeq) el.encryptionStatus.textContent = err.message;
} finally { } finally {
@@ -4542,9 +4549,12 @@ function clearEncryptionForm() {
function renderSecurity() { function renderSecurity() {
const encryption = state.doc?.encryption; const encryption = state.doc?.encryption;
el.securityPanel.hidden = !state.doc; el.securityPanel.hidden = !state.doc;
el.securityEncryption.textContent = encryption?.encrypted ? "已加密" : "未加密"; el.securityEncryption.textContent = state.encryptionDirty ? "待保存" : encryption?.encrypted ? "已加密" : "未加密";
el.securityMethod.textContent = encryption?.method || ""; const scheme = { "1.1.1": "口令", "1.1.2": "证书" }[encryption?.method];
el.securityMethodRow.hidden = !encryption?.method; el.securityScheme.textContent = encryption?.layers > 1 ? "多重" : scheme || encryption?.method || "";
el.securitySchemeRow.hidden = !encryption?.encrypted;
el.securityMethod.textContent = scheme ? "SM4-CBC" : "";
el.securityMethodRow.hidden = !encryption?.encrypted || !scheme;
el.encryptSaveButton.disabled = !state.doc || !state.ready || state.exporting || document.body.hasAttribute("aria-busy"); el.encryptSaveButton.disabled = !state.doc || !state.ready || state.exporting || document.body.hasAttribute("aria-busy");
el.verifyButton.disabled = el.encryptSaveButton.disabled; el.verifyButton.disabled = el.encryptSaveButton.disabled;
el.signButton.disabled = el.encryptSaveButton.disabled; el.signButton.disabled = el.encryptSaveButton.disabled;