mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-26 05:10:41 +03:00
Database changed to MongoDB
This commit is contained in:
parent
9c1b9997b6
commit
8024891de2
36 changed files with 807 additions and 1210 deletions
|
@ -19,8 +19,6 @@ And, you can learn informations about API in `APIDOCS.md`.
|
|||
|
||||
## To Do (Backend, bug fixes)
|
||||
- Better error codes, example 400 for bad request
|
||||
- Database change. (To MongoDB)
|
||||
- Better DB writing. Example, not `message.author.id`, `messsage.authorID`
|
||||
- `/errors/error` will change, better error page.
|
||||
|
||||
## Roadmap
|
||||
|
@ -48,12 +46,12 @@ And, you can learn informations about API in `APIDOCS.md`.
|
|||
- [ ] Multiple theme support
|
||||
- [ ] Search
|
||||
- [x] New Thread theme, better render for messages
|
||||
- [ ] sending message etc. Will turn api model
|
||||
- [ ] Sending message etc. Will turn api model
|
||||
- [ ] API
|
||||
- [x] Other client for forum via API
|
||||
- [ ] Deleting message
|
||||
- [x] Sending message
|
||||
- [ ] Open thread
|
||||
- [x] Open thread
|
||||
- [x] Get Thread info
|
||||
## Image:
|
||||
![image](https://user-images.githubusercontent.com/70021050/160255959-ef216cba-1348-4d4b-9347-fe67e21348e7.png)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
const Message = require("./message");
|
||||
const Thread = require("./thread");
|
||||
const User = require("./user");
|
||||
const React = require("./react");
|
||||
|
||||
/**
|
||||
* Classes for akf-forum;
|
||||
*/
|
||||
module.exports = { Message, Thread, User, React };
|
||||
module.exports = { Message, Thread, User };
|
|
@ -1,44 +1,52 @@
|
|||
const { MessageModel } = require("../models");
|
||||
const User = require("./user");
|
||||
|
||||
const User = require("./user")
|
||||
const Thread = require("./thread")
|
||||
const db = require("quick.db");
|
||||
module.exports = class Message {
|
||||
|
||||
|
||||
constructor(content, author = new User(), thread = new Thread(), time = new Date().getTime(), deleted = false, edited = false, react = {}) {
|
||||
|
||||
constructor(content, author = User, threadID = null, time = Date.now(), deleted = false, edited = false, react = {}) {
|
||||
|
||||
this.authorID = author?.id;
|
||||
this.content = content;
|
||||
this.author = author;
|
||||
this.time = time;
|
||||
this.thread = thread;
|
||||
this.threadID = threadID;
|
||||
this.deleted = deleted;
|
||||
this.edited = edited;
|
||||
this.react = react;
|
||||
|
||||
}
|
||||
getId(id = this.id) {
|
||||
const message = db.get("messages").find(msg => msg.id == id);
|
||||
async getById(id = this.id) {
|
||||
this.id = Number(id);
|
||||
|
||||
const message = await MessageModel.findOne({ id });
|
||||
if (!message) return null;
|
||||
|
||||
this.id = Number(id);
|
||||
const { content, author, thread = new Thread(), time = new Date().getTime(), deleted = false, edited = false, react = {} } = message;
|
||||
const { content, authorID, author = null, threadID = null, time = Date.now(), deleted = false, edited = false, react = {} } = message;
|
||||
this.content = content;
|
||||
this.thread = thread;
|
||||
this.threadID = threadID;
|
||||
this.author = author;
|
||||
this.authorID = authorID;
|
||||
this.time = time;
|
||||
this.deleted = deleted;
|
||||
this.edited = edited;
|
||||
this.react = react;
|
||||
return this
|
||||
}
|
||||
takeId() {
|
||||
this.id = db.get("messages").length || 0;
|
||||
return this;
|
||||
}
|
||||
write(id = this.id) {
|
||||
db.set("messages." + id, this)
|
||||
|
||||
async takeId() {
|
||||
this.id = await MessageModel.count({}) || 0;
|
||||
return this;
|
||||
}
|
||||
async write(id = this.id) {
|
||||
const writing = await MessageModel.findOneAndUpdate({ id }, this);
|
||||
|
||||
if (!writing)
|
||||
await MessageModel.create(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
getLink(id = this.id) {
|
||||
return "/messages/" + id;
|
||||
}
|
||||
|
|
8
classes/react.js
vendored
8
classes/react.js
vendored
|
@ -1,8 +0,0 @@
|
|||
const User = require("./user")
|
||||
|
||||
module.exports = class Message {
|
||||
constructor(like = true, author = new User()) {
|
||||
this.like = like;
|
||||
this.author= author;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
const db = require("quick.db")
|
||||
const User = require("./user")
|
||||
|
||||
|
||||
const { ThreadModel } = require("../models");
|
||||
|
||||
|
||||
module.exports = class Thread {
|
||||
|
||||
constructor(title, author = new User(), messages = [], time = new Date().getTime(),deleted = false) {
|
||||
constructor(title, author = User, messages = [], time = Date.now(), deleted = false) {
|
||||
|
||||
this.author = author;
|
||||
this.authorID = author?.id;
|
||||
this.title = title;
|
||||
this.messages = messages;
|
||||
this.time = time;
|
||||
|
@ -16,38 +16,44 @@ module.exports = class Thread {
|
|||
|
||||
}
|
||||
|
||||
getId(id = this.id) {
|
||||
const thread = db.get("threads").find(t => t.id == id);
|
||||
if (!thread) return null;
|
||||
async getById(id = this.id) {
|
||||
this.id = Number(id);
|
||||
const { title, author, messages = [], time = new Date().getTime(), deleted = false } = thread;
|
||||
|
||||
|
||||
const thread = await ThreadModel.findOne({ id });
|
||||
if (!thread) return null;
|
||||
|
||||
const { title, authorID, author, messages = [], time = Date.now(), deleted = false } = thread;
|
||||
this.title = title
|
||||
this.author = author
|
||||
this.author = author;
|
||||
this.authorID = authorID;
|
||||
this.messages = messages;
|
||||
this.time = time;
|
||||
this.deleted = deleted;
|
||||
|
||||
return this;
|
||||
}
|
||||
takeId(){
|
||||
|
||||
|
||||
this.id = db.get("threads").length;
|
||||
return this
|
||||
}
|
||||
|
||||
push(message){
|
||||
this.messages.push(message)
|
||||
push(messageID) {
|
||||
this.messages.push(messageID)
|
||||
return this;
|
||||
}
|
||||
write(id = this.id) {
|
||||
|
||||
db.set("threads."+id, this)
|
||||
async takeId() {
|
||||
this.id = await ThreadModel.count({}) || 0;
|
||||
return this;
|
||||
}
|
||||
async write(id = this.id) {
|
||||
const writing = await ThreadModel.findOneAndUpdate({ id }, this);
|
||||
|
||||
if (!writing)
|
||||
await ThreadModel.create(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
getLink(id = this.id) {
|
||||
return "/threads/" + id;
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
const db = require("quick.db")
|
||||
const { UserModel } = require("../models");
|
||||
|
||||
module.exports = class User {
|
||||
|
||||
|
||||
constructor(name = "guest", avatar = "/images/guest.png", time = new Date().getTime(), admin = false, deleted = false) {
|
||||
constructor(name = "guest", avatar = "/images/guest.png", time = Date.now(), admin = false, deleted = false) {
|
||||
|
||||
this.name = name;
|
||||
this.avatar = avatar;
|
||||
|
@ -13,26 +13,12 @@ module.exports = class User {
|
|||
|
||||
}
|
||||
|
||||
getId(id = this.id) {
|
||||
const user = db.get("users").find(u => u.id == id);
|
||||
if (!user) return null;
|
||||
async getById(id = this.id) {
|
||||
this.id = Number(id);
|
||||
const { name = "guest", avatar = "/images/guest.png", time = new Date().getTime(), admin = false, deleted = false } = user;
|
||||
this.name = name;
|
||||
this.avatar = avatar;
|
||||
this.time = time;
|
||||
this.admin = admin;
|
||||
this.deleted = deleted;
|
||||
return this ;
|
||||
|
||||
}
|
||||
|
||||
getName(name1 = this.name) {
|
||||
|
||||
const user = db.get("users").find(u => u.name == name1);
|
||||
const user = await UserModel.findOne({ id });
|
||||
if (!user) return null;
|
||||
this.id = Number(user.id);
|
||||
const { name = "guest", avatar = "/images/guest.png", time = new Date().getTime(), admin = false, deleted = false } = user;
|
||||
|
||||
const { name = "guest", avatar = "/images/guest.png", time = Date.now(), admin = false, deleted = false } = user;
|
||||
this.name = name;
|
||||
this.avatar = avatar;
|
||||
this.time = time;
|
||||
|
@ -41,16 +27,36 @@ module.exports = class User {
|
|||
return this;
|
||||
|
||||
}
|
||||
takeId() {
|
||||
let id = db.get("users");
|
||||
this.id = id ? id.length : 0;
|
||||
return this
|
||||
|
||||
async getByName(Name = this.name) {
|
||||
|
||||
const user = await UserModel.findOne({ name: Name });
|
||||
if (!user) return null;
|
||||
|
||||
const { name = "guest", avatar = "/images/guest.png", time = Date.now(), admin = false, deleted = false } = user;
|
||||
this.name = name;
|
||||
this.avatar = avatar;
|
||||
this.time = time;
|
||||
this.admin = admin;
|
||||
this.deleted = deleted;
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
write(id = this.id) {
|
||||
|
||||
db.set("users." + id, this)
|
||||
async takeId() {
|
||||
this.id = await UserModel.count({}) || 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
async write(id = this.id) {
|
||||
const writing = await UserModel.findOneAndUpdate({ id }, this);
|
||||
|
||||
if (!writing)
|
||||
await UserModel.create(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
getLink(id = this.id) {
|
||||
return "/users/" + id;
|
||||
}
|
||||
|
|
5
index.js
5
index.js
|
@ -2,15 +2,20 @@ const error = require("./errors/error.js"),
|
|||
session = require('express-session'),
|
||||
bodyParser = require('body-parser'),
|
||||
port = process.env.PORT ?? 3000,
|
||||
mongoose = require("mongoose"),
|
||||
express = require('express'),
|
||||
fs = require("fs"),
|
||||
app = express();
|
||||
|
||||
mongoose.connect('mongodb://localhost:27017/akf-forum', () =>console.log("Database is connected"));
|
||||
|
||||
app.use(session({ secret: 'secret', resave: true, saveUninitialized: true }));
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
app.use(express.static("public"));
|
||||
app.set("view engine", "ejs");
|
||||
app.use(express.json());
|
||||
app.use(require("./middlewares/user"));
|
||||
app.use(require("./middlewares/timeout"));
|
||||
|
||||
for (const file of fs.readdirSync("./routes"))
|
||||
app.use("/" + file.replace(".js", ""), require(`./routes/${file}`));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = (req, res, next) => {
|
||||
if (!req.session.loggedin) return res.redirect('/login');
|
||||
if (!req.session.userid?.toString()) return res.redirect('/login');
|
||||
next();
|
||||
}
|
15
middlewares/timeout.js
Normal file
15
middlewares/timeout.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const { TimeoutModel } = require("../models");
|
||||
module.exports = async (req, res, next) => {
|
||||
if (!req.user || req.user.admin) return next();
|
||||
|
||||
const timeout = await TimeoutModel.findOne({ id: req.user.id }) || new TimeoutModel({ until: Date.now() - 1000, id: req.user.id });
|
||||
|
||||
req.timeout = timeout;
|
||||
|
||||
if (timeout.until > Date.now())
|
||||
req.ratelimit = true;
|
||||
|
||||
|
||||
next();
|
||||
|
||||
}
|
6
middlewares/user.js
Normal file
6
middlewares/user.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
const { User } = require("../classes");
|
||||
|
||||
module.exports = async (req, res, next) => {
|
||||
req.user = await new User().getById(req.session.userid);
|
||||
next();
|
||||
}
|
17
models/Message.js
Normal file
17
models/Message.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const { Schema, model } = require("mongoose")
|
||||
|
||||
module.exports = model('message', new Schema({
|
||||
id: { type: Number, unique: true },
|
||||
|
||||
authorID: Number,
|
||||
threadID: Number,
|
||||
author: Object,
|
||||
|
||||
content: String,
|
||||
time: Number,
|
||||
deleted: { type: Boolean, default: false },
|
||||
edited: { type: Boolean, default: false },
|
||||
messages: [Number],
|
||||
react: Object
|
||||
|
||||
}))
|
10
models/Secret.js
Normal file
10
models/Secret.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const { Schema, model } = require("mongoose")
|
||||
|
||||
module.exports = model('secret', new Schema({
|
||||
|
||||
username: { type: String, unique: true },
|
||||
password: String,
|
||||
id: { type: Number, unique: true }
|
||||
|
||||
|
||||
}))
|
15
models/Thread.js
Normal file
15
models/Thread.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const { Schema, model } = require("mongoose")
|
||||
|
||||
|
||||
module.exports = model('thread', new Schema({
|
||||
id: { type: Number, unique: true },
|
||||
|
||||
authorID: Number,
|
||||
author: Object,
|
||||
|
||||
title: String,
|
||||
time: Number,
|
||||
deleted: { type: Boolean, default: false },
|
||||
messages: [Number]
|
||||
|
||||
}))
|
8
models/Timeout.js
Normal file
8
models/Timeout.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
const { Schema, model } = require("mongoose")
|
||||
|
||||
|
||||
module.exports = model('timeout', new Schema({
|
||||
id: { type: Number, unique: true },
|
||||
until: Number
|
||||
|
||||
}))
|
12
models/User.js
Normal file
12
models/User.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
const { Schema, model } = require("mongoose")
|
||||
|
||||
module.exports = model('user', new Schema({
|
||||
id: { type: Number, unique: true },
|
||||
|
||||
name: String,
|
||||
avatar: String,
|
||||
time: Number,
|
||||
deleted: { type: Boolean, default: false },
|
||||
admin: { type: Boolean, default: false }
|
||||
|
||||
}))
|
7
models/index.js
Normal file
7
models/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
const UserModel = require("./User"),
|
||||
MessageModel = require("./Message"),
|
||||
ThreadModel = require("./Thread"),
|
||||
SecretModel = require("./Secret"),
|
||||
TimeoutModel = require("./Timeout");
|
||||
|
||||
module.exports = { UserModel, MessageModel, ThreadModel, SecretModel, TimeoutModel };
|
1322
package-lock.json
generated
1322
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "akf-lang",
|
||||
"name": "akf-forum",
|
||||
"version": "2.1.2",
|
||||
"description": "A forum script written in Node.js",
|
||||
"main": "index.js",
|
||||
|
@ -9,7 +9,7 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Akif9748/akf-lang.git"
|
||||
"url": "git+https://github.com/Akif9748/akf-forum.git"
|
||||
},
|
||||
"author": "Akif9748",
|
||||
"contributors": [
|
||||
|
@ -17,7 +17,7 @@
|
|||
],
|
||||
"license": "GPL-3.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Akif9748/akf-lang/issues"
|
||||
"url": "https://github.com/Akif9748/akf-forum/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Akif9748/akf-lang#readme",
|
||||
"dependencies": {
|
||||
|
@ -25,6 +25,6 @@
|
|||
"ejs": "^3.1.6",
|
||||
"express": "^4.17.3",
|
||||
"express-session": "^1.17.2",
|
||||
"quick.db": "^7.1.3"
|
||||
"mongoose": "^6.2.9"
|
||||
}
|
||||
}
|
||||
|
|
19
reset.js
19
reset.js
|
@ -1,7 +1,14 @@
|
|||
const { set } = require("quick.db");
|
||||
set("users", new Array());
|
||||
set("threads", new Array());
|
||||
set("secret", new Object());
|
||||
set("messages", new Array());
|
||||
set("timeouts", new Array());
|
||||
const mongoose = require("mongoose");
|
||||
mongoose.connect('mongodb://localhost:27017/akf-forum', () => 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")
|
||||
})();
|
||||
|
||||
|
||||
|
|
15
routes/.js
15
routes/.js
|
@ -1,17 +1,14 @@
|
|||
const { User } = require("../classes");
|
||||
const { get } = require("quick.db")
|
||||
|
||||
const { UserModel, ThreadModel, MessageModel } = require("../models")
|
||||
const { Router } = require("express");
|
||||
const app = Router();
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
|
||||
app.get("/", async (req, res) => {
|
||||
const
|
||||
mem = process.memoryUsage().heapUsed / Math.pow(2, 20),
|
||||
users = get("users").length,
|
||||
threads = get("threads").length,
|
||||
messages = get("messages").length,
|
||||
user = new User().getId(req.session.userid);
|
||||
users = await UserModel.count({}),
|
||||
threads = await ThreadModel.count({}),
|
||||
messages = await MessageModel.count({}),
|
||||
user = req.user;
|
||||
|
||||
res.render("index", { mem, user, users, threads, messages })
|
||||
|
||||
|
|
|
@ -7,20 +7,20 @@ const app = Router();
|
|||
|
||||
app.use(require("../middlewares/login"));
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
const user = new User().getId(req.session.userid)
|
||||
app.get("/", async (req, res) => {
|
||||
const user = req.user;
|
||||
|
||||
if (!user.admin) return error(res, 403, "You have not got permissions for view to this page.");
|
||||
|
||||
res.render("admin", { user, user2: false })
|
||||
});
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
app.post("/", async (req, res) => {
|
||||
|
||||
const user = new User().getId(req.session.userid)
|
||||
const user = req.user;
|
||||
|
||||
if (!user.admin) return error(res, 403, "You have not got permissions for view to this page.");
|
||||
const user2 = new User().getId(req.body.userid)
|
||||
const user2 = await new User().getById(req.body.userid)
|
||||
|
||||
if (!user2)
|
||||
return error(res, 404, "We have not got this user in all of the forum. Vesselam.");
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
const { User, Message, Thread } = require("../../classes");
|
||||
const db = require("quick.db");
|
||||
const { Router } = require("express")
|
||||
const app = Router();
|
||||
|
||||
|
||||
const { request, response } = require("express");
|
||||
|
||||
|
||||
const { SecretModel } = require("../../models")
|
||||
const ApiResponse = require("./ApiResponse")
|
||||
/**
|
||||
* AUTH TYPE:
|
||||
|
||||
|
@ -29,29 +27,29 @@ const { request, response } = require("express");
|
|||
|
||||
|
||||
/**
|
||||
* For intellisense
|
||||
* Auth checker
|
||||
* @param {request} req
|
||||
* @param {response} res
|
||||
*/
|
||||
|
||||
app.use((req, res, next) => {
|
||||
app.use(async (req, res, next) => {
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }))
|
||||
|
||||
const { username = null, password = null } = req.headers;
|
||||
|
||||
if (!username || !password)
|
||||
return error(401, "Headers are missing")
|
||||
return error(401, "Authorise headers are missing")
|
||||
|
||||
const user = db.get("secret." + username);
|
||||
const user = await SecretModel.findOne({ username });
|
||||
|
||||
if (!user)
|
||||
return error(401, "We have not got any user has got this name")
|
||||
|
||||
if (user.key !== password)
|
||||
if (user.password !== password)
|
||||
return error(401, 'Incorrect Password!')
|
||||
next();
|
||||
})
|
||||
});
|
||||
|
||||
app.use("/messages", require("./routes/message"))
|
||||
app.use("/users", require("./routes/user"))
|
||||
|
|
|
@ -5,14 +5,14 @@ const { Router } = require("express")
|
|||
|
||||
const app = Router();
|
||||
|
||||
app.get("/:id", (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;
|
||||
if (!id) return error(400, "Missing id in query")
|
||||
const message = new Message().getId(id);
|
||||
const message = await new Message().getById(id);
|
||||
|
||||
if (!message || message.deleted) return error(404, "We have not got any message declared as this id.");
|
||||
|
||||
|
@ -20,18 +20,18 @@ app.get("/:id", (req, res) => {
|
|||
|
||||
})
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }));
|
||||
const { threadID = null, content = null } = req.body;
|
||||
const thread = new Thread().getId(threadID);
|
||||
const thread = await new Thread().getById(threadID);
|
||||
|
||||
if (!content) return error(400, "Missing message content in request body.");
|
||||
if (!thread) return error(404, "We have not got this thread.");
|
||||
|
||||
|
||||
const message = new Message(content, new User().getName(req.headers.username), thread).takeId().write();
|
||||
const message = await new Message(content, await new User().getByName(req.headers.username), thread.id).takeId()
|
||||
message.write();
|
||||
thread.push(message.id).write();
|
||||
|
||||
res.status(200).json(new ApiResponse(200, message));
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const { Thread } = require("../../../classes");
|
||||
const { Thread, User, Message } = require("../../../classes");
|
||||
const ApiResponse = require("../ApiResponse");
|
||||
const { Router } = require("express")
|
||||
|
||||
const app = Router();
|
||||
|
||||
app.get("/:id", (req, res) => {
|
||||
app.get("/:id", async (req, res) => {
|
||||
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }))
|
||||
|
@ -13,11 +13,31 @@ app.get("/:id", (req, res) => {
|
|||
const { id = null } = req.params;
|
||||
if (!id) return error(400, "Missing id in query")
|
||||
|
||||
const thread = new Thread().getId(id);
|
||||
const thread = await new Thread().getById(id);
|
||||
if (!thread || thread.deleted) return 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.");
|
||||
|
||||
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).write();
|
||||
await message.write();
|
||||
|
||||
res.status(200).json(new ApiResponse(200, thread));
|
||||
|
||||
});
|
||||
|
||||
module.exports = app;
|
|
@ -4,7 +4,7 @@ const { Router } = require("express")
|
|||
|
||||
const app = Router();
|
||||
|
||||
app.get("/:id", (req, res) => {
|
||||
app.get("/:id", async (req, res) => {
|
||||
|
||||
const error = (status, error) =>
|
||||
res.status(status).json(new ApiResponse(status, { error }))
|
||||
|
@ -12,7 +12,7 @@ app.get("/:id", (req, res) => {
|
|||
|
||||
const { id = null } = req.params;
|
||||
if (!id) return error(400, "Missing id in query")
|
||||
const member = new User().getId(id);
|
||||
const member = await new User().getById(id);
|
||||
if (!member || member.deleted) return error(404, "We have not got any user declared as this id.");
|
||||
|
||||
res.status(200).json(new ApiResponse(200, member));
|
||||
|
|
|
@ -1,27 +1,23 @@
|
|||
const { User } = require("../classes");
|
||||
const db = require("quick.db")
|
||||
|
||||
const { Router } = require("express")
|
||||
const error = require("../errors/error")
|
||||
|
||||
const { Router } = require("express");
|
||||
const { SecretModel } = require("../models");
|
||||
const error = require("../errors/error");
|
||||
const app = Router();
|
||||
|
||||
app.get("/", (req, res) => res.render("login"));
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
req.session.loggedin = false;
|
||||
req.session.username = null;
|
||||
app.post("/", async (req, res) => {
|
||||
req.session.userid = null;
|
||||
|
||||
const { username = null, password = null } = req.body;
|
||||
|
||||
if (username && password) {
|
||||
const user = db.get("secret." + username)
|
||||
const user = await SecretModel.findOne({ username });
|
||||
if (user) {
|
||||
// Authenticate the user
|
||||
if (user.key !== password) return error(res, 403, 'Incorrect Password!')
|
||||
if (new User().getName(username).deleted) return error(res, 403, 'Incorrect Username and/or Password!')
|
||||
req.session.loggedin = true;
|
||||
req.session.username = username;
|
||||
if (user.password !== password) return error(res, 403, 'Incorrect Password!')
|
||||
const member = await new User().getByName(username)
|
||||
if (!member || member.deleted) return error(res, 403, 'Incorrect Username and/or Password!')
|
||||
|
||||
req.session.userid = user.id;
|
||||
|
||||
res.redirect('/');
|
||||
|
|
|
@ -5,24 +5,31 @@ const { Router } = require("express");
|
|||
|
||||
const app = Router();
|
||||
|
||||
app.get("/:id", (req, res) => {
|
||||
const message = new Message().getId(req.params.id);
|
||||
app.get("/:id", async (req, res) => {
|
||||
const message = await new Message().getById(req.params.id);
|
||||
|
||||
if (!message || message.deleted) return error(res, 404, "We have not got any message declared as this id.");
|
||||
|
||||
res.redirect("/threads/" + message.thread.id);
|
||||
res.redirect("/threads/" + message.threadID);
|
||||
|
||||
});
|
||||
|
||||
app.use(require("../middlewares/login"));
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
const thread = new Thread().getId(req.body.threadID);
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
if (req.ratelimit)
|
||||
return error(res, 429, "Wait until " + new Date(req.timeout.until).toLocaleTimeString("tr") + ", you are too quick for send.")
|
||||
|
||||
const thread = await new Thread().getById(req.body.threadID);
|
||||
if (thread) {
|
||||
const message = new Message(req.body.content, new User().getId(req.session.userid), thread).takeId().write();
|
||||
thread.push(message.id)
|
||||
const message = await new Message(req.body.content, req.user, thread.id).takeId()
|
||||
await message.write();
|
||||
thread.push(message.id);
|
||||
thread.write();
|
||||
|
||||
req.timeout.until += 1000 * 30;
|
||||
await req.timeout.save()
|
||||
|
||||
res.redirect('/threads/' + req.body.threadID);
|
||||
|
||||
}
|
||||
|
@ -31,24 +38,23 @@ app.post("/", (req, res) => {
|
|||
|
||||
});
|
||||
|
||||
|
||||
app.post("/:id/delete", (req, res) => {
|
||||
const message = new Message().getId(req.params.id)
|
||||
app.post("/:id/delete", async (req, res) => {
|
||||
const message = await new Message().getById(req.params.id)
|
||||
if (!message || message.deleted) return error(res, 404, "We have not got any message declared as this id.");
|
||||
const user = new User().getId(req.session.userid);
|
||||
if (user.id != message.author.id && !user.admin)
|
||||
const user = req.user;
|
||||
if (user.id != message.authorID && !user.admin)
|
||||
return error(res, 403, "You have not got permission for this.");
|
||||
message.deleted = true;
|
||||
message.write();
|
||||
|
||||
|
||||
res.status(200).redirect("/threads/" + message.thread.id);
|
||||
res.status(200).redirect("/threads/" + message.threadID);
|
||||
|
||||
})
|
||||
app.post("/:id/react", (req, res) => {
|
||||
app.post("/:id/react", async (req, res) => {
|
||||
const { id = null } = req.params;
|
||||
const info = req.body;
|
||||
const message = new Message().getId(id);
|
||||
const message = await new Message().getById(id);
|
||||
if (message) {
|
||||
if (!(req.session.userid in message.react))
|
||||
message.react[req.session.userid] = "like" in info;
|
||||
|
@ -56,10 +62,13 @@ app.post("/:id/react", (req, res) => {
|
|||
delete message.react[req.session.userid];
|
||||
|
||||
message.write();
|
||||
res.redirect("/threads/" + message.thread.id);
|
||||
res.redirect("/threads/" + message.threadID);
|
||||
} else error(res, 404, "We have not got this Message for reacting.");
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = app;
|
|
@ -1,5 +1,5 @@
|
|||
const { User } = require("../classes");
|
||||
const db = require("quick.db")
|
||||
const { SecretModel } = require("../models");
|
||||
|
||||
const { Router } = require("express")
|
||||
const error = require("../errors/error")
|
||||
|
@ -8,26 +8,29 @@ const app = Router();
|
|||
|
||||
app.get("/", (req, res) => res.render("register"));
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
req.session.loggedin = false;
|
||||
req.session.username = null;
|
||||
app.post("/", async (req, res) => {
|
||||
req.session.userid = null;
|
||||
const { username = null, password = null } = req.body;
|
||||
|
||||
|
||||
let { username = null, password = null, avatar } = req.body;
|
||||
|
||||
if (username && password) {
|
||||
const user = db.get("secret." + username)
|
||||
const user = await SecretModel.findOne({ username });
|
||||
|
||||
if (user)
|
||||
error(res, 404, `We have got an user named ${username}!`)
|
||||
|
||||
else {
|
||||
const user2 = new User(req.body.username, req.body.avatar ?? null).takeId()
|
||||
db.set("secret." + username, { id: user2.id, key: password })
|
||||
req.session.loggedin = true;
|
||||
req.session.username = username;
|
||||
|
||||
if (!avatar) avatar ="/images/guest.png";
|
||||
|
||||
const user2 = await new User(req.body.username, avatar).takeId();
|
||||
|
||||
await SecretModel.create({ username, password, id: user2.id })
|
||||
req.session.userid = user2.id;
|
||||
user2.write()
|
||||
|
||||
user2.write();
|
||||
|
||||
res.redirect('/');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,43 @@
|
|||
const { Thread, Message, User } = require("../classes");
|
||||
const error = require("../errors/error")
|
||||
const db = require("quick.db")
|
||||
|
||||
const { Router } = require("express");
|
||||
|
||||
const app = Router();
|
||||
|
||||
const { Thread, Message, User } = require("../classes");
|
||||
const error = require("../errors/error")
|
||||
const { ThreadModel } = require("../models")
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
|
||||
const user = new User().getId(req.session.userid);
|
||||
app.get("/", async (req, res) => {
|
||||
|
||||
const threads = db.get("threads").slice(0, 10)
|
||||
const links = threads.map(thread => "/threads/" + threads.indexOf(thread))
|
||||
const user = req.user;
|
||||
|
||||
return res.render("threads", { threads, links, user })
|
||||
const threads = await Promise.all((await ThreadModel.find({}).limit(10))
|
||||
.map(async threads => await new Thread().getById(threads.id)));
|
||||
|
||||
return res.render("threads", { threads, user });
|
||||
});
|
||||
|
||||
|
||||
app.get("/open*", (req, res) => {
|
||||
app.get("/open*", async (req, res) => {
|
||||
|
||||
const user = new User().getId(req.session.userid)
|
||||
const user = req.user
|
||||
res.render("openThread", { user })
|
||||
|
||||
});
|
||||
|
||||
app.get("/:id", (req, res) => {
|
||||
app.get("/:id", async (req, res) => {
|
||||
|
||||
const { id } = req.params;
|
||||
|
||||
const thread = new Thread().getId(id);
|
||||
const thread = await new Thread().getById(id);
|
||||
|
||||
if (thread) {
|
||||
const user = new User().getId(req.session.userid);
|
||||
const messages = thread.messages.filter(id => !new Message().getId(id).deleted).map(id => new Message().getId(id));
|
||||
const user = req.user;
|
||||
|
||||
const messages = await Promise.all(thread.messages.map(async id => {
|
||||
const message = await new Message().getById(id)
|
||||
return (message.deleted || !message) ? null : message;
|
||||
}));
|
||||
|
||||
res.render("thread", { thread, messages, user })
|
||||
} else
|
||||
error(res, 404, "We have not got this thread.");
|
||||
|
@ -46,22 +49,22 @@ app.get("/:id", (req, res) => {
|
|||
app.use(require("../middlewares/login"));
|
||||
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
|
||||
const user = new User().getId(req.session.userid);
|
||||
app.post("/", async (req, res) => {
|
||||
if (req.ratelimit)
|
||||
return error(res, 429, "Wait until " + new Date(req.timeout.until).toLocaleTimeString("tr") + ", you are too quick for send.")
|
||||
|
||||
const { title = null, content = null } = req.body;
|
||||
|
||||
if (!title || !content) return error(res, 400, "Title and content is missing");
|
||||
if (!title || !content) return error(res, 400, "Title and/or content is missing");
|
||||
const user = req.user
|
||||
const thread = await new Thread(title, user).takeId()
|
||||
const message = await new Message(content, user, thread.id).takeId()
|
||||
|
||||
const thread = new Thread(title, user).takeId().write();
|
||||
thread.push(message.id).write();
|
||||
|
||||
thread
|
||||
.push(new Message(content, user, thread).takeId().write().id)
|
||||
.write();
|
||||
message.write();
|
||||
|
||||
res.redirect('/threads/' + thread.id);
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
const { User } = require("../classes");
|
||||
const db = require("quick.db")
|
||||
|
||||
const { Router } = require("express")
|
||||
const error = require("../errors/error")
|
||||
|
||||
const { Router } = require("express");
|
||||
const app = Router();
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
const user = new User().getId(req.session.userid)
|
||||
const users = db.get("users").slice(0);
|
||||
const error = require("../errors/error");
|
||||
|
||||
const { User } = require("../classes");
|
||||
const { UserModel, MessageModel, ThreadModel } = require("../models");
|
||||
|
||||
app.get("/", async (req, res) => {
|
||||
const user = req.user
|
||||
const users = await UserModel.find({});
|
||||
|
||||
const links = users.filter(user => !user.deleted).map(user => "/users/" + user.id);
|
||||
return res.render("users", { users, links, user })
|
||||
|
||||
});
|
||||
|
||||
app.get("/:id", (req, res) => {
|
||||
const user = new User().getId(req.session.userid)
|
||||
app.get("/:id", async (req, res) => {
|
||||
const user = req.user
|
||||
const { id = null } = req.params;
|
||||
const member = new User().getId(req.params.id);
|
||||
const member = await new User().getById(req.params.id);
|
||||
|
||||
|
||||
if (member && (user?.admin || !member.deleted)) {
|
||||
const message = db.get("messages").filter(message => message.author.id === Number(id)).length
|
||||
const thread = db.get("threads").filter(thread => thread.author.id === Number(id)).length
|
||||
|
||||
const message = await MessageModel.count({ authorID: id });
|
||||
const thread = await ThreadModel.count({ authorID: id });
|
||||
const counts = { message, thread }
|
||||
res.render("user", { user, member, counts })
|
||||
}
|
||||
|
@ -35,13 +35,14 @@ app.get("/:id", (req, res) => {
|
|||
app.use(require("../middlewares/login"));
|
||||
|
||||
|
||||
app.post("/:id/delete/", (req, res) => {
|
||||
const user = new User().getId(req.session.userid);
|
||||
app.post("/:id/delete/", async (req, res) => {
|
||||
const user = req.user;
|
||||
if (!user?.admin)
|
||||
return error(res, 403, "You have not got permission for this.");
|
||||
|
||||
const id = req.url.slice(9 + 3)
|
||||
const member = new User().getId(id);
|
||||
const { id = null } = req.params;
|
||||
const member = await new User().getById(id);
|
||||
|
||||
if (!member || member.deleted) return error(res, 404, "We have not got any user declared as this id.");
|
||||
|
||||
member.deleted = true;
|
||||
|
|
|
@ -12,39 +12,24 @@ r = requests.get("http://localhost:3000/api/messages/1/", headers=headers)
|
|||
print(r.json())
|
||||
|
||||
example_response = {
|
||||
"status": 200,
|
||||
"result":
|
||||
{ # content of message
|
||||
"content": "a",
|
||||
# author of message
|
||||
"author": {
|
||||
"name": "ForumcuCocuk",
|
||||
"avatar": "/images/guest.png",
|
||||
"time": 1647177723873,
|
||||
"admin": True,
|
||||
"id": 1
|
||||
'status': 200,
|
||||
'result': {
|
||||
'authorID': 0,
|
||||
'content': 'a',
|
||||
'author': {
|
||||
'name': 'Akif9748',
|
||||
'avatar': 'https://www.technopat.net/sosyal/data/avatars/o/298/298223.jpg?1644694020',
|
||||
'time': 1649189944864,
|
||||
'admin': False,
|
||||
'deleted': False,
|
||||
'id': 0
|
||||
},
|
||||
# UNIX Timestamp of message
|
||||
"time": 1647178873587,
|
||||
# thread information of message
|
||||
"thread": {
|
||||
"author": {
|
||||
"name": "ForumcuCocuk",
|
||||
"avatar": "/images/guest.png",
|
||||
"time": 1647177723873,
|
||||
"admin": True,
|
||||
"id": 1
|
||||
},
|
||||
"title": "My",
|
||||
"messages": [0], # ids of messages
|
||||
"time": 1647178870047,
|
||||
"deleted": False,
|
||||
"id": 0
|
||||
},
|
||||
# Other informations about message
|
||||
"deleted": False,
|
||||
"edited": False,
|
||||
"react": {},
|
||||
"id": 1
|
||||
'time': 1649189950166,
|
||||
'threadID': 0,
|
||||
'deleted': False,
|
||||
'edited': False,
|
||||
# Reactions: {userid: isLike (Bool)}
|
||||
'react': {'0': True},
|
||||
'id': 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ headers = {
|
|||
}
|
||||
|
||||
|
||||
r = requests.get("http://localhost:3000/api/threads/0", headers=headers)
|
||||
r = requests.get("http://localhost:3000/api/threads/0/", headers=headers)
|
||||
|
||||
print(r.json())
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ headers = {
|
|||
# Body for message parameters
|
||||
body = {
|
||||
"content": "This message sent via API",
|
||||
"threadID": 1
|
||||
"threadID": 0
|
||||
}
|
||||
|
||||
r = requests.post("http://localhost:3000/api/messages/",
|
||||
|
|
50
tests/post_thread.py
Normal file
50
tests/post_thread.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
import requests
|
||||
|
||||
# Headers for login to Akf-forum
|
||||
headers = {
|
||||
"username": "testUser",
|
||||
"password": "testPassword"
|
||||
}
|
||||
|
||||
# Body for message parameters
|
||||
body = {
|
||||
"content": "This message sent via API",
|
||||
"title": "This thread opened by API"
|
||||
}
|
||||
|
||||
r = requests.post("http://localhost:3000/api/threads/",
|
||||
headers=headers, data=body)
|
||||
|
||||
print(r.json())
|
||||
|
||||
example_response = {
|
||||
'status': 200,
|
||||
'result': {
|
||||
'content': 'This message sent via API',
|
||||
'author': {
|
||||
'name': 'testUser',
|
||||
'avatar': '',
|
||||
'time': 1649009854217,
|
||||
'admin': False,
|
||||
'deleted': False,
|
||||
'id': 2
|
||||
},
|
||||
'time': 1649010863471,
|
||||
'thread': {
|
||||
'author': {
|
||||
'name': 'Akif9748',
|
||||
'avatar': 'https://www.technopat.net/sosyal/data/avatars/o/298/298223.jpg?1644694020',
|
||||
'time': 1647895891332, 'admin': True, 'deleted': False, 'id': 0
|
||||
},
|
||||
'title': 'API TEST',
|
||||
'messages': [4, 6],
|
||||
'time': 1649010834064,
|
||||
'deleted': False,
|
||||
'id': 1
|
||||
},
|
||||
'deleted': False,
|
||||
'edited': False,
|
||||
'react': {},
|
||||
'id': 6
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
</h2>
|
||||
<hr>
|
||||
<% messages.forEach(message=>{ %>
|
||||
<% if (message){ %>
|
||||
|
||||
<div id="message-<%= message.id %>" style="border: 2px solid #444444; padding: 10px;">
|
||||
|
||||
|
@ -57,7 +58,13 @@
|
|||
|
||||
</div>
|
||||
|
||||
<% } else { %>
|
||||
<div id="deleted-message" style="border: 2px solid #444444; padding: 10px;">
|
||||
<h1>DELETED MESSAGE</h1>
|
||||
</div>
|
||||
<% } %>
|
||||
<br>
|
||||
|
||||
<% }); %>
|
||||
|
||||
<hr>
|
||||
|
|
|
@ -12,9 +12,8 @@
|
|||
<ul>
|
||||
<% threads.forEach(thread=>{ %>
|
||||
<li>
|
||||
<h1><a href=<%=links[threads.indexOf(thread)] %> > <%= thread.title %> by <%= thread.author.name
|
||||
%></a>
|
||||
</h1>
|
||||
<h1 style="display: inline;"> <a href=<%= thread.getLink() %> ><%= thread.title %></a></h1>
|
||||
<h3 style="display: inline;"> | By <%= thread.author.name %></h3>
|
||||
</li>
|
||||
<% }); %>
|
||||
</ul>
|
||||
|
|
Loading…
Reference in a new issue