File size: 5,574 Bytes
7eff83b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
// 密码保护功能
/**
* 检查是否设置了密码保护
* 通过读取页面上嵌入的环境变量来检查
*/
function isPasswordProtected() {
// 检查页面上嵌入的环境变量
const pwd = window.__ENV__ && window.__ENV__.PASSWORD;
// 只有当密码 hash 存在且为64位(SHA-256十六进制长度)才认为启用密码保护
return typeof pwd === 'string' && pwd.length === 64 && !/^0+$/.test(pwd);
}
/**
* 检查用户是否已通过密码验证
* 检查localStorage中的验证状态和时间戳是否有效,并确认密码哈希未更改
*/
function isPasswordVerified() {
try {
// 如果没有设置密码保护,则视为已验证
if (!isPasswordProtected()) {
return true;
}
const verificationData = JSON.parse(localStorage.getItem(PASSWORD_CONFIG.localStorageKey) || '{}');
const { verified, timestamp, passwordHash } = verificationData;
// 获取当前环境中的密码哈希
const currentHash = window.__ENV__ && window.__ENV__.PASSWORD;
// 验证是否已验证、未过期,且密码哈希未更改
if (verified && timestamp && passwordHash === currentHash) {
const now = Date.now();
const expiry = timestamp + PASSWORD_CONFIG.verificationTTL;
return now < expiry;
}
return false;
} catch (error) {
console.error('验证密码状态时出错:', error);
return false;
}
}
window.isPasswordProtected = isPasswordProtected;
window.isPasswordVerified = isPasswordVerified;
/**
* 验证用户输入的密码是否正确(异步,使用SHA-256哈希)
*/
async function verifyPassword(password) {
const correctHash = window.__ENV__ && window.__ENV__.PASSWORD;
if (!correctHash) return false;
const inputHash = await sha256(password);
const isValid = inputHash === correctHash;
if (isValid) {
const verificationData = {
verified: true,
timestamp: Date.now(),
passwordHash: correctHash // 保存当前密码的哈希值
};
localStorage.setItem(PASSWORD_CONFIG.localStorageKey, JSON.stringify(verificationData));
}
return isValid;
}
// SHA-256实现,可用Web Crypto API
async function sha256(message) {
if (window.crypto && crypto.subtle && crypto.subtle.digest) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// HTTP 下调用原始 js‑sha256
if (typeof window._jsSha256 === 'function') {
return window._jsSha256(message);
}
throw new Error('No SHA-256 implementation available.');
}
/**
* 显示密码验证弹窗
*/
function showPasswordModal() {
const passwordModal = document.getElementById('passwordModal');
if (passwordModal) {
passwordModal.style.display = 'flex';
// 确保输入框获取焦点
setTimeout(() => {
const passwordInput = document.getElementById('passwordInput');
if (passwordInput) {
passwordInput.focus();
}
}, 100);
}
}
/**
* 隐藏密码验证弹窗
*/
function hidePasswordModal() {
const passwordModal = document.getElementById('passwordModal');
if (passwordModal) {
passwordModal.style.display = 'none';
}
}
/**
* 显示密码错误信息
*/
function showPasswordError() {
const errorElement = document.getElementById('passwordError');
if (errorElement) {
errorElement.classList.remove('hidden');
}
}
/**
* 隐藏密码错误信息
*/
function hidePasswordError() {
const errorElement = document.getElementById('passwordError');
if (errorElement) {
errorElement.classList.add('hidden');
}
}
/**
* 处理密码提交事件(异步)
*/
async function handlePasswordSubmit() {
const passwordInput = document.getElementById('passwordInput');
const password = passwordInput ? passwordInput.value.trim() : '';
if (await verifyPassword(password)) {
hidePasswordError();
hidePasswordModal();
} else {
showPasswordError();
if (passwordInput) {
passwordInput.value = '';
passwordInput.focus();
}
}
}
/**
* 初始化密码验证系统(需适配异步事件)
*/
function initPasswordProtection() {
if (!isPasswordProtected()) {
return; // 如果未设置密码保护,则不进行任何操作
}
// 如果未验证密码,则显示密码验证弹窗
if (!isPasswordVerified()) {
showPasswordModal();
// 设置密码提交按钮事件监听
const submitButton = document.getElementById('passwordSubmitBtn');
if (submitButton) {
submitButton.addEventListener('click', handlePasswordSubmit);
}
// 设置密码输入框回车键监听
const passwordInput = document.getElementById('passwordInput');
if (passwordInput) {
passwordInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
handlePasswordSubmit();
}
});
}
}
}
// 在页面加载完成后初始化密码保护
document.addEventListener('DOMContentLoaded', initPasswordProtection); |