Logging in and spaces are added

master
Eirik Th S 2021-04-27 02:56:39 +02:00
parent 646fb07646
commit 76e7a87ee0
10 changed files with 472 additions and 137 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.idea/
webdata/config.php
temp/
css/archive/*

View File

@ -11,7 +11,7 @@
<h1 class="headline text-center">Grocery Assist</h1>
<div class="container-sm" style="padding-top: 5px;">
<div class="card-group" style="text-align: center;">
<div class="card-group" style="text-align: center;">
<div class="card h-100" style="">
<a href='./plan'>
@ -24,7 +24,7 @@
</div>
<div class="card h-100" style="">
<img src="#" class="card-img-top" alt="Plan"></a>
<img src="#" class="card-img-top" alt="Review">
<div class="card-body">
<h5 class="card-title">Review</h5>
<p class="card-text">Coming soon</p>
@ -32,8 +32,8 @@
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,4 +1,49 @@
<?php require 'webdata/init.php'; ?><!DOCTYPE html>
<?php
require 'webdata/init.php';
$returnToPage = "../";
if(isset($_POST['referrerPage'])){
$returnToPage = $_POST['referrerPage'];
}
else if(isset($_SERVER['HTTP_REFERER'])){
$returnToPage = $_SERVER['HTTP_REFERER'];
}
if(stristr($returnToPage, "login.php") || stristr($returnToPage, "register.php")){
$returnToPage = "./";
}
if( checkLogin() ){
header("Location: ".$returnToPage);
}
$msg = [];
if(isset($_GET['thank'])){
$msg[] = "Thank you for registering. Please log in to continue!";
}
if(isset($_POST) && !empty($_POST)){
$db = database();
$data = [];
foreach($_POST as $key => $value){
if(($data[$key] = filter($value)) === false){
print_r($value);
echo "Failed to sanitize: `".$key."`: ".$value." \t-\t type: ".gettype($value)."\n";
}
}
$err = loginUser($data['loginEmail'], $data['loginPwd']);
if($err === true){
header("Location: ".$returnToPage);
die();
}
}
//echo PwdGen("Passord123", true);
?><!DOCTYPE html>
<html lang="en">
<head>
<?=getHtmlHeaders();?>
@ -7,24 +52,47 @@
<body id='plan'>
<?php include 'webdata/navbar.php'; ?>
<div class='container-sm'>
<div class='container-sm' style="max-width: 540px;">
<h1 class="headline text-center">Login</h1>
<form action="#" method="POST">
<?php if(!empty($err)){
foreach($err as $e){
echo "<div class='alert alert-danger' role='alert'>$e</div>";
}
}
if(!empty($msg)){
foreach($msg as $m){
echo "<div class='alert alert-success' role='alert'>$m</div>";
}
}
?>
<form action="login.php" method="POST">
<input type="hidden" name="referrerPage" value="<?=$returnToPage;?>">
<div class="form-group row">
<label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3">
<input type="email" class="form-control" name="loginEmail" id="inputEmail3">
</div>
</div>
<div class="form-group row">
<label for="inputPassword3" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3">
<input type="password" class="form-control" name="loginPwd" id="inputPassword3">
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck">
I agree to save a temporary cookie in my browser for the logged in functions to work.
</label>
</div>
<div class="form-group row">
<button type="submit" class="btn btn-primary mb-3">Login</button>
</div>
</form>
<p>Do you not have an account? <a href="register.php">Register</a> </p>
</div>
</body>

View File

@ -1,8 +1,11 @@
<?php
require '../webdata/init.php';
$db = database();
if(!checkLogin()){
returns("Not logged in",2);
}
$user_id = 1;
$user_id = $_SESSION['user_id'];
header("Content-Type: application/json");
@ -23,6 +26,17 @@ foreach([$_GET, $_POST] as $request){
if(!empty($data) && isset($user_id)){
if(isset($data['plan'])){
if(isset($data['space'])){
$spaceID = verifySpaceID($data['space']);
}
else {
$spaceID = verifySpaceID();
}
if($spaceID == 0){
returns('No access to space', 3);
}
if($data['plan'] == 'saveStore'){
if($data['storeName'] == ""){
@ -114,23 +128,27 @@ if(!empty($data) && isset($user_id)){
}
else {
$sql = "SELECT `plan_store_id`, `name`, `created` FROM plan_store WHERE `user_id` = '$user_id'";
$sql = "SELECT `plan_store_id`, `name`, `created` FROM plan_store WHERE space_id = $spaceID";
$result = $db->query($sql);
while($stores = $result->fetch_assoc()){
if($result->num_rows > 0){
if($result2 = $db->query("SELECT `plan_item_id`, `name`, `price`, `amount` FROM plan_store_item WHERE `plan_store_id` = '$stores[plan_store_id]' ORDER BY pos")){
while($stores = $result->fetch_assoc()){
$stores['items'] = [];
if($result2->num_rows > 0){
$stores['items'] = $result2->fetch_all(MYSQLI_ASSOC);
if($result2 = $db->query("SELECT `plan_item_id`, `name`, `price`, `amount` FROM plan_store_item WHERE `plan_store_id` = '$stores[plan_store_id]' ORDER BY pos")){
$stores['items'] = [];
if($result2->num_rows > 0){
$stores['items'] = $result2->fetch_all(MYSQLI_ASSOC);
}
}
else {
returns($db->error,1);
}
}
else {
returns($db->error,1);
}
$returns[] = $stores;
$returns[] = $stores;
}
}
}
@ -158,25 +176,6 @@ function returns($content = 'Success', $code = 0){
}
function filter($data){
global $db;
if(gettype($data) !== "array"){
$data = trim(htmlentities(strip_tags($data)));
return $db->real_escape_string($data);
}
else if(gettype($data) == "array"){
foreach($data as $key => $value){
$data[$key] = filter($value);
}
return $data;
}
return false;
}
// class Store {
// private $storeID;
// private $storeName;
@ -198,24 +197,50 @@ function checkArgs($args){
return true;
}
function initStore($storeName){
function verifySpaceID($input = null): int{
global $db, $user_id;
if($input != null){
$countOwnerSQL = "SELECT count(0) FROM plan_space WHERE owner_id = $user_id AND space_id = $input";
$countMemberSQL = "SELECT count(0) FROM plan_space_member WHERE member_id = $user_id AND space_id = $input";
$verifyAccessSQL = "SELECT ($countOwnerSQL)+($countMemberSQL) verified;";
if(($verifyRes = $db->query($verifyAccessSQL)) && $verifyRes->fetch_row()[0] >= 1){
return $input;
}
return 0;
}
// CHECK FOR users own space
$selectSpaceQuery = $db->query("SELECT space_id FROM plan_space WHERE `owner_id` = '$user_id';");
// IF none, create a space
if($selectSpaceQuery->num_rows == 0){
$db->query("INSERT INTO plan_space SET owner_id = $user_id;");
return $db->insert_id;
}
return $selectSpaceQuery->fetch_row()[0];
}
function initStore($storeName){
global $db, $spaceID;
// CHECK IF STORE EXISTS
$storeCheckSql = "SELECT count(0) FROM plan_store WHERE `user_id` = '$user_id' AND `name` = '$storeName';";
$storeCheckSql = "SELECT count(0) FROM plan_store WHERE `space_id` = '$spaceID' AND `name` = '$storeName';";
if($storeCheckRes = $db->query($storeCheckSql)){
$matchingStores = $storeCheckRes->fetch_row()[0];
if($matchingStores == 1){
// $sql = "UPDATE plan_store SET null WHERE `user_id` = '$user_id' AND `name` = '$storeName';";
$sql = "SELECT plan_store_id FROM plan_store WHERE `user_id` = '$user_id' AND `name` = '$storeName';";
$sql = "SELECT plan_store_id FROM plan_store WHERE `space_id` = '$spaceID' AND `name` = '$storeName';";
if( ($res = $db->query($sql)) !== false){
return $res->fetch_assoc()["plan_store_id"];
}
}
else if($matchingStores == 0){
$sql = "INSERT INTO plan_store (user_id, `name`) VALUES ($user_id, '$storeName');";
$sql = "INSERT INTO plan_store (`space_id`, `name`) VALUES ($spaceID, '$storeName');";
if( $db->query($sql) !== false){
return $db->insert_id;
@ -227,14 +252,14 @@ function initStore($storeName){
}
function renameStore($storeID, $newName){
global $db, $user_id;
global $db, $spaceID;
$storeCheckSql = "SELECT count(0) FROM plan_store WHERE `user_id` = '$user_id' AND `name` = '$newName';";
$storeCheckSql = "SELECT count(0) FROM plan_store WHERE `space_id` = '$spaceID' AND `name` = '$newName';";
if(($storeCheckRes = $db->query($storeCheckSql)) && $storeCheckRes->fetch_row()[0] > 0){
return false;
}
$renameStoreSql = "UPDATE plan_store SET `name` = '$newName' WHERE `user_id` = '$user_id' AND `plan_store_id` = '$storeID';";
$renameStoreSql = "UPDATE plan_store SET `name` = '$newName' WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID';";
if($db->query($renameStoreSql) !== false){
return true;
@ -242,9 +267,9 @@ function renameStore($storeID, $newName){
}
function deleteStore($storeID, $storeName, $itemsLength){
global $db, $user_id;
global $db, $spaceID;
$verifyOwnerSql = "SELECT `plan_store_id` FROM plan_store WHERE `user_id` = '$user_id' AND `plan_store_id` = '$storeID' AND `name` = '$storeName'";
$verifyOwnerSql = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID' AND `name` = '$storeName'";
$getItemsSql = "SELECT `plan_store_id` FROM plan_store_item WHERE `plan_store_id` = ($verifyOwnerSql)";
if(($getItemsSql = $db->query($getItemsSql)) &&
@ -256,7 +281,7 @@ function deleteStore($storeID, $storeName, $itemsLength){
if($getItemsSql->num_rows > 0){
$deleteSql .= "DELETE FROM plan_store_item WHERE `plan_store_id` = '$storeID';\n";
}
$deleteSql .= "DELETE FROM plan_store WHERE `user_id` = '$user_id' AND `plan_store_id` = '$storeID' AND `name` = '$storeName';";
$deleteSql .= "DELETE FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID' AND `name` = '$storeName';";
if($db->multi_query($deleteSql)){
return true;
@ -267,9 +292,9 @@ function deleteStore($storeID, $storeName, $itemsLength){
}
function addItem($storeID, $name, $price){
global $db, $user_id;
global $db, $spaceID;
$verifyUserOwnershipSQL = "SELECT plan_store_id FROM plan_store WHERE `user_id` = '$user_id' AND plan_store_id = '$storeID'";
$verifyUserOwnershipSQL = "SELECT plan_store_id FROM plan_store WHERE `space_id` = '$spaceID' AND plan_store_id = '$storeID'";
$insertItemSQL = "INSERT INTO plan_store_item (`plan_store_id`, `pos`, `name`, `price`)
SELECT ($verifyUserOwnershipSQL), count(0)+1, '$name', $price FROM plan_store_item WHERE plan_store_id = '$storeID';";
@ -281,9 +306,9 @@ function addItem($storeID, $name, $price){
}
function remItem($storeID, $itemID, $price){
global $db, $user_id;
global $db, $spaceID;
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `user_id` = '$user_id' AND `plan_store_id` = '$storeID'";
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID'";
$findRowSql = "SELECT `plan_item_id` FROM plan_store_item WHERE `plan_store_id` = ($verifyUserOwnershipSQL) AND `plan_item_id` = '$itemID'";
$removeItemsql = "DELETE FROM plan_store_item WHERE `plan_item_id` = ($findRowSql) AND `price` = '$price';";
if($db->query($removeItemsql) && mysqli_affected_rows($db) > 0){
@ -293,9 +318,9 @@ function remItem($storeID, $itemID, $price){
}
function moveItem($storeID, $itemID, $afterID){
global $db, $user_id;
global $db, $spaceID;
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `user_id` = '$user_id' AND `plan_store_id` = '$storeID'";
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID'";
$getStoreItemsSQL = "SELECT plan_item_id FROM plan_store_item WHERE `plan_store_id` = ($verifyUserOwnershipSQL) ORDER BY if(pos is \N,1,0), pos;";
if($getStoreItems = $db->query($getStoreItemsSQL)){

View File

@ -46,10 +46,9 @@ class Store {
this.selector.find(".addItemForm").on('submit', ev => {
ev.preventDefault();
this.addItem($(ev.target).find('.newItemName').val(), $(ev.target).find('.newItemPrice').val())
.done(json => {
$(this).find('.newItemPrice').val(0);
$(this).find('.newItemName').val("").focus();
this.addItem($(ev.target).find('.newItemName').val(), $(ev.target).find('.newItemPrice').val()).done(json => {
this.selector.find('.newItemPrice').val(0);
this.selector.find('.newItemName').val("").focus();
});
});
@ -57,7 +56,7 @@ class Store {
this.selector.find('.editStoreName').one('click keyup', ev => { this.editNameFn(ev); });
this.selector.find('.removeStore').on('click keyup', ev => {
if(ev.type == 'click' || ev.keyCode == 13){
if(ev.type === 'click' || ev.keyCode === 13){
if(confirm("Are you sure you want to remove this store?")){ this.removeStore(); }
}
});
@ -72,7 +71,7 @@ class Store {
}
editNameFn(ev){
if(ev.type == 'click' || ev.keyCode == 13){
if(ev.type === 'click' || ev.keyCode === 13){
$(ev.target).parent().hide();
@ -81,7 +80,7 @@ class Store {
headerElem.html("<span style='display: none;'>"+orgHtml+"</span><form action='#' class='changeNameForm'><input type='text' class='newName' value='"+orgHtml+"'><input type='image' src='../icon/pencil-square.svg'></form>");
headerElem.find(".changeNameForm").on('submit keyup', ev2 => {
if(ev2.type == "submit"){
if(ev2.type === "submit"){
ev2.preventDefault();
@ -106,8 +105,8 @@ class Store {
resetEditNameFn(ev){
if(
(ev.type=="keyup" && ev.keyCode === 27) ||
ev.type != "keyup"
(ev.type==="keyup" && ev.keyCode === 27) ||
ev.type !== "keyup"
){
// cancel
let orgHtml = this.selector.find('.card-header span').html();
@ -124,20 +123,17 @@ class Store {
if(this.storeID === null){
this.getStoreID().done(json => { this.addItem(text, price); });
return;
return $.ajax();
}
let that = this;
return ajaxReq({ plan: 'addItem', storeID: this.storeID, name: text, price: price })
.done(json => {
// console.log("addItem return:", json);
return that.addItemHtml(text, price, json['data']);
});
}
return false;
}
addItemHtml(text, price, itemID, amount){
@ -161,7 +157,6 @@ class Store {
html += " </span>";
*/
html += " <span class='price'>"+price.toFixed(2)+" kr ";
// html += "<button class='remItem' data-price='"+price+"' data-toggle='tooltip' title='Remove item' style='background: url(../icon/dash.svg); height: 20px; width: 20px;'></button></span>";
html += "<img src='../icon/dash-circle.svg' alt='Remove item' class='remItem' data-itemID='"+itemID+"' data-price='"+price+"' style='height: 20px; width: 20px; cursor: pointer;'></span>";
html += "</li>";
@ -180,28 +175,18 @@ class Store {
remItem(pos, itemID, price){
let that = this;
return $.ajax({
method: "POST",
url: "do.php",
data: { plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return false;
}
// console.log("remItem return:", json);
return that.remItemHtml(itemID);
})
.fail(handleAjaxErrors);
return ajaxReq({ plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price })
.done(json => {
// console.log("remItem return:", json);
return that.remItemHtml(itemID);
});
}
remItemHtml(itemID){
// this.items.splice(pos,1);
for(let i = 0; i < this.items.length; i++){
if(this.items[i].itemID == itemID){
if(this.items[i].itemID === itemID){
this.items.splice(i,1);
break;
}
@ -230,7 +215,7 @@ class Store {
setItemPosition(itemID, afterID){
afterID = afterID || 0;
if(itemID != afterID){
if(itemID !== afterID){
return ajaxReq({ plan: 'moveItem', storeID: this.storeID, itemID: itemID, afterID: afterID });
}
return false;
@ -353,20 +338,10 @@ class Store {
removeStore(){
this.selector.remove();
if(this.storeID != null){
$.ajax({
method: "POST",
url: "do.php",
data: { plan: 'deleteStore', storeID: this.storeID, storeName: this.title, itemsLength: this.items.length },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return;
}
console.log("Delete store response:",json);
})
.fail(handleAjaxErrors);
ajaxReq({ plan: 'deleteStore', storeID: this.storeID, storeName: this.title, itemsLength: this.items.length })
.done(json => {
console.log("Delete store response:",json);
});
}
}
@ -401,8 +376,7 @@ $("#addStore").click(ev => {
$("#refreshAll").click(ev => {
$(".tooltip").remove();
stores = [];
getStores();
getStores(spaceID);
});
$("body").on('click', function(ev){
@ -411,11 +385,20 @@ $("body").on('click', function(ev){
}
});
var spaceID = 0;
// GET STORES
function getStores(){
$("#stores").html("");
function getStores(spaceID){
spaceID = spaceID || 0;
$.getJSON('do.php', { plan: '' })
$("#stores").html("");
stores = [];
let options = { plan: '' };
if(spaceID !== 0){
options = { plan: '', space: spaceID }
}
$.getJSON('do.php', options)
.done(json => {
if(handleJsonErrors(json)){
return;
@ -423,7 +406,7 @@ function getStores(){
// console.log(json);
for(const store in json.data){
storeID = stores.length;
let storeID = stores.length;
stores.push(new Store(json.data[store].name, json.data[store].plan_store_id));
for(const item in json.data[store].items){
@ -437,10 +420,13 @@ function getStores(){
})
.fail(handleAjaxErrors);
}
getStores();
getStores(spaceID);
function ajaxReq( data ){
if(typeof spaceID !== "undefined" && spaceID != 0){
data.space = spaceID;
}
return $.ajax({
method: "POST",
url: "do.php",

116
register.php Normal file
View File

@ -0,0 +1,116 @@
<?php
require 'webdata/init.php';
$returnToPage = "./";
if(isset($_POST['referrerPage'])){
$returnToPage = $_POST['referrerPage'];
}
else if(isset($_SERVER['HTTP_REFERER'])){
$returnToPage = $_SERVER['HTTP_REFERER'];
}
if(stristr($returnToPage, "login.php") || stristr($returnToPage, "register.php")){
$returnToPage = "./";
}
if(isset($_POST) && !empty($_POST)) {
$db = database();
$data = [];
foreach ($_POST as $key => $value) {
if (($data[$key] = filter($value)) === false) {
print_r($value);
echo "Failed to sanitize: `" . $key . "`: " . $value . " \t-\t type: " . gettype($value) . "\n";
}
}
$userEmail = $data['newEmail'];
$userPass = $data['newPassword'];
$userName = $data['newName'] ?? '';
if(strlen($userPass) < 6){
$err[] = "Password is too short. Password needs to be at least 6 characters!";
}
else if(strlen($userPass) > 30){
$err[] = "Password is too long. Max length is set to 30 characters. If you believe it should be higher please contact the developers.";
}
if(strlen($userEmail) > 220){
$err[] = "Your email-address is too long. Can you please register with another email?";
}
if(strlen($userName) > 200){
$err[] = "Your name seems to be too large to fit this system. Maybe you can short it somehow?";
}
if(empty($err)){
// HASH PASSWORD
$newPass = PwdGen($userPass, true);
$createUserSQL = "INSERT INTO user SET full_name = '$userName', user_email = '$userEmail', pwd = '$newPass';";
if($db->query($createUserSQL)){
$newID = $db->insert_id;
$updateUserSQL = "UPDATE user SET md5_id = '".md5($newID)."' WHERE user_id = '$newID';";
$db->query($updateUserSQL);
header("Location: login.php?thank");
}
else {
$err[] = "Something went wrong:<br>".$db->error;
}
}
}
?><!DOCTYPE html>
<html lang="en">
<head>
<?=getHtmlHeaders();?>
<title>Register - Grocery Assist</title>
</head>
<body id='plan'>
<?php include 'webdata/navbar.php'; ?>
<div class='container-md' style="max-width: 720px;">
<h1 class="headline text-center">Register</h1>
<br>
<?php if(!empty($err)){
foreach($err as $e){
echo "<div class='alert alert-danger' role='alert'>$e</div>";
}
echo "<br>";
}
?>
<form action="register.php" method="POST" class="row">
<input type="hidden" name="referrerPage" value="<?=$returnToPage;?>">
<div class="col-md-6">
<label for="newEmail" class="form-label">Email*</label>
<input type="email" class="form-control" id="newEmail" name="newEmail" maxlength="220" required value="<?= $data['newEmail'] ?? '';?>">
</div>
<div class="col-md-6">
<label for="newPassword" class="form-label">Password*</label>
<input type="password" class="form-control" id="newPassword" name="newPassword" minlength="6" maxlength="30" required>
</div>
<div class="col-12">
<label for="newName" class="form-label">Full name</label>
<input type="text" class="form-control" id="newName" name="newName" maxlength="200" value="<?= $data['newName'] ?? '';?>">
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck" required>
<label class="form-check-label" for="gridCheck">
I will read the Terms and Conditions when they are published.
</label>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Sign up</button>
</div>
</form>
<p>Already have an account? <a href="login.php">Login</a></p>
</div>
</body>
</html>

View File

@ -6,5 +6,5 @@ $config["db"]["pass"] = "password";
$config["db"]["database"] = "database";
$config["general"]["projectRoot"] = "/groceries";
$config["general"]["pepper"] = "IAmBadAtSecurity";
?>

View File

@ -6,6 +6,10 @@ error_reporting(E_ALL);
require_once 'config.php';
if(!isset($config) || empty($config)){
die("<h1>Configuration error</h1><p>Copy the webdata/config.sample.php file to webdata/config.php and fill out your connection settings.</p>");
}
$projectRoot = $config["general"]["projectRoot"];
function database(){
@ -20,6 +24,25 @@ function database(){
return $db;
}
function filter($data){
global $db;
if(gettype($data) !== "array"){
$data = trim(htmlentities(strip_tags($data)));
return $db->real_escape_string($data);
}
else if(gettype($data) == "array"){
foreach($data as $key => $value){
$data[$key] = filter($value);
}
return $data;
}
return false;
}
function getHtmlHeaders($prepend = ""){
return "<meta charset='UTF-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
@ -30,17 +53,124 @@ function getHtmlHeaders($prepend = ""){
<script src='".$prepend."js/jquery-3.5.1.min.js'></script>
<script src='".$prepend."js/popper.min.js'></script>
<script src='".$prepend."js/bootstrap.min.js'></script>\n\n";
<script src='".$prepend."js/bootstrap.min.js'></script>
<script src='".$prepend."js/hammer.js'></script>
<script src='".$prepend."js/hammer.jquery.js'></script>
\n";
}
function checkLogin(){
global $user_id;
function loginUser($email, $pass) {
global $db;
if(isset($user_id)){
return $user_id;
$err = [];
// get user from database
$getUserSQL = "SELECT pwd, user_id, user_email FROM user WHERE user_email = '$email' LIMIT 1;";
$getUserRes = $db->query($getUserSQL);
$dbPass = "missingPassword";
$dbUserId = 0;
$dbUserName = "Unknown";
if($getUserRes->num_rows == 1){
// Verify password
list($dbPass, $dbUserId, $dbUserName) = $getUserRes->fetch_row();
}
return 1;
if(password_verify(PwdGen($pass), $dbPass)){
if(!isset($_SESSION)){
session_start();
}
else {
session_regenerate_id(true);
}
$_SESSION['user_id'] = $dbUserId;
$_SESSION['user_name'] = $dbUserName;
$_SESSION['user_agent'] = md5($_SERVER['HTTP_USER_AGENT']);
$userKey = GenKey();
$updateUserSQL = "UPDATE user SET ctime = ".time().", ckey = '$userKey' WHERE user_id = $dbUserId;";
if($db->query($updateUserSQL)){
$_SESSION['user_key'] = sha1($userKey);
return true;
}
else {
$err[] = "Failed to login.\n".$db->error;
}
}
else {
$err[] = "Username and/or Password is wrong.";
}
return $err;
}
function PwdGen($pass, $returnHashed = false): string {
global $config;
$pepper = $config['general']['pepper'] ?? 'IAmBadAtSecurity';
$pwd_peppered = hash_hmac("sha256", $pass, $pepper);
if(!$returnHashed){
return $pwd_peppered;
}
return password_hash($pwd_peppered, PASSWORD_ARGON2ID, ['threads' => 2]);
}
function GenKey($length = 7): string{
$password = "";
$possible = "0123456789abcdefghijkmnopqrstuvwxyz";
$i = 0;
while($i < $length){
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
if(!strstr($password, $char)){
$password .= $char;
$i++;
}
}
return $password;
}
function checkLogin(): bool{
global $db, $_SESSION;
if($db == null){
$db = database();
}
if(!isset($_SESSION)){
session_start();
}
if(md5($_SERVER['HTTP_USER_AGENT']) == @$_SESSION['user_agent']){
$verifyLoginRes = $db->query("SELECT ckey FROM user WHERE user_id = ".$_SESSION['user_id']);
list($cKey) = $verifyLoginRes->fetch_row();
if(sha1($cKey) == $_SESSION['user_key']){
return true;
}
}
return false;
}
function checkLoginSimple(): bool {
global $_SESSION;
if(!isset($_SESSION)){
session_start();
}
if(isset($_SESSION['user_id'])){
return true;
}
return false;
}

View File

@ -24,6 +24,9 @@ if($activePage == "/index.php"){ $activePage = "/"; }
}
?>
</ul>
<div class="navbar-nav" id="navLogin">
<?php if(checkLoginSimple()){ echo "<span title='Logged in as: ".($_SESSION['user_name'] ?? '')."'>Logged in</span>"; } else { ?><a class="nav-item nav-link" id='login' href='<?=$projectRoot;?>/login.php'>Login</a><?php } ?>
</div>
</div>
</div>
</nav>

View File

@ -5,37 +5,46 @@
// CREATE TABLES
$sql = "CREATE OR REPLACE TABLE `user` (
`user_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`md5_id` VARCHAR(200),
`user_id` BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`md5_id` VARCHAR(200) UNIQUE,
`full_name` TINYTEXT,
`user_name` VARCHAR(200) NOT NULL,
`user_email` VARCHAR(220) NOT NULL,
`user_email` VARCHAR(220) NOT NULL UNIQUE,
`user_level` TINYINT(4) NOT NULL DEFAULT 1,
`pwd` VARCHAR(220),
`date` DATE NOT NULL DEFAULT(CURRENT_DATE),
`user_ip` VARCHAR(200),
`ckey` VARCHAR(220),
`ctime` VARCHAR(220),
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_Email` (`user_email`),
UNIQUE KEY `user_md5ID` (`md5_id`)
`ctime` VARCHAR(220)
) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO `user` (full_name, user_name, user_email, user_level, pwd)
VALUES ('Admin', 'admin', 'admin@svagard.no', 5, 'cb4f8b8b16b0c41d1ece858548340b40dfe6c7fd7fad1ecce');
INSERT INTO `user` (full_name, user_email, user_level, pwd)
VALUES ('Admin', 'admin@svagard.no', 5, '-');
CREATE OR REPLACE TABLE plan_space (
`space_id` INT auto_increment PRIMARY KEY,
`space_name` tinytext,
`owner_id` BIGINT(20),
CONSTRAINT plan_space_owner_FK FOREIGN KEY (`owner_id`) REFERENCES `user`(`user_id`)
);
CREATE OR REPLACE TABLE plan_space_member (
`space_id` INT auto_increment NOT NULL,
`member_id` BIGINT(20) NOT NULL,
`timestamp` DATETIME default current_timestamp() NOT NULL,
PRIMARY KEY (`space_id`, `member_id`),
CONSTRAINT space_member_FK FOREIGN KEY (`member_id`) REFERENCES `user`(`user_id`),
CONSTRAINT space_member_space_FK FOREIGN KEY (`space_id`) REFERENCES `plan_space`(`space_id`)
);
CREATE OR REPLACE TABLE plan_store (
`plan_store_id` INT auto_increment,
`user_id` BIGINT(20) NOT NULL,
`space_id` INT NOT NULL,
`name` varchar(100) NOT NULL,
`created` DATETIME DEFAULT CURRENT_DATE NOT NULL,
`created` DATETIME default current_timestamp() NOT NULL,
PRIMARY KEY (plan_store_id),
CONSTRAINT plan_store_user_FK FOREIGN KEY (`user_id`) REFERENCES `user`(`user_id`)
CONSTRAINT plan_store_user_FK FOREIGN KEY (`space_id`) REFERENCES `plan_space`(`space_id`)
) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO plan_store (user_id, name)
VALUES (1, 'Store 1');
CREATE OR REPLACE TABLE plan_store_item (
`plan_item_id` INT auto_increment NOT NULL,
`plan_store_id` INT NOT NULL,
@ -47,9 +56,6 @@ CREATE OR REPLACE TABLE plan_store_item (
CONSTRAINT plan_store_item_FK FOREIGN KEY (plan_store_id) REFERENCES `plan_store`(`plan_store_id`)
) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO plan_store_item (plan_store_id, name, price)
VALUES (1, 'Kake', 49.90),
(1, 'Kaffe', 24.90);
";