mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-01 03:25:04 +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.
|
- `/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 |
|
||||||
|
|
|
@ -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 { 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;
|
|
@ -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);
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -28,10 +28,10 @@ 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);
|
||||||
|
|
||||||
if (thread && !thread.deleted) {
|
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
|
|
||||||
|
if (thread && (user?.admin || !thread.deleted)) {
|
||||||
|
|
||||||
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)
|
||||||
return user?.admin || !message?.deleted ? message : null;
|
return user?.admin || !message?.deleted ? message : null;
|
||||||
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue