The following code works, I just want to know if there are any suggestions as to how I can make it better or more secure.
config.php:
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'database');
?>
connect.php:
<?php
class DB_Connect {
private $con;
public function connect() {
require_once dirname(__FILE__) . '/config.php';
$this->con = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
return $this->con;
}
}
?>
functions.php:
<?php
class DB_Functions {
private $con;
function __construct() {
require_once dirname(__FILE__) . '/../database/connect.php';
$db = new DB_Connect();
$this->con = $db->connect();
}
function __destruct() {
}
public function storeUser($username, $email, $password) {
$uuid = uniqid('', true);
$email_code = md5($_POST['username'] + microtime());
$hash = $this->hashSSHA($password);
$encrypted_password = $hash['encrypted'];
$salt = $hash['salt'];
$stmt = $this->con->prepare("INSERT INTO users(unique_id, username, email, email_code, encrypted_password, salt, created_at) VALUES(?, ?, ?, ?, ?, ?, NOW())");
$stmt->bind_param('ssssss', $uuid, $username, $email, $email_code, $encrypted_password, $salt);
$result = $stmt->execute();
$stmt->close();
if ($result) {
$stmt = $this->con->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param('s', $email);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
$stmt->close();
return $user;
} else {
return false;
}
}
public function getUserByUsernameAndPassword($username, $password) {
$stmt = $this->con->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param('s', $username);
if ($stmt->execute()) {
$user = $stmt->get_result()->fetch_assoc();
$stmt->close();
$salt = $user['salt'];
$encrypted_password = $user['encrypted_password'];
$hash = $this->checkhashSSHA($salt, $password);
if ($encrypted_password == $hash) {
return $user;
}
} else {
return NULL;
}
}
public function doesUserEmailExist($email) {
$stmt = $this->con->prepare("SELECT email FROM users WHERE email = ?");
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->close();
return true;
} else {
$stmt->close();
return false;
}
}
public function doesUsernameExist($username) {
$stmt = $this->con->prepare("SELECT username FROM users WHERE username = ?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->close();
return true;
} else {
$stmt->close();
return false;
}
}
public function isActive($username) {
$stmt = $this->con->prepare("SELECT COUNT user_id FROM users WHERE username = ? AND active = 1");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->close();
return true;
} else {
$stmt->close();
return false;
}
}
public function hashSSHA($password) {
$salt = sha1(rand());
$salt = substr($salt, 0, 10);
$encrypted = base64_encode(sha1($password . $salt, true) . $salt);
$hash = array('salt' => $salt, 'encrypted' => $encrypted);
return $hash;
}
public function checkhashSSHA($salt, $password) {
$hash = base64_encode(sha1($password . $salt, true) . $salt);
return $hash;
}
}
?>
index.php:
<?php
?>
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Website</title>
<link href='https://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/main.css">
</head>
<body background='img/main_bg.jpg'>
<div id="header">
<div id="login-div">
<form action="login.php" method="post">
<ul id="login">
<li>
<input type="text" name="username" placeholder="Username">
</li>
<li>
<input type="password" name="password" placeholder="Password">
</li>
<li>
<input type="submit" value="Login">
</li>
</ul>
</form>
</div>
</div>
<div id="container">
<h1 id="main-title">Website</h1>
<div id="register-div">
<form action="register.php" method="post">
<ul id="register">
<li>
<input type="text" name="username" placeholder="Username">
</li>
<li>
<input type="text" name="email" placeholder="Email">
</li>
<li>
<input type="password" name="password" placeholder="Password">
</li>
<li>
<input type="password" name="confirm-password" placeholder="Confirm Password">
</li>
<li>
<input type="checkbox" id="agreement" name="agreement" value="agreement">
<label for="agreement" id="agreement-label">I have read and agree to the terms of service.</label>
</li>
<li>
<input type="submit" value="Register">
</li>
</ul>
</form>
</div>
</div>
<div id="footer">
FOOTER
</div>
</body>
</html>
register.php:
<?php
require_once dirname(__FILE__) . '/includes/functions/functions.php';
$db = new DB_Functions();
$errors = array();
if (!empty($_POST['username']) && !empty($_POST['email']) && !empty($_POST['password']) && !empty($_POST['confirm-password'])) {
if (isset($_POST['agreement'])) {
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$confirm_password = $_POST['confirm-password'];
if ($password == $confirm_password) {
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$errors[] = 'You must use a valid email address.';
}
if ($db->doesUserEmailExist($email)) {
$errors[] = 'The email ' . $email . ' is already in use.';
}
if (preg_match("/\\s/", $username) == true) {
$errors[] = 'Your username cannot contain spaces.';
}
if ($db->doesUsernameExist($username)) {
$errors[] = 'The username ' . $username . ' is already in use.';
}
if (strlen($password) < 6) {
$errors[] = 'Password must contain at least 6 characters.';
}
} else {
$errors[] = 'Your passwords do not match.';
}
} else {
$errors[] = 'You must accept terms agreement before registering.';
}
} else {
$errors[] = 'All fields are required.';
}
if (isset($_GET['success']) && empty($_GET['success'])) {
echo 'YOU HAVE REGISTERED SUCCESSFULLY';
} else {
if (!empty($_POST) && empty($errors)) {
$user = $db->storeUser($username, $email, $password);
if ($user) {
header('Location: register.php?success');
exit();
}
} else if (!empty($errors)) {
echo json_encode($errors);
}
}
?>
login.php:
<?php
require_once dirname(__FILE__) . '/includes/functions/functions.php';
$db = new DB_Functions();
$errors = array();
if (!empty($_POST['username']) && !empty($_POST['password'])) {
if (!$db->doesUsernameExist($_POST['username'])) {
$errors[] = 'We can\'t find this username. Have you registered?';
} else {
if (!$db->getUserByUsernameAndPassword($_POST['username'], $_POST['password'])) {
$errors[] = 'The username/password combination is incorrect.';
} else {
if (isActive($username)) {
$user = $db->getUserByUsernameAndPassword($_POST['username'], $_POST['password']);
$_SESSION['user_id'] = $user['user_id'];
header('Location: home.php');
exit();
} else {
$errors[] = 'You have not activated your account.';
}
}
}
} else {
$errors[] = 'Username and password are required.';
}
echo json_encode($errors);
?>