diff --git a/APIDOCS.md b/APIDOCS.md index 04c716b..fbf3acb 100644 --- a/APIDOCS.md +++ b/APIDOCS.md @@ -16,25 +16,30 @@ But in front end, the API will works with session. ## How to request? ### Request types: +- GET `/api/bans/` fetch all bans. +- GET `/api/bans/:id` fetch a ban. +- POST `/api/bans/:id?reason=flood` for ban an IP adress. +- DELETE `/api/bans/:id` for unban an IP adress. + - GET `/api/users/:id` for fetch user. -- POST `/api/users/:id/delete` for delete user. +- DELETE `/api/users/:id/` for delete user. - POST `/api/users/:id/undelete` for undelete user. - POST `/api/users/:id/admin` for give admin permissions for a user. -- POST `/api/users/:id/edit` for edit user. +- PATCH `/api/users/:id/` for edit user. - GET `/api/threads/:id` for fetch thread. - GET `/api/threads/:id/messages/` for fetch messages in thread. - POST `/api/threads` for create thread. -- POST `/api/threads/:id/delete` for delete thread. +- DELETE `/api/threads/:id/` for delete thread. - POST `/api/threads/:id/undelete` for undelete thread. -- POST `/api/threads/:id/edit` for edit thread. +- PATCH `/api/threads/:id/` for edit thread. - GET `/api/messages/:id` for fetch message. - POST `/api/messages` for create message. -- POST `/api/messages/:id/delete` for delete message. +- DELETE `/api/messages/:id/` for delete message. - POST `/api/messages/:id/undelete` for undelete message. - POST `/api/messages/:id/react/:type` for react to a message. -- POST `/api/messages/:id/edit` for edit message. +- PATCH `/api/messages/:id/` for edit message. ### Example request: GET ```/api/messages/0``` diff --git a/README.md b/README.md index fa580a3..9dd59a2 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Akf-forum has got an API for AJAX, other clients etc. And, you can learn about A - API, ?fast= - extra ratelimits - better edits +- IP BAN CLI IN ADMIN PANEL ### Frontend #### User diff --git a/index.js b/index.js index 346f839..8bd4c91 100644 --- a/index.js +++ b/index.js @@ -34,8 +34,6 @@ app.use(session({ secret: 'secret', resave: true, saveUninitialized: true }), } ); - - for (const file of fs.readdirSync("./routes")) app.use("/" + file.replace(".js", ""), require(`./routes/${file}`)); diff --git a/models/Ban.js b/models/Ban.js index 1c1288c..fc5f1d2 100644 --- a/models/Ban.js +++ b/models/Ban.js @@ -1,7 +1,9 @@ const mongoose = require("mongoose") const schema = new mongoose.Schema({ - ip: { type: String, unique: true } + ip: { type: String, unique: true }, + reason: { type: String, default: "No reason given" }, + authorID: { type: String } }); module.exports = mongoose.model('ban', schema); \ No newline at end of file diff --git a/public/js/thread.js b/public/js/thread.js index 83a2371..11a43c0 100644 --- a/public/js/thread.js +++ b/public/js/thread.js @@ -2,24 +2,30 @@ import request from "./request.js"; window.edit_t = async function (id) { const title = prompt("Enter new title!"); - const res = await request(`/api/threads/${id}/edit`, "POST", { title }); + const res = await request(`/api/threads/${id}/edit`, "PATCH", { title }); if (res.error) return; alert(`Thread updated`); document.getElementById("title").innerHTML = title; } - - -window.thread = async function (id, un = "") { - const res = await request(`/api/threads/${id}/${un}delete`); +window.delete_thread = async function (id) { + const res = await request(`/api/threads/${id}/`, "DELETE"); if (res.error) return; - alert(`Thread ${un}deleted`); + alert(`Thread deleted`); + location.reload(); +} + +window.undelete_thread = async function (id) { + const res = await request(`/api/threads/${id}/undelete`); + if (res.error) return; + + alert(`Thread undeleted`); location.reload(); } window.edit_message = async function (id) { const content = prompt("Enter new content!"); - const res = await request(`/api/messages/${id}/edit`, "POST", { content }); + const res = await request(`/api/messages/${id}/`, "PATCH", { content }); if (res.error) return; alert(`Message updated`); @@ -36,7 +42,7 @@ window.undelete_message = async function (id) { } window.delete_message = async function (id) { - const response = await request(`/api/messages/${id}/delete`); + const response = await request(`/api/messages/${id}/`,"DELETE"); if (response.deleted) { alert("Message deleted"); document.getElementById("dots-" + id).innerHTML = ` diff --git a/routes/admin.js b/routes/admin.js index fec6ead..fb8308b 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -1,9 +1,9 @@ const { Router } = require("express") - +const { BanModel } = require("../models"); const app = Router(); app.get("/", async (req, res) => { if (!req.user?.admin) return res.error(403, "You have not got permissions for view to this page."); - res.reply("admin") + res.reply("admin",{bans: await BanModel.find({})}); }); module.exports = app; \ No newline at end of file diff --git a/routes/api/index.js b/routes/api/index.js index cc14037..7b385ac 100644 --- a/routes/api/index.js +++ b/routes/api/index.js @@ -1,5 +1,6 @@ const { Router, request, response } = require("express") const app = Router(); +const fs =require("fs") const bcrypt = require("bcrypt"); const { SecretModel, UserModel } = require("../../models") @@ -32,11 +33,9 @@ app.use(async (req, res, next) => { next(); }); -/* will add for loop */ -app.use("/messages", require("./routes/messages")) -app.use("/users", require("./routes/users")) -app.use("/threads", require("./routes/threads")) - +for (const file of fs.readdirSync("./routes/api/routes")) + app.use("/" + file.replace(".js", ""), require(`./routes/${file}`)); + app.all("*", (req, res) => res.error(400, "Bad request")); module.exports = app; \ No newline at end of file diff --git a/routes/api/routes/bans.js b/routes/api/routes/bans.js new file mode 100644 index 0000000..a4d3a1c --- /dev/null +++ b/routes/api/routes/bans.js @@ -0,0 +1,35 @@ +const { BanModel } = require("../../../models"); +const { Router } = require("express") + +const app = Router(); + +app.use((req, res, next) => { + if (!req.user || !req.user.admin) return res.error(403, "You have not got permission for this."); + next(); +}); + +app.get("/", async (req, res) => { + const bans = await BanModel.find({}); + res.complate(bans); +}); +app.get("/:ip", async (req, res) => { + const ban = await BanModel.findOne({ ip: req.params.ip }); + if (!ban) return res.error(400, "This ip is not banned."); + res.complate(ban); + +}); + +app.post("/:ip", async (req, res) => { + + if (await BanModel.exists({ ip: req.params.ip })) return res.error(400, "This ip is already banned."); + res.complate(await BanModel.create({ ip: req.params.ip, reason: req.query.reason || "No reason given", authorID: req.user.id })); + +}); + +app.delete("/:ip/", async (req, res) => { + + if (!await BanModel.exists({ ip: req.params.ip })) return res.error(400, "This ip is already not banned."); + res.complate(await BanModel.deleteOne({ ip: req.params.ip })); + +}); +module.exports = app; \ No newline at end of file diff --git a/routes/api/routes/messages.js b/routes/api/routes/messages.js index 0bc2213..cad5705 100644 --- a/routes/api/routes/messages.js +++ b/routes/api/routes/messages.js @@ -15,7 +15,7 @@ app.get("/:id", async (req, res) => { res.complate(message.toObject({ virtuals: true })); }) -app.post("/:id/edit", async (req, res) => { +app.patch("/:id/", async (req, res) => { const message = await MessageModel.get(req.params.id); @@ -88,7 +88,7 @@ app.post("/:id/react/:type", async (req, res) => { }); -app.post("/:id/delete", async (req, res) => { +app.delete("/:id/", async (req, res) => { const message = await MessageModel.get(req.params.id); if (!message || (message.deleted && req.user && !req.user.admin)) return res.error(404, `We don't have any message with id ${req.params.id}.`); diff --git a/routes/api/routes/threads.js b/routes/api/routes/threads.js index f3985ae..b5c9120 100644 --- a/routes/api/routes/threads.js +++ b/routes/api/routes/threads.js @@ -53,7 +53,7 @@ app.post("/", async (req, res) => { res.complate(thread.toObject({ virtuals: true })); }); -app.post("/:id/edit", async (req, res) => { +app.patch("/:id/", async (req, res) => { const thread = await ThreadModel.get(req.params.id); @@ -68,7 +68,7 @@ app.post("/:id/edit", async (req, res) => { res.complate(thread.toObject({ virtuals: true })); }) -app.post("/:id/delete", async (req, res) => { +app.delete("/:id/", async (req, res) => { const thread = await ThreadModel.get(req.params.id); if (!thread || thread.deleted) return res.error(404, `We don't have any thread with id ${req.params.id}.`); const user = req.user; diff --git a/routes/api/routes/users.js b/routes/api/routes/users.js index 3cb49ce..0a0e65d 100644 --- a/routes/api/routes/users.js +++ b/routes/api/routes/users.js @@ -14,7 +14,7 @@ app.get("/:id", async (req, res) => { }); -app.post("/:id/delete/", async (req, res) => { +app.delete("/:id/", async (req, res) => { const user = req.user; if (!user.admin) return res.error(403, "You have not got permission for this."); @@ -46,7 +46,7 @@ app.post("/:id/undelete/", async (req, res) => { }) -app.post("/:id/edit", async (req, res) => { +app.patch("/:id/", async (req, res) => { const member = await UserModel.get(req.params.id); diff --git a/routes/threads.js b/routes/threads.js index fe4a8fe..f89fecf 100644 --- a/routes/threads.js +++ b/routes/threads.js @@ -12,7 +12,7 @@ app.get("/", async (req, res) => { }); -app.get("/create*", (req, res) => res.reply("create_thread")); +app.get("/create/", (req, res) => res.reply("create_thread")); app.get("/:id/", async (req, res) => { diff --git a/util/admin.js b/util/admin.js index aea3873..40ee083 100644 --- a/util/admin.js +++ b/util/admin.js @@ -6,9 +6,7 @@ mongoose.connect(process.env.MONGO_DB_URL, () => console.log("Database is connec const { UserModel } = require("../models"); (async () => { - const member= await UserModel.get(0); + const member= await UserModel.get("0"); member.admin = true; console.log(await member.save()); -})(); - - +})(); \ No newline at end of file diff --git a/util/reset.js b/util/reset.js index d63fa07..431e61a 100644 --- a/util/reset.js +++ b/util/reset.js @@ -3,14 +3,6 @@ require("dotenv").config(); mongoose.connect(process.env.MONGO_DB_URL, () => console.log("Database is connected")); -const { SecretModel, UserModel, MessageModel, ThreadModel } = require("../models"); -(async () => { - - await UserModel.deleteMany({}); - await ThreadModel.deleteMany({}); - await MessageModel.deleteMany({}); - await SecretModel.deleteMany({}); - console.log("Success") -})(); - +const Models = require("../models"); +Object.values(Models).forEach(model => model.deleteMany({}).then(console.log)); diff --git a/views/admin.ejs b/views/admin.ejs index f8a9929..5a4aa24 100644 --- a/views/admin.ejs +++ b/views/admin.ejs @@ -6,8 +6,31 @@ <%- include("extra/navbar") %> -SİLME LAN İT BEN SİLECEĞİM -

