diff --git a/back/api/users.js b/back/api/users.js index 2ad60ec..e7c9047 100644 --- a/back/api/users.js +++ b/back/api/users.js @@ -1,5 +1,5 @@ const express = require('express'); -const { getConnection, getUsers, getUserByUsername, getUserLastMessages, getMentions, deleteUser, deleteUserMessages, deleteUserMentions } = require('../libs/mysql'); +const { getConnection, getUsers, getUserByUsername, getUserLastMessages, getMentions, deleteUser, deleteUserMessages, deleteUserMentions, setUserPfp } = require('../libs/mysql'); const { checkAuth } = require("../libs/middlewares") const path = require('path'); const fs = require('node:fs'); @@ -98,4 +98,35 @@ router.post('/:username/delete', checkAuth, async (req, res) => { res.send({ message: 'User deleted' }); }); +router.post('/:username/deletepfp', checkAuth, async (req, res) => { + const username = req.params.username; + const user = req.user; + + const connection = await getConnection(); + + const userToDelete = await getUserByUsername(connection, username); + + if (!userToDelete[0]) { + connection.end(); + return res.status(400).send({ error: 'No user found' }); + } + + if (user.admin !== 1) { + connection.end(); + return res.status(401).send({ error: 'Unauthorized' }); + } + + if (userToDelete[0].pfp) { + await setUserPfp(connection, userToDelete[0].id, null); + } + + if (fs.existsSync(path.join(__dirname, `../data/pfps/${userToDelete[0].pfp}`))) { + fs.unlinkSync(path.join(__dirname, `../data/pfps/${userToDelete[0].pfp}`)); + } + + connection.end(); + + res.send({ message: 'User pfp deleted' }); +}); + module.exports = router; \ No newline at end of file diff --git a/front/src/pages/ChannelPage.tsx b/front/src/pages/ChannelPage.tsx index 57db881..a7b3bf6 100644 --- a/front/src/pages/ChannelPage.tsx +++ b/front/src/pages/ChannelPage.tsx @@ -42,6 +42,9 @@ export default function ChannelPage({socket}: {socket: WebSocket}) { } function purgeChannel() { + if (!window.confirm(`Are you sure you want to purge ${channel?.name}?`)) { + return; + } axios .post(`/api/channels/${name}/purge`, { token }) .catch((err) => { @@ -51,6 +54,9 @@ export default function ChannelPage({socket}: {socket: WebSocket}) { } function deleteChannel() { + if (!window.confirm(`Are you sure you want to delete ${channel?.name}?`)) { + return; + } axios .post(`/api/channels/${name}/delete`, { token }) .then(() => { diff --git a/front/src/pages/ChannelsPage.tsx b/front/src/pages/ChannelsPage.tsx index 7bb5f39..c6473e2 100644 --- a/front/src/pages/ChannelsPage.tsx +++ b/front/src/pages/ChannelsPage.tsx @@ -13,6 +13,9 @@ export default function ChannelsPage({socket}: {socket: WebSocket}) { const [user, setUser] = useState(); function deleteChannel(name: string) { + if (!window.confirm(`Are you sure you want to delete ${name}?`)) { + return; + } axios .post(`/api/channels/${name}/delete`, { token }) .catch((err) => { diff --git a/front/src/pages/UserPage.tsx b/front/src/pages/UserPage.tsx index a2a777f..c65baa7 100644 --- a/front/src/pages/UserPage.tsx +++ b/front/src/pages/UserPage.tsx @@ -1,4 +1,4 @@ -import { Link, useParams } from "react-router-dom"; +import { Link, useParams, useNavigate } from "react-router-dom"; import { useEffect, useState } from "react"; import { User, Messages } from "../types"; import TopBar from "../components/TopBar"; @@ -8,16 +8,47 @@ import axios from "axios"; import "../styles/UserPage.css"; export default function UserPage({socket}: {socket: WebSocket}) { + const navigate = useNavigate(); const { username } = useParams(); const [pageUser, setPageUser] = useState(); const [messages, setMessages] = useState(); const [user, setUser] = useState(); const [noUser, setNoUser] = useState(false); + const [token, setToken] = useState(""); + + function deleteUser() { + if (!window.confirm(`Are you sure you want to delete ${pageUser?.username}?`)) { + return; + } + axios + .post(`/api/users/${pageUser?.username}/delete`, { token }) + .then(() => { + navigate("/"); + }) + .catch((err) => { + console.error(err.response.data); + }); + } + + function deleteUserPfp() { + if (!window.confirm(`Are you sure you want to delete ${pageUser?.username}'s profile picture?`)) { + return; + } + axios + .post(`/api/users/${pageUser?.username}/deletepfp`, { token }) + .then(() => { + window.location.reload(); + }) + .catch((err) => { + console.error(err.response.data); + }); + } useEffect(() => { const localToken = localStorage.getItem("token"); if (localToken) { + setToken(localToken); axios .post("/api/auth/me", { token: localToken }).then((res) => { setUser(res.data); @@ -100,6 +131,16 @@ export default function UserPage({socket}: {socket: WebSocket}) { {pageUser.id === user?.id && ( Edit profile )} + {user?.admin == 1 && ( +
+ + +
+ )}

Last messages

diff --git a/front/src/pages/UsersPage.tsx b/front/src/pages/UsersPage.tsx index 1a3df99..cd2bb4b 100644 --- a/front/src/pages/UsersPage.tsx +++ b/front/src/pages/UsersPage.tsx @@ -13,6 +13,9 @@ export default function UsersPage({socket}: {socket: WebSocket}) { const [thisUser, setThisUser] = useState(); function deleteUser(username: string) { + if (!window.confirm(`Are you sure you want to delete ${username}?`)) { + return; + } axios .post(`/api/users/${username}/delete`, { token }) .catch((err) => { diff --git a/front/src/styles/UserPage.css b/front/src/styles/UserPage.css index 6e04963..ca491f5 100644 --- a/front/src/styles/UserPage.css +++ b/front/src/styles/UserPage.css @@ -13,6 +13,7 @@ padding: 10px; display: flex; flex-direction: column; + align-items: start; background-color: #fff6fd; }