From b26314d4a2f30462eabb0b919f5c7fdf2cd481d2 Mon Sep 17 00:00:00 2001 From: Akif9748 <akif9748@gmail.com> Date: Sat, 27 Aug 2022 14:08:28 +0300 Subject: [PATCH] bcrypt fix + forms to a --- README.md | 2 + public/css/threads.css | 2 +- public/css/users.css | 2 + public/js/thread.js | 127 ++++++++++++++++++++--------------------- routes/api/index.js | 10 ++-- routes/login.js | 4 +- views/thread.ejs | 44 +++++++------- views/user.ejs | 31 ++++------ views/users.ejs | 2 + 9 files changed, 107 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index 1866ee6..0360654 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ Akf-forum has got an API for AJAX, other clients etc. And, you can learn about A - If thread deleted, not show its messages in API. - Thread.ejs fix with new theme - Profile photos will store in database +- regex for pfp for now and +- admin perm for undelete, thread+message ### Frontend ### User diff --git a/public/css/threads.css b/public/css/threads.css index 9b06ce4..61357c3 100644 --- a/public/css/threads.css +++ b/public/css/threads.css @@ -1,4 +1,3 @@ - .threads { width: 100%; padding: 20px; @@ -18,6 +17,7 @@ .threads-box:hover { background-color: #e2e2e2; } + .thread-box-title { padding: 10px; font-size: 18px; diff --git a/public/css/users.css b/public/css/users.css index 6c2e740..208bd19 100644 --- a/public/css/users.css +++ b/public/css/users.css @@ -13,6 +13,7 @@ flex-direction: column; align-items: center; box-shadow: 0 0 5px 0 #beb9b9; + max-width:500px; } .user-box-title { @@ -28,6 +29,7 @@ .user-box-img { width: 80px; height: 80px; + margin: auto; } @media (max-width: 992px) { diff --git a/public/js/thread.js b/public/js/thread.js index 14bc41c..e74013b 100644 --- a/public/js/thread.js +++ b/public/js/thread.js @@ -1,7 +1,11 @@ import request from "./request.js"; -const messages = document.getElementById("messages"); -let messages_raw = []; +const message_div = document.getElementById("messages"); + +const messages_raw = await fetch(`/api/threads/${message_div.getAttribute("value")}/messages/`).then(res => res.json()); +for (const message of messages_raw) + renderMessage(message); + function renderMessage(message) { const messageElement = document.createElement("div"); messageElement.classList.add("message"); @@ -12,50 +16,35 @@ function renderMessage(message) { <h3 style="float:right;">${new Date(message.time).toLocaleString()}</h3> <h2> - <img class="circle" src=${message.author.avatar} alt=${message.author.name}> - <a href=${"/users/" + message.author.id}> ${message.author.name}</a>: + <img class="circle" src="${message.author.avatar}" alt="${message.author.name}"> + <a href="/users/${message.author.id}"> ${message.author.name}</a>: </h2> <p>${message.content.replaceAll("\n", "<br>")}</p><br> <div id="message-delete-${message.id}"> - ${!message.deleted ? - `<form style="display:inline;"> - <button id="delete_message" value="${message.id}" type="submit">DELETE</button> - </form>` : - "<h3 style=\"display:inline;\">This message has been deleted</h3>"} + ${/* if */!message.deleted ? + ` + <a onclick="delete_message('${message.id}');">DELETE</a> + <a onclick="edit_message('${message.id}');">EDIT</a> + ` /* else */ : + `<h3 style=\"display:inline;\">This message has been deleted</h3> + <a onclick="undelete_message('${message.id}');">UNDELETE</a> + ` + + } </div> <div style="float: right;"> - <h3 id="count${message.id}" style="display:inline;">${message.reactCount}</h3> - <button style="display:inline;" id="like" value="${message.id}">+🔼</button> - <button style="display:inline;" id="dislike" value="${message.id}" >-🔽</button> + <h3 id="count${message.id}" style="display:inline;">0</h3> + <a onclick="react('${message.id}', 'like');">+🔼</a> + <a onclick="react('${message.id}', 'dislike');">-🔽</a> </div> `; - messages.appendChild(messageElement); - messages.innerHTML += "<br>"; + message_div.appendChild(messageElement); + message_div.innerHTML += "<br>"; }; -/** - * Main Renderer - */ -(async () => { - - messages_raw = await fetch(`/api/threads/${messages.getAttribute("value")}/messages/`).then(res => res.json()); - if (messages_raw?.error) { - - document.getElementById("messages").innerHTML - += '<div class="message"><h1>THIS THREAD HAS NOT GOT ANY MESSAGE</h1></div>'; - - - } else - for (const message of messages_raw) - renderMessage(message); - - window.scrollTo(0, document.body.scrollHeight); - -})(); - - +window.scrollTo(0, document.body.scrollHeight); /** * Message Sender @@ -74,41 +63,49 @@ document.getElementById("send").addEventListener("submit", async e => { }); }); - /** - * Button Listener + * OTHER FUNCTIONS */ -document.addEventListener("click", async e => { - // e.preventDefault(); - if (e.target.id === "delete_thread") { - const response = await request("/api/threads/" + e.target.value + "/delete"); - if (response.deleted) { - alert("Thread deleted"); - location.reload(); - } - } else if (e.target.id === "undelete_thread") { - const response = await request("/api/threads/" + e.target.value + "/undelete"); - if (!response.deleted) { - alert("Thread undeleted"); - location.reload(); +async function delete_thread(id) { + const response = await request("/api/threads/" + id + "/delete"); + if (response.deleted) { + alert("Thread deleted"); + location.reload(); + } - } +} +async function undelete_thread(id) { + const response = await request("/api/threads/" + id + "/undelete"); + if (!response.deleted) { + alert("Thread undeleted"); + location.reload(); - } else if (e.target.id === "delete_message") { - e.preventDefault(); - const response = await request(`/api/messages/${e.target.value}/delete`); - if (response.deleted) { - alert("Message deleted"); - document.getElementById("message-delete-" + e.target.value).innerHTML = "<h3 style=\"display:inline;\">This message has been deleted</h3>"; - } - } /*else if (e.target.id === "edit_thread") { - window.location.href = "/threads/<%= thread.id }/edit"; - } */ + } - if (!e.target.id.includes("like")) return; - const res = await request("/api/messages/" + e.target.value + "/react/" + e.target.id) +} +async function undelete_message(id) { + const response = await request(`/api/messages/${id}/undelete`); + if (!response.deleted) + document.getElementById("message-delete-" + id).innerHTML = `<a onclick=\"delete_message('${id}');\">DELETE</a>`; - document.getElementById("count" + e.target.value).innerHTML = res.reactCount; +} +async function delete_message(id) { + const response = await request(`/api/messages/${id}/delete`); + if (response.deleted) { + alert("Message deleted"); + document.getElementById("message-delete-" + id).innerHTML = ` + <h3 style=\"display:inline;\">This message has been deleted</h3> + <a onclick="undelete_message('${id}');">UNDELETE</a>`;// ADMIN PERM FIX + } +} +async function react(id, type) { + const res = await request(`/api/messages/${id}/react/${type}`) + document.getElementById(`count${id}`).innerHTML = res.reactCount; +} -}); +window.delete_message = delete_message; +window.undelete_message = undelete_message; +window.react = react; +window.delete_thread = delete_thread; +window.undelete_thread = undelete_thread; \ No newline at end of file diff --git a/routes/api/index.js b/routes/api/index.js index 5026339..b24e072 100644 --- a/routes/api/index.js +++ b/routes/api/index.js @@ -1,7 +1,6 @@ -const { Router } = require("express") +const { Router, request, response } = require("express") const app = Router(); const bcrypt = require("bcrypt"); -const { request, response } = require("express"); const { SecretModel, UserModel } = require("../../models") /** @@ -11,7 +10,7 @@ const { SecretModel, UserModel } = require("../../models") */ app.use(async (req, res, next) => { - res.error = (status, error) => res.status(status).json({error}); + res.error = (status, error) => res.status(status).json({ error }); res.complate = result => res.status(200).json(result); @@ -26,10 +25,9 @@ app.use(async (req, res, next) => { if (!user) return res.error(401, "We have not got any user has got this name") - const validPassword = await bcrypt.compare(password, user.password); - if (!validPassword) - return res.error(401, 'Incorrect Password!') + if (!bcrypt.compare(password, user.password)) return res.error(401, 'Incorrect Password!'); + req.user = await UserModel.findOne({ name: req.headers.username }); next(); diff --git a/routes/login.js b/routes/login.js index 93d1ad1..f187091 100644 --- a/routes/login.js +++ b/routes/login.js @@ -14,9 +14,7 @@ app.post("/", async (req, res) => { const user = await SecretModel.findOne({ username }); if (user) { - const validPassword = await bcrypt.compare(password, user.password); - - if (!validPassword) return res.error( 403, 'Incorrect Password!') + if (!bcrypt.compare(password, user.password)) return res.error( 403, 'Incorrect Password!') const member = await UserModel.findOne({ name: username }); if (!member || member.deleted) return res.error( 403, 'Incorrect Username and/or Password!') diff --git a/views/thread.ejs b/views/thread.ejs index 310b4ce..28f43e7 100644 --- a/views/thread.ejs +++ b/views/thread.ejs @@ -8,26 +8,26 @@ <%- include("extra/navbar") %> <link rel="stylesheet" href="/css/thread.css" /> - + <% if (user){ %> + <script type="module" src="/js/thread.js"></script> + <% }%> - <h1 style="font-size: 35px;color: #4d18e6;" > - <%= thread.title %> - </h1> + <h1 style="font-size: 35px;color: #4d18e6;" ><%= thread.title %></h1> - <h2 style="display:inline;">By <a href="<%="/users/" + thread.author.id %>"> <%= thread.author.name %></a> + <h2 style="display:inline;">By <a href="<%='/users/' + thread.author.id %>"> <%= thread.author.name %></a> <img class="circle" src="<%=thread.author.avatar %>"> </h2> <% if (user && !thread.deleted){ %> - <button id="delete_thread" value="<%= thread.id %>" style="display:inline;" type="submit">DELETE</button> - <button id="edit_thread" style="display:inline;" type="submit">EDIT</button> - <% } else if (thread.deleted) { %> - <h3 style="display:inline;">This thread has been deleted</h3> - <button id="undelete_thread" value="<%= thread.id %>" style="display:inline;" type="submit">UNDELETE</button> + <a onclick="delete_thread('<%= thread.id %>' )" value=style="display:inline;" >DELETE</a> + <a onclick="edit_thread('<%= thread.id %>')" style="display:inline;" >EDIT</a> + <% } else if (thread.deleted) { %> + <h3 style="display:inline;">This thread has been deleted</h3> + <a onclick="undelete_thread('<%= thread.id %>')" style="display:inline;" >UNDELETE</a> - <% }; %> + <% }; %> <hr> @@ -44,20 +44,20 @@ <h3 style="float:right;">26.08.2022 15:37:42</h3> <h2> - <img class="circle" src="https://cdn.discordapp.com/avatars/539506680140922890/abd74d10aac094fc8a5ad5c86f29fdb9.png?size=1024" alt="Akif9748"> + <img class="circle" src="https://cdn.discordapp.com/avatars/539506680140922890/abd74d10aac094fc8a5ad5c86f29fdb9.png?size=1024"> <a href="/users/0"> Akif9748</a>: </h2> <p>Example message for development</p><br> <div id="message-delete-3"> - <form style="display:inline;"> - <button id="delete_message" value="3" type="submit">DELETE</button> - </form> + <a onclick="delete_message('3');">DELETE</a> + <a onclick="edit_message('3');">EDIT</a> + </div> <div style="float: right;"> <h3 id="count3" style="display:inline;">0</h3> - <button style="display:inline;" id="like" value="3">+🔼</button> - <button style="display:inline;" id="dislike" value="3">-🔽</button> + <a onclick="react('3', 'like');">+🔼</a> + <a onclick="react('3', 'dislike');">-🔽</a> </div> </div> <!--EXAMPLE MESSAGE END--> @@ -74,15 +74,13 @@ <br> <% if (user){ %> <button type="submit">Send!</button> - <%} else {%> - <button disabled>Login for send</button> - <% }%> + <%} else {%> + <button disabled>Login for send</button> + <% }%> </form> - <% if (user){ %> - <script type="module" src="/js/thread.js"></script> - <% }%> + <script> document.getElementById("message-<%= scroll %>").scrollIntoView(); </script> diff --git a/views/user.ejs b/views/user.ejs index 3dabfba..4df01ed 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -40,22 +40,16 @@ </ul> <% if (user?.admin && !member.deleted) {%> - <form id="admin"> - <button class="big" type="submit">Give admin permissions!</button> - </form> - - <form id="delete"> - <button class="big" type="submit">Delete user!</button> - </form> + <a class="big" id="admin">Give admin permissions!</a> + <a class="big" id="delete">Delete user!</a> + <script type="module"> import request from "../../js/request.js"; - - document.addEventListener("submit", async e => { + document.addEventListener("click", async e => { e.preventDefault(); - - if (e.target.id == "admin") { + if (e.target.id == "admin") { const response = await request("/api/users/<%= member.id %>/admin"); @@ -77,23 +71,22 @@ <% }; %> <% if (member.deleted) {%> <h1>This user has been deleted!</h1> - - <form id="undelete"> - <button class="big" type="submit">Undelete user!</button> - </form> + <a onclick="undelete();" type="">Undelete user! </a> + + <script type="module"> import request from "../../js/request.js"; - - document.addEventListener("submit", async e => { - + async function undelete(params) { + const response = await request("/api/users/<%= member.id %>/undelete"); if (response.deleted) return; alert("User is undeleted successfully!"); location.reload() - }); + } + </script> diff --git a/views/users.ejs b/views/users.ejs index 73392c8..a8a243a 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -11,12 +11,14 @@ <div class="users"> <% users.forEach(user=>{ %> + <div style="display:flex;justify-content:center;"> <div class="user-box"> <img src="<%= user.avatar %>" class="user-box-img"> <div class="user-box-title"> <a href="<%= user.getLink() %>"> <% if (user.deleted) { %> <span style="color: RED;">[DELETED]</span><% } %> <%= user.name %></a></div> </div> + </div> <% }); %> </div>