some tweaks and readme

This commit is contained in:
2024-01-25 16:47:06 +01:00
parent 3ad55cd36a
commit 1273706b8c
9 changed files with 472 additions and 69 deletions
+32
View File
@@ -0,0 +1,32 @@
JWT_SECRET = "Secret"
PORT = 3000
USERNAMELENGTH = 20
# Time format: 1d2h3m4s
PERMTOKENAGE = 30d5h # 30 days 5 hours
ACCESSTOKENAGE = 1h # 1 hour
REFRESHTOKENAGE = 5d2m # 5 days 2 minutes
MINPASSWORDLENGTH = 8
MAXPASSWORDLENGTH = 64
PASSMINLOWERCASE = 0
PASSMINUPPERCASE = 0
PASSMINNUMBERS = 0
PASSMINSYMBOLS = 0
#allowed symbols so use in password
PASSSYMBOLS = "!@$%^&*()_+~|}{[]:;?><,./-="
MINTITLELENGTH = 5
MAXTITLELENGTH = 50
MAXCONTENTLENGTH = 5000
MINCONTENTLENGTH = 20
SaltRounds = 12
DBURL = ws://localhost:8000/rpc
DBUSER = root
DBPASS = root
DBNS = test
DBDB = test
+59 -9
View File
@@ -7,31 +7,81 @@ Short description or introduction of your project.
- [About](#about)
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [Contributing](#contributing)
- [License](#license)
- [Creators](#creators)
- [Contact](#contact)
## About
Detailed information about the project, its purpose, goals, and any relevant background.
This is the backend for a forum you can self host. It is written in NodeJS and uses the Surrealdb database. It is a REST API that uses JSON for communication. It is uses the Express framework. Further it uses the following packages:
- auth-guardian: "^1.1.1",
- cookie-parser: "^1.4.6",
- cors": "2.8.5",
- dotenv: "^16.3.1",
- express: "^4.18.2",
- jsonwebtoken: "^9.0.2",
- surrealdb.node: "^0.3.0"
The frontend will be written in NextJS and will be a seperate repository.
This project is under development and is not ready for production.
## Features
Highlight key features or functionalities of the project.
- [x] User authentication
- [x] User registration
- [x] User login
- [x] User logout
- [x] User profile
- [x] User profile update
- [x] User profile delete
- [x] Create post
- [x] Like post
- [x] Comment on post
- [x] Save post
- [x] Comment on comment
- [x] Like comment
- [x] Save comment
- [x] Search posts
- [x] Search users
- [x] Trending posts
- [x] Most active users
- [x] Most liked posts
- [x] Most commented posts
- [x] Most saved posts
## Installation
Step-by-step instructions on how to install or set up the project. Include any prerequisites or dependencies.
### Prerequisites
NodeJS and NPM are required to run this project. You can download them [here](https://nodejs.org/en/download/).
## Usage
### Clone
Examples, code snippets, or instructions on how to use the project. Showcasing different use cases can be beneficial.
Clone this repository to your local machine using
## Contributing
```shell
git clone https://gitea.quiztimes.nl/kajvans/forum-backend.git
```
Guidelines for contributing to the project. Include information on how to report issues, suggest improvements, or submit pull requests.
### Setup
Edit .env.example and rename it to .env. Fill in the required information.
### Install dependencies
Install the required dependencies using
```shell
npm install
```
### Running
Run the project using
```shell
npm start
```
## License
+8 -1
View File
@@ -3,7 +3,7 @@ const dotenv = require('dotenv');
const cors = require('cors');
const {auth} = require('./auth/middleware');
const cookieParser = require('cookie-parser');
const {updateAll} = require('./jobs/jobs');
const {updateAll} = require('./jobs');
dotenv.config();
@@ -22,6 +22,13 @@ setInterval(() => {
updateAll();
}, 43200000);
app.get('/logout', (req, res) => {
//clear all cookies
res.clearCookie('accessToken');
res.clearCookie('refreshToken');
res.clearCookie('permToken');
});
app.use('/register', require('./routes/register.js'));
app.use('/login', require('./routes/login.js'));
app.use('/user', require('./routes/user.js'));
+1 -1
View File
@@ -1,4 +1,4 @@
const db = require('../surreal');
const db = require('./surreal');
async function SetTrending(){
try{
+330 -46
View File
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -11,18 +11,17 @@
"license": "MIT",
"dependencies": {
"auth-guardian": "^1.1.1",
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"jest": "^29.7.0",
"jsonwebtoken": "^9.0.2",
"supertest": "^6.3.4",
"surrealdb.node": "^0.3.0",
"timestringconverter": "^1.0.0"
},
"devDependencies": {
"nodemon": "^3.0.2"
"jest": "^29.7.0",
"nodemon": "^3.0.2",
"supertest": "^6.3.4"
}
}
+4 -4
View File
@@ -109,14 +109,14 @@ router.post('/like/:postId/:commentId',auth, async (req, res) => {
//check if user already liked post
for(let i = 0; i < postData[0].likes.length; i++){
if(postData[0].likes[i] === username){
const post = await db.query(`UPDATE posts SET likes -= "${username}" WHERE id = "${postId}"`);
const post = await db.query(`UPDATE comments SET likes -= "${username}" WHERE id = "${postId}"`);
const user = await db.query(`UPDATE users SET likedPosts -= "${req.params.postId}" WHERE username = string::lowercase("${username}")`);
return res.status(200).json({message: "Post unliked"});
}
}
const post = await db.query(`UPDATE posts SET likes += "${username}" WHERE id = "${postId}"`);
const post = await db.query(`UPDATE comments SET likes += "${username}" WHERE id = "${postId}"`);
const user = await db.query(`UPDATE users SET likedPosts += "${req.params.postId}" WHERE username = string::lowercase("${username}")`);
res.status(200).json({message: "Post liked"});
@@ -161,14 +161,14 @@ router.post('/save/:postId/:commentId',auth, async (req, res) => {
//check if user already saved post
for(let i = 0; i < postData[0].saves.length; i++){
if(postData[0].saves[i] === username){
const post = await db.query(`UPDATE posts SET saves -= "${username}" WHERE id = "${postId}"`);
const post = await db.query(`UPDATE comments SET saves -= "${username}" WHERE id = "${postId}"`);
const user = await db.query(`UPDATE users SET savedPosts -= "${req.params.postId}" WHERE username = string::lowercase("${username}")`);
return res.status(200).json({message: "Post unsaved"});
}
}
const post = await db.query(`UPDATE posts SET saves += "${username}" WHERE id = "${postId}"`);
const post = await db.query(`UPDATE comments SET saves += "${username}" WHERE id = "${postId}"`);
const user = await db.query(`UPDATE users SET savedPosts += "${req.params.postId}" WHERE username = string::lowercase("${username}")`);
res.status(200).json({message: "Post saved"});
+31
View File
@@ -253,4 +253,35 @@ router.get('/activity/:type', auth, async (req, res) => {
}
});
router.delete('/delete', auth, async (req, res) => {
try{
const username = req.user;
const {password} = req.body;
if(!username) return res.status(400).json({error: "Missing username"});
if(!password) return res.status(400).json({error: "Missing password"});
const user = await db.query(`SELECT * FROM users WHERE username = string::lowercase("${username}")`);
if(user.length == 0) return res.status(400).json({error: "User does not exist"});
const verify = await passwordauth.verify(password, user[0].password);
if(!verify) return res.status(400).json({error: "Password is incorrect"});
const deletePosts = await db.query(`DELETE FROM posts WHERE author = string::lowercase("${username}")`);
const deleteComments = await db.query(`DELETE FROM comments WHERE author = string::lowercase("${username}")`);
const deleteLikedPosts = await db.query(`DELETE FROM posts WHERE likes = "${username}"`);
const deleteLikedComments = await db.query(`DELETE FROM comments WHERE likes = "${username}"`);
const deleteSavedPosts = await db.query(`DELETE FROM posts WHERE savedPosts = "${username}"`);
const deleteSavedComments = await db.query(`DELETE FROM comments WHERE savedComments = "${username}"`);
const deleteUser = await db.query(`DELETE FROM users WHERE username = string::lowercase("${username}")`);
res.status(200).json({message: "User deleted"});
}
catch(err){
console.log(err);
res.status(500).json({error: "Internal server error"});
}
});
module.exports = router;
+4 -4
View File
@@ -6,16 +6,16 @@ async function main() {
try {
// Connect to the database
await db.connect('wss://db.services.quiztimes.nl/rpc');
await db.connect(process.env.DBURL);
// Signin as a namespace, database, or root user
await db.signin({
username: 'root',
password: 'root',
username: process.env.DBUSER,
password: process.env.DBPASS,
});
// Select a specific namespace / database
await db.use({ ns: 'forum', db: 'forum' });
await db.use({ ns: process.env.DBNS, db: process.env.DBDB });
} catch (e) {