//! MNOTE 登录页面组件 use leptos::prelude::*; const TEST_ACCOUNT_EMAIL: &str = "mnote.e2e@example.com"; const TEST_ACCOUNT_PASSWORD: &str = "MnoteE2E123!"; const TEST_ACCOUNT_NAME: &str = "mnote-e2e"; /// MNOTE 登录页面 #[component] pub fn AuthPage() -> impl IntoView { view! {
"MNOTE"

"账号登录"

"登录后进入你的工作区"

} } const AUTH_SCRIPT: &str = r#" (function () { var root = document.querySelector('[data-testid="mnote-auth-page"]'); if (!root) return; var form = root.querySelector('form[data-auth-mode="control-plane-session"]'); var flowInput = root.querySelector('[data-auth-flow]'); var accountInput = root.querySelector('#account'); var emailInput = root.querySelector('#email'); var usernameInput = root.querySelector('#username'); var accountField = root.querySelector('[data-auth-field="account"]'); var emailField = root.querySelector('[data-auth-field="email"]'); var usernameField = root.querySelector('[data-auth-field="username"]'); var accountLabel = root.querySelector('[data-auth-account-label]'); var title = root.querySelector('#mnote-auth-title'); var subtitle = root.querySelector('.mnote-auth-heading p'); var submit = root.querySelector('[data-auth-submit]'); var quickLogin = root.querySelector('[data-auth-test-login]'); var switcher = root.querySelector('[data-auth-switch]'); var message = root.querySelector('[data-auth-message]'); if (!form || !flowInput || !submit || !quickLogin || !switcher || !message) return; function setMessage(text, type) { message.textContent = text || ''; message.dataset.type = type || ''; } function setBusy(isBusy) { submit.disabled = !!isBusy; quickLogin.disabled = !!isBusy; switcher.disabled = !!isBusy; } function setFlow(nextFlow) { var isSignUp = nextFlow === 'signUp'; flowInput.value = nextFlow; switcher.dataset.flow = nextFlow; if (title) title.textContent = isSignUp ? '创建账号' : '账号登录'; if (subtitle) subtitle.textContent = isSignUp ? '创建账号后进入你的工作区' : '登录后进入你的工作区'; submit.textContent = isSignUp ? '注册并登录' : '登录'; switcher.textContent = isSignUp ? '已有账号?登录' : '没有账号?注册'; if (accountLabel) accountLabel.textContent = '邮箱或用户名'; if (accountField) accountField.hidden = isSignUp; if (emailField) emailField.hidden = !isSignUp; if (usernameField) usernameField.hidden = !isSignUp; if (accountInput) { accountInput.required = !isSignUp; accountInput.placeholder = '请输入邮箱或用户名'; accountInput.autocomplete = 'username'; } if (emailInput) { emailInput.required = isSignUp; } if (usernameInput) { usernameInput.required = isSignUp; } quickLogin.hidden = isSignUp; var passwordInput = root.querySelector('#password'); if (passwordInput) passwordInput.autocomplete = isSignUp ? 'new-password' : 'current-password'; setMessage('', ''); } function buildPayload(flow, values) { var accountValue = String(values.account || '').trim(); var emailValue = String(values.email || '').trim(); var usernameValue = String(values.username || '').trim(); var payload = { action: 'auth:signIn', args: { provider: 'password', params: { password: values.password, flow: flow } } }; if (flow === 'signUp') { payload.args.params.email = emailValue; payload.args.params.name = usernameValue; } else { payload.args.params.account = accountValue; if (accountValue.indexOf('@') !== -1) payload.args.params.email = accountValue; if (accountValue) payload.args.params.name = accountValue.indexOf('@') === -1 ? accountValue : accountValue.split('@')[0]; } return payload; } async function requestAuth(flow, values) { var response = await fetch('/api/auth', { method: 'POST', headers: { 'content-type': 'application/json' }, credentials: 'include', body: JSON.stringify(buildPayload(flow, values)) }); var data = await response.json().catch(function () { return {}; }); if (!response.ok || data.error) { throw new Error(data.error || '登录失败,请重试'); } return data; } switcher.addEventListener('click', function () { setFlow(flowInput.value === 'signIn' ? 'signUp' : 'signIn'); }); form.addEventListener('submit', async function (event) { event.preventDefault(); var account = String((accountInput || {}).value || '').trim(); var email = String((emailInput || {}).value || '').trim(); var username = String((usernameInput || {}).value || '').trim(); var password = String((root.querySelector('#password') || {}).value || ''); var flow = flowInput.value === 'signUp' ? 'signUp' : 'signIn'; if ((flow === 'signIn' && !account) || (flow === 'signUp' && (!email || !username)) || !password) { setMessage('请完整填写信息', 'error'); return; } setBusy(true); setMessage(flow === 'signUp' ? '正在创建账号...' : '正在登录...', 'info'); try { await requestAuth(flow, { account: account, email: email, username: username, password: password }); setMessage('登录成功,正在进入工作区...', 'success'); window.location.assign('/'); } catch (error) { setMessage(error && error.message ? error.message : '登录失败,请重试', 'error'); setBusy(false); } }); quickLogin.addEventListener('click', async function () { var email = String(quickLogin.dataset.testEmail || '').trim(); var password = String(quickLogin.dataset.testPassword || ''); var username = String(quickLogin.dataset.testName || '').trim(); if (!email || !password || !username) { setMessage('测试账号配置缺失,请联系开发者', 'error'); return; } var passwordInput = root.querySelector('#password'); if (accountInput) accountInput.value = email; if (passwordInput) passwordInput.value = password; setBusy(true); setMessage('正在登录测试账号...', 'info'); try { await requestAuth('signIn', { account: email, password: password }); setMessage('登录成功,正在进入工作区...', 'success'); window.location.assign('/'); return; } catch (_signInError) { setMessage('测试账号不存在,正在自动创建...', 'info'); } try { await requestAuth('signUp', { email: email, username: username, password: password }); setMessage('测试账号已创建,正在进入工作区...', 'success'); window.location.assign('/'); } catch (error) { setMessage(error && error.message ? error.message : '测试账号登录失败,请重试', 'error'); setBusy(false); } }); setFlow('signIn'); })(); "#;