Welcome to the admin panel of the forum, <%= user.name %>!

-

Write an ID to give someone admin permissions:

+ SİLME LAN İT BEN SİLECEĞİM +

Welcome to the admin panel of the forum, <%= user.name %>!

+

Banned users:

+ + + + + + + + <% for (const ban of bans) { %> + + + + + + <% } %> +
IPReasonAuthorID
<%=ban.ip%><%=ban.reason%><%=ban.authorID%>
+ + + diff --git a/views/thread.ejs b/views/thread.ejs index 196519e..7b75095 100644 --- a/views/thread.ejs +++ b/views/thread.ejs @@ -16,7 +16,7 @@
<%= thread.title %>
- <%= new Date(thread.time).toLocaleString() %> • Views: <%= thread.views %> + <%= new Date(thread.time).toLocaleString() %> • Views: <%= thread.views %> <%= "• "+thread.edited %>
@@ -25,11 +25,11 @@ <% if (user && !thread.deleted){ %> - DELETE + DELETE EDIT <% } else if (thread.deleted) { %>

This thread has been deleted

- UNDELETE + UNDELETE <% }; %> diff --git a/views/user.ejs b/views/user.ejs index 761e36b..e926a25 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -36,52 +36,51 @@

<%= counts.thread %>

-

About:


+

About:

<%= member.about %>

- <% if (user && (user.id === member.id ||user.admin)) {%> - - Change name of the user! - Change avatar of the user! <% if (user?.admin && !member.deleted) {%> + Change name of the user! + Change avatar of the user! + Change about of the user! Give admin permissions! - Delete user! + Delete user! - <% }; %> - <% if (member.deleted) {%> -

This user has been deleted!

- Undelete user! + <% }; %> + <% if (member.deleted) {%> +

This user has been deleted!

+ Undelete user! - - - - <% }; %> + if (response.deleted) return; + alert("User is undeleted successfully!"); + location.reload() + } + + <% }; %> - +