dj_mix_hosting_software/login.php
2025-02-22 17:20:19 -08:00

154 lines
6.4 KiB
PHP

<?php
require_once 'includes/globals.php';
require_once 'vendor/autoload.php';
use DJMixHosting\Database;
use DJMixHosting\User;
use DJMixHosting\SessionManager;
use Random\RandomException;
// If a user is already logged in, redirect to profile.
if (SessionManager::getUser()) {
header("Location: /profile");
exit;
}
// Generate a CSRF token if one is not set
if (!isset($_SESSION['csrf_token'])) {
try {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
} catch (RandomException $e) {
die("An error occurred. Please try again.");
}
}
$title = $locale['home'];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['email'], $_POST['password'], $_POST['csrf_token'])) {
// Check the CSRF token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
$_SESSION['error'] = $locale['message'] . ": Invalid form submission. Please try again.";
} else {
$email = $_POST['email'];
$password = $_POST['password'];
$db = new Database($config);
$user = new User($db);
$result = $user->login($email, $password);
// If login() returns an array, the login was successful.
if (is_array($result)) {
SessionManager::setUser([
'id' => $result['id'],
'email' => $result['email'],
'username' => $result['username'],
'firstName' => $result['firstName'],
'lastName' => $result['lastName'],
'role' => $result['isAdmin'] ? 'admin' : 'user'
]);
header("Location: profile.php");
exit;
} else {
// Login failed; $result contains an error message.
$_SESSION['error'] = $result;
}
}
}
}
require_once 'includes/header.php';
if (isset($_SESSION['error'])) {
echo '<div class="alert alert-danger alert-dismissible fade show mb-4" role="alert">
' . htmlspecialchars($_SESSION['error']) . '
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>';
unset($_SESSION['error']);
}
?>
<section class="login-section py-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-5">
<div class="card shadow-sm border-0">
<div class="card-body p-4">
<h3 class="text-center mb-4"><?php echo $locale['login'];?></h3>
<form action="login.php" method="post" class="needs-validation" novalidate>
<div class="mb-3">
<label for="email" class="form-label"><?php echo $locale['email'];?></label>
<input type="email" class="form-control form-control-lg" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label"><?php echo $locale['password'];?></label>
<div class="input-group">
<input type="password" class="form-control form-control-lg" id="password" name="password" required>
<button class="btn btn-outline-secondary px-3" type="button" id="togglePassword"
style="border-left: none;">
<i class="bi bi-eye-fill fs-5"></i>
</button>
</div>
</div>
<div class="mb-4 form-check">
<input type="checkbox" class="form-check-input" id="rememberMe" name="remember_me">
<label class="form-check-label" for="rememberMe"><?php echo $locale['rememberMe'];?></label>
</div>
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token']); ?>">
<button type="submit" class="btn btn-primary w-100 btn-lg mb-3"><?php echo $locale['login'];?></button>
<div class="text-center">
<a href="forgot-password.php" class="text-decoration-none"><?php echo $locale['forgotPassword'];?></a>
</div>
</form>
</div>
</div>
<div class="text-center mt-4">
<p class="mb-0"><?php echo $locale['dontHaveAccount'];?> <a href="/" class="text-decoration-none"><?php echo $locale['signUp'];?></a></p>
</div>
</div>
</div>
</div>
</section>
<style>
.form-control:focus {
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.15);
}
#togglePassword:hover {
background-color: #f8f9fa;
}
#togglePassword:focus {
box-shadow: none;
}
.input-group .form-control:focus {
border-right: 1px solid #86b7fe;
}
.input-group .btn {
border-left: 0;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Form validation
const form = document.querySelector('.needs-validation');
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
// Password visibility toggle with improved UX
const togglePassword = document.querySelector('#togglePassword');
const password = document.querySelector('#password');
togglePassword.addEventListener('click', function() {
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
password.setAttribute('type', type);
this.querySelector('i').classList.toggle('bi-eye-fill');
this.querySelector('i').classList.toggle('bi-eye-slash-fill');
});
});
</script>
<?php require_once 'includes/footer.php'; ?>