Some checks failed
CI / Lint + Build (push) Has been cancelled
审计修复: - CSP: unsafe-inline移除, nonce替代; unsafe-eval保留供Vditor使用 - HSTS: 始终启用(不再依赖release模式) - Controller Exp: common.GetGinExp包装, 不再直接读context - UID解析: common.ParseUIDParam统一, follow/admin controller改用 重构: - router/api.go(198行)拆为7个域文件: auth/settings/posts/comments/reactions/social/studio - 管理后台站点设置: 单页拆为4个子页(brand/security/registration/content)+子菜单 - 前台用户设置页: 1201行拆为6个独立模板+6个独立JS文件 新增: - DB健康检测中间件(middleware/db_health.go): 5s ping+降级页面 - 时区配置: config.yaml server.timezone→time.Local初始化 - .gitea/workflows/ci.yml: strict模式CI流水线
112 lines
4.7 KiB
JavaScript
112 lines
4.7 KiB
JavaScript
(function(){'use strict';
|
|
<script nonce="{{.CSPNonce}}">
|
|
(function () {
|
|
'use strict';
|
|
|
|
var toastEl = document.getElementById('settingsToast');
|
|
var toastTimer = null;
|
|
|
|
function showSettingsToast(msg, isError) {
|
|
if (!toastEl) return;
|
|
clearTimeout(toastTimer);
|
|
toastEl.textContent = msg;
|
|
toastEl.className = 'settings-toast' + (isError ? ' error' : '');
|
|
void toastEl.offsetWidth;
|
|
toastEl.classList.add('show');
|
|
toastTimer = setTimeout(function () {
|
|
toastEl.classList.remove('show');
|
|
}, 5000);
|
|
}
|
|
// 修改密码
|
|
// ---- 修改密码 ----
|
|
var currentPwd = document.getElementById('currentPassword');
|
|
var newPwd = document.getElementById('newPassword');
|
|
var changePwdBtn = document.getElementById('changePwdBtn');
|
|
if (currentPwd && newPwd && changePwdBtn) {
|
|
changePwdBtn.addEventListener('click', function () {
|
|
if (!currentPwd.value) {
|
|
showSettingsToast('请输入当前密码', true);
|
|
return;
|
|
}
|
|
if (!newPwd.value || !/[a-z]/.test(newPwd.value) || !/[A-Z]/.test(newPwd.value) || !/\d/.test(newPwd.value) || newPwd.value.length < 8) {
|
|
showSettingsToast('新密码至少 8 位,包含大小写字母和数字', true);
|
|
return;
|
|
}
|
|
changePwdBtn.disabled = true;
|
|
changePwdBtn.textContent = '修改中...';
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('PUT', '/api/settings/password', true);
|
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState !== 4) return;
|
|
changePwdBtn.disabled = false;
|
|
changePwdBtn.textContent = '修改密码';
|
|
try {
|
|
var res = JSON.parse(xhr.responseText);
|
|
if (res.success) {
|
|
showSettingsToast('密码已修改,请重新登录');
|
|
currentPwd.value = '';
|
|
newPwd.value = '';
|
|
setTimeout(function () {
|
|
window.location.href = '/';
|
|
}, 2000);
|
|
} else {
|
|
showSettingsToast(res.message || '修改失败', true);
|
|
}
|
|
} catch (e) {
|
|
showSettingsToast('修改失败', true);
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify({
|
|
current_password: currentPwd.value,
|
|
new_password: newPwd.value
|
|
}));
|
|
});
|
|
}
|
|
// 注销账号
|
|
// ---- 注销账号 ----
|
|
var deletePwd = document.getElementById('deletePassword');
|
|
var deleteReason = document.getElementById('deleteReason');
|
|
var deleteAccountBtn = document.getElementById('deleteAccountBtn');
|
|
if (deletePwd && deleteAccountBtn) {
|
|
deleteAccountBtn.addEventListener('click', function () {
|
|
if (!deletePwd.value) {
|
|
showSettingsToast('请输入密码确认', true);
|
|
return;
|
|
}
|
|
showConfirm('注销账号', '确定要注销账号吗?\n\n注销后 7 天内重新登录可撤销注销,期满后将永久删除。').then(function(ok) {
|
|
if (!ok) return;
|
|
deleteAccountBtn.disabled = true;
|
|
deleteAccountBtn.textContent = '注销中...';
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', '/api/settings/delete-account', true);
|
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState !== 4) return;
|
|
deleteAccountBtn.disabled = false;
|
|
deleteAccountBtn.textContent = '确认注销';
|
|
try {
|
|
var res = JSON.parse(xhr.responseText);
|
|
if (res.success) {
|
|
showSettingsToast(res.message || '账号已注销');
|
|
setTimeout(function () {
|
|
window.location.href = '/';
|
|
}, 2000);
|
|
} else {
|
|
showSettingsToast(res.message || '操作失败', true);
|
|
}
|
|
} catch (e) {
|
|
showSettingsToast('操作失败', true);
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify({
|
|
password: deletePwd.value,
|
|
reason: deleteReason ? deleteReason.value : ''
|
|
}));
|
|
});
|
|
});
|
|
}
|
|
})();
|