/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import { AlertCircle, CheckCircle, Shield } from 'lucide-react'; import { useRouter, useSearchParams } from 'next/navigation'; import { Suspense, useEffect, useState } from 'react'; import { CURRENT_VERSION } from '@/lib/version'; import { checkForUpdates, UpdateStatus } from '@/lib/version_check'; import MachineCode from '@/lib/machine-code'; import { useSite } from '@/components/SiteProvider'; import { ThemeToggle } from '@/components/ThemeToggle'; import GlobalThemeLoader from '@/components/GlobalThemeLoader'; // 版本显示组件 function VersionDisplay() { const [updateStatus, setUpdateStatus] = useState(null); const [isChecking, setIsChecking] = useState(true); useEffect(() => { const checkUpdate = async () => { try { const status = await checkForUpdates(); setUpdateStatus(status); } catch (_) { // do nothing } finally { setIsChecking(false); } }; checkUpdate(); }, []); return ( ); } function LoginPageClient() { const router = useRouter(); const searchParams = useSearchParams(); const [password, setPassword] = useState(''); const [username, setUsername] = useState(''); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const [shouldAskUsername, setShouldAskUsername] = useState(false); // 机器码相关状态 const [machineCode, setMachineCode] = useState(''); const [deviceInfo, setDeviceInfo] = useState(''); const [, setShowMachineCodeInput] = useState(false); const [requireMachineCode, setRequireMachineCode] = useState(false); const [machineCodeGenerated, setMachineCodeGenerated] = useState(false); const [, setShowBindOption] = useState(false); const [bindMachineCode, setBindMachineCode] = useState(false); const [deviceCodeEnabled, setDeviceCodeEnabled] = useState(true); // 站点是否启用设备码功能 const { siteName } = useSite(); // 在客户端挂载后设置配置并生成机器码 useEffect(() => { if (typeof window !== 'undefined') { const runtimeConfig = (window as any).RUNTIME_CONFIG; const storageType = runtimeConfig?.STORAGE_TYPE; const requireDeviceCode = runtimeConfig?.REQUIRE_DEVICE_CODE; setShouldAskUsername(storageType && storageType !== 'localstorage'); setDeviceCodeEnabled(requireDeviceCode !== false); // 默认启用,除非明确设置为 false // 只有在启用设备码功能时才生成机器码和设备信息 const generateMachineInfo = async () => { if (requireDeviceCode !== false && MachineCode.isSupported()) { try { const code = await MachineCode.generateMachineCode(); const info = await MachineCode.getDeviceInfo(); setMachineCode(code); setDeviceInfo(info); setMachineCodeGenerated(true); } catch (error) { console.error('生成机器码失败:', error); } } }; generateMachineInfo(); } }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!password || (shouldAskUsername && !username)) return; try { setLoading(true); // 构建请求数据 const requestData: any = { password, ...(shouldAskUsername ? { username } : {}), }; // 只有在启用设备码功能时才处理机器码逻辑 if (deviceCodeEnabled && (requireMachineCode || bindMachineCode) && machineCode) { requestData.machineCode = machineCode; } const res = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestData), }); const data = await res.json().catch(() => ({})); if (res.ok) { // 登录成功,如果启用设备码功能且用户选择绑定机器码,则绑定 if (deviceCodeEnabled && bindMachineCode && machineCode && shouldAskUsername) { try { await fetch('/api/machine-code', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ machineCode, deviceInfo, }), }); } catch (bindError) { console.error('绑定机器码失败:', bindError); } } const redirect = searchParams.get('redirect') || '/'; router.replace(redirect); } else if (res.status === 403) { // 处理机器码相关错误 if (data.requireMachineCode) { setRequireMachineCode(true); setShowMachineCodeInput(true); setError('该账户已绑定设备,请验证机器码'); } else if (data.machineCodeMismatch) { setError('机器码不匹配,此账户只能在绑定的设备上使用'); } else { setError(data.error || '访问被拒绝'); } } else if (res.status === 409) { // 机器码被其他用户绑定 setError(data.error || '机器码冲突'); } else if (res.status === 401) { setError('用户名或密码错误'); } else { setError(data.error ?? '服务器错误'); } } catch (error) { setError('网络错误,请稍后重试'); } finally { setLoading(false); } }; return (

{siteName}

{shouldAskUsername && (
setUsername(e.target.value)} />
)}
setPassword(e.target.value)} />
{/* 机器码信息显示 - 只有在启用设备码功能时才显示 */} {deviceCodeEnabled && machineCodeGenerated && shouldAskUsername && (
设备识别码
{MachineCode.formatMachineCode(machineCode)}
设备信息: {deviceInfo}
{/* 绑定选项 */} {!requireMachineCode && (
setBindMachineCode(e.target.checked)} className='w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600' />
{/*

// 管理员可选择不绑定机器码直接登录

*/}
)}
)} {error && (

{error}

)} {/* 登录按钮 */}
{/* 版本信息显示 */}
); } export default function LoginPage() { return ( Loading...}> ); }