diff --git a/bin/adduser.js b/bin/adduser.js new file mode 100644 index 0000000..d2cb4c7 --- /dev/null +++ b/bin/adduser.js @@ -0,0 +1,25 @@ +$(document).ready(function(){ + $("#button_newuser").click(function(){ + $.post("/php/edit-user.php", + { + function: "new-user", + username: $("#text_user").val(), + passwd: $("#text_passwd").val() + }, + function(data){ + if(data==0){ + infoPopUp("Benutzer erfolgreich erstellt!", 100); + $("#text_user").val(""); + $("#text_passwd").val(""); + $("#adduser-button-done").removeClass("button-disabled"); + } + else { + infoPopUp("Fehler bei der Benutzeranlage!", 100); + } + } + ); + }); + $("#adduser-button-done").click(function(){ + window.location.href = "/"; + }); +}); diff --git a/bin/index.js b/bin/index.js new file mode 100644 index 0000000..1e6efec --- /dev/null +++ b/bin/index.js @@ -0,0 +1,5 @@ +function infoPopUp(infotext, timeout){ + $("#info-popup-text").text(infotext); + $("#info-popup-text").css("animation", "none"); + setTimeout(function(){$("#info-popup-text").css("animation", "fade 4s linear");}, timeout); +} diff --git a/bin/list.js b/bin/list.js index 0dfe365..f469531 100644 --- a/bin/list.js +++ b/bin/list.js @@ -9,14 +9,8 @@ $(document).ready(function(){ id: dataId, status: $(this).prop("checked") }, - success: function(){ - $("#saved font").css("animation", "none"); - setTimeout(function(){$("#saved font").css("animation", "fade 4s linear");}, 100); - }, - error: function(){ - $("#error font").css("animation", "none"); - setTimeout(function(){$("#error font").css("animation", "fade 6s linear");}, 100); - } + success: function(){infoPopUp("SAVED!", 100);}, + error: function(){infoPopUp("Netzwerkfehler! Bitte aktualisieren.", 100);} }); if($(this).prop("checked")){$("[data-id='"+dataId+"']").addClass("checked");} else{$("[data-id='"+dataId+"']").removeClass("checked");} diff --git a/bin/nav.js b/bin/nav.js index 157dc97..94b4461 100644 --- a/bin/nav.js +++ b/bin/nav.js @@ -15,4 +15,7 @@ $(document).ready(function(){ $("#logout").click(function(){ window.location.href = "/php/logout.php"; }); + $("#settings").click(function(){ + window.location.href = "/settings"; + }); }); diff --git a/bin/settings.js b/bin/settings.js new file mode 100644 index 0000000..51164bb --- /dev/null +++ b/bin/settings.js @@ -0,0 +1,107 @@ +function downloadObjectAsJson(exportObj, exportName){ + var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj)); + var downloadAnchorNode = document.createElement('a'); + downloadAnchorNode.setAttribute("href", dataStr); + downloadAnchorNode.setAttribute("download", exportName + ".json"); + document.body.appendChild(downloadAnchorNode); // required for firefox + downloadAnchorNode.click(); + downloadAnchorNode.remove(); +} +$(document).ready(function(){ + $("#username-input").focus(function(){$(this).css("color", "black");}); + $("#mail-input").focus(function(){$(this).css("color", "black");}); + + // change password + $("#old-password-input").focus(function(){$(this).css("color", "black");}); + $("#new-password-input").focus(function(){$(this).css("color", "black");}); + $("#check-password-input").focus(function(){$(this).css("color", "black");}); + $(".password-input").on("input", function(){ + if( + (($("#old-password-input").val()).length>0) && + (($("#new-password-input").val()).length>0) && + (($("#check-password-input").val()).length>0) && + ($("#new-password-input").val()==$("#check-password-input").val()) + ){ + $("#passwordSaveButton").prop("disabled", false); + $("#passwordSaveButton").removeClass("button-disabled"); + } + else{ + $("#passwordSaveButton").prop("disabled", true); + $("#passwordSaveButton").addClass("button-disabled"); + } + }); + $("#passwordSaveButton").click(function(){ + $.post("/php/edit-user.php", + { + function: "change-pw", + current: $("#old-password-input").val(), + new: $("#new-password-input").val() + }, + function(data){ + if(data==0){ + $("#old-password-input").val(""); + $("#new-password-input").val(""); + $("#check-password-input").val(""); + infoPopUp("Passwort erfolgreich geändert!", 100); + } + else { + infoPopUp("Altes Passwort Falsch!", 100); + } + } + ); + }); + + $("#export-recipe-button").click(function(){ + $.post("/php/edit-recipes.php", {function:"export"}, function(data){ + downloadObjectAsJson(JSON.parse(data), "recipes"); + }); + }); + + $("#export-list-button").click(function(){ + $.post("/php/edit-list.php", {function:"export"}, function(data){ + downloadObjectAsJson(JSON.parse(data), "list"); + }); + }); + + $("#import-button").click(function(){ + $('').on('change', function () { + var file = this.files[0]; + var reader = new FileReader(); + reader.onload = function(){ + var content = JSON.parse(reader.result); + if(content.sites!=null){ + $.post("/php/edit-recipes.php", + { + function: "import", + content: reader.result + }, + function(data){ + if(data==0){ + infoPopUp("Alle Rezepte erfolgreich Importiert!", 200); + } + else{ + infoPopUp("Nicht alle Rezepte konnten Importiert werden!", 1000); + downloadObjectAsJson(JSON.parse(data), "failed_recipe_import"); + } + } + ); + } + else if(content.list!=null){ + $.post("/php/edit-list.php", + { + function: "import", + content: reader.result + }, + function(data){ + console.log(data); + if(data==0){ + infoPopUp("Alle Listeneinträge erfolgreich Importiert!", 200); + } + } + ); + } + }; + reader.readAsText(file); + }).click(); + }); +}); diff --git a/config/.htaccess b/config/.htaccess index b66e808..98e9e6d 100644 --- a/config/.htaccess +++ b/config/.htaccess @@ -1 +1,4 @@ -Require all denied +# prevent access to these files while not logged in + + Require all denied + diff --git a/cont/.htaccess b/cont/.htaccess index 6f56351..98e9e6d 100644 --- a/cont/.htaccess +++ b/cont/.htaccess @@ -1,4 +1,4 @@ # prevent access to these files while not logged in - -Require all denied + + Require all denied diff --git a/cont/adduser.php b/cont/adduser.php index 7945db7..0f98a8d 100644 --- a/cont/adduser.php +++ b/cont/adduser.php @@ -1,12 +1,11 @@ - - - +

