mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-26 05:10:41 +03:00
API is optimized, and better ratelimit
This commit is contained in:
parent
853b315459
commit
dc29ed5906
9 changed files with 71 additions and 74 deletions
|
@ -23,7 +23,7 @@ And, you can learn about API in `util/APIDOCS.md`.
|
|||
- `/errors/error` will change, better error page.
|
||||
- Redirect query.
|
||||
- Will fix API
|
||||
|
||||
- message.js/12, so, admin perms,(req.user?.admin || !thread.deleted), and api in message
|
||||
## Roadmap
|
||||
### User
|
||||
| To do | Is done? | Priority |
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
class ApiResponse {
|
||||
constructor(status, result) {
|
||||
this.status = status;
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
module.exports = ApiResponse;
|
|
@ -1,13 +1,10 @@
|
|||
const { Router } = require("express")
|
||||
const app = Router();
|
||||
const bcrypt = require("bcrypt");
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* for less time
|
||||
*/
|
||||
const { request, response } = require("express");
|
||||
const { SecretModel } = require("../../models")
|
||||
const ApiResponse = require("./ApiResponse")
|
||||
const { SecretModel, UserModel } = require("../../models")
|
||||
|
||||
/**
|
||||
* AUTH TYPE:
|
||||
|
||||
|
@ -34,30 +31,37 @@ const ApiResponse = require("./ApiResponse")
|
|||
* @param {request} req
|
||||
* @param {response} res
|
||||
*/
|
||||
/*
|
||||
|
||||
app.use(async (req, res, next) => {
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }))
|
||||
res.error = (status, error) =>
|
||||
res.status(status).json({ status, result: { error } })
|
||||
|
||||
res.complate = result => res.status(200).json({ status: 200, result });
|
||||
|
||||
const { username = null, password = null } = req.headers;
|
||||
|
||||
if (!username || !password)
|
||||
return error(401, "Authorise headers are missing")
|
||||
return res.error(401, "Authorise headers are missing")
|
||||
|
||||
const user = await SecretModel.findOne({ username });
|
||||
|
||||
if (!user)
|
||||
return error(401, "We have not got any user has got this name")
|
||||
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!')
|
||||
req.user = await UserModel.findOne({ name: req.headers.username });
|
||||
|
||||
if (user.password !== password)
|
||||
return error(401, 'Incorrect Password!')
|
||||
next();
|
||||
});
|
||||
|
||||
/* will add for loop */
|
||||
app.use("/messages", require("./routes/message"))
|
||||
app.use("/users", require("./routes/user"))
|
||||
app.use("/threads", require("./routes/threads"))
|
||||
*/
|
||||
app.all("*", (req, res) => res.status(400).json(new ApiResponse(400, { error: "Bad request" })));
|
||||
|
||||
app.all("*", (req, res) => res.error(400, "Bad request"));
|
||||
|
||||
module.exports = app;
|
|
@ -1,5 +1,5 @@
|
|||
const { User, Message, Thread } = require("../../../classes");
|
||||
const ApiResponse = require("../ApiResponse");
|
||||
const { UserModel, MessageModel, ThreadModel } = require("../../../models");
|
||||
const rateLimit = require('express-rate-limit')
|
||||
|
||||
const { Router } = require("express")
|
||||
|
||||
|
@ -7,34 +7,37 @@ const app = Router();
|
|||
|
||||
app.get("/:id", async (req, res) => {
|
||||
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }));
|
||||
|
||||
const { id = null } = req.params;
|
||||
if (!id) return error(400, "Missing id in query")
|
||||
const message = await new Message().getById(id);
|
||||
if (!id) return res.error(400, "Missing id in query")
|
||||
const message = await MessageModel.get(id);
|
||||
|
||||
if (!message || message.deleted) return error(404, "We have not got any message declared as this id.");
|
||||
if (!message || message.deleted) return res.error(404, "We have not got any message declared as this id.");
|
||||
|
||||
res.status(200).json(new ApiResponse(200, message));
|
||||
res.complate(message);
|
||||
|
||||
})
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }));
|
||||
app.post("/", rateLimit({
|
||||
windowMs: 60_000, max: 1, standardHeaders: true, legacyHeaders: false,
|
||||
handler: (request, response, next, options) =>
|
||||
!request.user.admin ?
|
||||
response.error(options.statusCode, "You are begin ratelimited")
|
||||
: next()
|
||||
}), async (req, res) => {
|
||||
|
||||
const { threadID = null, content = null } = req.body;
|
||||
const thread = await new Thread().getById(threadID);
|
||||
if (!content) return res.error(400, "Missing message content in request body.");
|
||||
|
||||
if (!content) return error(400, "Missing message content in request body.");
|
||||
if (!thread) return error(404, "We have not got this thread.");
|
||||
const thread = await ThreadModel.get(threadID);
|
||||
|
||||
if (!thread) return res.error(404, "We have not got this thread.");
|
||||
|
||||
const message = await new Message(content, await new User().getByName(req.headers.username), thread.id).takeId()
|
||||
message.save();
|
||||
thread.push(message.id).save();
|
||||
const message = await new MessageModel({ content, author: req.user, threadID: thread.id }).takeId();
|
||||
await message.save();
|
||||
await thread.push(message.id).save();
|
||||
|
||||
res.status(200).json(new ApiResponse(200, message));
|
||||
res.complate(message);
|
||||
|
||||
})
|
||||
|
||||
|
|
|
@ -1,42 +1,36 @@
|
|||
const { Thread, User, Message } = require("../../../classes");
|
||||
const ApiResponse = require("../ApiResponse");
|
||||
const { UserModel, MessageModel, ThreadModel } = require("../../../models");
|
||||
const { Router } = require("express")
|
||||
|
||||
const app = Router();
|
||||
|
||||
app.get("/:id", async (req, res) => {
|
||||
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }))
|
||||
|
||||
|
||||
const { id = null } = req.params;
|
||||
if (!id) return error(400, "Missing id in query")
|
||||
if (!id) return res.error(400, "Missing id in query")
|
||||
|
||||
const thread = await new Thread().getById(id);
|
||||
if (!thread || thread.deleted) return error(404, "We have not got any thread declared as this id.");
|
||||
const thread = await ThreadModel.get(id);
|
||||
if (thread && (req.user?.admin || !thread.deleted))
|
||||
res.complate( thread);
|
||||
else
|
||||
return res.error(404, "We have not got any thread declared as this id.");
|
||||
|
||||
res.status(200).json(new ApiResponse(200, thread));
|
||||
|
||||
});
|
||||
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }));
|
||||
|
||||
const { title = null, content = null } = req.body;
|
||||
|
||||
if (!content || !title) return error(400, "Missing content/title in request body.");
|
||||
if (!content || !title) return res.error(400, "Missing content/title in request body.");
|
||||
|
||||
const user = await new User().getByName(req.headers.username)
|
||||
const thread = await new Thread(title, user).takeId()
|
||||
const message = await new Message(content, user, thread.id).takeId()
|
||||
thread.push(message.id).save();
|
||||
const user = req.user;
|
||||
const thread = await new ThreadModel({ title, author: user }).takeId()
|
||||
const message = await new MessageModel({ content, author: user, threadID: thread.id }).takeId()
|
||||
await thread.push(message.id).save();
|
||||
await message.save();
|
||||
|
||||
res.status(200).json(new ApiResponse(200, thread));
|
||||
res.complate(thread);
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
const { User } = require("../../../classes");
|
||||
const ApiResponse = require("../ApiResponse");
|
||||
const { UserModel, MessageModel, ThreadModel } = require("../../../models");
|
||||
const { Router } = require("express")
|
||||
|
||||
const app = Router();
|
||||
|
||||
app.get("/:id", async (req, res) => {
|
||||
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }))
|
||||
|
||||
|
||||
const { id = null } = req.params;
|
||||
if (!id) return error(400, "Missing id in query")
|
||||
const member = await new User().getById(id);
|
||||
if (!member || member.deleted) return error(404, "We have not got any user declared as this id.");
|
||||
if (!id) return res.error(400, "Missing id in query")
|
||||
const member = await UserModel.get(id);
|
||||
if (!member || member.deleted) return res.error(404, "We have not got any user declared as this id.");
|
||||
|
||||
res.status(200).json(new ApiResponse(200, member));
|
||||
res.complate(member);
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,11 @@ app.get("/:id", async (req, res) => {
|
|||
app.use(require("../middlewares/login"));
|
||||
|
||||
app.post("/", rateLimit({
|
||||
windowMs: 60_000, max: 1, standardHeaders: true, legacyHeaders: false
|
||||
windowMs: 60_000, max: 1, standardHeaders: true, legacyHeaders: false,
|
||||
handler: (request, response, next, options) =>
|
||||
!request.user.admin ?
|
||||
error(response, options.statusCode, "You are begin ratelimited")
|
||||
: next()
|
||||
}), async (req, res) => {
|
||||
|
||||
const thread = await ThreadModel.get(req.body.threadID);
|
||||
|
|
|
@ -28,10 +28,10 @@ app.get("/:id", async (req, res) => {
|
|||
const { id } = req.params;
|
||||
|
||||
const thread = await ThreadModel.get(id);
|
||||
|
||||
if (thread && !thread.deleted) {
|
||||
const user = req.user;
|
||||
|
||||
if (thread && (user?.admin || !thread.deleted)) {
|
||||
|
||||
const messages = await Promise.all(thread.messages.map(async id => {
|
||||
const message = await MessageModel.get(id)
|
||||
return user?.admin || !message?.deleted ? message : null;
|
||||
|
@ -49,7 +49,11 @@ app.use(require("../middlewares/login"));
|
|||
|
||||
|
||||
app.post("/", rateLimit({
|
||||
windowMs: 10 * 60_000, max: 1, standardHeaders: true, legacyHeaders: false
|
||||
windowMs: 10 * 60_000, max: 1, standardHeaders: true, legacyHeaders: false,
|
||||
handler: (request, response, next, options) =>
|
||||
!request.user.admin ?
|
||||
error(response, options.statusCode, "You are begin ratelimited")
|
||||
: next()
|
||||
}), async (req, res) => {
|
||||
|
||||
const { title = null, content = null } = req.body;
|
||||
|
|
Loading…
Reference in a new issue