diff --git a/SerpentRace_Backend/src/Api/routers/deckRouter.ts b/SerpentRace_Backend/src/Api/routers/deckRouter.ts index 55b35f42..67632a33 100644 --- a/SerpentRace_Backend/src/Api/routers/deckRouter.ts +++ b/SerpentRace_Backend/src/Api/routers/deckRouter.ts @@ -199,12 +199,13 @@ deckRouter.patch('/:id', authRequired, async (req, res) => { try { const deckId = req.params.id; const userId = (req as any).user.userId; - + const authLevel = (req as any).user.authLevel; + logRequest('Update deck endpoint accessed', req, res, { deckId, userId, updateFields: Object.keys(req.body) }); // Convert string enum values to integers const updateData = convertEnumValues(req.body); - - const result = await container.updateDeckCommandHandler.execute({ id: deckId, userstate: userState, ...updateData }); + + const result = await container.updateDeckCommandHandler.execute({ userid: userId, authLevel: authLevel, id: deckId, ...updateData }); logRequest('Deck updated successfully', req, res, { deckId, userId }); res.json(result); @@ -244,9 +245,11 @@ deckRouter.delete('/:id', authRequired, async (req, res) => { try { const deckId = req.params.id; const userId = (req as any).user.userId; - - const result = await container.deleteDeckCommandHandler.execute({ id: deckId, soft: true }); - + const authLevel = (req as any).user.authLevel; + logRequest('Soft delete deck endpoint accessed', req, res, { deckId, userId }); + + const result = await container.deleteDeckCommandHandler.execute({ userid: userId, authLevel: authLevel, id: deckId, soft: true }); + logRequest('Deck soft delete successful', req, res, { deckId, userId, success: result }); res.json({ success: result }); } catch (error) { diff --git a/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommand.ts b/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommand.ts index bf8ac418..d41de235 100644 --- a/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommand.ts +++ b/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommand.ts @@ -1,4 +1,6 @@ export interface DeleteDeckCommand { + userid: string; + authLevel: number; id: string; soft?: boolean; } diff --git a/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommandHandler.ts b/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommandHandler.ts index e484c4ef..07309b19 100644 --- a/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/Deck/commands/DeleteDeckCommandHandler.ts @@ -1,10 +1,24 @@ import { IDeckRepository } from '../../../Domain/IRepository/IDeckRepository'; +import { logAuth, logError } from '../../Services/Logger'; import { DeleteDeckCommand } from './DeleteDeckCommand'; export class DeleteDeckCommandHandler { constructor(private readonly deckRepo: IDeckRepository) {} async execute(cmd: DeleteDeckCommand): Promise { + + //get decks userid + const deck = await this.deckRepo.findById(cmd.id); + if (!deck) { + logError(`Deck not found with ID: ${cmd.id}`); + throw new Error('Deck not found'); + } + + if(cmd.authLevel !==1 && deck.userid !== cmd.userid) { + logAuth(`Unauthorized access attempt to deck with ID: ${cmd.id}, UserID: ${cmd.userid}`); + throw new Error('Unauthorized'); + } + if (cmd.soft) { await this.deckRepo.softDelete(cmd.id); } else { diff --git a/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommand.ts b/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommand.ts index b1ce0066..9fbbb3a9 100644 --- a/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommand.ts +++ b/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommand.ts @@ -1,11 +1,10 @@ -import { n } from "framer-motion/dist/types.d-D0HXPxHm"; - export interface UpdateDeckCommand { + userid: string; + authLevel: number; id: string; userstate?: number; name?: string; type?: number; - userid?: string; cards?: any[]; ctype?: number; state?: number; diff --git a/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommandHandler.ts b/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommandHandler.ts index ced487ce..8e5b2ca5 100644 --- a/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/Deck/commands/UpdateDeckCommandHandler.ts @@ -3,7 +3,7 @@ import { UpdateDeckCommand } from './UpdateDeckCommand'; import { ShortDeckDto } from '../../DTOs/DeckDto'; import { DeckMapper } from '../../DTOs/Mappers/DeckMapper'; import { DeckAggregate } from '../../../Domain/Deck/DeckAggregate'; -import { logError } from '../../Services/Logger'; +import { logAuth, logError } from '../../Services/Logger'; export class UpdateDeckCommandHandler { constructor(private readonly deckRepo: IDeckRepository) {} @@ -24,6 +24,11 @@ export class UpdateDeckCommandHandler { throw new Error('Deck not found'); } + if(cmd.authLevel !==1 && existingDeck.userid !== cmd.userid) { + logAuth(`Unauthorized access attempt to deck with ID: ${cmd.id}, UserID: ${cmd.userid}`); + throw new Error('Unauthorized'); + } + const for_update: Partial = {}; if(cmd.name !== undefined) for_update.name = cmd.name; if(cmd.type !== undefined) for_update.type = cmd.type; diff --git a/SerpentRace_Docker/docker-compose.watch.yml b/SerpentRace_Docker/docker-compose.watch.yml index 8d026a06..e7d79b8e 100644 --- a/SerpentRace_Docker/docker-compose.watch.yml +++ b/SerpentRace_Docker/docker-compose.watch.yml @@ -76,8 +76,7 @@ services: - NODE_ENV=development - VITE_API_URL=http://localhost:3000 volumes: - - ../SerpentRace_Frontend:/app - - /app/node_modules + [] develop: watch: - action: sync diff --git a/SerpentRace_Frontend/src/App.jsx b/SerpentRace_Frontend/src/App.jsx index 7ed485e4..99e536d2 100644 --- a/SerpentRace_Frontend/src/App.jsx +++ b/SerpentRace_Frontend/src/App.jsx @@ -10,7 +10,7 @@ import Landingpage from "./pages/Landing/Landingpage" import Home from "./pages/Landing/Home" import DeckManagerPage from "./pages/Decks/DeckManagerPage" import DeckCreator from "./pages/DeckCreator/DeckCreator" -import CompanyHub from "./pages/Companies/Companies" +import CompanyHub from "./pages/Contacts/Contacts" import About from "./pages/About/About" import ScrollToTop from "./components/ScrollToTop" import GameScreen from "./pages/Game/GameScreen" @@ -64,7 +64,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> diff --git a/SerpentRace_Frontend/src/components/Footer/Footer.jsx b/SerpentRace_Frontend/src/components/Footer/Footer.jsx index 45c3394c..1c2f277e 100644 --- a/SerpentRace_Frontend/src/components/Footer/Footer.jsx +++ b/SerpentRace_Frontend/src/components/Footer/Footer.jsx @@ -57,7 +57,7 @@ const Footer = () => { Rólunk - + Kapcsolat diff --git a/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx b/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx index 1f37c884..79391347 100644 --- a/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx +++ b/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx @@ -8,7 +8,7 @@ import { motion } from "framer-motion" import { isAuthenticated } from "../../hooks/useRequireAuth" // <-- added import import { useNavigate } from "react-router-dom" // <-- NEW -const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame }) => { +const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame, onNavigateToContacts }) => { const auth = isAuthenticated() // <-- check without redirect const navigate = useNavigate() // <-- NEW @@ -68,7 +68,7 @@ const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame }) = ) : ( - navigate("/home")} width="w-60" /> + )} @@ -178,7 +178,7 @@ const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame }) = diff --git a/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx b/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx index 979be9de..68d471aa 100644 --- a/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx +++ b/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx @@ -19,9 +19,9 @@ const Navbar = () => { return (