diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..c41d281
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,38 @@
+
+
+
+
+
+# Contributing to the Project
+
+> First of all, thanks for considering or taking the time to contribute!
+
+The following is a simple guide on contributing to this Project. These are mostly guidelines, so feel free to use your best judgement and propose changes to this document in a pull request.
+
+### Did you fix whitespace, format code, or make a purely cosmetic patch?
+
+- Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of the project will generally not be accepted.
+
+### Do you intend to add a new feature or change an existing one?
+
+- Suggest your idea to [my email](mailto:saad01.1999@gmail.com) and start development on your idea.
+- Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
+- If you want to add to this project, I have a list of features to add in the future [here](README.md#future-improvements). It would be best if you pick a feature from this list to develop on.
+- Once development is complete, make a pull request to this project's master branch. Ensure the Pull Request's description clearly (and in detail) defines the goal, functionality and purpose of the new feature as well as details on the changes in original Project files.
+
+### Did you find a bug?
+
+- Ensure the bug was not already reported by searching on GitHub under Issues.
+- If you're unable to find an open issue addressing the problem, open a [new one](https://github.com/msaad1999/PHP-Login-System/issues/new). Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring.
+
+### Did you write a patch that fixes a bug?
+
+- Open a new GitHub pull request with the patch.
+- Ensure the Pull Request description clearly describes the problem and solution.
+
+### Do you have questions about the source code?
+
+- Ask any questions related to the Project to [my email](mailto:saad01.1999@gmail.com).
+
+
+> Any contribution from you guys would be greatly appreciated and welcomed.
diff --git a/README.md b/README.md
index df69ce2..399e995 100644
--- a/README.md
+++ b/README.md
@@ -1,243 +1,362 @@
-
-
+
+
-> A complete PHP Login and Registration System with Profile editing & authentication System
+> Embeddable and Secure PHP Authentication System with Login, Signup, User Profiles, Profile Editing, Account Verification via Email, Password Reset System, Remember Me Feature, Global ERROR & STATUS variables system and Authentication checks.
# Table of Contents
-* [Installation](#installation)
- * [Requirements](#requirements)
- * [Installation Steps](#installation-steps)
- * [Getting Started](#getting-started)
-* [Features](#Features)
-* [Components](#Components)
- * [Languages](#Languages)
- * [Development Environment](#Development-Environment)
- * [Database](#database)
- * [DBMS](#DBMS)
- * [API](#api)
- * [Frameworks and Libraries](#Frameworks-and-Libraries)
- * [External PLugins](#external-plugins)
-* [Details](#details)
-* [View KLiK, The Complete Project](#klik-social-media-website)
+- [Table of Contents](#table-of-contents)
+ - [Getting Started](#getting-started)
+ - [Requirements](#requirements)
+ - [Installation](#installation)
+ - [Existing Account(s)](#existing-accounts)
+ - [Project File Structure](#project-file-structure)
+ - [Building on top of System](#building-on-top-of-system)
+ - [Components](#components)
+ - [Languages](#languages)
+ - [Development Environment](#development-environment)
+ - [External Resources/Plugins](#external-resourcesplugins)
+ - [Features](#features)
+ - [Easy Integration / Embedding](#easy-integration--embedding)
+ - [Security](#security)
+ - [SQL Injection Protection](#sql-injection-protection)
+ - [Header & Email Injection Protection](#header--email-injection-protection)
+ - [CSRF Protection](#csrf-protection)
+ - [Secure Remember-me Cookie](#secure-remember-me-cookie)
+ - [Secure Account Activation & Password Reset](#secure-account-activation--password-reset)
+ - [Login | Signup](#login--signup)
+ - [User Profile | Profile Editing](#user-profile--profile-editing)
+ - [Email Verification | Account Activation](#email-verification--account-activation)
+ - [Password Resetting](#password-resetting)
+ - [Auth Verification](#auth-verification)
+ - [Remember Me Feature](#remember-me-feature)
+ - [GLOBAL temporary ERROR & STATUS values](#global-temporary-error--status-values)
+ - [Contact System](#contact-system)
+ - [Future Improvements](#future-improvements)
+ - [Contribution Guidelines](#contribution-guidelines)
+ - [License](#license)
+ - [Personal Note](#personal-note)
+
+## Getting Started
+
+### Requirements
+* PHP
+* Apache server
+* MySQL
+* PHPMailer
+* Bootstrap
+* JQuery
+### Installation
+1. Import the file `assets/setup/DBcreation.sql` into the current DBMS. The dump file also creates the database (named `klik_loginsystem`), so no prior action is needed. If database name needs to be updated, change it in the dump file where the database title is declared.
+2. Edit the file `assets/setup/env.php` and setup the Application information, Database connection and SMTP server. Port value is usually not needed in Database connections, so only edit if you know what you are doing. The email server (and the connected email account) will be used to send confirmation, validation and notification emails.
-## Installation
+```php
+// env.php
-#### Requirements
-* PHP
-* Apache server
-* MySQL Database
-* SQL
+if (!defined('APP_NAME')) define('APP_NAME' ,'Login System');
+if (!defined('APP_ORGANIZATION')) define('APP_ORGANIZATION' ,'KLiK');
+if (!defined('APP_OWNER')) define('APP_OWNER' ,'msaad1999');
+if (!defined('APP_DESCRIPTION')) define('APP_DESCRIPTION' ,'Embeddable and Secure PHP Login System');
+
+
+if (!defined('DB_DATABASE')) define('DB_DATABASE', 'klik_loginsystem');
+if (!defined('DB_HOST')) define('DB_HOST','127.0.0.1');
+if (!defined('DB_USERNAME')) define('DB_USERNAME','root');
+if (!defined('DB_PASSWORD')) define('DB_PASSWORD' ,'');
+if (!defined('DB_PORT')) define('DB_PORT' ,'');
+
+
+if (!defined('MAIL_HOST')) define('MAIL_HOST', 'smtp.gmail.com');
+if (!defined('MAIL_USERNAME')) define('MAIL_USERNAME', 'example.email@gmail.com');
+if (!defined('MAIL_PASSWORD')) define('MAIL_PASSWORD', 'example_password');
+if (!defined('MAIL_ENCRYPTION')) define('MAIL_ENCRYPTION', 'ssl');
+if (!defined('MAIL_PORT')) define('MAIL_PORT', 465);
+```
+
+### Existing Account(s)
+The database already contains a sample account to test things out with. Use that or head over to the signup page and start making new accounts.
+
+```php
+// credentials for existing account
+
+username: supahot
+password: aaaaaa
+```
+
+### Project File Structure
+
+
+| Path / File | Purpose |
+| -- | -- |
+| `[accessible URLs/Pages]` | All folders in root directory except `assets`. |
+| `assets/css` | Folder for global or layout-specific custom CSS files. |
+| `assets/images` | Images used in Application UI or git README. |
+| `assets/includes` | Functions or classes. |
+| `assets/js` | Custom js files. |
+| `assets/setup` | Project configuration and setup files. |
+| `assets/uploads` | Folder for all content uploaded by application users. |
+| `assets/uploads/users` | Images uploaded by users. |
+| `assets/vendor` | Folder for all plugins/resources. |
+
+### Building on top of System
+
+Once this Authentication system has been set up, it can be easily built upon this way: New pages can be quickly added by creating more folders in the root directory, with the main frontend file being `index.php`, backend functionalities in the `includes` subfolder and custom styling in the `custom.css` file, present in the same top-level folder as that of index.php.
+
+New function groups or classes can be created in new files in the `assets/includes/` folder, and will have to be included in relevant pages. if the added functionalities are mostly universal, they can be required in the `assets/layouts/header.php` file (this includes them for all frontend files but backend files will still have to be individually linked). In the same way, more global css files can be saved in `assets/css` and included in the header.php layout file. Same convention will hold for JS files, with the scripts being in `assets/js/` and included in `assets/layouts/footer.php` file.
+
+Additional plugins or offline resources can be placed in the `assets/vendor/` folder and linked-to in either the header or footer layout file, depending on the file type to be linked.
+
+> A good convention to adopt while building on top of this would be to adopt the same file structure conventions as in this system, in order to avoid extra and/or unneeded effort to synchronise the entire project. The system has already been made with the default PHP Application file structure in order to avoid most conflicts.
+
+## Components
+
+### Languages
-> All of these requirements can be completed at once by simply installing a server stack like `Wamp` or `Xampp`
+- PHP-7.3.11
+- MySQLi API
+- HTML5
+- CSS3
-#### Installation Steps
-1. Import the `DBcreation.sql` file in the `includes` folder into phpMyAdmin. There is no need for any change in the .sql file. This will create the database required for the application to function.
+### Development Environment
-2. Edit the `dbh.inc.php` file in the `includes` folder to create the database connection. Change the password and username to the ones being used within `phpMyAdmin`. There is no need to change anything else.
+- Apache-2.4.41
+- Windows 10
+
+### External Resources/Plugins
+
+- PHPMailer-6.0.6
+- Bootstrap-4.3.1
+- Font awesome-5.12.0
+- JQuery-3.4.1
+
+## Features
+
+### Easy Integration / Embedding
+
+The application is designed to be easily embeddable and is meant to be built upon. The current UI has been built mostly on raw bootstrap, and is meant to be completely replaced rather than improved upon. The purpose of this project is to provide the needed `backend` functionality, and all `UI elements` should be replaced and/or rebuilt when creating a separate application.
+
+It is recommended that the application be installed/embedded into the project before creation of application backend _and preferably the frontend as well). Otherwise, if the existing file structure conflicts with this project's, it may cause problems and will make it difficult to re-synchronise the entire project again.
+
+The project was created with the standard PHP development file structure, in order to maintain flexibility. Simply add more features/ pages in the same way the sample page-folders in the root folder are created.
+
+In each page folder, the `index.php` is the main target page, the `includes` folder holds the backend functionality and the `custom.css` enables custom designs on top of a global css file without interfering with other pages.
+
+### Security
+
+#### SQL Injection Protection
+
+The system employs `mysqli prepared statements` for all database interactions, which eliminates most risks of SQL injection. There is no raw SQL query used anywhere, and moreover, all data input by user is verified and checked before being used in any application functionality. Hence further hardening the security measures.
```php
-$serverName = "localhost";
-$dBUsername = "root";
-$dBPassword = "examplePassword";
-$dBName = "loginsystem";
+// example database query
-$conn = mysqli_connect($serverName, $dBUsername, $dBPassword, $dBName, 3307);
+$sql = "DELETE FROM auth_tokens WHERE user_email=? AND auth_type='account_verify';";
+$stmt = mysqli_stmt_init($conn);
+if (!mysqli_stmt_prepare($stmt, $sql)) {
-if (!$conn)
-{
- die("Connection failed: ". mysqli_connect_error());
+ $_SESSION['ERRORS']['sqlerror'] = 'SQL ERROR';
+ header("Location: ../");
+ exit();
+}
+else {
+
+ mysqli_stmt_bind_param($stmt, "s", $email);
+ mysqli_stmt_execute($stmt);
}
```
-> The port number does not need to be changed under normal circumstances, but if you are running into a problem or the server stack is installed on another port, feel free to change it, but do so carefully.
-3. Edit the `email-server.php` file in the `includes` folder and change the variables accordingly:
+#### Header & Email Injection Protection
+
+The application uses the `_cleaninjections()` function defined in the `assets/includes/security_functions.php` to filter and validate data. Any and all data entered by users for any functionality is checked for header injection before being used. The filter functions remove any character(s) that may prove to be a threat, thus rendering any malicious script or data harmless.
- * `$SMTPuser` : email address on `gmail`
- * `$SMTPpwd` : email address password
- * `SMTPtitle` : hypothetical company's name
+On all back functionality, each and every single value being passed in the POST body is checked for possible injection. The same holds for emails, preventing users to add additional email-specific fields in it. This greatly reduces the risk of Header or Email injection.
```php
-$SMTPuser = 'klik.official.website@gmail.com';
-$SMTPpwd = 'some-example-password';
-$SMTPtitle = "KLiK inc.";
-```
-> This step is mainly for setting up an email account to enable the `contact` and `password reset system`, all of which require mailing.
+// Securing against Header Injection
-#### Getting started
-The database already contains two pre-made accounts for you to explore around with. If not sufficient, head over to the `signup page` and start making new accounts.
-##### Existing Accounts:
-```
-username: admin
-password: admin
-```
+foreach($_POST as $key => $value){
+
+ $_POST[$key] = _cleaninjections(trim($value));
+}
```
-username: user
-password: user
+
+#### CSRF Protection
+
+There are also heavy protection measures against CSRF attempts. A secure `csrf token` is generated on session start, and sent as a hidden value in the post body for all forms, where it is validated and only allows the script to proceed if the validation succeeds. The csrf protection works for all forms regardless of whether the user is logged in or not.
+
+The csrf token is handled by the functions present in the `assets/includes/security_functions.php` file. The token is encrypted to keep it from being extracted and exploited.
+
+```php
+// csrf token generation
+
+function generate_csrf_token() {
+ if (!isset($_SESSION)) {
+ session_start();
+ }
+ if (empty($_SESSION['token'])) {
+ $_SESSION['token'] = bin2hex(random_bytes(32));
+ }
+}
```
-> **Note:** The GUI files are in the `root directory`, and the `backend files` are present in the `includes` folder. The main HTML structuring files are the `HTML-head.php` and `HTML-footer.php`, which also reside in the includes folder
+#### Secure Remember-me Cookie
-## Features
+The cookie set for the `remember-me` feature uses encrypted `selector` and `validator` values that keep it from being interfered with or exploited. The token itself is not stored as-is in the database as well, eliminating risk of info leak in case of database breach. The authentication token and selector are stored in the `auth_tokens` table in the database.
-* [Registration / Signup System](#registration-signup-system)
-* [Login System](#login-system)
-* [Profile System](#profile-system)
-* [Profile Editing System](#profile-editing-system)
-* [Contact System](#contact-system)
+#### Secure Account Activation & Password Reset
+The features for account activation and password reset both use a link sent via email which also uses encrypted encrypted `selector` and `validator` values. All three features, namely remember-me cookies, account activation and password reset use the `auth_tokens` table to store the encrypted tokens and selector. Each of the tokens have an expiry time, meaning that once expired, they cannot be used. All tokens are deleted on being used, so they cannot be used over and over again.
-## Components
+### Login | Signup
-#### Languages
-```
-PHP 5.6.40
-SQL 14.0
-HTML5
-CSS3
-```
+The system supports a default and secure login and signup system. The user can signup to make a new account, and then will be prompted to login to the new account with his credentials. The user can also set his profile image on signup. To make a new account, the user must set a unique username and email. There are also additional information fields available, but they are optional and can be skipped.
-#### Development Environment
-```
-WampServer Stack 3.0.6
-Windows 10
-```
+The login system also supports a `remember me` feature, which will keep the user logged in for a certain time (currently a month) even if the browser or system is turned off.
-#### Database
-```
-MySQL Database 8.0.13
-```
+### User Profile | Profile Editing
-#### DBMS
-```
-phpMyAdmin 4.8.3
-```
+The system supports a proper user profile accessible on registration. Currently only a few extra-information fields have been put into the database, namely the user's first name, last name, gender, profile headline and bio. These are only meant to showcase the use of additional user information, and as such, are optional fields and can be skipped during signup. The user also has a profile image that he can choose/set at signup and can also update it later.
-#### API
-```
-MySQLi APIs
+There is also a profile update system, in which the user can update all of his information. In current system, the user must have a unique username and email, so the system confirms the availability of new username or email if they were changed for profile updation.
+
+> The system can also update the user's profile image, and deletes the old image afterwards to prevent useless images piling up in the server's file system.
+
+There is also a separate check for the password updation, which requires the user to input the current password and confirm the new password as well. Once password is updated, a notification email is sent to the user on his (now) current email address.
+
+### Email Verification | Account Activation
+
+On signup / registration, the system gives the user access to the new account, but with limited access. On successful signup, a confirmation mail is sent to the user's email, with a secure verification link. Once the link is accessed, the account is unlocked/activated and the user can access all the additional functionalities. The link is created with encrypted `selector` and `token` fields, while the respective entry is created in the database for verification for whenever the link is accessed.
+
+The database fields which determines if the account is verified/unlocked or not is the `verified_at` column. If the column is NULL, then the account is not verified. The verification email sent to the user sets that column value to the current Date/Time at that point, hence unlocking the account.
+
+On login, the script checks the `verified_at` column and sets the value of `$_SESSION['auth']` accordingly. If the user is unverified, he is redirected to the `APPLICATION_PATH/verify` page where he is prompted to activate his account with the sent email. In case that the user did not receive the email, an option is provided for him to resend that email. Once the account is activated and the page is refreshed, the user will be redirected away from the verify page to the default `APPLICATION_PATH/home` page.
+
+### Password Resetting
+
+There is also a password reset system, or by well known terminology, a `forgot password?` feature. Link to that feature is present on the login page below the login form, and requires that the user input his email with which he had signed up. If the email is not present in the database, the request is ignored, and if it is, a highly secure confirmation email is sent to the user. The user can access the link provided in that email, which will force him to recreate his password, and once done, will prompt the user to log in with the new credentials.
+
+The confirmation / reset email uses the `auth_tokens` table in the database to create a secure `selector` and `token` for the user, then appends them to the reset link after encryption. The token has a certain expiry time (currently `1 hour`), after which it becomes invalid.
+
+### Auth Verification
+
+The system handles authentication checks with the help of specific functions stored in `assets/includes/auth_functions.php`. There are multiple functions to determine current state of the user. And the checks can be applied to any page in just one like by simply calling the respective function at the top of the file.
+
+The available authentication functions (as of right now) are:
+
+```php
+function check_logged_in() { ... }
+function check_logged_in_butnot_verified() { ... }
+function check_logged_out() { ... }
+function check_verified() { ... }
+function check_remember_me() { ... }
+function force_login($email) { ... }
```
-#### Frameworks and Libraries
+Each page can be set to accept users in a certain state by simply calling the respective function at the top of the file.
+
+```php
+// Home page, only meant for verified users
+
+define('TITLE', "Home");
+include '../assets/layouts/header.php';
+check_verified();
```
-BootStrap v4.2.1
+
+### Remember Me Feature
+
+The system's login system has a `remember me` feature, which keeps the user logged in even if the browser or device is shutdown. During logging in, if the user checked the `rememer me` option, the feature sets a secure cookie with encrypted `selector` and `token` values, and creates the respective values in the `auth_tokens` table in the database.
+
+```php
+$selector = bin2hex(random_bytes(8));
+$token = random_bytes(32);
+setcookie(
+ 'rememberme',
+ $selector.':'.bin2hex($token),
+ time() + 864000,
+ '/',
+ NULL,
+ false,
+ true
+);
```
-#### External Plugins
+To validate the cookie, the system uses the `check_remember_me()` function in the `assets/includes/auth_functions.php` file. Once the encrypted values are verified against the ones stored in the database, it calls the `force_login()` method which simply creates the relevant session variables for the user and logs him/her into the application.
+
+### GLOBAL temporary ERROR & STATUS values
+
+The project uses a global ERROR and STATUS variable for any errors and page status, assigned as an associative array to `$_SESSION['ERRORS']` and `$_SESSION['STATUS']`, with the keys being error/status names and values being the messages. These values are temporary, meaning that the error values disappear when the page is refreshed, returning the page to its original state. This keeps the URLs clean (by not using URL queries) and the associative array means that on occurence of any error, a new key with any name could be created and given the error message as the value, and could easily be dealt with on the frontend files as well.
+
+For example, an example of creating an error and assigning it to `$_SESSION['ERRORS']` in a backend script is:
+
+```php
+// checking email availability
+
+if ($_SESSION['email'] != $email && !availableEmail($conn, $email)) {
+
+ $_SESSION['ERRORS']['emailerror'] = 'email already taken';
+ header("Location: ../");
+ exit();
+}
```
-[PHPMailer 6.0.6](https://github.com/PHPMailer/PHPMailer)
+
+Similarly, this is how the error can be accessed on the visible frontend file:
+
+```html
+// profile update form with email field
+
+
+
+
+
+
+
+
```
-> This was used for creating a `mail server` on `Windows localhost`, since there is not one like in Linux. This plugin was used for the sending and receiving of emails on localhost, this is not needed on a live domain
-
-## Details
-
-> Details of important Features of the Application
-
-### Registration / Signup System
-
-* A `status icon` in the top left corner shows online or logged out status
-* registration is done through the `signup` page.
-* `username` cannot be changed after signing up, since i thought it would be an exploitable weakness
-* `email` required for registration.
-* Password needs to be re-entered for additional confirmation
-* Passwords `encrypted` before being stored in database so even owners donot have access to them
-* User can set a `profile image` at signup. In case they dont, their profile image is set to a default image.
-
-> currently the upload image button does not give a visible response on clicking and uploading an image, but it does work. It is purely a design matter and not a back-end issue
-
-* There are also additional information fields that are `optional`, i.e; a user can signup without setting them.
-* Optional fields are `gender`, `full name`, `profile headline` and `bio`
-* Implemented several `authentication methods` to verify user info before registering him.
-* Authentication checks for:
- * `empty fields`
- * `invalid username or email`
- * `password mismatch`
- * `wrong profile image error`
- * `SQL errors`
- * `internal server errors`
-
-### Login System
-
-* `username` and `password` required for logging in.
-* Authentication checks to return valid error messages.
-* Authentication checks for:
- * `wrong username`
- * `wrong password`
-
-### Profile System
-
-* Each is assigned a `user profile` on registration.
-* Profile can be accessed through the `menu options` which become visible after logging in or the `link` beneath the profile image on the right.
-* Profile page displays all of the User's information, except (naturally) for the password.
-* Displayed information:
- * `profile image`
- * `username`
- * `full name`
- * `gender`
- * `headline`
- * `bio`
-* Profile page cannot be accessed without logging in.
-* Signup page cannot be page `after logging in`.
-
-### Profile Editing System
-
-* User can edit his profile information with the help of the `profile editing system`
-* Profile Editing page can be accessed from `menu option` or `link` below profile image on the right
-* `username` cannot be changed
-* Profile Editing already has the existing information so user does not have to type everything all over again if he merely wishes to slightly edit current information.
-* Current password required for changing password.
-* Changing password also requires confirmation / re-entering of new password.
-* user profile image can also be changed.
-* Authentication checks for:
- * `empty fields`
- * `invalid information`
- * `wrong current password`
- * `new password mismatch`
- * `image upload errors`
### Contact System
-* contact system is accessible with or without logging in
-* uses `PHPMailer` to create an email server with which it sends emails.
-* options for subscribing to newsletter (or basically any additional option for contacting)
-* does not require PHPMailer on live domain (only required on windows localhost)
+The application has a simple contact system that uses the mail server setup in `assets/setup/env.php` to send an email to itself, containing the sender information as well as the message. The contact form is accessible on being logged in or not. When not logged it, it requires the sender name and email. And when logged in, it uses the current user's username and email to send the contact mail.
+The system uses an email template to send the emails, which can be updated, improved or replaced.
-### Security
+## Future Improvements
-* `Password hashing` before storing in database.
-* Filtering of information obtained from `$_GET` and `$_POST` methods to prevent `header injection`.
-* Implementation of `MySQLi Prepared Statements` for **advanced** database security.
+There are some things i have in mind for adding to this project later on. However, that is a commitment I may or may not be able to stay true to. If any of you people end up improving on this in any way, it would be an honor to have you contribute to this project.
- **Example:**
-```php
-$sql = "select uidUsers from users where uidUsers=?;";
- $stmt = mysqli_stmt_init($conn);
- if (!mysqli_stmt_prepare($stmt, $sql))
- {
- header("Location: ../signup.php?error=sqlerror");
- exit();
- }
- else
- {
- mysqli_stmt_bind_param($stmt, "s", $userName);
- mysqli_stmt_execute($stmt);
- mysqli_stmt_store_result($stmt);
- }
-```
+That being said, these are some possible improvements I have in my mind right now:
-### KLiK - Social Media Website
+- OAuth login. (login via 3rd party applications like gmail or github etc).
+- Requirement for mail confirmation with new address for email update.
+- Keep a `data` column in `users` table in the database with JSON encoded text and move extra fields like first name, last name, bio and headline etc into it. That will make the table more manageable and create more flexibility to add as many data fields as needed in JSON format.
+- Raw functionality of a simple admin dashboard, with a simple list of all users with functionality to:
+ - Search for a user.
+ - Filter users.
+ - Delete users.
+ - Activate/ deactivate users (By manually setting their `verified_at` column to NULL or current date/time).
+ - Create users.
+ - Update non-critical (and maybe critical too) information for users.
+- Option to delete account, with confirmation via email being necessary for that.
+- Cover images for users.
+- User levels assigned upon registration (admin, normal-user etc) and permissions system for that.
+- Sending emails via `AJAX scripts` in the background to decrease script execution times.
+- Realtime password strength checker with `JQuery`.
+- One universal file with validation rules for all user inputs.
-Check out the complete project for this login system. [KLiK](https://github.com/msaad1999/KLiK-SocialMediaWebsite) is a complete Social Media website, along with a Complete Login/Registration system, Profile system, Chat room, Forum system and Blog/Polls/Event Management System.
+## Contribution Guidelines
-> Check out [KLiK here](https://github.com/msaad1999/KLiK-SocialMediaWebsite)
+If you want to contribute to this project, please refer to the [Contributing Guidelines](CONTRIBUTING.md).
-
-
-
+## License
+
+This project has been assigned the [MIT License](LICENSE), so go ahead and feel free to use any and/or all parts of this system and to build on it. Although I would still insist that if you do end up improving this, do accidentally contribute, it would be an honour.
+
+## Personal Note
-> Do star my projects! :)
+Hey there, this was a small little side project, which was a great learning experience for me and influenced me to focus more on bigger, more complex frameworks. I have now moved on to Laravel development, and if you think you're adding too much to this or any other raw PHP system, it may be high time for you to move onto a better framework like Laravel as well.
-> If you liked my work, please show support by `starring` the repository! It means a lot to me, and is all im asking for.
+> As mentioned before, in case that you do actually appreciate this project or the effort put into it, you're probably too far away for me to demand a good cup of coffee, so for now, how about a star? And if you're feeling great, how about a contribution?
\ No newline at end of file
diff --git a/_git assets/cover.png b/_git assets/cover.png
deleted file mode 100644
index f56537c..0000000
Binary files a/_git assets/cover.png and /dev/null differ
diff --git a/_git assets/klik.png b/_git assets/klik.png
deleted file mode 100644
index c7ab502..0000000
Binary files a/_git assets/klik.png and /dev/null differ
diff --git a/assets/css/app.css b/assets/css/app.css
new file mode 100644
index 0000000..0dacb97
--- /dev/null
+++ b/assets/css/app.css
@@ -0,0 +1,268 @@
+html,
+body {
+ overflow-x: hidden;
+ height: 100%;
+}
+
+.box-shadow {
+ box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
+}
+
+.form-auth {
+ margin-top: 10%;
+ width: 100%;
+ padding: 15px;
+}
+
+.form-auth .checkbox {
+ font-weight: 400;
+}
+
+.form-auth .form-control {
+ position: relative;
+ box-sizing: border-box;
+ height: auto;
+ padding: 10px;
+ font-size: 16px;
+}
+
+.form-auth .form-control:focus {
+ z-index: 2;
+}
+
+.form-auth input[type="email"] {
+ margin-bottom: -1px;
+}
+
+.form-auth input[type="password"] {
+ margin-bottom: 10px;
+}
+
+
+/* --------------User Image Upload---------------------- */
+
+.avatar-upload {
+ text-align: center;
+ display: inline-block;
+}
+
+.avatar-edit {
+ top: 150px;
+ margin-right: -125px;
+ margin-top: -40px;
+}
+
+.avatar-upload .avatar-edit input {
+ display: none;
+}
+
+.avatar-upload .avatar-edit input+label {
+ width: 34px;
+ height: 34px;
+ margin-bottom: 0;
+ border-radius: 100%;
+ z-index: 1000000;
+ background: blue;
+ border: 1px solid transparent;
+ box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.12);
+ cursor: pointer;
+ font-weight: normal;
+ transition: all 0.2s ease-in-out;
+}
+
+.avatar-upload .avatar-edit input+label:hover {
+ background: #757575;
+ border-color: #757575;
+}
+
+.avatar-upload .avatar-edit input+label:after {
+ color: #757575;
+ position: absolute;
+ top: 5px;
+ left: 1px;
+ right: 0;
+ text-align: center;
+ margin: auto;
+}
+
+.avatar-upload .avatar-preview {
+ width: 162px;
+ height: 162px;
+ position: relative;
+ border-radius: 100%;
+ box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.3);
+}
+
+.avatar-upload .avatar-preview>div {
+ width: 100%;
+ height: 100%;
+ border-radius: 100%;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
+.navbar-img {
+ width: 30px;
+ height: 30px;
+ object-fit: cover;
+ border-radius: 50%;
+}
+
+
+/* --------------Profile card---------------------- */
+
+.card-profile {
+ width: 230px;
+ min-height: 330px;
+ margin: 50px auto;
+ /* background-color: #e6e5e1; */
+ border-radius: 0;
+ border: 0;
+}
+
+.card-profile .card-img-top {
+ border-radius: 0;
+}
+
+.card-img-profile {
+ width: 110px;
+ height: 110px;
+ object-fit: cover;
+ border-radius: 50%;
+ margin-top: -45px;
+ margin-bottom: 35px;
+ border: 2px solid #ffffff;
+}
+
+.edit-profile {
+ position: absolute;
+ right: 10px;
+ top: 110px;
+}
+
+.card-img-profile {
+ transition: transform .2s;
+}
+
+.card-img-profile:hover {
+ transform: scale(1.02);
+}
+
+.card-profile .card-title {
+ margin-bottom: 30px;
+}
+
+.card-profile .card-title small {
+ display: block;
+ font-size: .6em;
+ margin-top: .2em;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+.card-profile .fa {
+ color: grey;
+}
+
+.card-profile .fa:hover {
+ color: blue;
+}
+
+
+/* --------------Footer---------------------- */
+
+footer {
+ margin-top: 100px;
+}
+
+#myFooter {
+ background-color: #3c3d41;
+ color: white;
+ padding-top: 30px;
+}
+
+#myFooter .footer-copyright {
+ background-color: #333333;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ text-align: center;
+}
+
+#myFooter .row {
+ margin-bottom: 60px;
+}
+
+#myFooter .navbar-brand {
+ margin-top: 45px;
+ height: 65px;
+}
+
+#myFooter .footer-copyright p {
+ margin: 10px;
+ color: #ccc;
+}
+
+#myFooter .footer-copyright a:hover {
+ color: #d84b6b;
+}
+
+#myFooter ul {
+ list-style-type: none;
+ padding-left: 0;
+ line-height: 1.7;
+}
+
+#myFooter h5 {
+ font-size: 18px;
+ color: white;
+ font-weight: bold;
+ margin-top: 30px;
+}
+
+#myFooter h2 a {
+ font-size: 50px;
+ text-align: center;
+ color: #fff;
+}
+
+#myFooter a {
+ color: #d2d1d1;
+ text-decoration: none;
+}
+
+#myFooter a:hover,
+#myFooter a:focus {
+ text-decoration: none;
+ color: white;
+}
+
+#myFooter .social-networks {
+ text-align: center;
+ padding-top: 30px;
+ padding-bottom: 16px;
+}
+
+#myFooter .social-networks a {
+ font-size: 32px;
+ color: #f9f9f9;
+ padding: 10px;
+ transition: 0.2s;
+}
+
+#myFooter .social-networks a:hover {
+ text-decoration: none;
+ color: #d84b6b;
+}
+
+#myFooter .btn {
+ color: white;
+ background-color: #d84b6b;
+ border-radius: 20px;
+ border: none;
+ width: 150px;
+ display: block;
+ margin: 0 auto;
+ margin-top: 10px;
+ line-height: 25px;
+}
\ No newline at end of file
diff --git a/assets/images/README_cover.png b/assets/images/README_cover.png
new file mode 100644
index 0000000..8852983
Binary files /dev/null and b/assets/images/README_cover.png differ
diff --git a/assets/images/banner.png b/assets/images/banner.png
new file mode 100644
index 0000000..8a5c646
Binary files /dev/null and b/assets/images/banner.png differ
diff --git a/assets/images/contribution_cover.png b/assets/images/contribution_cover.png
new file mode 100644
index 0000000..3ae21e3
Binary files /dev/null and b/assets/images/contribution_cover.png differ
diff --git a/assets/images/favicon.png b/assets/images/favicon.png
new file mode 100644
index 0000000..18cb688
Binary files /dev/null and b/assets/images/favicon.png differ
diff --git a/assets/images/logo.png b/assets/images/logo.png
new file mode 100644
index 0000000..e3a485f
Binary files /dev/null and b/assets/images/logo.png differ
diff --git a/assets/images/logo_blackbg.png b/assets/images/logo_blackbg.png
new file mode 100644
index 0000000..30c3746
Binary files /dev/null and b/assets/images/logo_blackbg.png differ
diff --git a/assets/images/logonotext.png b/assets/images/logonotext.png
new file mode 100644
index 0000000..b3fd0dd
Binary files /dev/null and b/assets/images/logonotext.png differ
diff --git a/assets/images/logonotextwhite.png b/assets/images/logonotextwhite.png
new file mode 100644
index 0000000..dd91297
Binary files /dev/null and b/assets/images/logonotextwhite.png differ
diff --git a/assets/images/logowhite.png b/assets/images/logowhite.png
new file mode 100644
index 0000000..a8155e7
Binary files /dev/null and b/assets/images/logowhite.png differ
diff --git a/assets/images/profile_banner.jpg b/assets/images/profile_banner.jpg
new file mode 100644
index 0000000..fbffae9
Binary files /dev/null and b/assets/images/profile_banner.jpg differ
diff --git a/assets/images/repo_gitklik.png b/assets/images/repo_gitklik.png
new file mode 100644
index 0000000..c3e8d3d
Binary files /dev/null and b/assets/images/repo_gitklik.png differ
diff --git a/assets/images/repo_klik.png b/assets/images/repo_klik.png
new file mode 100644
index 0000000..0c1a019
Binary files /dev/null and b/assets/images/repo_klik.png differ
diff --git a/assets/images/repo_loginsystem.png b/assets/images/repo_loginsystem.png
new file mode 100644
index 0000000..565e9df
Binary files /dev/null and b/assets/images/repo_loginsystem.png differ
diff --git a/assets/includes/auth_functions.php b/assets/includes/auth_functions.php
new file mode 100644
index 0000000..da47660
--- /dev/null
+++ b/assets/includes/auth_functions.php
@@ -0,0 +1,174 @@
+= NOW() LIMIT 1;";
+ $stmt = mysqli_stmt_init($conn);
+
+ if (!mysqli_stmt_prepare($stmt, $sql)) {
+
+ // SQL ERROR
+ return false;
+ }
+ else {
+
+ mysqli_stmt_bind_param($stmt, "s", $selector);
+ mysqli_stmt_execute($stmt);
+ $results = mysqli_stmt_get_result($stmt);
+
+ if (!($row = mysqli_fetch_assoc($results))) {
+
+ // COOKIE VALIDATION FAILURE
+ return false;
+ }
+ else {
+
+ $tokenBin = hex2bin($validator);
+ $tokenCheck = password_verify($tokenBin, $row['token']);
+
+ if ($tokenCheck === false) {
+
+ // COOKIE VALIDATION FAILURE
+ return false;
+ }
+ else if ($tokenCheck === true) {
+
+ $email = $row['user_email'];
+ force_login($email);
+
+ return true;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/includes/datacheck.php b/assets/includes/datacheck.php
new file mode 100644
index 0000000..c30f3d3
--- /dev/null
+++ b/assets/includes/datacheck.php
@@ -0,0 +1,51 @@
+ 0) {
+
+ return false;
+ } else {
+
+ return true;
+ }
+ }
+}
+
+function availableEmail($conn, $email){
+
+ $sql = "select id from users where email=?;";
+ $stmt = mysqli_stmt_init($conn);
+ if (!mysqli_stmt_prepare($stmt, $sql)) {
+
+ return $_SESSION['ERRORS']['scripterror'] = 'SQL error';
+ }
+ else {
+
+ mysqli_stmt_bind_param($stmt, "s", $email);
+ mysqli_stmt_execute($stmt);
+ mysqli_stmt_store_result($stmt);
+ $resultCheck = mysqli_stmt_num_rows($stmt);
+
+ if ($resultCheck > 0) {
+
+ return false;
+ } else {
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/includes/security_functions.php b/assets/includes/security_functions.php
new file mode 100644
index 0000000..2ecf900
--- /dev/null
+++ b/assets/includes/security_functions.php
@@ -0,0 +1,60 @@
+';
+}
+
+function verify_csrf_token() {
+
+ generate_csrf_token();
+
+ if (!empty($_POST['token'])) {
+
+ if (hash_equals($_SESSION['token'], $_POST['token'])) {
+
+ return true;
+ }
+ else {
+
+ return false;
+ }
+ }
+ else {
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/assets/js/app.js b/assets/js/app.js
new file mode 100644
index 0000000..e69de29
diff --git a/assets/layouts/footer.php b/assets/layouts/footer.php
new file mode 100644
index 0000000..76dedb6
--- /dev/null
+++ b/assets/layouts/footer.php
@@ -0,0 +1,80 @@
+
+
+
+