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:
4
db.php
4
db.php
@@ -1,13 +1,13 @@
|
||||
<?php
|
||||
function getConnection() {
|
||||
$host = getenv('DB_HOST') ?: 'localhost';
|
||||
$port = 3308;
|
||||
$port = 3308; // ✅ using custom port
|
||||
$db = getenv('DB_NAME') ?: 'ai_email';
|
||||
$user = getenv('DB_USER') ?: 'root';
|
||||
$pass = getenv('DB_PASS') ?: '';
|
||||
$charset = 'utf8mb4';
|
||||
|
||||
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||
$dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
|
||||
10
home.php
10
home.php
@@ -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');
|
||||
$conn = getConnection();?>
|
||||
|
||||
|
||||
@@ -151,3 +151,29 @@ button + button {
|
||||
white-space: pre-wrap;
|
||||
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;
|
||||
}
|
||||
@@ -5,13 +5,23 @@ require_once($_SERVER['DOCUMENT_ROOT'] . '/db.php');
|
||||
$errors = [];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$user = trim($_POST['user'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
$user = trim($_POST['login_email'] ?? '');
|
||||
$password = $_POST['login_password'] ?? '';
|
||||
$captcha = $_POST['g-recaptcha-response'] ?? '';
|
||||
|
||||
if (empty($user) || empty($password)) {
|
||||
$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)) {
|
||||
$conn = getConnection();
|
||||
$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.";
|
||||
}
|
||||
}
|
||||
|
||||
$_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; ?>
|
||||
|
||||
@@ -7,13 +7,20 @@ $errors = [];
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$confirm_email = trim($_POST['confirm_email'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
$age = (int) ($_POST['age'] ?? 0);
|
||||
$captcha = $_POST['g-recaptcha-response'] ?? '';
|
||||
|
||||
// Validate inputs
|
||||
if (empty($username) || empty($email) || empty($password)) {
|
||||
// Basic validation
|
||||
if (empty($username) || empty($email) || empty($confirm_email) || empty($password) || empty($age)) {
|
||||
$errors[] = "All fields are required.";
|
||||
}
|
||||
|
||||
if ($email !== $confirm_email) {
|
||||
$errors[] = "Emails do not match.";
|
||||
}
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = "Invalid email format.";
|
||||
}
|
||||
@@ -22,10 +29,23 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$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)) {
|
||||
$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->execute(['email' => $email, 'username' => $username]);
|
||||
|
||||
@@ -33,7 +53,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$errors[] = "Email or username already in use.";
|
||||
} else {
|
||||
$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->execute([
|
||||
@@ -50,18 +70,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
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; ?>
|
||||
|
||||
95
landing.php
95
landing.php
@@ -1,28 +1,83 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
// Already logged in, redirect to email generator
|
||||
header("Location: /home.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/header.php');
|
||||
session_start();
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/db.php');
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/config.php');
|
||||
include($_SERVER['DOCUMENT_ROOT'] . '/inc/php/header.php');
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" href="/inc/css/style.css">
|
||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
||||
|
||||
<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 class="container" id="auth-container">
|
||||
<h1>AI Email Generator</h1>
|
||||
|
||||
<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>
|
||||
<!-- Login Form -->
|
||||
<div id="login-box" class="auth-box">
|
||||
<form action="/inc/php/login.php" method="POST">
|
||||
<h2>Login</h2>
|
||||
|
||||
<div style="margin-top: 30px;">
|
||||
<button id="darkModeBtn">Toggle Dark Mode</button>
|
||||
</div>
|
||||
<?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>
|
||||
|
||||
<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'); ?>
|
||||
|
||||
Reference in New Issue
Block a user