Skip to content

Commit

Permalink
Merge pull request #154 from sopra-fs24-group-09/dev
Browse files Browse the repository at this point in the history
Add authentication in requests and websocket messages
  • Loading branch information
Haaaan1 authored May 12, 2024
2 parents 736d9c4 + 9533eee commit 8d096ca
Show file tree
Hide file tree
Showing 4 changed files with 463 additions and 189 deletions.
116 changes: 65 additions & 51 deletions src/components/views/Gameroom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ const Gameroom = () => {
// console.log(mssg)
console.log("[onResponseReceived] receiptId",msg.receiptId)
console.log("[onResponseReceived] reqList:",requestLists.current)

// Check if the message indicates an invalid or expired token
if (msg.auth === false) {
showToast("Invalid or expired token, please login again!", "error");
sessionStorage.clear(); // Clear session storage
navigate("/login"); // Navigate to the login page

return; // Exit the function to avoid further processing
}

const index = requestLists.current.findIndex(item => item.receiptId === msg.receiptId);
if (index !== INDEX_NOT_FOUND) {
const messageType = requestLists.current[index].type;
Expand Down Expand Up @@ -214,6 +224,7 @@ const Gameroom = () => {
/// 2. if the response is success, do nothing
/// 3. if the response is failure, show the error message
/// 4. if the response is not received, do something to handle the timeout
/// 5. if the response is unauthorized, navigate to login page and clear session
};

const onPlayerInfoReceived = (payload) => {
Expand Down Expand Up @@ -396,7 +407,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current?.send(
`/app/message/users/enterroom/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
requestLists.current.push({ type: "enter",receiptId: receiptId });
Expand Down Expand Up @@ -429,7 +441,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current?.send(
`/app/message/users/ready/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
requestLists.current.push({ type: "ready",receiptId: receiptId });
Expand Down Expand Up @@ -461,7 +474,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current?.send(
`/app/message/users/unready/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
requestLists.current.push({ type: "unready",receiptId: receiptId });
Expand Down Expand Up @@ -493,7 +507,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current?.send(
`/app/message/games/start/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
requestLists.current.push({ type: "start",receiptId: receiptId });
Expand Down Expand Up @@ -527,7 +542,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current?.send(
`/app/message/users/exitroom/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
// requestLists.current.push({ type: "leave",receiptId: receiptId });
Expand Down Expand Up @@ -562,7 +578,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current?.send(
`/app/message/games/validate/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
requestLists.current.push({ type: "submit",receiptId: receiptId });
Expand Down Expand Up @@ -603,7 +620,8 @@ const Gameroom = () => {
const receiptId = uuidv4();
stompClientRef.current.send(
`/app/message/games/audio/upload/${currentRoomID}`,
{ receiptId: receiptId },
{ receiptId: receiptId,
token: sessionStorage.getItem("token") },
JSON.stringify(payload)
);
requestLists.current.push({ type: "upload",receiptId: receiptId });
Expand Down Expand Up @@ -644,55 +662,51 @@ const Gameroom = () => {
return (
<>
{playerStatus !== null && (
<div className="gameroom leaderboarddiv">
<div className="gameroom leaderboard">
<div className="leaderboarddiv">
<div className="leaderboard">
{sortedPlayerStatus.map((playerInfo, index) => (
<div className="gameroom singleScoreContainer" key={index}>
<span className={"gameroom ranking-" + index}>{index + 1}</span>
<span className="gameroom ldPlayerAvatar">
<i
className={"twa twa-" + playerInfo.user.avatar}
style={{ fontSize: "2.8rem" }}
/>
</span>
<span className="gameroom ldPlayerName">
{playerInfo.user.name}
</span>
<span className="gameroom scorenum" style={{ gridColumn: "3" }}>
{playerInfo.score.total}
<div className="single-score-container" key={index}>
<span className={`ranking-badge ranking-${index}`}>{index + 1}</span>
<span className={"ldgrid-item-1"}>
<span className="avatar">
<i className={`twa twa-${playerInfo.user.avatar}`} style={{ fontSize: "2.8rem" }} />
</span>
<span className="title">{playerInfo.user.name}</span>
</span>
<span className="gameroom ldtitle" style={{ gridColumn: "3" }}>
Total
<span className={"ldgrid-item-2"}>
<span className="score-container">{playerInfo.score.total}</span>
<span className="title">Total</span>
</span>
<span className="gameroom scorenum" style={{ gridColumn: "4" }}>
{playerInfo.score.guess}
<span className={"ldgrid-item-3"}>
<span className="score-container">{playerInfo.score.guess}</span>
<span className="title">Guess</span>
</span>
<span className="gameroom ldtitle" style={{ gridColumn: "4" }}>
Guess
<span className={"ldgrid-item-4"}>
<span className="score-container">{playerInfo.score.read}</span>
<span className="title">Read</span>
</span>
<span className="gameroom scorenum" style={{ gridColumn: "5" }}>
{playerInfo.score.read}
</span>
<span className="gameroom ldtitle" style={{ gridColumn: "5" }}>
Read
</span>
{playerInfo.score.details.map((detail, detailIndex) => (
<React.Fragment key={detailIndex}>
<span
className="gameroom scorenum"
style={{ gridColumn: `${detailIndex + LEADER_BOARD_GAP}` }}
>
{detail.score}
</span>

<span
className="gameroom ldtitle"
style={{ gridColumn: `${detailIndex + LEADER_BOARD_GAP}` }}
>
{detail.word}
</span>
</React.Fragment>
))}
{playerInfo.score.details.map((detail, detailIndex) => {
const getBackgroundColor = (score) => {
if (score > 0) return "#d4edda";
if (score < 0) return "#f8d7da";

return "#fff3cd";
};

return (
<React.Fragment key={detailIndex}>
<span
className={"ldgrid-item"}
style={{ gridColumn: `${detailIndex + LEADER_BOARD_GAP}`}}
>
<span
style={{backgroundColor: getBackgroundColor(detail.score)}}
className={"score-container"}>{detail.score}</span>
<span className="title">{detail.word}</span>
</span>
</React.Fragment>
);
})}
</div>
))}
</div>
Expand Down
47 changes: 36 additions & 11 deletions src/components/views/Lobby.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useCallback, useRef, useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { api, handleError } from "helpers/api";
import { Button } from "components/ui/Button";
import { throttle } from "lodash";
Expand All @@ -12,7 +11,7 @@ import { Dropdown } from "components/ui/Dropdown";
import "styles/views/Lobby.scss";
import { getDomain } from "helpers/getDomain";
import "styles/ui/Popup.scss";
import { MAX_USERNAME_LENGTH, MAX_ROOM_NAME_LENGTH } from "../../constants/constants";
import { MAX_USERNAME_LENGTH, MAX_ROOM_NAME_LENGTH, HTTP_STATUS } from "../../constants/constants";
import SockJS from "sockjs-client";
import { over } from "stompjs";
import { showToast} from "../../helpers/toastService";
Expand Down Expand Up @@ -119,7 +118,6 @@ const Lobby = () => {

const logout = async () => {
const id = sessionStorage.getItem("id");
sessionStorage.removeItem("token");
//apply a post request for user logout
try {
const requestBody = JSON.stringify({ id: id });
Expand Down Expand Up @@ -187,7 +185,7 @@ const Lobby = () => {
// showToast("Reconnect to your previous room!", "success");
// }

setRooms(payload); // 确保这里是数组
setRooms(payload);
console.log("Rooms updated:", message_lobby.message);
} else {
console.error("Received data is not in expected format:", message_lobby);
Expand Down Expand Up @@ -287,7 +285,7 @@ const Lobby = () => {
console.log("Room ID:", response.data.roomId);
const roomId = response.data.roomId;
navigate(`/rooms/${roomId}/${roomName}`);
//toggleRoomCreationPop(); // 关闭创建房间的弹窗
//toggleRoomCreationPop();
} catch (error) {
handleError(error);

Expand Down Expand Up @@ -386,26 +384,53 @@ const Lobby = () => {

///
/// if error is network error, clear the session and navigate to login page
/// if unauthorized, clear the session and navigate to login page
///
const handleError = (error) => {
// if(!error.message){
// // if error message is undefined
// showToast("Something went wrong, please try again later.", "error");
// }
if (error.message.match(/Network Error/)) {
// Check if there's a response object in the error
if (error.response) {
const { status, data } = error.response;

// Handle 401 Unauthorized errors
if (status === HTTP_STATUS.UNAUTHORIZED) {
console.error("Unauthorized: " + data.message + "\n" + error);
showToast("Your session has expired or is invalid. Please log in again.", "error");
sessionStorage.clear();
navigate("/login");
} else if (status === HTTP_STATUS.FORBIDDEN) {
// Handle 403 Forbidden errors
console.error("Forbidden: Access is denied. " + data.message + "\n" + error);
showToast("Access is denied. You do not have permission to access this resource.", "error");
} else {
// Handle other types of errors generically
console.error(`Error: ${data.message}\n${error}`);
showToast("An error occurred: ${data.message}", "error");
}
} else if (error.message && error.message.match(/Network Error/)) {
// Handle network errors
console.error(`The server cannot be reached.\nDid you start it?\n${error}`);
showToast(`The server cannot be reached.\nDid you start it?\n${error}`);
sessionStorage.clear();
navigate("/login");
showToast("The server cannot be reached.\nDid you start it?", "error");
} else {
console.error(`Something went wrong: \n${error}`);
showToast(`Something went wrong: \n${error}`);
showToast("Something went wrong: \n${error}", "error");
}
}

const throttledClickHandler = throttle((Room, navigate, showToast) => {
try {
// Check if the session token is empty
const token = sessionStorage.getItem("token");
if (!token) {
showToast("Session expired or invalid, please log in again.", "error");
sessionStorage.clear(); // Clear session storage
navigate("/login");

return; // Exit the function to avoid further processing
}

if (Room.roomPlayersList.length === Room.roomMaxNum) {
showToast("Room is Full, please enter another room!", "error");
} else if (Room.status === "In Game") {
Expand Down
19 changes: 19 additions & 0 deletions src/helpers/api.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import axios from "axios";
import { getDomain } from "./getDomain";
import {HTTP_STATUS} from "../constants/constants"

export const api = axios.create({
baseURL: getDomain(),
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }
});

// Request interceptor
api.interceptors.request.use(function (config) {
const token = sessionStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`; // Append token to headers if it exists
}
console.log("Sending request to:", config.url);
console.log("Request headers:", config.headers);
console.log("Request method:", config.method);
if (config.data) {
console.log("Request data:", config.data);
}

return config;
}, function (error) {
return Promise.reject(error); // Handle request error
});

export const handleError = error => {
const response = error.response;

Expand Down
Loading

0 comments on commit 8d096ca

Please sign in to comment.