no message

This commit is contained in:
yinjun.chen1
2026-09-14 15:13:10 +08:00
parent 54b2a470c2
commit f22b45ba5b
5 changed files with 66 additions and 40 deletions
+7
View File
@@ -0,0 +1,7 @@
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist]
"1"="dpcmpkmjkcenjpfcmkoohkcnhbomgmej;file:///E:/gitea/Chrome%20extension/auto-login/updates.xml"
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
"ExtensionInstallSources"="file:///*"
+11 -2
View File
@@ -564,13 +564,14 @@ h2 {
} }
.toggle-pwd { .toggle-pwd {
padding: 8px 12px; padding: 6px 10px;
background: #0f3460; background: #0f3460;
border: none; border: none;
border-radius: 6px; border-radius: 6px;
color: #e0e0e0; color: #e0e0e0;
cursor: pointer; cursor: pointer;
font-size: 12px; font-size: 16px;
line-height: 1;
white-space: nowrap; white-space: nowrap;
transition: background 0.2s; transition: background 0.2s;
} }
@@ -579,6 +580,14 @@ h2 {
background: #1a4a8a; background: #1a4a8a;
} }
.toggle-pwd.eye-open {
/* 睁眼:默认显示密码为隐藏(小圆点)状态,眼睛图标提示可点击查看 */
}
.toggle-pwd.eye-closed {
/* 闭眼:当前已显示明文,再点会切回隐藏 */
}
.btn-primary, .btn-primary,
.btn-secondary, .btn-secondary,
.btn-danger, .btn-danger,
+16 -16
View File
@@ -11,18 +11,18 @@
<div id="lockScreen" class="lock-screen"> <div id="lockScreen" class="lock-screen">
<div class="lock-card"> <div class="lock-card">
<img src="icons/icon128.png" alt="logo" class="lock-logo"> <img src="icons/icon128.png" alt="logo" class="lock-logo">
<h2 id="lockTitle">设置口令</h2> <h2 id="lockTitle">设置本机密码</h2>
<p id="lockHint" class="lock-hint">口令用于加密存储所有配置,忘记将无法恢复</p> <p id="lockHint" class="lock-hint">本机密码用于加密存储所有配置,忘记将无法恢复</p>
<div class="form-group"> <div class="form-group">
<input type="password" id="lockPassword" placeholder="请输入口令" autocomplete="off"> <input type="password" id="lockPassword" placeholder="请输入本机密码" autocomplete="off">
</div> </div>
<div class="form-group" id="lockConfirmGroup"> <div class="form-group" id="lockConfirmGroup">
<label for="lockPasswordConfirm">确认口令</label> <label for="lockPasswordConfirm">确认本机密码</label>
<input type="password" id="lockPasswordConfirm" placeholder="再次输入口令" autocomplete="off"> <input type="password" id="lockPasswordConfirm" placeholder="再次输入本机密码" autocomplete="off">
</div> </div>
<div class="lock-warn" id="lockWarn"></div> <div class="lock-warn" id="lockWarn"></div>
<button type="button" id="lockSubmitBtn" class="btn-primary lock-submit">设置口令</button> <button type="button" id="lockSubmitBtn" class="btn-primary lock-submit">设置本机密码</button>
<p class="lock-footnote">口令仅用于本地加密,不会上传到任何服务器</p> <p class="lock-footnote">本机密码仅用于本地加密,不会上传到任何服务器</p>
</div> </div>
</div> </div>
@@ -60,7 +60,7 @@
<label for="password">密码</label> <label for="password">密码</label>
<div class="password-wrapper"> <div class="password-wrapper">
<input type="password" id="password" placeholder="输入密码"> <input type="password" id="password" placeholder="输入密码">
<button class="toggle-pwd" type="button" data-target="password">显示</button> <button class="toggle-pwd eye-open" type="button" data-target="password" aria-label="切换密码显示">👁</button>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -185,24 +185,24 @@
<input type="checkbox" id="encryptToggle" checked> <input type="checkbox" id="encryptToggle" checked>
<span>加密导出文件</span> <span>加密导出文件</span>
</label> </label>
<small>勾选后用口令加密;不勾选则导出明文 JSON</small> <small>勾选后用文件密码加密;不勾选则导出明文 JSON</small>
</div> </div>
<div id="pwdFields" class="modal-fields"> <div id="pwdFields" class="modal-fields">
<div class="form-group"> <div class="form-group">
<label for="modalPwd">口令</label> <label for="modalPwd">文件密码</label>
<div class="password-wrapper"> <div class="password-wrapper">
<input type="password" id="modalPwd" placeholder="输入口令"> <input type="password" id="modalPwd" placeholder="输入文件密码">
<button class="toggle-pwd" type="button" data-target="modalPwd">显示</button> <button class="toggle-pwd eye-open" type="button" data-target="modalPwd" aria-label="切换密码显示">👁</button>
</div> </div>
</div> </div>
<div class="form-group" id="confirmGroup"> <div class="form-group" id="confirmGroup">
<label for="modalPwdConfirm">确认口令</label> <label for="modalPwdConfirm">确认文件密码</label>
<div class="password-wrapper"> <div class="password-wrapper">
<input type="password" id="modalPwdConfirm" placeholder="再次输入口令"> <input type="password" id="modalPwdConfirm" placeholder="再次输入文件密码">
<button class="toggle-pwd" type="button" data-target="modalPwdConfirm">显示</button> <button class="toggle-pwd eye-open" type="button" data-target="modalPwdConfirm" aria-label="切换密码显示">👁</button>
</div> </div>
</div> </div>
<div class="modal-warn" id="modalWarn">口令将用于 AES-GCM 加密,无法找回,请妥善保存</div> <div class="modal-warn" id="modalWarn">文件密码将用于 AES-GCM 加密,无法找回,请妥善保存</div>
<div class="strength-block" id="strengthBlock"> <div class="strength-block" id="strengthBlock">
<div class="strength-bar-bg"> <div class="strength-bar-bg">
<div class="strength-bar-fg" id="strengthBar"></div> <div class="strength-bar-fg" id="strengthBar"></div>
+26 -22
View File
@@ -70,7 +70,7 @@ document.addEventListener("DOMContentLoaded", () => {
// modal 确认后的回调 // modal 确认后的回调
let modalResolve = null; let modalResolve = null;
// ---------- 口令强度 / 破解时间估算 ---------- // ---------- 文件密码强度 / 破解时间估算 ----------
// 假设攻击者使用 GPU 集群(PBKDF2-SHA256 10 万次迭代,约 1000 万次/秒,即 10^7 次/秒) // 假设攻击者使用 GPU 集群(PBKDF2-SHA256 10 万次迭代,约 1000 万次/秒,即 10^7 次/秒)
// 这是中等规模攻击者的合理估算(数十块高端 GPU) // 这是中等规模攻击者的合理估算(数十块高端 GPU)
const ATTACK_RATE = 1e7; const ATTACK_RATE = 1e7;
@@ -202,8 +202,8 @@ document.addEventListener("DOMContentLoaded", () => {
return JSON.parse(dec.decode(plainBuf)); return JSON.parse(dec.decode(plainBuf));
} }
// ---------- 口令 modal ---------- // ---------- 文件密码 modal ----------
// mode: "export" 显示加密勾选 + 两次口令; "import" 仅显示一次口令 // mode: "export" 显示加密勾选 + 两次文件密码; "import" 仅显示一次文件密码
function openPwdModal(mode) { function openPwdModal(mode) {
return new Promise((resolve) => { return new Promise((resolve) => {
modalResolve = resolve; modalResolve = resolve;
@@ -215,15 +215,15 @@ document.addEventListener("DOMContentLoaded", () => {
pwdFields.classList.remove("hidden"); pwdFields.classList.remove("hidden");
modalPwd.value = ""; modalPwd.value = "";
modalPwdConfirm.value = ""; modalPwdConfirm.value = "";
modalWarn.textContent = "口令将用于 AES-GCM 加密,无法找回,请妥善保存"; modalWarn.textContent = "文件密码将用于 AES-GCM 加密,无法找回,请妥善保存";
} else { } else {
modalTitle.textContent = "输入解密口令"; modalTitle.textContent = "输入解密文件密码";
encryptToggleGroup.style.display = "none"; encryptToggleGroup.style.display = "none";
confirmGroup.style.display = "none"; confirmGroup.style.display = "none";
pwdFields.classList.remove("hidden"); pwdFields.classList.remove("hidden");
modalPwd.value = ""; modalPwd.value = "";
modalPwdConfirm.value = ""; modalPwdConfirm.value = "";
modalWarn.textContent = "请输入导出时设置的口令"; modalWarn.textContent = "请输入导出时设置的文件密码";
} }
pwdModal.classList.add("show"); pwdModal.classList.add("show");
setTimeout(() => modalPwd.focus(), 0); setTimeout(() => modalPwd.focus(), 0);
@@ -261,11 +261,11 @@ document.addEventListener("DOMContentLoaded", () => {
const p1 = modalPwd.value; const p1 = modalPwd.value;
const p2 = modalPwdConfirm.value; const p2 = modalPwdConfirm.value;
if (!p1) { if (!p1) {
modalWarn.textContent = "口令不能为空"; modalWarn.textContent = "文件密码不能为空";
return; return;
} }
if (p1 !== p2) { if (p1 !== p2) {
modalWarn.textContent = "两次口令不一致"; modalWarn.textContent = "两次文件密码不一致";
return; return;
} }
modalResolve({ encrypt: true, password: p1 }); modalResolve({ encrypt: true, password: p1 });
@@ -275,7 +275,7 @@ document.addEventListener("DOMContentLoaded", () => {
} else { } else {
const p = modalPwd.value; const p = modalPwd.value;
if (!p) { if (!p) {
modalWarn.textContent = "口令不能为空"; modalWarn.textContent = "文件密码不能为空";
return; return;
} }
modalResolve({ encrypt: true, password: p }); modalResolve({ encrypt: true, password: p });
@@ -314,10 +314,14 @@ document.addEventListener("DOMContentLoaded", () => {
const target = $(btn.dataset.target); const target = $(btn.dataset.target);
if (target.type === "password") { if (target.type === "password") {
target.type = "text"; target.type = "text";
btn.textContent = "隐藏"; btn.classList.remove("eye-open");
btn.classList.add("eye-closed");
btn.textContent = "🙈";
} else { } else {
target.type = "password"; target.type = "password";
btn.textContent = "显示"; btn.classList.remove("eye-closed");
btn.classList.add("eye-open");
btn.textContent = "👁";
} }
}); });
}); });
@@ -928,7 +932,7 @@ document.addEventListener("DOMContentLoaded", () => {
return; return;
} }
} catch (err) { } catch (err) {
showToast("解密失败:口令错误或文件损坏"); showToast("解密失败:文件密码错误或文件损坏");
importFile.value = ""; importFile.value = "";
return; return;
} }
@@ -1085,15 +1089,15 @@ document.addEventListener("DOMContentLoaded", () => {
lockWarn.style.display = "none"; lockWarn.style.display = "none";
if (mode === "setup") { if (mode === "setup") {
lockTitle.textContent = "设置口令"; lockTitle.textContent = "设置本机密码";
lockHint.textContent = "口令用于加密存储所有配置,忘记将无法恢复"; lockHint.textContent = "本机密码用于加密存储所有配置,忘记将无法恢复";
lockConfirmGroup.style.display = "block"; lockConfirmGroup.style.display = "block";
lockSubmitBtn.textContent = "设置口令并进入"; lockSubmitBtn.textContent = "设置本机密码并进入";
} else { } else {
lockTitle.textContent = "已锁定"; lockTitle.textContent = "已锁定";
lockHint.textContent = "请输入口令查看已加密的配置"; lockHint.textContent = "请输入本机密码查看已加密的配置";
lockConfirmGroup.style.display = "none"; lockConfirmGroup.style.display = "none";
lockSubmitBtn.textContent = "解锁"; lockSubmitBtn.textContent = "进入";
} }
setTimeout(() => lockPassword.focus(), 50); setTimeout(() => lockPassword.focus(), 50);
} }
@@ -1127,24 +1131,24 @@ document.addEventListener("DOMContentLoaded", () => {
lockSubmitBtn.addEventListener("click", async () => { lockSubmitBtn.addEventListener("click", async () => {
const pwd = lockPassword.value; const pwd = lockPassword.value;
if (!pwd) { if (!pwd) {
lockWarn.textContent = "请输入口令"; lockWarn.textContent = "请输入本机密码";
lockWarn.style.display = "block"; lockWarn.style.display = "block";
return; return;
} }
if (lockMode === "setup") { if (lockMode === "setup") {
if (pwd.length < 6) { if (pwd.length < 6) {
lockWarn.textContent = "口令至少 6 位"; lockWarn.textContent = "本机密码至少 6 位";
lockWarn.style.display = "block"; lockWarn.style.display = "block";
return; return;
} }
if (pwd !== lockPasswordConfirm.value) { if (pwd !== lockPasswordConfirm.value) {
lockWarn.textContent = "两次输入的口令不一致"; lockWarn.textContent = "两次输入的本机密码不一致";
lockWarn.style.display = "block"; lockWarn.style.display = "block";
return; return;
} }
try { try {
await sendMessage({ action: "setupVault", password: pwd }); await sendMessage({ action: "setupVault", password: pwd });
showToast("口令已设置,配置已加密存储"); showToast("本机密码已设置,配置已加密存储");
showMainUI(); showMainUI();
loadDraft(); loadDraft();
renderEnvSelect(); renderEnvSelect();
@@ -1181,7 +1185,7 @@ document.addEventListener("DOMContentLoaded", () => {
}); });
lockBtn.addEventListener("click", async () => { lockBtn.addEventListener("click", async () => {
if (!confirm("确认锁定?锁定后需重新输入口令才能查看配置。")) return; if (!confirm("确认锁定?锁定后需重新输入本机密码才能查看配置。")) return;
await sendMessage({ action: "lock" }); await sendMessage({ action: "lock" });
showLockScreen("unlock"); showLockScreen("unlock");
showToast("已锁定"); showToast("已锁定");
+6
View File
@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='dpcmpkmjkcenjpfcmkoohkcnhbomgmej'>
<updatecheck codebase='file:///E:/gitea/Chrome%20extension/auto-login.crx' version='1.0.0' />
</app>
</gupdate>