From bd6b518aae61608ddc2d82b43ccc283dc95b9c54 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 11 三月 2026 13:59:33 +0800
Subject: [PATCH] #
---
src/main/webapp/static/js/login/login.js | 73 ++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/src/main/webapp/static/js/login/login.js b/src/main/webapp/static/js/login/login.js
index 9a7b1d0..2fb1a1b 100644
--- a/src/main/webapp/static/js/login/login.js
+++ b/src/main/webapp/static/js/login/login.js
@@ -11,6 +11,7 @@
localeOptions: [],
currentLocale: "zh-CN",
loginLoading: false,
+ passkeyLoading: false,
mfaLoading: false,
toolsDialogVisible: false,
textDialogVisible: false,
@@ -152,6 +153,33 @@
return true;
});
},
+ handlePasskeyLogin: function () {
+ var vm = this;
+ if (!window.WCS_WEBAUTHN || !window.WCS_WEBAUTHN.isSupported()) {
+ vm.$message.error(vm.resolvePasskeyErrorMessage({ message: window.isSecureContext ? "not-supported" : "secure-context" }, "login.error.passkeyOptionsFailed", "鑾峰彇閫氳瀵嗛挜鐧诲綍鍙傛暟澶辫触"));
+ return;
+ }
+ vm.passkeyLoading = true;
+ ajaxJson({
+ url: baseUrl + "/login/passkey/options.action",
+ data: {
+ mobile: vm.loginForm.mobile
+ },
+ method: "POST",
+ success: function (res) {
+ if (Number(res.code) !== 200) {
+ vm.passkeyLoading = false;
+ vm.$message.error(res.msg || vm.text("login.error.passkeyOptionsFailed", "鑾峰彇閫氳瀵嗛挜鐧诲綍鍙傛暟澶辫触"));
+ return;
+ }
+ vm.executePasskeyLogin(res.data || {});
+ },
+ error: function () {
+ vm.passkeyLoading = false;
+ vm.$message.error(vm.text("login.error.passkeyOptionsFailed", "鑾峰彇閫氳瀵嗛挜鐧诲綍鍙傛暟澶辫触"));
+ }
+ });
+ },
submitLogin: function () {
var vm = this;
vm.loginLoading = true;
@@ -250,12 +278,57 @@
}
});
},
+ executePasskeyLogin: function (payload) {
+ var vm = this;
+ window.WCS_WEBAUTHN.authenticate(payload).then(function (assertion) {
+ ajaxJson({
+ url: baseUrl + "/login/passkey/verify.action",
+ data: {
+ ticket: payload.ticket,
+ credentialId: assertion.credentialId,
+ clientDataJSON: assertion.clientDataJSON,
+ authenticatorData: assertion.authenticatorData,
+ signature: assertion.signature
+ },
+ method: "POST",
+ success: function (res) {
+ if (Number(res.code) === 200) {
+ vm.finishLogin(res.data || {});
+ return;
+ }
+ vm.$message.error(res.msg || vm.text("login.error.passkeyVerifyFailed", "閫氳瀵嗛挜楠岃瘉澶辫触"));
+ },
+ error: function () {
+ vm.$message.error(vm.text("login.error.passkeyVerifyFailed", "閫氳瀵嗛挜楠岃瘉澶辫触"));
+ },
+ complete: function () {
+ vm.passkeyLoading = false;
+ }
+ });
+ }).catch(function (err) {
+ vm.passkeyLoading = false;
+ vm.$message.error(vm.resolvePasskeyErrorMessage(err, "login.error.passkeyVerifyFailed", "閫氳瀵嗛挜楠岃瘉澶辫触"));
+ });
+ },
finishLogin: function (payload) {
localStorage.setItem("token", payload.token || "");
localStorage.setItem("username", payload.username || this.loginForm.mobile || "");
this.closeMfaDialog();
window.location.href = "index.html";
},
+ resolvePasskeyErrorMessage: function (err, fallbackKey, fallbackText) {
+ var message = err && err.message ? String(err.message) : "";
+ if (message === "secure-context") {
+ return this.text("login.passkey.secureContext", "閫氳瀵嗛挜浠呮敮鎸佸湪 HTTPS 鎴� localhost 鐜涓嬩娇鐢�");
+ }
+ if (message === "not-supported" || message === "extension-unsupported" || message === "public-key-missing") {
+ return this.text("login.passkey.browserUnsupported", "褰撳墠娴忚鍣ㄤ笉鏀寔閫氳瀵嗛挜锛岃浣跨敤鏈�鏂扮増 Chrome銆丒dge 鎴� Safari");
+ }
+ if (err && err.name === "NotAllowedError") {
+ return this.text(fallbackKey, fallbackText);
+ }
+ return this.text(fallbackKey, fallbackText);
+ },
openTextDialog: function (title, label, text, tip) {
var pretty = "";
try {
--
Gitblit v1.9.1