(function () {
|
function handleForbidden(res) {
|
if (res && Number(res.code) === 403) {
|
top.location.href = baseUrl + "/";
|
return true;
|
}
|
return false;
|
}
|
|
new Vue({
|
el: "#app",
|
data: function () {
|
return {
|
loading: false,
|
saving: false,
|
passwordDialogVisible: false,
|
passwordSaving: false,
|
mfaDialogVisible: false,
|
mfaDialogMode: "enable",
|
mfaSetupLoading: false,
|
mfaSubmitting: false,
|
passkeyDialogVisible: false,
|
passkeyDialogMode: "register",
|
passkeySubmitting: false,
|
form: {
|
id: "",
|
roleName: "",
|
username: "",
|
mobile: "",
|
createTime$: "",
|
mfaAllow: 0,
|
mfaAllow$: "否",
|
mfaEnabled: 0,
|
mfaEnabled$: "否",
|
mfaBoundTime$: "",
|
mfaMaskedSecret: "",
|
passkeyBound: false,
|
passkeyName: "",
|
passkeyBoundTime$: "",
|
passkeyLastUsedTime$: "",
|
passkeyTransports: ""
|
},
|
passwordForm: {
|
oldPassword: "",
|
password: "",
|
rePassword: ""
|
},
|
mfaForm: {
|
currentPassword: "",
|
code: ""
|
},
|
mfaSetup: {
|
secret: "",
|
qrCode: "",
|
otpAuth: ""
|
},
|
passkeyForm: {
|
name: "",
|
currentPassword: ""
|
},
|
rules: {
|
username: [
|
{ required: true, message: "请输入名称", trigger: "blur" }
|
],
|
mobile: [
|
{ required: true, message: "请输入账号", trigger: "blur" }
|
]
|
},
|
passwordRules: {
|
oldPassword: [
|
{ required: true, message: "请输入当前密码", trigger: "blur" }
|
],
|
password: [
|
{ required: true, message: "请输入新密码", trigger: "blur" },
|
{
|
validator: function (rule, value, callback) {
|
if (!value) {
|
callback(new Error("请输入新密码"));
|
return;
|
}
|
if (String(value).length < 4) {
|
callback(new Error("不能少于4个字符"));
|
return;
|
}
|
if (value === this.passwordForm.oldPassword) {
|
callback(new Error("与旧密码不能相同"));
|
return;
|
}
|
callback();
|
}.bind(this),
|
trigger: "blur"
|
}
|
],
|
rePassword: [
|
{ required: true, message: "请再次输入新密码", trigger: "blur" },
|
{
|
validator: function (rule, value, callback) {
|
if (value !== this.passwordForm.password) {
|
callback(new Error("密码不一致"));
|
return;
|
}
|
callback();
|
}.bind(this),
|
trigger: "blur"
|
}
|
]
|
},
|
mfaRules: {
|
currentPassword: [
|
{ required: true, message: "请输入当前密码", trigger: "blur" }
|
],
|
code: [
|
{ required: true, message: "请输入6位验证码", trigger: "blur" },
|
{
|
validator: function (rule, value, callback) {
|
if (!/^\d{6}$/.test(String(value || "").trim())) {
|
callback(new Error("请输入6位数字验证码"));
|
return;
|
}
|
callback();
|
},
|
trigger: "blur"
|
}
|
]
|
},
|
passkeyRules: {
|
currentPassword: [
|
{ required: true, message: "请输入当前密码", trigger: "blur" }
|
]
|
}
|
};
|
},
|
created: function () {
|
this.loadDetail();
|
},
|
methods: {
|
loadDetail: function () {
|
var vm = this;
|
vm.loading = true;
|
$.ajax({
|
url: baseUrl + "/user/detail/auth",
|
headers: { token: localStorage.getItem("token") },
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "资料加载失败");
|
return;
|
}
|
var user = res.data || {};
|
vm.form = Object.assign({}, vm.form, user);
|
},
|
error: function () {
|
vm.$message.error("资料加载失败");
|
},
|
complete: function () {
|
vm.loading = false;
|
}
|
});
|
},
|
openPasswordDialog: function () {
|
this.passwordForm = {
|
oldPassword: "",
|
password: "",
|
rePassword: ""
|
};
|
this.passwordDialogVisible = true;
|
if (this.$refs.passwordForm) {
|
this.$nextTick(function () {
|
this.$refs.passwordForm.clearValidate();
|
});
|
}
|
},
|
closePasswordDialog: function () {
|
this.passwordDialogVisible = false;
|
},
|
handlePasswordSave: function () {
|
var vm = this;
|
vm.$refs.passwordForm.validate(function (valid) {
|
if (!valid) {
|
return false;
|
}
|
vm.submitPasswordSave();
|
return true;
|
});
|
},
|
submitPasswordSave: function () {
|
var vm = this;
|
vm.passwordSaving = true;
|
$.ajax({
|
url: baseUrl + "/user/password/update/auth",
|
headers: { token: localStorage.getItem("token") },
|
data: {
|
oldPassword: hex_md5(vm.passwordForm.oldPassword),
|
password: hex_md5(vm.passwordForm.password)
|
},
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "密码修改失败");
|
return;
|
}
|
vm.passwordDialogVisible = false;
|
vm.$alert("密码修改成功,请重新登录", "提示", {
|
confirmButtonText: "确定",
|
callback: function () {
|
localStorage.removeItem("token");
|
top.location.href = baseUrl + "/";
|
}
|
});
|
},
|
error: function () {
|
vm.$message.error("密码修改失败");
|
},
|
complete: function () {
|
vm.passwordSaving = false;
|
}
|
});
|
},
|
openMfaEnableDialog: function () {
|
if (Number(this.form.mfaAllow) !== 1) {
|
this.$message.warning("当前账号未开通MFA使用权限");
|
return;
|
}
|
this.mfaDialogMode = "enable";
|
this.resetMfaDialogState();
|
this.mfaDialogVisible = true;
|
this.loadMfaSetup();
|
},
|
openMfaDisableDialog: function () {
|
this.mfaDialogMode = "disable";
|
this.resetMfaDialogState();
|
this.mfaDialogVisible = true;
|
},
|
closeMfaDialog: function () {
|
this.mfaDialogVisible = false;
|
this.resetMfaDialogState();
|
},
|
resetMfaDialogState: function () {
|
this.mfaSubmitting = false;
|
this.mfaSetupLoading = false;
|
this.mfaForm = {
|
currentPassword: "",
|
code: ""
|
};
|
this.mfaSetup = {
|
secret: "",
|
qrCode: "",
|
otpAuth: ""
|
};
|
if (this.$refs.mfaForm) {
|
this.$refs.mfaForm.clearValidate();
|
}
|
},
|
loadMfaSetup: function () {
|
var vm = this;
|
vm.mfaSetupLoading = true;
|
$.ajax({
|
url: baseUrl + "/user/mfa/setup/auth",
|
headers: { token: localStorage.getItem("token") },
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "MFA配置加载失败");
|
return;
|
}
|
vm.mfaSetup = Object.assign({}, vm.mfaSetup, res.data || {});
|
},
|
error: function () {
|
vm.$message.error("MFA配置加载失败");
|
},
|
complete: function () {
|
vm.mfaSetupLoading = false;
|
}
|
});
|
},
|
handleMfaSubmit: function () {
|
var vm = this;
|
if (!vm.$refs.mfaForm) {
|
return;
|
}
|
vm.$refs.mfaForm.validate(function (valid) {
|
if (!valid) {
|
return false;
|
}
|
if (vm.mfaDialogMode === "enable" && !vm.mfaSetup.secret) {
|
vm.$message.error("MFA密钥尚未生成,请稍后重试");
|
return false;
|
}
|
vm.submitMfaAction();
|
return true;
|
});
|
},
|
submitMfaAction: function () {
|
var vm = this;
|
vm.mfaSubmitting = true;
|
$.ajax({
|
url: baseUrl + (vm.mfaDialogMode === "enable" ? "/user/mfa/enable/auth" : "/user/mfa/disable/auth"),
|
headers: { token: localStorage.getItem("token") },
|
data: {
|
currentPassword: hex_md5(vm.mfaForm.currentPassword),
|
code: vm.mfaForm.code,
|
secret: vm.mfaSetup.secret
|
},
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "MFA操作失败");
|
return;
|
}
|
vm.$message.success(vm.mfaDialogMode === "enable" ? "MFA已启用" : "MFA已停用");
|
vm.closeMfaDialog();
|
vm.loadDetail();
|
},
|
error: function () {
|
vm.$message.error("MFA操作失败");
|
},
|
complete: function () {
|
vm.mfaSubmitting = false;
|
}
|
});
|
},
|
openPasskeyRegisterDialog: function () {
|
if (!window.WCS_WEBAUTHN || !window.WCS_WEBAUTHN.isSupported()) {
|
this.$message.error(this.resolvePasskeyErrorMessage({ message: window.isSecureContext ? "not-supported" : "secure-context" }, "当前环境不支持通行密钥"));
|
return;
|
}
|
this.passkeyDialogMode = "register";
|
this.resetPasskeyDialogState();
|
this.passkeyDialogVisible = true;
|
},
|
openPasskeyRemoveDialog: function () {
|
this.passkeyDialogMode = "remove";
|
this.resetPasskeyDialogState();
|
this.passkeyDialogVisible = true;
|
},
|
closePasskeyDialog: function () {
|
this.passkeyDialogVisible = false;
|
this.resetPasskeyDialogState();
|
},
|
resetPasskeyDialogState: function () {
|
this.passkeySubmitting = false;
|
this.passkeyForm = {
|
name: "",
|
currentPassword: ""
|
};
|
if (this.$refs.passkeyForm) {
|
this.$refs.passkeyForm.clearValidate();
|
}
|
},
|
handlePasskeySubmit: function () {
|
var vm = this;
|
if (!vm.$refs.passkeyForm) {
|
return;
|
}
|
vm.$refs.passkeyForm.validate(function (valid) {
|
if (!valid) {
|
return false;
|
}
|
if (vm.passkeyDialogMode === "register") {
|
vm.submitPasskeyRegister();
|
} else {
|
vm.submitPasskeyRemove();
|
}
|
return true;
|
});
|
},
|
submitPasskeyRegister: function () {
|
var vm = this;
|
if (!window.WCS_WEBAUTHN || !window.WCS_WEBAUTHN.isSupported()) {
|
vm.$message.error(vm.resolvePasskeyErrorMessage({ message: window.isSecureContext ? "not-supported" : "secure-context" }, "当前环境不支持通行密钥"));
|
return;
|
}
|
vm.passkeySubmitting = true;
|
$.ajax({
|
url: baseUrl + "/user/passkey/register/options/auth",
|
headers: { token: localStorage.getItem("token") },
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.passkeySubmitting = false;
|
vm.$message.error(res.msg || "通行密钥配置加载失败");
|
return;
|
}
|
vm.executePasskeyRegister(res.data || {});
|
},
|
error: function () {
|
vm.passkeySubmitting = false;
|
vm.$message.error("通行密钥配置加载失败");
|
}
|
});
|
},
|
executePasskeyRegister: function (optionsPayload) {
|
var vm = this;
|
window.WCS_WEBAUTHN.register(optionsPayload).then(function (credential) {
|
$.ajax({
|
url: baseUrl + "/user/passkey/register/finish/auth",
|
headers: { token: localStorage.getItem("token") },
|
data: {
|
ticket: optionsPayload.ticket,
|
currentPassword: hex_md5(vm.passkeyForm.currentPassword),
|
name: vm.passkeyForm.name,
|
credentialId: credential.credentialId,
|
clientDataJSON: credential.clientDataJSON,
|
authenticatorData: credential.authenticatorData,
|
publicKey: credential.publicKey,
|
publicKeyAlgorithm: credential.publicKeyAlgorithm,
|
transports: credential.transports
|
},
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "通行密钥绑定失败");
|
return;
|
}
|
vm.$message.success("通行密钥已绑定");
|
vm.closePasskeyDialog();
|
vm.loadDetail();
|
},
|
error: function () {
|
vm.$message.error("通行密钥绑定失败");
|
},
|
complete: function () {
|
vm.passkeySubmitting = false;
|
}
|
});
|
}).catch(function (err) {
|
vm.passkeySubmitting = false;
|
vm.$message.error(vm.resolvePasskeyErrorMessage(err, "通行密钥绑定失败"));
|
});
|
},
|
submitPasskeyRemove: function () {
|
var vm = this;
|
vm.passkeySubmitting = true;
|
$.ajax({
|
url: baseUrl + "/user/passkey/remove/auth",
|
headers: { token: localStorage.getItem("token") },
|
data: {
|
currentPassword: hex_md5(vm.passkeyForm.currentPassword)
|
},
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "通行密钥解绑失败");
|
return;
|
}
|
vm.$message.success("通行密钥已解绑");
|
vm.closePasskeyDialog();
|
vm.loadDetail();
|
},
|
error: function () {
|
vm.$message.error("通行密钥解绑失败");
|
},
|
complete: function () {
|
vm.passkeySubmitting = false;
|
}
|
});
|
},
|
resolvePasskeyErrorMessage: function (err, fallback) {
|
var message = err && err.message ? String(err.message) : "";
|
if (message === "secure-context") {
|
return "通行密钥仅支持在 HTTPS 或 localhost 环境下使用";
|
}
|
if (message === "not-supported" || message === "extension-unsupported" || message === "public-key-missing") {
|
return "当前浏览器不支持通行密钥,请使用最新版 Chrome、Edge 或 Safari";
|
}
|
if (err && err.name === "NotAllowedError") {
|
return "已取消通行密钥操作或验证超时";
|
}
|
return fallback || "通行密钥操作失败";
|
},
|
copySecret: function () {
|
var vm = this;
|
var text = vm.mfaSetup.secret || "";
|
if (!text) {
|
return;
|
}
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
navigator.clipboard.writeText(text).then(function () {
|
vm.$message.success("密钥已复制");
|
}).catch(function () {
|
vm.fallbackCopy(text);
|
});
|
return;
|
}
|
vm.fallbackCopy(text);
|
},
|
fallbackCopy: function (text) {
|
try {
|
var textarea = document.createElement("textarea");
|
textarea.value = text;
|
textarea.style.position = "fixed";
|
textarea.style.opacity = "0";
|
document.body.appendChild(textarea);
|
textarea.select();
|
document.execCommand("copy");
|
document.body.removeChild(textarea);
|
this.$message.success("密钥已复制");
|
} catch (err) {
|
this.$message.error("复制失败");
|
}
|
},
|
handleSave: function () {
|
var vm = this;
|
vm.$refs.profileForm.validate(function (valid) {
|
if (!valid) {
|
return false;
|
}
|
vm.$confirm("确定修改资料吗?", "提示", {
|
type: "warning",
|
confirmButtonText: "确定",
|
cancelButtonText: "取消"
|
}).then(function () {
|
vm.submitSave();
|
}).catch(function () {
|
});
|
return true;
|
});
|
},
|
submitSave: function () {
|
var vm = this;
|
vm.saving = true;
|
$.ajax({
|
url: baseUrl + "/user/update/auth",
|
headers: { token: localStorage.getItem("token") },
|
data: {
|
id: vm.form.id,
|
username: vm.form.username,
|
mobile: vm.form.mobile
|
},
|
method: "POST",
|
success: function (res) {
|
if (handleForbidden(res)) {
|
return;
|
}
|
if (Number(res.code) !== 200) {
|
vm.$message.error(res.msg || "保存失败");
|
return;
|
}
|
vm.$message.success(res.msg || "修改成功");
|
localStorage.setItem("username", vm.form.username || "");
|
if (window.parent && window.parent.document) {
|
var usernameNode = window.parent.document.getElementById("person-username");
|
if (usernameNode) {
|
usernameNode.textContent = localStorage.getItem("username");
|
}
|
}
|
},
|
error: function () {
|
vm.$message.error("保存失败");
|
},
|
complete: function () {
|
vm.saving = false;
|
}
|
});
|
}
|
}
|
});
|
})();
|