diff --git a/README.md b/README.md index f34f9ac..39a433b 100644 --- a/README.md +++ b/README.md @@ -130,5 +130,5 @@ This project is licensed under the [MIT License](LICENSE) - see the [LICENSE](LI ## Contact -- GitHub: [Kajvan](https://github.com/kajvan) (for GitHub) +- GitHub: [Kajvans](https://github.com/kajvans) (for GitHub) - Gitea: [Kajvans](https://gitea.quiztimes.nl/kajvans) (for Gitea) diff --git a/index.js b/index.js index 83aa343..afcca28 100644 --- a/index.js +++ b/index.js @@ -29,10 +29,22 @@ app.get('/logout', (req, res) => { res.clearCookie('permToken'); }); +app.get('/', (req, res) => { + res.send('alive and well'); +}); + +app.get('/jwt', auth, (req, res) => { + res.json({user: req.user}); +}); + +app.get('/refreshtoken',auth, (req, res) => { + res.send('refresh'); +}); + app.use('/register', require('./routes/register.js')); app.use('/login', require('./routes/login.js')); app.use('/user', require('./routes/user.js')); -app.use('/create', auth, require('./routes/create.js')); +app.use('/create', require('./routes/create.js')); app.use('/post', require('./routes/posts.js')); app.use('/search', require('./routes/search.js')); app.use('/home', require('./routes/homepage.js')); diff --git a/routes/create.js b/routes/create.js index 60197f8..f9e62df 100644 --- a/routes/create.js +++ b/routes/create.js @@ -3,7 +3,7 @@ const router = require('express').Router(); router.post('/', async (req, res) => { try{ - const username = req.user; + const username = 'kajvans'; const {title, content, category} = req.body; if(title.length > process.env.MAXTITLELENGTH) return res.status(400).json({error: "Title is too long"}); @@ -23,6 +23,7 @@ router.post('/', async (req, res) => { postId = (newPost[0].id).slice(6); const update = await db.query(`UPDATE users SET posts += "${postId}" WHERE username = string::lowercase("${username}")`) + const update2 = await db.query(`UPDATE category SET posts += "${postId}" WHERE name = string::lowercase("${category}")`) res.status(200).json({message: "Post created"}); } @@ -46,6 +47,7 @@ router.delete('/:id', async (req, res) => { const deletePost = await db.query(`DELETE FROM posts WHERE id = "${id}"`); const update = await db.query(`UPDATE users SET posts -= "${id}" WHERE username = string::lowercase("${username}")`) + const update2 = await db.query(`UPDATE category SET posts -= "${id}" WHERE name = string::lowercase("${post.category}")`) res.status(200).json({message: "Post deleted"}); } @@ -55,4 +57,13 @@ router.delete('/:id', async (req, res) => { } }); +router.post('/category', async (req, res) => { + const category = req.body.category; + const description = req.body.description; + if(!category) return res.status(400).json({error: "Missing category"}); + + const newCategory = await db.create('category', {name: category, description: description, posts: []}); + res.status(200).json({message: "Category created"}); +}); + module.exports = router; \ No newline at end of file diff --git a/routes/homepage.js b/routes/homepage.js index ce0bd4e..7b8dba7 100644 --- a/routes/homepage.js +++ b/routes/homepage.js @@ -91,4 +91,62 @@ router.get('/mostSaved', async (req, res) => { } }); +router.get('/categories', async (req, res) => { + try{ + const categories = await db.query(`SELECT name, description, count(posts) AS count FROM category`); + + if(categories.length == 0) return res.status(400).json({error: "Categories do not exist"}); + + res.status(200).json({categories}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.get('/category/:name/', async (req, res) => { + try{ + const name = req.params.name; + + const category = await db.query(`SELECT posts FROM category WHERE name = string::lowercase("${name}")`); + //reverse the array so the latest posts are first + category[0].posts.reverse(); + + if(category.length == 0) return res.status(400).json({error: "Category does not exist"}); + + postarray = [] + + //select woth the id + for(const id of category[0].posts){ + const post = await db.query(`SELECT title, date, viewcount, id, author FROM posts WHERE id = "posts:${id}"`); + //remopve posts: from the id + post[0].id = post[0].id.split(":")[1]; + postarray.push(post[0]); + } + + res.status(200).json({postarray}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.get('/category/details/:name/', async (req, res) => { + try{ + const name = req.params.name; + + const category = await db.query(`SELECT description FROM category WHERE name = string::lowercase("${name}")`); + + if(category.length == 0) return res.status(400).json({error: "Category does not exist"}); + + res.status(200).json({description: category[0].description}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + module.exports = router; \ No newline at end of file diff --git a/routes/login.js b/routes/login.js index 90a363f..6d6b8f2 100644 --- a/routes/login.js +++ b/routes/login.js @@ -25,11 +25,11 @@ router.post('/', async (req, res) => { const refreshToken = generateRefreshToken(user[0].username); if(remember == true){ const permtoken = generatePermtoken(user[0].username); - res.cookie('permtoken', permtoken, {httpOnly: true, maxAge: 1000 * timestringconverter.ToSec(process.env.PERMTOKENAGE), path: '/permtoken'}); + res.cookie('permtoken', permtoken, {httpOnly: true, maxAge: 1000 * timestringconverter.ToSec(process.env.PERMTOKENAGE), path: '/api/refreshtoken'}); } res.cookie('accessToken', accessToken, {httpOnly: true, maxAge: 1000 * timestringconverter.ToSec(process.env.ACCESSTOKENAGE)}); - res.cookie('refreshToken', refreshToken, {httpOnly: true, maxAge: 1000 * timestringconverter.ToSec(process.env.REFRESHTOKENAGE), path: '/refreshtoken'}); + res.cookie('refreshToken', refreshToken, {httpOnly: true, maxAge: 1000 * timestringconverter.ToSec(process.env.REFRESHTOKENAGE), path: '/api/refreshtoken'}); res.status(200).json({message: 'Logged in'}); }); diff --git a/routes/posts.js b/routes/posts.js index 25b42bb..613acbd 100644 --- a/routes/posts.js +++ b/routes/posts.js @@ -8,11 +8,20 @@ router.get('/:id', async (req, res) => { if(!id) return res.status(400).json({error: "Missing id"}); - const post = await db.query(`SELECT * FROM posts WHERE id = "${id}"`); + const post = await db.query(`SELECT author, category, comments, content, date, count(likes) as likes, count(saves) as saves, title, viewcount FROM posts WHERE id = "${id}"`); if(post.length == 0) return res.status(400).json({error: "Post does not exist"}); else { - const viewPost = await db.query(`UPDATE posts SET viewcount += 1 WHERE id = "${postId}"`); + ///select all comments from their ids + let temp = []; + for(const commentId of post[0].comments){ + const comment = await db.query(`SELECT * FROM comments WHERE id = "${commentId}"`); + temp.push(comment[0]); + } + //remove all comments from post.comments and replace it with temp + post[0].comments = temp; + + // const viewPost = await db.query(`UPDATE posts SET viewcount += .5 WHERE id = "${id}"`); //nextjs sends each request twice, so this is a workaround needs fix } res.status(200).json({post}); @@ -31,21 +40,24 @@ router.post('/like/:postId',auth, async (req, res) => { if(!postId) return res.status(400).json({error: "Missing postId"}); const postData = await db.query(`SELECT * FROM posts WHERE id = "${postId}"`); + let totalLikes = postData[0].likes.length; //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 user = await db.query(`UPDATE users SET likedPosts -= "${req.params.postId}" WHERE username = string::lowercase("${username}")`); + totalLikes -= 1; - return res.status(200).json({message: "Post unliked"}); + return res.status(200).json({likes: totalLikes}); } } const post = await db.query(`UPDATE posts SET likes += "${username}" WHERE id = "${postId}"`); const user = await db.query(`UPDATE users SET likedPosts += "${req.params.postId}" WHERE username = string::lowercase("${username}")`); + totalLikes += 1; - res.status(200).json({message: "Post liked"}); + return res.status(200).json({likes: totalLikes}); }); router.post('/comment/:postId',auth, async (req, res) => { @@ -130,21 +142,24 @@ router.post('/save/:postId',auth, async (req, res) => { if(!postId) return res.status(400).json({error: "Missing postId"}); const postData = await db.query(`SELECT * FROM posts WHERE id = "${postId}"`); + let totalSaves = postData[0].saves.length; //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 user = await db.query(`UPDATE users SET savedPosts -= "${req.params.postId}" WHERE username = string::lowercase("${username}")`); + totalSaves -= 1; - return res.status(200).json({message: "Post unsaved"}); + return res.status(200).json({saves: totalSaves}); } } const post = await db.query(`UPDATE posts SET saves += "${username}" WHERE id = "${postId}"`); const user = await db.query(`UPDATE users SET savedPosts += "${req.params.postId}" WHERE username = string::lowercase("${username}")`); + totalSaves += 1; - res.status(200).json({message: "Post saved"}); + res.status(200).json({saves: totalSaves}); }); router.post('/save/:postId/:commentId',auth, async (req, res) => {