some tweaks and readme
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
const db = require('../surreal');
|
||||
const db = require('./surreal');
|
||||
|
||||
async function SetTrending(){
|
||||
try{
|
||||
|
||||
Generated
+330
-46
File diff suppressed because it is too large
Load Diff
+3
-4
@@ -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
@@ -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"});
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user