施工(HEL-226): 实现登录门户与本机免密切换账号
用设备 Cookie 和授权表记住本机已验证账号,登录页按确认样图做成门户,不再把密码写进浏览器。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
8a5e78f022
commit
f0a1adf52f
@@ -5,10 +5,15 @@
|
||||
|
||||
function readTheme() {
|
||||
try {
|
||||
return global.localStorage.getItem(THEME_KEY) === "dark" ? "dark" : "light";
|
||||
const stored = global.localStorage.getItem(THEME_KEY);
|
||||
if (stored === "dark" || stored === "light") return stored;
|
||||
} catch (_error) {
|
||||
return "light";
|
||||
}
|
||||
if (global.matchMedia && global.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
return "dark";
|
||||
}
|
||||
return "light";
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
|
||||
@@ -250,6 +250,7 @@
|
||||
'<h2>小白复盘</h2>',
|
||||
'<p>登录后进入你的复盘空间</p>',
|
||||
"</div>",
|
||||
'<div class="m-auth-accounts" id="m-auth-accounts" hidden></div>',
|
||||
'<div class="m-auth-tabs">',
|
||||
'<button class="m-auth-tab active" type="button" data-auth-mode="login">登录</button>',
|
||||
'<button class="m-auth-tab" type="button" data-auth-mode="register">注册</button>',
|
||||
@@ -265,6 +266,7 @@
|
||||
].join("");
|
||||
authMode = "login";
|
||||
bindAuth();
|
||||
loadMobileAccounts();
|
||||
}
|
||||
|
||||
function setAuthMode(mode) {
|
||||
@@ -287,6 +289,34 @@
|
||||
document.getElementById("m-auth-form").addEventListener("submit", submitAuth);
|
||||
}
|
||||
|
||||
async function loadMobileAccounts() {
|
||||
const host = document.getElementById("m-auth-accounts");
|
||||
if (!host || !global.MobileSession.listAccounts) return;
|
||||
try {
|
||||
const payload = await global.MobileSession.listAccounts();
|
||||
const accounts = payload.accounts || [];
|
||||
if (!accounts.length) return;
|
||||
host.hidden = false;
|
||||
host.innerHTML = accounts.map(function (account) {
|
||||
return '<button class="m-auth-account" type="button" data-switch-id="' + account.user_id + '">' +
|
||||
'<strong>' + escapeHtml(account.username) + '</strong>' +
|
||||
'<span>直接进入</span></button>';
|
||||
}).join("");
|
||||
host.querySelectorAll("[data-switch-id]").forEach(function (button) {
|
||||
button.addEventListener("click", async function () {
|
||||
try {
|
||||
await global.MobileSession.switchAccount(Number(button.dataset.switchId));
|
||||
replace(DEFAULT_HASH);
|
||||
} catch (error) {
|
||||
showAuthError(document.getElementById("m-auth-error"), error.message || "该账号需重新验证");
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (_error) {
|
||||
host.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
function showAuthError(element, message) {
|
||||
element.textContent = message;
|
||||
element.classList.remove("m-motion-fade-in");
|
||||
|
||||
@@ -47,5 +47,30 @@
|
||||
return Boolean(state.user && state.user.role === "admin");
|
||||
}
|
||||
|
||||
global.MobileSession = { state: state, me: me, login: login, register: register, logout: logout, isAdmin: isAdmin };
|
||||
async function listAccounts() {
|
||||
return global.MobileAPI.request("/api/auth/accounts");
|
||||
}
|
||||
|
||||
async function switchAccount(userId) {
|
||||
const payload = await global.MobileAPI.request("/api/auth/switch", "POST", {
|
||||
user_id: userId
|
||||
});
|
||||
return applySession(payload);
|
||||
}
|
||||
|
||||
async function forgetAccount(userId) {
|
||||
await global.MobileAPI.request("/api/auth/forget", "POST", { user_id: userId });
|
||||
}
|
||||
|
||||
global.MobileSession = {
|
||||
state: state,
|
||||
me: me,
|
||||
login: login,
|
||||
register: register,
|
||||
logout: logout,
|
||||
listAccounts: listAccounts,
|
||||
switchAccount: switchAccount,
|
||||
forgetAccount: forgetAccount,
|
||||
isAdmin: isAdmin
|
||||
};
|
||||
})(window);
|
||||
|
||||
Reference in New Issue
Block a user