From 7dea3612afeeb6748797d2df0113158ec06214e4 Mon Sep 17 00:00:00 2001 From: Lukian Date: Mon, 24 Mar 2025 20:59:33 +0100 Subject: [PATCH] add: added channel admins --- back/api/channels.js | 32 ++++++++++++++++++++++++++++++-- back/libs/mysql.js | 21 ++++++++++++++++++--- front/src/main.tsx | 2 +- front/src/pages/Channel.tsx | 30 ++++++++++++++++++++++++++++-- front/src/pages/Home.tsx | 2 +- front/src/types.tsx | 1 + 6 files changed, 79 insertions(+), 9 deletions(-) diff --git a/back/api/channels.js b/back/api/channels.js index 817af9f..e1060db 100644 --- a/back/api/channels.js +++ b/back/api/channels.js @@ -1,6 +1,6 @@ const express = require('express'); const jwt = require('jsonwebtoken'); -const { getConnection, getUser, getChannels, getChannel, addChannel, getMessages, addMessage } = require('../libs/mysql'); +const { getConnection, getUser, getChannels, getChannel, addChannel, getMessages, addMessage, deleteMessage } = require('../libs/mysql'); const router = express.Router(); @@ -59,6 +59,34 @@ router.post('/:name/messages/send', async (req, res) => { res.send({ message: 'Message sent' }); }); +router.post('/:name/messages/delete', async (req, res) => { + const { token, message_id } = req.body; + const name = req.params.name; + const connection = await getConnection(); + + const decoded = jwt.verify(token, process.env.JWT_SECRET); + const user = await getUser(connection, decoded.id); + if (!user[0]) { + connection.end(); + return res.status(401).send({ error: 'Invalid token' }); + } + + const channel = await getChannel(connection, name); + if (!channel[0]) { + connection.end(); + return res.status(400).send({ error: 'No channel found' }); + } + + if (user[0].id !== channel[0].owner_id && user[0].id !== message_id) { + connection.end(); + return res.status(401).send({ error: 'Unauthorized' }); + } + + await deleteMessage(connection, message_id); + connection.end(); + res.send({ message: 'Message deleted' }); +}); + router.post('/add', async (req, res) => { const { name, description, token } = req.body; const connection = await getConnection(); @@ -81,7 +109,7 @@ router.post('/add', async (req, res) => { return res.status(400).send({ error: 'Invalid channel name' }); } - await addChannel(connection, name, description); + await addChannel(connection, name, description, user[0].id); connection.end(); res.send({ message: 'Channel added' }); }); diff --git a/back/libs/mysql.js b/back/libs/mysql.js index 2b92d73..25c1d88 100644 --- a/back/libs/mysql.js +++ b/back/libs/mysql.js @@ -79,10 +79,10 @@ function getChannel(connection, name) { }); } -function addChannel(connection, name, description) { +function addChannel(connection, name, description, owner_id) { return new Promise((resolve, reject) => { connection.query( - `INSERT INTO channels (name, description) VALUES ('${name}', '${description}')`, + `INSERT INTO channels (name, description, owner_id) VALUES ('${name}', '${description}', ${owner_id})`, (error, result) => { if (error) { reject(new Error(error)); @@ -121,6 +121,20 @@ function addMessage(connection, channel_id, user_id, message) { }); } +function deleteMessage(connection, message_id) { + return new Promise((resolve, reject) => { + connection.query( + `DELETE FROM messages WHERE id = ${message_id}`, + (error, result) => { + if (error) { + reject(new Error(error)); + } + resolve(result); + } + ); + }); +} + module.exports = { getConnection, getUser, @@ -130,5 +144,6 @@ module.exports = { getChannel, addChannel, getMessages, - addMessage + addMessage, + deleteMessage }; diff --git a/front/src/main.tsx b/front/src/main.tsx index beef788..ab5df2c 100644 --- a/front/src/main.tsx +++ b/front/src/main.tsx @@ -12,7 +12,7 @@ createRoot(document.getElementById('root')!).render( } /> - } /> + } /> } /> } /> } /> diff --git a/front/src/pages/Channel.tsx b/front/src/pages/Channel.tsx index 27fd159..7956b20 100644 --- a/front/src/pages/Channel.tsx +++ b/front/src/pages/Channel.tsx @@ -1,6 +1,6 @@ import { useParams, Link } from "react-router-dom"; import React, { useEffect, useState } from "react"; -import { Channel_type, Messages } from "../types"; +import { Channel_type, Messages, User } from "../types"; import axios from "axios"; export default function Channel() { @@ -8,6 +8,7 @@ export default function Channel() { const [channel, setChannel] = useState(); const [messages, setMessages] = useState(); const [token, setToken] = useState(""); + const [user, setUser] = useState(); const [message, setMessage] = useState(""); const [maxMessageToShown, setMaxMessageToShown] = useState(10); @@ -29,9 +30,31 @@ export default function Channel() { }); } + function deleteMessage(message_id: number) { + axios + .post(`/api/channels/${name}/messages/delete`, { token, message_id }) + .then(() => { + axios + .get(`/api/channels/${name}/messages`) + .then((res) => { + setMessages(res.data); + } + ); + }) + .catch((err) => { + console.error(err.response.data.message); + }); + } + useEffect(() => { const localToken = localStorage.getItem("token"); - if (localToken) setToken(localToken); + if (localToken) { + setToken(localToken); + axios.post("/api/auth/me", { token: localToken }).then((res) => { + setUser(res.data); + } + ); + } axios.get(`/api/channels/${name}`).then((res) => { setChannel(res.data); }); @@ -72,6 +95,9 @@ export default function Channel() { {messages.slice(0, maxMessageToShown).map((message) => (
  • {message.username}: {message.content}

    + {(user?.id === message.user_id || user?.id === channel.owner_id) && ( + + )}
  • ))} diff --git a/front/src/pages/Home.tsx b/front/src/pages/Home.tsx index d5d59bf..471644c 100644 --- a/front/src/pages/Home.tsx +++ b/front/src/pages/Home.tsx @@ -48,7 +48,7 @@ export default function Home() {
      {channels?.map((channel) => (
    • - {channel.name} + {channel.name}
    • ))}
    diff --git a/front/src/types.tsx b/front/src/types.tsx index 02a2d8c..f47b83c 100644 --- a/front/src/types.tsx +++ b/front/src/types.tsx @@ -2,6 +2,7 @@ export type Channel_type ={ id: number, name: string description: string + owner_id: number } export type Channels = Channel_type[]