From ca66d448253faae7cb88d1069e36d773c8724e68 Mon Sep 17 00:00:00 2001 From: Akif9748 Date: Thu, 1 Sep 2022 15:19:12 +0300 Subject: [PATCH] Pages for threads and users pages, and lib/ --- README.md | 8 +++---- lib/index.js | 11 ++++++++++ public/css/pages.css | 41 +++++++++++++++++++++++++++++++++++ public/css/thread.css | 44 -------------------------------------- routes/api/routes/users.js | 13 +++++------ routes/register.js | 4 ++-- routes/threads.js | 16 ++++++-------- routes/users.js | 17 +++++++-------- views/edit_user.ejs | 12 ++++++----- views/thread.ejs | 2 ++ views/threads.ejs | 24 +++++++++++++++++++-- views/users.ejs | 24 ++++++++++++++++++++- 12 files changed, 133 insertions(+), 83 deletions(-) create mode 100644 lib/index.js create mode 100644 public/css/pages.css diff --git a/README.md b/README.md index 31dda4e..1e1eba9 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,10 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn | Profile Message | 🔴 | LOW | | Search | 🔴 | MEDIUM | | Footer | 🟡 | LOW | +| Better Auth | 🔴 | MEDIUM | +| Local pfp store | 🔴 | MEDIUM | +| IPs of users will add SecretModel | 🔴 | MEDIUM | -- Better Auth -- Profile photos will store in a folder -- replacer function global -- page for threads - users -- IPs of users will add SecretModel - message counts for API - better theme patch UserModel - ajax, delete update thread dom diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..4f8d09b --- /dev/null +++ b/lib/index.js @@ -0,0 +1,11 @@ +module.exports = { + + URLRegex: /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g, + clearContent: (content) => { + if (!content) return ""; + return content.replaceAll("&", "&") + .replaceAll("<", "<").replaceAll(">", ">") + .replaceAll("\"", """).replaceAll("'", "'") + .replaceAll("\n", "
"); + } +} \ No newline at end of file diff --git a/public/css/pages.css b/public/css/pages.css new file mode 100644 index 0000000..9fbfc1d --- /dev/null +++ b/public/css/pages.css @@ -0,0 +1,41 @@ +.pagination { + box-shadow: 0 0 5px 0 var(--box-shadow); + margin: 10px auto; + padding: 8px; + display: flex; + justify-content: space-between; + align-items: center; + max-width: 400px; + gap: 10px; + position: relative; +} + +.pagination .back, +.pagination .after { + color: var(--second); + font-size: 26px; + cursor: pointer; +} + + +.pagination .numbers { + display: flex; + align-items: center; + gap: 5px; +} + +.pagination .number { + color: var(--second); + font-size: 22px; + border: 0 0 5px var(--second); + padding: 8px; + border-radius: 2px; + font-weight: 600; + cursor: pointer; + margin: 8px; +} + +.pagination .number.active { + color: var(--main); + font-weight: 700; +} \ No newline at end of file diff --git a/public/css/thread.css b/public/css/thread.css index 48b2aca..6a8b935 100644 --- a/public/css/thread.css +++ b/public/css/thread.css @@ -67,50 +67,6 @@ font-size: 22px; } - -.pagination { - box-shadow: 0 0 5px 0 var(--box-shadow); - margin: 10px auto; - padding: 8px; - display: flex; - justify-content: space-between; - align-items: center; - max-width: 400px; - gap: 10px; - position: relative; -} - -.pagination .back, -.pagination .after { - color: var(--second); - font-size: 26px; - cursor: pointer; -} - - -.pagination .numbers { - display: flex; - align-items: center; - gap: 5px; -} - -.pagination .number { - color: var(--second); - font-size: 22px; - border: 0 0 5px var(--second); - padding: 8px; - border-radius: 2px; - font-weight: 600; - cursor: pointer; - margin: 8px; -} - -.pagination .number.active { - color: var(--main); - font-weight: 700; -} - - .dots { position: absolute; right: 20px; diff --git a/routes/api/routes/users.js b/routes/api/routes/users.js index 3434ff6..724b69e 100644 --- a/routes/api/routes/users.js +++ b/routes/api/routes/users.js @@ -1,5 +1,6 @@ const { UserModel, SecretModel } = require("../../../models"); -const { Router } = require("express") +const { Router } = require("express"); +const { URLRegex } = require("../../../lib"); const app = Router(); @@ -58,19 +59,19 @@ app.patch("/:id/", async (req, res) => { if (admin?.length && !req.user.admin) return res.error(403, "You have not got permission for edit 'admin' information, or bad request."); - if (avatar && /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g.test(avatar)) + if (avatar && URLRegex.test(avatar)) member.avatar = avatar; if (name) { - await SecretModel.findOneAndUpdate({ name: member.name }, { name }); + await SecretModel.updateOne({ id: member.id }, { username: name }); member.name = name; } if (about) member.about = about; - if (theme) + if (theme) member.theme = member.theme === "default" ? "black" : "default"; - - if(typeof admin === "boolean" || ["false","true"].includes(admin)) member.admin = admin; + + if (typeof admin === "boolean" || ["false", "true"].includes(admin)) member.admin = admin; member.edited = true; await member.save(); diff --git a/routes/register.js b/routes/register.js index d943c5c..eb308bd 100644 --- a/routes/register.js +++ b/routes/register.js @@ -2,7 +2,7 @@ const { UserModel, SecretModel } = require("../models"); const { Router } = require("express") const bcrypt = require("bcrypt"); const rateLimit = require('express-rate-limit') - +const {URLRegex} = require("../lib") const app = Router(); app.get("/", (req, res) => res.reply("register", { user: null })); @@ -22,7 +22,7 @@ app.post("/", rateLimit({ const user2 = new UserModel({ name: req.body.username }) - if (avatar && /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g.test(avatar)) user2.avatar = avatar; + if (avatar && URLRegex.test(avatar)) user2.avatar = avatar; if (about) user2.about = about; diff --git a/routes/threads.js b/routes/threads.js index df9abc4..d2ee3b8 100644 --- a/routes/threads.js +++ b/routes/threads.js @@ -1,14 +1,15 @@ const { Router } = require("express"); const app = Router(); - +const {clearContent} = require("../lib"); const { ThreadModel, MessageModel } = require("../models") - app.get("/", async (req, res) => { - - let threads = await ThreadModel.find(req.user?.admin ? {} : { deleted: false })//.limit(10); + const page = Number(req.query.page) || 0; + const query = req.user?.admin ? {} : { deleted: false }; + let threads = await ThreadModel.find(query).limit(10).skip(page * 10); threads = await Promise.all(threads.map(thread => thread.get_author())); - return res.reply("threads", { threads }); + + return res.reply("threads", { threads, page, pages: Math.ceil(await ThreadModel.count(query) / 10) }); }); @@ -30,10 +31,7 @@ app.get("/:id/", async (req, res) => { const messages = await Promise.all(await MessageModel.find(query).sort({ time: 1 }).limit(10).skip(page * 10) .then(messages => messages.map(async message => { - message.content = message.content.replaceAll("&", "&") - .replaceAll("<", "<").replaceAll(">", ">") - .replaceAll("\"", """).replaceAll("'", "'") - .replaceAll("\n", "
"); + message.content =clearContent( message.content) return await message.get_author(); }))); res.reply("thread", { page, thread, messages, scroll: req.query.scroll || messages[0]?.id }); diff --git a/routes/users.js b/routes/users.js index d4def5c..3cfd1dc 100644 --- a/routes/users.js +++ b/routes/users.js @@ -1,16 +1,18 @@ const { Router } = require("express"); const app = Router(); +const {clearContent} = require("../lib"); const { UserModel, MessageModel, ThreadModel } = require("../models"); -app.get("/", async ({ user }, res) => { - const users = await UserModel.find(user?.admin ? {} : { deleted: false }); - return res.reply("users", { users }) - +app.get("/", async (req, res) => { + const page = Number(req.query.page) || 0; + const query = req.user?.admin ? {} : { deleted: false }; + let users = await UserModel.find(query).limit(10).skip(page * 10); + return res.reply("users", { users, page, pages: Math.ceil(await UserModel.count(query) / 10) }); }); app.get("/:id/edit", async (req, res) => { - if(!req.user || (!req.user.admin&&req.params.id !== req.user.id)) return res.error(403, "You have not got permission for this."); + if (!req.user || (!req.user.admin && req.params.id !== req.user.id)) return res.error(403, "You have not got permission for this."); const member = await UserModel.get(req.params.id); if (member && (req.user?.admin || !member.deleted)) @@ -29,10 +31,7 @@ app.get("/:id", async (req, res) => { const message = await MessageModel.count({ authorID: id }); const thread = await ThreadModel.count({ authorID: id }); - member.about = member.about.replaceAll("&", "&") - .replaceAll("<", "<").replaceAll(">", ">") - .replaceAll("\"", """).replaceAll("'", "'") - .replaceAll("\n", "
"); + member.about = clearContent( member.about) res.reply("user", { member, counts: { message, thread } }) } else res.error(404, `We don't have any user with id ${id}.`); diff --git a/views/edit_user.ejs b/views/edit_user.ejs index 95e82ef..3398bce 100644 --- a/views/edit_user.ejs +++ b/views/edit_user.ejs @@ -7,13 +7,17 @@ - + <%- include("extra/navbar") %> -

Edit <%= member.name %>

+

Edit <%= member.name %>

-
+ @@ -41,8 +45,6 @@ if (res) alert(`User is updated!`); location.reload(); }); - - diff --git a/views/thread.ejs b/views/thread.ejs index aea6cf2..fa1adec 100644 --- a/views/thread.ejs +++ b/views/thread.ejs @@ -9,6 +9,8 @@ + + <% if (user){ %> <% }; %> diff --git a/views/threads.ejs b/views/threads.ejs index eaa405d..af13387 100644 --- a/views/threads.ejs +++ b/views/threads.ejs @@ -3,9 +3,10 @@ <%- include("extra/meta", {title: "Thread list!" }) %> - + + <%- include("extra/navbar") %> @@ -20,7 +21,7 @@
<% if (user && !thread.deleted){ %> - + <% } %> <%= thread.author.name %>
@@ -32,5 +33,24 @@ <% }); %>
+ \ No newline at end of file diff --git a/views/users.ejs b/views/users.ejs index 7123e51..43b6b1c 100644 --- a/views/users.ejs +++ b/views/users.ejs @@ -5,8 +5,10 @@ + - + + <%- include("extra/navbar") %>
@@ -22,4 +24,24 @@ <% }); %>
+ \ No newline at end of file