isLoggedIn()) { header('Location: /'); exit; } I18n::init(); include __DIR__ . '/../../Views/Web/login.php'; } public function loginSubmit() { header('Content-Type: application/json'); $data = json_decode(file_get_contents('php://input'), true); $username = trim($data['username'] ?? ''); $password = $data['password'] ?? ''; $remember = $data['remember'] ?? false; if (empty($username) || empty($password)) { echo json_encode(['success' => false, 'message' => 'Please fill in all fields']); return; } $db = new Database(); $user = $db->get('users', '*', ['username' => $username]); if (!$user || !password_verify($password, $user['password'])) { echo json_encode(['success' => false, 'message' => 'Invalid username or password']); return; } if (isset($user['status']) && $user['status'] == 0) { echo json_encode(['success' => false, 'message' => 'Account disabled']); return; } // 邮箱验证检查(虚拟账户跳过) if (empty($user['is_virtual']) && isset($user['email_verified']) && !$user['email_verified']) { echo json_encode(['success' => false, 'message' => 'Please verify your email first', 'need_verify' => true]); return; } if (session_status() === PHP_SESSION_NONE) session_start(); $_SESSION['web_user_id'] = $user['id']; $_SESSION['web_username'] = $user['username']; $_SESSION['web_role'] = $user['role'] ?? 'user'; $_SESSION['web_last_activity'] = time(); $_SESSION['web_ip'] = $_SERVER['REMOTE_ADDR']; $_SESSION['web_ua'] = $_SERVER['HTTP_USER_AGENT']; if ($remember) $_SESSION['web_remember'] = true; if (!empty($user['lang'])) $_SESSION['lang'] = $user['lang']; echo json_encode(['success' => true, 'message' => 'Login successful', 'redirect' => '/']); } public function registerSubmit() { header('Content-Type: application/json'); $data = json_decode(file_get_contents('php://input'), true); $username = trim($data['username'] ?? ''); $password = $data['password'] ?? ''; $confirmPassword = $data['confirm_password'] ?? ''; $email = trim($data['email'] ?? ''); $inviteCode = trim($data['invite_code'] ?? ''); $verifyCode = trim($data['verify_code'] ?? ''); if (empty($username) || empty($password) || empty($email)) { echo json_encode(['success' => false, 'message' => 'Please fill in all required fields']); return; } if (!preg_match('/^[a-zA-Z0-9_]{3,20}$/', $username)) { echo json_encode(['success' => false, 'message' => 'Username: 3-20 chars, letters/numbers/underscore only']); return; } if (strlen($password) < 6) { echo json_encode(['success' => false, 'message' => 'Password must be at least 6 characters']); return; } if ($password !== $confirmPassword) { echo json_encode(['success' => false, 'message' => 'Passwords do not match']); return; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo json_encode(['success' => false, 'message' => 'Invalid email address']); return; } $db = new Database(); // 唯一性检查 if ($db->get('users', 'id', ['username' => $username])) { echo json_encode(['success' => false, 'message' => 'Username already exists']); return; } if ($db->get('users', 'id', ['email' => $email])) { echo json_encode(['success' => false, 'message' => 'Email already registered']); return; } // 验证邮箱验证码 $ev = $db->get('email_verifications', '*', [ 'email' => $email, 'code' => $verifyCode, 'used' => 0, 'expires_at[>]' => date('Y-m-d H:i:s'), 'ORDER' => ['id' => 'DESC'] ]); if (!$ev) { echo json_encode(['success' => false, 'message' => 'Invalid or expired verification code']); return; } // 处理邀请码 → 代理关联 $agentId = null; if (!empty($inviteCode)) { $agent = $db->get('agents', '*', ['agent_code' => $inviteCode, 'status' => 1]); if ($agent) $agentId = $agent['id']; } $db->insert('users', [ 'username' => $username, 'password' => password_hash($password, PASSWORD_DEFAULT), 'email' => $email, 'role' => 'user', 'status' => 1, 'email_verified' => 1, 'agent_id' => $agentId, 'lang' => 'en', 'created_at' => date('Y-m-d H:i:s'), ]); // 标记验证码已用 $db->update('email_verifications', ['used' => 1], ['id' => $ev['id']]); echo json_encode(['success' => true, 'message' => 'Registration successful', 'redirect' => '/login']); } public function sendVerifyCode() { header('Content-Type: application/json'); $data = json_decode(file_get_contents('php://input'), true); $email = trim($data['email'] ?? ''); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo json_encode(['success' => false, 'message' => 'Invalid email']); return; } // 频率限制: 60秒内只能发一次 $db = new Database(); $recent = $db->get('email_verifications', '*', [ 'email' => $email, 'created_at[>]' => date('Y-m-d H:i:s', time() - 60), ]); if ($recent) { echo json_encode(['success' => false, 'message' => 'Please wait 60 seconds']); return; } $code = str_pad(mt_rand(0, 999999), 6, '0', STR_PAD_LEFT); $db->insert('email_verifications', [ 'email' => $email, 'code' => $code, 'expires_at' => date('Y-m-d H:i:s', time() + 600), // 10分钟 'created_at' => date('Y-m-d H:i:s'), ]); // 发送邮件 $subject = 'Email Verification Code'; $body = "Your verification code is: $code
Valid for 10 minutes."; $sent = \App\Core\Mailer::send($email, $subject, $body); echo json_encode(['success' => true, 'message' => 'Verification code sent']); } public function logout() { if (session_status() === PHP_SESSION_NONE) session_start(); $keys = ['web_user_id','web_username','web_role','web_last_activity','web_ip','web_ua','web_remember','lang']; foreach ($keys as $k) unset($_SESSION[$k]); header('Location: /login'); exit; } private function isLoggedIn(): bool { if (session_status() === PHP_SESSION_NONE) session_start(); return isset($_SESSION['web_user_id']); } }