Skip to content

Commit

Permalink
fix(joinGameHandler): Allow teachers and admins to join any game console
Browse files Browse the repository at this point in the history
  • Loading branch information
Baboo7 committed Jun 22, 2023
1 parent e3be4b6 commit 6263ca3
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useTranslation } from "../../translations/useTranslation";

export { GameConsoleView };

// TODO: protect page using user role.
function GameConsoleView() {
const [selectedScreen, setSelectedScreen] = useState<string>("Teams");
return (
Expand Down
4 changes: 4 additions & 0 deletions packages/client/src/modules/play/context/playContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ function useGameSocket({
setIsInitialised(true);
});

newSocket.on("game:leave", () => {
navigate("/play/my-games");
});

newSocket.on("game:update", ({ update }: { update: Partial<IGame> }) => {
setGame((previous) => {
if (previous === null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ import {
gameServices,
playerServices,
productionActionServices,
roleServices,
teamServices,
} from "../services";
import { BusinessError } from "../../utils/businessError";
import { Game } from "../../games/types";
import { User } from "../../users/types";

export { handleJoinGame };

Expand All @@ -29,10 +33,8 @@ function handleJoinGame(io: Server, socket: Socket) {
socket.data.gameId = gameId;
socket.data.user = user;

const isPlayer = game?.teacherId !== user.id;

let gameInitData: GameInitEmitted;
if (isPlayer) {
if (await hasPlayerAccess(user, game)) {
const player = await playerServices.findOne(gameId, user.id, {
include: {
user: true,
Expand Down Expand Up @@ -82,7 +84,7 @@ function handleJoinGame(io: Server, socket: Socket) {
players: [player],
teams: [team],
};
} else {
} else if (await hasTeacherAccess(user, game)) {
const [players, teams, consumptionActions, productionActions] =
await Promise.all([
playerServices.findMany(gameId, {
Expand Down Expand Up @@ -116,9 +118,37 @@ function handleJoinGame(io: Server, socket: Socket) {
players,
teams,
};
} else {
socket.emit("game:leave");
throw new BusinessError(
`User ${user.id} is not authorized to join game ${game.id}`
);
}

socket.emit("game:init", gameInitData);
})
);
}

async function hasTeacherAccess(user: User, game: Game) {
if (game.teacherId === user.id) {
return true;
}

// TODO: protect game access with a list of allowed teachers?
const userRole = await roleServices.findOne(user.roleId);
if (["admin", "teacher"].includes(userRole?.name || "")) {
return true;
}

return false;
}

async function hasPlayerAccess(user: User, game: Game) {
const player = await playerServices.findOne(game.id, user.id);
if (player) {
return true;
}

return false;
}
1 change: 1 addition & 0 deletions packages/server/src/modules/websocket/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export * from "./playerActionServices";
export * from "./playerServices";
export * from "./productionActionServices";
export * from "./profileServices";
export * from "./roleServices";
export * from "./teamActionServices";
export * from "./teamServices";
16 changes: 16 additions & 0 deletions packages/server/src/modules/websocket/services/roleServices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Role } from "@prisma/client";
import { database } from "../../../database";

const model = database.role;

export const roleServices = {
findOne,
};

async function findOne(id: number): Promise<Role | null> {
return model.findFirst({
where: {
id,
},
});
}
1 change: 1 addition & 0 deletions packages/server/src/modules/websocket/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type ListenEvents = any;

type EmitEvents = {
"game:init": (args: GameInitEmitted) => void;
"game:leave": () => void;
"game:update": (args: { update: Partial<Game> }) => void;
"player:update": (args: { updates: Partial<PlayerEmitted>[] }) => void;
"player-actions:update": (args: {
Expand Down

0 comments on commit 6263ca3

Please sign in to comment.