237 lines
8.8 KiB
PHP
237 lines
8.8 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Core\Controller;
|
|
|
|
class AuthController extends Controller {
|
|
|
|
public function loginForm() {
|
|
if (isset($_SESSION['user_id'])) {
|
|
$this->redirect('/profile');
|
|
}
|
|
$this->view('auth/login');
|
|
}
|
|
|
|
public function registerForm() {
|
|
if (isset($_SESSION['user_id'])) {
|
|
$this->redirect('/profile');
|
|
}
|
|
// Check GET first, then Session
|
|
$ref = $_GET['ref'] ?? ($_SESSION['global_ref'] ?? '');
|
|
$this->view('auth/register', ['ref' => $ref]);
|
|
}
|
|
|
|
public function login() {
|
|
$username = $_POST['username'] ?? '';
|
|
$password = $_POST['password'] ?? '';
|
|
$ip = get_client_ip();
|
|
|
|
$db = db_pdo();
|
|
|
|
// Anti-Brute Force check by IP (for non-existent users)
|
|
$stmt = $db->prepare("SELECT attempts, last_attempt FROM login_logs WHERE ip_address = ?");
|
|
$stmt->execute([$ip]);
|
|
$ip_log = $stmt->fetch();
|
|
|
|
if ($ip_log && $ip_log['attempts'] >= 10 && (time() - strtotime($ip_log['last_attempt'])) < 900) {
|
|
$this->view('auth/login', ['error' => 'Too many failed attempts from this IP. Please try again in 15 minutes.']);
|
|
return;
|
|
}
|
|
|
|
$stmt = $db->prepare("SELECT * FROM users WHERE username = ?");
|
|
$stmt->execute([$username]);
|
|
$user = $stmt->fetch();
|
|
|
|
if ($user) {
|
|
// Check if account is banned
|
|
if ($user['is_banned']) {
|
|
$this->view('auth/login', ['error' => 'Your account has been banned. Please contact support.']);
|
|
return;
|
|
}
|
|
|
|
// Check brute force for specific user
|
|
if ($user['login_attempts'] >= 5 && (time() - strtotime($user['last_attempt_time'])) < 900) {
|
|
$this->view('auth/login', ['error' => 'Too many failed attempts. Please try again in 15 minutes.']);
|
|
return;
|
|
}
|
|
|
|
if (password_verify($password, $user['password'])) {
|
|
// Reset attempts
|
|
$stmt = $db->prepare("UPDATE users SET login_attempts = 0, last_ip = ? WHERE id = ?");
|
|
$stmt->execute([$ip, $user['id']]);
|
|
|
|
$_SESSION['user_id'] = $user['id'];
|
|
$_SESSION['username'] = $user['username'];
|
|
$_SESSION['role'] = $user['role'];
|
|
|
|
if ($user['role'] === 'admin') {
|
|
$this->redirect('/admin');
|
|
} else {
|
|
$this->redirect('/profile');
|
|
}
|
|
} else {
|
|
// Increment attempts
|
|
$stmt = $db->prepare("UPDATE users SET login_attempts = login_attempts + 1, last_attempt_time = NOW() WHERE id = ?");
|
|
$stmt->execute([$user['id']]);
|
|
|
|
$this->view('auth/login', ['error' => __('error_invalid_login')]);
|
|
}
|
|
} else {
|
|
// Log failed attempt by IP
|
|
if ($ip_log) {
|
|
$stmt = $db->prepare("UPDATE login_logs SET attempts = attempts + 1, last_attempt = NOW() WHERE ip_address = ?");
|
|
$stmt->execute([$ip]);
|
|
} else {
|
|
$stmt = $db->prepare("INSERT INTO login_logs (ip_address, attempts) VALUES (?, 1)");
|
|
$stmt->execute([$ip]);
|
|
}
|
|
$this->view('auth/login', ['error' => __('error_invalid_login')]);
|
|
}
|
|
}
|
|
|
|
public function register() {
|
|
$username = $_POST['username'] ?? '';
|
|
$password = $_POST['password'] ?? '';
|
|
$confirm_password = $_POST['confirm_password'] ?? '';
|
|
$ref_code = $_POST['ref_code'] ?? '';
|
|
$honeypot = $_POST['full_name'] ?? ''; // Hidden field
|
|
$ip = get_client_ip();
|
|
|
|
// Bot protection (Honeypot)
|
|
if (!empty($honeypot)) {
|
|
// Silent fail or show error
|
|
$this->view('auth/register', ['error' => 'Bot detected.', 'ref' => $ref_code]);
|
|
return;
|
|
}
|
|
|
|
if ($password !== $confirm_password) {
|
|
$this->view('auth/register', ['error' => __('error_password_mismatch'), 'ref' => $ref_code]);
|
|
return;
|
|
}
|
|
|
|
$db = db_pdo();
|
|
|
|
// Multi-account check (Anti-bot/Anti-cheat)
|
|
$stmt = $db->prepare("SELECT COUNT(*) FROM users WHERE registration_ip = ? AND created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)");
|
|
$stmt->execute([$ip]);
|
|
if ($stmt->fetchColumn() >= 3) {
|
|
$this->view('auth/register', ['error' => 'Too many registrations from this IP. Please try again later.', 'ref' => $ref_code]);
|
|
return;
|
|
}
|
|
|
|
// Check if username exists
|
|
$stmt = $db->prepare("SELECT id FROM users WHERE username = ?");
|
|
$stmt->execute([$username]);
|
|
if ($stmt->fetch()) {
|
|
$this->view('auth/register', ['error' => __('error_username_exists'), 'ref' => $ref_code]);
|
|
return;
|
|
}
|
|
|
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
|
$referral_code = substr(md5(uniqid($username, true)), 0, 8);
|
|
|
|
$referred_by = null;
|
|
if (!empty($ref_code)) {
|
|
$stmt = $db->prepare("SELECT id FROM users WHERE referral_code = ?");
|
|
$stmt->execute([$ref_code]);
|
|
$referrer = $stmt->fetch();
|
|
if ($referrer) {
|
|
$referred_by = $referrer['id'];
|
|
|
|
// Anti-self referral check
|
|
$stmt_ip = $db->prepare("SELECT registration_ip FROM users WHERE id = ?");
|
|
$stmt_ip->execute([$referred_by]);
|
|
$referrer_ip = $stmt_ip->fetchColumn();
|
|
|
|
if ($referrer_ip === $ip) {
|
|
// Possible self-referral, mark but allow or block?
|
|
// Let's block if IP matches exactly
|
|
$this->view('auth/register', ['error' => 'Self-referral is not allowed.', 'ref' => $ref_code]);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
$stmt = $db->prepare("INSERT INTO users (username, password, referral_code, referred_by, role, balance, registration_ip, last_ip) VALUES (?, ?, ?, ?, 'user', 0, ?, ?)");
|
|
$stmt->execute([$username, $hashed_password, $referral_code, $referred_by, $ip, $ip]);
|
|
$userId = $db->lastInsertId();
|
|
|
|
if ($referred_by) {
|
|
// Reward referrer
|
|
$stmt = $db->prepare("UPDATE users SET points = points + 10, total_referrals = total_referrals + 1 WHERE id = ?");
|
|
$stmt->execute([$referred_by]);
|
|
}
|
|
|
|
$_SESSION['user_id'] = $userId;
|
|
$_SESSION['username'] = $username;
|
|
$_SESSION['role'] = 'user';
|
|
|
|
$this->redirect('/profile');
|
|
}
|
|
|
|
public function logout() {
|
|
session_destroy();
|
|
$this->redirect('/');
|
|
}
|
|
|
|
public function profile() {
|
|
if (!isset($_SESSION['user_id'])) {
|
|
$this->redirect('/login');
|
|
}
|
|
|
|
$db = db_pdo();
|
|
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
|
|
$stmt->execute([$_SESSION['user_id']]);
|
|
$user = $stmt->fetch();
|
|
|
|
$stmt = $db->prepare("SELECT * FROM withdrawals WHERE user_id = ? ORDER BY created_at DESC");
|
|
$stmt->execute([$user['id']]);
|
|
$withdrawals = $stmt->fetchAll();
|
|
|
|
$this->view('auth/profile', [
|
|
'user' => $user,
|
|
'withdrawals' => $withdrawals,
|
|
'success' => $_SESSION['success'] ?? null,
|
|
'error' => $_SESSION['error'] ?? null
|
|
]);
|
|
unset($_SESSION['success'], $_SESSION['error']);
|
|
}
|
|
|
|
public function requestWithdrawal() {
|
|
if (!isset($_SESSION['user_id'])) {
|
|
$this->redirect('/login');
|
|
}
|
|
|
|
$amount = (float)$_POST['amount'];
|
|
$method = $_POST['method'];
|
|
$details = $_POST['details'];
|
|
|
|
if ($amount < 10000) { // Minimum WD
|
|
$_SESSION['error'] = __('error_min_withdraw');
|
|
$this->redirect('/profile');
|
|
}
|
|
|
|
$db = db_pdo();
|
|
$stmt = $db->prepare("SELECT balance FROM users WHERE id = ?");
|
|
$stmt->execute([$_SESSION['user_id']]);
|
|
$balance = $stmt->fetchColumn();
|
|
|
|
if ($balance < $amount) {
|
|
$_SESSION['error'] = __('error_insufficient_balance');
|
|
$this->redirect('/profile');
|
|
}
|
|
|
|
// Deduct balance
|
|
$stmt = $db->prepare("UPDATE users SET balance = balance - ? WHERE id = ?");
|
|
$stmt->execute([$amount, $_SESSION['user_id']]);
|
|
|
|
// Create WD request
|
|
$stmt = $db->prepare("INSERT INTO withdrawals (user_id, amount, method, account_details, status) VALUES (?, ?, ?, ?, 'pending')");
|
|
$stmt->execute([$_SESSION['user_id'], $amount, $method, $details]);
|
|
|
|
$_SESSION['success'] = __('success_withdraw_submitted');
|
|
$this->redirect('/profile');
|
|
}
|
|
}
|