node_modules/**/* | |||||
.expo/* | |||||
npm-debug.* | |||||
*.jks | |||||
*.p8 | |||||
*.p12 | |||||
*.key | |||||
*.mobileprovision | |||||
*.orig.* | |||||
web-build/ | |||||
web-report/ | |||||
.idea/* | |||||
lettalk-release-key.keystore | |||||
*.iml | |||||
*.pem | |||||
trash | |||||
*.env | |||||
# macOS | |||||
.DS_Store |
{"email":"admin@ghd.de","username":"admin","password":"$2b$10$30zu4TwSjMdjmnGQ.Nr6C./Tu71kEhlUHkHso2bnkKkn7Pm2q.u3e","role":"admin","_id":"VxsdGrHioVlUga4q"} |
#!/bin/bash | |||||
#update sytem | |||||
sudo apt-get -y update | |||||
sudo apt-get -y upgrade | |||||
#enable and start ssh | |||||
sudo systemctl enable ssh | |||||
sudo systemctl start ssh | |||||
#install remote desktop | |||||
sudo apt-get -y install xrdp | |||||
#install nodejs | |||||
sudo apt-get -y install nodejs | |||||
#install npm | |||||
sudo apt-get -y install npm | |||||
#install firefox | |||||
sudo apt-get -y install firefox-esr | |||||
cd `dirname $0` | |||||
echo "`dirname $0`" | |||||
#get correct node modules | |||||
rm -rf node_modules | |||||
npm install express | |||||
npm install bcrypt | |||||
npm install nedb | |||||
npm install express-session | |||||
npm install nedb-session-store | |||||
#add server.start to autostart if not found | |||||
find="`grep server.start /etc/rc.local`" | |||||
if [ "$find" = "" ] | |||||
then | |||||
echo "adding server startup to /etc/rc.local" | |||||
cp /etc/rc.local "`pwd`" | |||||
sed -i '$d' rc.local | |||||
echo "`pwd`/server.start" >> rc.local | |||||
echo "exit 0" >> rc.local | |||||
sudo mv rc.local /etc/rc.local | |||||
else | |||||
echo "server startup already in /etc/rc.local" | |||||
fi | |||||
#add firefox start in kiosk mode after logged in | |||||
find="`grep firefox ~/.profile`" | |||||
if [ "$find" = "" ] | |||||
then | |||||
echo "adding firefox start to ~/.profile" | |||||
echo "firefox --kiosk http://localhost:8080/info &" >> ~/.profile | |||||
else | |||||
echo "firefox start already found in ~/.profile" | |||||
fi | |||||
sudo chmod +x server.start | |||||
echo "network/mac adress:`hostname -I`" | |||||
#system restart | |||||
echo "System will restart in 10s. ^C to cancel" | |||||
sleep 10 | |||||
sudo reboot -h now |
{ | |||||
"name": "NodeHelp", | |||||
"version": "1.0.0", | |||||
"dependencies": { | |||||
"body-parser": "^1.19.0", | |||||
"express": "^4.17.1", | |||||
"nedb": "^1.8.0", | |||||
"nedb-session-store": "^1.1.2" | |||||
}, | |||||
"devDependencies": { | |||||
"bcrypt": "^5.0.0", | |||||
"express-session": "^1.17.1" | |||||
} | |||||
} |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<title>Admin-Page</title> | |||||
<link rel="stylesheet" text="text/css" href="styles.css"> | |||||
<script src="admin.js"></script> | |||||
<!--Font Awesome Icons CDN--> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<div class=main> | |||||
<div class="container user-container"> | |||||
<div class="header"> | |||||
<h1>Adminseite</h1> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="lgoBtn">Logout</button> | |||||
<div class="rightButtons"> | |||||
<button class="manageButton" id="mngBtn">Manage Posts</button> | |||||
<button data-popup-target="#addPopup" id="addBtn">+</button> | |||||
<div class="popup" id="addPopup"> | |||||
<div class="popup-header"> | |||||
<div class="title">Registration Form</div> | |||||
<button data-close-btn class="close-btn">×</button> | |||||
</div> | |||||
<div class="popup-body"> | |||||
<form class="" id="formNewUser" method="POST"> | |||||
<div class="regSection"> | |||||
<input type="email" id="email" required placeholder="e-Mail"> | |||||
</div> | |||||
<div class="regSection"> | |||||
<input type="text" id="username" required placeholder="Username"> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button type="submit" value="Create" id="submit"> | |||||
Submit | |||||
</button> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
<div class="" id="overlay"></div> | |||||
</div> | |||||
</div> | |||||
<div class="table" id="table"> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="changePwBtn">Change Password</button> | |||||
<div class="rightButtons"> | |||||
<button class="icon-backward , backButton" id="pageDown"></button> | |||||
<button class="icon-forward , nextButton" id="pageUp"></button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
var form = document.getElementById("formNewUser"); | |||||
form.addEventListener("submit", function(e){ | |||||
e.preventDefault(); | |||||
console.log("Sending Formular") | |||||
async function register(){ | |||||
var email = document.getElementById("email").value; | |||||
var username = document.getElementById("username").value; | |||||
var bodyContent = {email:email, username:username}; | |||||
var response = await fetch("/newmod", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify(bodyContent) | |||||
}); | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
loadMods(); | |||||
} | |||||
register(); | |||||
}); | |||||
document.getElementById("changePwBtn").onclick = function(){ | |||||
window.location = "/new-password"; | |||||
} | |||||
/*changin page*/ | |||||
var pageUp = document.getElementById("pageUp"); | |||||
var pageDown = document.getElementById("pageDown"); | |||||
pageUp.addEventListener("click", () => { | |||||
if(maxPages > currentPage+1) { | |||||
currentPage++; | |||||
loadMods(); | |||||
} | |||||
}); | |||||
pageDown.addEventListener("click", () => { | |||||
if(currentPage > 0){ | |||||
currentPage--; | |||||
loadMods(); | |||||
} | |||||
}); | |||||
/*logout*/ | |||||
var lgoBtn = document.getElementById("lgoBtn"); | |||||
lgoBtn.addEventListener("click", () => { | |||||
window.location = "/logout"; | |||||
}); | |||||
var maxPages; | |||||
var currentPage = 0; | |||||
var maxDisplayed = 8; | |||||
async function loadMods(){ | |||||
var response = await fetch("/getmods", { | |||||
method: "GET", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
} | |||||
}) | |||||
var data = await response.json(); | |||||
try{ | |||||
showMods(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
maxPages = data.users.length / 8; | |||||
console.log(maxPages, currentPage+1) | |||||
}catch(error){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
} | |||||
}; | |||||
loadMods(); | |||||
function showMods(pdata){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
var container = document.getElementById("table"); //insert in table | |||||
pdata.forEach(element => { | |||||
var row = document.createElement("div"); | |||||
var status; | |||||
var susbuttonstate; | |||||
if(element.suspended) { | |||||
status = "suspended" | |||||
susbuttonstate = "icon-pause" | |||||
} else { | |||||
status = "notSuspended" | |||||
susbuttonstate = "icon-play" | |||||
} | |||||
row.classList.add("row"); | |||||
row.innerHTML = ` | |||||
<div class="col-left"> | |||||
<h2>${element.username}</h2> | |||||
</div> | |||||
<div class="col-right"> | |||||
<button class="${status} susButton" data-username="${element.username}"> | |||||
<i class="${susbuttonstate} , icon"></i> | |||||
</button> | |||||
<button class="remButton" data-username="${element.username}"> | |||||
<i class="icon-trash , icon"></i> | |||||
</button> | |||||
</div> | |||||
` | |||||
container.appendChild(row) | |||||
}); | |||||
} | |||||
async function toggleSus(pun){ | |||||
var response = await fetch("/toggleSus", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({username:pun}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadMods(); | |||||
} | |||||
}; | |||||
async function deleteMod(username){ | |||||
var response = await fetch("/deleteMod", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({username:username}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadMods(); | |||||
} | |||||
}; | |||||
var mngBtn = document.getElementById("mngBtn"); | |||||
mngBtn.addEventListener("click", () => { | |||||
window.location = "/manage-posts"; | |||||
}); | |||||
document.addEventListener("click", function(e){ | |||||
if(e.target && e.target.classList.contains("susButton")){ | |||||
var un = e.target.getAttribute("data-username"); | |||||
toggleSus(un); | |||||
}else if(e.target && e.target.classList.contains("remButton")){ | |||||
var username = e.target.getAttribute("data-username"); | |||||
deleteMod(username); | |||||
} | |||||
}) | |||||
/*-----New User Popup-----*/ | |||||
const openPopupBtns = document.querySelectorAll("[data-popup-target]"); | |||||
const closePopupBtns = document.querySelectorAll("[data-close-btn]"); | |||||
const overlay = document.getElementById("overlay"); | |||||
openPopupBtns.forEach(btn => { | |||||
btn.addEventListener("click", () => { | |||||
const popup = document.querySelector(btn.dataset.popupTarget); | |||||
openPopup(popup); | |||||
}) | |||||
}); | |||||
closePopupBtns.forEach(btn => { | |||||
btn.addEventListener("click", () => { | |||||
const popup = btn.closest(".popup") | |||||
closePopup(popup); | |||||
}) | |||||
}); | |||||
function openPopup(popup) { | |||||
if (popup == null) return | |||||
popup.classList.add("active"); | |||||
overlay.classList.add("active"); | |||||
} | |||||
function closePopup(popup) { | |||||
if (popup == null) return | |||||
popup.classList.remove("active"); | |||||
overlay.classList.remove("active"); | |||||
} | |||||
}); |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=2.0"> | |||||
<title>Change Password</title> | |||||
<link rel="stylesheet" text="text/css" href="styles.css"> | |||||
<script src="change-pw.js"></script> | |||||
</head> | |||||
<body> | |||||
<div class="main"> | |||||
<div class="container"> | |||||
<div class="header"> | |||||
<h1>Change Password</h1> | |||||
</div> | |||||
<form name="login" method="post" id="loginform"> | |||||
<div class="datasec"> | |||||
<input class="password" type="password" name="password" id="old_pw" required placeholder="Old Password"> | |||||
</div> | |||||
<div class="datasec"> | |||||
<input class="password" type="password" name="password" id="new_pw_1" required placeholder="New Password"> | |||||
</div> | |||||
<div class="datasec"> | |||||
<input class="password" type="password" name="password" id="new_pw_2" required placeholder="Confirm Password"> | |||||
</div> | |||||
<div class="buttons-container"> | |||||
<button class="button" | |||||
type="submit" | |||||
name="submit"> | |||||
<span id="loginText">Change Password</span> | |||||
</button> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
//write code in next section | |||||
//will run when DOM is loaded | |||||
document.addEventListener("DOMContentLoaded", function(){ | |||||
var form = document.getElementById("loginform"); | |||||
async function login() { | |||||
var old_pw = document.getElementById("old_pw").value; | |||||
var new_pw_1 = document.getElementById("new_pw_1").value; | |||||
var new_pw_2 = document.getElementById("new_pw_2").value; | |||||
var body = {old_password:old_pw, new_password_1:new_pw_1, new_password_2:new_pw_2}; | |||||
var response = await fetch("/changepw", { | |||||
method:"POST", | |||||
headers:{ | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify(body) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log("Data: "); | |||||
console.log(data); | |||||
if(data.suc){ | |||||
window.location = "/main" | |||||
} | |||||
} | |||||
form.addEventListener("submit", function(e){ | |||||
e.preventDefault(); | |||||
login(); | |||||
}); | |||||
}); |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=2.0"> | |||||
<title>Login</title> | |||||
<link rel="stylesheet" text="text/css" href="styles.css"> | |||||
<script src="login.js"></script> | |||||
</head> | |||||
<body> | |||||
<div class="main"> | |||||
<div class="container"> | |||||
<div class="header"> | |||||
<h1>Login</h1> | |||||
</div> | |||||
<form name="login" method="post" id="loginform"> | |||||
<div class="datasec"> | |||||
<input class="username" type="text" name="username" id="un" required placeholder="Username" autocomplete="off"> | |||||
</div> | |||||
<div class="datasec"> | |||||
<input class="password" type="password" name="password" id="pw" required placeholder="Password"> | |||||
</div> | |||||
<div class="buttons-container"> | |||||
<button class="button" | |||||
type="submit" | |||||
name="submit"> | |||||
<span id="loginText">Log In</span> | |||||
</button> | |||||
</div> | |||||
</form> | |||||
<button class="button" id="prev"> | |||||
<span>Preview</span> | |||||
</button> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset='utf-8'> | |||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'> | |||||
<title>InfoTafel</title> | |||||
<meta name='viewport' content='width=device-width, initial-scale=1'> | |||||
<link rel='stylesheet' type='text/css' media='screen' href='styles.css'> | |||||
<script src='info-page.js'></script> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
<meta name="viewport" content="width=device-width"> | |||||
</head> | |||||
<body> | |||||
<div class="TitleRow" id="topper"> | |||||
<div class="titleDiv"></div> | |||||
<div class="titleDiv"> | |||||
<h1>Infoseite</h1> | |||||
<h3>Brought to you by Th-Nürnberg</h3> | |||||
</div> | |||||
<div class="titleDiv"> | |||||
<h2 id="clock"></h2> | |||||
</div> | |||||
</div> | |||||
<div id="content"> | |||||
</div> | |||||
<div id="lower"> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
var SwitchTime = 10; // in Seconds | |||||
document.getElementById("topper").onclick = function(){ | |||||
window.location = "/main"; | |||||
} | |||||
var maxPages; | |||||
var currentPage = 0; | |||||
var maxDisplayed = 6; | |||||
async function loadPosts(){ | |||||
var response = await fetch("/getliveposts", { | |||||
method: "GET", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
} | |||||
}) | |||||
var data = await response.json(); | |||||
//console.log(data); | |||||
try{ | |||||
showPosts(data.posts.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
//console.log(data.posts.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
maxPages = data.posts.length / maxDisplayed; | |||||
//console.log(maxPages, currentPage+1) | |||||
}catch(error){ | |||||
document.getElementById("content").innerHTML = ""; //empty content | |||||
} | |||||
}; | |||||
loadPosts(); | |||||
function showPosts(pdata){ | |||||
var container = document.getElementById("content"); //insert in content | |||||
container.innerHTML = "" //empty content | |||||
pdata.forEach(element => { | |||||
var post = document.createElement("div"); | |||||
post.classList.add("post"); | |||||
post.style.backgroundColor = element.bcolor; | |||||
post.innerHTML = ` | |||||
<div class="title" style="background-color:${element.bcolor};"> | |||||
<h2 class="preview-title" >${element.title}</h2> | |||||
</div> | |||||
<div class="body"> | |||||
${element.text} | |||||
</div> | |||||
` | |||||
container.appendChild(post) | |||||
}); | |||||
} | |||||
function startTime() { | |||||
var today = new Date(); | |||||
var h = today.getHours(); | |||||
var m = today.getMinutes(); | |||||
var s = today.getSeconds(); | |||||
h = checkTime(h); | |||||
m = checkTime(m); | |||||
s = checkTime(s); | |||||
document.getElementById('clock').innerHTML = | |||||
h + ":" + m + ":" + s; | |||||
var t = setTimeout(startTime, 500); | |||||
} | |||||
function checkTime(i) { | |||||
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10 | |||||
return i; | |||||
} | |||||
startTime(); | |||||
function changePage(){ | |||||
if(maxPages > currentPage+1) { | |||||
currentPage++; | |||||
} | |||||
else{ | |||||
currentPage = 0; | |||||
loadPosts(); | |||||
} | |||||
loadPosts(); | |||||
setTimeout(changePage, SwitchTime*1000); | |||||
} | |||||
changePage(); | |||||
}); | |||||
//write code in next section | |||||
//will run when DOM is loaded | |||||
document.addEventListener("DOMContentLoaded", function(){ | |||||
var form = document.getElementById("loginform"); | |||||
async function login() { | |||||
var un = document.getElementById("un").value; | |||||
var pw = document.getElementById("pw").value; | |||||
var body = {username:un, password:pw}; | |||||
var response = await fetch("/login", { | |||||
method:"POST", | |||||
headers:{ | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify(body) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log("Data: "); | |||||
console.log(data); | |||||
if(data.suc){ | |||||
window.location = "/main" | |||||
} else { | |||||
var loginText = document.getElementById("loginText"); | |||||
var inputs = document.getElementsByTagName("input") | |||||
var inputList = Array.prototype.slice.call(inputs); | |||||
loginText.classList.add("fadeout"); | |||||
setTimeout(function() { | |||||
loginText.innerText = "Try Again"; | |||||
loginText.classList.remove("fadeout"); | |||||
}, 350); | |||||
console.log(inputs); | |||||
inputList.forEach(element => { | |||||
element.style.borderBottom="1px solid #F00"; | |||||
if(element.getAttribute("type") === "password"){ | |||||
element.value = ""; | |||||
element.focus(); | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
form.addEventListener("submit", function(e){ | |||||
e.preventDefault(); | |||||
login(); | |||||
}); | |||||
var prevBtn = document.getElementById("prev") | |||||
prevBtn.addEventListener("click", function(){ | |||||
window.location ="/info" | |||||
}) | |||||
}); |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<title>Manage-Posts</title> | |||||
<link rel="stylesheet" text="text/css" href="styles.css"> | |||||
<script src="manage-post.js"></script> | |||||
<!--Font Awesome Icons CDN--> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<div class=main> | |||||
<div class="container user-container"> | |||||
<div class="header"> | |||||
<h1>Manage Posts</h1> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="lgoBtn">Logout</button> | |||||
<div class="rightButtons"> | |||||
<button class="manageButton" id="mngBtn">Manage Group</button> | |||||
</div> | |||||
</div> | |||||
<div class="table" id="table"> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<div></div> | |||||
<div class="rightButtons"> | |||||
<button class="icon-backward , backButton" id="pageDown"></button> | |||||
<button class="icon-forward , nextButton" id="pageUp"></button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
/*changin page*/ | |||||
var pageUp = document.getElementById("pageUp"); | |||||
var pageDown = document.getElementById("pageDown"); | |||||
var reviewButtons = document.getElementsByClassName('editButton'); | |||||
pageUp.addEventListener("click", () => { | |||||
if(maxPages > currentPage+1) { | |||||
currentPage++; | |||||
loadPosts(); | |||||
} | |||||
}); | |||||
pageDown.addEventListener("click", () => { | |||||
if(currentPage > 0){ | |||||
currentPage--; | |||||
loadPosts(); | |||||
} | |||||
}); | |||||
/*logout*/ | |||||
var lgoBtn = document.getElementById("lgoBtn"); | |||||
lgoBtn.addEventListener("click", () => { | |||||
window.location = "/logout"; | |||||
}); | |||||
var mngBtn = document.getElementById("mngBtn"); | |||||
mngBtn.addEventListener("click", () => { | |||||
window.location = "/main"; | |||||
}); | |||||
async function toggleSus(postid){ | |||||
var response = await fetch("/toggleShow", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({postid:postid}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadPosts(); | |||||
} | |||||
}; | |||||
async function deletePost(postid){ | |||||
var response = await fetch("/deletePost", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({postid:postid}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadPosts(); | |||||
} | |||||
}; | |||||
document.addEventListener("click", function(e){ | |||||
if(e.target && e.target.classList.contains("susButton")){ | |||||
var postid = e.target.getAttribute("data-username"); | |||||
toggleSus(postid); | |||||
}else if(e.target && e.target.classList.contains("remButton")){ | |||||
var postid = e.target.getAttribute("data-username"); | |||||
deletePost(postid); | |||||
} | |||||
}) | |||||
/*Show Elements*/ | |||||
var maxPages; | |||||
var currentPage = 0; | |||||
var maxDisplayed = 8; | |||||
async function loadPosts(){ | |||||
var response = await fetch("/getposts", { | |||||
method: "GET", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
} | |||||
}) | |||||
var data = await response.json(); | |||||
try{ | |||||
showPosts(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
maxPages = data.users.length / 8; | |||||
console.log(maxPages, currentPage+1) | |||||
reviewButtons = document.getElementsByClassName('editButton'); | |||||
console.log(reviewButtons.length); | |||||
addButtons(); | |||||
}catch(error){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
} | |||||
}; | |||||
loadPosts(); | |||||
function showPosts(pdata){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
var container = document.getElementById("table"); //insert in table | |||||
pdata.forEach(element => { | |||||
var row = document.createElement("div"); | |||||
var status; | |||||
var susbuttonstate; | |||||
if(!element.showpost) { | |||||
status = "hidden" | |||||
susbuttonstate = "icon-eye-close" | |||||
} else { | |||||
status = "shown" | |||||
susbuttonstate = "icon-eye-open" | |||||
} | |||||
row.classList.add("row"); | |||||
row.innerHTML = ` | |||||
<div class="col-left"> | |||||
<h2>${element.title}</h2> | |||||
</div> | |||||
<div class="col-right"> | |||||
<button class="editButton" data-username="${element.postid}"> | |||||
<i class="icon-file-text-alt , icon"></i> | |||||
</button> | |||||
<button class="${status} susButton" data-username="${element.postid}"> | |||||
<i class="${susbuttonstate} , icon"></i> | |||||
</button> | |||||
<button class="remButton" data-username="${element.postid}"> | |||||
<i class="icon-trash , icon"></i> | |||||
</button> | |||||
</div> | |||||
` | |||||
container.appendChild(row) | |||||
}); | |||||
} | |||||
async function reviewPost(postid){ | |||||
var response = await fetch("/updatePostID", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({postid:postid}) | |||||
}) | |||||
var data = await response.json(); | |||||
if(data || !data) | |||||
{ | |||||
window.location = "/post-review"; | |||||
} | |||||
}; | |||||
function addButtons(){ | |||||
for(let i = 0; i < reviewButtons.length; i++){ | |||||
reviewButtons[i].addEventListener('click', function(){ | |||||
reviewPost(this.dataset.username) | |||||
}) | |||||
} | |||||
} | |||||
}); |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<title>Mod-Page</title> | |||||
<link rel="stylesheet" text="text/css" href="styles.css"> | |||||
<script src="mod.js"></script> | |||||
<!--Font Awesome Icons CDN--> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<div class=main> | |||||
<div class="container user-container"> | |||||
<div class="header"> | |||||
<h1>Modseite</h1> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="lgoBtn">Logout</button> | |||||
<div class="rightButtons"> | |||||
<button class="manageButton" id="mngBtn">Manage Posts</button> | |||||
<button data-popup-target="#addPopup" id="addBtn">+</button> | |||||
<div class="popup" id="addPopup"> | |||||
<div class="popup-header"> | |||||
<div class="title">Registration Form</div> | |||||
<button data-close-btn class="close-btn">×</button> | |||||
</div> | |||||
<div class="popup-body"> | |||||
<form class="" id="formNewUser" method="POST"> | |||||
<div class="regSection"> | |||||
<input type="email" id="email" required placeholder="e-Mail"> | |||||
</div> | |||||
<div class="regSection"> | |||||
<input type="text" id="username" required placeholder="Username"> | |||||
</div> | |||||
<div class="btn"> | |||||
<button type="submit" value="Create" id="submit"> | |||||
<span>Submit</span> | |||||
</button> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
<div class="" id="overlay"></div> | |||||
</div> | |||||
</div> | |||||
<div class="table" id="table"> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="changePwBtn">Change Password</button> | |||||
<div class="rightButtons"> | |||||
<button class="icon-backward , backButton" id="pageDown"></button> | |||||
<button class="icon-forward , nextButton" id="pageUp"></button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
var form = document.getElementById("formNewUser"); | |||||
form.addEventListener("submit", function(e){ | |||||
e.preventDefault(); | |||||
console.log("Sending Formular") | |||||
async function register(){ | |||||
var email = document.getElementById("email").value; | |||||
var username = document.getElementById("username").value; | |||||
var bodyContent = {email:email, username:username}; | |||||
var response = await fetch("/newuser", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify(bodyContent) | |||||
}); | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
loadUsers(); | |||||
} | |||||
register(); | |||||
}); | |||||
document.getElementById("changePwBtn").onclick = function(){ | |||||
window.location = "/new-password"; | |||||
} | |||||
/*changin page*/ | |||||
var pageUp = document.getElementById("pageUp"); | |||||
var pageDown = document.getElementById("pageDown"); | |||||
pageUp.addEventListener("click", () => { | |||||
if(maxPages > currentPage+1) { | |||||
currentPage++; | |||||
loadUsers(); | |||||
} | |||||
}); | |||||
pageDown.addEventListener("click", () => { | |||||
if(currentPage > 0){ | |||||
currentPage--; | |||||
loadUsers(); | |||||
} | |||||
}); | |||||
/*logout*/ | |||||
var lgoBtn = document.getElementById("lgoBtn"); | |||||
lgoBtn.addEventListener("click", () => { | |||||
window.location = "/logout"; | |||||
}); | |||||
var mngBtn = document.getElementById("mngBtn"); | |||||
mngBtn.addEventListener("click", () => { | |||||
window.location = "/manage-posts"; | |||||
}); | |||||
var maxPages; | |||||
var currentPage = 0; | |||||
var maxDisplayed = 8; | |||||
async function loadUsers(){ | |||||
var response = await fetch("/getusers", { | |||||
method: "GET", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
} | |||||
}) | |||||
var data = await response.json(); | |||||
try{ | |||||
showUsers(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
maxPages = data.users.length / 8; | |||||
console.log(maxPages, currentPage+1) | |||||
}catch(error){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
} | |||||
}; | |||||
loadUsers(); | |||||
function showUsers(pdata){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
var container = document.getElementById("table"); //insert in table | |||||
pdata.forEach(element => { | |||||
var row = document.createElement("div"); | |||||
var status; | |||||
var susbuttonstate; | |||||
if(element.suspended) { | |||||
status = "suspended" | |||||
susbuttonstate = "icon-pause" | |||||
} else { | |||||
status = "notSuspended" | |||||
susbuttonstate = "icon-play" | |||||
} | |||||
row.classList.add("row"); | |||||
row.innerHTML = ` | |||||
<div class="col-left"> | |||||
<h2>${element.username}</h2> | |||||
</div> | |||||
<div class="col-right"> | |||||
<button class="${status} susButton" data-username="${element.username}"> | |||||
<i class="${susbuttonstate} , icon"></i> | |||||
</button> | |||||
<button class="remButton" data-username="${element.username}"> | |||||
<i class="icon-trash , icon"></i> | |||||
</button> | |||||
</div> | |||||
` | |||||
container.appendChild(row) | |||||
}); | |||||
} | |||||
async function toggleSus(pun){ | |||||
var response = await fetch("/toggleSus", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({username:pun}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadUsers(); | |||||
} | |||||
}; | |||||
async function deleteUser(username){ | |||||
var response = await fetch("/deleteUser", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({username:username}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadUsers(); | |||||
} | |||||
}; | |||||
document.addEventListener("click", function(e){ | |||||
if(e.target && e.target.classList.contains("susButton")){ | |||||
var un = e.target.getAttribute("data-username"); | |||||
toggleSus(un); | |||||
}else if(e.target && e.target.classList.contains("remButton")){ | |||||
var username = e.target.getAttribute("data-username"); | |||||
deleteUser(username); | |||||
} | |||||
}) | |||||
/*-----New User Popup-----*/ | |||||
const openPopupBtns = document.querySelectorAll("[data-popup-target]"); | |||||
const closePopupBtns = document.querySelectorAll("[data-close-btn]"); | |||||
const overlay = document.getElementById("overlay"); | |||||
openPopupBtns.forEach(btn => { | |||||
btn.addEventListener("click", () => { | |||||
const popup = document.querySelector(btn.dataset.popupTarget); | |||||
openPopup(popup); | |||||
}) | |||||
}); | |||||
closePopupBtns.forEach(btn => { | |||||
btn.addEventListener("click", () => { | |||||
const popup = btn.closest(".popup") | |||||
closePopup(popup); | |||||
}) | |||||
}); | |||||
function openPopup(popup) { | |||||
if (popup == null) return | |||||
popup.classList.add("active"); | |||||
overlay.classList.add("active"); | |||||
} | |||||
function closePopup(popup) { | |||||
if (popup == null) return | |||||
popup.classList.remove("active"); | |||||
overlay.classList.remove("active"); | |||||
} | |||||
}); |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset='utf-8'> | |||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'> | |||||
<title>Post Editor</title> | |||||
<meta name='viewport' content='width=device-width, initial-scale=1'> | |||||
<link rel='stylesheet' type='text/css' media='screen' href='styles.css'> | |||||
<script src='new-Postv2.js'></script> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<div class="main"> | |||||
<div class="container postContainer" id="box"> | |||||
<div class=topper> | |||||
<button id="cancelBtn" title="Cancel">×</button> | |||||
</div> | |||||
<div class="editor"> | |||||
<div class="editor-menubar"> | |||||
<button class="editor-button icon-picture" data-popup-target="#addPopup" data-attribute="insertImage" title="Add Image"></button> | |||||
<div class="" id="overlay"></div> | |||||
<div class="popup" id="addPopup"> | |||||
<div class="popup-header"> | |||||
<div class="title">Add Picture</div> | |||||
<button data-close-btn class="close-btn">×</button> | |||||
</div> | |||||
<div class="popup-body"> | |||||
<div class="" id="formNewUser"> | |||||
<div class="regSection"> | |||||
<input type="text" id="url" required placeholder="URL"> | |||||
</div> | |||||
<div class="btn"> | |||||
<button type="submit" value="Create" id="add"> | |||||
<span>Add</span> | |||||
</button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<button class="editor-button icon-bold" data-attribute="bold" title="Bold"></button> | |||||
<button class="editor-button icon-italic" data-attribute="italic" title="Italic"></button> | |||||
<button class="editor-button icon-underline" data-attribute="underline" title="Underline"></button> | |||||
<button class="editor-button icon-superscript" data-attribute="superscript" title="Superscript"></button> | |||||
<button class="editor-button icon-subscript" data-attribute="subscript" title="Subscript"></button> | |||||
<input class="color-select" data-attribute="forecolor" type="color" id="forecolor" title="Text Colour"> | |||||
</div> | |||||
<div id="title-text"> | |||||
<div class="canvas" id="title-canvas" contenteditable=true data-text="Title"></div> | |||||
<div class="canvas" id="editor-canvas" contenteditable=true data-text="Content"></div> | |||||
</div> | |||||
<div class="editor-menubar"> | |||||
<button class="editor-button icon-undo" data-attribute="undo" title="Undo"></button> | |||||
<button class="editor-button icon-repeat" data-attribute="redo" title="Redo"></button> | |||||
<button class="editor-button icon-align-left" data-attribute="justifyleft" title="Justify Left"></button> | |||||
<button class="editor-button icon-align-center" data-attribute="justifycenter" title="Justify Center"></button> | |||||
<button class="editor-button icon-align-right" data-attribute="justifyright" title="Justify Right"></button> | |||||
<input class="color-select" data-attribute="backcolor" type="color" id="backcolor" title="Background Colour" value="#ffffff"> | |||||
</div> | |||||
</div> | |||||
<div class="lower"> | |||||
<div class="calendar"> | |||||
<label for="start">Start date:</label> | |||||
<input class="calendar-element" type="date" id="startDate" value=2020-01-01 min=2020-01-01> | |||||
</div> | |||||
<div class="calendar"> | |||||
<label for="start">End date:</label> | |||||
<input class="calendar-element" type="date" id="endDate" value=2020-01-01 min=2020-01-01> | |||||
</div> | |||||
<button id="submit-post">Submit</button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
const editorButtons = document.getElementsByClassName('editor-button'); | |||||
const setAttribute = (element) => { | |||||
document.execCommand(element.dataset.attribute, false); | |||||
}; | |||||
for(let i = 0; i <editorButtons.length; i++) { | |||||
editorButtons[i].addEventListener('click', function(){ | |||||
setAttribute(this); | |||||
}); | |||||
} | |||||
document.getElementById("cancelBtn").onclick = function(){ | |||||
window.location = "/main"; | |||||
} | |||||
document.getElementById("add").onclick = function(){ | |||||
document.execCommand("insertImage", false, document.getElementById("url").value); | |||||
} | |||||
document.getElementById("forecolor").onchange = function(){setColor(this);} | |||||
const setColor = (element) => { | |||||
console.log(element); | |||||
document.execCommand(element.dataset.attribute, false, element.value); | |||||
}; | |||||
const backColor = document.getElementById("backcolor"); | |||||
const helo = document.getElementsByClassName("canvas"); | |||||
backColor.addEventListener('change', function(){ | |||||
console.log(this); | |||||
for(let i = 0; i <helo.length; i++) { | |||||
helo[i].style.backgroundColor = backColor.value; | |||||
}; | |||||
}); | |||||
document.getElementById("submit-post").onclick = function(){ | |||||
if(document.getElementById('title-canvas').innerHTML && document.getElementById('editor-canvas').innerHTML) | |||||
{ | |||||
const title = document.getElementById('title-canvas').innerHTML; | |||||
const content = document.getElementById('editor-canvas').innerHTML; | |||||
const date_begin = document.getElementById('startDate').value; | |||||
const date_end = document.getElementById('endDate').value; | |||||
const bcolor = document.getElementById('backcolor').value; | |||||
var bodyContent = {title:title, text:content, startDate:date_begin, endDate:date_end, bcolor:bcolor}; | |||||
send(bodyContent); | |||||
} | |||||
}; | |||||
async function send(bodyContent){ | |||||
console.log(bodyContent); | |||||
var response = await fetch("/newpost", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify(bodyContent) | |||||
}); | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
console.log(helo); | |||||
window.location = "/main"; | |||||
} | |||||
/*-----New User Popup-----*/ | |||||
const openPopupBtns = document.querySelectorAll("[data-popup-target]"); | |||||
const closePopupBtns = document.querySelectorAll("[data-close-btn]"); | |||||
const overlay = document.getElementById("overlay"); | |||||
openPopupBtns.forEach(btn => { | |||||
btn.addEventListener("click", () => { | |||||
const popup = document.querySelector(btn.dataset.popupTarget); | |||||
openPopup(popup); | |||||
}) | |||||
}); | |||||
closePopupBtns.forEach(btn => { | |||||
btn.addEventListener("click", () => { | |||||
const popup = btn.closest(".popup") | |||||
closePopup(popup); | |||||
}) | |||||
}); | |||||
function openPopup(popup) { | |||||
if (popup == null) return | |||||
popup.classList.add("active"); | |||||
overlay.classList.add("active"); | |||||
} | |||||
function closePopup(popup) { | |||||
if (popup == null) return | |||||
popup.classList.remove("active"); | |||||
overlay.classList.remove("active"); | |||||
} | |||||
document.getElementById("startDate").onchange = function(){ | |||||
document.getElementById("endDate").min = document.getElementById("startDate").value; | |||||
var end = new Date(document.getElementById("startDate").value); | |||||
end.setDate(end.getDate() +7); | |||||
var endDate = end.toISOString().slice(0,10); | |||||
document.getElementById("endDate").value = endDate; | |||||
} | |||||
function date(){ | |||||
var today = new Date().toISOString().slice(0,10); | |||||
var end = new Date(); | |||||
end.setDate(end.getDate() + 7) | |||||
var endDate = end.toISOString().slice(0,10); | |||||
document.getElementById("startDate").value = today; | |||||
document.getElementById("startDate").min = today; | |||||
document.getElementById("endDate").value = endDate; | |||||
document.getElementById("endDate").min = today; | |||||
}; | |||||
date() | |||||
}); |
<!DOCTYPE html> | |||||
<html> | |||||
<head> | |||||
<meta charset='utf-8'> | |||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'> | |||||
<title>Post Editor</title> | |||||
<meta name='viewport' content='width=device-width, initial-scale=1'> | |||||
<link rel='stylesheet' type='text/css' media='screen' href='styles.css'> | |||||
<script src='post-review.js'></script> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<div class="main"> | |||||
<div class="container postContainer" id="box"> | |||||
<div class=topper> | |||||
<button id="cancelBtn" title="Cancel">×</button> | |||||
</div> | |||||
<div id="title-text"> | |||||
<div class="canvas" id="title-canvas" data-text="Title"></div> | |||||
<div class="canvas" id="editor-canvas" data-text="Content"></div> | |||||
</div> | |||||
<div class="lower"> | |||||
<button id="submit-post"></button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
document.getElementById("cancelBtn").onclick = function(){ | |||||
window.location = "/main"; | |||||
} | |||||
var id; | |||||
async function loadPost(){ | |||||
var response = await fetch("/getReviewPost", { | |||||
method: "GET", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
} | |||||
}) | |||||
var data = await response.json(); | |||||
id = data.post[0].postid; | |||||
document.getElementsByClassName("canvas")[0].style.backgroundColor = data.post[0].bcolor; | |||||
document.getElementsByClassName("canvas")[1].style.backgroundColor = data.post[0].bcolor; | |||||
document.getElementById("title-canvas").innerHTML = data.post[0].title; | |||||
document.getElementById("editor-canvas").innerHTML = data.post[0].text; | |||||
if(data.post[0].showpost) { | |||||
document.getElementById("submit-post").innerHTML = "Suspend Post" | |||||
} else { | |||||
document.getElementById("submit-post").innerHTML = "Confirm Post" | |||||
} | |||||
}; | |||||
loadPost(); | |||||
document.getElementById("submit-post").onclick = function(){ | |||||
toggleShow(id); | |||||
} | |||||
async function toggleShow(pun){ | |||||
var response = await fetch("/toggleShow", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({postid:pun}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
window.location = "/main" | |||||
} | |||||
}; | |||||
}); |
:root { | |||||
--border-prop: 0px solid #F2F; | |||||
--header-height: 10%; | |||||
--prime-color: rgb(71, 17, 221); | |||||
--container-bg: rgba(30, 30, 50, 0.644); | |||||
--text-color: rgba(255,255,255, 1); | |||||
--row-color: rgba(0, 0, 100, 0.3); | |||||
--button-prim: rgba(255,255,255,0.1); | |||||
--button-sec: rgba(255, 255, 255, 0.4); | |||||
--popup-border: 2px solid rgb(11, 11, 128); | |||||
--popup-stripe: 3px solid rgba(0,0,50,0.5); | |||||
--title-size: 60px; | |||||
--text-size: 30px; | |||||
--smal-text: 20px; | |||||
} | |||||
div{ | |||||
border: 0px #F2F; | |||||
border-style: dashed; | |||||
} | |||||
html, body { | |||||
width: 100%; | |||||
height: 100%; | |||||
background: var(--prime-color); | |||||
margin: 0; | |||||
} | |||||
header{ | |||||
height: var(--header-height); | |||||
padding-top: 30px; | |||||
display: flex; | |||||
justify-content: center; | |||||
} | |||||
/*text*/ | |||||
h1, h2, h3, .title, label{ | |||||
font-size: var(--title-size); | |||||
padding: 0px; | |||||
margin: 0px; | |||||
font-family: Arial; | |||||
color: var(--text-color); | |||||
} | |||||
h2, label{ | |||||
font-size: var(--text-size); | |||||
} | |||||
h3{ | |||||
font-size: var(--smal-text); | |||||
} | |||||
input { | |||||
width: 100%; | |||||
font-family: Arial; | |||||
font-size: 2em; | |||||
color: rgb(255, 255, 255); | |||||
padding: 0; | |||||
padding-bottom: 5px; | |||||
background: none; | |||||
border: none; | |||||
border-bottom: 1px solid #ffffff; | |||||
margin-bottom: 15px; | |||||
margin-top: 15px | |||||
} | |||||
input:focus { | |||||
outline: 0; | |||||
} | |||||
.main { | |||||
width: 100%; | |||||
height: 100%; | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: center; | |||||
} | |||||
.container{ | |||||
width: 400px; | |||||
border: var(--border-prop); | |||||
background-color: var(--container-bg); | |||||
padding: 20px; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.user-container{ | |||||
width: 50%; | |||||
min-height: 35em; | |||||
} | |||||
.header { | |||||
border: var(--border-prop); | |||||
font-size: 25px; | |||||
text-align: center; | |||||
margin-bottom: 25px; | |||||
} | |||||
.datasec { | |||||
border: var(--border-prop); | |||||
font-family: Arial; | |||||
font-size: 30px; | |||||
color: white; | |||||
} | |||||
/* buttons */ | |||||
.buttons-container { | |||||
border: var(--border-prop); | |||||
display: flex; | |||||
justify-content: center; | |||||
width: 100%; | |||||
} | |||||
.button { | |||||
display: inline-block; | |||||
border-radius: 0; | |||||
background-color: #303030; | |||||
border: none; | |||||
/*text*/ | |||||
color: #FFFFFF; | |||||
text-align: center; | |||||
font-size: var(--text-size); | |||||
padding: 10px; | |||||
width: 100%; | |||||
cursor: pointer; | |||||
} | |||||
.button span{ | |||||
cursor: pointer; | |||||
display: inline-block; | |||||
position: relative; | |||||
transition: 1s; | |||||
} | |||||
.button span::after { | |||||
content: '\00bb'; | |||||
position: absolute; | |||||
opacity: 0; | |||||
top: 0; | |||||
right: -20px; | |||||
transition: .5s; | |||||
} | |||||
.button:hover span { | |||||
padding-right: 25px; | |||||
} | |||||
.button:hover span::after{ | |||||
opacity: 1; | |||||
right: 0; | |||||
} | |||||
.susButton , .remButton, .nextButton, .manageButton, #addBtn{ | |||||
margin-left: 5px; | |||||
} | |||||
.icon{ | |||||
pointer-events: none; | |||||
} | |||||
/* end of buttons*/ | |||||
#loginText { | |||||
transition: 0.35s; | |||||
} | |||||
.fadeout { | |||||
opacity: 0; | |||||
} | |||||
#loginform { | |||||
border: var(--border-prop); | |||||
margin-bottom: 10px; | |||||
} | |||||
/* | |||||
border: 1px #F2F; | |||||
border-style: dashed; | |||||
*/ | |||||
/* User/Mod Table */ | |||||
.table{ | |||||
min-height: 32em; | |||||
} | |||||
.row{ | |||||
display: flex; | |||||
flex-direction: row; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
background-color: var(--row-color); | |||||
margin-top: 10px; | |||||
margin-bottom: 10px; | |||||
padding-left: 10px; | |||||
padding-right: 10px; | |||||
} | |||||
.col-left , .col-right{ | |||||
display: flex; | |||||
padding: 0; | |||||
margin: 0; | |||||
} | |||||
/* End of Table */ | |||||
/* Page Selector */ | |||||
.rightButtons{ | |||||
display: flex; | |||||
margin-left: 10px; | |||||
} | |||||
.ButtonRow{ | |||||
display: flex; | |||||
flex-direction: row; | |||||
justify-content: space-between; | |||||
padding-right: 10px; | |||||
} | |||||
/* End of Page Selector*/ | |||||
/*-----POPUP-----*/ | |||||
.popup{ | |||||
position: fixed; | |||||
top: 50%; | |||||
left: 50%; | |||||
transform: translate(-50%, -50%) scale(0); | |||||
transition: 50ms ease-in-out; | |||||
border: var(--popup-border); | |||||
z-index: 10; /*lay ontop of everything*/ | |||||
background-color: var(--prime-color); | |||||
width: 500px; | |||||
max-width: 80%; | |||||
min-height: 18em; | |||||
display: flex; | |||||
flex-direction: column; | |||||
justify-content: space-evenly; | |||||
} | |||||
.popup.active{ | |||||
transform: translate(-50%, -50%) scale(1); | |||||
} | |||||
.popup-header{ | |||||
padding: 10px; | |||||
display: flex; | |||||
justify-content: space-between; | |||||
align-items: center; | |||||
border-bottom: var(--popup-stripe); | |||||
} | |||||
.popup-header .title{ | |||||
font-size: var(--text-size); | |||||
font-weight: bold; | |||||
} | |||||
.popup-header .close-btn{ | |||||
cursor: pointer; | |||||
border: none; | |||||
outline: none; | |||||
background: none; | |||||
font-size: var(--title-size); | |||||
font-weight: bold; | |||||
color: white; | |||||
} | |||||
.popup-body{ | |||||
display: flex; | |||||
justify-content: center; | |||||
padding: 10px; | |||||
} | |||||
#overlay{ | |||||
position: fixed; | |||||
opacity: 0; | |||||
transition: 50ms ease-in-out; | |||||
top: 0; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 0; | |||||
background-color: rgba(0,0,0,.75); | |||||
pointer-events: none; | |||||
} | |||||
#overlay.active{ | |||||
opacity: 1; | |||||
pointer-events: all; | |||||
} | |||||
.popup-body{ | |||||
display: fixed; | |||||
justify-items: center; | |||||
} | |||||
#formNewUser{ | |||||
width: 50%; | |||||
} | |||||
input { | |||||
width: 100%; | |||||
font-family: Arial; | |||||
font-size: var(--text-size); | |||||
color: white; | |||||
padding: 0; | |||||
padding-bottom: 5px; | |||||
background: none; | |||||
border: none; | |||||
border-bottom: 1px solid #ffffff; | |||||
margin-bottom: 15px; | |||||
margin-top: 15px | |||||
} | |||||
input:focus { | |||||
outline: 0; | |||||
} | |||||
/*-----POPUP-END-----*/ | |||||
/* New Post Section*/ | |||||
[contentEditable=true]:empty:not(:focus):before{ | |||||
content:attr(data-text); | |||||
color: rgba(0,0,0,0.5); | |||||
} | |||||
.preview-title{ | |||||
color: #000; | |||||
} | |||||
.editor{ | |||||
display: flex; | |||||
flex-flow: row; | |||||
justify-content: center; | |||||
} | |||||
.editor-menubar{ | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
justify-content: center; | |||||
} | |||||
button, .color-select{ | |||||
color: #ffffff; | |||||
font-size: var(--text-size); | |||||
padding-left: 10px; | |||||
padding-right: 10px; | |||||
background-color: var(--button-prim); | |||||
cursor: pointer; | |||||
transition: all 250ms; | |||||
border: none; | |||||
min-width: 50px; | |||||
min-height: 50px; | |||||
} | |||||
button:hover{ | |||||
background-color: var(--button-sec); | |||||
} | |||||
button:focus{ | |||||
outline: none; | |||||
} | |||||
.regSection{ | |||||
font-size: var(--text-size); | |||||
} | |||||
.canvas{ | |||||
background-color: rgba(255,255,255,1); | |||||
width: 46.3rem; | |||||
height: 30rem; | |||||
padding: 2.5rem; | |||||
font-size: var(--text-size); | |||||
color: #000; | |||||
font-family: arial; | |||||
line-height: 1.5em; | |||||
} | |||||
.canvas:focus{ | |||||
outline: none; | |||||
} | |||||
#title-canvas, #editor-canvas{ | |||||
height: 5rem; | |||||
font-size: var(--title-size); | |||||
align-self: center; | |||||
text-align: center; | |||||
text-justify: center; | |||||
padding: 10px; | |||||
border-bottom: .5rem solid #000 ; | |||||
} | |||||
#editor-canvas{ | |||||
text-align: left; | |||||
text-justify: left; | |||||
height: 30rem; | |||||
font-size: var(--smal-text); | |||||
} | |||||
#box{ | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
#cancelBtn{ | |||||
padding: 0; | |||||
font-size: var(--title-size); | |||||
line-height: 1.8rem; | |||||
} | |||||
.postContainer{ | |||||
width: 60em; | |||||
} | |||||
.lower{ | |||||
display: flex; | |||||
flex-flow: row; | |||||
justify-content: center; | |||||
align-items: center; | |||||
} | |||||
.topper{ | |||||
display: flex; | |||||
flex-flow: row; | |||||
justify-content: flex-end; | |||||
align-items: flex-end; | |||||
} | |||||
.calendar{ | |||||
color: #ffffff; | |||||
font-size: var(--text-size); | |||||
padding: 1rem; | |||||
transition: all 250ms; | |||||
display: flex; | |||||
flex-flow: column; | |||||
align-items: center; | |||||
justify-content: center; | |||||
margin-left: .5rem; | |||||
margin-right: .5rem; | |||||
} | |||||
.calendar-element{ | |||||
border: none; | |||||
} | |||||
.calendar-element:focus{ | |||||
outline: none; | |||||
} | |||||
#title-text{ | |||||
width: 100%; | |||||
display: flex; | |||||
flex-flow: column; | |||||
} | |||||
#submit-post{ | |||||
margin-left: .5rem; | |||||
} | |||||
.color-select{ | |||||
background-color: var(--button-prim); | |||||
padding-left: 0px; | |||||
padding-right: 0px; | |||||
display: flex; | |||||
justify-content: center; | |||||
margin: 0px; | |||||
} | |||||
.color-select:hover{ | |||||
background-color: var(--button-sec); | |||||
} | |||||
.editor-button{ | |||||
min-width: 50px; | |||||
max-width: 50px; | |||||
min-height: 50px; | |||||
max-height: 50px; | |||||
} | |||||
/* End of New Post*/ | |||||
/* Preview */ | |||||
.TitleRow{ | |||||
max-width: 100%; | |||||
display: flex; | |||||
flex-direction: row; | |||||
justify-content: space-evenly; | |||||
background-color: var(--container-bg); | |||||
padding-right: 10px; | |||||
padding-bottom: 10px; | |||||
align-items: center; | |||||
margin-bottom: 5px; | |||||
} | |||||
.titleDiv{ | |||||
min-width: 25%; | |||||
} | |||||
#topper{ | |||||
height: 10%; | |||||
text-align: center; | |||||
top: 0px; | |||||
} | |||||
#content{ | |||||
width: 100%; | |||||
height: 85%; | |||||
display: flex; | |||||
justify-content: center; | |||||
flex-wrap: wrap; | |||||
} | |||||
@keyframes fadein { | |||||
0% { | |||||
opacity: 0; | |||||
} | |||||
} | |||||
.post{ | |||||
animation: fadein 2s ease; | |||||
min-width: 30%; | |||||
max-width: 45%; | |||||
min-height: 28%; | |||||
max-height: 45%; | |||||
padding: 2vh; | |||||
margin: 5px; | |||||
border-width: 0px; | |||||
border-color: var(--prime); | |||||
color: black; | |||||
} | |||||
.hidden{ | |||||
color: red; | |||||
} | |||||
/* End of Preview */ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<title>User-Page</title> | |||||
<link rel="stylesheet" text="text/css" href="styles.css"> | |||||
<script src="user.js"></script> | |||||
<!--Font Awesome Icons CDN--> | |||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> | |||||
</head> | |||||
<body> | |||||
<div class=main> | |||||
<div class="container user-container"> | |||||
<div class="header"> | |||||
<h1>Benutzerseite</h1> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="lgoBtn">Logout</button> | |||||
<button onclick="location.href='/newPost'" id="addBtn">+</button> | |||||
<div class="" id="overlay"></div> | |||||
</div> | |||||
<div class="table" id="table"> | |||||
</div> | |||||
<div class="ButtonRow"> | |||||
<button class="logoutButton" id="changePwBtn">Change Password</button> | |||||
<div class="rightButtons"> | |||||
<button class="icon-backward , backButton" id="pageDown"></button> | |||||
<button class="icon-forward , nextButton" id="pageUp"></button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
document.addEventListener("DOMContentLoaded", function(){ | |||||
/*changin page*/ | |||||
var pageUp = document.getElementById("pageUp"); | |||||
var pageDown = document.getElementById("pageDown"); | |||||
var reviewButtons = document.getElementsByClassName('editButton'); | |||||
document.getElementById("changePwBtn").onclick = function(){ | |||||
window.location = "/new-password"; | |||||
} | |||||
pageUp.addEventListener("click", () => { | |||||
if(maxPages > currentPage+1) { | |||||
currentPage++; | |||||
loadPosts(); | |||||
} | |||||
}); | |||||
pageDown.addEventListener("click", () => { | |||||
if(currentPage > 0){ | |||||
currentPage--; | |||||
loadPosts(); | |||||
} | |||||
}); | |||||
async function deletePost(postid){ | |||||
var response = await fetch("/deletePost", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({postid:postid}) | |||||
}) | |||||
var data = await response.json(); | |||||
console.log(data); | |||||
if(data.suc || !data.suc){ | |||||
loadPosts(); | |||||
} | |||||
}; | |||||
document.addEventListener("click", function(e){ | |||||
if(e.target && e.target.classList.contains("remButton")){ | |||||
var postid = e.target.getAttribute("data-username"); | |||||
deletePost(postid); | |||||
} | |||||
}) | |||||
/*logout*/ | |||||
var lgoBtn = document.getElementById("lgoBtn"); | |||||
lgoBtn.addEventListener("click", () => { | |||||
window.location = "/logout"; | |||||
}); | |||||
/*NewPost*/ | |||||
var addBtn = document.getElementById("addBtn"); | |||||
addBtn.addEventListener("click", () => { | |||||
window.location = "/newPost"; | |||||
}); | |||||
/*Show Elements*/ | |||||
var maxPages; | |||||
var currentPage = 0; | |||||
var maxDisplayed = 8; | |||||
async function loadPosts(){ | |||||
var response = await fetch("/getposts", { | |||||
method: "GET", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
} | |||||
}) | |||||
var data = await response.json(); | |||||
try{ | |||||
showPosts(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); | |||||
maxPages = data.users.length / 8; | |||||
console.log(maxPages, currentPage+1) | |||||
reviewButtons = document.getElementsByClassName('editButton'); | |||||
console.log(reviewButtons.length); | |||||
addButtons(); | |||||
}catch(error){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
} | |||||
}; | |||||
loadPosts(); | |||||
function showPosts(pdata){ | |||||
document.getElementById("table").innerHTML = ""; //empty table | |||||
var container = document.getElementById("table"); //insert in table | |||||
pdata.forEach(element => { | |||||
var row = document.createElement("div"); | |||||
var status; | |||||
if(!element.showpost) { | |||||
status = "hidden icon-eye-close" | |||||
} else { | |||||
status = "shown icon-eye-open" | |||||
} | |||||
row.classList.add("row"); | |||||
row.innerHTML = ` | |||||
<div class="col-left"> | |||||
<h2>${element.title}</h2> | |||||
</div> | |||||
<div class="col-right"> | |||||
<button class="editButton" data-username="${element.postid}"> | |||||
<i class="icon-file-text-alt , icon"></i> | |||||
</button> | |||||
<button class="${status} susButton"> | |||||
</button> | |||||
<button class="remButton" data-username="${element.postid}"> | |||||
<i class="icon-trash , icon"></i> | |||||
</button> | |||||
</div> | |||||
` | |||||
container.appendChild(row) | |||||
}); | |||||
} | |||||
async function reviewPost(postid){ | |||||
var response = await fetch("/updatePostID", { | |||||
method: "POST", | |||||
headers: { | |||||
"Accept":"application/json", | |||||
"Content-Type":"application/json" | |||||
}, | |||||
body:JSON.stringify({postid:postid}) | |||||
}) | |||||
var data = await response.json(); | |||||
if(data || !data) | |||||
{ | |||||
window.location = "/post-review"; | |||||
} | |||||
}; | |||||
function addButtons(){ | |||||
for(let i = 0; i < reviewButtons.length; i++){ | |||||
reviewButtons[i].addEventListener('click', function(){ | |||||
reviewPost(this.dataset.username) | |||||
}) | |||||
} | |||||
} | |||||
}); |
const express = require("express"); | |||||
const bodyParser = require("body-parser"); | |||||
const app = express(); | |||||
const bcrypt = require("bcrypt"); | |||||
const Datastore = require("nedb"); | |||||
const session = require("express-session"); | |||||
const NedbSessionStore = require("nedb-session-store")(session); | |||||
app.listen(8080, () => { | |||||
console.log("Server online on port 8080"); | |||||
}) | |||||
app.use(session({ | |||||
secret: process.env.SECRET || 'ENTER YOUR SECRET KEY IN ENV VARIABLES!', | |||||
resave: false, | |||||
saveUninitialized: false, | |||||
unset: "destroy", | |||||
cookie: { | |||||
path: '/', | |||||
httpOnly: true, | |||||
maxAge: 3600000 //cookie time in ms (=1h) | |||||
}, | |||||
store: new NedbSessionStore({ | |||||
filename: 'db/sessions.db' | |||||
}) | |||||
})) | |||||
app.use(express.static("public")); | |||||
app.use(bodyParser.json()); | |||||
app.use(bodyParser.urlencoded({ extended: true })); | |||||
/*--------------------------------------------------PAGE REQUESTS--------------------------------------------------*/ | |||||
app.get("/", (req, res) => { | |||||
res.send("index.html"); | |||||
}); | |||||
app.get("/info", (req, res) => { | |||||
res.sendFile(__dirname + '/public/info-page.html') | |||||
}); | |||||
app.get("/main", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "admin"){ | |||||
res.sendFile(__dirname + '/public/admin-login.html') | |||||
}else if(req.session.isLoggedIn && req.session.userRole === "mod") { | |||||
res.sendFile(__dirname + '/public/mod-login.html') | |||||
}else if(req.session.isLoggedIn && req.session.userRole === "user") { | |||||
res.sendFile(__dirname + '/public/user-login.html') | |||||
}else { | |||||
req.session = null; | |||||
res.redirect("/"); | |||||
} | |||||
}); | |||||
app.get("/newPost", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "user"){ | |||||
res.sendFile(__dirname + '/public/new-Postv2.html') | |||||
} else { | |||||
req.session = null; | |||||
res.redirect("/"); | |||||
} | |||||
}); | |||||
app.get("/manage-posts", (req, res) => { | |||||
if(req.session.isLoggedIn && (req.session.userRole === "mod" || req.session.userRole === "admin")){ | |||||
res.sendFile(__dirname + '/public/manage-post.html') | |||||
} else { | |||||
req.session = null; | |||||
res.redirect("/"); | |||||
} | |||||
}); | |||||
app.get("/new-password", (req, res) => { | |||||
if(req.session.isLoggedIn){ | |||||
res.sendFile(__dirname + '/public/change-pw.html') | |||||
} else { | |||||
req.session = null; | |||||
res.redirect("/"); | |||||
} | |||||
}); | |||||
app.post("/updatePostID", (req, res) => { | |||||
if(req.session.isLoggedIn){ | |||||
req.session.revpost = req.body.postid; | |||||
res.json({suc:true}); | |||||
//res.sendFile(__dirname + '/public/post-review.html') | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.get("/post-review", (req, res) => { | |||||
if(req.session.isLoggedIn ){ | |||||
res.sendFile(__dirname + '/public/post-review.html') | |||||
} else { | |||||
req.session = null; | |||||
res.redirect("/"); | |||||
} | |||||
}); | |||||
/*--------------------------------------------------GETTER FUNCTIONS--------------------------------------------------*/ | |||||
app.get("/getmods", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "admin"){ | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({role:"mod"}, (err, docs) => { | |||||
if(docs.length > 0) { | |||||
let resArray = []; | |||||
docs.forEach(element => { | |||||
resArray.push({ | |||||
username:element.username, | |||||
suspended:element.suspended | |||||
}) | |||||
}); | |||||
res.json({suc:true, users:resArray}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.get("/getusers", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "mod"){ | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({role:"user" , group: req.session.userid }, (err, docs) => { | |||||
if(docs.length > 0) { | |||||
let resArray = []; | |||||
docs.forEach(element => { | |||||
resArray.push({ | |||||
username:element.username, | |||||
suspended:element.suspended | |||||
}) | |||||
}); | |||||
res.json({suc:true, users:resArray}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.get("/getReviewPost", (req, res) => { | |||||
if(req.session.isLoggedIn){ | |||||
const db = new Datastore("db/posts.db"); | |||||
db.loadDatabase(); | |||||
db.find({_id:req.session.revpost}, (err, docs) => { | |||||
if(docs.length === 1) { | |||||
let post = []; | |||||
post.push({ | |||||
postid:docs[0]._id, | |||||
username:docs[0].creatorName, | |||||
showpost:docs[0].showpost, | |||||
title:docs[0].title, | |||||
text:docs[0].text, | |||||
bcolor:docs[0].bcolor, | |||||
startdate:docs[0].startDate, | |||||
enddate:docs[0].endDate, | |||||
}) | |||||
res.json({suc:true, post:post}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.get("/getposts", (req, res) => { | |||||
if(req.session.isLoggedIn){ | |||||
const db_post = new Datastore("db/posts.db"); | |||||
db_post.loadDatabase(); | |||||
switch(req.session.userRole) | |||||
{ | |||||
case "admin": | |||||
db_post.find({}, (err, docs) => { | |||||
if(docs.length > 0) { | |||||
let resArray = []; | |||||
docs.forEach(element => { | |||||
resArray.push({ | |||||
creator: element.creatorName, | |||||
postid: element._id, | |||||
title:element.title, | |||||
text:element.text, | |||||
showpost:element.showpost, | |||||
startDate:element.startDate, | |||||
endDate:element.endDate, | |||||
}) | |||||
}); | |||||
res.json({suc:true, users:resArray}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
break; | |||||
case "mod": | |||||
db_post.find({creatorGroup:req.session.userid}, (err, docs) => { | |||||
if(docs.length > 0) { | |||||
let resArray = []; | |||||
docs.forEach(element => { | |||||
resArray.push({ | |||||
creator: element.creatorName, | |||||
postid: element._id, | |||||
title:element.title, | |||||
text:element.text, | |||||
showpost:element.showpost, | |||||
startDate:element.startDate, | |||||
endDate:element.endDate, | |||||
}) | |||||
}); | |||||
res.json({suc:true, users:resArray}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
break; | |||||
case "user": | |||||
db_post.find({creatorId:req.session.userid}, (err, docs) => { | |||||
if(docs.length > 0) { | |||||
let resArray = []; | |||||
docs.forEach(element => { | |||||
resArray.push({ | |||||
title:element.title, | |||||
showpost:element.showpost, | |||||
postid:element._id | |||||
}) | |||||
}); | |||||
res.json({suc:true, users:resArray}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
}}); | |||||
break; | |||||
} | |||||
} | |||||
}); | |||||
app.get("/getliveposts", (req, res) => { | |||||
const now = new Date(); | |||||
const db_post = new Datastore("db/posts.db"); | |||||
db_post.loadDatabase(); | |||||
const db_users = new Datastore("db/users.db"); | |||||
db_users.loadDatabase(); | |||||
db_post.find({}, (err, docs) => { | |||||
if(docs.length > 0) { | |||||
let resArray = []; | |||||
docs.forEach(element => { | |||||
if(element.showpost){ | |||||
var start = new Date(element.startDate) - now; | |||||
var end = new Date(element.endDate) - now; | |||||
if(start < 0 && end > 0){ | |||||
db_users.find({_id:element.creatorId}, (err2, docs2) =>{ | |||||
docs2.forEach(element2 => { | |||||
if(!element2.suspended) | |||||
{ | |||||
db_users.find({_id:element.creatorGroup}, (err3, docs3) =>{ | |||||
docs3.forEach(element3 => { | |||||
if(!element3.suspended) | |||||
{ | |||||
resArray.push({ | |||||
title:element.title, | |||||
text:element.text, | |||||
bcolor:element.bcolor | |||||
}) | |||||
} | |||||
}) | |||||
}) | |||||
} | |||||
}) | |||||
}) | |||||
} | |||||
} | |||||
}); | |||||
setTimeout(function(){ res.json({suc:true, posts:resArray}); }, 100); //delay to resolve timing issue | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
}); | |||||
/*--------------------------------------------------FUNCTIONS--------------------------------------------------*/ | |||||
app.post("/login", (req, res) => { | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
const un = req.body.username; | |||||
const pw = req.body.password; | |||||
if(un && pw){ | |||||
db.find({username:un}, (err, docs) => { | |||||
if(docs.length === 1){ | |||||
const userRole = docs[0].role; | |||||
bcrypt.compare(pw, docs[0].password, (err2, result) => { | |||||
if(result){ | |||||
req.session.userRole = userRole; | |||||
req.session.userid = docs[0]._id; | |||||
req.session.gr = docs[0].group; | |||||
req.session.un = docs[0].username; | |||||
req.session.revpost = 0; | |||||
req.session.isLoggedIn = true; | |||||
if(userRole === "admin") { | |||||
res.json({suc:true, redirect:"admin"}) //login to admin page | |||||
} else if(userRole === "mod"){ | |||||
res.json({suc:true, redirect:"mod"}) //login to mod page | |||||
} else if(userRole === "user"){ | |||||
res.json({suc:true, redirect:"user"}) //login to user page | |||||
} | |||||
} else { res.json({suc:false}); } | |||||
}) | |||||
} else { res.json({suc:false}); } | |||||
}) | |||||
} else { res.json({suc:false}); } | |||||
}); | |||||
app.get("/logout", (req, res) => { | |||||
req.session = null; | |||||
res.redirect("/"); | |||||
}); | |||||
app.post("/changepw", (req, res) => { | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
const old_pw = req.body.old_password; | |||||
const new_pw_1 = req.body.new_password_1; | |||||
const new_pw_2 = req.body.new_password_2; | |||||
if(old_pw && (new_pw_1 === new_pw_2)){ | |||||
db.find({_id:req.session.userid}, (err, docs) => { | |||||
if(docs.length === 1){ | |||||
bcrypt.compare(old_pw, docs[0].password, (err2, result) => { | |||||
if(result){ | |||||
bcrypt.hash(new_pw_1, 10, (err3, hash) => { | |||||
db.update({_id: docs[0]._id}, {$set: {password: hash}}, (err4, num) =>{ | |||||
res.json({suc:true}); | |||||
}); | |||||
}) | |||||
} else { res.json({suc:false}); } | |||||
}) | |||||
} else { res.json({suc:false}); } | |||||
}) | |||||
} else { res.json({suc:false}); } | |||||
}) | |||||
app.post("/newmod", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "admin"){ | |||||
const nun = req.body.username; | |||||
const nemail = req.body.email; | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({username:nun}, (err, docs) => { | |||||
if(docs.length === 0){ | |||||
db.find({email:nemail}, (err2, docs2) => { | |||||
if(docs2.length === 0){ | |||||
bcrypt.hash(nun, 10, (err3, hash) => { | |||||
db.insert({email: nemail, | |||||
username: nun, | |||||
password: hash, | |||||
role: "mod", | |||||
suspended: false | |||||
}, (err4, doc) => { | |||||
res.json({suc:true}); | |||||
}); | |||||
}); | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
app.post("/newuser", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "mod"){ | |||||
const nun = req.body.username; | |||||
const nemail = req.body.email; | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({username:nun}, (err, docs) => { | |||||
if(docs.length === 0){ | |||||
db.find({email:nemail}, (err2, docs2) => { | |||||
if(docs2.length === 0){ | |||||
bcrypt.hash(nun, 10, (err3, hash) => { | |||||
db.insert({ | |||||
email: nemail, | |||||
username: nun, | |||||
password: hash, | |||||
role: "user", | |||||
group: req.session.userid, | |||||
suspended: false | |||||
}, (err4, doc) => { | |||||
res.json({suc:true}); | |||||
}); | |||||
}); | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
app.post("/newpost", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "user"){ | |||||
const db = new Datastore("db/posts.db"); | |||||
db.loadDatabase(); | |||||
db.insert({ | |||||
creatorId:req.session.userid , | |||||
creatorName:req.session.un , | |||||
creatorGroup:req.session.gr , | |||||
showpost:false , | |||||
startDate:req.body.startDate , | |||||
endDate:req.body.endDate , | |||||
title:req.body.title , | |||||
text:req.body.text, | |||||
bcolor:req.body.bcolor | |||||
}, (err, doc) => { | |||||
res.json({suc:true}); | |||||
}); | |||||
} | |||||
}); | |||||
app.post("/toggleSus", (req, res) => { | |||||
if(req.session.isLoggedIn && (req.session.userRole === "admin" || req.session.userRole === "mod")){ | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({username:req.body.username}, (err, docs) => { | |||||
if(docs.length === 1) { | |||||
var now = !docs[0].suspended; | |||||
db.update({_id: docs[0]._id}, {$set: {suspended: now}}, (err2, num) =>{ | |||||
res.json({suc:true}); | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.post("/toggleShow", (req, res) => { | |||||
if(req.session.isLoggedIn && (req.session.userRole === "mod" || req.session.userRole === "admin")){ | |||||
const db = new Datastore("db/posts.db"); | |||||
db.loadDatabase(); | |||||
db.find({_id:req.body.postid}, (err, docs) => { | |||||
if(docs.length === 1) { | |||||
var now = !docs[0].showpost; | |||||
db.update({_id: docs[0]._id}, {$set: {showpost: now}}, (err2, num) =>{ | |||||
res.json({suc:true}); | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.post("/deleteMod", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "admin") { | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({username:req.body.username}, (err, docs) => { | |||||
if(docs.length === 1) { | |||||
deleteMod(docs[0]._id); | |||||
setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.post("/deleteUser", (req, res) => { | |||||
if(req.session.isLoggedIn && req.session.userRole === "mod"){ | |||||
const db = new Datastore("db/users.db"); | |||||
db.loadDatabase(); | |||||
db.find({username:req.body.username}, (err, docs) => { | |||||
if(docs.length === 1) { | |||||
deleteUser(docs[0]._id); | |||||
setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
app.post("/deletePost", (req, res) => { | |||||
if(req.session.isLoggedIn){ | |||||
const db = new Datastore("db/posts.db"); | |||||
db.loadDatabase(); | |||||
db.find({_id:req.body.postid}, (err, docs) => { | |||||
if(docs.length === 1) { | |||||
deletePost(docs[0]._id); | |||||
setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}) | |||||
} else { | |||||
res.json({suc:false}); | |||||
} | |||||
}); | |||||
/*--------------------------------------------------FUNCTIONS--------------------------------------------------*/ | |||||
function deleteMod(modID){ | |||||
const db_users = new Datastore("db/users.db"); | |||||
db_users.loadDatabase(); | |||||
db_users.find({group:modID}, (err, docs) => { | |||||
docs.forEach(element => { | |||||
deleteUser(element._id); | |||||
if(docs.indexOf(element) === docs.length-1) | |||||
db_users.find({_id:modID}, (err2, docs2) => { | |||||
console.log("deleted mod: ", docs2[0]._id); | |||||
db_users.remove({_id: docs2[0]._id}); | |||||
}) | |||||
}); | |||||
}) | |||||
} | |||||
function deleteUser(userID){ | |||||
const db_posts = new Datastore("db/posts.db"); | |||||
db_posts.loadDatabase(); | |||||
db_posts.find({creatorId:userID}, (err, docs) => { | |||||
docs.forEach(element => { | |||||
deletePost(element._id); | |||||
}); | |||||
}) | |||||
const db_users = new Datastore("db/users.db"); | |||||
db_users.loadDatabase(); | |||||
db_users.find({_id:userID}, (err, docs) => { | |||||
console.log("deleted user: ", docs[0]._id); | |||||
db_users.remove({_id: docs[0]._id}) | |||||
}) | |||||
} | |||||
function deletePost(postID){ | |||||
const db_posts = new Datastore("db/posts.db"); | |||||
db_posts.loadDatabase(); | |||||
db_posts.find({_id:postID}, (err, docs) => { | |||||
console.log("deleted post: ", docs[0]._id); | |||||
db_posts.remove({_id: docs[0]._id}); | |||||
}) | |||||
} |
#!/bin/bash | |||||
cd `dirname $0` | |||||
node server.js |