API is optimized, and better ratelimit

This commit is contained in:
Akif9748 2022-08-10 02:08:18 +03:00
parent 853b315459
commit dc29ed5906
9 changed files with 71 additions and 74 deletions

View file

@ -23,7 +23,7 @@ And, you can learn about API in `util/APIDOCS.md`.
- `/errors/error` will change, better error page. - `/errors/error` will change, better error page.
- Redirect query. - Redirect query.
- Will fix API - Will fix API
- message.js/12, so, admin perms,(req.user?.admin || !thread.deleted), and api in message
## Roadmap ## Roadmap
### User ### User
| To do | Is done? | Priority | | To do | Is done? | Priority |

View file

View file

@ -1,7 +0,0 @@
class ApiResponse {
constructor(status, result) {
this.status = status;
this.result = result;
}
}
module.exports = ApiResponse;

View file

@ -1,13 +1,10 @@
const { Router } = require("express") const { Router } = require("express")
const app = Router(); const app = Router();
const bcrypt = require("bcrypt");
/**
* @deprecated
* for less time
*/
const { request, response } = require("express"); const { request, response } = require("express");
const { SecretModel } = require("../../models") const { SecretModel, UserModel } = require("../../models")
const ApiResponse = require("./ApiResponse")
/** /**
* AUTH TYPE: * AUTH TYPE:
@ -34,30 +31,37 @@ const ApiResponse = require("./ApiResponse")
* @param {request} req * @param {request} req
* @param {response} res * @param {response} res
*/ */
/*
app.use(async (req, res, next) => { app.use(async (req, res, next) => {
const error = (status, error) => res.error = (status, error) =>
res.status(status).json(new ApiResponse(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; const { username = null, password = null } = req.headers;
if (!username || !password) if (!username || !password)
return error(401, "Authorise headers are missing") return res.error(401, "Authorise headers are missing")
const user = await SecretModel.findOne({ username }); const user = await SecretModel.findOne({ username });
if (!user) 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(); next();
}); });
/* will add for loop */
app.use("/messages", require("./routes/message")) app.use("/messages", require("./routes/message"))
app.use("/users", require("./routes/user")) app.use("/users", require("./routes/user"))
app.use("/threads", require("./routes/threads")) 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; module.exports = app;

View file

@ -1,5 +1,5 @@
const { User, Message, Thread } = require("../../../classes"); const { UserModel, MessageModel, ThreadModel } = require("../../../models");
const ApiResponse = require("../ApiResponse"); const rateLimit = require('express-rate-limit')
const { Router } = require("express") const { Router } = require("express")
@ -7,34 +7,37 @@ const app = Router();
app.get("/:id", async (req, res) => { app.get("/:id", async (req, res) => {
const error = (status, error) =>
res.status(status).json(new ApiResponse(status, { error }));
const { id = null } = req.params; 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 message = await new Message().getById(id); 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) => { app.post("/", rateLimit({
const error = (status, error) => windowMs: 60_000, max: 1, standardHeaders: true, legacyHeaders: false,
res.status(status).json(new ApiResponse(status, { error })); 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 { 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."); const thread = await ThreadModel.get(threadID);
if (!thread) return error(404, "We have not got this thread.");
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() const message = await new MessageModel({ content, author: req.user, threadID: thread.id }).takeId();
message.save(); await message.save();
thread.push(message.id).save(); await thread.push(message.id).save();
res.status(200).json(new ApiResponse(200, message)); res.complate(message);
}) })

View file

@ -1,42 +1,36 @@
const { Thread, User, Message } = require("../../../classes"); const { UserModel, MessageModel, ThreadModel } = require("../../../models");
const ApiResponse = require("../ApiResponse");
const { Router } = require("express") const { Router } = require("express")
const app = Router(); const app = Router();
app.get("/:id", async (req, res) => { app.get("/:id", async (req, res) => {
const error = (status, error) =>
res.status(status).json(new ApiResponse(status, { error }))
const { id = null } = req.params; 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); const thread = await ThreadModel.get(id);
if (!thread || thread.deleted) return error(404, "We have not got any thread declared as this 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) => { app.post("/", async (req, res) => {
const error = (status, error) =>
res.status(status).json(new ApiResponse(status, { error }));
const { title = null, content = null } = req.body; 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 user = req.user;
const thread = await new Thread(title, user).takeId() const thread = await new ThreadModel({ title, author: user }).takeId()
const message = await new Message(content, user, thread.id).takeId() const message = await new MessageModel({ content, author: user, threadID: thread.id }).takeId()
thread.push(message.id).save(); await thread.push(message.id).save();
await message.save(); await message.save();
res.status(200).json(new ApiResponse(200, thread)); res.complate(thread);
}); });

View file

@ -1,21 +1,16 @@
const { User } = require("../../../classes"); const { UserModel, MessageModel, ThreadModel } = require("../../../models");
const ApiResponse = require("../ApiResponse");
const { Router } = require("express") const { Router } = require("express")
const app = Router(); const app = Router();
app.get("/:id", async (req, res) => { app.get("/:id", async (req, res) => {
const error = (status, error) =>
res.status(status).json(new ApiResponse(status, { error }))
const { id = null } = req.params; 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 member = await new User().getById(id); const member = await UserModel.get(id);
if (!member || member.deleted) return error(404, "We have not got any user declared as this 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);
}); });

View file

@ -17,7 +17,11 @@ app.get("/:id", async (req, res) => {
app.use(require("../middlewares/login")); app.use(require("../middlewares/login"));
app.post("/", rateLimit({ 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) => { }), async (req, res) => {
const thread = await ThreadModel.get(req.body.threadID); const thread = await ThreadModel.get(req.body.threadID);

View file

@ -28,9 +28,9 @@ app.get("/:id", async (req, res) => {
const { id } = req.params; const { id } = req.params;
const thread = await ThreadModel.get(id); const thread = await ThreadModel.get(id);
const user = req.user;
if (thread && !thread.deleted) { if (thread && (user?.admin || !thread.deleted)) {
const user = req.user;
const messages = await Promise.all(thread.messages.map(async id => { const messages = await Promise.all(thread.messages.map(async id => {
const message = await MessageModel.get(id) const message = await MessageModel.get(id)
@ -49,7 +49,11 @@ app.use(require("../middlewares/login"));
app.post("/", rateLimit({ 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) => { }), async (req, res) => {
const { title = null, content = null } = req.body; const { title = null, content = null } = req.body;