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']);
}
}