Skip to content

Commit

Permalink
login feature completed
Browse files Browse the repository at this point in the history
  • Loading branch information
kuldp18 committed Dec 31, 2023
1 parent b1c6ba5 commit 139185e
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 18 deletions.
37 changes: 37 additions & 0 deletions controllers/login.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

function is_input_empty(string $email, string $password)
{
if (empty($email) || empty($password)) {
return true;
}
return false;
}


function is_email_invalid(string $email)
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return true;
}
return false;
}


function is_email_wrong(bool|array $result)
{
if (!$result) {
return true;
}
return false;
}

function is_password_wrong(string $pass, string $hashed_pass)
{
if (!password_verify($pass, $hashed_pass)) {
return true;
}
return false;
}
45 changes: 35 additions & 10 deletions includes/config_session.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,44 @@

//Regenerate session ID every 30 minutes for security

if(!isset($_SESSION["last_regeneration"])){
// no last regeneration time exists, so regenerate session ID
regen_session_id();
}else{
// wait 30 minutes before regenerating session ID
$interval = 60 * 30; // 30 minutes
if(time() - $_SESSION["last_regeneration"] >= $interval){
// check if user is logged in
if (isset($_SESSION['user_id'])) {
if (!isset($_SESSION["last_regeneration"])) {
// no last regeneration time exists, so regenerate session ID
regen_session_id_logged_in();
} else {
// wait 30 minutes before regenerating session ID
$interval = 60 * 30; // 30 minutes
if (time() - $_SESSION["last_regeneration"] >= $interval) {
regen_session_id_logged_in();
}
}
} else {
if (!isset($_SESSION["last_regeneration"])) {
// no last regeneration time exists, so regenerate session ID
regen_session_id();
} else {
// wait 30 minutes before regenerating session ID
$interval = 60 * 30; // 30 minutes
if (time() - $_SESSION["last_regeneration"] >= $interval) {
regen_session_id();
}
}
}


function regen_session_id(){
session_regenerate_id();

function regen_session_id_logged_in()
{
session_regenerate_id(true);
$new_session_id = session_create_id();
$session_id = $new_session_id . "_" . $_SESSION["user_id"];
session_id($session_id); // set the new session id
$_SESSION["last_regeneration"] = time();
}

function regen_session_id()
{
session_regenerate_id(true);
$_SESSION["last_regeneration"] = time();
}
}
72 changes: 72 additions & 0 deletions includes/login.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'];
$pass = $_POST['password'];

try {
require_once "./db_handler.inc.php";
require_once "../models/login.inc.php";
require_once "../controllers/login.inc.php";

// Error handlers

$errors = [];

// Check for empty inputs
if (is_input_empty($email, $pass)) {
// make sure to use local variables here
$errors["empty_input"] = "Please fill in all fields";
}

// Check if email is invalid
if (is_email_invalid($email)) {
$errors["invalid_email"] = "Please enter a valid email address";
}

// fetch user from database
$result = get_user($pdo, $email);

// Check if email is wrong
if (is_email_wrong($result)) {
$errors["login_incorrect"] = "Email or password is incorrect";
}
// check if email is right and password is wrong
if (!is_email_wrong($result) && is_password_wrong($pass, $result["password"])) {
$errors["login_incorrect"] = "Email or password is incorrect";
}

require_once "./config_session.inc.php";

if ($errors) {
$_SESSION["errors_login"] = $errors;
header('Location: ../pages/login.php');
die();
}

// generate new session id and append user id to it
$new_session_id = session_create_id();
$session_id = $new_session_id . "_" . $result["id"];
session_id($session_id); // set the new session id

// set session variables
$_SESSION["user_id"] = $result["id"];
$_SESSION["user_username"] = htmlspecialchars($result["username"]);
$_SESSION["user_fullname"] = htmlspecialchars($result["fullname"]);
$_SESSION["last_regeneration"] = time();

// redirect to home page
header('Location: ../index.php?login=success');

// close connection
$pdo = null;
$stmt = null;

die();
} catch (PDOException $e) {
die("Query failed: " . $e->getMessage());
}
} else {
header('Location: ../index.php');
die();
}
14 changes: 14 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@
<a href="./pages/login.php" class="home__link">Login</a>
</main>

<?php
if (isset($_GET["login"]) && $_GET["login"] === "success") {
echo <<<HTML
<section class="modal modal--success">
<h1 class="modal__title">Login successful!</h1>
<span class="modal__close modal__close--success">X</span>
</section>
HTML;
}
?>


<script src="./js/close_modal.js"></script>

</body>

</html>
18 changes: 13 additions & 5 deletions js/close_modal.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
const closeBtn = document.querySelector('.modal__close');
closeBtn.addEventListener('click', () => {
let parent = document.querySelector('.modal');
parent.remove();
});
let modal = document.querySelector('.modal');

if (modal) {
let closeBtn = document.querySelector('.modal__close');

// add event listener only if closeBtn exists
if (closeBtn) {
closeBtn.addEventListener('click', function () {
let parent = document.querySelector('.modal');
parent.remove();
});
}
}
14 changes: 14 additions & 0 deletions models/login.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

function get_user(object $pdo, string $email)
{
$query = "SELECT * FROM users WHERE email = :email"; // :email is a named placeholder
$stmt = $pdo->prepare($query); // prepare the query
$stmt->bindParam(":email", $email, PDO::PARAM_STR); // bind the $email variable to the :email placeholder
$stmt->execute(); // execute the query

$result = $stmt->fetch(PDO::FETCH_ASSOC); //fetch the result from the query
return $result;
}
19 changes: 16 additions & 3 deletions pages/login.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<?php
require_once "../includes/config_session.inc.php";
require_once "../views/login.inc.php";
?>


<!DOCTYPE html>
<html lang="en">

Expand All @@ -16,15 +22,16 @@
New to Quirx? Register
<a href="./register.php" class="login__link">here</a>.
</h3>
<form class="login__form">
<input type="email" name="email" placeholder="Enter email" required />
<input type="password" name="password" placeholder="Enter password" required />
<form class="login__form" method="post" action="../includes/login.inc.php">
<input type="email" name="email" placeholder="Enter email" />
<input type="password" name="password" placeholder="Enter password" />
<!-- TODO : ADD FORGOT PASSWORD FEATURE -->
<input type="submit" value="Login" class="login__btn" />
</form>
</main>

<?php

if (isset($_GET["signup"]) && $_GET["signup"] === "success") {
echo <<<HTML
<section class="modal modal--success">
Expand All @@ -34,6 +41,12 @@
HTML;
}
?>

<?php
check_and_print_login_errors();

?>

<script src="../js/close_modal.js"></script>
</body>

Expand Down
21 changes: 21 additions & 0 deletions views/login.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

function check_and_print_login_errors()
{

if (isset($_SESSION["errors_login"])) {
$errors = $_SESSION["errors_login"];
if (count($errors) > 0) {
echo "<section class='modal modal--error'>";
echo "<h1 class='modal__title'>Errors occurred while logging in: </h1>";
echo "<span class='modal__close modal__close--error'>X</span>";
foreach ($errors as $error) {
echo "<p class='modal__item'>$error</p>";
}
echo "</section>";
unset($_SESSION["errors_login"]);
}
}
}

0 comments on commit 139185e

Please sign in to comment.