mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-26 05:10:41 +03:00
ratelimit & crypto & .ejs fix
added ratelimit to post threads and messages. Added encryption to passwords. Thread.ejs is fixed
This commit is contained in:
parent
086f2b5713
commit
11965e8de9
9 changed files with 44 additions and 12 deletions
|
@ -6,9 +6,10 @@ A forum software written in Node.js.
|
|||
## Installation
|
||||
- Clone or download this repo.
|
||||
- Run `npm i` to install **dependencies**.
|
||||
- Run `node util/reset` to **reset the database**, and `npm start` for run it.
|
||||
- Run `npm start` for run it.
|
||||
|
||||
**Note:** Reseting the database is important!
|
||||
### Extra
|
||||
Run `node util/reset` to **reset the database**, and run `node util/admin` for give admin perms for first member.
|
||||
|
||||
## API
|
||||
Akf-forum has got an API for other clients etc. You can test api with run apitest.py.
|
||||
|
@ -21,7 +22,6 @@ And, you can learn about API in `util/APIDOCS.md`.
|
|||
## To do (Backend, bug fixes)
|
||||
- `/errors/error` will change, better error page.
|
||||
- Redirect query.
|
||||
- middleware for timeouts
|
||||
- Will fix API
|
||||
|
||||
## Roadmap
|
||||
|
@ -42,7 +42,7 @@ And, you can learn about API in `util/APIDOCS.md`.
|
|||
### Messages
|
||||
| To do | Is done? | Priority |
|
||||
| ----- | -------- | -------- |
|
||||
| Ratelimit | 🔴 | HIGH |
|
||||
| Ratelimit | 🟢 | HIGH |
|
||||
| Send | 🟢 | HIGH |
|
||||
| Delete | 🟢 | HIGH |
|
||||
| Edit | 🔴 | HIGH |
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const mongoose = require("mongoose")
|
||||
|
||||
const schema = new mongoose.Schema({
|
||||
id: { type: String, unique: true },
|
||||
id: { type: String },
|
||||
|
||||
name: String,
|
||||
avatar: { type: String, default: "/images/guest.png" },
|
||||
|
|
18
package-lock.json
generated
18
package-lock.json
generated
|
@ -14,6 +14,7 @@
|
|||
"dotenv": "^16.0.1",
|
||||
"ejs": "^3.1.6",
|
||||
"express": "^4.17.3",
|
||||
"express-rate-limit": "^6.5.1",
|
||||
"express-session": "^1.17.2",
|
||||
"mongoose": "^6.5.1"
|
||||
}
|
||||
|
@ -486,6 +487,17 @@
|
|||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express-rate-limit": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.5.1.tgz",
|
||||
"integrity": "sha512-pxO6ioBLd3i8IHL+RmJtL4noYzte5fugoMdaDabtU4hcg53+x0QkTwfPtM7vWD0YUaXQgNj9NRdzmps+CHEHlA==",
|
||||
"engines": {
|
||||
"node": ">= 12.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"express": "^4 || ^5"
|
||||
}
|
||||
},
|
||||
"node_modules/express-session": {
|
||||
"version": "1.17.2",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz",
|
||||
|
@ -1904,6 +1916,12 @@
|
|||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"express-rate-limit": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.5.1.tgz",
|
||||
"integrity": "sha512-pxO6ioBLd3i8IHL+RmJtL4noYzte5fugoMdaDabtU4hcg53+x0QkTwfPtM7vWD0YUaXQgNj9NRdzmps+CHEHlA==",
|
||||
"requires": {}
|
||||
},
|
||||
"express-session": {
|
||||
"version": "1.17.2",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz",
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"dotenv": "^16.0.1",
|
||||
"ejs": "^3.1.6",
|
||||
"express": "^4.17.3",
|
||||
"express-rate-limit": "^6.5.1",
|
||||
"express-session": "^1.17.2",
|
||||
"mongoose": "^6.5.1"
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ const { UserModel, SecretModel } = require("../models");
|
|||
const { Router } = require("express");
|
||||
const error = require("../errors/error");
|
||||
const app = Router();
|
||||
const bcrypt = require("bcrypt");
|
||||
|
||||
app.get("/", (req, res) => res.render("login"));
|
||||
|
||||
|
@ -13,7 +14,10 @@ app.post("/", async (req, res) => {
|
|||
if (username && password) {
|
||||
const user = await SecretModel.findOne({ username });
|
||||
if (user) {
|
||||
if (user.password !== password) return error(res, 403, 'Incorrect Password!')
|
||||
|
||||
const validPassword = await bcrypt.compare(password, user.password);
|
||||
|
||||
if (!validPassword) return error(res, 403, 'Incorrect Password!')
|
||||
const member = await UserModel.findOne({ name: username });
|
||||
if (!member || member.deleted) return error(res, 403, 'Incorrect Username and/or Password!')
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const { ThreadModel, MessageModel } = require("../models");
|
||||
const error = require("../errors/error")
|
||||
const rateLimit = require('express-rate-limit')
|
||||
|
||||
const { Router } = require("express");
|
||||
|
||||
|
@ -15,8 +16,9 @@ app.get("/:id", async (req, res) => {
|
|||
|
||||
app.use(require("../middlewares/login"));
|
||||
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
app.post("/", rateLimit({
|
||||
windowMs: 60_000, max: 1, standardHeaders: true, legacyHeaders: false
|
||||
}), async (req, res) => {
|
||||
|
||||
const thread = await ThreadModel.get(req.body.threadID);
|
||||
if (thread) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const { UserModel, SecretModel } = require("../models");
|
||||
const { Router } = require("express")
|
||||
const error = require("../errors/error")
|
||||
const bcrypt = require("bcrypt");
|
||||
|
||||
const app = Router();
|
||||
|
||||
|
@ -24,6 +25,9 @@ app.post("/", async (req, res) => {
|
|||
const user2 = new UserModel({ name: req.body.username, avatar })
|
||||
await user2.takeId()
|
||||
await user2.save();
|
||||
|
||||
const salt = await bcrypt.genSalt(10);
|
||||
password = await bcrypt.hash(password, salt);
|
||||
await SecretModel.create({ username, password, id: user2.id })
|
||||
req.session.userid = user2.id;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const { Router } = require("express");
|
||||
const app = Router();
|
||||
const rateLimit = require('express-rate-limit')
|
||||
|
||||
const error = require("../errors/error")
|
||||
const { ThreadModel, MessageModel } = require("../models")
|
||||
|
@ -47,7 +48,9 @@ app.get("/:id", async (req, res) => {
|
|||
app.use(require("../middlewares/login"));
|
||||
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
app.post("/", rateLimit({
|
||||
windowMs: 10*60_000, max: 1, standardHeaders: true, legacyHeaders: false
|
||||
}), async (req, res) => {
|
||||
|
||||
const { title = null, content = null } = req.body;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<%= thread.title %>
|
||||
</h1>
|
||||
|
||||
<h2>By <a style="color: #bcbcbc;" href=<%="/users/" + thread.author.id %>> <%= thread.author.name %></a>
|
||||
<h2>By <a href=<%="/users/" + thread.author.id %>> <%= thread.author.name %></a>
|
||||
<img class="yuvarlak" src=<%= thread.author.avatar %> alt=<%= thread.author.name %>>
|
||||
</h2>
|
||||
<hr>
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
<h2>
|
||||
<img class="yuvarlak" src=<%=message.author.avatar %> alt=<%= message.author.name %>>
|
||||
<a style="color: #bcbcbc;" href=<%="/users/" + message.author.id %>> <%= message.author.name %></a>:
|
||||
<a href=<%="/users/" + message.author.id %>> <%= message.author.name %></a>:
|
||||
</h2>
|
||||
|
||||
<h2>
|
||||
|
|
Loading…
Reference in a new issue