Added full user authentication system: register/login with validation, bcrypt, reCAPTCHA integration, session handling, and new landing page with animated form switcher.

This commit is contained in:
Dr3amFury
2025-07-29 19:22:49 +02:00
parent a2af4c3d1a
commit 08a5cead74
6 changed files with 159 additions and 57 deletions

4
db.php
View File

@@ -1,13 +1,13 @@
<?php <?php
function getConnection() { function getConnection() {
$host = getenv('DB_HOST') ?: 'localhost'; $host = getenv('DB_HOST') ?: 'localhost';
$port = 3308; $port = 3308; // ✅ using custom port
$db = getenv('DB_NAME') ?: 'ai_email'; $db = getenv('DB_NAME') ?: 'ai_email';
$user = getenv('DB_USER') ?: 'root'; $user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASS') ?: ''; $pass = getenv('DB_PASS') ?: '';
$charset = 'utf8mb4'; $charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset"; $dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";
$options = [ $options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,

View File

@@ -1,4 +1,12 @@
<?php include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/header.php'); <?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: /landing.php");
exit();
}
include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/header.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/db.php'); require_once($_SERVER['DOCUMENT_ROOT'] . '/db.php');
$conn = getConnection();?> $conn = getConnection();?>

View File

@@ -151,3 +151,29 @@ button + button {
white-space: pre-wrap; white-space: pre-wrap;
word-wrap: break-word; word-wrap: break-word;
} }
.auth-box {
max-width: 400px;
margin: auto;
padding: 20px;
border-radius: 10px;
background: #fff;
transition: all 0.5s ease;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.auth-box.hidden {
display: none;
}
.auth-box h2 {
text-align: center;
}
.auth-box .error {
color: red;
text-align: center;
margin-bottom: 10px;
}
.auth-box input, .auth-box button {
display: block;
width: 100%;
margin: 10px 0;
}

View File

@@ -5,13 +5,23 @@ require_once($_SERVER['DOCUMENT_ROOT'] . '/db.php');
$errors = []; $errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$user = trim($_POST['user'] ?? ''); $user = trim($_POST['login_email'] ?? '');
$password = $_POST['password'] ?? ''; $password = $_POST['login_password'] ?? '';
$captcha = $_POST['g-recaptcha-response'] ?? '';
if (empty($user) || empty($password)) { if (empty($user) || empty($password)) {
$errors[] = "All fields are required."; $errors[] = "All fields are required.";
} }
// CAPTCHA validation
$captcha_secret = '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'; // Google's test secret key
$captcha_response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$captcha_secret}&response={$captcha}");
$captcha_data = json_decode($captcha_response);
if (!$captcha_data->success) {
$errors[] = "CAPTCHA verification failed.";
}
if (empty($errors)) { if (empty($errors)) {
$conn = getConnection(); $conn = getConnection();
$stmt = $conn->prepare("SELECT id, password, uniqueid FROM users WHERE email = :user OR username = :user"); $stmt = $conn->prepare("SELECT id, password, uniqueid FROM users WHERE email = :user OR username = :user");
@@ -27,17 +37,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors[] = "Invalid credentials."; $errors[] = "Invalid credentials.";
} }
} }
$_SESSION['login_error'] = implode("<br>", $errors);
header("Location: /landing.php");
exit();
} }
?> ?>
<!-- Basic form UI -->
<h2>Login</h2>
<form method="POST">
<input name="user" placeholder="Username or Email" required><br>
<input name="password" type="password" placeholder="Password" required><br>
<button type="submit">Login</button>
</form>
<?php if (!empty($errors)): ?>
<ul><?php foreach ($errors as $e) echo "<li>$e</li>"; ?></ul>
<?php endif; ?>

View File

@@ -7,13 +7,20 @@ $errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? ''); $username = trim($_POST['username'] ?? '');
$email = trim($_POST['email'] ?? ''); $email = trim($_POST['email'] ?? '');
$confirm_email = trim($_POST['confirm_email'] ?? '');
$password = $_POST['password'] ?? ''; $password = $_POST['password'] ?? '';
$age = (int) ($_POST['age'] ?? 0);
$captcha = $_POST['g-recaptcha-response'] ?? '';
// Validate inputs // Basic validation
if (empty($username) || empty($email) || empty($password)) { if (empty($username) || empty($email) || empty($confirm_email) || empty($password) || empty($age)) {
$errors[] = "All fields are required."; $errors[] = "All fields are required.";
} }
if ($email !== $confirm_email) {
$errors[] = "Emails do not match.";
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email format."; $errors[] = "Invalid email format.";
} }
@@ -22,10 +29,23 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors[] = "Password must be at least 6 characters."; $errors[] = "Password must be at least 6 characters.";
} }
if ($age < 16) {
$errors[] = "You must be at least 16 years old to register.";
}
// CAPTCHA validation
$captcha_secret = '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'; // Google's test secret key
$captcha_response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$captcha_secret}&response={$captcha}");
$captcha_data = json_decode($captcha_response);
if (!$captcha_data->success) {
$errors[] = "CAPTCHA verification failed.";
}
if (empty($errors)) { if (empty($errors)) {
$conn = getConnection(); $conn = getConnection();
// Check if email or username already exists // Check for existing user
$stmt = $conn->prepare("SELECT id FROM users WHERE email = :email OR username = :username"); $stmt = $conn->prepare("SELECT id FROM users WHERE email = :email OR username = :username");
$stmt->execute(['email' => $email, 'username' => $username]); $stmt->execute(['email' => $email, 'username' => $username]);
@@ -33,7 +53,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors[] = "Email or username already in use."; $errors[] = "Email or username already in use.";
} else { } else {
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$uniqueId = bin2hex(random_bytes(16)); // session ID $uniqueId = bin2hex(random_bytes(16));
$insert = $conn->prepare("INSERT INTO users (username, email, password, uniqueid) VALUES (:username, :email, :password, :uniqueid)"); $insert = $conn->prepare("INSERT INTO users (username, email, password, uniqueid) VALUES (:username, :email, :password, :uniqueid)");
$insert->execute([ $insert->execute([
@@ -50,18 +70,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exit(); exit();
} }
} }
$_SESSION['register_error'] = implode("<br>", $errors);
header("Location: /landing.php");
exit();
} }
?> ?>
<!-- Basic form UI -->
<h2>Register</h2>
<form method="POST">
<input name="username" placeholder="Username" required><br>
<input name="email" type="email" placeholder="Email" required><br>
<input name="password" type="password" placeholder="Password" required><br>
<button type="submit">Register</button>
</form>
<?php if (!empty($errors)): ?>
<ul><?php foreach ($errors as $e) echo "<li>$e</li>"; ?></ul>
<?php endif; ?>

View File

@@ -1,28 +1,83 @@
<?php <?php
session_start(); session_start();
require_once($_SERVER['DOCUMENT_ROOT'] . '/db.php');
if (isset($_SESSION['user_id'])) { require_once($_SERVER['DOCUMENT_ROOT'] . '/config.php');
// Already logged in, redirect to email generator include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/header.php');
header("Location: /home.php");
exit();
}
include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/header.php');
?> ?>
<body>
<div class="container" style="text-align: center;">
<h1>Welcome to AI Email Generator</h1>
<p style="margin-bottom: 20px;">Craft professional emails in seconds. Please login or register to get started.</p>
<div style="display: flex; justify-content: center; gap: 20px;">
<a href="/inc/php/login.php"><button style="padding: 10px 20px;">Login</button></a>
<a href="/inc/php/register.php"><button style="padding: 10px 20px;">Register</button></a>
</div>
<div style="margin-top: 30px;"> <link rel="stylesheet" href="/inc/css/style.css">
<button id="darkModeBtn">Toggle Dark Mode</button> <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</div>
<body>
<div class="container" id="auth-container">
<h1>AI Email Generator</h1>
<!-- Login Form -->
<div id="login-box" class="auth-box">
<form action="/inc/php/login.php" method="POST">
<h2>Login</h2>
<?php if (isset($_SESSION['login_error'])): ?>
<p class="error"><?= $_SESSION['login_error']; unset($_SESSION['login_error']); ?></p>
<?php endif; ?>
<label for="login_email">Email or Username</label>
<input type="text" name="login_email" required>
<label for="login_password">Password</label>
<input type="password" name="login_password" required>
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
<button type="submit">Login</button>
<p>Don't have an account? <a href="#" onclick="showRegister()">Register here</a></p>
</form>
</div> </div>
<script src="/inc/js/theme.js"></script> <!-- Register Form -->
<div id="register-box" class="auth-box hidden">
<form action="/inc/php/register.php" method="POST">
<h2>Register</h2>
<?php if (isset($_SESSION['register_error'])): ?>
<p class="error"><?= $_SESSION['register_error']; unset($_SESSION['register_error']); ?></p>
<?php endif; ?>
<label for="username">Username</label>
<input type="text" name="username" required>
<label for="email">Email</label>
<input type="email" name="email" required>
<label for="confirm_email">Confirm Email</label>
<input type="email" name="confirm_email" required>
<label for="password">Password</label>
<input type="password" name="password" required>
<label for="age">Age</label>
<input type="number" name="age" min="16" required>
<div class="g-recaptcha" data-sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"></div>
<button type="submit">Register</button>
<p>Already have an account? <a href="#" onclick="showLogin()">Login here</a></p>
</form>
</div>
</div>
<script>
function showRegister() {
document.getElementById("login-box").classList.add("hidden");
document.getElementById("register-box").classList.remove("hidden");
}
function showLogin() {
document.getElementById("register-box").classList.add("hidden");
document.getElementById("login-box").classList.remove("hidden");
}
</script>
<?php include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/footer.php'); ?> <?php include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/footer.php'); ?>