Benutzer hinzufügen

-
- - +
+ + - +
+ diff --git a/cont/list.php b/cont/list.php index e512a47..7810c60 100644 --- a/cont/list.php +++ b/cont/list.php @@ -35,5 +35,3 @@ ?> -
SAVED!
-
Netzwerkfehler!
Bitte aktualisieren.
diff --git a/cont/nav.php b/cont/nav.php index 8025acb..c670412 100644 --- a/cont/nav.php +++ b/cont/nav.php @@ -2,6 +2,7 @@ "; if($site && ($site!="login")){include $_SESSION["docroot"].'/cont/nav.php';} ?> +
diff --git a/install/adduser.php b/install/adduser.php index 7945db7..06fa697 100644 --- a/install/adduser.php +++ b/install/adduser.php @@ -1,12 +1,18 @@ - + + +

Benutzer hinzufügen

-
- - +
+ + - +
+ + + +
diff --git a/install/install.php b/install/install.php index 3a4cc2c..0211e93 100644 --- a/install/install.php +++ b/install/install.php @@ -1,9 +1,9 @@ 0){ header("Location: /cont/error.php?id=php_modules&missing_mods=".serialize($missing_mods)); } @@ -28,7 +33,7 @@ if (!($_SESSION["docroot"])) header("Location: /"); exit; } - ?> +?> diff --git a/php/.htaccess b/php/.htaccess new file mode 100644 index 0000000..da07521 --- /dev/null +++ b/php/.htaccess @@ -0,0 +1,16 @@ +# prevent access to these files while not logged in + + Require all denied + + + + Require all denied + + + + Require all denied + + + + Require all denied + diff --git a/php/adduser_action.php b/php/adduser_action.php deleted file mode 100644 index 3bd10d6..0000000 --- a/php/adduser_action.php +++ /dev/null @@ -1,15 +0,0 @@ -query("INSERT INTO `users` (`username`, `password`, `salt`, `last_login`) VALUES ('".$_POST["username"]."', '".$password."', '".$salt."', CURRENT_TIMESTAMP);"); -$mysqli->close(); - -unset($salt); -unset($password); -header("Location: /"); -?> diff --git a/php/classes.list.php b/php/classes.list.php index 8b29ca1..8bf1a49 100644 --- a/php/classes.list.php +++ b/php/classes.list.php @@ -60,6 +60,15 @@ $mysqli->query("UPDATE `Einkauf` SET `Erledigt` = $status WHERE `Einkauf`.`ID` = $id"); $mysqli->close(); } + + function import(){ + $import = json_decode($_POST["content"]); + $units = new units(); + foreach($import->list as $item){ + $this->newItem($item->Anzahl, $units->getID($item->Einheit), $item->Name); + } + print_f("0"); + } } class unit { @@ -86,5 +95,13 @@ } $mysqli->close(); } + + function getID($Name){ + foreach($this->list as $units){ + if($units->Name==$Name){ + return $units->ID; + } + } + } } ?> diff --git a/php/classes.recipe.php b/php/classes.recipe.php index a4b1ec3..666f88d 100644 --- a/php/classes.recipe.php +++ b/php/classes.recipe.php @@ -20,6 +20,12 @@ } $mysqli->close(); } + function getID($Name){ + include $_SESSION["docroot"].'/php/connect.php'; + $result = $mysqli->query("SELECT `ID` FROM `Einheit` WHERE `Name` = '$Name'"); + $ID = $result->fetch_assoc(); + return $ID["ID"]; + } } class ingredient { @@ -89,15 +95,51 @@ $mysqli->close(); } + function importCookbook(){ + include $_SESSION["docroot"].'/php/connect.php'; + $units = new unitList(); + $failed_sites = array(); + $succeeded_sites = array(); + $import = json_decode($_POST["content"]); + if($import->sites!=null){ + foreach ($import->sites as $site) { + $result = $mysqli->query("SELECT * FROM `Rezept` WHERE `Name`='$site->Name'"); + if($result->num_rows>0){ + array_push($failed_sites, $site); + } + else{ + array_push($succeeded_sites, $site); + $Zutaten = array(); + foreach($site->Zutaten as $Zutat) { + $nZutat = null; + $nZutat["ID"] = $Zutat->ID; + $nZutat["Amount"] = $Zutat->Menge; + $nZutat["Unit"] = $units->getID($Zutat->Einheit); + $nZutat["Name"] = $Zutat->Name; + array_push($Zutaten, $nZutat); + } + $this->newRecipe($site->Name, $site->Dauer, $site->Beschreibung, $Zutaten); + } + } + if(sizeof($failed_sites)==0){ + print_r("0"); + } + else{ + print_r(json_encode($failed_sites)); + } + } + } + function newRecipe($Name, $Dauer, $Beschreibung, $Zutaten){ include $_SESSION["docroot"].'/php/connect.php'; - $mysqli->query("INSERT INTO Rezept (Name, Dauer, Beschreibung) VALUES ('$Name', '$Dauer', '$Beschreibung')"); + $mysqli->query("INSERT INTO `Rezept` (`Name`, `Dauer`, `Beschreibung`) VALUES ('$Name', '$Dauer', '$Beschreibung')"); $RezeptID = $mysqli->insert_id; foreach ($Zutaten as $Zutat) { $ZutatID = null; $result = $mysqli->query("SELECT ID FROM `Zutat` WHERE `Name` LIKE '".$Zutat["Name"]."'"); if($result->num_rows>0){ - while($item = $result->fetch_assoc()){$ZutatID = $item["ID"];} + $item = $result->fetch_assoc(); + $ZutatID = $item["ID"]; } else{ $mysqli->query("INSERT INTO `Zutat` (`Name`) VALUES ('".ucwords($Zutat["Name"])."')"); diff --git a/php/classes.user.php b/php/classes.user.php new file mode 100644 index 0000000..1391ca4 --- /dev/null +++ b/php/classes.user.php @@ -0,0 +1,56 @@ +query($query); + $user = $result->fetch_assoc(); + $this->uid = $user["uid"]; + $this->username = $user["username"]; + $this->email = $user["email"]; + $this->last_login = $user["last_login"]; + $this->salt = $user["salt"]; + $mysqli->close(); + } + + function change_password($current, $new){ + include $_SESSION["docroot"].'/php/hash.php'; + include $_SESSION["docroot"].'/php/connect.php'; + $current_pwhash = hash_password($current, $this->salt); + $query = "SELECT `uid` FROM `users` WHERE `uid` = $this->uid AND `password` = '$current_pwhash'"; + $result = $mysqli->query($query); + if($result->num_rows===1){ + $new_pwdhash = hash_password($new, $this->salt); + $mysqli->query("UPDATE `users` SET `password` = '$new_pwdhash' WHERE `users`.`uid` = $this->uid;"); + $mysqli->close(); + print_r("0"); + } + else{ + print_r("1"); + } + } + + function new($uname, $password){ + session_start(); + include $_SESSION["docroot"].'/php/connect.php'; + include $_SESSION["docroot"].'/php/hash.php'; + + $query = "SELECT `uid` FROM `users` WHERE `username` = '$uname'"; + $result = $mysqli->query($query); + if($result->num_rows==0){ + $salt = create_salt(); + $passhash = hash_password($password, $salt); + $query = "INSERT INTO `users` (`username`, `password`, `salt`, `last_login`) VALUES ('$uname', '$passhash', '$salt', CURRENT_TIMESTAMP);"; + $result = $mysqli->query($query); + unset($salt); + unset($password); + print_r(0); + } + else{print_r(1);} + $mysqli->close(); + } + } +?> diff --git a/php/edit-list.php b/php/edit-list.php index e9237df..82326c9 100644 --- a/php/edit-list.php +++ b/php/edit-list.php @@ -19,6 +19,15 @@ case 'check': $shopping->check($_POST["id"], $_POST["status"]); + break; + + case 'export': + echo json_encode($shopping); + break; + + case 'import': + $shopping->import(); + break; default: // code... diff --git a/php/edit-recipes.php b/php/edit-recipes.php index fcf86e0..aa068c6 100644 --- a/php/edit-recipes.php +++ b/php/edit-recipes.php @@ -27,6 +27,15 @@ header(("Location: /recipe/".$_POST["id"])); break; + case 'export': + $book->fillCookbook(); + echo json_encode($book); + break; + + case 'import': + $book->importCookbook(); + break; + default: // code... break; diff --git a/php/edit-user.php b/php/edit-user.php new file mode 100644 index 0000000..4729fee --- /dev/null +++ b/php/edit-user.php @@ -0,0 +1,22 @@ +get_info($_COOKIE["token"]); + } + + switch ($_POST["function"]) { + case 'change-pw': + $user->change_password($_POST["current"], $_POST["new"]); + break; + + case 'new-user': + $user->new($_POST["username"], $_POST["passwd"]); + break; + + default: + // code... + break; + } +?> diff --git a/pic/settings.svg b/pic/settings.svg new file mode 100644 index 0000000..9cc62a7 --- /dev/null +++ b/pic/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/style/adduser.css b/style/adduser.css index 8ba74e0..31df069 100644 --- a/style/adduser.css +++ b/style/adduser.css @@ -13,3 +13,8 @@ label { flex-direction: column; width: 50%; } +#adduser-button-done { + position: absolute; + bottom: 2em; + right: 2em; +} diff --git a/style/list.css b/style/list.css index e522262..23aa14b 100644 --- a/style/list.css +++ b/style/list.css @@ -92,33 +92,3 @@ border-left: none; .list_row.odd.checked { border-left: 3px solid #888; } - -#saved, #error { - pointer-events: none; - position: fixed; - display: flex; - justify-content: center; - bottom: 2%; - margin: 0; - left: 0; - width: 100%; -} -#saved font, #error font { - color: #ffffff; - background-color: #000000; - padding: .1em .5em .2em; - border-radius: 50px; - opacity: 0; -} - -#error font { - padding: .1em 1em .2em; -} -@keyframes fade { - 0% { - opacity: 0; - } - 10% { - opacity: 1; - } -} diff --git a/style/master.css b/style/master.css index 864a674..2553976 100644 --- a/style/master.css +++ b/style/master.css @@ -26,6 +26,15 @@ h2 { width: 80%; } +h3 { + font-size: 1.5em; + text-align: left; + margin-top: .5em; + padding-bottom: .5em; + border-bottom: 1px solid grey; + width: 75%; +} + .even { background-color: #565656; } @@ -53,9 +62,50 @@ h2 { font-weight: 800; background-color: #4CAF50; color: white; + cursor: pointer; +} + +.button:hover { + background-color: #4CAFFF; +} + +.button-disabled { + background-color: grey; + cursor: not-allowed; +} + +.button-disabled:hover { + background-color: grey; } .hover:hover { background-color: #4CAF50; cursor: pointer; } + +#info-popup { + pointer-events: none; + position: fixed; + display: flex; + justify-content: center; + bottom: 2%; + margin: 0; + left: 0; + width: 100%; +} +#info-popup-text { + color: #ffffff; + background-color: #000000; + padding: .1em .5em .2em; + border-radius: 50px; + opacity: 0; +} + +@keyframes fade { + 0% { + opacity: 0; + } + 10% { + opacity: 1; + } +} diff --git a/style/nav.css b/style/nav.css index 25ff827..14701d2 100644 --- a/style/nav.css +++ b/style/nav.css @@ -31,6 +31,13 @@ height: 45px; cursor: pointer; } +#settings { + position: absolute; + top: calc(.5em + 5px); + right: calc(2em + 45px); + height: 35px; + cursor: pointer; +} #burgerMenue { width: 60px; height: 45px; diff --git a/style/settings.css b/style/settings.css new file mode 100644 index 0000000..7d19e53 --- /dev/null +++ b/style/settings.css @@ -0,0 +1,61 @@ +.settings { + display: flex; + justify-content: flex-start; + flex-direction: row; + flex-wrap: wrap; +} +.pane { + border: 1px solid grey; + border-radius: 5px; + background-color: #ddd; + margin: 1%; + width: auto; + min-width: max-content; + max-width: 45%; + height: max-content; +} +.userprofile-pane { + display: flex; + flex-direction: column; + justify-content: flex-start; +} +.userprofile { + width: 22em; + display: flex; + flex-direction: column; +} +.userpassword-pane { + display: flex; + flex-direction: column; + justify-content: flex-start; +} +.userpassword { + width: 22em; + display: flex; + flex-direction: column; +} +.userprofile span { + display: flex; + flex-direction: row; + align-items: center; +} +.userpassword span { + display: flex; + flex-direction: row; + align-items: center; +} +.attribute { + width: 6em; + padding: 1em; +} +.change-attribute-input { + text-indent: 1em; + color: grey; +} +.value { + padding: 1em; +} +#passwordSaveButton, #userSaveButton { + align-self: flex-end; + margin: 1em; +}