diff --git a/website/public/API/editFriendship.php b/website/public/API/editFriendship.php new file mode 100644 index 0000000..0518733 --- /dev/null +++ b/website/public/API/editFriendship.php @@ -0,0 +1,27 @@ + Bevriend")); + } else if(friendshipStatus == 1) { + $buttonContainer.append($("")); + } else if(friendshipStatus == 2) { + $buttonContainer.append($("")); + } else if(friendshipStatus == 3) { + $buttonContainer.append($("")); + $buttonContainer.append($("")); + } + + $buttonContainer.children().click(function() { + $.post("API/editFriendship.php", { usr: userID, action: this.value }) + .done(function() { + placeFriendButtons(); + }); + }); + }); +} \ No newline at end of file diff --git a/website/public/js/masonry.js b/website/public/js/masonry.js index e9419a2..3b872ba 100644 --- a/website/public/js/masonry.js +++ b/website/public/js/masonry.js @@ -1,5 +1,30 @@ margin = 20; +// scrolling modal taken from http://stackoverflow.com/questions/10476632/how-to-scroll-the-page-when-a-modal-dialog-is-longer-than-the-screen +function scrollbarMargin(width, overflow) { + $('body').css({ + marginRight: width, + overflow: overflow + }); + $('.profile-menu').css({ + marginRight: width + }); +} + +function requestPost(post) { + $(".modal").show(); + $.get( + "API/loadPost.php", + $(post).children("form").serialize() + ).done(function (data) { + $('.modal-default').hide(); + var scrollBarWidth = window.innerWidth - document.body.offsetWidth; + scrollbarMargin(scrollBarWidth, 'hidden'); + $('#modal-response').show(); + $('#modal-response').html(data); + }); +} + $(window).on("load", function() { console.log("LOADED"); container = $("div.posts"); @@ -69,8 +94,14 @@ function mansonry() { column = $('
').append(columns[i][1]); console.log(column); container.append(column); - } $("div.posts div.column").width(100/columnCount + "%"); + + $(".modal-close").click(function () { + $(".modal").hide(); + scrollbarMargin(0, 'auto'); + $('#modal-response').hide(); + $('.modal-default').show(); + }); } \ No newline at end of file diff --git a/website/public/js/profile.js b/website/public/js/profile.js new file mode 100644 index 0000000..2a47dce --- /dev/null +++ b/website/public/js/profile.js @@ -0,0 +1,8 @@ +function loadPost(postID) { + $.get( + "API/loadPost.php", + $(postID).serialize() + ).done(function (data) { + $('#modal-response').innerHTML= JSON.parse(data); + }); +} \ No newline at end of file diff --git a/website/public/js/registerAndLogin.js b/website/public/js/registerAndLogin.js index ef49e83..b2fda05 100644 --- a/website/public/js/registerAndLogin.js +++ b/website/public/js/registerAndLogin.js @@ -12,4 +12,4 @@ function bannedAlert(){ function emailNotConfirmed(){ alert("Your account has not been verified yet!\nAnother email has been sent to you") -} \ No newline at end of file +} diff --git a/website/public/login.php b/website/public/login.php index de4ecab..0515793 100644 --- a/website/public/login.php +++ b/website/public/login.php @@ -6,6 +6,8 @@ include_once("../queries/login.php"); include_once("../queries/checkInput.php"); include_once("../queries/emailconfirm.php"); + include_once("../queries/requestpassword.php"); + include_once("../queries/register.php"); ?> getMessage(); + switch ($_POST["submit"]) { + case "login": + try { + $uname = ($_POST["uname"]); + validateLogin($_POST["uname"], $_POST["psw"]); + } catch(loginException $e) { + $loginErr = $e->getMessage(); + } + break; + case "reset": + try { + resetEmail($_POST["forgotEmail"]); + sendPasswordRecovery($_POST["forgotEmail"]); + } catch (emailException $e){ + $resetErr = $e->getMessage(); + echo ""; + } + break; + } } +// // Trying to login +// if ($_SERVER["REQUEST_METHOD"] == "POST") { +// try{ +// $uname = ($_POST["uname"]); +// validateLogin($_POST["uname"], $_POST["psw"]); +// } catch(loginException $e) { +// $loginErr = $e->getMessage(); +// } +// } /* This view adds login view */ include("../views/login-view.php"); diff --git a/website/public/profile.php b/website/public/profile.php index be71023..c0fa0fc 100644 --- a/website/public/profile.php +++ b/website/public/profile.php @@ -2,9 +2,11 @@ - + + @@ -12,6 +14,7 @@ include("../queries/user.php"); include("../queries/friendship.php"); include("../queries/nicetime.php"); +include("../queries/post.php"); if(empty($_GET["username"])) { $userID = $_SESSION["userID"]; @@ -24,6 +27,13 @@ $profile_friends = selectAllFriends($userID); $profile_groups = selectAllUserGroups($userID); $posts = selectAllUserPosts($userID); + +if ($userID == $_SESSION["userID"]) { + $friendship_status = -1; +} else { + $friendship_status = $user["friend_status"]; +} + /* * This view adds the main layout over the screen. * Header, menu, footer. @@ -36,5 +46,13 @@ include("../views/profile.php"); /* This adds the footer. */ include("../views/footer.php"); ?> + + + diff --git a/website/public/resetpassword.php b/website/public/resetpassword.php new file mode 100644 index 0000000..c2f9221 --- /dev/null +++ b/website/public/resetpassword.php @@ -0,0 +1,49 @@ +prepare(" + UPDATE + `user` + SET + `password` = :password + WHERE + `userID` = :userID + "); + $stmt->bindParam(":password", $_POST["password"]); + $stmt->bindParam(":userID", $_POST["u"]); + $stmt->execute(); +} + +function verifyLink(int $userID, string $hash) { + $stmt = $GLOBALS["db"]->prepare(" + SELECT + `password` + FROM + `user` + WHERE + `userID` = :userID + "); + $stmt->bindParam(":userID", $userID); + $password = $stmt->fetch()["password"]; + return password_verify($password, $hash); +} \ No newline at end of file diff --git a/website/public/styles/index.css b/website/public/styles/index.css index fc9d3d6..97d6f63 100644 --- a/website/public/styles/index.css +++ b/website/public/styles/index.css @@ -3,11 +3,11 @@ a.button { border-radius: 5px; color: black; cursor: pointer; - height: 50%; padding: 8px 20px; - width: 50%; font-family: Arial; - font-size: 20px; + font-size: 22px; + box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); + } /* Body */ @@ -28,12 +28,13 @@ body { form { /*background-color: #a87a87;*/ border-radius: 12px; - height: 75%; + height: 85%; margin: auto; width: 80%; overflow-y:auto; } + /* inlog titel */ h1 { padding: 8px; @@ -48,6 +49,11 @@ h2 { font-size: 2.0em; } +h3 { + padding: 16px; + text-align: center; + font-size: 1.5em; +} input[type=text], input[type=password], input[type=email], input[type="date"] { box-sizing: border-box; @@ -60,14 +66,22 @@ input[type=text], input[type=password], input[type=email], input[type="date"] { width: 55%; } -button[type=submit] { +.center{ + text-align: center; +} + +button { background-color: #C8CABD; + border-radius: 5px; color: black; cursor: pointer; + height: 50%; + padding: 8px 20px; + margin: 10px; font-family: Arial; font-size: 22px; - height: 30px; - width: 120px; + box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); + } .error { @@ -80,31 +94,6 @@ label { display: block; } -.left-arrow { - display: inline-block; - position: relative; - background-color: #C8CABD; - height: 25px; - width: 120px; - padding: 3px 3px 3px 3px; - text-align: center; - border-radius: 0px 5px 5px 0px; - font-size: 22px; - -} -.left-arrow:after { - content: ''; - display: block; - position: absolute; - right: 100%; - top: 0; - bottom: 0; - border-top: 12px solid transparent; - border-right: 20px solid #C8CABD; - border-bottom: 12px solid transparent; - border-left: 0px solid transparent; -} - /* padding voor registreer container */ .login_containerregister { padding: 16px; @@ -137,24 +126,84 @@ label { background-repeat: repeat-x; background-attachment: fixed;*/ box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); - height: 500px; + height: 400px; margin: 34px auto; overflow-y: auto; padding: 20px; width: 45%; } -/*.platform { - width: 40%; - margin: 34px auto; -}*/ - -@-webkit-keyframes animatezoom { - from {-webkit-transform: scale(0)} - to {-webkit-transform: scale(1)} -} - ul { font-family: Arial; font-size: 16px; } + +/* The Modal (background) */ +.modal { + display: none; /* Hidden by default */ + position: fixed; /* Stay in place */ + z-index: 1; /* Sit on top */ + padding-top: 100px; /* Location of the box */ + left: 0; + top: 0; + width: 100%; /* Full width */ + height: 100%; /* Full height */ + overflow: auto; /* Enable scroll if needed */ + background-color: rgb(0,0,0); /* Fallback color */ + background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ +} + +/* Modal Content */ +.modal-content { + position: relative; + background-color: #FFFFFF; + margin: auto; + padding: 0; + border: 1px solid #888; + width: 500px; + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19); + -webkit-animation-name: animatetop; + -webkit-animation-duration: 0.4s; + animation-name: animatetop; + animation-duration: 0.4s +} + +/* Add Animation */ +@-webkit-keyframes animatetop { + from {top:-300px; opacity:0} + to {top:0; opacity:1} +} + +@keyframes animatetop { + from {top:-300px; opacity:0} + to {top:0; opacity:1} +} + +/* The Close Button */ +.close { + color: white; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; +} + +.modal-header { + padding: 2px 16px; + background-color: #FBC02D; + color: black; +} + +.modal-body {padding: 2px 16px;} + +.modal-footer { + padding: 2px 16px; + background-color: #FBC02D; + color: black; +} \ No newline at end of file diff --git a/website/public/styles/main.css b/website/public/styles/main.css index 8c50b19..b8f39ee 100644 --- a/website/public/styles/main.css +++ b/website/public/styles/main.css @@ -175,6 +175,15 @@ textarea:focus, input:focus, select:focus { } /* All buttons */ +button.red { + background-color: firebrick; +} + +button.green { + background-color: forestgreen; +} + + button, input[type="submit"], input[type="reset"] { diff --git a/website/public/styles/post-popup.css b/website/public/styles/post-popup.css new file mode 100644 index 0000000..11fe03b --- /dev/null +++ b/website/public/styles/post-popup.css @@ -0,0 +1,72 @@ +/* modal based on: http://www.w3schools.com/howto/howto_css_modals.asp */ + +.modal { + display: none; + position: fixed; + top: 80px; + left: 256px; + width: calc(100% - 256px); /* Full width */ + height: calc(100% - 80px); /* Full height */ + background-color: rgb(0,0,0); /* Fallback color */ + background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ + overflow-y: auto; +} + +/* Modal Content/Box */ +.modal-content { + margin: 5% auto; + width: 70%; /* Could be more or less, depending on screen size */ + overflow-y: auto; +} + +.modal-close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + margin: auto; +} + +.modal-close:hover, +.modal-close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +.modal-content img { + max-height: 100%; + max-width: 100%; +} + +.post-header h4 { + font-size: 20pt; +} + +.post-content { + margin: 30px auto; + width: 90%; +} + +.commentfield { + margin-bottom: 20px; +} + +.commentfield textarea { + width: 100%; +} + +.comment { + padding-top: 10px; + padding-bottom: 10px; + border-top: 1px solid #4CAF50; +} + +.commentinfo { + font-size: 10pt; +} + +.commentcontent { + margin: 5px auto; + width: 95%; +} \ No newline at end of file diff --git a/website/public/styles/profile.css b/website/public/styles/profile.css index fbd8775..85b2db5 100644 --- a/website/public/styles/profile.css +++ b/website/public/styles/profile.css @@ -78,17 +78,16 @@ div.posts .post form textarea.newpost { font-size: 0.8em; } -input.profile-button { +button.friend-button { float: right; height: auto; padding: 10px; + margin-left: 10px; border-radius: 5px; - background-color: #4CAF50; - color: #FFFFFF; transition-duration: 250ms; cursor: pointer; } -.profile-button:hover { +button.friend-button:hover { box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } \ No newline at end of file diff --git a/website/public/styles/resetpassword.css b/website/public/styles/resetpassword.css new file mode 100644 index 0000000..a3d7942 --- /dev/null +++ b/website/public/styles/resetpassword.css @@ -0,0 +1,17 @@ +.password-change { + height: 100%; + background-color: #FBC02D; + margin: auto; +} + +.top-logo { + text-align: center; +} + +.item-box { + margin: 30px auto auto; + display: block; +} +.password-change img { + width: 50%; +} diff --git a/website/public/styles/search.css b/website/public/styles/search.css index 86fd41d..565723e 100644 --- a/website/public/styles/search.css +++ b/website/public/styles/search.css @@ -25,5 +25,5 @@ } li.search-item:hover{ - background-color: #EEE; + background-color: #FBC02D; } \ No newline at end of file diff --git a/website/queries/checkInput.php b/website/queries/checkInput.php index 5f72f10..9b91833 100644 --- a/website/queries/checkInput.php +++ b/website/queries/checkInput.php @@ -97,6 +97,18 @@ function validateEmail($variable){ } } +/* checks if an input is a valid email. */ +function resetEmail($variable){ + if (empty($variable)) { + throw new emailException("Verplicht!"); + } else if (!filter_var($variable, FILTER_VALIDATE_EMAIL)) { + throw new emailException("Geldige email invullen"); + } else if (getResetEmail() == 0){ + throw new emailException("Email bestaat niet!"); + } +} + + /* checks if two passwords matches. */ function matchPassword(){ if ($_POST["password"] != $_POST["confirmpassword"]) { diff --git a/website/queries/friendship.php b/website/queries/friendship.php index 1bfa6ea..57dacd8 100644 --- a/website/queries/friendship.php +++ b/website/queries/friendship.php @@ -105,6 +105,16 @@ function selectAllFriendRequests() { } function getFriendshipStatus($userID) { + # -2: Query failed. + # -1: user1 and 2 are the same user + # 0 : no record found + # 1 : confirmed + # 2 : user1 sent request (you) + # 3 : user2 sent request (other) + if($_SESSION["userID"] == $userID) { + return -1; + } + $stmt = $GLOBALS["db"]->prepare(" SELECT CASE `status` IS NULL @@ -131,8 +141,10 @@ function getFriendshipStatus($userID) { $stmt->bindParam(':me', $_SESSION["userID"], PDO::PARAM_INT); $stmt->bindParam(':other', $userID, PDO::PARAM_INT); - $stmt->execute(); - return $stmt->fetch()["friend_state"]; + if(!$stmt->execute()) { + return -2; + } + return intval($stmt->fetch()["friend_state"]); } function requestFriendship($userID) { @@ -143,7 +155,7 @@ function requestFriendship($userID) { $stmt->bindParam(':user1', $_SESSION["userID"], PDO::PARAM_INT); $stmt->bindParam(':user2', $userID, PDO::PARAM_INT); - $stmt->execute(); + return $stmt->execute(); } function removeFriendship($userID) { @@ -154,11 +166,12 @@ function removeFriendship($userID) { `user2ID` = :user2 OR `user1ID` = :user2 AND `user2ID` = :user1 + LIMIT 1 "); $stmt->bindParam(':user1', $_SESSION["userID"], PDO::PARAM_INT); $stmt->bindParam(':user2', $userID, PDO::PARAM_INT); - $stmt->execute(); + return $stmt->execute(); } function acceptFriendship($userID) { @@ -173,7 +186,7 @@ function acceptFriendship($userID) { $stmt->bindParam(':user1', $userID, PDO::PARAM_INT); $stmt->bindParam(':user2', $_SESSION["userID"], PDO::PARAM_INT); - $stmt->execute(); + return $stmt->execute(); } function setLastVisited($friend) { diff --git a/website/queries/post.php b/website/queries/post.php new file mode 100644 index 0000000..0183a5d --- /dev/null +++ b/website/queries/post.php @@ -0,0 +1,97 @@ +prepare(" + SELECT + `user`.`fname`, + `user`.`lname`, + `user`.`username`, + `post`.`groupID`, + `post`.`title`, + `post`.`content`, + `post`.`creationdate` + FROM + `post` + INNER JOIN + `user` + ON + `post`.`author` = `user`. `userID` + WHERE + `post`.`postID` = :postID + "); + + $stmt->bindParam(':postID', $postID); + $stmt->execute(); + return $stmt; +} + +function selectCommentsByPostId($postID) { + $stmt = $GLOBALS["db"]->prepare(" + SELECT + `comment`.`commentID`, + `comment`.`postID`, + `comment`.`author`, + `comment`.`content`, + `comment`.`creationdate`, + `user`.`fname`, + `user`.`lname`, + `user`.`username` + FROM + `comment` + INNER JOIN + `user` + ON + `comment`.`author` = `user`.`userID` + WHERE + `comment`.`postID` = :postID + "); + + $stmt->bindParam(':postID', $postID); + $stmt->execute(); + return $stmt; +} + +function makePost($userID, $groupID, $title, $content) { + $stmt = $GLOBALS["db"]->prepare(" + INSERT INTO + `post` ( + `author`, + `groupID`, + `title`, + `content` + ) + VALUES ( + :userID, + :groupID, + :title, + :content + ) + "); + + $stmt->bindParam(':userID', $userID); + $stmt->bindParam(':groupID', $groupID); + $stmt->bindParam(':title', $title); + $stmt->bindParam(':content', $content); + $stmt->execute(); +} + +function makeComment($postID, $userID, $content) { + $stmt = $_GLOBAL["db"]->prepare(" + INSERT INTO + `comment` ( + `postID`, + `author`, + `content` + ) + VALUES ( + :postID, + :userID, + :content + ) + "); + + $stmt->bindParam(':postID', $postID); + $stmt->bindParam(':userID', $userID); + $stmt->bindParam(':content', $content); + $stmt->execute(); +} \ No newline at end of file diff --git a/website/queries/register.php b/website/queries/register.php index 4700e72..738ef43 100644 --- a/website/queries/register.php +++ b/website/queries/register.php @@ -32,6 +32,22 @@ function getExistingEmail() { } +function getResetEmail() { + $stmt = $GLOBALS["db"]->prepare(" + SELECT + `email` + FROM + `user` + WHERE + `email` LIKE :email + "); + + $stmt->bindParam(":email", $_POST["forgotEmail"]); + $stmt->execute(); + return $stmt->rowCount(); + +} + function registerAccount() { $stmt = $GLOBALS["db"]->prepare(" INSERT INTO diff --git a/website/queries/requestpassword.php b/website/queries/requestpassword.php new file mode 100644 index 0000000..abf87c7 --- /dev/null +++ b/website/queries/requestpassword.php @@ -0,0 +1,55 @@ +prepare(" + SELECT + `userID`, + `username` + FROM + `user` + WHERE + `email` = :email + "); + $stmt->bindParam(":email", $email); + $stmt->execute(); + if (!$stmt->rowCount()) { + // TODO: Just stop. + return; + } + $result = $stmt->fetch(); + $userID = $result["userID"]; + $username = $result["username"]; + $hash = md5(random_int(0, 1000000)); + $hashedHash = password_hash($hash, PASSWORD_DEFAULT); + setHashToDatabase($userID, $hash); + doSendPasswordRecovery($userID, $email, $username, $hashedHash); + + + } else { + // TODO: Be angry! + } +} + +function doSendPasswordRecovery(int $userID, string $email, string $username, string $hash) { + $resetLink = "https://myhyvesbookplus.nl/resetpassword.php?u=$userID&h=$hash"; + + $subject = "Reset uw wachtwoord"; + $body = "Hallo $username,\r\n\r\nKlik op de onderstaande link om uw wachtwoord te resetten.\r\n\r\n$resetLink\r\n\r\nGroeten MyHyvesbook+"; + $header = "From: MyHyvesbook+