/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import { AlertCircle, CheckCircle, Eye, EyeOff } 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 { useSite } from '@/components/SiteProvider'; import { ThemeToggle } from '@/components/ThemeToggle'; // 版本显示组件 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 RegisterPageClient() { const router = useRouter(); const searchParams = useSearchParams(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); const [turnstileToken, setTurnstileToken] = useState(null); const [turnstileLoaded, setTurnstileLoaded] = useState(false); const [siteConfig, setSiteConfig] = useState(null); const [turnstileWidgetId, setTurnstileWidgetId] = useState(null); const [backgroundImage, setBackgroundImage] = useState(''); const { siteName } = useSite(); // 在客户端挂载后设置配置 useEffect(() => { if (typeof window !== 'undefined') { const runtimeConfig = (window as any).RUNTIME_CONFIG; // 设置背景图(支持多张随机选择) const registerBg = runtimeConfig?.REGISTER_BACKGROUND_IMAGE; if (registerBg) { const urls = registerBg .split('\n') .map((url: string) => url.trim()) .filter((url: string) => url !== ''); if (urls.length > 0) { // 随机选择一张背景图 const randomIndex = Math.floor(Math.random() * urls.length); setBackgroundImage(urls[randomIndex]); } } // 设置站点配置 const config = { EnableRegistration: runtimeConfig?.ENABLE_REGISTRATION || false, RegistrationRequireTurnstile: runtimeConfig?.REGISTRATION_REQUIRE_TURNSTILE || false, TurnstileSiteKey: runtimeConfig?.TURNSTILE_SITE_KEY || '', }; setSiteConfig(config); // 如果未开启注册,重定向到登录页 if (!config.EnableRegistration) { router.replace('/login'); } } }, [router]); // 加载Cloudflare Turnstile脚本 useEffect(() => { if (!siteConfig?.RegistrationRequireTurnstile || !siteConfig?.TurnstileSiteKey) { return; } const script = document.createElement('script'); script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js'; script.async = true; script.defer = true; script.onload = () => { setTurnstileLoaded(true); }; document.body.appendChild(script); return () => { document.body.removeChild(script); }; }, [siteConfig]); // 渲染Turnstile组件 useEffect(() => { if (!turnstileLoaded || !siteConfig?.TurnstileSiteKey) { return; } const container = document.getElementById('turnstile-container'); if (container && (window as any).turnstile) { const widgetId = (window as any).turnstile.render('#turnstile-container', { sitekey: siteConfig.TurnstileSiteKey, callback: (token: string) => { setTurnstileToken(token); }, }); setTurnstileWidgetId(widgetId); } }, [turnstileLoaded, siteConfig]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!username || !password || !confirmPassword) { setError('请填写所有字段'); return; } if (password !== confirmPassword) { setError('两次输入的密码不一致'); return; } if (password.length < 6) { setError('密码长度至少为6位'); return; } // 检查Turnstile验证 if (siteConfig?.RegistrationRequireTurnstile && !turnstileToken) { setError('请完成人机验证'); return; } try { setLoading(true); const res = await fetch('/api/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password, turnstileToken: siteConfig?.RegistrationRequireTurnstile ? turnstileToken : undefined, }), }); if (res.ok) { // 注册成功,跳转到登录页 const redirect = searchParams.get('redirect') || '/login'; router.replace(redirect); } else { // 注册失败,重置Turnstile if (siteConfig?.RegistrationRequireTurnstile && turnstileWidgetId !== null && (window as any).turnstile) { (window as any).turnstile.reset(turnstileWidgetId); setTurnstileToken(null); } if (res.status === 400) { const data = await res.json().catch(() => ({})); setError(data.error || '注册失败'); } else if (res.status === 409) { setError('用户名已存在'); } else { const data = await res.json().catch(() => ({})); setError(data.error ?? '服务器错误'); } } } catch (error) { // 网络错误,重置Turnstile if (siteConfig?.RegistrationRequireTurnstile && turnstileWidgetId !== null && (window as any).turnstile) { (window as any).turnstile.reset(turnstileWidgetId); setTurnstileToken(null); } setError('网络错误,请稍后重试'); } finally { setLoading(false); } }; // 如果配置未加载或未开启注册,显示加载中 if (!siteConfig) { return (
加载中...
); } return (

{siteName}

创建新账号

setUsername(e.target.value)} />
setPassword(e.target.value)} />
setConfirmPassword(e.target.value)} />
{/* Cloudflare Turnstile */} {siteConfig?.RegistrationRequireTurnstile && siteConfig?.TurnstileSiteKey && (
)} {error && (

{error}

)} {/* 注册按钮 */} {/* 返回登录链接 */}
{/* 版本信息显示 */}
); } export default function RegisterPage() { return ( Loading...}> ); }