From 421ab338fcc592e9169095dbe265571424cf42a3 Mon Sep 17 00:00:00 2001 From: kajvans Date: Wed, 24 Jan 2024 16:28:02 +0100 Subject: [PATCH] tuned some things and added some to user route --- auth/middleware.js | 104 +++++++++++++++++++---- auth/middleware.test.js | 100 +++++++++++++++++++--- index.js | 4 +- routes/create.js | 5 +- routes/login.js | 2 - routes/posts.js | 147 +++++++++++++++++++++++++++++++- routes/register.js | 3 - routes/user.js | 181 ++++++++++++++++++++++++++++++++++++++-- 8 files changed, 500 insertions(+), 46 deletions(-) diff --git a/auth/middleware.js b/auth/middleware.js index 80a0439..ebfb44b 100644 --- a/auth/middleware.js +++ b/auth/middleware.js @@ -1,50 +1,124 @@ -const {verifyToken, generateAccesToken, generateRefreshToken} = require("./auth"); +const { verifyToken, generateAccesToken, generateRefreshToken } = require("./auth"); const auth = (req, res, next) => { const refreshToken = req.cookies.refreshToken; const accessToken = req.cookies.accessToken; const permtoken = req.cookies.permtoken; - if(!refreshToken && !accessToken && !permtoken) return res.status(401).json({error: "Unauthorized"}); + if (!refreshToken && !accessToken && !permtoken) return res.status(401).json({ error: "Unauthorized" }); - if(accessToken){ + if (accessToken) { const result = verifyToken(accessToken); - if(result.user){ + if (result == false) { + //remove refresh token + res.cookie("accessToken", "", { httpOnly: true }); + } + if (result.user) { req.user = result.user; return next(); } } - else if(refreshToken && !accessToken){ + else if (refreshToken && !accessToken) { const result = verifyToken(refreshToken); - if(result != false){ + if (result != false) { //create new access token const newAccessToken = generateAccesToken(result.user); - res.cookie("accessToken", newAccessToken, {httpOnly: true}); + res.cookie("accessToken", newAccessToken, { httpOnly: true }); } - if(result.user){ + else { + //remove refresh token + res.cookie("refreshToken", "", { httpOnly: true }); + } + if (result.user) { req.user = result.user; return next(); } } - else if(permtoken){ + else if (permtoken) { const result = verifyToken(permtoken); - if(result != false){ + if (result != false) { //create new access token const newAccessToken = generateAccesToken(result.user); - res.cookie("accessToken", newAccessToken, {httpOnly: true}); + res.cookie("accessToken", newAccessToken, { httpOnly: true }); //create new refresh token const newRefreshToken = generateRefreshToken(result.user); - res.cookie("refreshToken", newRefreshToken, {httpOnly: true}); + res.cookie("refreshToken", newRefreshToken, { httpOnly: true }); } - if(result.user){ + else { + //remove permtoken + res.cookie("permtoken", "", { httpOnly: true }); + } + if (result.user) { req.user = result.user; return next(); } } - return res.status(401).json({error: "Unauthorized"}); + return res.status(401).json({ error: "Unauthorized" }); } -module.exports = auth; \ No newline at end of file +const publicauth = (req, res, next) => { + const refreshToken = req.cookies.refreshToken; + const accessToken = req.cookies.accessToken; + const permtoken = req.cookies.permtoken; + if (!refreshToken && !accessToken && !permtoken) { + req.user = null; + return next(); + } + + if (accessToken) { + const result = verifyToken(accessToken); + if (result == false) { + //remove refresh token + res.cookie("accessToken", "", { httpOnly: true }); + } + if (result.user) { + req.user = result.user; + return next(); + } + } + + else if (refreshToken && !accessToken) { + const result = verifyToken(refreshToken); + if (result != false) { + //create new access token + const newAccessToken = generateAccesToken(result.user); + res.cookie("accessToken", newAccessToken, { httpOnly: true }); + } + else { + //remove refresh token + res.cookie("refreshToken", "", { httpOnly: true }); + } + if (result.user) { + req.user = result.user; + return next(); + } + } + + else if (permtoken) { + const result = verifyToken(permtoken); + if (result != false) { + //create new access token + const newAccessToken = generateAccesToken(result.user); + res.cookie("accessToken", newAccessToken, { httpOnly: true }); + + //create new refresh token + const newRefreshToken = generateRefreshToken(result.user); + res.cookie("refreshToken", newRefreshToken, { httpOnly: true }); + } + else { + //remove permtoken + res.cookie("permtoken", "", { httpOnly: true }); + } + if (result.user) { + req.user = result.user; + return next(); + } + } + + req.user = null; +} + +module.exports = { auth, publicauth }; \ No newline at end of file diff --git a/auth/middleware.test.js b/auth/middleware.test.js index 47861b9..c558a07 100644 --- a/auth/middleware.test.js +++ b/auth/middleware.test.js @@ -1,6 +1,6 @@ const dotenv = require("dotenv"); const { generateAccesToken, generateRefreshToken, generatePermtoken, verifyToken} = require("./auth"); -const middleware = require("./middleware"); +const {auth, publicauth} = require("./middleware"); dotenv.config(); describe('Middleware.js Tests', () => { @@ -23,61 +23,61 @@ describe('Middleware.js Tests', () => { test('should call next() if access token is valid', () => { const token = generateAccesToken(user); req.cookies.accessToken = token; - middleware(req, res, next); + auth(req, res, next); expect(next).toHaveBeenCalled(); }); test('should call next() if refresh token is valid', () => { const token = generateRefreshToken(user); req.cookies.refreshToken = token; - middleware(req, res, next); + auth(req, res, next); expect(next).toHaveBeenCalled(); }); test('should call next() if permtoken is valid', () => { const token = generatePermtoken(user); req.cookies.permtoken = token; - middleware(req, res, next); + auth(req, res, next); expect(next).toHaveBeenCalled(); }); test('should return 401 if no tokens are present', () => { - middleware(req, res, next); + auth(req, res, next); expect(res.status).toHaveBeenCalledWith(401); }); test('should return 401 if access token is invalid', () => { const token = generateAccesToken(user); req.cookies.accessToken = token + 'a'; - middleware(req, res, next); + auth(req, res, next); expect(res.status).toHaveBeenCalledWith(401); }); test('should return 401 if refresh token is invalid', () => { const token = generateRefreshToken(user); req.cookies.refreshToken = token + 'a'; - middleware(req, res, next); + auth(req, res, next); expect(res.status).toHaveBeenCalledWith(401); }); test('should return 401 if permtoken is invalid', () => { const token = generatePermtoken(user); req.cookies.permtoken = token + 'a'; - middleware(req, res, next); + auth(req, res, next); expect(res.status).toHaveBeenCalledWith(401); }); test('should return access token if refresh token is valid', () => { const token = generateRefreshToken(user); req.cookies.refreshToken = token; - middleware(req, res, next); + auth(req, res, next); expect(res.cookie).toHaveBeenCalledWith('accessToken', expect.any(String), { httpOnly: true }); }); test('should return access token and refresh if permtoken is valid', () => { const token = generatePermtoken(user); req.cookies.permtoken = token; - middleware(req, res, next); + auth(req, res, next); expect(res.cookie).toHaveBeenCalledWith('accessToken', expect.any(String), { httpOnly: true }); expect(res.cookie).toHaveBeenCalledWith('refreshToken', expect.any(String), { httpOnly: true }); }); @@ -85,14 +85,90 @@ describe('Middleware.js Tests', () => { test('should not return refresh token if access token is valid', () => { const token = generateAccesToken(user); req.cookies.accessToken = token; - middleware(req, res, next); + auth(req, res, next); expect(res.cookie).not.toHaveBeenCalledWith('refreshToken', expect.any(String), { httpOnly: true }); }); test('should not return permtoken token if refresh is valid', () => { const token = generatePermtoken(user); req.cookies.permtoken = token; - middleware(req, res, next); + auth(req, res, next); expect(res.cookie).not.toHaveBeenCalledWith('permtoken', expect.any(String), { httpOnly: true }); }); + + test('should return req.user equals null if no tokens are present for publicauth', () => { + publicauth(req, res, next); + expect(req.user).toBe(null); + }); + + test('should return req.user equals null if access token is invalid for publicauth', () => { + const token = generateAccesToken(user); + req.cookies.accessToken = token + 'a'; + publicauth(req, res, next); + expect(req.user).toBe(null); + }); + + test('should return req.user equals null if refresh token is invalid for publicauth', () => { + const token = generateRefreshToken(user); + req.cookies.refreshToken = token + 'a'; + publicauth(req, res, next); + expect(req.user).toBe(null); + }); + + test('should return req.user equals null if permtoken is invalid for publicauth', () => { + const token = generatePermtoken(user); + req.cookies.permtoken = token + 'a'; + publicauth(req, res, next); + expect(req.user).toBe(null); + }); + + test('should return req.user equals user if access token is valid for publicauth', () => { + const token = generateAccesToken(user); + req.cookies.accessToken = token; + publicauth(req, res, next); + expect(req.user).toEqual(user); + }); + + test('should remove access token if access token is invalid', () => { + const token = generateAccesToken(user); + req.cookies.accessToken = token + 'a'; + auth(req, res, next); + expect(res.cookie).toHaveBeenCalledWith('accessToken', '', { httpOnly: true }); + }); + + test('should remove refresh token if refresh token is invalid', () => { + const token = generateRefreshToken(user); + req.cookies.refreshToken = token + 'a'; + auth(req, res, next); + expect(res.cookie).toHaveBeenCalledWith('refreshToken', '', { httpOnly: true }); + }); + + test('should remove permtoken if permtoken is invalid', () => { + const token = generatePermtoken(user); + req.cookies.permtoken = token + 'a'; + auth(req, res, next); + expect(res.cookie).toHaveBeenCalledWith('permtoken', '', { httpOnly: true }); + }); + + test('should remove access token if access token is invalid for publicauth', () => { + const token = generateAccesToken(user); + req.cookies.accessToken = token + 'a'; + publicauth(req, res, next); + expect(res.cookie).toHaveBeenCalledWith('accessToken', '', { httpOnly: true }); + }); + + test('should remove refresh token if refresh token is invalid for publicauth', () => { + const token = generateRefreshToken(user); + req.cookies.refreshToken = token + 'a'; + publicauth(req, res, next); + expect(res.cookie).toHaveBeenCalledWith('refreshToken', '', { httpOnly: true }); + }); + + test('should remove permtoken if permtoken is invalid for publicauth', () => { + const token = generatePermtoken(user); + req.cookies.permtoken = token + 'a'; + publicauth(req, res, next); + expect(res.cookie).toHaveBeenCalledWith('permtoken', '', { httpOnly: true }); + }); + }); \ No newline at end of file diff --git a/index.js b/index.js index e97259d..fae8ea5 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ const express = require('express'); const dotenv = require('dotenv'); const cors = require('cors'); -const auth = require('./auth/middleware'); +const {auth} = require('./auth/middleware'); const cookieParser = require('cookie-parser'); dotenv.config(); @@ -19,6 +19,6 @@ 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('/post',auth, require('./routes/posts.js')); +app.use('/post', require('./routes/posts.js')); module.exports = app; \ No newline at end of file diff --git a/routes/create.js b/routes/create.js index c19a77b..b585e35 100644 --- a/routes/create.js +++ b/routes/create.js @@ -4,7 +4,7 @@ const router = require('express').Router(); router.post('/', async (req, res) => { try{ const username = req.user; - const {title, content} = req.body; + const {title, content, category} = req.body; if(title.length > process.env.MAXTITLELENGTH) return res.status(400).json({error: "Title is too long"}); if(content.length > process.env.MAXCONTENTLENGTH) return res.status(400).json({error: "Content is too long"}); @@ -12,13 +12,14 @@ router.post('/', async (req, res) => { if(title.length < process.env.MINTITLELENGTH) return res.status(400).json({error: "Title is too short"}); if(content.length < process.env.MINCONTENTLENGTH) return res.status(400).json({error: "Content is too short"}); if(!username) return res.status(400).json({error: "Missing username"}); + if(!category) return res.status(400).json({error: "Missing category"}); const currentDate = new Date(); const formattedDateAndTime = currentDate.toLocaleTimeString('en-gb', { timeStyle: 'short' }); const formattedDate = currentDate.toLocaleDateString('en-gb'); const date = formattedDateAndTime + " " + formattedDate; - const newPost = await db.create('posts', {title: title, content: content, author: username, date: date}); + const newPost = await db.create('posts', {category: category, title: title, content: content, author: username, date: date}); postId = (newPost[0].id).slice(6); const update = await db.query(`UPDATE users SET posts += "${postId}" WHERE username = string::lowercase("${username}")`) diff --git a/routes/login.js b/routes/login.js index dd16031..90a363f 100644 --- a/routes/login.js +++ b/routes/login.js @@ -8,8 +8,6 @@ const timestringconverter = require('timestringconverter'); router.post('/', async (req, res) => { const {username, password, remember} = req.body; - console.log(username) - if(!username) return res.status(400).json({error: "Username not provided"}); if(!password) return res.status(400).json({error: "Password not provided"}); diff --git a/routes/posts.js b/routes/posts.js index f039d8c..b25e3ab 100644 --- a/routes/posts.js +++ b/routes/posts.js @@ -1,7 +1,26 @@ const db = require('../surreal'); const router = require('express').Router(); +const {auth} = require('../auth/middleware'); -router.post('/like/:postId', async (req, res) => { +router.get('/:id', async (req, res) => { + try{ + const id = 'posts:' + req.params.id; + + if(!id) return res.status(400).json({error: "Missing id"}); + + const post = await db.query(`SELECT * FROM posts WHERE id = "${id}"`); + + if(post.length == 0) return res.status(400).json({error: "Post does not exist"}); + + res.status(200).json({post}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.post('/like/:postId',auth, async (req, res) => { const username = req.user; const postId = 'posts:' + req.params.postId; @@ -26,4 +45,130 @@ router.post('/like/:postId', async (req, res) => { res.status(200).json({message: "Post liked"}); }); +router.post('/comment/:postId',auth, async (req, res) => { + const username = req.user; + const postId = 'posts:' + req.params.postId; + const comment = req.body.comment; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!postId) return res.status(400).json({error: "Missing postId"}); + if(!comment) return res.status(400).json({error: "Missing comment"}); + + const Comment = { + author: username, + comment: comment + } + + const commentDB = await db.create('comments', Comment); + + const post = await db.query(`UPDATE posts SET comments += "${commentDB[0].id}" WHERE id = "${postId}"`); + const user = await db.query(`UPDATE users SET comments += "${commentDB[0].id}" WHERE username = string::lowercase("${username}")`); + + res.status(200).json({message: "Comment added"}); +}); + +router.post('/comment/:postId/:commentId',auth, async (req, res) => { + const username = req.user; + const postId = 'posts:' + req.params.postId; + const commentId = 'comments:' + req.params.commentId; + const comment = req.body.comment; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!postId) return res.status(400).json({error: "Missing postId"}); + if(!commentId) return res.status(400).json({error: "Missing commentId"}); + if(!comment) return res.status(400).json({error: "Missing comment"}); + + const Comment = { + author: username, + comment: comment, + parent: commentId + } + + const commentDB = await db.create('comments', Comment); + + const post = await db.query(`UPDATE posts SET comments += "${commentDB[0].id}" WHERE id = "${postId}"`); + const user = await db.query(`UPDATE users SET comments += "${commentDB[0].id}" WHERE username = string::lowercase("${username}")`); + + res.status(200).json({message: "Comment added"}); +}); + +router.post('/like/:postId/:commentId',auth, async (req, res) => { + const username = req.user; + const postId = 'posts:' + req.params.postId; + const commentId = 'comments:' + req.params.commentId; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!postId) return res.status(400).json({error: "Missing postId"}); + if(!commentId) return res.status(400).json({error: "Missing commentId"}); + + const postData = await db.query(`SELECT * FROM posts WHERE id = "${postId}"`); + + //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}")`); + + return res.status(200).json({message: "Post unliked"}); + } + } + + 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}")`); + + res.status(200).json({message: "Post liked"}); +}); + +router.post('/save/:postId',auth, async (req, res) => { + const username = req.user; + const postId = 'posts:' + req.params.postId; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!postId) return res.status(400).json({error: "Missing postId"}); + + const postData = await db.query(`SELECT * FROM posts WHERE id = "${postId}"`); + + //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}")`); + + return res.status(200).json({message: "Post unsaved"}); + } + } + + 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}")`); + + res.status(200).json({message: "Post saved"}); +}); + +router.post('/save/:postId/:commentId',auth, async (req, res) => { + const username = req.user; + const postId = 'posts:' + req.params.postId; + const commentId = 'comments:' + req.params.commentId; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!postId) return res.status(400).json({error: "Missing postId"}); + if(!commentId) return res.status(400).json({error: "Missing commentId"}); + + const postData = await db.query(`SELECT * FROM posts WHERE id = "${postId}"`); + + //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}")`); + + return res.status(200).json({message: "Post unsaved"}); + } + } + + 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}")`); + + res.status(200).json({message: "Post saved"}); +}); + module.exports = router; \ No newline at end of file diff --git a/routes/register.js b/routes/register.js index 5817ceb..6f40339 100644 --- a/routes/register.js +++ b/routes/register.js @@ -44,10 +44,7 @@ router.post('/', async (req, res) => { creation: currentDate.toLocaleDateString('en-gb'), } - console.log(user) - const newUser = await db.create('users', user); - console.log(newUser); const accessToken = generateAccesToken(newUser[0].username); const refreshToken = generateRefreshToken(newUser[0].username); diff --git a/routes/user.js b/routes/user.js index 132bf58..50e81da 100644 --- a/routes/user.js +++ b/routes/user.js @@ -1,25 +1,58 @@ const db = require('../surreal'); const router = require('express').Router(); -const middleware = require('../auth/middleware'); +const {auth, publicauth} = require('../auth/middleware'); +const passwordauth = require('../auth/password'); -router.get('/:username', async (req, res) => { +router.get('/:username',publicauth, async (req, res) => { try{ const username = req.params.username; if(!username) return res.status(400).json({error: "Missing username"}); - const user = await db.query(`SELECT description, creation FROM users WHERE username = string::lowercase("${username}")`); + const user = await db.query(`SELECT description, creation, visibility, likedPosts, comments, savedPosts FROM users WHERE username = string::lowercase("${username}")`); + if(user.length == 0) return res.status(400).json({error: "User does not exist"}); const posts = await db.query(`SELECT * FROM posts WHERE author = string::lowercase("${username}")`); - const returnData = { - description: user[0].description, - creation: user[0].creation, - posts: posts + if(req.user == username){ + const returnData = { + description: user[0].description, + creation: user[0].creation, + posts: posts, + likedPosts: user[0].likedPosts, + comments: user[0].comments, + savedPosts: user[0].savedPosts, + visibility: user[0].visibility + } + + res.status(200).json({returnData}); } - res.status(200).json({returnData}); + else { + if(user[0].visibility.likes == false){ + for(let i = 0; i < posts.length; i++){ + posts[i].likes = "Hidden"; + } + } + + if(user[0].visibility.savedPosts == false){ + for(let i = 0; i < posts.length; i++){ + posts[i].savedPosts = "Hidden"; + } + } + + const returnData = { + description: user[0].description, + creation: user[0].creation, + posts: posts, + likedPosts: user[0].likedPosts, + comments: user[0].comments, + savedPosts: user[0].savedPosts + } + + res.status(200).json({returnData}); + } } catch(err){ console.log(err); @@ -27,7 +60,7 @@ router.get('/:username', async (req, res) => { } }); -router.put('/description', middleware, async (req, res) => { +router.put('/description', auth, async (req, res) => { try{ const username = req.user; const {description} = req.body; @@ -46,4 +79,134 @@ router.put('/description', middleware, async (req, res) => { } }); +router.put('/password', auth, async (req, res) => { + try{ + const username = req.user; + const {oldpassword, newpassword} = req.body; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!oldpassword) return res.status(400).json({error: "Missing old password"}); + if(!newpassword) return res.status(400).json({error: "Missing new 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(oldpassword, user[0].password); + if(!verify) return res.status(400).json({error: "Old password is incorrect"}); + + const hash = await passwordauth.hash(newpassword); + + const newUserPassword = await db.query(`UPDATE users SET password = "${hash}" WHERE username = string::lowercase("${username}")`); + + res.status(200).json({message: "Password updated"}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.put('/username', auth, async (req, res) => { + try{ + const username = req.user; + const {newusername} = req.body; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(!newusername) return res.status(400).json({error: "Missing new username"}); + + 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 check = await db.query(`SELECT * FROM users WHERE username = string::lowercase("${newusername}")`); + if(check.length > 0) return res.status(400).json({error: "Username already exists"}); + + const newUser = await db.query(`UPDATE users SET username = string::lowercase("${newusername}") WHERE username = string::lowercase("${username}")`); + const newPost = await db.query(`UPDATE posts SET author = string::lowercase("${newusername}") WHERE author = string::lowercase("${username}")`); + const newComment = await db.query(`UPDATE comments SET author = string::lowercase("${newusername}") WHERE author = string::lowercase("${username}")`); + + const likedPosts = user[0].likedPosts; + + for(let i = 0; i < likedPosts.length; i++){ + const post = await db.query(`SELECT * FROM posts WHERE id = posts:"${likedPosts[i]}"`); + const likes = post[0].likes; + + for(let j = 0; j < likes.length; j++){ + if(likes[j] == username){ + likes.splice(j, 1); + likes.push(newusername); + const updatePost = await db.query(`UPDATE posts SET likes = "${likes}" WHERE id = "${likedPosts[i]}"`); + } + } + } + + res.status(200).json({message: "Username updated"}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.put('/visibility', auth, async (req, res) => { + try{ + const username = req.user; + const {likes, savedPosts} = req.body; + + if(!username) return res.status(400).json({error: "Missing username"}); + if(likes == undefined) return res.status(400).json({error: "Missing likes"}); + if(savedPosts == undefined) return res.status(400).json({error: "Missing savedPosts"}); + if(typeof likes != "boolean") return res.status(400).json({error: "Invalid likes"}); + if(typeof savedPosts != "boolean") return res.status(400).json({error: "Invalid savedPosts"}); + + const visibility = { + likes: likes, + savedPosts: savedPosts + } + + const user = await db.query(`UPDATE users SET visibility = "${visibility}" WHERE username = string::lowercase("${username}")`); + + res.status(200).json({message: "Visibility updated"}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.get('/description/:username', publicauth, async (req, res) => { + try{ + const username = req.params.username; + + if(!username) return res.status(400).json({error: "Missing username"}); + + const user = await db.query(`SELECT description FROM users WHERE username = string::lowercase("${username}")`); + + if(user.length == 0) return res.status(400).json({error: "User does not exist"}); + + res.status(200).json({description: user[0].description}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + +router.get('/visibility', auth, async (req, res) => { + try{ + const username = req.user; + + if(!username) return res.status(400).json({error: "Missing username"}); + + const user = await db.query(`SELECT visibility FROM users WHERE username = string::lowercase("${username}")`); + + if(user.length == 0) return res.status(400).json({error: "User does not exist"}); + + res.status(200).json({visibility: user[0].visibility}); + } + catch(err){ + console.log(err); + res.status(500).json({error: "Internal server error"}); + } +}); + module.exports = router; \ No newline at end of file